diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2020-06-10 10:01:45 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2020-06-10 10:01:45 +0200 |
commit | 1ea33ab70f88fcfebf388a9a438e3c1e56fbdf0f (patch) | |
tree | 359f61dc51fee77abd1f376b45418501de549104 /libbuild2/parser.cxx | |
parent | d5faeeab1d2115c02a330ac9c95d63ba225faabc (diff) |
Handle special variable names when spelled as $(<char>) rather than $<char>
Diffstat (limited to 'libbuild2/parser.cxx')
-rw-r--r-- | libbuild2/parser.cxx | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index db00633..36e75a3 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -5815,7 +5815,44 @@ namespace build2 // token is a paren or a word, we turn it on and switch to the eval // mode if what we get next is a paren. // + // Also sniff out the special variables string from mode data for + // the ad hoc $() handling below. + // mode (lexer_mode::variable); + + auto special = [s = reinterpret_cast<const char*> (mode_data ())] + (const token& t) -> char + { + char r ('\0'); + + if (s != nullptr) + { + switch (t.type) + { + case type::less: r = '<'; break; + case type::greater: r = '>'; break; + case type::colon: r = ':'; break; + case type::dollar: r = '$'; break; + case type::question: r = '?'; break; + case type::comma: r = ','; break; + case type::log_not: r = '!'; break; + case type::lparen: r = '('; break; + case type::rparen: r = ')'; break; + case type::lcbrace: r = '{'; break; + case type::rcbrace: r = '}'; break; + case type::lsbrace: r = '['; break; + case type::rsbrace: r = ']'; break; + case type::pair_separator: r = t.value[0]; break; + default: break; + } + + if (r != '\0' && strchr (s, r) == nullptr) + r = '\0'; + } + + return r; + }; + next (t, tt); loc = get_location (t); @@ -5838,9 +5875,11 @@ namespace build2 // the variable name even during pre-parse. It should also be // faster. // - if (tt == type::word && peek () == type::rparen) + char c; + if ((tt == type::word || (c = special (t))) && + peek () == type::rparen) { - name = move (t.value); + name = (tt == type::word ? move (t.value) : string (1, c)); next (t, tt); // Get `)`. } else |