aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build2/buildfile1
-rw-r--r--build2/test/script/builtin45
-rw-r--r--build2/test/script/builtin.cxx67
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}
+ };
+ }
+ }
+}