From 08688bfc12a42a0399bcbdd6fe7d30d8f2486775 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 13 Dec 2017 04:07:04 +0300 Subject: Add workaround for libpkgconf flags parsing issue --- build2/cc/pkgconfig.cxx | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'build2/cc/pkgconfig.cxx') 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 (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 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 fd (&f); // Auto-deleter. + unescape (f); return to_strings (f, 'L', client_->filter_libdirs); } -- cgit v1.1