From 4f63afc1177021d6345502892dbd028f5d6db5eb Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 16 Jul 2018 15:21:26 +0200 Subject: Implement in module Given test.in containing something along these lines: foo = $foo$ Now we can do: using in file{test}: in{test.in} file{test}: foo = FOO The alternative variable substitution symbol can be specified with the in.symbol variable and lax (instead of the default strict) mode with in.substitution. For example: file{test}: in.symbol = '@' file{test}: in.substitution = lax --- build2/in/init.cxx | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 build2/in/init.cxx (limited to 'build2/in/init.cxx') diff --git a/build2/in/init.cxx b/build2/in/init.cxx new file mode 100644 index 0000000..337722a --- /dev/null +++ b/build2/in/init.cxx @@ -0,0 +1,110 @@ +// file : build2/in/init.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2018 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include + +#include +#include +#include +#include + +#include +#include + +using namespace std; + +namespace build2 +{ + namespace in + { + static const rule rule_; + + bool + base_init (scope& rs, + scope&, + const location&, + unique_ptr&, + bool first, + bool, + const variable_map&) + { + tracer trace ("in::base_init"); + l5 ([&]{trace << "for " << rs.out_path ();}); + + assert (first); + + // Enter variables. + // + { + auto& vp (var_pool.rw (rs)); + + // Alternative variable substitution symbol with '$' being the + // default. + // + vp.insert ("in.symbol"); + + // Substitution mode. Valid values are 'strict' (default) and 'lax'. + // In the strict mode every substitution symbol is expected to start a + // substitution with the double symbol (e.g., $$) serving as an escape + // sequence. + // + // In the lax mode a pair of substitution symbols is only treated as a + // substitution if what's between them looks like a build2 variable + // name (i.e., doesn't contain spaces, etc). Everything else, + // including unterminated substitution symbols, is copied as is. Note + // also that in this mode the double symbol is not treated as an + // escape sequence. + // + // The lax mode is mostly useful when trying to reuse existing .in + // files, for example, from autoconf. Note, however, that the lax mode + // is still stricter than the autoconf's semantics which also leaves + // unknown substitutions as is. + // + vp.insert ("in.substitution"); + } + + // Register target types. + // + rs.target_types.insert (); + + return true; + } + + bool + init (scope& rs, + scope& bs, + const location& loc, + unique_ptr&, + bool, + bool, + const variable_map&) + { + tracer trace ("in::init"); + l5 ([&]{trace << "for " << bs.out_path ();}); + + // Load in.base. + // + if (!cast_false (rs["in.base.loaded"])) + load_module (rs, rs, "in.base", loc); + + // Register rules. + // + { + auto& r (rs.rules); + + // There are rules that are "derived" from this generic in rule in + // order to provide extended preprocessing functionality (see the + // version module for an example). To make sure they are tried first + // we register for path_target, not file, but in rule::match() we only + // match if the target is a file. A bit of a hack. + // + r.insert (perform_update_id, "in", rule_); + r.insert (perform_clean_id, "in", rule_); + r.insert (configure_update_id, "in", rule_); + } + + return true; + } + } +} -- cgit v1.1