From 47faabe40caa2c01a6379f5d143af189fa96ca9b Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 26 Feb 2020 19:12:55 +0300 Subject: Release version 1.6.3+2 Invent PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS flag --- libpkgconf/README-DEV | 15 + libpkgconf/dont-merge-fragments.patch | 26 ++ libpkgconf/libpkgconf/fragment.c | 698 +++++++++++++++++++++++++++++++- libpkgconf/libpkgconf/fragment.c.orig | 1 + libpkgconf/libpkgconf/libpkgconf.h | 389 +++++++++++++++++- libpkgconf/libpkgconf/libpkgconf.h.orig | 1 + libpkgconf/manifest | 2 +- libpkgconf/tests/api/driver.c | 2 +- libpkgconf/tests/api/testscript | 9 +- 9 files changed, 1136 insertions(+), 7 deletions(-) create mode 100644 libpkgconf/dont-merge-fragments.patch mode change 120000 => 100644 libpkgconf/libpkgconf/fragment.c create mode 120000 libpkgconf/libpkgconf/fragment.c.orig mode change 120000 => 100644 libpkgconf/libpkgconf/libpkgconf.h create mode 120000 libpkgconf/libpkgconf/libpkgconf.h.orig diff --git a/libpkgconf/README-DEV b/libpkgconf/README-DEV index 0a63eb9..37a1317 100644 --- a/libpkgconf/README-DEV +++ b/libpkgconf/README-DEV @@ -29,3 +29,18 @@ $ cat libpkgconf/config.h.in | sort -u >defined-macros $ diff defined-macros used-macros + +We also extend the upstream package functionality allowing to prevent merging +of "special" fragments, such as `-framework `, into a single fragment. + +$ mv libpkgconf.h libpkgconf.h.orig +$ cp libpkgconf.h.orig libpkgconf.h + +$ mv fragment.c fragment.c.orig +$ cp fragment.c.orig fragment.c + +$ git apply dont-merge-fragments.patch + +Note that the patch is produces by the following command: + +$ git diff >dont-merge-fragments.patch diff --git a/libpkgconf/dont-merge-fragments.patch b/libpkgconf/dont-merge-fragments.patch new file mode 100644 index 0000000..d8e5eae --- /dev/null +++ b/libpkgconf/dont-merge-fragments.patch @@ -0,0 +1,26 @@ +diff --git a/libpkgconf/libpkgconf/fragment.c b/libpkgconf/libpkgconf/fragment.c +index b431694..37830c8 100644 +--- a/libpkgconf/libpkgconf/fragment.c ++++ b/libpkgconf/libpkgconf/fragment.c +@@ -150,7 +150,8 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const + { + char mungebuf[PKGCONF_ITEM_SIZE]; + +- if (list->tail != NULL && list->tail->data != NULL) ++ if (list->tail != NULL && list->tail->data != NULL && ++ !(client->flags & PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS)) + { + pkgconf_fragment_t *parent = list->tail->data; + +diff --git a/libpkgconf/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf/libpkgconf.h +index 44a9e7f..6f4c8b5 100644 +--- a/libpkgconf/libpkgconf/libpkgconf.h ++++ b/libpkgconf/libpkgconf/libpkgconf.h +@@ -247,6 +247,7 @@ PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const ch + #define PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS 0x0800 + #define PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS 0x1000 + #define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000 ++#define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000 + + #define PKGCONF_PKG_DEPF_INTERNAL 0x1 + diff --git a/libpkgconf/libpkgconf/fragment.c b/libpkgconf/libpkgconf/fragment.c deleted file mode 120000 index ccec352..0000000 --- a/libpkgconf/libpkgconf/fragment.c +++ /dev/null @@ -1 +0,0 @@ -../../upstream/libpkgconf/fragment.c \ No newline at end of file diff --git a/libpkgconf/libpkgconf/fragment.c b/libpkgconf/libpkgconf/fragment.c new file mode 100644 index 0000000..37830c8 --- /dev/null +++ b/libpkgconf/libpkgconf/fragment.c @@ -0,0 +1,697 @@ +/* + * fragment.c + * Management of fragment lists. + * + * Copyright (c) 2012, 2013, 2014 pkgconf authors (see AUTHORS). + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#include +#include + +/* + * !doc + * + * libpkgconf `fragment` module + * ============================ + * + * The `fragment` module provides low-level management and rendering of fragment lists. A + * `fragment list` contains various `fragments` of text (such as ``-I /usr/include``) in a matter + * which is composable, mergeable and reorderable. + */ + +struct pkgconf_fragment_check { + char *token; + size_t len; +}; + +static inline bool +pkgconf_fragment_is_unmergeable(const char *string) +{ + static const struct pkgconf_fragment_check check_fragments[] = { + {"-framework", 10}, + {"-isystem", 8}, + {"-idirafter", 10}, + {"-pthread", 8}, + {"-Wa,", 4}, + {"-Wl,", 4}, + {"-Wp,", 4}, + {"-trigraphs", 10}, + {"-pedantic", 9}, + {"-ansi", 5}, + {"-std=", 5}, + {"-stdlib=", 8}, + {"-include", 8}, + {"-nostdinc", 9}, + {"-nostdlibinc", 12}, + {"-nobuiltininc", 13}, + }; + + if (*string != '-') + return true; + + for (size_t i = 0; i < PKGCONF_ARRAY_SIZE(check_fragments); i++) + if (!strncmp(string, check_fragments[i].token, check_fragments[i].len)) + return true; + + /* only one pair of {-flag, arg} may be merged together */ + if (strchr(string, ' ') != NULL) + return false; + + return false; +} + +static inline bool +pkgconf_fragment_should_munge(const char *string, const char *sysroot_dir) +{ + if (*string != '/') + return false; + + if (sysroot_dir != NULL && strncmp(sysroot_dir, string, strlen(sysroot_dir))) + return true; + + return false; +} + +static inline bool +pkgconf_fragment_is_special(const char *string) +{ + if (*string != '-') + return true; + + if (!strncmp(string, "-lib:", 5)) + return true; + + return pkgconf_fragment_is_unmergeable(string); +} + +static inline void +pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir) +{ + *buf = '\0'; + + if (sysroot_dir == NULL) + sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir"); + + if (sysroot_dir != NULL && pkgconf_fragment_should_munge(source, sysroot_dir)) + pkgconf_strlcat(buf, sysroot_dir, buflen); + + pkgconf_strlcat(buf, source, buflen); + + if (*buf == '/' && !(client->flags & PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS)) + pkgconf_path_relocate(buf, buflen); +} + +static inline char * +pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source) +{ + char mungebuf[PKGCONF_ITEM_SIZE]; + pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir); + return strdup(mungebuf); +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string) + * + * Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set. + * + * :param pkgconf_client_t* client: The pkgconf client being accessed. + * :param pkgconf_list_t* list: The fragment list. + * :param char* string: The string of text to add as a fragment to the fragment list. + * :return: nothing + */ +void +pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string) +{ + pkgconf_fragment_t *frag; + + if (*string == '\0') + return; + + if (!pkgconf_fragment_is_special(string)) + { + frag = calloc(sizeof(pkgconf_fragment_t), 1); + + frag->type = *(string + 1); + frag->data = pkgconf_fragment_copy_munged(client, string + 2); + + PKGCONF_TRACE(client, "added fragment {%c, '%s'} to list @%p", frag->type, frag->data, list); + } + else + { + char mungebuf[PKGCONF_ITEM_SIZE]; + + if (list->tail != NULL && list->tail->data != NULL && + !(client->flags & PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS)) + { + pkgconf_fragment_t *parent = list->tail->data; + + /* only attempt to merge 'special' fragments together */ + if (!parent->type && pkgconf_fragment_is_unmergeable(parent->data)) + { + size_t len; + char *newdata; + + pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL); + + len = strlen(parent->data) + strlen(mungebuf) + 2; + newdata = malloc(len); + + pkgconf_strlcpy(newdata, parent->data, len); + pkgconf_strlcat(newdata, " ", len); + pkgconf_strlcat(newdata, mungebuf, len); + + PKGCONF_TRACE(client, "merging '%s' to '%s' to form fragment {'%s'} in list @%p", mungebuf, parent->data, newdata, list); + + free(parent->data); + parent->data = newdata; + parent->merged = true; + + /* use a copy operation to force a dedup */ + pkgconf_node_delete(&parent->iter, list); + pkgconf_fragment_copy(client, list, parent, false); + + /* the fragment list now (maybe) has the copied node, so free the original */ + free(parent->data); + free(parent); + + return; + } + } + + frag = calloc(sizeof(pkgconf_fragment_t), 1); + + frag->type = 0; + frag->data = strdup(string); + + PKGCONF_TRACE(client, "created special fragment {'%s'} in list @%p", frag->data, list); + } + + pkgconf_node_insert_tail(&frag->iter, frag, list); +} + +static inline pkgconf_fragment_t * +pkgconf_fragment_lookup(pkgconf_list_t *list, const pkgconf_fragment_t *base) +{ + pkgconf_node_t *node; + + PKGCONF_FOREACH_LIST_ENTRY_REVERSE(list->tail, node) + { + pkgconf_fragment_t *frag = node->data; + + if (base->type != frag->type) + continue; + + if (!strcmp(base->data, frag->data)) + return frag; + } + + return NULL; +} + +static inline bool +pkgconf_fragment_can_merge_back(const pkgconf_fragment_t *base, unsigned int flags, bool is_private) +{ + (void) flags; + + if (base->type == 'l') + { + if (is_private) + return false; + + return true; + } + + if (base->type == 'F') + return false; + if (base->type == 'L') + return false; + if (base->type == 'I') + return false; + + return true; +} + +static inline bool +pkgconf_fragment_can_merge(const pkgconf_fragment_t *base, unsigned int flags, bool is_private) +{ + (void) flags; + + if (is_private) + return false; + + return pkgconf_fragment_is_unmergeable(base->data); +} + +static inline pkgconf_fragment_t * +pkgconf_fragment_exists(pkgconf_list_t *list, const pkgconf_fragment_t *base, unsigned int flags, bool is_private) +{ + if (!pkgconf_fragment_can_merge_back(base, flags, is_private)) + return NULL; + + if (!pkgconf_fragment_can_merge(base, flags, is_private)) + return NULL; + + return pkgconf_fragment_lookup(list, base); +} + +static inline bool +pkgconf_fragment_should_merge(const pkgconf_fragment_t *base) +{ + const pkgconf_fragment_t *parent; + + /* if we are the first fragment, that means the next fragment is the same, so it's always safe. */ + if (base->iter.prev == NULL) + return true; + + /* this really shouldn't ever happen, but handle it */ + parent = base->iter.prev->data; + if (parent == NULL) + return true; + + switch (parent->type) + { + case 'l': + case 'L': + case 'I': + return true; + default: + return !base->type || parent->type == base->type; + } +} + +/* + * !doc + * + * .. c:function:: bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag) + * + * Checks if a `fragment` contains a `system path`. System paths are detected at compile time and optionally overridden by + * the ``PKG_CONFIG_SYSTEM_INCLUDE_PATH`` and ``PKG_CONFIG_SYSTEM_LIBRARY_PATH`` environment variables. + * + * :param pkgconf_client_t* client: The pkgconf client object the fragment belongs to. + * :param pkgconf_fragment_t* frag: The fragment being checked. + * :return: true if the fragment contains a system path, else false + * :rtype: bool + */ +bool +pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag) +{ + const pkgconf_list_t *check_paths = NULL; + + switch (frag->type) + { + case 'L': + check_paths = &client->filter_libdirs; + break; + case 'I': + check_paths = &client->filter_includedirs; + break; + default: + return false; + } + + return pkgconf_path_match_list(frag->data, check_paths); +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private) + * + * Copies a `fragment` to another `fragment list`, possibly removing a previous copy of the `fragment` + * in a process known as `mergeback`. + * + * :param pkgconf_client_t* client: The pkgconf client being accessed. + * :param pkgconf_list_t* list: The list the fragment is being added to. + * :param pkgconf_fragment_t* base: The fragment being copied. + * :param bool is_private: Whether the fragment list is a `private` fragment list (static linking). + * :return: nothing + */ +void +pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private) +{ + pkgconf_fragment_t *frag; + + if ((frag = pkgconf_fragment_exists(list, base, client->flags, is_private)) != NULL) + { + if (pkgconf_fragment_should_merge(frag)) + pkgconf_fragment_delete(list, frag); + } + else if (!is_private && !pkgconf_fragment_can_merge_back(base, client->flags, is_private) && (pkgconf_fragment_lookup(list, base) != NULL)) + return; + + frag = calloc(sizeof(pkgconf_fragment_t), 1); + + frag->type = base->type; + frag->merged = base->merged; + if (base->data != NULL) + frag->data = strdup(base->data); + + pkgconf_node_insert_tail(&frag->iter, frag, list); +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base) + * + * Copies a `fragment list` to another `fragment list`, possibly removing a previous copy of the fragments + * in a process known as `mergeback`. + * + * :param pkgconf_client_t* client: The pkgconf client being accessed. + * :param pkgconf_list_t* list: The list the fragments are being added to. + * :param pkgconf_list_t* base: The list the fragments are being copied from. + * :return: nothing + */ +void +pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base) +{ + pkgconf_node_t *node; + + PKGCONF_FOREACH_LIST_ENTRY(base->head, node) + { + pkgconf_fragment_t *frag = node->data; + + pkgconf_fragment_copy(client, list, frag, true); + } +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func) + * + * Copies a `fragment list` to another `fragment list` which match a user-specified filtering function. + * + * :param pkgconf_client_t* client: The pkgconf client being accessed. + * :param pkgconf_list_t* dest: The destination list. + * :param pkgconf_list_t* src: The source list. + * :param pkgconf_fragment_filter_func_t filter_func: The filter function to use. + * :param void* data: Optional data to pass to the filter function. + * :return: nothing + */ +void +pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data) +{ + pkgconf_node_t *node; + + PKGCONF_FOREACH_LIST_ENTRY(src->head, node) + { + pkgconf_fragment_t *frag = node->data; + + if (filter_func(client, frag, data)) + pkgconf_fragment_copy(client, dest, frag, true); + } +} + +static inline char * +fragment_quote(const pkgconf_fragment_t *frag) +{ + const char *src = frag->data; + ssize_t outlen = strlen(src) + 10; + char *out, *dst; + + if (frag->data == NULL) + return NULL; + + out = dst = calloc(outlen, 1); + + for (; *src; src++) + { + if (((*src < ' ') || + (*src >= (' ' + (frag->merged ? 1 : 0)) && *src < '$') || + (*src > '$' && *src < '(') || + (*src > ')' && *src < '+') || + (*src > ':' && *src < '=') || + (*src > '=' && *src < '@') || + (*src > 'Z' && *src < '^') || + (*src == '`') || + (*src > 'z' && *src < '~') || + (*src > '~'))) + *dst++ = '\\'; + + *dst++ = *src; + + if ((ptrdiff_t)(dst - out) + 2 > outlen) + { + outlen *= 2; + out = realloc(out, outlen); + } + } + + *dst = 0; + return out; +} + +static inline size_t +pkgconf_fragment_len(const pkgconf_fragment_t *frag) +{ + size_t len = 1; + + if (frag->type) + len += 2; + + if (frag->data != NULL) + { + char *quoted = fragment_quote(frag); + len += strlen(quoted); + free(quoted); + } + + return len; +} + +static size_t +fragment_render_len(const pkgconf_list_t *list, bool escape) +{ + (void) escape; + + size_t out = 1; /* trailing nul */ + pkgconf_node_t *node; + + PKGCONF_FOREACH_LIST_ENTRY(list->head, node) + { + const pkgconf_fragment_t *frag = node->data; + out += pkgconf_fragment_len(frag); + } + + return out; +} + +static void +fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape) +{ + (void) escape; + + pkgconf_node_t *node; + char *bptr = buf; + + memset(buf, 0, buflen); + + PKGCONF_FOREACH_LIST_ENTRY(list->head, node) + { + const pkgconf_fragment_t *frag = node->data; + size_t buf_remaining = buflen - (bptr - buf); + char *quoted = fragment_quote(frag); + + if (strlen(quoted) > buf_remaining) + { + free(quoted); + break; + } + + if (frag->type) + { + *bptr++ = '-'; + *bptr++ = frag->type; + } + + if (quoted != NULL) + { + bptr += pkgconf_strlcpy(bptr, quoted, buf_remaining); + free(quoted); + } + + *bptr++ = ' '; + } + + *bptr = '\0'; +} + +static const pkgconf_fragment_render_ops_t default_render_ops = { + .render_len = fragment_render_len, + .render_buf = fragment_render_buf +}; + +/* + * !doc + * + * .. c:function:: size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops) + * + * Calculates the required memory to store a `fragment list` when rendered as a string. + * + * :param pkgconf_list_t* list: The `fragment list` being rendered. + * :param bool escape: Whether or not to escape special shell characters (deprecated). + * :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``. + * :return: the amount of bytes required to represent the `fragment list` when rendered + * :rtype: size_t + */ +size_t +pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops) +{ + (void) escape; + + ops = ops != NULL ? ops : &default_render_ops; + return ops->render_len(list, true); +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops) + * + * Renders a `fragment list` into a buffer. + * + * :param pkgconf_list_t* list: The `fragment list` being rendered. + * :param char* buf: The buffer to render the fragment list into. + * :param size_t buflen: The length of the buffer. + * :param bool escape: Whether or not to escape special shell characters (deprecated). + * :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``. + * :return: nothing + */ +void +pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t buflen, bool escape, const pkgconf_fragment_render_ops_t *ops) +{ + (void) escape; + + ops = ops != NULL ? ops : &default_render_ops; + ops->render_buf(list, buf, buflen, true); +} + +/* + * !doc + * + * .. c:function:: char *pkgconf_fragment_render(const pkgconf_list_t *list) + * + * Allocate memory and render a `fragment list` into it. + * + * :param pkgconf_list_t* list: The `fragment list` being rendered. + * :param bool escape: Whether or not to escape special shell characters (deprecated). + * :param pkgconf_fragment_render_ops_t* ops: An optional ops structure to use for custom renderers, else ``NULL``. + * :return: An allocated string containing the rendered `fragment list`. + * :rtype: char * + */ +char * +pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops) +{ + (void) escape; + + size_t buflen = pkgconf_fragment_render_len(list, true, ops); + char *buf = calloc(1, buflen); + + pkgconf_fragment_render_buf(list, buf, buflen, true, ops); + + return buf; +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node) + * + * Delete a `fragment node` from a `fragment list`. + * + * :param pkgconf_list_t* list: The `fragment list` to delete from. + * :param pkgconf_fragment_t* node: The `fragment node` to delete. + * :return: nothing + */ +void +pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node) +{ + pkgconf_node_delete(&node->iter, list); + + free(node->data); + free(node); +} + +/* + * !doc + * + * .. c:function:: void pkgconf_fragment_free(pkgconf_list_t *list) + * + * Delete an entire `fragment list`. + * + * :param pkgconf_list_t* list: The `fragment list` to delete. + * :return: nothing + */ +void +pkgconf_fragment_free(pkgconf_list_t *list) +{ + pkgconf_node_t *node, *next; + + PKGCONF_FOREACH_LIST_ENTRY_SAFE(list->head, next, node) + { + pkgconf_fragment_t *frag = node->data; + + free(frag->data); + free(frag); + } +} + +/* + * !doc + * + * .. c:function:: bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value) + * + * Parse a string into a `fragment list`. + * + * :param pkgconf_client_t* client: The pkgconf client being accessed. + * :param pkgconf_list_t* list: The `fragment list` to add the fragment entries to. + * :param pkgconf_list_t* vars: A list of variables to use for variable substitution. + * :param char* value: The string to parse into fragments. + * :return: true on success, false on parse error + */ +bool +pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value) +{ + int i, ret, argc; + char **argv; + char *repstr = pkgconf_tuple_parse(client, vars, value); + + PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr); + + ret = pkgconf_argv_split(repstr, &argc, &argv); + if (ret < 0) + { + PKGCONF_TRACE(client, "unable to parse fragment string [%s]", repstr); + free(repstr); + return false; + } + + for (i = 0; i < argc; i++) + { + if (argv[i] == NULL) + { + PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i); + pkgconf_argv_free(argv); + free(repstr); + return false; + } + + pkgconf_fragment_add(client, list, argv[i]); + } + + pkgconf_argv_free(argv); + free(repstr); + + return true; +} diff --git a/libpkgconf/libpkgconf/fragment.c.orig b/libpkgconf/libpkgconf/fragment.c.orig new file mode 120000 index 0000000..ccec352 --- /dev/null +++ b/libpkgconf/libpkgconf/fragment.c.orig @@ -0,0 +1 @@ +../../upstream/libpkgconf/fragment.c \ No newline at end of file diff --git a/libpkgconf/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf/libpkgconf.h deleted file mode 120000 index b885e88..0000000 --- a/libpkgconf/libpkgconf/libpkgconf.h +++ /dev/null @@ -1 +0,0 @@ -../../upstream/libpkgconf/libpkgconf.h \ No newline at end of file diff --git a/libpkgconf/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf/libpkgconf.h new file mode 100644 index 0000000..6f4c8b5 --- /dev/null +++ b/libpkgconf/libpkgconf/libpkgconf.h @@ -0,0 +1,388 @@ +/* + * libpkgconf.h + * Global include file for everything in libpkgconf. + * + * Copyright (c) 2011, 2015 pkgconf authors (see AUTHORS). + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +#ifndef LIBPKGCONF__LIBPKGCONF_H +#define LIBPKGCONF__LIBPKGCONF_H + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* pkg-config uses ';' on win32 as ':' is part of path */ +#ifdef _WIN32 +#define PKG_CONFIG_PATH_SEP_S ";" +#else +#define PKG_CONFIG_PATH_SEP_S ":" +#endif + +#ifdef _WIN32 +#define PKG_DIR_SEP_S '\\' +#else +#define PKG_DIR_SEP_S '/' +#endif + +#ifdef _WIN32 +#define realpath(N,R) _fullpath((R),(N),_MAX_PATH) +#endif + +#define PKGCONF_BUFSIZE (65535) + +typedef enum { + PKGCONF_CMP_NOT_EQUAL, + PKGCONF_CMP_ANY, + PKGCONF_CMP_LESS_THAN, + PKGCONF_CMP_LESS_THAN_EQUAL, + PKGCONF_CMP_EQUAL, + PKGCONF_CMP_GREATER_THAN, + PKGCONF_CMP_GREATER_THAN_EQUAL +} pkgconf_pkg_comparator_t; + +#define PKGCONF_CMP_COUNT 7 + +typedef struct pkgconf_pkg_ pkgconf_pkg_t; +typedef struct pkgconf_dependency_ pkgconf_dependency_t; +typedef struct pkgconf_tuple_ pkgconf_tuple_t; +typedef struct pkgconf_fragment_ pkgconf_fragment_t; +typedef struct pkgconf_path_ pkgconf_path_t; +typedef struct pkgconf_client_ pkgconf_client_t; +typedef struct pkgconf_cross_personality_ pkgconf_cross_personality_t; + +#define PKGCONF_ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + +#define PKGCONF_FOREACH_LIST_ENTRY(head, value) \ + for ((value) = (head); (value) != NULL; (value) = (value)->next) + +#define PKGCONF_FOREACH_LIST_ENTRY_SAFE(head, nextiter, value) \ + for ((value) = (head), (nextiter) = (head) != NULL ? (head)->next : NULL; (value) != NULL; (value) = (nextiter), (nextiter) = (nextiter) != NULL ? (nextiter)->next : NULL) + +#define PKGCONF_FOREACH_LIST_ENTRY_REVERSE(tail, value) \ + for ((value) = (tail); (value) != NULL; (value) = (value)->prev) + +#define LIBPKGCONF_VERSION 10603 +#define LIBPKGCONF_VERSION_STR "1.6.3" + +struct pkgconf_fragment_ { + pkgconf_node_t iter; + + char type; + char *data; + + bool merged; +}; + +struct pkgconf_dependency_ { + pkgconf_node_t iter; + + char *package; + pkgconf_pkg_comparator_t compare; + char *version; + pkgconf_pkg_t *parent; + pkgconf_pkg_t *match; + + unsigned int flags; +}; + +struct pkgconf_tuple_ { + pkgconf_node_t iter; + + char *key; + char *value; +}; + +struct pkgconf_path_ { + pkgconf_node_t lnode; + + char *path; + void *handle_path; + void *handle_device; +}; + +#define PKGCONF_PKG_PROPF_NONE 0x00 +#define PKGCONF_PKG_PROPF_STATIC 0x01 +#define PKGCONF_PKG_PROPF_CACHED 0x02 +#define PKGCONF_PKG_PROPF_SEEN 0x04 +#define PKGCONF_PKG_PROPF_UNINSTALLED 0x08 +#define PKGCONF_PKG_PROPF_VIRTUAL 0x10 + +struct pkgconf_pkg_ { + pkgconf_node_t cache_iter; + + int refcount; + char *id; + char *filename; + char *realname; + char *version; + char *description; + char *url; + char *pc_filedir; + + pkgconf_list_t libs; + pkgconf_list_t libs_private; + pkgconf_list_t cflags; + pkgconf_list_t cflags_private; + + pkgconf_list_t required; /* this used to be requires but that is now a reserved keyword */ + pkgconf_list_t requires_private; + pkgconf_list_t conflicts; + pkgconf_list_t provides; + + pkgconf_list_t vars; + + unsigned int flags; + + pkgconf_client_t *owner; + + /* these resources are owned by the package and do not need special management, + * under no circumstance attempt to allocate or free objects belonging to these pointers + */ + pkgconf_tuple_t *orig_prefix; + pkgconf_tuple_t *prefix; +}; + +typedef bool (*pkgconf_pkg_iteration_func_t)(const pkgconf_pkg_t *pkg, void *data); +typedef void (*pkgconf_pkg_traverse_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *pkg, void *data); +typedef bool (*pkgconf_queue_apply_func_t)(pkgconf_client_t *client, pkgconf_pkg_t *world, void *data, int maxdepth); +typedef bool (*pkgconf_error_handler_func_t)(const char *msg, const pkgconf_client_t *client, const void *data); + +struct pkgconf_client_ { + pkgconf_list_t dir_list; + pkgconf_list_t pkg_cache; + + pkgconf_list_t filter_libdirs; + pkgconf_list_t filter_includedirs; + + pkgconf_list_t global_vars; + + void *error_handler_data; + void *warn_handler_data; + void *trace_handler_data; + + pkgconf_error_handler_func_t error_handler; + pkgconf_error_handler_func_t warn_handler; + pkgconf_error_handler_func_t trace_handler; + + FILE *auditf; + + char *sysroot_dir; + char *buildroot_dir; + + unsigned int flags; + + char *prefix_varname; + + bool already_sent_notice; +}; + +struct pkgconf_cross_personality_ { + const char *name; + + pkgconf_list_t dir_list; + + pkgconf_list_t filter_libdirs; + pkgconf_list_t filter_includedirs; + + char *sysroot_dir; +}; + +/* client.c */ +PKGCONF_API void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality); +PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data, const pkgconf_cross_personality_t *personality); +PKGCONF_API void pkgconf_client_deinit(pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_free(pkgconf_client_t *client); +PKGCONF_API const char *pkgconf_client_get_sysroot_dir(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_sysroot_dir(pkgconf_client_t *client, const char *sysroot_dir); +PKGCONF_API const char *pkgconf_client_get_buildroot_dir(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_buildroot_dir(pkgconf_client_t *client, const char *buildroot_dir); +PKGCONF_API unsigned int pkgconf_client_get_flags(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_flags(pkgconf_client_t *client, unsigned int flags); +PKGCONF_API const char *pkgconf_client_get_prefix_varname(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_prefix_varname(pkgconf_client_t *client, const char *prefix_varname); +PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_warn_handler(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_warn_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t warn_handler, void *warn_handler_data); +PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_error_handler(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_error_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data); +PKGCONF_API pkgconf_error_handler_func_t pkgconf_client_get_trace_handler(const pkgconf_client_t *client); +PKGCONF_API void pkgconf_client_set_trace_handler(pkgconf_client_t *client, pkgconf_error_handler_func_t trace_handler, void *trace_handler_data); +PKGCONF_API void pkgconf_client_dir_list_build(pkgconf_client_t *client, const pkgconf_cross_personality_t *personality); + +/* personality.c */ +PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_default(void); +PKGCONF_API pkgconf_cross_personality_t *pkgconf_cross_personality_find(const char *triplet); + +#define PKGCONF_IS_MODULE_SEPARATOR(c) ((c) == ',' || isspace ((unsigned int)(c))) +#define PKGCONF_IS_OPERATOR_CHAR(c) ((c) == '<' || (c) == '>' || (c) == '!' || (c) == '=') + +#define PKGCONF_PKG_PKGF_NONE 0x0000 +#define PKGCONF_PKG_PKGF_SEARCH_PRIVATE 0x0001 +#define PKGCONF_PKG_PKGF_ENV_ONLY 0x0002 +#define PKGCONF_PKG_PKGF_NO_UNINSTALLED 0x0004 +#define PKGCONF_PKG_PKGF_SKIP_ROOT_VIRTUAL 0x0008 +#define PKGCONF_PKG_PKGF_MERGE_PRIVATE_FRAGMENTS 0x0010 +#define PKGCONF_PKG_PKGF_SKIP_CONFLICTS 0x0020 +#define PKGCONF_PKG_PKGF_NO_CACHE 0x0040 +#define PKGCONF_PKG_PKGF_SKIP_ERRORS 0x0080 +#define PKGCONF_PKG_PKGF_ITER_PKG_IS_PRIVATE 0x0100 +#define PKGCONF_PKG_PKGF_SKIP_PROVIDES 0x0200 +#define PKGCONF_PKG_PKGF_REDEFINE_PREFIX 0x0400 +#define PKGCONF_PKG_PKGF_DONT_RELOCATE_PATHS 0x0800 +#define PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS 0x1000 +#define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000 +#define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000 + +#define PKGCONF_PKG_DEPF_INTERNAL 0x1 + +#define PKGCONF_PKG_ERRF_OK 0x0 +#define PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND 0x1 +#define PKGCONF_PKG_ERRF_PACKAGE_VER_MISMATCH 0x2 +#define PKGCONF_PKG_ERRF_PACKAGE_CONFLICT 0x4 +#define PKGCONF_PKG_ERRF_DEPGRAPH_BREAK 0x8 + +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define PRINTFLIKE(fmtarg, firstvararg) \ + __attribute__((__format__ (__printf__, fmtarg, firstvararg))) +#define DEPRECATED \ + __attribute__((deprecated)) +#else +#define PRINTFLIKE(fmtarg, firstvararg) +#define DEPRECATED +#endif /* defined(__INTEL_COMPILER) || defined(__GNUC__) */ + +/* parser.c */ +typedef void (*pkgconf_parser_operand_func_t)(void *data, const size_t lineno, const char *key, const char *value); +typedef void (*pkgconf_parser_warn_func_t)(void *data, const char *fmt, ...); + +PKGCONF_API void pkgconf_parser_parse(FILE *f, void *data, const pkgconf_parser_operand_func_t *ops, const pkgconf_parser_warn_func_t warnfunc, const char *filename); + +/* pkg.c */ +PKGCONF_API bool pkgconf_error(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); +PKGCONF_API bool pkgconf_warn(const pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); +PKGCONF_API bool pkgconf_trace(const pkgconf_client_t *client, const char *filename, size_t lineno, const char *funcname, const char *format, ...) PRINTFLIKE(5, 6); +PKGCONF_API bool pkgconf_default_error_handler(const char *msg, const pkgconf_client_t *client, const void *data); + +#ifndef PKGCONF_LITE +#if defined(__GNUC__) || defined(__INTEL_COMPILER) +#define PKGCONF_TRACE(client, ...) do { \ + pkgconf_trace(client, __FILE__, __LINE__, __PRETTY_FUNCTION__, __VA_ARGS__); \ + } while (0); +#else +#define PKGCONF_TRACE(client, ...) do { \ + pkgconf_trace(client, __FILE__, __LINE__, __func__, __VA_ARGS__); \ + } while (0); +#endif +#else +#define PKGCONF_TRACE(client, ...) +#endif + +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_ref(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_pkg_unref(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_find(pkgconf_client_t *client, const char *name); +PKGCONF_API unsigned int pkgconf_pkg_traverse(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_pkg_traverse_func_t func, void *data, int maxdepth, unsigned int skip_flags); +PKGCONF_API unsigned int pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int depth); +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_verify_dependency(pkgconf_client_t *client, pkgconf_dependency_t *pkgdep, unsigned int *eflags); +PKGCONF_API const char *pkgconf_pkg_get_comparator(const pkgconf_dependency_t *pkgdep); +PKGCONF_API unsigned int pkgconf_pkg_cflags(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth); +PKGCONF_API unsigned int pkgconf_pkg_libs(pkgconf_client_t *client, pkgconf_pkg_t *root, pkgconf_list_t *list, int maxdepth); +PKGCONF_API pkgconf_pkg_comparator_t pkgconf_pkg_comparator_lookup_by_name(const char *name); +PKGCONF_API pkgconf_pkg_t *pkgconf_builtin_pkg_get(const char *name); + +PKGCONF_API int pkgconf_compare_version(const char *a, const char *b); +PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func); + +/* parse.c */ +PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f); +PKGCONF_API void pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags); +PKGCONF_API void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags); +PKGCONF_API void pkgconf_dependency_append(pkgconf_list_t *list, pkgconf_dependency_t *tail); +PKGCONF_API void pkgconf_dependency_free(pkgconf_list_t *list); +PKGCONF_API pkgconf_dependency_t *pkgconf_dependency_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, const char *version, pkgconf_pkg_comparator_t compare, unsigned int flags); + +/* argvsplit.c */ +PKGCONF_API int pkgconf_argv_split(const char *src, int *argc, char ***argv); +PKGCONF_API void pkgconf_argv_free(char **argv); + +/* fragment.c */ +typedef struct pkgconf_fragment_render_ops_ { + size_t (*render_len)(const pkgconf_list_t *list, bool escape); + void (*render_buf)(const pkgconf_list_t *list, char *buf, size_t len, bool escape); +} pkgconf_fragment_render_ops_t; + +typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data); +PKGCONF_API bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value); +PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string); +PKGCONF_API void pkgconf_fragment_copy(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_fragment_t *base, bool is_private); +PKGCONF_API void pkgconf_fragment_copy_list(const pkgconf_client_t *client, pkgconf_list_t *list, const pkgconf_list_t *base); +PKGCONF_API void pkgconf_fragment_delete(pkgconf_list_t *list, pkgconf_fragment_t *node); +PKGCONF_API void pkgconf_fragment_free(pkgconf_list_t *list); +PKGCONF_API void pkgconf_fragment_filter(const pkgconf_client_t *client, pkgconf_list_t *dest, pkgconf_list_t *src, pkgconf_fragment_filter_func_t filter_func, void *data); +PKGCONF_API size_t pkgconf_fragment_render_len(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops); +PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape, const pkgconf_fragment_render_ops_t *ops); +PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape, const pkgconf_fragment_render_ops_t *ops); +PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client, const pkgconf_fragment_t *frag); + +/* fileio.c */ +PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream); + +/* tuple.c */ +PKGCONF_API pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse); +PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key); +PKGCONF_API char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value); +PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list); +PKGCONF_API void pkgconf_tuple_free_entry(pkgconf_tuple_t *tuple, pkgconf_list_t *list); +PKGCONF_API void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value); +PKGCONF_API char *pkgconf_tuple_find_global(const pkgconf_client_t *client, const char *key); +PKGCONF_API void pkgconf_tuple_free_global(pkgconf_client_t *client); +PKGCONF_API void pkgconf_tuple_define_global(pkgconf_client_t *client, const char *kv); + +/* queue.c */ +PKGCONF_API void pkgconf_queue_push(pkgconf_list_t *list, const char *package); +PKGCONF_API bool pkgconf_queue_compile(pkgconf_client_t *client, pkgconf_pkg_t *world, pkgconf_list_t *list); +PKGCONF_API void pkgconf_queue_free(pkgconf_list_t *list); +PKGCONF_API bool pkgconf_queue_apply(pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_queue_apply_func_t func, int maxdepth, void *data); +PKGCONF_API bool pkgconf_queue_validate(pkgconf_client_t *client, pkgconf_list_t *list, int maxdepth); + +/* cache.c */ +PKGCONF_API pkgconf_pkg_t *pkgconf_cache_lookup(pkgconf_client_t *client, const char *id); +PKGCONF_API void pkgconf_cache_add(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_cache_remove(pkgconf_client_t *client, pkgconf_pkg_t *pkg); +PKGCONF_API void pkgconf_cache_free(pkgconf_client_t *client); + +/* audit.c */ +PKGCONF_API void pkgconf_audit_set_log(pkgconf_client_t *client, FILE *auditf); +PKGCONF_API void pkgconf_audit_log(pkgconf_client_t *client, const char *format, ...) PRINTFLIKE(2, 3); +PKGCONF_API void pkgconf_audit_log_dependency(pkgconf_client_t *client, const pkgconf_pkg_t *dep, const pkgconf_dependency_t *depnode); + +/* path.c */ +PKGCONF_API void pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API size_t pkgconf_path_split(const char *text, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API size_t pkgconf_path_build_from_environ(const char *envvarname, const char *fallback, pkgconf_list_t *dirlist, bool filter); +PKGCONF_API bool pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist); +PKGCONF_API void pkgconf_path_free(pkgconf_list_t *dirlist); +PKGCONF_API bool pkgconf_path_relocate(char *buf, size_t buflen); +PKGCONF_API void pkgconf_path_copy_list(pkgconf_list_t *dst, const pkgconf_list_t *src); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libpkgconf/libpkgconf/libpkgconf.h.orig b/libpkgconf/libpkgconf/libpkgconf.h.orig new file mode 120000 index 0000000..b885e88 --- /dev/null +++ b/libpkgconf/libpkgconf/libpkgconf.h.orig @@ -0,0 +1 @@ +../../upstream/libpkgconf/libpkgconf.h \ No newline at end of file diff --git a/libpkgconf/manifest b/libpkgconf/manifest index 267bea1..af0394f 100644 --- a/libpkgconf/manifest +++ b/libpkgconf/manifest @@ -1,6 +1,6 @@ : 1 name: libpkgconf -version: 1.6.3+1 +version: 1.6.3+2 project: pkgconf summary: C library for retriving pkg-config compiler and linker flags license: ISC, MIT ; ISC for the most of original files. diff --git a/libpkgconf/tests/api/driver.c b/libpkgconf/tests/api/driver.c index 57f989d..6035771 100644 --- a/libpkgconf/tests/api/driver.c +++ b/libpkgconf/tests/api/driver.c @@ -130,7 +130,7 @@ main (int argc, const char* argv[]) int r = 1; int max_depth = 2000; - pkgconf_client_set_flags (c, 0); + pkgconf_client_set_flags (c, PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS); pkgconf_pkg_t* p = pkgconf_pkg_find (c, path); if (p != NULL) diff --git a/libpkgconf/tests/api/testscript b/libpkgconf/tests/api/testscript index dfada71..0382f87 100644 --- a/libpkgconf/tests/api/testscript +++ b/libpkgconf/tests/api/testscript @@ -114,9 +114,9 @@ EOO } -: merged +: no-merge : -: Note that we want the merged options to be eventually separated. +: Test that the -framework options are not merged into a single fragment. : { +cat <=libfoo.pc @@ -137,6 +137,9 @@ l ssl l crypto l z - -framework CoreFoundation -framework Security + -framework + CoreFoundation + -framework + Security EOO } -- cgit v1.1