aboutsummaryrefslogtreecommitdiff
path: root/build2/test/script/script
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2017-05-01 18:24:31 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2017-05-01 19:30:26 +0300
commit70317569c6dcd9809ed4a8c425777e653ec6ca08 (patch)
tree07a538b296933e9e2a1f81088f8fcc8da3f749ad /build2/test/script/script
parentcbec9ea8841c8a58b2d50bb628b28aea7a6fe179 (diff)
Add hxx extension for headers
Diffstat (limited to 'build2/test/script/script')
-rw-r--r--build2/test/script/script552
1 files changed, 0 insertions, 552 deletions
diff --git a/build2/test/script/script b/build2/test/script/script
deleted file mode 100644
index 9a54c71..0000000
--- a/build2/test/script/script
+++ /dev/null
@@ -1,552 +0,0 @@
-// file : build2/test/script/script -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BUILD2_TEST_SCRIPT_SCRIPT
-#define BUILD2_TEST_SCRIPT_SCRIPT
-
-#include <set>
-
-#include <build2/types>
-#include <build2/utility>
-
-#include <build2/variable>
-
-#include <build2/test/target>
-
-#include <build2/test/script/token> // replay_tokens
-
-namespace build2
-{
- class target;
-
- namespace test
- {
- namespace script
- {
- class parser; // Required by VC for 'friend class parser' declaration.
-
- // Pre-parse representation.
- //
-
- enum class line_type
- {
- var,
- cmd,
- cmd_if,
- cmd_ifn,
- cmd_elif,
- cmd_elifn,
- cmd_else,
- cmd_end
- };
-
- ostream&
- operator<< (ostream&, line_type);
-
- struct line
- {
- line_type type;
- replay_tokens tokens;
-
- union
- {
- const variable* var; // Pre-entered for line_type::var.
- };
- };
-
- // Most of the time we will have just one line (test command).
- //
- using lines = small_vector<line, 1>;
-
- // Parse object model.
- //
-
- // redirect
- //
- enum class redirect_type
- {
- none,
- pass,
- null,
- trace,
- merge,
- here_str_literal,
- here_str_regex,
- here_doc_literal,
- here_doc_regex,
- here_doc_ref, // Reference to here_doc literal or regex.
- file,
- };
-
- // Pre-parsed (but not instantiated) regex lines. The idea here is that
- // we should be able to re-create their (more or less) exact text
- // representation for diagnostics but also instantiate without any
- // re-parsing.
- //
- struct regex_line
- {
- // If regex is true, then value is the regex expression. Otherwise, it
- // is a literal. Note that special characters can be present in both
- // cases. For example, //+ is a regex, while /+ is a literal, both
- // with '+' as a special character. Flags are only valid for regex.
- // Literals falls apart into textual (has no special characters) and
- // special (has just special characters instead) ones. For example
- // foo is a textual literal, while /.+ is a special one. Note that
- // literal must not have value and special both non-empty.
- //
- bool regex;
-
- string value;
- string flags;
- string special;
-
- uint64_t line;
- uint64_t column;
-
- // Create regex with optional special characters.
- //
- regex_line (uint64_t l, uint64_t c,
- string v, string f, string s = string ())
- : regex (true),
- value (move (v)),
- flags (move (f)),
- special (move (s)),
- line (l),
- column (c) {}
-
- // Create a literal, either text or special.
- //
- regex_line (uint64_t l, uint64_t c, string v, bool s)
- : regex (false),
- value (s ? string () : move (v)),
- special (s ? move (v) : string ()),
- line (l),
- column (c) {}
- };
-
- struct regex_lines
- {
- char intro; // Introducer character.
- string flags; // Global flags (here-document).
-
- small_vector<regex_line, 8> lines;
- };
-
- // Output file redirect mode.
- //
- enum class redirect_fmode
- {
- compare,
- overwrite,
- append
- };
-
- struct redirect
- {
- redirect_type type;
-
- struct file_type
- {
- using path_type = build2::path;
- path_type path;
- redirect_fmode mode; // Meaningless for input redirect.
- };
-
- union
- {
- int fd; // Merge-to descriptor.
- string str; // Note: with trailing newline, if requested.
- regex_lines regex; // Note: with trailing blank, if requested.
- file_type file;
- reference_wrapper<const redirect> ref; // Note: no chains.
- };
-
- string modifiers; // Redirect modifiers.
- string end; // Here-document end marker (no regex intro/flags).
- uint64_t end_line; // Here-document end marker location.
- uint64_t end_column;
-
- // Create redirect of a type other than reference.
- //
- explicit
- redirect (redirect_type = redirect_type::none);
-
- // Create redirect of the reference type.
- //
- redirect (redirect_type t, const redirect& r)
- : type (redirect_type::here_doc_ref), ref (r)
- {
- // There is no support (and need) for reference chains.
- //
- assert (t == redirect_type::here_doc_ref &&
- r.type != redirect_type::here_doc_ref);
- }
-
- // Move constuctible/assignable-only type.
- //
- redirect (redirect&&);
- redirect& operator= (redirect&&);
-
- ~redirect ();
-
- const redirect&
- effective () const noexcept
- {
- return type == redirect_type::here_doc_ref ? ref.get () : *this;
- }
- };
-
- // cleanup
- //
- enum class cleanup_type
- {
- always, // &foo - cleanup, fail if does not exist.
- maybe, // &?foo - cleanup, ignore if does not exist.
- never // &!foo - don’t cleanup, ignore if doesn’t exist.
- };
-
- // File or directory to be automatically cleaned up at the end of the
- // scope. If the path ends with a trailing slash, then it is assumed to
- // be a directory, otherwise -- a file. A directory that is about to be
- // cleaned up must be empty.
- //
- // The last component in the path may contain a wildcard that have the
- // following semantics:
- //
- // dir/* - remove all immediate files
- // dir/*/ - remove all immediate sub-directories (must be empty)
- // dir/** - remove all files recursively
- // dir/**/ - remove all sub-directories recursively (must be empty)
- // dir/*** - remove directory dir with all files and sub-directories
- // recursively
- //
- struct cleanup
- {
- cleanup_type type;
- build2::path path;
- };
- using cleanups = vector<cleanup>;
-
- // command_exit
- //
- enum class exit_comparison {eq, ne};
-
- struct command_exit
- {
- // C/C++ don't apply constraints on program exit code other than it
- // being of type int.
- //
- // POSIX specifies that only the least significant 8 bits shall be
- // available from wait() and waitpid(); the full value shall be
- // available from waitid() (read more at _Exit, _exit Open Group
- // spec).
- //
- // While the Linux man page for waitid() doesn't mention any
- // deviations from the standard, the FreeBSD implementation (as of
- // version 11.0) only returns 8 bits like the other wait*() calls.
- //
- // Windows supports 32-bit exit codes.
- //
- // Note that in shells some exit values can have special meaning so
- // using them can be a source of confusion. For bash values in the
- // [126, 255] range are such a special ones (see Appendix E, "Exit
- // Codes With Special Meanings" in the Advanced Bash-Scripting Guide).
- //
- exit_comparison comparison;
- uint8_t status;
- };
-
- // command
- //
- struct command
- {
- path program;
- strings arguments;
-
- redirect in;
- redirect out;
- redirect err;
-
- script::cleanups cleanups;
-
- command_exit exit {exit_comparison::eq, 0};
- };
-
- enum class command_to_stream: uint16_t
- {
- header = 0x01,
- here_doc = 0x02, // Note: printed on a new line.
- all = header | here_doc
- };
-
- void
- to_stream (ostream&, const command&, command_to_stream);
-
- ostream&
- operator<< (ostream&, const command&);
-
- // command_pipe
- //
- using command_pipe = vector<command>;
-
- void
- to_stream (ostream&, const command_pipe&, command_to_stream);
-
- ostream&
- operator<< (ostream&, const command_pipe&);
-
- // command_expr
- //
- enum class expr_operator {log_or, log_and};
-
- struct expr_term
- {
- expr_operator op; // OR-ed to an implied false for the first term.
- command_pipe pipe;
- };
-
- using command_expr = vector<expr_term>;
-
- void
- to_stream (ostream&, const command_expr&, command_to_stream);
-
- ostream&
- operator<< (ostream&, const command_expr&);
-
- // command_type
- //
- enum class command_type {test, setup, teardown};
-
- ostream&
- operator<< (ostream&, command_type);
-
- // description
- //
- struct description
- {
- string id;
- string summary;
- string details;
-
- bool
- empty () const
- {
- return id.empty () && summary.empty () && details.empty ();
- }
- };
-
- // scope
- //
- class script;
-
- enum class scope_state {unknown, passed, failed};
-
- class scope
- {
- public:
- scope* const parent; // NULL for the root (script) scope.
- script* const root; // Self for the root (script) scope.
-
- // The chain of if-else scope alternatives. See also if_cond_ below.
- //
- unique_ptr<scope> if_chain;
-
- // Note that if we pass the variable name as a string, then it will
- // be looked up in the wrong pool.
- //
- variable_map vars;
-
- const path& id_path; // Id path ($@, relative in POSIX form).
- const dir_path& wd_path; // Working dir ($~, absolute and normalized).
-
- optional<description> desc;
-
- scope_state state = scope_state::unknown;
- test::script::cleanups cleanups;
-
- // Variables.
- //
- public:
- // Lookup the variable starting from this scope, continuing with outer
- // scopes, then the target being tested, then the testscript target,
- // and then outer buildfile scopes (including testscript-type/pattern
- // specific).
- //
- lookup
- find (const variable&) const;
-
- // As above but only look for buildfile variables. If target_only is
- // false then also look in scopes of the test target (this should only
- // be done if the variable's visibility is target).
- //
- lookup
- find_in_buildfile (const string&, bool target_only = true) const;
-
- // Return a value suitable for assignment. If the variable does not
- // exist in this scope's map, then a new one with the NULL value is
- // added and returned. Otherwise the existing value is returned.
- //
- value&
- assign (const variable& var) {return vars.assign (var);}
-
- // Return a value suitable for append/prepend. If the variable does
- // not exist in this scope's map, then outer scopes are searched for
- // the same variable. If found then a new variable with the found
- // value is added to this scope and returned. Otherwise this function
- // proceeds as assign() above.
- //
- value&
- append (const variable&);
-
- // Reset special $*, $N variables based on the test.* values.
- //
- void
- reset_special ();
-
- // Cleanup.
- //
- public:
- // 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 script working directory.
- //
- void
- clean (cleanup, bool implicit);
-
- public:
- virtual
- ~scope () = default;
-
- protected:
- scope (const string& id, scope* parent);
-
- // Pre-parse data.
- //
- public:
- virtual bool
- empty () const = 0;
-
- protected:
- friend class parser;
-
- location start_loc_;
- location end_loc_;
-
- optional<line> if_cond_;
- };
-
- // group
- //
- class group: public scope
- {
- public:
- vector<unique_ptr<scope>> scopes;
-
- public:
- group (const string& id, group& p): scope (id, &p) {}
-
- protected:
- group (const string& id): scope (id, nullptr) {} // For root.
-
- // Pre-parse data.
- //
- public:
- virtual bool
- empty () const override
- {
- return
- setup_.empty () &&
- tdown_.empty () &&
- find_if (scopes.begin (), scopes.end (),
- [] (const unique_ptr<scope>& s)
- {
- return !s->empty ();
- }) == scopes.end ();
- }
-
- private:
- friend class parser;
-
- lines setup_;
- lines tdown_;
- };
-
- // test
- //
- class test: public scope
- {
- public:
- test (const string& id, group& p): scope (id, &p) {}
-
- // Pre-parse data.
- //
- public:
- virtual bool
- empty () const override
- {
- return tests_.empty ();
- }
-
- private:
- friend class parser;
-
- lines tests_;
- };
-
- // script
- //
- class script_base // Make sure certain things are initialized early.
- {
- protected:
- script_base ();
-
- public:
- variable_pool var_pool;
- mutable shared_mutex var_pool_mutex;
-
- const variable& test_var; // test
- const variable& options_var; // test.options
- const variable& arguments_var; // test.arguments
- const variable& redirects_var; // test.redirects
- const variable& cleanups_var; // test.cleanups
-
- const variable& wd_var; // $~
- const variable& id_var; // $@
- const variable& cmd_var; // $*
- const variable* cmdN_var[10]; // $N
- };
-
- class script: public script_base, public group
- {
- public:
- script (const target& test_target,
- const testscript& script_target,
- const dir_path& root_wd);
-
- script (script&&) = delete;
- script (const script&) = delete;
- script& operator= (script&&) = delete;
- script& operator= (const script&) = delete;
-
- public:
- const target& test_target; // Target we are testing.
- const testscript& script_target; // Target of the testscript file.
-
- // Pre-parse data.
- //
- private:
- friend class parser;
-
- // Testscript file paths. Specifically, replay_token::file points to
- // these paths.
- //
- std::set<path> paths_;
- };
- }
- }
-}
-
-#include <build2/test/script/script.ixx>
-
-#endif // BUILD2_TEST_SCRIPT_SCRIPT