diff options
-rw-r--r-- | build/context.cxx | 10 | ||||
-rw-r--r-- | build/parser.cxx | 54 | ||||
-rw-r--r-- | tests/variable/representation/buildfile | 6 | ||||
-rw-r--r-- | tests/variable/representation/test.out | 6 |
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' |