aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/context.cxx10
-rw-r--r--build/parser.cxx54
-rw-r--r--tests/variable/representation/buildfile6
-rw-r--r--tests/variable/representation/test.out6
4 files changed, 47 insertions, 29 deletions
diff --git a/build/context.cxx b/build/context.cxx
index 530ac7a..3e3d0c3 100644
--- a/build/context.cxx
+++ b/build/context.cxx
@@ -72,15 +72,11 @@ namespace build
//
variable_pool.find ("subprojects", nullptr, '=');
- // Create global scope. For Win32 we use the empty path since there
- // is no "real" root path. On POSIX, however, this is a real path.
- // See the comment in <build/path-map> for details.
+ // Create global scope. For Win32 this is not a "real" root path.
+ // On POSIX, however, this is a real path. See the comment in
+ // <build/path-map> for details.
//
-#ifdef _WIN32
- global_scope = &scopes[dir_path ()];
-#else
global_scope = &scopes[dir_path ("/")];
-#endif
global_scope->assign ("work") = work;
global_scope->assign ("home") = home;
diff --git a/build/parser.cxx b/build/parser.cxx
index c728cb8..861c755 100644
--- a/build/parser.cxx
+++ b/build/parser.cxx
@@ -899,7 +899,7 @@ namespace build
}
}
- string::size_type n (name.size () - 1);
+ string::size_type n (p != string::npos ? name.size () - 1 : 0);
// See if this is a type name, directory prefix, or both. That
// is, it is followed by '{'.
@@ -964,40 +964,50 @@ namespace build
if (pair != 0 && pair != ns.size ())
ns.push_back (ns[pair - 1]);
+ count = 1;
+
// If it ends with a directory separator, then it is a directory.
// Note that at this stage we don't treat '.' and '..' as special
// (unless they are specified with a directory separator) because
// then we would have ended up treating '.: ...' as a directory
// scope. Instead, this is handled higher up the processing chain,
- // in target_types::find().
+ // in target_types::find(). This would also mess up reversibility
+ // to simple name.
//
// @@ TODO: and not quoted
//
if (p == n)
{
- // On Win32 translate the root path to the special empty path.
- // Search for global_scope for details.
+ // For reversibility to simple name, only treat it as a directory
+ // if the string is an exact representation.
//
-#ifdef _WIN32
- dir_path dir (name != "/" ? dir_path (name) : dir_path ());
-#else
- dir_path dir (name);
-#endif
- if (dp != nullptr)
- dir = *dp / dir;
-
- ns.emplace_back (pp1,
- move (dir),
- (tp != nullptr ? *tp : string ()),
- string ());
+ if (p != 0 && name[p - 1] != '/') // Take care of the "//" case.
+ name.resize (p); // Strip trailing '/'.
+
+ dir_path dir (move (name), dir_path::exact);
+
+ if (!dir.empty ())
+ {
+ if (dp != nullptr)
+ dir = *dp / dir;
+
+ ns.emplace_back (pp1,
+ move (dir),
+ (tp != nullptr ? *tp : string ()),
+ string ());
+ continue;
+ }
+
+ // Add the trailing slash back and treat it as a simple name.
+ //
+ if (p != 0 && name[p - 1] != '/')
+ name.push_back ('/');
}
- else
- ns.emplace_back (pp1,
- (dp != nullptr ? *dp : dir_path ()),
- (tp != nullptr ? *tp : string ()),
- move (name));
- count = 1;
+ ns.emplace_back (pp1,
+ (dp != nullptr ? *dp : dir_path ()),
+ (tp != nullptr ? *tp : string ()),
+ move (name));
continue;
}
diff --git a/tests/variable/representation/buildfile b/tests/variable/representation/buildfile
index 22913d5..7a2c3f2 100644
--- a/tests/variable/representation/buildfile
+++ b/tests/variable/representation/buildfile
@@ -2,6 +2,12 @@
#
val = -L/
val += -L/foo/
+val += ..
+val += ../
+val += /
+val += //
+val += ///
+val += //foo/
#val += dir{-L/}
val += foo%bar
diff --git a/tests/variable/representation/test.out b/tests/variable/representation/test.out
index af12c6f..04d8528 100644
--- a/tests/variable/representation/test.out
+++ b/tests/variable/representation/test.out
@@ -1,5 +1,11 @@
'-L/'
'-L/foo/'
+'..'
+'../'
+'/'
+'//'
+'///'
+'//foo/'
'foo%bar'
'foo%'
'%bar'