aboutsummaryrefslogtreecommitdiff
path: root/build2/variable.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-03-19 11:34:10 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-03-28 16:03:35 +0200
commit9d0d078ff297138622cd2f3f1076f5984395e42b (patch)
treef8b93311adc03410422b3d602ba000822394aebc /build2/variable.cxx
parenteb8b0f33b5e3b8a03d9c1b5230028ba9b9e8c391 (diff)
Add support for pair representation reversibility
Diffstat (limited to 'build2/variable.cxx')
-rw-r--r--build2/variable.cxx74
1 files changed, 47 insertions, 27 deletions
diff --git a/build2/variable.cxx b/build2/variable.cxx
index 39d8cdd..ce06d3e 100644
--- a/build2/variable.cxx
+++ b/build2/variable.cxx
@@ -123,9 +123,9 @@ namespace build2
// bool value
//
bool value_traits<bool>::
- assign (name& n)
+ assign (name& n, name* r)
{
- if (n.simple ())
+ if (r == nullptr && n.simple ())
{
const string& s (n.value);
@@ -145,7 +145,7 @@ namespace build2
{
name& n (v.front ());
- if (value_traits<bool>::assign (n))
+ if (assign<bool> (n))
return true;
}
@@ -178,47 +178,64 @@ namespace build2
// string value
//
bool value_traits<string>::
- assign (name& n)
+ assign (name& n, name* r)
{
- // The below code is quite convoluted because we don't want to
- // modify the name until we know it good (if it is not, then it
- // will most likely be printed by the caller in diagnostics).
-
- // Suspend project qualification.
+ // The goal is to reverse the name into its original representation. The
+ // code is a bit convoluted because we try to avoid extra allocation for
+ // the common cases (unqualified, unpaired simple name or directory).
//
- const string* p (n.proj);
- n.proj = nullptr;
- // Convert directory to string.
+ // We can only convert project-qualified simple and directory names.
//
- if (n.directory ())
+ if (!(n.simple (true) || n.directory (true)) ||
+ !(r == nullptr || r->simple (true) || r->directory (true)))
+ return false;
+
+ if (n.directory (true))
{
n.value = move (n.dir).string (); // Move string out of path.
- // Add / back to the end of the path unless it is already there.
- // Note that the string cannot be empty (n.directory () would
- // have been false).
+ // Add / back to the end of the path unless it is already there. Note
+ // that the string cannot be empty (n.directory () would have been
+ // false).
//
if (!dir_path::traits::is_separator (n.value[n.value.size () - 1]))
n.value += '/';
}
- if (!n.simple ())
- {
- n.proj = p; // Restore.
- return false;
- }
-
// Convert project qualification to its string representation.
//
- if (p != nullptr)
+ if (n.qualified ())
{
- string s (*p);
+ string s (*n.proj);
s += '%';
s += n.value;
s.swap (n.value);
}
+ // The same for the RHS of a pair, if we have one.
+ //
+ if (r != nullptr)
+ {
+ n.value += '@';
+
+ if (r->qualified ())
+ {
+ n.value += *r->proj;
+ n.value += '%';
+ }
+
+ if (r->directory (true))
+ {
+ n.value += r->dir.string ();
+
+ if (!dir_path::traits::is_separator (n.value[n.value.size () - 1]))
+ n.value += '/';
+ }
+ else
+ n.value += r->value;
+ }
+
return true;
}
@@ -236,7 +253,7 @@ namespace build2
{
name& n (v.front ());
- if (value_traits<string>::assign (n))
+ if (assign<string> (n))
return !n.value.empty ();
}
@@ -271,8 +288,11 @@ namespace build2
// dir_path value
//
bool value_traits<dir_path>::
- assign (name& n)
+ assign (name& n, name* r)
{
+ if (r != nullptr)
+ return false;
+
if (n.directory ())
return true;
@@ -304,7 +324,7 @@ namespace build2
{
name& n (v.front ());
- if (value_traits<dir_path>::assign (n))
+ if (assign<dir_path> (n))
return !n.dir.empty ();
}