Compare commits

...

6 Commits

9 changed files with 164 additions and 57 deletions

View File

@ -61,6 +61,7 @@ EXTRA_DIST = pkg.m4 \
tests/lib3/bar.pc \ tests/lib3/bar.pc \
tests/lib1/conflicts.pc \ tests/lib1/conflicts.pc \
tests/lib1/omg-uninstalled.pc \ tests/lib1/omg-uninstalled.pc \
tests/lib1/omg-sysroot-uninstalled.pc \
tests/lib1/isystem.pc \ tests/lib1/isystem.pc \
tests/lib1/idirafter.pc \ tests/lib1/idirafter.pc \
tests/lib1/idirafter-ordering.pc \ tests/lib1/idirafter-ordering.pc \

View File

@ -1018,6 +1018,9 @@ main(int argc, char *argv[])
if (getenv("PKG_CONFIG_FDO_SYSROOT_RULES")) if (getenv("PKG_CONFIG_FDO_SYSROOT_RULES"))
want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES; want_client_flags |= PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES;
if (getenv("PKG_CONFIG_PKGCONF1_SYSROOT_RULES"))
want_client_flags |= PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES;
if ((want_flags & PKG_SHORT_ERRORS) == PKG_SHORT_ERRORS) if ((want_flags & PKG_SHORT_ERRORS) == PKG_SHORT_ERRORS)
want_client_flags |= PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS; want_client_flags |= PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS;

View File

@ -434,7 +434,7 @@ pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_h
void void
pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags) pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist, const char *depends, unsigned int flags)
{ {
char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends); char *kvdepends = pkgconf_tuple_parse(client, &pkg->vars, depends, pkg->flags);
pkgconf_dependency_parse_str(client, deplist, kvdepends, flags); pkgconf_dependency_parse_str(client, deplist, kvdepends, flags);
free(kvdepends); free(kvdepends);

View File

@ -93,15 +93,18 @@ pkgconf_fragment_is_special(const char *string)
} }
static inline void static inline void
pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir) pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen, const char *source, const char *sysroot_dir, unsigned int flags)
{ {
*buf = '\0'; *buf = '\0';
if (!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES))
{
if (sysroot_dir == NULL) if (sysroot_dir == NULL)
sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir"); sysroot_dir = pkgconf_tuple_find_global(client, "pc_sysrootdir");
if (sysroot_dir != NULL && pkgconf_fragment_should_munge(source, sysroot_dir)) if (sysroot_dir != NULL && pkgconf_fragment_should_munge(source, sysroot_dir))
pkgconf_strlcat(buf, sysroot_dir, buflen); pkgconf_strlcat(buf, sysroot_dir, buflen);
}
pkgconf_strlcat(buf, source, buflen); pkgconf_strlcat(buf, source, buflen);
@ -110,27 +113,28 @@ pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen,
} }
static inline char * static inline char *
pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source) pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source, unsigned int flags)
{ {
char mungebuf[PKGCONF_ITEM_SIZE]; char mungebuf[PKGCONF_ITEM_SIZE];
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir); pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir, flags);
return strdup(mungebuf); return strdup(mungebuf);
} }
/* /*
* !doc * !doc
* *
* .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string) * .. c:function:: void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
* *
* Adds a `fragment` of text to a `fragment list`, possibly modifying the fragment if a sysroot is set. * 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_client_t* client: The pkgconf client being accessed.
* :param pkgconf_list_t* list: The fragment list. * :param pkgconf_list_t* list: The fragment list.
* :param char* string: The string of text to add as a fragment to the fragment list. * :param char* string: The string of text to add as a fragment to the fragment list.
* :param uint flags: Parsing-related flags for the package.
* :return: nothing * :return: nothing
*/ */
void void
pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string) pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags)
{ {
pkgconf_fragment_t *frag; pkgconf_fragment_t *frag;
@ -142,7 +146,7 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
frag = calloc(sizeof(pkgconf_fragment_t), 1); frag = calloc(sizeof(pkgconf_fragment_t), 1);
frag->type = *(string + 1); frag->type = *(string + 1);
frag->data = pkgconf_fragment_copy_munged(client, string + 2); frag->data = pkgconf_fragment_copy_munged(client, string + 2, flags);
PKGCONF_TRACE(client, "added fragment {%c, '%s'} to list @%p", frag->type, frag->data, list); PKGCONF_TRACE(client, "added fragment {%c, '%s'} to list @%p", frag->type, frag->data, list);
} }
@ -161,7 +165,7 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
size_t len; size_t len;
char *newdata; char *newdata;
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL); pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, string, NULL, flags);
len = strlen(parent->data) + strlen(mungebuf) + 2; len = strlen(parent->data) + strlen(mungebuf) + 2;
newdata = malloc(len); newdata = malloc(len);
@ -663,15 +667,16 @@ pkgconf_fragment_free(pkgconf_list_t *list)
* :param pkgconf_client_t* client: The pkgconf client being accessed. * :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* 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 pkgconf_list_t* vars: A list of variables to use for variable substitution.
* :param uint flags: Any parsing flags to be aware of.
* :param char* value: The string to parse into fragments. * :param char* value: The string to parse into fragments.
* :return: true on success, false on parse error * :return: true on success, false on parse error
*/ */
bool bool
pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value) pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags)
{ {
int i, ret, argc; int i, ret, argc;
char **argv; char **argv;
char *repstr = pkgconf_tuple_parse(client, vars, value); char *repstr = pkgconf_tuple_parse(client, vars, value, flags);
PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr); PKGCONF_TRACE(client, "post-subst: [%s] -> [%s]", value, repstr);
@ -685,6 +690,8 @@ pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkg
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
{ {
PKGCONF_TRACE(client, "processing %s", argv[i]);
if (argv[i] == NULL) if (argv[i] == NULL)
{ {
PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i); PKGCONF_TRACE(client, "parsed fragment string is inconsistent: argc = %d while argv[%d] == NULL", argc, i);
@ -693,7 +700,7 @@ pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkg
return false; return false;
} }
pkgconf_fragment_add(client, list, argv[i]); pkgconf_fragment_add(client, list, argv[i], flags);
} }
pkgconf_argv_free(argv); pkgconf_argv_free(argv);

View File

@ -262,6 +262,7 @@ PKGCONF_API void pkgconf_cross_personality_deinit(pkgconf_cross_personality_t *p
#define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000 #define PKGCONF_PKG_PKGF_DONT_FILTER_INTERNAL_CFLAGS 0x2000
#define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000 #define PKGCONF_PKG_PKGF_DONT_MERGE_SPECIAL_FRAGMENTS 0x4000
#define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES 0x8000 #define PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES 0x8000
#define PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES 0x10000
#define PKGCONF_PKG_DEPF_INTERNAL 0x1 #define PKGCONF_PKG_DEPF_INTERNAL 0x1
@ -324,7 +325,7 @@ 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); PKGCONF_API pkgconf_pkg_t *pkgconf_scan_all(pkgconf_client_t *client, void *ptr, pkgconf_pkg_iteration_func_t func);
/* parse.c */ /* parse.c */
PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f); PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *path, FILE *f, unsigned int flags);
PKGCONF_API void pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags); PKGCONF_API void pkgconf_dependency_parse_str(pkgconf_client_t *client, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags);
PKGCONF_API void pkgconf_dependency_parse(pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends, unsigned int flags); PKGCONF_API void pkgconf_dependency_parse(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_append(pkgconf_list_t *list, pkgconf_dependency_t *tail);
@ -346,8 +347,8 @@ typedef struct pkgconf_fragment_render_ops_ {
} pkgconf_fragment_render_ops_t; } pkgconf_fragment_render_ops_t;
typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data); 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 bool pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value, unsigned int flags);
PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string); PKGCONF_API void pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *string, unsigned int flags);
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(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_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_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
@ -362,9 +363,9 @@ PKGCONF_API bool pkgconf_fragment_has_system_dir(const pkgconf_client_t *client,
PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream); PKGCONF_API char *pkgconf_fgetline(char *line, size_t size, FILE *stream);
/* tuple.c */ /* 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 pkgconf_tuple_t *pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *parent, const char *key, const char *value, bool parse, unsigned int flags);
PKGCONF_API char *pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key); 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 char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *list, const char *value, unsigned int flags);
PKGCONF_API void pkgconf_tuple_free(pkgconf_list_t *list); 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_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 void pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value);

View File

@ -92,7 +92,7 @@ pkgconf_pkg_parser_tuple_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, cons
(void) lineno; (void) lineno;
char **dest = (char **)((char *) pkg + offset); char **dest = (char **)((char *) pkg + offset);
*dest = pkgconf_tuple_parse(client, &pkg->vars, value); *dest = pkgconf_tuple_parse(client, &pkg->vars, value, pkg->flags);
} }
static void static void
@ -105,7 +105,7 @@ pkgconf_pkg_parser_version_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, co
char **dest = (char **)((char *) pkg + offset); char **dest = (char **)((char *) pkg + offset);
/* cut at any detected whitespace */ /* cut at any detected whitespace */
p = pkgconf_tuple_parse(client, &pkg->vars, value); p = pkgconf_tuple_parse(client, &pkg->vars, value, pkg->flags);
len = strcspn(p, " \t"); len = strcspn(p, " \t");
if (len != strlen(p)) if (len != strlen(p))
@ -124,7 +124,7 @@ static void
pkgconf_pkg_parser_fragment_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value) pkgconf_pkg_parser_fragment_func(pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, const char *value)
{ {
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset); pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value); bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value, pkg->flags);
if (!ret) if (!ret)
{ {
@ -312,10 +312,10 @@ pkgconf_pkg_parser_value_set(void *opaque, const size_t lineno, const char *keyw
pkgconf_strlcpy(newvalue, pkg->prefix->value, sizeof newvalue); pkgconf_strlcpy(newvalue, pkg->prefix->value, sizeof newvalue);
pkgconf_strlcat(newvalue, canonicalized_value + strlen(pkg->orig_prefix->value), sizeof newvalue); pkgconf_strlcat(newvalue, canonicalized_value + strlen(pkg->orig_prefix->value), sizeof newvalue);
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, newvalue, false); pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, newvalue, false, pkg->flags);
} }
else if (strcmp(keyword, pkg->owner->prefix_varname) || !(pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX)) else if (strcmp(keyword, pkg->owner->prefix_varname) || !(pkg->owner->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX))
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true); pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true, pkg->flags);
else else
{ {
char pathbuf[PKGCONF_ITEM_SIZE]; char pathbuf[PKGCONF_ITEM_SIZE];
@ -324,12 +324,12 @@ pkgconf_pkg_parser_value_set(void *opaque, const size_t lineno, const char *keyw
if (relvalue != NULL) if (relvalue != NULL)
{ {
char *prefix_value = convert_path_to_value(relvalue); char *prefix_value = convert_path_to_value(relvalue);
pkg->orig_prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, "orig_prefix", canonicalized_value, true); pkg->orig_prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, "orig_prefix", canonicalized_value, true, pkg->flags);
pkg->prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, prefix_value, false); pkg->prefix = pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, prefix_value, false, pkg->flags);
free(prefix_value); free(prefix_value);
} }
else else
pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true); pkgconf_tuple_add(pkg->owner, &pkg->vars, keyword, value, true, pkg->flags);
} }
} }
@ -387,18 +387,19 @@ pkgconf_pkg_validate(const pkgconf_client_t *client, const pkgconf_pkg_t *pkg)
/* /*
* !doc * !doc
* *
* .. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f) * .. c:function:: pkgconf_pkg_t *pkgconf_pkg_new_from_file(const pkgconf_client_t *client, const char *filename, FILE *f, unsigned int flags)
* *
* Parse a .pc file into a pkgconf_pkg_t object structure. * Parse a .pc file into a pkgconf_pkg_t object structure.
* *
* :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution. * :param pkgconf_client_t* client: The pkgconf client object to use for dependency resolution.
* :param char* filename: The filename of the package file (including full path). * :param char* filename: The filename of the package file (including full path).
* :param FILE* f: The file object to read from. * :param FILE* f: The file object to read from.
* :param uint flags: The flags to use when parsing.
* :returns: A ``pkgconf_pkg_t`` object which contains the package data. * :returns: A ``pkgconf_pkg_t`` object which contains the package data.
* :rtype: pkgconf_pkg_t * * :rtype: pkgconf_pkg_t *
*/ */
pkgconf_pkg_t * pkgconf_pkg_t *
pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *f) pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *f, unsigned int flags)
{ {
pkgconf_pkg_t *pkg; pkgconf_pkg_t *pkg;
char *idptr; char *idptr;
@ -407,9 +408,10 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
pkg->owner = client; pkg->owner = client;
pkg->filename = strdup(filename); pkg->filename = strdup(filename);
pkg->pc_filedir = pkg_get_parent_dir(pkg); pkg->pc_filedir = pkg_get_parent_dir(pkg);
pkg->flags = flags;
char *pc_filedir_value = convert_path_to_value(pkg->pc_filedir); char *pc_filedir_value = convert_path_to_value(pkg->pc_filedir);
pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pc_filedir_value, true); pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pc_filedir_value, true, pkg->flags);
free(pc_filedir_value); free(pc_filedir_value);
/* If pc_filedir is outside of sysroot_dir, override sysroot_dir for this /* If pc_filedir is outside of sysroot_dir, override sysroot_dir for this
@ -417,7 +419,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
* See https://github.com/pkgconf/pkgconf/issues/213 * See https://github.com/pkgconf/pkgconf/issues/213
*/ */
if (client->sysroot_dir && strncmp(pkg->pc_filedir, client->sysroot_dir, strlen(client->sysroot_dir))) if (client->sysroot_dir && strncmp(pkg->pc_filedir, client->sysroot_dir, strlen(client->sysroot_dir)))
pkgconf_tuple_add(client, &pkg->vars, "pc_sysrootdir", "", false); pkgconf_tuple_add(client, &pkg->vars, "pc_sysrootdir", "", false, pkg->flags);
/* make module id */ /* make module id */
if ((idptr = strrchr(pkg->filename, PKG_DIR_SEP_S)) != NULL) if ((idptr = strrchr(pkg->filename, PKG_DIR_SEP_S)) != NULL)
@ -579,14 +581,12 @@ pkgconf_pkg_try_specific_path(pkgconf_client_t *client, const char *path, const
if (!(client->flags & PKGCONF_PKG_PKGF_NO_UNINSTALLED) && (f = fopen(uninst_locbuf, "r")) != NULL) if (!(client->flags & PKGCONF_PKG_PKGF_NO_UNINSTALLED) && (f = fopen(uninst_locbuf, "r")) != NULL)
{ {
PKGCONF_TRACE(client, "found (uninstalled): %s", uninst_locbuf); PKGCONF_TRACE(client, "found (uninstalled): %s", uninst_locbuf);
pkg = pkgconf_pkg_new_from_file(client, uninst_locbuf, f); pkg = pkgconf_pkg_new_from_file(client, uninst_locbuf, f, PKGCONF_PKG_PROPF_UNINSTALLED);
if (pkg != NULL)
pkg->flags |= PKGCONF_PKG_PROPF_UNINSTALLED;
} }
else if ((f = fopen(locbuf, "r")) != NULL) else if ((f = fopen(locbuf, "r")) != NULL)
{ {
PKGCONF_TRACE(client, "found: %s", locbuf); PKGCONF_TRACE(client, "found: %s", locbuf);
pkg = pkgconf_pkg_new_from_file(client, locbuf, f); pkg = pkgconf_pkg_new_from_file(client, locbuf, f, 0);
} }
return pkg; return pkg;
@ -624,7 +624,7 @@ pkgconf_pkg_scan_dir(pkgconf_client_t *client, const char *path, void *data, pkg
if (f == NULL) if (f == NULL)
continue; continue;
pkg = pkgconf_pkg_new_from_file(client, filebuf, f); pkg = pkgconf_pkg_new_from_file(client, filebuf, f, 0);
if (pkg != NULL) if (pkg != NULL)
{ {
if (func(pkg, data)) if (func(pkg, data))
@ -744,7 +744,7 @@ pkgconf_pkg_find(pkgconf_client_t *client, const char *name)
PKGCONF_TRACE(client, "%s is a file", name); PKGCONF_TRACE(client, "%s is a file", name);
pkg = pkgconf_pkg_new_from_file(client, name, f); pkg = pkgconf_pkg_new_from_file(client, name, f, 0);
if (pkg != NULL) if (pkg != NULL)
{ {
pkgconf_path_add(pkg->pc_filedir, &client->dir_list, true); pkgconf_path_add(pkg->pc_filedir, &client->dir_list, true);

View File

@ -45,7 +45,7 @@
void void
pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value) pkgconf_tuple_add_global(pkgconf_client_t *client, const char *key, const char *value)
{ {
pkgconf_tuple_add(client, &client->global_vars, key, value, false); pkgconf_tuple_add(client, &client->global_vars, key, value, false, 0);
} }
/* /*
@ -161,6 +161,45 @@ dequote(const char *value)
return buf; return buf;
} }
static const char *
find_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars)
{
const char *sysroot_dir;
sysroot_dir = pkgconf_tuple_find(client, vars, "pc_sysrootdir");
if (sysroot_dir == NULL)
sysroot_dir = client->sysroot_dir;
return sysroot_dir;
}
static bool
should_rewrite_sysroot(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *buf, unsigned int flags)
{
const char *sysroot_dir;
if (flags & PKGCONF_PKG_PROPF_UNINSTALLED && !(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES))
return false;
sysroot_dir = find_sysroot(client, vars);
if (sysroot_dir == NULL)
return false;
if (*buf != '/')
return false;
if (!strcmp(sysroot_dir, "/"))
return false;
if (strlen(buf) <= strlen(sysroot_dir))
return false;
if (strstr(buf + strlen(sysroot_dir), sysroot_dir) == NULL)
return false;
return true;
}
/* /*
* !doc * !doc
* *
@ -177,7 +216,7 @@ dequote(const char *value)
* :rtype: pkgconf_tuple_t * * :rtype: pkgconf_tuple_t *
*/ */
pkgconf_tuple_t * pkgconf_tuple_t *
pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse) pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const char *key, const char *value, bool parse, unsigned int flags)
{ {
char *dequote_value; char *dequote_value;
pkgconf_tuple_t *tuple = calloc(sizeof(pkgconf_tuple_t), 1); pkgconf_tuple_t *tuple = calloc(sizeof(pkgconf_tuple_t), 1);
@ -186,14 +225,14 @@ pkgconf_tuple_add(const pkgconf_client_t *client, pkgconf_list_t *list, const ch
dequote_value = dequote(value); dequote_value = dequote(value);
PKGCONF_TRACE(client, "adding tuple to @%p: %s => %s (parsed? %d)", list, key, dequote_value, parse);
tuple->key = strdup(key); tuple->key = strdup(key);
if (parse) if (parse)
tuple->value = pkgconf_tuple_parse(client, list, dequote_value); tuple->value = pkgconf_tuple_parse(client, list, dequote_value, flags);
else else
tuple->value = strdup(dequote_value); tuple->value = strdup(dequote_value);
PKGCONF_TRACE(client, "adding tuple to @%p: %s => %s (parsed? %d)", list, key, tuple->value, parse);
pkgconf_node_insert(&tuple->iter, tuple, list); pkgconf_node_insert(&tuple->iter, tuple, list);
free(dequote_value); free(dequote_value);
@ -233,24 +272,26 @@ pkgconf_tuple_find(const pkgconf_client_t *client, pkgconf_list_t *list, const c
/* /*
* !doc * !doc
* *
* .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value) * .. c:function:: char *pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags)
* *
* Parse an expression for variable substitution. * Parse an expression for variable substitution.
* *
* :param pkgconf_client_t* client: The pkgconf client object to access. * :param pkgconf_client_t* client: The pkgconf client object to access.
* :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list). * :param pkgconf_list_t* list: The variable list to search for variables (along side the global variable list).
* :param char* value: The ``key=value`` string to parse. * :param char* value: The ``key=value`` string to parse.
* :param uint flags: Any flags to consider while parsing.
* :return: the variable data with any variables substituted * :return: the variable data with any variables substituted
* :rtype: char * * :rtype: char *
*/ */
char * char *
pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value) pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const char *value, unsigned int flags)
{ {
char buf[PKGCONF_BUFSIZE]; char buf[PKGCONF_BUFSIZE];
const char *ptr; const char *ptr;
char *bptr = buf; char *bptr = buf;
if (!(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES)) if (!(client->flags & PKGCONF_PKG_PKGF_FDO_SYSROOT_RULES) &&
(!(flags & PKGCONF_PKG_PROPF_UNINSTALLED) || (client->flags & PKGCONF_PKG_PKGF_PKGCONF1_SYSROOT_RULES)))
{ {
if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir))) if (*value == '/' && client->sysroot_dir != NULL && strncmp(value, client->sysroot_dir, strlen(client->sysroot_dir)))
bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf); bptr += pkgconf_strlcpy(buf, client->sysroot_dir, sizeof buf);
@ -289,6 +330,8 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
} }
} }
PKGCONF_TRACE(client, "lookup tuple %s", varname);
ptr += (pptr - ptr); ptr += (pptr - ptr);
kv = pkgconf_tuple_find_global(client, varname); kv = pkgconf_tuple_find_global(client, varname);
if (kv != NULL) if (kv != NULL)
@ -302,7 +345,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
if (kv != NULL) if (kv != NULL)
{ {
parsekv = pkgconf_tuple_parse(client, vars, kv); parsekv = pkgconf_tuple_parse(client, vars, kv, flags);
strncpy(bptr, parsekv, PKGCONF_BUFSIZE - (bptr - buf)); strncpy(bptr, parsekv, PKGCONF_BUFSIZE - (bptr - buf));
bptr += strlen(parsekv); bptr += strlen(parsekv);
@ -329,18 +372,13 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
* safe to skip ahead in the string to scan for our sysroot dir. * safe to skip ahead in the string to scan for our sysroot dir.
* *
* Finally, we call pkgconf_path_relocate() to clean the path of spurious elements. * Finally, we call pkgconf_path_relocate() to clean the path of spurious elements.
*
* New in 1.9: Only attempt to rewrite the sysroot if we are not processing an uninstalled package.
*/ */
const char *sysroot_dir = pkgconf_tuple_find(client, vars, "pc_sysrootdir"); if (should_rewrite_sysroot(client, vars, buf, flags))
if (sysroot_dir == NULL)
sysroot_dir = client->sysroot_dir;
if (*buf == '/' &&
sysroot_dir != NULL &&
strcmp(sysroot_dir, "/") != 0 &&
strlen(buf) > strlen(sysroot_dir) &&
strstr(buf + strlen(sysroot_dir), sysroot_dir) != NULL)
{ {
char cleanpath[PKGCONF_ITEM_SIZE]; char cleanpath[PKGCONF_ITEM_SIZE];
const char *sysroot_dir = find_sysroot(client, vars);
pkgconf_strlcpy(cleanpath, buf + strlen(sysroot_dir), sizeof cleanpath); pkgconf_strlcpy(cleanpath, buf + strlen(sysroot_dir), sizeof cleanpath);
pkgconf_path_relocate(cleanpath, sizeof cleanpath); pkgconf_path_relocate(cleanpath, sizeof cleanpath);

View File

@ -0,0 +1,10 @@
prefix=${pc_sysrootdir}/test
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/include
Name: omg-sysroot
Description: A testing pkg-config file
Version: 1.2.3
Libs: -L${libdir} -lomg
Cflags: -fPIC -I${includedir}/omg

View File

@ -6,7 +6,11 @@ tests_init \
cflags \ cflags \
variable \ variable \
do_not_eat_slash \ do_not_eat_slash \
do_not_duplicate_sysroot_dir do_not_duplicate_sysroot_dir \
uninstalled \
uninstalled_pkgconf1 \
uninstalled_fdo \
uninstalled_fdo_pc_sysrootdir
do_not_eat_slash_body() do_not_eat_slash_body()
{ {
@ -61,3 +65,46 @@ do_not_duplicate_sysroot_dir_body()
-o inline:"-I${SYSROOT_DIR}/usr/include \n" \ -o inline:"-I${SYSROOT_DIR}/usr/include \n" \
pkgconf --cflags sysroot-dir-4 pkgconf --cflags sysroot-dir-4
} }
uninstalled_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
atf_check \
-o inline:"-L/test/lib -lomg \n" \
pkgconf --libs omg
}
uninstalled_pkgconf1_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
export PKG_CONFIG_PKGCONF1_SYSROOT_RULES="1"
atf_check \
-o inline:"-L/sysroot/test/lib -lomg \n" \
pkgconf --libs omg
}
uninstalled_fdo_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
export PKG_CONFIG_FDO_SYSROOT_RULES="1"
atf_check \
-o inline:"-L/test/lib -lomg \n" \
pkgconf --libs omg
}
uninstalled_fdo_pc_sysrootdir_body()
{
export PKG_CONFIG_PATH="${selfdir}/lib1"
export PKG_CONFIG_SYSROOT_DIR="/sysroot"
export PKG_CONFIG_FDO_SYSROOT_RULES="1"
atf_check \
-o inline:"-L/sysroot/test/lib -lomg \n" \
pkgconf --libs omg-sysroot
}