aboutsummaryrefslogtreecommitdiff
path: root/libpkgconf/pkg.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpkgconf/pkg.c')
-rw-r--r--libpkgconf/pkg.c126
1 files changed, 43 insertions, 83 deletions
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 <libpkgconf/stdinc.h>
#include <libpkgconf/config.h>
#include <libpkgconf/libpkgconf.h>
-#include <assert.h>
-
/*
* !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);