aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/script/script.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'libbuild2/script/script.hxx')
-rw-r--r--libbuild2/script/script.hxx168
1 files changed, 158 insertions, 10 deletions
diff --git a/libbuild2/script/script.hxx b/libbuild2/script/script.hxx
index 4a62c77..f5bd69a 100644
--- a/libbuild2/script/script.hxx
+++ b/libbuild2/script/script.hxx
@@ -27,6 +27,9 @@ namespace build2
cmd_elif,
cmd_elifn,
cmd_else,
+ cmd_while,
+ cmd_for_args, // `for x: ...`
+ cmd_for_stream, // `... | for x` and `for x <...`
cmd_end
};
@@ -40,7 +43,7 @@ namespace build2
union
{
- const variable* var; // Pre-entered for line_type::var.
+ const variable* var; // Pre-entered for line_type::{var,cmd_for_*}.
};
};
@@ -262,7 +265,7 @@ namespace build2
cleanup_type type;
build2::path path;
};
- using cleanups = vector<cleanup>;
+ using cleanups = small_vector<cleanup, 1>;
// command_exit
//
@@ -295,11 +298,30 @@ namespace build2
// command
//
- // Align with butl::process_env, assuming it is not very common to (un)set
- // more than two variables.
+ // Assume it is not very common to (un)set more than a few environment
+ // variables in the script.
//
- using environment_vars = small_vector<string, 2>;
+ struct environment_vars: small_vector<string, 4>
+ {
+ // Find a variable (un)set.
+ //
+ // Note that only the variable name is considered for both arguments. In
+ // other words, passing a variable set as a first argument can result
+ // with a variable unset being found and vice versa.
+ //
+ environment_vars::iterator
+ find (const string&);
+
+ // Add or overwrite an existing variable (un)set.
+ //
+ void
+ add (string);
+ };
+ // @@ For better diagnostics we may want to store an individual location
+ // of each command in the pipeline (maybe we can share the file part
+ // somehow since a pipline cannot span multiple files).
+ //
struct command
{
// We use NULL initial as an indication that the path stored in recall
@@ -308,8 +330,14 @@ namespace build2
//
process_path program;
- strings arguments;
- environment_vars variables;
+ strings arguments;
+
+ // These come from the env builtin.
+ //
+ optional<dir_path> cwd;
+ environment_vars variables;
+ optional<duration> timeout;
+ bool timeout_success = false;
optional<redirect> in;
optional<redirect> out;
@@ -337,6 +365,10 @@ namespace build2
// command_pipe
//
+ // Note that we cannot use small_vector here, since moving from objects of
+ // the command_pipe type would invalidate the command redirects of the
+ // reference type in this case.
+ //
using command_pipe = vector<command>;
void
@@ -355,7 +387,7 @@ namespace build2
command_pipe pipe;
};
- using command_expr = vector<expr_term>;
+ using command_expr = small_vector<expr_term, 1>;
void
to_stream (ostream&, const command_expr&, command_to_stream);
@@ -363,6 +395,46 @@ namespace build2
ostream&
operator<< (ostream&, const command_expr&);
+ // Stack-allocated linked list of iteration indexes of the nested loops.
+ //
+ struct iteration_index
+ {
+ size_t index; // 1-based.
+
+ const iteration_index* prev; // NULL for the top-most loop.
+ };
+
+ struct timeout
+ {
+ duration value;
+ bool success;
+
+ timeout (duration d, bool s): value (d), success (s) {}
+ };
+
+ struct deadline
+ {
+ timestamp value;
+ bool success;
+
+ deadline (timestamp t, bool s): value (t), success (s) {}
+ };
+
+ // If timestamps/durations are equal, the failure is less than the
+ // success.
+ //
+ bool
+ operator< (const deadline&, const deadline&);
+
+ bool
+ operator< (const timeout&, const timeout&);
+
+ optional<deadline>
+ to_deadline (const optional<timestamp>&, bool success);
+
+ optional<timeout>
+ to_timeout (const optional<duration>&, bool success);
+
// Script execution environment.
//
class environment
@@ -447,7 +519,8 @@ namespace build2
// Register a cleanup. If the cleanup is explicit, then override the
// cleanup type if this path is already registered. Ignore implicit
- // registration of a path outside root directory (see below).
+ // registration of a path outside sandbox directory, if specified (see
+ // above).
//
void
clean (cleanup, bool implicit);
@@ -460,15 +533,55 @@ namespace build2
void
clean_special (path);
+ // Command execution environment variables.
+ //
+ public:
+ // Environment variable (un)sets from the export builtin call.
+ //
+ // Each variable in the list can only be present once.
+ //
+ environment_vars exported_vars;
+
+ // Return the environment variable (un)sets which can potentially rely
+ // on factors besides the export builtin call sequence (scoping,
+ // etc). The default implementation returns exported_vars.
+ //
+ virtual const environment_vars&
+ exported_variables (environment_vars& storage);
+
+ // Merge the own environment variable (un)sets with the specified ones,
+ // overriding the former with the latter.
+ //
+ const environment_vars&
+ merge_exported_variables (const environment_vars&,
+ environment_vars& storage);
+
public:
// Set variable value with optional (non-empty) attributes.
//
virtual void
- set_variable (string&& name,
+ set_variable (string name,
names&&,
const string& attrs,
const location&) = 0;
+ // Set the script execution timeout from the timeout builtin call.
+ //
+ // The builtin argument semantics is script implementation-dependent. If
+ // success is true then a process missing this deadline should not be
+ // considered as failed unless it didn't terminate gracefully and had to
+ // be killed.
+ //
+ virtual void
+ set_timeout (const string& arg, bool success, const location&) = 0;
+
+ // Return the script execution deadline which can potentially rely on
+ // factors besides the latest timeout builtin call (variables, scoping,
+ // etc).
+ //
+ virtual optional<deadline>
+ effective_deadline () = 0;
+
// Create the temporary directory and set the temp_dir reference target
// to its path. Must only be called if temp_dir is empty.
//
@@ -479,6 +592,41 @@ namespace build2
virtual
~environment () = default;
};
+
+ // Custom command function that can be executed at the end of the
+ // pipeline. Should throw io_error on the underlying OS error.
+ //
+ // Note: the pipeline can be NULL (think of `for x <<<='foo'`).
+ //
+ struct pipe_command;
+
+ using command_function = void (environment&,
+ const strings& args,
+ auto_fd in,
+ pipe_command* pipeline,
+ const optional<deadline>&,
+ const location&);
+
+ // Helpers.
+ //
+ // Issue diagnostics with the specified prefix and fail if the string
+ // (potentially an option value) is not a valid variable name or
+ // assignment (empty, etc).
+ //
+ void
+ verify_environment_var_name (const string&,
+ const char* prefix,
+ const location&,
+ const char* opt = nullptr);
+
+ void
+ verify_environment_var_assignment (const string&,
+ const char* prefix,
+ const location&);
+
+ // "Unhide" operator<< from the build2 namespace.
+ //
+ using build2::operator<<;
}
}