aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pkgconfig/pcparser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pkgconfig/pcparser.cpp')
-rw-r--r--src/lib/pkgconfig/pcparser.cpp69
1 files changed, 37 insertions, 32 deletions
diff --git a/src/lib/pkgconfig/pcparser.cpp b/src/lib/pkgconfig/pcparser.cpp
index 388363af6..4469ca193 100644
--- a/src/lib/pkgconfig/pcparser.cpp
+++ b/src/lib/pkgconfig/pcparser.cpp
@@ -62,6 +62,11 @@ namespace std {
namespace qbs {
+using Internal::completeBaseName;
+using Internal::parentPath;
+using Internal::startsWith;
+using Internal::endsWith;
+
namespace {
// workaround for a missing ctor before c++20
@@ -195,17 +200,6 @@ std::optional<std::vector<std::string>> splitCommand(std::string_view s)
return result;
}
-bool startsWith(std::string_view haystack, std::string_view needle)
-{
- return haystack.size() >= needle.size() && haystack.compare(0, needle.size(), needle) == 0;
-}
-
-bool endsWith(std::string_view haystack, std::string_view needle)
-{
- return haystack.size() >= needle.size()
- && haystack.compare(haystack.size() - needle.size(), needle.size(), needle) == 0;
-}
-
[[noreturn]] void raizeUnknownComparisonException(const PcPackage &pkg, std::string_view verName, std::string_view comp)
{
std::string message;
@@ -397,17 +391,6 @@ PcPackage::RequiredVersion::ComparisonType comparisonFromString(
raizeUnknownComparisonException(pkg, verName, comp);
}
-std::string baseName(const std::string_view &filePath)
-{
- auto pos = filePath.rfind('/');
- const auto fileName =
- pos == std::string_view::npos ? std::string_view() : filePath.substr(pos + 1);
- pos = fileName.rfind('.');
- return std::string(pos == std::string_view::npos
- ? std::string_view()
- : fileName.substr(0, pos));
-}
-
} // namespace
PcParser::PcParser(const PkgConfig &pkgConfig)
@@ -429,7 +412,7 @@ try
if (!file.is_open())
throw PcException(std::string("Can't open file ") + path);
- package.baseFileName = baseName(path);
+ package.baseFileName = std::string{completeBaseName(path)};
#if HAS_STD_FILESYSTEM
const auto fsPath = std::filesystem::path(path);
package.filePath = fsPath.generic_string();
@@ -445,7 +428,7 @@ try
parseLine(package, line);
return package;
} catch(const PcException &ex) {
- return PcBrokenPackage{path, baseName(path), ex.what()};
+ return PcBrokenPackage{path, std::string{completeBaseName(path)}, ex.what()};
}
std::string PcParser::trimAndSubstitute(const PcPackage &pkg, std::string_view str) const
@@ -488,6 +471,35 @@ std::string PcParser::trimAndSubstitute(const PcPackage &pkg, std::string_view s
return result;
}
+std::string PcParser::evaluateVariable(
+ PcPackage &pkg, std::string_view tag, std::string_view str) const
+{
+ static constexpr std::string_view prefixVariable = "prefix";
+ if (m_pkgConfig.options().definePrefix) {
+ if (tag == prefixVariable) {
+ std::string_view prefix = pkg.filePath;
+ prefix = parentPath(prefix);
+ if (completeBaseName(prefix) == "pkgconfig") {
+ prefix = parentPath(prefix);
+ prefix = parentPath(prefix);
+ }
+ pkg.oldPrefix = std::string(str);
+ if (!prefix.empty())
+ str = prefix;
+ return std::string(str);
+ } else if (pkg.oldPrefix
+ && str.size() > pkg.oldPrefix->size()
+ && str.substr(0, pkg.oldPrefix->size()) == *pkg.oldPrefix
+ && str[pkg.oldPrefix->size()] == '/') {
+ auto result = pkg.variables["prefix"];
+ result += str.substr(pkg.oldPrefix->size());
+ return trimAndSubstitute(pkg, result);
+ }
+ }
+
+ return trimAndSubstitute(pkg, str);
+}
+
void PcParser::parseStringField(
PcPackage &pkg,
std::string &field,
@@ -765,14 +777,7 @@ void PcParser::parseLine(PcPackage &pkg, std::string_view str)
str.remove_prefix(1); // cut '='
str = trimmed(str);
- // TODO: support guesstimating of the prefix variable (pkg-config's --define-prefix option)
- // from doc: "try to override the value of prefix for each .pc file found with a
- // guesstimated value based on the location of the .pc file"
- // https://gitlab.freedesktop.org/pkg-config/pkg-config/-/blob/pkg-config-0.29.2/parse.c#L998
- // This option is disabled by default, and Qbs doesn't allow to override it yet, so we can
- // ignore this feature for now
-
- const auto value = trimAndSubstitute(pkg, str);
+ const auto value = evaluateVariable(pkg, tag, str);
if (!pkg.variables.insert({std::string(tag), value}).second)
raizeDuplicateVariableException(pkg, tag);
}