aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/export.build2
-rw-r--r--build2/dump.cxx3
-rw-r--r--build2/parser.cxx321
-rw-r--r--build2/parser.hxx5
-rw-r--r--old-tests/amalgam/libtest/build/export.build2
-rw-r--r--old-tests/attribute/buildfile4
-rw-r--r--old-tests/cli/lib/libtest/build/export.build2
-rw-r--r--old-tests/cli/lib/libtest/test/buildfile2
-rw-r--r--old-tests/install/lib/libtest/build/export.build2
-rw-r--r--old-tests/install/lib/libtest/build/root.build2
-rw-r--r--old-tests/postponed/buildfile2
-rw-r--r--old-tests/scope/amalgamation/l1/build/bootstrap.build2
-rw-r--r--old-tests/scope/amalgamation/l1/buildfile8
-rw-r--r--old-tests/semantics/include/includer5
-rw-r--r--old-tests/semantics/source/sourcer4
-rwxr-xr-xold-tests/test.sh1
-rw-r--r--old-tests/variable/override/buildfile2
-rw-r--r--old-tests/variable/override/p/buildfile2
-rw-r--r--old-tests/variable/qualified/buildfile27
-rw-r--r--old-tests/variable/qualified/test.out12
-rwxr-xr-xold-tests/variable/qualified/test.sh3
-rw-r--r--old-tests/variable/type-pattern-append/buildfile4
-rw-r--r--old-tests/variable/type/buildfile4
-rw-r--r--tests/eval/qual.test2
-rw-r--r--tests/search/dir/testscript4
-rw-r--r--tests/variable/override/testscript6
-rw-r--r--tests/variable/scope-specific/buildfile5
-rw-r--r--tests/variable/scope-specific/testscript54
-rw-r--r--tests/variable/target-specific/buildfile5
-rw-r--r--tests/variable/target-specific/testscript61
30 files changed, 366 insertions, 192 deletions
diff --git a/build/export.build b/build/export.build
index dc3401a..dc77dee 100644
--- a/build/export.build
+++ b/build/export.build
@@ -2,7 +2,7 @@
# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
# license : MIT; see accompanying LICENSE file
-$out_root/:
+$out_root/
{
include build2/
}
diff --git a/build2/dump.cxx b/build2/dump.cxx
index 263f1b5..07ca17c 100644
--- a/build2/dump.cxx
+++ b/build2/dump.cxx
@@ -340,7 +340,8 @@ namespace build2
os << ind << (rd.empty () ? dir_path (".") : rd);
}
- os << ":" << endl << ind << '{';
+ os << endl
+ << ind << '{';
const dir_path* orb (relative_base);
relative_base = &d;
diff --git a/build2/parser.cxx b/build2/parser.cxx
index bb7123c..071703a 100644
--- a/build2/parser.cxx
+++ b/build2/parser.cxx
@@ -68,6 +68,8 @@ namespace build2
}
}
+ explicit operator bool () const {return p_ != nullptr;}
+
// Note: move-assignable to empty only.
//
enter_scope (enter_scope&& x) {*this = move (x);}
@@ -439,9 +441,24 @@ namespace build2
}
}
- const location nloc (get_location (t));
+ location nloc (get_location (t));
names ns (parse_names (t, tt, pattern_mode::ignore));
+ // Allow things like function calls that don't result in anything.
+ //
+ if (tt == type::newline && ns.empty ())
+ {
+ if (at.first)
+ fail (at.second) << "standalone attributes";
+ else
+ attributes_pop ();
+
+ next (t, tt);
+ continue;
+ }
+
+ // If we have a colon, then this is target-related.
+ //
if (tt == type::colon)
{
// While '{}:' means empty name, '{$x}:' where x is empty list
@@ -454,7 +471,7 @@ namespace build2
if (tt == type::newline)
{
- // See if this is a directory/target scope.
+ // See if this is a target scope.
//
if (peek () == type::lcbrace)
{
@@ -465,50 +482,15 @@ namespace build2
if (next (t, tt) != type::newline)
fail (t) << "expected newline after {";
- // See if this is a directory or target scope. Different
- // things can appear inside depending on which one it is.
- //
- bool dir (false);
- for (const auto& n: ns)
- {
- if (n.directory ())
- {
- if (ns.size () != 1)
- {
- // @@ TODO: point to name (and above).
- //
- fail (nloc) << "multiple names in directory scope";
- }
-
- dir = true;
- }
- }
-
- next (t, tt);
-
- if (dir)
- {
- // Directory scope.
- //
- if (at.first)
- fail (at.second) << "attributes before directory scope";
- else
- attributes_pop ();
-
- // Can contain anything that a top level can.
- //
- enter_scope sg (*this, move (ns[0].dir));
- parse_clause (t, tt);
- }
+ if (at.first)
+ fail (at.second) << "attributes before target scope";
else
- {
- if (at.first)
- fail (at.second) << "attributes before target scope";
- else
- attributes_pop ();
+ attributes_pop ();
- // @@ TODO: target scope (also prerequisite scope below).
- }
+ // @@ TODO: target scope (also prerequisite scope below).
+ //
+ fail (nloc) << "target scopes are not yet supported" <<
+ info << "if migrating, remove ':'";
if (tt != type::rcbrace)
fail (t) << "expected } instead of " << t;
@@ -525,15 +507,14 @@ namespace build2
// If this is not a scope, then it is a target without any
// prerequisites. Fall through.
- //
}
// Dependency declaration (including prerequisite-specific variable
- // assignment) or scope/target-specific variable assignment.
+ // assignment) or target-specific variable assignment.
//
if (at.first)
- fail (at.second) << "attributes before target/scope";
+ fail (at.second) << "attributes before target";
else
attributes_pop ();
@@ -546,32 +527,28 @@ namespace build2
tt == type::newline ||
tt == type::eos)
{
- // @@ PAT: currently we pattern-expand scope/target-specific vars.
+ // @@ PAT: currently we pattern-expand target-specific vars.
//
const location ploc (get_location (t));
names pns (tt != type::newline && tt != type::eos
? parse_names (t, tt, pattern_mode::expand)
: names ());
- // Scope/target-specific variable assignment.
+ // Target-specific variable assignment.
//
if (tt == type::assign || tt == type::prepend || tt == type::append)
{
token at (t);
type att (tt);
- const variable& var (
- var_pool.rw (*scope_).insert (
- parse_variable_name (move (pns), ploc),
- true /* overridable */));
-
+ const variable& var (parse_variable_name (move (pns), ploc));
apply_variable_attributes (var);
- // If we have multiple targets/scopes, then we save the value
- // tokens when parsing the first one and then replay them for
- // the subsequent. We have to do it this way because the value
- // may contain variable expansions that would be sensitive to
- // the target/scope context in which they are evaluated.
+ // If we have multiple targets, then we save the value tokens when
+ // parsing the first one and then replay them for the subsequent.
+ // We have to do it this way because the value may contain
+ // variable expansions that would be sensitive to the target/scope
+ // context in which they are evaluated.
//
// Note: watch out for an out-qualified single target (two names).
//
@@ -583,12 +560,18 @@ namespace build2
name& n (*i);
if (n.qualified ())
- fail (nloc) << "project name in scope/target " << n;
+ fail (nloc) << "project name in target " << n;
if (n.directory () && !n.pair) // Not out-qualified.
{
// Scope variable.
//
+
+ // @@ TODO: break for now before changing to target.
+ //
+ fail (nloc) << "change of semantics: will be target, not scope" <<
+ info << "remove ':' for scope semantics";
+
if (var.visibility == variable_visibility::target)
fail (ploc) << "variable " << var << " has target "
<< "visibility but assigned in a scope" <<
@@ -840,11 +823,7 @@ namespace build2
type at (tt);
- const variable& var (
- var_pool.rw (*scope_).insert (
- parse_variable_name (move (vns), vloc),
- true /* overridable */));
-
+ const variable& var (parse_variable_name (move (vns), vloc));
apply_variable_attributes (var);
// We handle multiple targets and/or prerequisites by replaying
@@ -889,40 +868,124 @@ namespace build2
// Variable assignment.
//
- if (tt == type::assign || tt == type::prepend || tt == type::append)
+ // This can take any of the following forms:
+ //
+ // x = y
+ // foo/ x = y (ns will have two elements)
+ // foo/ [attrs] x = y (tt will be '[')
+ //
+ // In the future we may also want to support:
+ //
+ // foo/ bar/ x = y
+ //
+ if (tt == type::assign || tt == type::prepend || tt == type::append ||
+ tt == type::lsbrace)
{
- const variable& var (
- var_pool.rw (*scope_).insert (
- parse_variable_name (move (ns), nloc),
- true /* overridable */));
+ // Detect and handle the directory scope. If things look off, then we
+ // let parse_variable_name() complain.
+ //
+ dir_path d;
- apply_variable_attributes (var);
+ if ((ns.size () == 2 && ns[0].directory ()) ||
+ (ns.size () == 1 && ns[0].directory () && tt == type::lsbrace))
+ {
+ if (at.first)
+ fail (at.second) << "attributes before scope directory";
- if (var.visibility == variable_visibility::target)
- fail (nloc) << "variable " << var << " has target visibility but "
- << "assigned in a scope" <<
- info << "consider changing to '*: " << var << "'";
+ if (tt == type::lsbrace)
+ {
+ attributes_pop ();
+ attributes_push (t, tt);
- parse_variable (t, tt, var, tt);
+ d = move (ns[0].dir);
+ nloc = get_location (t);
+ ns = parse_names (t, tt, pattern_mode::ignore);
- if (tt == type::newline)
- next (t, tt);
- else if (tt != type::eos)
- fail (t) << "expected newline instead of " << t;
+ // It got to be a variable assignment.
+ //
+ if (tt != type::assign &&
+ tt != type::prepend &&
+ tt != type::append)
+ fail (t) << "variable assignment expected instead of " << t;
+ }
+ else
+ {
+ d = move (ns[0].dir);
+ ns.erase (ns.begin ());
+ }
+ }
- continue;
+ if (tt != type::lsbrace)
+ {
+ const variable& var (parse_variable_name (move (ns), nloc));
+ apply_variable_attributes (var);
+
+ if (var.visibility == variable_visibility::target)
+ fail (nloc) << "variable " << var << " has target visibility but "
+ << "assigned in a scope" <<
+ info << "consider changing to '*: " << var << "'";
+
+ {
+ enter_scope sg (d.empty ()
+ ? enter_scope ()
+ : enter_scope (*this, move (d)));
+ parse_variable (t, tt, var, tt);
+ }
+
+ if (tt == type::newline)
+ next (t, tt);
+ else if (tt != type::eos)
+ fail (t) << "expected newline instead of " << t;
+
+ continue;
+ }
+
+ // Not "our" attribute, see if anyone else likes it.
}
- // Allow things like function calls that don't result in anything.
+ // See if this is a directory scope.
//
- if (tt == type::newline && ns.empty ())
+ if (tt == type::newline && peek () == type::lcbrace)
{
+ if (ns.size () != 1)
+ fail (nloc) << "multiple scope directories";
+
+ name& n (ns[0]);
+
+ if (!n.directory ())
+ fail (nloc) << "scope directory expected";
+
+ next (t, tt);
+
+ // Should be on its own line.
+ //
+ if (next (t, tt) != type::newline)
+ fail (t) << "expected newline after {";
+
+ next (t, tt);
+
if (at.first)
- fail (at.second) << "standalone attributes";
+ fail (at.second) << "attributes before scope directory";
else
attributes_pop ();
- next (t, tt);
+ // Can contain anything that a top level can.
+ //
+ {
+ enter_scope sg (*this, move (n.dir));
+ parse_clause (t, tt);
+ }
+
+ if (tt != type::rcbrace)
+ fail (t) << "expected } instead of " << t;
+
+ // Should be on its own line.
+ //
+ if (next (t, tt) == type::newline)
+ next (t, tt);
+ else if (tt != type::eos)
+ fail (t) << "expected newline after }";
+
continue;
}
@@ -1726,11 +1789,7 @@ namespace build2
if (tt != type::colon)
fail (t) << "expected ':' instead of " << t << " after variable name";
- const variable& var (
- var_pool.rw (*scope_).insert (
- parse_variable_name (move (vns), vloc),
- true /* overridable */));
-
+ const variable& var (parse_variable_name (move (vns), vloc));
apply_variable_attributes (var);
if (var.visibility == variable_visibility::target)
@@ -2020,7 +2079,7 @@ namespace build2
next (t, tt); // Swallow newline.
}
- string parser::
+ const variable& parser::
parse_variable_name (names&& ns, const location& l)
{
// The list should contain a single, simple name.
@@ -2030,11 +2089,15 @@ namespace build2
string& n (ns[0].value);
+ //@@ OLD
if (n.front () == '.') // Fully qualified name.
- return string (n, 1, string::npos);
+ n.erase (0, 1);
else
+ {
//@@ TODO: append namespace if any.
- return move (n);
+ }
+
+ return var_pool.rw (*scope_).insert (move (n), true /* overridable */);
}
void parser::
@@ -2601,12 +2664,12 @@ namespace build2
}
// If this is the first expression then handle the eval-qual special case
- // (scope/target qualified name represented as a special ':'-style pair).
+ // (target-qualified name represented as a special ':'-style pair).
//
if (first && tt == type::colon)
{
if (at.first)
- fail (at.second) << "attributes before qualified variable name";
+ fail (at.second) << "attributes before target-qualified variable name";
attributes_pop ();
@@ -2621,7 +2684,7 @@ namespace build2
return v; // Empty.
if (v.type != nullptr || !v || v.as<names> ().size () != 1)
- fail (l) << "expected scope/target before ':'";
+ fail (l) << "expected target before ':'";
if (n.type != nullptr || !n || n.as<names> ().size () != 1)
fail (nl) << "expected variable name after ':'";
@@ -3897,24 +3960,32 @@ namespace build2
vector_view<build2::name> ns (reverse (v, storage)); // Movable.
size_t n (ns.size ());
- // Make sure the result of evaluation is a potentially-qualified
- // simple name.
+ // We cannot handle scope-qualification in the eval context as
+ // we do for target-qualification (see eval-qual) since then we
+ // would be treating all paths as qualified variables. So we
+ // have to do it here.
//
- if (n > 2 ||
- (n == 2 && ns[0].pair != ':') ||
- !ns[n - 1].simple ())
- fail (loc) << "expected variable/function name instead of '"
- << ns << "'";
-
- if (n == 2)
+ if (n == 2 && ns[0].pair == ':') // $(foo: x)
{
qual = move (ns[0]);
if (qual.empty ())
fail (loc) << "empty variable/function qualification";
-
- qual.pair = '\0'; // We broke up the pair.
}
+ else if (n == 2 && ns[0].directory ()) // $(foo/ x)
+ {
+ qual = move (ns[0]);
+ qual.pair = '/';
+ }
+ else if (n > 1)
+ fail (loc) << "expected variable/function name instead of '"
+ << ns << "'";
+
+ // Note: checked for empty below.
+ //
+ if (!ns[n - 1].simple ())
+ fail (loc) << "expected variable/function name instead of '"
+ << ns[n - 1] << "'";
name = move (ns[n - 1].value);
}
@@ -3941,7 +4012,7 @@ namespace build2
next (t, tt); // Get '('.
// @@ Should we use (target/scope) qualification (of name) as the
- // context in which to call the function?
+ // context in which to call the function? Hm, interesting...
//
values args (parse_eval (t, tt, pmode));
tt = peek ();
@@ -4601,13 +4672,13 @@ namespace build2
{
tracer trace ("parser::lookup_variable", &path_);
- // Process variable name.
+ // Process variable name. @@ OLD
//
if (name.front () == '.') // Fully namespace-qualified name.
name.erase (0, 1);
else
{
- //@@ TODO: append namespace if any.
+ //@@ TODO : append namespace if any.
}
// If we are qualified, it can be a scope or a target.
@@ -4615,13 +4686,29 @@ namespace build2
enter_scope sg;
enter_target tg;
- if (qual.directory ()) //@@ OUT
- sg = enter_scope (*this, move (qual.dir));
- else if (!qual.empty ())
- // @@ OUT TODO
- //
- tg = enter_target (
- *this, move (qual), build2::name (), true, loc, trace);
+ if (!qual.empty ())
+ {
+ switch (qual.pair)
+ {
+ case '/':
+ {
+ assert (qual.directory ());
+ sg = enter_scope (*this, move (qual.dir));
+ break;
+ }
+ case ':':
+ {
+ qual.pair = '\0';
+
+ // @@ OUT TODO
+ //
+ tg = enter_target (
+ *this, move (qual), build2::name (), true, loc, trace);
+ break;
+ }
+ default: assert (false);
+ }
+ }
// Lookup.
//
diff --git a/build2/parser.hxx b/build2/parser.hxx
index 1b39491..acf507e 100644
--- a/build2/parser.hxx
+++ b/build2/parser.hxx
@@ -117,7 +117,7 @@ namespace build2
void
parse_variable (token&, token_type&, const variable&, token_type);
- string
+ const variable&
parse_variable_name (names&&, const location&);
// Note: calls attributes_push() that the caller must pop.
@@ -368,6 +368,9 @@ namespace build2
// Customization hooks.
//
protected:
+ // If qual is not empty, then its pair member should indicate the kind
+ // of qualification: ':' -- target, '/' -- scope.
+ //
virtual lookup
lookup_variable (name&& qual, string&& name, const location&);
diff --git a/old-tests/amalgam/libtest/build/export.build b/old-tests/amalgam/libtest/build/export.build
index b95e409..c1c6a8b 100644
--- a/old-tests/amalgam/libtest/build/export.build
+++ b/old-tests/amalgam/libtest/build/export.build
@@ -1,4 +1,4 @@
-$out_root/:
+$out_root/
{
include buildfile
}
diff --git a/old-tests/attribute/buildfile b/old-tests/attribute/buildfile
index 6675894..7338641 100644
--- a/old-tests/attribute/buildfile
+++ b/old-tests/attribute/buildfile
@@ -6,10 +6,10 @@
#[foo=dir/file{bar}] # error: invalid attribute key
#[foo] print hello # error: attributes before print
-#[foo]./: # error: attributes before directory scope
+#[foo]./ # error: attributes before directory scope
#{
#}
-#[foo]./: # error: attributes before target/scope
+#[foo]./: # error: attributes before target scope
#./: [foo] buildfile # error: attributes before prerequisites
#import [foo] libz # error: attributes without variable
diff --git a/old-tests/cli/lib/libtest/build/export.build b/old-tests/cli/lib/libtest/build/export.build
index e8b12b3..f5e50c7 100644
--- a/old-tests/cli/lib/libtest/build/export.build
+++ b/old-tests/cli/lib/libtest/build/export.build
@@ -1,4 +1,4 @@
-$out_root/:
+$out_root/
{
include test/
}
diff --git a/old-tests/cli/lib/libtest/test/buildfile b/old-tests/cli/lib/libtest/test/buildfile
index a7667e6..4cf5ebe 100644
--- a/old-tests/cli/lib/libtest/test/buildfile
+++ b/old-tests/cli/lib/libtest/test/buildfile
@@ -6,7 +6,7 @@ cli.cxx{base}: cli{base}
cli.options += -I $src_root --include-with-brackets
-extra/:
+extra/
{
cxx{test} hxx{test}: cli{test}
cli.options += --include-prefix test/extra --guard-prefix TEST_EXTRA \
diff --git a/old-tests/install/lib/libtest/build/export.build b/old-tests/install/lib/libtest/build/export.build
index e8b12b3..f5e50c7 100644
--- a/old-tests/install/lib/libtest/build/export.build
+++ b/old-tests/install/lib/libtest/build/export.build
@@ -1,4 +1,4 @@
-$out_root/:
+$out_root/
{
include test/
}
diff --git a/old-tests/install/lib/libtest/build/root.build b/old-tests/install/lib/libtest/build/root.build
index 20536a2..9cf16a1 100644
--- a/old-tests/install/lib/libtest/build/root.build
+++ b/old-tests/install/lib/libtest/build/root.build
@@ -4,7 +4,7 @@ hxx{*}: extension = hxx
ixx{*}: extension = ixx
cxx{*}: extension = cxx
-tests/:
+tests/
{
exe{*}: test = true
install = false
diff --git a/old-tests/postponed/buildfile b/old-tests/postponed/buildfile
index 53873aa..437d85f 100644
--- a/old-tests/postponed/buildfile
+++ b/old-tests/postponed/buildfile
@@ -2,4 +2,4 @@ using cxx
exe{driver}: cxx{driver} fsdir{$out_root/out}
-./: exe{driver}
+./: exe{driver}
diff --git a/old-tests/scope/amalgamation/l1/build/bootstrap.build b/old-tests/scope/amalgamation/l1/build/bootstrap.build
index 6bde838..81499d4 100644
--- a/old-tests/scope/amalgamation/l1/build/bootstrap.build
+++ b/old-tests/scope/amalgamation/l1/build/bootstrap.build
@@ -8,7 +8,7 @@ using config
# If they are the same, then this scope will simply
# be "upgraded".
#
-$src_root/../:
+$src_root/../
{
print 0: $project
print 0: $src_base
diff --git a/old-tests/scope/amalgamation/l1/buildfile b/old-tests/scope/amalgamation/l1/buildfile
index 55d8c64..c6d3506 100644
--- a/old-tests/scope/amalgamation/l1/buildfile
+++ b/old-tests/scope/amalgamation/l1/buildfile
@@ -1,6 +1,6 @@
# Out of amalgamation.
#
-../../:
+../../
{
print -1: $project
print -1: $src_base
@@ -9,7 +9,7 @@
# In amalgamation.
#
-../s/:
+../s/
{
print 0: $project
print 0: $src_base
@@ -18,7 +18,7 @@
# In project.
#
-s/:
+s/
{
print 1: $project
print 1: $src_base
@@ -27,7 +27,7 @@ s/:
# In sub-project.
#
-l2/s/:
+l2/s/
{
print 2: $project
print 2: $src_base
diff --git a/old-tests/semantics/include/includer b/old-tests/semantics/include/includer
index 70527a5..700076e 100644
--- a/old-tests/semantics/include/includer
+++ b/old-tests/semantics/include/includer
@@ -2,9 +2,10 @@ include
include includee1
include includee1 ../include/includee2 # includee1 is skipped
include nested/includee3
-nested/:
+nested/
{
include includee5
include ../includee2 # skipped
}
-:
+
+./:
diff --git a/old-tests/semantics/source/sourcer b/old-tests/semantics/source/sourcer
index eb1310e..030e9bc 100644
--- a/old-tests/semantics/source/sourcer
+++ b/old-tests/semantics/source/sourcer
@@ -1,9 +1,9 @@
source
source sourcee1
source sourcee1 ../source/sourcee2
-nested/:
+nested/
{
source sourcee3
source ../sourcee1
}
-:
+./:
diff --git a/old-tests/test.sh b/old-tests/test.sh
index f02291a..96a7ed3 100755
--- a/old-tests/test.sh
+++ b/old-tests/test.sh
@@ -24,6 +24,5 @@ test "variable/expansion"
test "variable/null"
test "variable/override"
test "variable/prepend"
-test "variable/qualified"
test "variable/type"
test "variable/type-pattern-append"
diff --git a/old-tests/variable/override/buildfile b/old-tests/variable/override/buildfile
index c090e81..2889f69 100644
--- a/old-tests/variable/override/buildfile
+++ b/old-tests/variable/override/buildfile
@@ -20,7 +20,7 @@ elif ($a == pr)
print ". :" $v
-d/:
+d/
{
if ($d_a == as)
{
diff --git a/old-tests/variable/override/p/buildfile b/old-tests/variable/override/p/buildfile
index 527b9ae..5b84925 100644
--- a/old-tests/variable/override/p/buildfile
+++ b/old-tests/variable/override/p/buildfile
@@ -13,7 +13,7 @@ elif ($p_a == pr)
print "p :" $v
-d/:
+d/
{
if ($p_d_a == as)
{
diff --git a/old-tests/variable/qualified/buildfile b/old-tests/variable/qualified/buildfile
deleted file mode 100644
index 870b808..0000000
--- a/old-tests/variable/qualified/buildfile
+++ /dev/null
@@ -1,27 +0,0 @@
-#v = (foo:) # error: variable name expected before ':'
-#v = (:bar) # error: scope/target expected after ':'
-
-print (foo:bar)
-print (foo :bar)
-print (foo: bar)
-print (foo : bar)
-print (foo/: bar)
-print (foo/file{fox}: bar)
-
-bar=bar
-sub/:
-{
- bar=Bar
- fsdir{./}: bar=BAR
- file{x}: bar=BBAARR
-}
-
-print $(./:bar)
-print $(sub/:bar)
-print $(fsdir{sub/}:bar)
-print $(sub/file{x}:bar)
-
-print $(sub/file{y}:bar)
-print $(sup/:bar)
-
-./:
diff --git a/old-tests/variable/qualified/test.out b/old-tests/variable/qualified/test.out
deleted file mode 100644
index 5bf062e..0000000
--- a/old-tests/variable/qualified/test.out
+++ /dev/null
@@ -1,12 +0,0 @@
-foo:bar
-foo:bar
-foo:bar
-foo:bar
-foo/:bar
-foo/file{fox}:bar
-bar
-Bar
-BAR
-BBAARR
-Bar
-bar
diff --git a/old-tests/variable/qualified/test.sh b/old-tests/variable/qualified/test.sh
deleted file mode 100755
index c745b76..0000000
--- a/old-tests/variable/qualified/test.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-b -q | diff --strip-trailing-cr -u test.out -
diff --git a/old-tests/variable/type-pattern-append/buildfile b/old-tests/variable/type-pattern-append/buildfile
index a91b340..348f70f 100644
--- a/old-tests/variable/type-pattern-append/buildfile
+++ b/old-tests/variable/type-pattern-append/buildfile
@@ -41,7 +41,7 @@ x = $(dir{./}:x5)
print $(dir{./}:x5)
x6 = [string] a
-sub/:
+sub/
{
dir{*}: x6 += b
dir{*}: x6 += [null]
@@ -50,7 +50,7 @@ sub/:
x7 = [string] b
dir{*}: x7 =+ a
-sub/:
+sub/
{
dir{*}: x7 += c
print $(dir{./}:x7)
diff --git a/old-tests/variable/type/buildfile b/old-tests/variable/type/buildfile
index a22cddd..ef56f19 100644
--- a/old-tests/variable/type/buildfile
+++ b/old-tests/variable/type/buildfile
@@ -54,14 +54,14 @@ v4b =+ [uint64] 01
print $v4b # 2
v5a = 01
-sub/:
+sub/
{
v5a += [uint64] 01
print $v5a # 2
}
v5b = 01
-sub/:
+sub/
{
v5b =+ [uint64] 01
print $v5b # 2
diff --git a/tests/eval/qual.test b/tests/eval/qual.test
index f6e6592..341b315 100644
--- a/tests/eval/qual.test
+++ b/tests/eval/qual.test
@@ -12,7 +12,7 @@ $* <'print (foo/dir{}: bar)' >'dir{foo/}:bar' : scope
: attribute
:
$* <'([string] foo:bar)' 2>>EOE != 0
-<stdin>:1:2: error: attributes before qualified variable name
+<stdin>:1:2: error: attributes before target-qualified variable name
EOE
: leader
diff --git a/tests/search/dir/testscript b/tests/search/dir/testscript
index 4cd368b..e9ffa6a 100644
--- a/tests/search/dir/testscript
+++ b/tests/search/dir/testscript
@@ -30,14 +30,14 @@ $* <'./: bar/' >'bar'
: existing-scope
:
$* <<EOI >'bar'
-bar/: x = y
+bar/ x = y
./: bar/
EOI
: existing-target-implied
:
$* <<EOI >'bar'
-dir{bar/}: x = y
+dir{bar/}: x = y # @@ TMP
./: bar/
EOI
diff --git a/tests/variable/override/testscript b/tests/variable/override/testscript
index 9b8efdf..3529574 100644
--- a/tests/variable/override/testscript
+++ b/tests/variable/override/testscript
@@ -34,15 +34,15 @@
x = [string] 0
print $x
- dir/:
+ dir/
{
print $x
}
- dir/: x = [uint64] 1
+ dir/ x = [uint64] 1
print $x
- dir/:
+ dir/
{
print $x
}
diff --git a/tests/variable/scope-specific/buildfile b/tests/variable/scope-specific/buildfile
new file mode 100644
index 0000000..2f3de77
--- /dev/null
+++ b/tests/variable/scope-specific/buildfile
@@ -0,0 +1,5 @@
+# file : tests/variable/scope-specific/buildfile
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+./: test{testscript} $b
diff --git a/tests/variable/scope-specific/testscript b/tests/variable/scope-specific/testscript
new file mode 100644
index 0000000..1f5f5fb
--- /dev/null
+++ b/tests/variable/scope-specific/testscript
@@ -0,0 +1,54 @@
+# file : tests/variable/scope-specific/testscript
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+.include ../../common.test
+
+: basic-line
+:
+$* <<EOI >>EOO
+x = x
+foo/ x = X
+foo/ [uint64] y=00
+print $x
+print $(foo/ x)
+print $(foo/ y)
+EOI
+x
+X
+0
+EOO
+
+: basic-block
+:
+$* <<EOI >>EOO
+x = x
+foo/
+{
+ x = X
+ [uint64] y = 00
+ print $x
+}
+print $x
+print $(foo/ y)
+EOI
+X
+x
+0
+EOO
+
+: expect-assignment
+:
+$* <<EOI 2>>EOE != 0
+foo/ [uint64] y
+EOI
+<stdin>:1:16: error: variable assignment expected instead of <newline>
+EOE
+
+: unexpected-attribute
+:
+$* <<EOI 2>>EOE != 0
+[uint64] foo/ y = 0
+EOI
+<stdin>:1:1: error: attributes before scope directory
+EOE
diff --git a/tests/variable/target-specific/buildfile b/tests/variable/target-specific/buildfile
new file mode 100644
index 0000000..5a8178b
--- /dev/null
+++ b/tests/variable/target-specific/buildfile
@@ -0,0 +1,5 @@
+# file : tests/variable/target-specific/buildfile
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+./: test{testscript} $b
diff --git a/tests/variable/target-specific/testscript b/tests/variable/target-specific/testscript
new file mode 100644
index 0000000..e8cc9c2
--- /dev/null
+++ b/tests/variable/target-specific/testscript
@@ -0,0 +1,61 @@
+# file : tests/variable/scope-specific/testscript
+# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
+# license : MIT; see accompanying LICENSE file
+
+.include ../../common.test
+
+: basic-line
+:
+$* <<EOI >>EOO
+x = x
+#./: x = X @@ TMP
+dir{./}: x = X
+file{foo}: [uint64] y=00
+sub/
+{
+ file{foo}: z = Z
+}
+print $x
+print $(./: x)
+print $(file{foo}: y)
+print $(sub/file{foo}: z)
+EOI
+x
+X
+0
+Z
+EOO
+
+: eval-qual
+:
+$* <<EOI >>EOO
+print (foo:bar)
+print (foo :bar)
+print (foo: bar)
+print (foo : bar)
+print (foo/: bar)
+print (foo/file{fox}: bar)
+EOI
+foo:bar
+foo:bar
+foo:bar
+foo:bar
+foo/:bar
+foo/file{fox}:bar
+EOO
+
+: eval-qual-name-expected
+:
+$* <<EOI 2>>EOE != 0
+print (foo:)
+EOI
+<stdin>:1:12: error: expected name instead of ')'
+EOE
+
+: eval-qual-target-expected
+:
+$* <<EOI 2>>EOE != 0
+print (:foo)
+EOI
+<stdin>:1:8: error: expected target before ':'
+EOE