From da2bd25f0867a54a3b797815b24e44a130ac2b11 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 24 Aug 2015 14:49:10 +0200 Subject: Only treat name as directory if it is reversible --- build/context.cxx | 10 +++------- build/parser.cxx | 54 ++++++++++++++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 29 deletions(-) (limited to 'build') 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 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 + // 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; } -- cgit v1.1