diff options
-rw-r--r-- | build2/buildfile | 1 | ||||
-rw-r--r-- | build2/test/script/builtin | 45 | ||||
-rw-r--r-- | build2/test/script/builtin.cxx | 67 |
3 files changed, 113 insertions, 0 deletions
diff --git a/build2/buildfile b/build2/buildfile index f7b2dd9..86b67a9 100644 --- a/build2/buildfile +++ b/build2/buildfile @@ -76,6 +76,7 @@ exe{b}: \ test/{hxx cxx}{ operation } \ test/{hxx cxx}{ rule } \ test/{hxx cxx}{ target } \ +test/script/{hxx cxx}{ builtin } \ test/script/{hxx cxx}{ lexer } \ test/script/{hxx cxx}{ parser } \ test/script/{hxx cxx}{ runner } \ diff --git a/build2/test/script/builtin b/build2/test/script/builtin new file mode 100644 index 0000000..805e5fd --- /dev/null +++ b/build2/test/script/builtin @@ -0,0 +1,45 @@ +// file : build2/test/script/builtin -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#ifndef BUILD2_TEST_SCRIPT_BUILTIN +#define BUILD2_TEST_SCRIPT_BUILTIN + +#include <build2/types> +#include <build2/utility> + +#include <map> + +namespace build2 +{ + namespace test + { + namespace script + { + // Note that unlike argc/argv, our args don't include the program name. + // + using builtin = int (*) (const strings& args, + int in_fd, int out_fd, int err_fd); + + class builtin_map: public std::map<string, builtin> + { + public: + using base = std::map<string, builtin>; + using base::base; + + // Return NULL if not a builtin. + // + builtin + find (const string& n) const + { + auto i (base::find (n)); + return i != end () ? i->second : nullptr; + } + }; + + extern const builtin_map builtins; + } + } +} + +#endif // BUILD2_TEST_SCRIPT_BUILTIN diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx new file mode 100644 index 0000000..f3a0bd4 --- /dev/null +++ b/build2/test/script/builtin.cxx @@ -0,0 +1,67 @@ +// file : build2/test/script/builtin.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd +// license : MIT; see accompanying LICENSE file + +#include <build2/test/script/builtin> + +#include <butl/fdstream> + +using namespace std; +using namespace butl; + +namespace build2 +{ + //@@ auto_fd handover + // + // 1. We need auto_fd in libbutl + // 2. Overload fdstream ctors for auto_fd&& (or replace? also process data + // members?) + // 3. The builtin signature then will become: + // + // static int + // echo (const strings& args, auto_fd in, auto_fd out, auto_fd err) + + static int + echo (const strings& args, int in_fd, int out_fd, int err_fd) + try + { + int r (0); + ofdstream cerr (err_fd); + + try + { + fdclose (in_fd); //@@ TMP + ofdstream cout (out_fd); + + for (auto b (args.begin ()), i (b), e (args.end ()); i != e; ++i) + cout << (i != b ? " " : "") << *i; + + cout << endl; + + cout.close (); + } + catch (const std::exception& e) + { + cerr << "echo: " << e.what (); + r = 1; + } + + cerr.close (); + return r; + } + catch (const std::exception&) + { + return 1; + } + + namespace test + { + namespace script + { + const builtin_map builtins + { + {"echo", &echo} + }; + } + } +} |