// file : tests/builtin/driver.cxx -*- C++ -*- // license : MIT; see accompanying LICENSE file #include #ifndef __cpp_lib_modules_ts #include #include #include // move() #include #include #endif // Other includes. #ifdef __cpp_modules_ts #ifdef __cpp_lib_modules_ts import std.core; import std.io; #endif import butl.path; import butl.utility; // eof() import butl.builtin; import butl.optional; import butl.timestamp; // to_stream(duration) #else #include #include #include #include #include #endif using namespace std; using namespace butl; inline ostream& operator<< (ostream& os, const path& p) { return os << p.representation (); } // Usage: argv[0] [-d ] [-o ] [-c] [-i] // // Execute the builtin and exit with its exit status. // // -d use as a current working directory // -c use callbacks that, in particular, trace calls to stdout // -o additional builtin option recognized by the callback // -i read lines from stdin and append them to the builtin arguments // int main (int argc, char* argv[]) { using butl::optional; cin.exceptions (ios::badbit); cout.exceptions (ios::failbit | ios::badbit); cerr.exceptions (ios::failbit | ios::badbit); bool in (false); dir_path cwd; string option; builtin_callbacks callbacks; string name; vector args; auto flag = [] (bool v) {return v ? "true" : "false";}; // Parse the driver options and arguments. // int i (1); for (; i != argc; ++i) { string a (argv[i]); if (a == "-d") { ++i; assert (i != argc); cwd = dir_path (argv[i]); } else if (a == "-o") { ++i; assert (i != argc); option = argv[i]; } else if (a == "-c") { callbacks = builtin_callbacks ( [&flag] (const path& p, bool pre) { cout << "create " << p << ' ' << flag (pre) << endl; }, [&flag] (const path& from, const path& to, bool force, bool pre) { cout << "move " << from << ' ' << to << ' ' << flag (force) << ' ' << flag (pre) << endl; }, [&flag] (const path& p, bool force, bool pre) { cout << "remove " << p << ' ' << flag (force) << ' ' << flag (pre) << endl; }, [&option] (const vector& args, size_t i) { cout << "option " << args[i] << endl; return !option.empty () && args[i] == option ? 1 : 0; }, [] (const duration& d) { cout << "sleep "; to_stream (cout, d, false /* nanoseconds */); cout << endl; } ); } else if (a == "-i") in = true; else break; } // Parse the builtin name and arguments. // assert (i != argc); name = argv[i++]; for (; i != argc; ++i) args.push_back (argv[i]); // Read out additional arguments from stdin. // if (in) { string s; while (!eof (getline (cin, s))) args.push_back (move (s)); } // Execute the builtin. // const builtin_info* bi (builtins.find (name)); if (bi == nullptr) { cerr << "unknown builtin '" << name << "'" << endl; return 1; } if (bi->function == nullptr) { cerr << "external builtin '" << name << "'" << endl; return 1; } uint8_t r; // Storage. builtin b (bi->function (r, args, nullfd, nullfd, nullfd, cwd, callbacks)); return b.wait (); }