From e42da2a469404e1d421ccee7ccbccb36f363a98b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 30 Sep 2019 13:57:10 +0200 Subject: Handle attributes in switch value and pattern expressions --- libbuild2/parser.cxx | 30 ++++++++++++++++++++++++++++-- libbuild2/parser.hxx | 8 ++++++++ tests/switch/testscript | 38 ++++++++++++++++++++++++++++++++++---- 3 files changed, 70 insertions(+), 6 deletions(-) diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx index a6a5a83..6a5698d 100644 --- a/libbuild2/parser.cxx +++ b/libbuild2/parser.cxx @@ -2105,7 +2105,10 @@ namespace build2 expr e; e.value = - parse_value (t, tt, pattern_mode::expand, "expression", nullptr); + parse_value_with_attributes (t, tt, + pattern_mode::expand, + "expression", + nullptr); if (tt == type::colon) { @@ -2203,7 +2206,7 @@ namespace build2 auto parse_pattern = [this] (token& t, type& tt) { - return parse_value ( + return parse_value_with_attributes ( t, tt, pattern_mode::ignore, "pattern", nullptr); }; @@ -3048,6 +3051,29 @@ namespace build2 } } + value parser:: + parse_value_with_attributes (token& t, token_type& tt, + pattern_mode pmode, + const char* what, + const string* separators) + { + // Parse value attributes if any. Note that it's ok not to have anything + // after the attributes (think [null]). + // + attributes_push (t, tt, true); + + value rhs (tt != type::newline && tt != type::eos + ? parse_value (t, tt, pmode, what, separators) + : value (names ())); + + if (pre_parse_) + return rhs; // Empty. + + value lhs; + apply_value_attributes (nullptr, lhs, move (rhs), type::assign); + return lhs; + } + values parser:: parse_eval (token& t, type& tt, pattern_mode pmode) { diff --git a/libbuild2/parser.hxx b/libbuild2/parser.hxx index 581ad1b..7174b3e 100644 --- a/libbuild2/parser.hxx +++ b/libbuild2/parser.hxx @@ -336,6 +336,14 @@ namespace build2 return v; } + // As above but also handle value attributes. + // + value + parse_value_with_attributes (token& t, token_type& tt, + pattern_mode pmode, + const char* what = "name", + const string* separators = &name_separators); + // Append names and return the indication if the parsed value is not NULL // and whether it is typed (and whether it is a pattern if pattern_mode is // detect). diff --git a/tests/switch/testscript b/tests/switch/testscript index e0ffe8e..221ad47 100644 --- a/tests/switch/testscript +++ b/tests/switch/testscript @@ -68,7 +68,7 @@ EOI d EOO -: basics-matcher +: matcher : $* <>EOO for i: 123 abc @@ -86,7 +86,7 @@ n a EOO -: basics-matcher-arg +: matcher-arg : $* <>EOO for i: abc ABC aBC @@ -103,7 +103,7 @@ a a EOO -: basics-matcher-multiple +: matcher-multiple : $* <>EOO for i: 123 abc @@ -126,7 +126,7 @@ aa EOO #\ -: basics-extractor +: extractor : $* <>EOO for i: 123 abc @@ -145,6 +145,36 @@ d EOO #\ +: attributes +: +$* <>EOO +switch [uint64] 1, 01 +{ + case 01, [uint64] 1 + print 1 +} +EOI +1 +EOO + +: null +: +$* <>EOO +for i: 0 1 +{ + switch ($i == 0 ? [null] : $i) + { + case [null] + print n + case [uint64] 1 + print 1 + } +} +EOI +n +1 +EOO + : empty : $* <