aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/test/script/lexer7
-rw-r--r--build2/test/script/parser.cxx16
2 files changed, 19 insertions, 4 deletions
diff --git a/build2/test/script/lexer b/build2/test/script/lexer
index 65ef297..5597e9a 100644
--- a/build2/test/script/lexer
+++ b/build2/test/script/lexer
@@ -44,8 +44,11 @@ namespace build2
using base_lexer = build2::lexer;
using base_mode = build2::lexer_mode;
- lexer (istream& is, const path& name, lexer_mode m)
- : base_lexer (is, name, nullptr, nullptr, false) {mode (m);}
+ lexer (istream& is,
+ const path& name,
+ lexer_mode m,
+ const char* escapes = nullptr)
+ : base_lexer (is, name, escapes, nullptr, false) {mode (m);}
virtual void
mode (base_mode, char = '\0') override;
diff --git a/build2/test/script/parser.cxx b/build2/test/script/parser.cxx
index df1cd9f..0cc54f7 100644
--- a/build2/test/script/parser.cxx
+++ b/build2/test/script/parser.cxx
@@ -1595,7 +1595,7 @@ namespace build2
// interesting characters (operators plus quotes/escapes),
// then no need to re-lex.
//
- // NOTE: updated quoting (script.cxx:to_stream_q()) if adding
+ // NOTE: update quoting (script.cxx:to_stream_q()) if adding
// any new characters.
//
if (q || s.find_first_of ("|&<>\'\"\\") == string::npos)
@@ -1631,8 +1631,20 @@ namespace build2
name = path (move (n));
}
+ // When re-parsing we do "effective escaping" and only for
+ // ['"\] (quotes plus the backslash itself). In particular,
+ // there is no way to escape redirects, operators, etc. The
+ // idea is to prefer quoting except for passing literal
+ // quotes, for example:
+ //
+ // args = \"&foo\"
+ // cmd $args # cmd &foo
+ //
+ // args = 'x=\"foo bar\"'
+ // cmd $args # cmd x="foo bar"
+ //
istringstream is (s);
- lexer lex (is, name, lexer_mode::command_line);
+ lexer lex (is, name, lexer_mode::command_line, "\'\"\\");
// Treat the first "sub-token" as always separated from what
// we saw earlier.