From 54fae3a9ca0af5ab29cc02d9c91fc2c63c6bc872 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Tue, 19 Sep 2017 21:04:30 +0300 Subject: Merge with latest original package version (master branch) --- libpkgconf/pkg.c | 126 +++++++++++++++++++------------------------------------ 1 file changed, 43 insertions(+), 83 deletions(-) (limited to 'libpkgconf/pkg.c') diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c index fe4592a..92acdb2 100644 --- a/libpkgconf/pkg.c +++ b/libpkgconf/pkg.c @@ -13,11 +13,10 @@ * from the use of this software. */ +#include #include #include -#include - /* * !doc * @@ -52,10 +51,9 @@ str_has_suffix(const char *str, const char *suffix) } static inline const char * -get_default_pkgconfig_path(void) +get_default_pkgconfig_path(char *outbuf, size_t outlen) { #ifdef _WIN32 - static char outbuf[MAX_PATH]; char namebuf[MAX_PATH]; char *p; @@ -71,27 +69,29 @@ get_default_pkgconfig_path(void) return PKG_DEFAULT_PATH; *p = '\0'; - pkgconf_strlcpy(outbuf, namebuf, sizeof outbuf); - pkgconf_strlcat(outbuf, "/", sizeof outbuf); - pkgconf_strlcat(outbuf, "../lib/pkgconfig", sizeof outbuf); - pkgconf_strlcat(outbuf, ";", sizeof outbuf); - pkgconf_strlcat(outbuf, namebuf, sizeof outbuf); - pkgconf_strlcat(outbuf, "/", sizeof outbuf); - pkgconf_strlcat(outbuf, "../share/pkgconfig", sizeof outbuf); + pkgconf_strlcpy(outbuf, namebuf, outlen); + pkgconf_strlcat(outbuf, "/", outlen); + pkgconf_strlcat(outbuf, "../lib/pkgconfig", outlen); + pkgconf_strlcat(outbuf, ";", outlen); + pkgconf_strlcat(outbuf, namebuf, outlen); + pkgconf_strlcat(outbuf, "/", outlen); + pkgconf_strlcat(outbuf, "../share/pkgconfig", outlen); return outbuf; +#else + (void) outbuf; + (void) outlen; #endif return PKG_DEFAULT_PATH; } static const char * -pkg_get_parent_dir(pkgconf_pkg_t *pkg) +pkg_get_parent_dir(pkgconf_pkg_t *pkg, char *buf, size_t buflen) { - static char buf[PKGCONF_BUFSIZE]; char *pathbuf; - pkgconf_strlcpy(buf, pkg->filename, sizeof buf); + pkgconf_strlcpy(buf, pkg->filename, buflen); pathbuf = strrchr(buf, PKG_DIR_SEP_S); if (pathbuf == NULL) pathbuf = strrchr(buf, '/'); @@ -119,7 +119,11 @@ pkgconf_pkg_dir_list_build(pkgconf_client_t *client) pkgconf_path_build_from_environ("PKG_CONFIG_PATH", NULL, &client->dir_list, true); if (!(client->flags & PKGCONF_PKG_PKGF_ENV_ONLY)) - pkgconf_path_build_from_environ("PKG_CONFIG_LIBDIR", get_default_pkgconfig_path(), &client->dir_list, true); + { + char pathbuf[PKGCONF_BUFSIZE]; + + pkgconf_path_build_from_environ("PKG_CONFIG_LIBDIR", get_default_pkgconfig_path(pathbuf, sizeof pathbuf), &client->dir_list, true); + } } typedef void (*pkgconf_pkg_parser_keyword_func_t)(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value); @@ -186,13 +190,12 @@ pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pk } static const char * -determine_prefix(const pkgconf_pkg_t *pkg) +determine_prefix(const pkgconf_pkg_t *pkg, char *buf, size_t buflen) { - static char buf[PKGCONF_BUFSIZE]; char *pathiter; - pkgconf_strlcpy(buf, pkg->filename, sizeof buf); - pkgconf_path_relocate(buf, sizeof buf); + pkgconf_strlcpy(buf, pkg->filename, buflen); + pkgconf_path_relocate(buf, buflen); pathiter = strrchr(buf, PKG_DIR_SEP_S); if (pathiter == NULL) @@ -272,12 +275,14 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * { pkgconf_pkg_t *pkg; char readbuf[PKGCONF_BUFSIZE]; + char pathbuf[PKGCONF_BUFSIZE]; + char prefixbuf[PKGCONF_BUFSIZE]; char *idptr; size_t lineno = 0; pkg = calloc(sizeof(pkgconf_pkg_t), 1); pkg->filename = strdup(filename); - pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pkg_get_parent_dir(pkg), true); + pkgconf_tuple_add(client, &pkg->vars, "pcfiledir", pkg_get_parent_dir(pkg, pathbuf, sizeof pathbuf), true); /* make module id */ if ((idptr = strrchr(pkg->filename, PKG_DIR_SEP_S)) != NULL) @@ -301,10 +306,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * lineno++; - /* - * Workaround MinGW/msvcrt issue (see the comment in client.c for details). - */ - PKGCONF_TRACE(client, "%s:%lu > [%s]", filename, (unsigned long)lineno, readbuf); + PKGCONF_TRACE(client, "%s:" SIZE_FMT_SPECIFIER " > [%s]", filename, lineno, readbuf); p = readbuf; while (*p && (isalpha((unsigned int)*p) || isdigit((unsigned int)*p) || *p == '_' || *p == '.')) @@ -318,13 +320,8 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * { if (!warned_key_whitespace) { - /* - * Workaround MinGW/msvcrt issue (see the comment in client.c for - * details). - */ - pkgconf_warn(client, "%s:%lu: warning: whitespace encountered while parsing key section\n", - pkg->filename, (unsigned long)lineno); - + pkgconf_warn(client, "%s:" SIZE_FMT_SPECIFIER ": warning: whitespace encountered while parsing key section\n", + pkg->filename, lineno); warned_key_whitespace = true; } @@ -346,12 +343,8 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * { if (!warned_value_whitespace && op == '=') { - /* - * Workaround MinGW/msvcrt issue (see the comment in client.c for - * details). - */ - pkgconf_warn(client, "%s:%lu: warning: trailing whitespace encountered while parsing value section\n", - pkg->filename, (unsigned long)lineno); + pkgconf_warn(client, "%s:" SIZE_FMT_SPECIFIER ": warning: trailing whitespace encountered while parsing value section\n", + pkg->filename, lineno); warned_value_whitespace = true; } @@ -369,7 +362,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * pkgconf_tuple_add(client, &pkg->vars, key, value, true); else { - const char *relvalue = determine_prefix(pkg); + const char *relvalue = determine_prefix(pkg, prefixbuf, sizeof prefixbuf); if (relvalue != NULL) { pkgconf_tuple_add(client, &pkg->vars, "orig_prefix", value, true); @@ -412,46 +405,13 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE * void pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg) { - /* - * The function leaks (issue #132 is reported). The whole concept of "static" - * packages is quite murky, so it's better just not to use it, at least - * until fixed by the library owners. In particular don't use - * pkgconf_queue_* functions. - */ - assert (pkg == NULL || (pkg->flags & PKGCONF_PKG_PROPF_STATIC) == 0); - - if (pkg == NULL || pkg->flags & PKGCONF_PKG_PROPF_STATIC) + if (pkg == NULL) return; - /* - * Note that if a package is loaded by the file path it is not cached (see - * pkgconf_pkg_find() for details). Trying to remove such a package from the - * cache just breaks the cache (issue #133 is reported). So let's first check - * if the package in the cache. - * - * Generally it's quite murky that the function that frees the - * reference-countable object also removes it's pointer from cache that must - * own a reference to it (see how pkgconf_cache_add() increments the - * reference count). It sounds that by the time the object is freed the - * reference count should be zero and so nobody, including cache, can contain - * a reference to the object. - * - * While probably nothing should surprise in the world, where - * pkgconf_pkg_free() and pkgconf_pkg_unref() are both available to the - * client (quite widelly used both in the library's code) and where - * pkgconf_pkg_unref() assumes the reference count can be negative. - */ - pkgconf_node_t *node; - PKGCONF_FOREACH_LIST_ENTRY(client->pkg_cache.head, node) - { - pkgconf_pkg_t *p = node->data; + if (pkg->flags & PKGCONF_PKG_PROPF_STATIC && !(pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL)) + return; - if (p == pkg) - { - pkgconf_cache_remove(client, pkg); - break; - } - } + pkgconf_cache_remove(client, pkg); pkgconf_dependency_free(&pkg->requires); pkgconf_dependency_free(&pkg->requires_private); @@ -465,6 +425,9 @@ pkgconf_pkg_free(pkgconf_client_t *client, pkgconf_pkg_t *pkg) pkgconf_tuple_free(&pkg->vars); + if (pkg->flags & PKGCONF_PKG_PROPF_VIRTUAL) + return; + if (pkg->id != NULL) free(pkg->id); @@ -572,7 +535,7 @@ pkgconf_pkg_scan_dir(pkgconf_client_t *client, const char *path, void *data, pkg for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir)) { - static char filebuf[PKGCONF_BUFSIZE]; + char filebuf[PKGCONF_BUFSIZE]; pkgconf_pkg_t *pkg; FILE *f; @@ -694,6 +657,7 @@ pkgconf_pkg_find_in_registry_key(pkgconf_client_t *client, HKEY hkey, const char pkgconf_pkg_t * pkgconf_pkg_find(pkgconf_client_t *client, const char *name) { + char pathbuf[PKGCONF_BUFSIZE]; pkgconf_pkg_t *pkg = NULL; pkgconf_node_t *n; FILE *f; @@ -712,7 +676,7 @@ pkgconf_pkg_find(pkgconf_client_t *client, const char *name) pkg = pkgconf_pkg_new_from_file(client, name, f); if (pkg != NULL) { - pkgconf_path_add(pkg_get_parent_dir(pkg), &client->dir_list, true); + pkgconf_path_add(pkg_get_parent_dir(pkg, pathbuf, sizeof pathbuf), &client->dir_list, true); return pkg; } } @@ -731,8 +695,6 @@ pkgconf_pkg_find(pkgconf_client_t *client, const char *name) if ((pkg = pkgconf_cache_lookup(client, name)) != NULL) { PKGCONF_TRACE(client, "%s is cached", name); - - pkg->flags |= PKGCONF_PKG_PROPF_CACHED; return pkg; } } @@ -1341,16 +1303,14 @@ pkgconf_pkg_verify_graph(pkgconf_client_t *client, pkgconf_pkg_t *root, int dept static unsigned int pkgconf_pkg_report_graph_error(pkgconf_client_t *client, pkgconf_pkg_t *parent, pkgconf_pkg_t *pkg, pkgconf_dependency_t *node, unsigned int eflags) { - static bool already_sent_notice = false; - if (eflags & PKGCONF_PKG_ERRF_PACKAGE_NOT_FOUND) { - if (!(client->flags & PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS) && !already_sent_notice) + if (!(client->flags & PKGCONF_PKG_PKGF_SIMPLIFY_ERRORS) & !client->already_sent_notice) { pkgconf_error(client, "Package %s was not found in the pkg-config search path.\n", node->package); pkgconf_error(client, "Perhaps you should add the directory containing `%s.pc'\n", node->package); pkgconf_error(client, "to the PKG_CONFIG_PATH environment variable\n"); - already_sent_notice = true; + client->already_sent_notice = true; } pkgconf_error(client, "Package '%s', required by '%s', not found\n", node->package, parent->id); -- cgit v1.1