From 9f56941794837ec63b8732d8d0cae4659528e714 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 3 Jun 2016 15:15:33 +0200 Subject: Treat trailing backslash as directory indicator Note that with this change we broke reversibility for such names, i.e., 'foo\' name will be reversed to 'foo/'. --- build2/parser.cxx | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) (limited to 'build2/parser.cxx') diff --git a/build2/parser.cxx b/build2/parser.cxx index 29af4be..6351cae 100644 --- a/build2/parser.cxx +++ b/build2/parser.cxx @@ -1911,7 +1911,9 @@ namespace build2 continue; } - string::size_type p (name.find_last_of ("/%")); + //@@ PATH + // + string::size_type p (name.find_last_of ("/\\%")); // First take care of project. A project-qualified name is // not very common, so we can afford some copying for the @@ -2001,24 +2003,45 @@ namespace build2 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(). This would also mess up reversibility - // to simple name. + // 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 + // scope::find_target_type(). This would also mess up reversibility to + // simple name. // // @@ TODO: and not quoted // if (p == n) { - // For reversibility to simple name, only treat it as a directory - // if the string is an exact representation. + // @@ PATH: currently we treat backslashes as directory separators + // which means they will be reversed as forward slashes. We have + // no choice here since otherwise Windows paths will be pretty + // much unusable (e.g., configure(C:\foo\@...)). Some ideas on + // how we could mitigate this: + // + // - Only do this in buildspec parsing (but what about command + // line vars). + // + // - When reversing, employ some heuristics to decide which + // slash to use. E.g., if it already contains back slashes. + // Though the problem is with reversing something that isn't + // a path, say 'foo\'. + // + + // Take care of "/" and "...//" (the latter is not reversible). // - if (p != 0 && name[p - 1] != '/') // Take care of the "//" case. + char t ('\0'); + if (p != 0 && !path::traits::is_separator (name[p - 1])) + { + t = name[p]; name.resize (p); // Strip trailing '/'. + } + // For reversibility to simple name, only treat it as a directory + // if the string is an exact representation. + // dir_path dir (move (name), dir_path::exact); if (!dir.empty ()) @@ -2035,8 +2058,8 @@ namespace build2 // Add the trailing slash back and treat it as a simple name. // - if (p != 0 && name[p - 1] != '/') - name.push_back ('/'); + if (t != '\0') + name.push_back (t); } ns.emplace_back (pp1, -- cgit v1.1