aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-12-13 04:07:04 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-12-13 04:07:04 +0300
commit08688bfc12a42a0399bcbdd6fe7d30d8f2486775 (patch)
tree24168d08caacd22fc4a74c481be514df4280e9a2
parent2d16c7ef06e22cae51436957bb6b80ea350a709f (diff)
Add workaround for libpkgconf flags parsing issue
-rw-r--r--build2/cc/pkgconfig.cxx50
1 files changed, 50 insertions, 0 deletions
diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx
index 1ad9f77..6eab22c 100644
--- a/build2/cc/pkgconfig.cxx
+++ b/build2/cc/pkgconfig.cxx
@@ -241,6 +241,54 @@ namespace build2
return r;
}
+ // Unescape backslashes in fragment data.
+ //
+ // Note that currently libpkgconf parses flags:
+ //
+ // "-IC:\\D C"
+ // '-IC:\D C'
+ // -IC:\\D\ C
+ //
+ // into fragments data:
+ //
+ // C:\D C
+ // C:D C
+ // C:\\D C
+ //
+ // This looks broken, as we could expect all 3 forms to result in the same
+ // (most natural) internal representation:
+ //
+ // C:\D C
+ //
+ // We workaround this issue for the third case, unescaping backslashes. This
+ // way we can break the first case, but that's not very probable. And we
+ // can't do much about the second case.
+ //
+ static void
+ unescape (pkgconf_list_t& frags)
+ {
+ pkgconf_node_t *node;
+ PKGCONF_FOREACH_LIST_ENTRY(frags.head, node)
+ {
+ auto frag (static_cast<pkgconf_fragment_t*> (node->data));
+
+ char* d (frag->data);
+ for (char* s (d); *s != '\0'; ++s, ++d)
+ {
+ char c (*s);
+
+ // Unescape the backslash.
+ //
+ if (c == '\\' && s[1] == '\\')
+ ++s;
+
+ *d = c;
+ }
+
+ *d = '\0';
+ }
+ }
+
// Note that some libpkgconf functions can potentially return NULL, failing
// to allocate the required memory block. However, we will not check the
// returned value for NULL as the library doesn't do so, prior to filling the
@@ -357,6 +405,7 @@ namespace build2
throw failed (); // Assume the diagnostics is issued.
unique_ptr<pkgconf_list_t, fragments_deleter> fd (&f); // Auto-deleter.
+ unescape (f);
return to_strings (f, 'I', client_->filter_includedirs);
}
@@ -386,6 +435,7 @@ namespace build2
throw failed (); // Assume the diagnostics is issued.
unique_ptr<pkgconf_list_t, fragments_deleter> fd (&f); // Auto-deleter.
+ unescape (f);
return to_strings (f, 'L', client_->filter_libdirs);
}