aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-10-20 15:06:48 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-11-04 09:26:33 +0200
commit62436ec452ea4453fdffc7cda2c7bfcdcbdd5a71 (patch)
treeb94421724961e94c18121c2d7ae8cc14ee11c075
parent78406602be0ce392224dd3735ad9a9442df572f7 (diff)
Add support for ignoring separators inside names
-rw-r--r--build2/parser25
-rw-r--r--build2/parser.cxx30
2 files changed, 38 insertions, 17 deletions
diff --git a/build2/parser b/build2/parser
index 59cdac2..4b84ae4 100644
--- a/build2/parser
+++ b/build2/parser
@@ -157,20 +157,28 @@ namespace build2
// If chunk is true, then parse the smallest but complete, name-wise,
// chunk of input. Note that in this case you may still end up with
- // multiple names, for example, {foo bar} or $foo.
+ // multiple names, for example, {foo bar} or $foo. In the pre-parse mode
+ // always return empty list of names.
//
// The what argument is used in diagnostics (e.g., "expected <what>
// instead of ...".
//
- // In pre-parse mode always return empty list of names.
+ // The separators argument specifies the special characters to recognize
+ // inside the name. These can be the directory separators and the '%'
+ // project separator. Note that even if it is NULL, the result may still
+ // contain non-simple names due to variable expansions.
//
+ static const string name_separators;
+
names
parse_names (token& t, token_type& tt,
bool chunk = false,
- const char* what = "name")
+ const char* what = "name",
+ const string* separators = &name_separators)
{
names ns;
- parse_names (t, tt, ns, chunk, what, 0, nullptr, nullptr, nullptr);
+ parse_names (
+ t, tt, ns, chunk, what, separators, 0, nullptr, nullptr, nullptr);
return ns;
}
@@ -180,10 +188,13 @@ namespace build2
// context evaluation.
//
value
- parse_names_value (token& t, token_type& tt, const char* what = "name")
+ parse_names_value (token& t, token_type& tt,
+ const char* what = "name",
+ const string* separators = &name_separators)
{
names ns;
- return parse_names (t, tt, ns, false, what, 0, nullptr, nullptr, nullptr)
+ return parse_names (
+ t, tt, ns, false, what, separators, 0, nullptr, nullptr, nullptr)
? value (move (ns))
: value (nullptr);
}
@@ -195,6 +206,7 @@ namespace build2
names&,
bool chunk = false,
const char* what = "name",
+ const string* separators = &name_separators,
size_t pair = 0,
const string* prj = nullptr,
const dir_path* dir = nullptr,
@@ -204,6 +216,7 @@ namespace build2
parse_names_trailer (token&, token_type&,
names&,
const char* what,
+ const string* separators,
size_t pair,
const string* prj,
const dir_path* dir,
diff --git a/build2/parser.cxx b/build2/parser.cxx
index dfe85be..64907b4 100644
--- a/build2/parser.cxx
+++ b/build2/parser.cxx
@@ -769,7 +769,7 @@ namespace build2
next (t, tt);
const location l (get_location (t));
names ns (tt != type::newline && tt != type::eos
- ? parse_names (t, tt)
+ ? parse_names (t, tt, false, "path", nullptr)
: names ());
for (name& n: ns)
@@ -845,7 +845,7 @@ namespace build2
next (t, tt);
const location l (get_location (t));
names ns (tt != type::newline && tt != type::eos
- ? parse_names (t, tt)
+ ? parse_names (t, tt, false, "path", nullptr)
: names ());
for (name& n: ns)
@@ -1176,7 +1176,7 @@ namespace build2
next (t, tt);
const location l (get_location (t));
names ns (tt != type::newline && tt != type::eos
- ? parse_names (t, tt)
+ ? parse_names (t, tt, false, "module", nullptr)
: names ());
for (auto i (ns.begin ()); i != ns.end (); ++i)
@@ -1315,7 +1315,7 @@ namespace build2
// Parse as names to get variable expansion, evaluation, etc.
//
const location nsl (get_location (t));
- names ns (parse_names (t, tt));
+ names ns (parse_names (t, tt, false, "expression", nullptr));
// Should evaluate to 'true' or 'false'.
//
@@ -1841,7 +1841,7 @@ namespace build2
if (tt != type::rsbrace && tt != type::newline && tt != type::eos)
{
- names ns (parse_names (t, tt));
+ names ns (parse_names (t, tt, false, "key-value", nullptr));
if (!pre_parse_)
{
@@ -1904,6 +1904,7 @@ namespace build2
parse_names_trailer (token& t, type& tt,
names& ns,
const char* what,
+ const string* separators,
size_t pair,
const string* pp,
const dir_path* dp,
@@ -1918,6 +1919,7 @@ namespace build2
ns,
false,
what,
+ separators,
(pair != 0
? pair
: (ns.empty () || ns.back ().pair ? ns.size () : 0)),
@@ -1935,7 +1937,8 @@ namespace build2
const location loc (get_location (t));
names x; // Parse into a separate list of names.
- parse_names_trailer (t, tt, x, what, 0, nullptr, nullptr, nullptr);
+ parse_names_trailer (
+ t, tt, x, what, separators, 0, nullptr, nullptr, nullptr);
if (size_t n = x.size ())
{
@@ -2015,7 +2018,7 @@ namespace build2
// Slashe(s) plus '%'. Note that here we assume '/' is there since that's
// in our buildfile "syntax".
//
- static const string name_separators (
+ const string parser::name_separators (
string (path::traits::directory_separators) + '%');
bool parser::
@@ -2023,6 +2026,7 @@ namespace build2
names& ns,
bool chunk,
const char* what,
+ const string* separators,
size_t pair,
const string* pp,
const dir_path* dp,
@@ -2116,9 +2120,11 @@ namespace build2
if (!pre_parse_)
{
- // Find slash or %.
+ // Find a separator (slash or %).
//
- string::size_type p (name.find_last_of (name_separators));
+ string::size_type p (separators != nullptr
+ ? name.find_last_of (*separators)
+ : string::npos);
// First take care of project. A project-qualified name is
// not very common, so we can afford some copying for the
@@ -2194,7 +2200,8 @@ namespace build2
tp1 = &t1;
}
- count = parse_names_trailer (t, tt, ns, what, pair, pp1, dp1, tp1);
+ count = parse_names_trailer (
+ t, tt, ns, what, separators, pair, pp1, dp1, tp1);
tt = peek ();
continue;
}
@@ -2571,7 +2578,8 @@ namespace build2
//
if (tt == type::lcbrace)
{
- count = parse_names_trailer (t, tt, ns, what, pair, pp, dp, tp);
+ count = parse_names_trailer (
+ t, tt, ns, what, separators, pair, pp, dp, tp);
tt = peek ();
continue;
}