summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Nicholson <dbn.lists@gmail.com>2013-05-16 07:03:27 -0700
committerDan Nicholson <dbn.lists@gmail.com>2013-05-17 05:53:13 -0700
commit715cc306b0e4add06523b8fcce49867da469a728 (patch)
tree7fd7573541ebf4d10a01f280176aa26b6aeb58a0
parent2f41b2de42c77b8f44048295a8a3f794711cd4df (diff)
downloadpkg-config-715cc306b0e4add06523b8fcce49867da469a728.tar.gz
Allow errors in .pc files for --list-all
Normally, the parser will exit immediately when it encounters errors in .pc files. This is good most of the time, but for --list-all, the purpose is to just get a quick list of packages and not to validate .pc files. This is especially the case for pkg-config wrappers such as the Ruby or Bash completion modules that scrape the output from --list-all and don't expect to encounter errors there. Freedesktop #26615 (https://bugs.freedesktop.org/show_bug.cgi?id=26615)
-rw-r--r--check/Makefile.am1
-rwxr-xr-xcheck/check-print-options5
-rw-r--r--check/sub/broken.pc4
-rw-r--r--main.c4
-rw-r--r--parse.c130
-rw-r--r--pkg.h3
6 files changed, 105 insertions, 42 deletions
diff --git a/check/Makefile.am b/check/Makefile.am
index f348128..9bef3b4 100644
--- a/check/Makefile.am
+++ b/check/Makefile.am
@@ -44,6 +44,7 @@ EXTRA_DIST = \
fields-blank.pc \
sub/sub1.pc \
sub/sub2.pc \
+ sub/broken.pc \
inst.pc \
inst-uninstalled.pc \
other.pc \
diff --git a/check/check-print-options b/check/check-print-options
index a2a41e7..fcd94d6 100755
--- a/check/check-print-options
+++ b/check/check-print-options
@@ -34,8 +34,9 @@ RESULT="private-dep >= 1"
run_test --print-requires-private requires-test
# --list-all, limit to a subdirectory
-RESULT="sub1 Subdirectory package 1 - Test package 1 for subdirectory
-sub2 Subdirectory package 2 - Test package 2 for subdirectory"
+RESULT="sub1 Subdirectory package 1 - Test package 1 for subdirectory
+sub2 Subdirectory package 2 - Test package 2 for subdirectory
+broken Broken package - Module with broken .pc file"
PKG_CONFIG_LIBDIR="$srcdir/sub" run_test --list-all
# Check handling when multiple incompatible options are set
diff --git a/check/sub/broken.pc b/check/sub/broken.pc
new file mode 100644
index 0000000..684d027
--- /dev/null
+++ b/check/sub/broken.pc
@@ -0,0 +1,4 @@
+Name: Broken package
+Description: Module with broken .pc file
+Version: 1.0
+Name: 2nd name
diff --git a/main.c b/main.c
index f0f2762..62758b8 100644
--- a/main.c
+++ b/main.c
@@ -621,6 +621,10 @@ main (int argc, char **argv)
if (pkg_flags == 0 && !want_requires && !want_exists)
disable_requires();
+ /* Allow errors in .pc files when listing all. */
+ if (want_list)
+ parse_strict = FALSE;
+
if (want_my_version)
{
printf ("%s\n", VERSION);
diff --git a/parse.c b/parse.c
index 64399e6..87e5191 100644
--- a/parse.c
+++ b/parse.c
@@ -34,6 +34,7 @@
#endif
#include <sys/types.h>
+gboolean parse_strict = TRUE;
gboolean define_prefix = ENABLE_DEFINE_PREFIX;
char *prefix_variable = "prefix";
@@ -199,8 +200,8 @@ trim_and_sub (Package *pkg, const char *str, const char *path)
{
verbose_error ("Variable '%s' not defined in '%s'\n",
varname, path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
}
g_free (varname);
@@ -229,8 +230,10 @@ parse_name (Package *pkg, const char *str, const char *path)
if (pkg->name)
{
verbose_error ("Name field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
pkg->name = trim_and_sub (pkg, str, path);
@@ -242,8 +245,10 @@ parse_version (Package *pkg, const char *str, const char *path)
if (pkg->version)
{
verbose_error ("Version field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
pkg->version = trim_and_sub (pkg, str, path);
@@ -255,8 +260,10 @@ parse_description (Package *pkg, const char *str, const char *path)
if (pkg->description)
{
verbose_error ("Description field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
pkg->description = trim_and_sub (pkg, str, path);
@@ -408,9 +415,8 @@ parse_module_list (Package *pkg, const char *str, const char *path)
GList *retval = NULL;
split = split_module_list (str, path);
-
- iter = split;
- while (iter != NULL)
+
+ for (iter = split; iter != NULL; iter = g_list_next (iter))
{
RequiredVersion *ver;
char *p;
@@ -440,8 +446,10 @@ parse_module_list (Package *pkg, const char *str, const char *path)
if (*start == '\0')
{
verbose_error ("Empty package name in Requires or Conflicts in file '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ continue;
}
ver->name = g_strdup (start);
@@ -473,9 +481,13 @@ parse_module_list (Package *pkg, const char *str, const char *path)
ver->comparison = NOT_EQUAL;
else
{
- verbose_error ("Unknown version comparison operator '%s' after package name '%s' in file '%s'\n", start, ver->name, path);
-
- exit (1);
+ verbose_error ("Unknown version comparison operator '%s' after "
+ "package name '%s' in file '%s'\n", start,
+ ver->name, path);
+ if (parse_strict)
+ exit (1);
+ else
+ continue;
}
}
@@ -492,9 +504,15 @@ parse_module_list (Package *pkg, const char *str, const char *path)
if (ver->comparison != ALWAYS_MATCH && *start == '\0')
{
- verbose_error ("Comparison operator but no version after package name '%s' in file '%s'\n", ver->name, path);
-
- exit (1);
+ verbose_error ("Comparison operator but no version after package "
+ "name '%s' in file '%s'\n", ver->name, path);
+ if (parse_strict)
+ exit (1);
+ else
+ {
+ ver->version = g_strdup ("0");
+ continue;
+ }
}
if (*start != '\0')
@@ -503,8 +521,6 @@ parse_module_list (Package *pkg, const char *str, const char *path)
}
g_assert (ver->name);
-
- iter = g_list_next (iter);
}
g_list_foreach (split, (GFunc) g_free, NULL);
@@ -523,8 +539,10 @@ parse_requires (Package *pkg, const char *str, const char *path)
if (pkg->requires)
{
verbose_error ("Requires field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
trimmed = trim_and_sub (pkg, str, path);
@@ -540,8 +558,10 @@ parse_requires_private (Package *pkg, const char *str, const char *path)
if (pkg->requires_private)
{
verbose_error ("Requires.private field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
trimmed = trim_and_sub (pkg, str, path);
@@ -557,8 +577,10 @@ parse_conflicts (Package *pkg, const char *str, const char *path)
if (pkg->conflicts)
{
verbose_error ("Conflicts field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
trimmed = trim_and_sub (pkg, str, path);
@@ -691,8 +713,10 @@ parse_libs (Package *pkg, const char *str, const char *path)
if (pkg->libs_num > 0)
{
verbose_error ("Libs field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
trimmed = trim_and_sub (pkg, str, path);
@@ -702,7 +726,13 @@ parse_libs (Package *pkg, const char *str, const char *path)
{
verbose_error ("Couldn't parse Libs field into an argument vector: %s\n",
error ? error->message : "unknown");
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ {
+ g_free (trimmed);
+ return;
+ }
}
_do_parse_libs(pkg, argc, argv);
@@ -735,8 +765,10 @@ parse_libs_private (Package *pkg, const char *str, const char *path)
if (pkg->libs_private_num > 0)
{
verbose_error ("Libs.private field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
trimmed = trim_and_sub (pkg, str, path);
@@ -746,7 +778,13 @@ parse_libs_private (Package *pkg, const char *str, const char *path)
{
verbose_error ("Couldn't parse Libs.private field into an argument vector: %s\n",
error ? error->message : "unknown");
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ {
+ g_free (trimmed);
+ return;
+ }
}
_do_parse_libs(pkg, argc, argv);
@@ -771,8 +809,10 @@ parse_cflags (Package *pkg, const char *str, const char *path)
if (pkg->cflags)
{
verbose_error ("Cflags field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
trimmed = trim_and_sub (pkg, str, path);
@@ -782,7 +822,13 @@ parse_cflags (Package *pkg, const char *str, const char *path)
{
verbose_error ("Couldn't parse Cflags field into an argument vector: %s\n",
error ? error->message : "unknown");
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ {
+ g_free (trimmed);
+ return;
+ }
}
i = 0;
@@ -843,8 +889,10 @@ parse_url (Package *pkg, const char *str, const char *path)
if (pkg->url != NULL)
{
verbose_error ("URL field occurs twice in '%s'\n", path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ return;
}
pkg->url = trim_and_sub (pkg, str, path);
@@ -1011,8 +1059,10 @@ parse_line (Package *pkg, const char *untrimmed, const char *path,
{
verbose_error ("Duplicate definition of variable '%s' in '%s'\n",
tag, path);
-
- exit (1);
+ if (parse_strict)
+ exit (1);
+ else
+ goto cleanup;
}
varname = g_strdup (tag);
diff --git a/pkg.h b/pkg.h
index 328ac26..fd3538e 100644
--- a/pkg.h
+++ b/pkg.h
@@ -134,6 +134,9 @@ extern char *pcsysrootdir;
*/
extern char *pkg_config_pc_path;
+/* Exit on parse errors if TRUE. */
+extern gboolean parse_strict;
+
/* If TRUE, define "prefix" in .pc files at runtime. */
extern gboolean define_prefix;