aboutsummaryrefslogtreecommitdiff
path: root/libbuild2
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2')
-rw-r--r--libbuild2/lexer+normal.test.testscript36
-rw-r--r--libbuild2/lexer.cxx23
-rw-r--r--libbuild2/parser.cxx10
-rw-r--r--libbuild2/token.cxx1
-rw-r--r--libbuild2/token.hxx1
5 files changed, 65 insertions, 6 deletions
diff --git a/libbuild2/lexer+normal.test.testscript b/libbuild2/lexer+normal.test.testscript
new file mode 100644
index 0000000..c9448c3
--- /dev/null
+++ b/libbuild2/lexer+normal.test.testscript
@@ -0,0 +1,36 @@
+# file : libbuild2/lexer+normal.test.testscript
+# license : MIT; see accompanying LICENSE file
+
+test.arguments = normal
+
+: assign
+:
+$* <:'x=y' >>EOO
+'x'
+=
+'y'
+EOO
+
+: append
+:
+$* <:'x+=y' >>EOO
+'x'
++=
+'y'
+EOO
+
+: prepend
+:
+$* <:'x=+y' >>EOO
+'x'
+=+
+'y'
+EOO
+
+: default-assign
+:
+$* <:'x?=y' >>EOO
+'x'
+?=
+'y'
+EOO
diff --git a/libbuild2/lexer.cxx b/libbuild2/lexer.cxx
index 9989d1e..5ffac54 100644
--- a/libbuild2/lexer.cxx
+++ b/libbuild2/lexer.cxx
@@ -43,8 +43,8 @@ namespace build2
case lexer_mode::normal:
{
a = true;
- s1 = ":<>=+ $(){}#\t\n";
- s2 = " = ";
+ s1 = ":<>=+? $(){}#\t\n";
+ s2 = " == ";
break;
}
case lexer_mode::value:
@@ -182,6 +182,8 @@ namespace build2
// NOTE: remember to update mode(), next_eval() if adding any new special
// characters.
+ // These are special in all the modes handled by this function.
+ //
switch (c)
{
case '\n':
@@ -248,11 +250,10 @@ namespace build2
}
}
- // The following characters are special in the normal, variable, and
+ // The following characters are special in the normal and
// switch_expressions modes.
//
if (m == lexer_mode::normal ||
- m == lexer_mode::variable ||
m == lexer_mode::switch_expressions ||
m == lexer_mode::case_patterns)
{
@@ -262,9 +263,9 @@ namespace build2
}
}
- // The following characters are special in the normal and variable modes.
+ // The following characters are special in the normal mode.
//
- if (m == lexer_mode::normal || m == lexer_mode::variable)
+ if (m == lexer_mode::normal)
{
switch (c)
{
@@ -285,6 +286,16 @@ namespace build2
get ();
return make_token (type::append);
}
+ break;
+ }
+ case '?':
+ {
+ if (peek () == '=')
+ {
+ get ();
+ return make_token (type::default_assign);
+ }
+ break;
}
}
}
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx
index 91f2d5c..ec5e161 100644
--- a/libbuild2/parser.cxx
+++ b/libbuild2/parser.cxx
@@ -2749,6 +2749,16 @@ namespace build2
void parser::
parse_variable (token& t, type& tt, const variable& var, type kind)
{
+ // @@ TODO: yet unclear what should the logic be here: we could expect
+ // the called to handle skipping or skip it here. Need to see how
+ // everything fits.
+ //
+ // Note that here we treat default assignment (?=) the same as normal
+ // assignment expecting the caller to check whether the assignment is
+ // necessary (and skipping evaluating the value altogether otherwise).
+ //
+ assert (kind != type::default_assign);
+
value rhs (parse_variable_value (t, tt));
value& lhs (
diff --git a/libbuild2/token.cxx b/libbuild2/token.cxx
index 0f9a189..4975a02 100644
--- a/libbuild2/token.cxx
+++ b/libbuild2/token.cxx
@@ -41,6 +41,7 @@ namespace build2
case token_type::assign: os << q << '=' << q; break;
case token_type::prepend: os << q << "=+" << q; break;
case token_type::append: os << q << "+=" << q; break;
+ case token_type::default_assign: os << q << "?=" << q; break;
case token_type::equal: os << q << "==" << q; break;
case token_type::not_equal: os << q << "!=" << q; break;
diff --git a/libbuild2/token.hxx b/libbuild2/token.hxx
index 4cf1f51..e48c088 100644
--- a/libbuild2/token.hxx
+++ b/libbuild2/token.hxx
@@ -53,6 +53,7 @@ namespace build2
assign, // =
prepend, // =+
append, // +=
+ default_assign, // ?=
equal, // ==
not_equal, // !=