aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-10-14 00:05:03 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-10-14 00:05:03 +0300
commit598b0256a354cb2e65ea240e50662d4378f5462c (patch)
treeeebc14a4f618ade0678107c40b16f6538d30aade
parent8a5f879840bfe9933a6ff01792b42000de99f8c2 (diff)
Merge with latest original package version (master branch)
-rw-r--r--libpkgconf/argvsplit.c7
-rw-r--r--libpkgconf/argvsplit.c.orig2
-rw-r--r--libpkgconf/dependency.c4
-rw-r--r--libpkgconf/fileio.c6
-rw-r--r--libpkgconf/fileio.c.orig121
-rw-r--r--libpkgconf/fragment.c34
-rw-r--r--libpkgconf/fragment.c.orig30
-rw-r--r--libpkgconf/libpkgconf-api.h2
-rw-r--r--libpkgconf/libpkgconf.h4
-rw-r--r--libpkgconf/libpkgconf.h.orig331
-rw-r--r--libpkgconf/path.c6
-rw-r--r--libpkgconf/pkg.c42
-rw-r--r--libpkgconf/pkg.c.orig28
-rw-r--r--libpkgconf/stdinc.h65
-rw-r--r--libpkgconf/stdinc.h.orig4
-rw-r--r--libpkgconf/tuple.c5
-rw-r--r--libpkgconf/tuple.c.orig1
17 files changed, 149 insertions, 543 deletions
diff --git a/libpkgconf/argvsplit.c b/libpkgconf/argvsplit.c
index fdc4dc9..4e40327 100644
--- a/libpkgconf/argvsplit.c
+++ b/libpkgconf/argvsplit.c
@@ -93,11 +93,14 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
* There is no reason to keep space character escaped in fragment
* objects, especially given that other characters are unescaped (issue
* #139 is reported).
+ *
+ * Update: as a part of the issue #140 fix the backslash is now
+ * escaped as well.
*/
/*
- if (isspace((unsigned int) *src_iter))
+ if (isspace((unsigned int) *src_iter) || *src_iter == '\\')
*dst_iter++ = '\\';
- */
+ */
*dst_iter++ = *src_iter;
}
diff --git a/libpkgconf/argvsplit.c.orig b/libpkgconf/argvsplit.c.orig
index 81a2ec1..a9e8efa 100644
--- a/libpkgconf/argvsplit.c.orig
+++ b/libpkgconf/argvsplit.c.orig
@@ -89,7 +89,7 @@ pkgconf_argv_split(const char *src, int *argc, char ***argv)
}
else
{
- if (isspace((unsigned int) *src_iter))
+ if (isspace((unsigned int) *src_iter) || *src_iter == '\\')
*dst_iter++ = '\\';
*dst_iter++ = *src_iter;
diff --git a/libpkgconf/dependency.c b/libpkgconf/dependency.c
index 6f72dbb..1a4ec68 100644
--- a/libpkgconf/dependency.c
+++ b/libpkgconf/dependency.c
@@ -56,7 +56,7 @@ static inline pkgconf_dependency_t *
pkgconf_dependency_addraw(const pkgconf_client_t *client, pkgconf_list_t *list, const char *package, size_t package_sz, const char *version, size_t version_sz, pkgconf_pkg_comparator_t compare)
{
pkgconf_dependency_t *dep;
- char depbuf[PKGCONF_SBUFSIZE];
+ char depbuf[PKGCONF_ITEM_SIZE];
dep = calloc(sizeof(pkgconf_dependency_t), 1);
dep->package = pkgconf_strndup(package, package_sz);
@@ -161,7 +161,7 @@ pkgconf_dependency_parse_str(const pkgconf_client_t *client, pkgconf_list_t *dep
{
parse_state_t state = OUTSIDE_MODULE;
pkgconf_pkg_comparator_t compare = PKGCONF_CMP_ANY;
- char cmpname[PKGCONF_SBUFSIZE];
+ char cmpname[PKGCONF_ITEM_SIZE];
char buf[PKGCONF_BUFSIZE];
size_t package_sz = 0, version_sz = 0;
char *start = buf;
diff --git a/libpkgconf/fileio.c b/libpkgconf/fileio.c
index 7411dc3..b64205d 100644
--- a/libpkgconf/fileio.c
+++ b/libpkgconf/fileio.c
@@ -29,16 +29,12 @@ pkgconf_fgetline(char *line, size_t size, FILE *stream)
while (s < end && (c = getc(stream)) != EOF)
{
- /*
- * Fix double-backslash swallowing (issue #140 is reported).
- */
if (c == '\\' && !quoted)
{
quoted = true;
continue;
}
-
- if (c == '#')
+ else if (c == '#')
{
if (!quoted) {
/* Skip the rest of the line */
diff --git a/libpkgconf/fileio.c.orig b/libpkgconf/fileio.c.orig
deleted file mode 100644
index eb073d5..0000000
--- a/libpkgconf/fileio.c.orig
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * fileio.c
- * File reading utilities
- *
- * Copyright (c) 2012 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 <libpkgconf/stdinc.h>
-#include <libpkgconf/libpkgconf.h>
-
-char *
-pkgconf_fgetline(char *line, size_t size, FILE *stream)
-{
- char *s = line;
- char *end = line + size - 1;
- bool quoted = false;
- int c = '\0', c2;
-
- if (s == NULL)
- return NULL;
-
- while (s < end && (c = getc(stream)) != EOF)
- {
- if (c == '\\')
- {
- quoted = true;
- continue;
- }
- else if (c == '#')
- {
- if (!quoted) {
- /* Skip the rest of the line */
- do {
- c = getc(stream);
- } while (c != '\n' && c != EOF);
- *s++ = c;
- break;
- }
- quoted = false;
- continue;
- }
- else if (c == '\n')
- {
- if (quoted)
- {
- /* Trim spaces */
- do {
- c2 = getc(stream);
- } while (c2 == '\t' || c2 == ' ');
-
- ungetc(c2, stream);
-
- quoted = false;
- continue;
- }
- else
- {
- *s++ = c;
- }
-
- break;
- }
- else if (c == '\r')
- {
- *s++ = '\n';
-
- if ((c2 = getc(stream)) == '\n')
- {
- if (quoted)
- {
- quoted = false;
- continue;
- }
-
- break;
- }
-
- ungetc(c2, stream);
-
- if (quoted)
- {
- quoted = false;
- continue;
- }
-
- break;
- }
- else
- {
- if (quoted) {
- *s++ = '\\';
- quoted = false;
- }
- *s++ = c;
- }
-
- }
-
- if (c == EOF && (s == line || ferror(stream)))
- return NULL;
-
- *s = '\0';
-
- /* Remove newline character. */
- if (s > line && *(--s) == '\n') {
- *s = '\0';
-
- if (s > line && *(--s) == '\r')
- *s = '\0';
- }
-
- return line;
-}
diff --git a/libpkgconf/fragment.c b/libpkgconf/fragment.c
index 22d6d04..7646f31 100644
--- a/libpkgconf/fragment.c
+++ b/libpkgconf/fragment.c
@@ -122,7 +122,7 @@ pkgconf_fragment_munge(const pkgconf_client_t *client, char *buf, size_t buflen,
static inline char *
pkgconf_fragment_copy_munged(const pkgconf_client_t *client, const char *source)
{
- char mungebuf[PKGCONF_SBUFSIZE];
+ char mungebuf[PKGCONF_ITEM_SIZE];
pkgconf_fragment_munge(client, mungebuf, sizeof mungebuf, source, client->sysroot_dir);
return strdup(mungebuf);
}
@@ -158,7 +158,7 @@ pkgconf_fragment_add(const pkgconf_client_t *client, pkgconf_list_t *list, const
}
else
{
- char mungebuf[PKGCONF_SBUFSIZE];
+ char mungebuf[PKGCONF_ITEM_SIZE];
if (list->tail != NULL && list->tail->data != NULL)
{
@@ -600,7 +600,7 @@ pkgconf_fragment_free(pkgconf_list_t *list)
/*
* !doc
*
- * .. c:function:: void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
+ * .. 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`.
*
@@ -608,20 +608,40 @@ pkgconf_fragment_free(pkgconf_list_t *list)
* :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: nothing
+ * :return: true on success, false on parse error
*/
-void
+bool
pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
{
- int i, argc;
+ int i, ret, argc;
char **argv;
char *repstr = pkgconf_tuple_parse(client, vars, value);
- pkgconf_argv_split(repstr, &argc, &argv);
+ 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/fragment.c.orig b/libpkgconf/fragment.c.orig
index b405631..9e73515 100644
--- a/libpkgconf/fragment.c.orig
+++ b/libpkgconf/fragment.c.orig
@@ -600,7 +600,7 @@ pkgconf_fragment_free(pkgconf_list_t *list)
/*
* !doc
*
- * .. c:function:: void pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
+ * .. 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`.
*
@@ -608,20 +608,40 @@ pkgconf_fragment_free(pkgconf_list_t *list)
* :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: nothing
+ * :return: true on success, false on parse error
*/
-void
+bool
pkgconf_fragment_parse(const pkgconf_client_t *client, pkgconf_list_t *list, pkgconf_list_t *vars, const char *value)
{
- int i, argc;
+ int i, ret, argc;
char **argv;
char *repstr = pkgconf_tuple_parse(client, vars, value);
- pkgconf_argv_split(repstr, &argc, &argv);
+ 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-api.h b/libpkgconf/libpkgconf-api.h
index 1c4fb73..d6ba409 100644
--- a/libpkgconf/libpkgconf-api.h
+++ b/libpkgconf/libpkgconf-api.h
@@ -8,7 +8,7 @@
#if defined(PKGCONFIG_IS_STATIC)
# define PKGCONF_API
#elif defined(_WIN32) || defined(_WIN64)
-# ifdef LIBPKGCONF_EXPORT
+# if defined(LIBPKGCONF_EXPORT) || defined(DLL_EXPORT)
# define PKGCONF_API __declspec(dllexport)
# else
# define PKGCONF_API __declspec(dllimport)
diff --git a/libpkgconf/libpkgconf.h b/libpkgconf/libpkgconf.h
index 66b4f54..ac873bf 100644
--- a/libpkgconf/libpkgconf.h
+++ b/libpkgconf/libpkgconf.h
@@ -41,6 +41,8 @@ extern "C" {
#define PKG_DIR_SEP_S '/'
#endif
+#define PKGCONF_BUFSIZE (65535)
+
typedef enum {
PKGCONF_CMP_NOT_EQUAL,
PKGCONF_CMP_ANY,
@@ -271,7 +273,7 @@ PKGCONF_API void pkgconf_argv_free(char **argv);
/* fragment.c */
typedef bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data);
-PKGCONF_API void 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);
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_delete(pkgconf_list_t *list, pkgconf_fragment_t *node);
diff --git a/libpkgconf/libpkgconf.h.orig b/libpkgconf/libpkgconf.h.orig
deleted file mode 100644
index d7fe911..0000000
--- a/libpkgconf/libpkgconf.h.orig
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <libpkgconf/iter.h>
-#include <libpkgconf/bsdstubs.h>
-#include <libpkgconf/libpkgconf-api.h>
-
-#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
-
-#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;
-
-#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)
-
-struct pkgconf_fragment_ {
- pkgconf_node_t iter;
-
- char type;
- char *data;
-};
-
-struct pkgconf_dependency_ {
- pkgconf_node_t iter;
-
- char *package;
- pkgconf_pkg_comparator_t compare;
- char *version;
- pkgconf_pkg_t *parent;
-};
-
-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 requires;
- pkgconf_list_t requires_private;
- pkgconf_list_t conflicts;
- pkgconf_list_t provides;
-
- pkgconf_list_t vars;
-
- unsigned int flags;
-};
-
-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;
-};
-
-/* client.c */
-PKGCONF_API void pkgconf_client_init(pkgconf_client_t *client, pkgconf_error_handler_func_t error_handler, void *error_handler_data);
-PKGCONF_API pkgconf_client_t * pkgconf_client_new(pkgconf_error_handler_func_t error_handler, void *error_handler_data);
-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);
-
-#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_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
-
-/* pkg.c */
-#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__) */
-
-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);
-
-#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
-
-PKGCONF_API pkgconf_pkg_t *pkgconf_pkg_ref(const 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);
-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);
-PKGCONF_API void pkgconf_pkg_dir_list_build(pkgconf_client_t *client);
-
-/* 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);
-PKGCONF_API void pkgconf_dependency_parse(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, pkgconf_list_t *deplist_head, const char *depends);
-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);
-
-/* 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 bool (*pkgconf_fragment_filter_func_t)(const pkgconf_client_t *client, const pkgconf_fragment_t *frag, void *data);
-PKGCONF_API void 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_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);
-PKGCONF_API void pkgconf_fragment_render_buf(const pkgconf_list_t *list, char *buf, size_t len, bool escape);
-PKGCONF_API char *pkgconf_fragment_render(const pkgconf_list_t *list, bool escape);
-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(const 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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/libpkgconf/path.c b/libpkgconf/path.c
index 7f90928..36855fe 100644
--- a/libpkgconf/path.c
+++ b/libpkgconf/path.c
@@ -78,7 +78,7 @@ void
pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter)
{
pkgconf_path_t *node;
- char path[PKGCONF_SBUFSIZE];
+ char path[PKGCONF_ITEM_SIZE];
#ifdef PKGCONF_CACHE_INODES
struct stat st;
@@ -89,7 +89,7 @@ pkgconf_path_add(const char *text, pkgconf_list_t *dirlist, bool filter)
return;
if (S_ISLNK(st.st_mode))
{
- char linkdest[PKGCONF_SBUFSIZE];
+ char linkdest[PKGCONF_ITEM_SIZE];
ssize_t len = readlink(text, linkdest, sizeof(linkdest));
if (len != -1 && (size_t)len < sizeof(linkdest) &&
@@ -201,7 +201,7 @@ bool
pkgconf_path_match_list(const char *path, const pkgconf_list_t *dirlist)
{
pkgconf_node_t *n = NULL;
- char relocated[PKGCONF_SBUFSIZE];
+ char relocated[PKGCONF_ITEM_SIZE];
const char *cpath = path;
pkgconf_strlcpy(relocated, path, sizeof relocated);
diff --git a/libpkgconf/pkg.c b/libpkgconf/pkg.c
index d366fd3..ce3921b 100644
--- a/libpkgconf/pkg.c
+++ b/libpkgconf/pkg.c
@@ -125,7 +125,7 @@ pkgconf_pkg_dir_list_build(pkgconf_client_t *client)
}
}
-typedef void (*pkgconf_pkg_parser_keyword_func_t)(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value);
+typedef void (*pkgconf_pkg_parser_keyword_func_t)(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value);
typedef struct {
const char *keyword;
const pkgconf_pkg_parser_keyword_func_t func;
@@ -139,22 +139,34 @@ static int pkgconf_pkg_parser_keyword_pair_cmp(const void *key, const void *ptr)
}
static void
-pkgconf_pkg_parser_tuple_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value)
+pkgconf_pkg_parser_tuple_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
+ (void) keyword;
+ (void) lineno;
+
char **dest = (char **)((char *) pkg + offset);
*dest = pkgconf_tuple_parse(client, &pkg->vars, value);
}
static void
-pkgconf_pkg_parser_fragment_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value)
+pkgconf_pkg_parser_fragment_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
- pkgconf_fragment_parse(client, dest, &pkg->vars, value);
+ bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value);
+
+ if (!ret)
+ {
+ pkgconf_warn(client, "%s:" SIZE_FMT_SPECIFIER ": warning: unable to parse field '%s' into an argument vector, value [%s]\n", pkg->filename,
+ lineno, keyword, value);
+ }
}
static void
-pkgconf_pkg_parser_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value)
+pkgconf_pkg_parser_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
+ (void) keyword;
+ (void) lineno;
+
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
pkgconf_dependency_parse(client, pkg, dest, value);
}
@@ -175,7 +187,7 @@ static const pkgconf_pkg_parser_keyword_pair_t pkgconf_pkg_parser_keyword_funcs[
};
static bool
-pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, char *value)
+pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const size_t lineno, const char *keyword, char *value)
{
const pkgconf_pkg_parser_keyword_pair_t *pair = bsearch(keyword,
pkgconf_pkg_parser_keyword_funcs, PKGCONF_ARRAY_SIZE(pkgconf_pkg_parser_keyword_funcs),
@@ -184,7 +196,7 @@ pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pk
if (pair == NULL || pair->func == NULL)
return false;
- pair->func(client, pkg, pair->offset, value);
+ pair->func(client, pkg, keyword, lineno, pair->offset, value);
return true;
}
@@ -274,7 +286,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
{
pkgconf_pkg_t *pkg;
char readbuf[PKGCONF_BUFSIZE];
- char pathbuf[PKGCONF_SBUFSIZE];
+ char pathbuf[PKGCONF_ITEM_SIZE];
char *idptr;
size_t lineno = 0;
@@ -353,7 +365,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
switch (op)
{
case ':':
- pkgconf_pkg_parser_keyword_set(client, pkg, key, value);
+ pkgconf_pkg_parser_keyword_set(client, pkg, lineno, key, value);
break;
case '=':
if (strcmp(key, client->prefix_varname) || !(client->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX))
@@ -495,8 +507,8 @@ pkgconf_pkg_try_specific_path(pkgconf_client_t *client, const char *path, const
{
pkgconf_pkg_t *pkg = NULL;
FILE *f;
- char locbuf[PKGCONF_SBUFSIZE];
- char uninst_locbuf[PKGCONF_SBUFSIZE];
+ char locbuf[PKGCONF_ITEM_SIZE];
+ char uninst_locbuf[PKGCONF_ITEM_SIZE];
PKGCONF_TRACE(client, "trying path: %s for %s", path, name);
@@ -533,7 +545,7 @@ pkgconf_pkg_scan_dir(pkgconf_client_t *client, const char *path, void *data, pkg
for (dirent = readdir(dir); dirent != NULL; dirent = readdir(dir))
{
- char filebuf[PKGCONF_SBUFSIZE];
+ char filebuf[PKGCONF_ITEM_SIZE];
pkgconf_pkg_t *pkg;
FILE *f;
@@ -620,7 +632,7 @@ pkgconf_pkg_find_in_registry_key(pkgconf_client_t *client, HKEY hkey, const char
while (RegEnumValue(key, i++, buf, &bufsize, NULL, NULL, NULL, NULL)
== ERROR_SUCCESS)
{
- char pathbuf[PKGCONF_SBUFSIZE];
+ char pathbuf[PKGCONF_ITEM_SIZE];
DWORD type;
DWORD pathbuflen = sizeof pathbuf;
@@ -655,7 +667,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_SBUFSIZE];
+ char pathbuf[PKGCONF_ITEM_SIZE];
pkgconf_pkg_t *pkg = NULL;
pkgconf_node_t *n;
FILE *f;
@@ -735,7 +747,7 @@ int
pkgconf_compare_version(const char *a, const char *b)
{
char oldch1, oldch2;
- char buf1[PKGCONF_SBUFSIZE], buf2[PKGCONF_SBUFSIZE];
+ char buf1[PKGCONF_ITEM_SIZE], buf2[PKGCONF_ITEM_SIZE];
char *str1, *str2;
char *one, *two;
int ret;
diff --git a/libpkgconf/pkg.c.orig b/libpkgconf/pkg.c.orig
index 1a2f6b4..a35a756 100644
--- a/libpkgconf/pkg.c.orig
+++ b/libpkgconf/pkg.c.orig
@@ -126,7 +126,7 @@ pkgconf_pkg_dir_list_build(pkgconf_client_t *client)
}
}
-typedef void (*pkgconf_pkg_parser_keyword_func_t)(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value);
+typedef void (*pkgconf_pkg_parser_keyword_func_t)(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value);
typedef struct {
const char *keyword;
const pkgconf_pkg_parser_keyword_func_t func;
@@ -140,22 +140,34 @@ static int pkgconf_pkg_parser_keyword_pair_cmp(const void *key, const void *ptr)
}
static void
-pkgconf_pkg_parser_tuple_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value)
+pkgconf_pkg_parser_tuple_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
+ (void) keyword;
+ (void) lineno;
+
char **dest = (char **)((char *) pkg + offset);
*dest = pkgconf_tuple_parse(client, &pkg->vars, value);
}
static void
-pkgconf_pkg_parser_fragment_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value)
+pkgconf_pkg_parser_fragment_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
- pkgconf_fragment_parse(client, dest, &pkg->vars, value);
+ bool ret = pkgconf_fragment_parse(client, dest, &pkg->vars, value);
+
+ if (!ret)
+ {
+ pkgconf_warn(client, "%s:" SIZE_FMT_SPECIFIER ": warning: unable to parse field '%s' into an argument vector, value [%s]\n", pkg->filename,
+ lineno, keyword, value);
+ }
}
static void
-pkgconf_pkg_parser_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const ptrdiff_t offset, char *value)
+pkgconf_pkg_parser_dependency_func(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, const size_t lineno, const ptrdiff_t offset, char *value)
{
+ (void) keyword;
+ (void) lineno;
+
pkgconf_list_t *dest = (pkgconf_list_t *)((char *) pkg + offset);
pkgconf_dependency_parse(client, pkg, dest, value);
}
@@ -176,7 +188,7 @@ static const pkgconf_pkg_parser_keyword_pair_t pkgconf_pkg_parser_keyword_funcs[
};
static bool
-pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const char *keyword, char *value)
+pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pkg, const size_t lineno, const char *keyword, char *value)
{
const pkgconf_pkg_parser_keyword_pair_t *pair = bsearch(keyword,
pkgconf_pkg_parser_keyword_funcs, PKGCONF_ARRAY_SIZE(pkgconf_pkg_parser_keyword_funcs),
@@ -185,7 +197,7 @@ pkgconf_pkg_parser_keyword_set(const pkgconf_client_t *client, pkgconf_pkg_t *pk
if (pair == NULL || pair->func == NULL)
return false;
- pair->func(client, pkg, pair->offset, value);
+ pair->func(client, pkg, keyword, lineno, pair->offset, value);
return true;
}
@@ -355,7 +367,7 @@ pkgconf_pkg_new_from_file(pkgconf_client_t *client, const char *filename, FILE *
switch (op)
{
case ':':
- pkgconf_pkg_parser_keyword_set(client, pkg, key, value);
+ pkgconf_pkg_parser_keyword_set(client, pkg, lineno, key, value);
break;
case '=':
if (strcmp(key, client->prefix_varname) || !(client->flags & PKGCONF_PKG_PKGF_REDEFINE_PREFIX))
diff --git a/libpkgconf/stdinc.h b/libpkgconf/stdinc.h
index abebe03..418a06a 100644
--- a/libpkgconf/stdinc.h
+++ b/libpkgconf/stdinc.h
@@ -26,14 +26,36 @@
#include <sys/types.h>
#include <stdint.h>
+/*
+ * The original libpkgconf package uses PKGCONF_BUFSIZE size for all
+ * stack-allocated buffers, imposing high requirements for the thread stack
+ * size. This make it unusable on MacOS (as of 10.12) for non-main threads that
+ * are created with the default 512KB stack size. In particular that make it
+ * impossible to use libpkgconf API in threads created with C++11 std::thread
+ * class, that doesn't allow stack size customization.
+ *
+ * As an example, using pkgconf_pkg_find() for quite a simple .pc file consumes
+ * at least 460KB. The measurement was made as a difference between addresses
+ * of 2 stack-allocated variables: one was defined right before the function
+ * call, another right after the buffer definition in pkgconf_tuple_parse()
+ * function.
+ *
+ * To relax the stack size requirements we will minimize the usage of
+ * PKGCONF_BUFSIZE, inventing the smaller PKGCONF_ITEM_SIZE, and using it
+ * wherever it is possible instead. The PKGCONF_ITEM_SIZE is selected in such a
+ * way that a buffer of this size can accommodate the file system path, the
+ * value fragment, the variable name or the package dependency specification.
+ * The latest implies it also fits for the package key or the package version.
+ * This optimization decreased the stack usage for the described use case to
+ * 140KB.
+ *
+ * Issue #149 is reported.
+ */
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <malloc.h>
# define PATH_DEV_NULL "nul"
-/*
- * Fix MinGW GCC print format warnings (issue #142 is reported).
- */
# ifdef _WIN64
# define SIZE_FMT_SPECIFIER "%I64u"
# else
@@ -52,48 +74,17 @@
# else
# include <dirent.h>
# endif
+# define PKGCONF_ITEM_SIZE (_MAX_PATH + 1024)
#else
# define PATH_DEV_NULL "/dev/null"
# define SIZE_FMT_SPECIFIER "%zu"
# include <dirent.h>
# include <unistd.h>
-#endif
-
-/*
- * Stack-allocated buffer sizes.
- *
- * Original libpkgconf package uses PKGCONF_BUFSIZE size for all
- * stack-allocated buffers, imposing high requirements for the thread stack
- * size. This make it unusable on MacOS (as of 10.12) for non-main threads that
- * are created with the default 512K stack size. In particular that make it
- * impossible to use libpkgconf API in threads created with C++11 std::thread
- * class, that doesn't allow stack size customization.
- *
- * As an example, using pkgconf_pkg_find() for quite a simple .pc file consumes
- * at least 460K. The measurment was made as a differece between addresses of 2
- * stack-allocated variables: one was defined right before the function call,
- * another right after the buffer definition in pkgconf_tuple_parse() function.
- *
- * To relax the stack size requirements we will minimize the usage of
- * PKGCONF_BUFSIZE, using the smaller PKGCONF_SBUFSIZE instead, wherever it is
- * possible. The PKGCONF_SBUFSIZE is selected in such a way that a buffer of
- * this size can accommodate the file system path, the value fragment, the
- * variable name or the package dependency specification. The latest implies it
- * also fits for the package key or the package version. This optimization
- * decreased the stack usage for the described use case to 140K.
- *
- * Note that we moved PKGCONF_BUFSIZE definition from libpkgconf.h.
- */
-#define PKGCONF_BUFSIZE (65535)
-
-#ifdef _WIN32
-# define PKGCONF_SBUFSIZE (_MAX_PATH + 1024)
-#else
# include <limits.h>
# ifdef PATH_MAX
-# define PKGCONF_SBUFSIZE (PATH_MAX + 1024)
+# define PKGCONF_ITEM_SIZE (PATH_MAX + 1024)
# else
-# define PKGCONF_SBUFSIZE (4096 + 1024)
+# define PKGCONF_ITEM_SIZE (4096 + 1024)
# endif
#endif
diff --git a/libpkgconf/stdinc.h.orig b/libpkgconf/stdinc.h.orig
index 43d7eeb..d0a43ad 100644
--- a/libpkgconf/stdinc.h.orig
+++ b/libpkgconf/stdinc.h.orig
@@ -32,9 +32,9 @@
# include <malloc.h>
# define PATH_DEV_NULL "nul"
# ifdef _WIN64
-# define SIZE_FMT_SPECIFIER "%llu"
+# define SIZE_FMT_SPECIFIER "%I64u"
# else
-# define SIZE_FMT_SPECIFIER "%lu"
+# define SIZE_FMT_SPECIFIER "%u"
# endif
# ifndef ssize_t
# ifndef __MINGW32__
diff --git a/libpkgconf/tuple.c b/libpkgconf/tuple.c
index ae5fe55..7fbc71b 100644
--- a/libpkgconf/tuple.c
+++ b/libpkgconf/tuple.c
@@ -231,7 +231,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
*bptr++ = *ptr;
else if (*(ptr + 1) == '{')
{
- char varname[PKGCONF_SBUFSIZE];
+ char varname[PKGCONF_ITEM_SIZE];
char *vptr = varname;
const char *pptr;
char *kv, *parsekv;
@@ -292,10 +292,11 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
*/
if (*buf == '/' &&
client->sysroot_dir != NULL &&
+ strcmp(client->sysroot_dir, "/") != 0 &&
strlen(buf) > strlen(client->sysroot_dir) &&
strstr(buf + strlen(client->sysroot_dir), client->sysroot_dir) != NULL)
{
- char cleanpath[PKGCONF_SBUFSIZE];
+ char cleanpath[PKGCONF_ITEM_SIZE];
pkgconf_strlcpy(cleanpath, buf + strlen(client->sysroot_dir), sizeof cleanpath);
pkgconf_path_relocate(cleanpath, sizeof cleanpath);
diff --git a/libpkgconf/tuple.c.orig b/libpkgconf/tuple.c.orig
index b0cda45..0b22b9a 100644
--- a/libpkgconf/tuple.c.orig
+++ b/libpkgconf/tuple.c.orig
@@ -292,6 +292,7 @@ pkgconf_tuple_parse(const pkgconf_client_t *client, pkgconf_list_t *vars, const
*/
if (*buf == '/' &&
client->sysroot_dir != NULL &&
+ strcmp(client->sysroot_dir, "/") != 0 &&
strlen(buf) > strlen(client->sysroot_dir) &&
strstr(buf + strlen(client->sysroot_dir), client->sysroot_dir) != NULL)
{