From 3fa1b103014bab51f8f257e1e12f27f7e498f42e Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 13 Sep 2019 20:57:00 +0300 Subject: Add support for builtin escaping to command running API --- libbutl/command.cxx | 12 +++++++++++- libbutl/command.mxx | 5 +++++ tests/command/testscript | 10 ++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/libbutl/command.cxx b/libbutl/command.cxx index a344790..1126bb0 100644 --- a/libbutl/command.cxx +++ b/libbutl/command.cxx @@ -272,11 +272,21 @@ namespace butl } else // Execute the program. { + // Strip the potential leading `^`, indicating that this is an external + // program rather than a builtin. Consider only simple paths and don't + // end up with an empty path. + // + const char* p (prog.size () > 1 && + prog[0] == '^' && + path::traits_type::find_separator (prog) == string::npos + ? prog.c_str () + 1 + : prog.c_str ()); + // Prepare the process environment. // // Note: cwd passed to process_env() may not be a temporary object. // - process_env pe (prog, cwd, env ? env->vars : nullptr); + process_env pe (p, cwd, env ? env->vars : nullptr); // Finally, run the process. // diff --git a/libbutl/command.mxx b/libbutl/command.mxx index 0e6617b..8423f59 100644 --- a/libbutl/command.mxx +++ b/libbutl/command.mxx @@ -37,6 +37,11 @@ LIBBUTL_MODEXPORT namespace butl // error, ios::failure on the underlying OS error, process_error on the // process running error and std::system_error on the builtin running error. // + // To run a system utility rather than a builtin prefix its name with `^`, + // for example: + // + // ^cat --squeeze-blank file + // // The process environment path is unused and must point to the empty // process path. // diff --git a/tests/command/testscript b/tests/command/testscript index db9bb5c..12ddd79 100644 --- a/tests/command/testscript +++ b/tests/command/testscript @@ -184,4 +184,14 @@ end { $* -p 'echo abc >a' >'echo abc >a' &a } + + : escape + : + : Note that the sed builtin doesn't support multiple scripts. + : + if ($cxx.target.class != 'windows') + { + echo 'abc' >=f; + $* '^sed -e s/a/b/ -e s/c/b/ f' >'bbb' + } } -- cgit v1.1