Commit f30e82d7 authored by Samuel Newbold's avatar Samuel Newbold

collect_errors_*, .try_catch is a looping construct

parent 674b1b74
......@@ -2,5 +2,6 @@
*.a
rwsh
last.test.result
last.test_inconsistent.result
last.test_quick.result
test_files/tmp
// The definition of the Arg_script class which contains a vector of
// Arg_spec objects and a Function*, and which represents the mapping
// between the Argm that was passed to the function and the Argm that will
// The definition of the Arg_script class which contains a vector of
// Arg_spec objects and a Function*, and which represents the mapping
// between the Argm that was passed to the function and the Argm that will
// be used to run a given executable.
//
// Copyright (C) 2006-2016 Samuel Newbold
......@@ -9,6 +9,7 @@
#include <exception>
#include <fstream>
#include <iterator>
#include <list>
#include <map>
#include <set>
#include <string>
......@@ -35,7 +36,7 @@ std::string::size_type Arg_script::add_quote(const std::string& src,
unsigned max_soon) {
std::string literal;
const char* separators = "\\()";
std::string::size_type split = src.find_first_of(separators, point+1);
std::string::size_type split = src.find_first_of(separators, point+1);
for (unsigned nesting = 0;
split != std::string::npos && (nesting || src[split] != ')');
split = src.find_first_of(separators, split+1)) switch(src[split]) {
......@@ -62,7 +63,7 @@ std::string::size_type Arg_script::parse_token(const std::string& src,
if (src[token_start] == '(')
return add_quote(src, token_start, max_soon);
else if (src[token_start] == ')')
throw Signal_argm(Argm::Mismatched_parenthesis,
throw Exception(Argm::Mismatched_parenthesis,
src.substr(0, token_start+1));
std::string::size_type split = src.find_first_of(all_separators, token_start),
point = token_start;
......@@ -104,14 +105,14 @@ Arg_script::Arg_script(const std::string& src, unsigned max_soon) :
point = constructor(src, point, max_soon);
if (point < src.length())
if (src[point] == '}' || src[point] == ';')
throw Signal_argm(Argm::Mismatched_brace, src.substr(0, point+1));
throw Exception(Argm::Mismatched_brace, src.substr(0, point+1));
else std::abort();}
Arg_script::Arg_script(const std::string& src, std::string::size_type& point,
unsigned max_soon) :
argfunction(0), argfunction_level(0), input(default_input),
output(default_output), error(default_error), terminator('!') {
std::string::size_type tpoint = src.find_first_not_of(" ", point);
std::string::size_type tpoint = src.find_first_not_of(WSPACE, point);
indent = src.substr(point, tpoint-point);
point = constructor(src, tpoint, max_soon);}
......@@ -125,8 +126,8 @@ std::string::size_type Arg_script::constructor(const std::string& src,
if (!args.size()) args.push_back(Arg_spec("", max_soon));
if (is_argfunction_name(args.front().str()) && // argfunction_level handling
args.front().str() != "rwsh.mapped_argfunction")
if (args.size() != 1 || argfunction)
throw Signal_argm(Argm::Arguments_for_argfunction, args.front().str());
if (args.size() != 1 || argfunction)
throw Exception(Argm::Arguments_for_argfunction, args.front().str());
else if (args.front().str() == "rwsh.unescaped_argfunction")
argfunction_level = 1;
else if (args.front().str() == "rwsh.argfunction") argfunction_level = 2;
......@@ -141,31 +142,31 @@ void Arg_script::add_token(const std::string& src, unsigned max_soon) {
switch (src[0]) {
case '<':
if (!input.is_default())
throw Signal_argm(Argm::Double_redirection, input.str(), src);
throw Exception(Argm::Double_redirection, input.str(), src);
else input = Rwsh_istream_p(new File_istream(src.substr(1)),
false, false);
break;
case '>':
if (!output.is_default())
throw Signal_argm(Argm::Double_redirection, output.str(), src);
throw Exception(Argm::Double_redirection, output.str(), src);
else output = Rwsh_ostream_p(new File_ostream(src.substr(1)),
false, false);
break;
default:
args.push_back(Arg_spec(src, max_soon));}}
std::string::size_type Arg_script::add_function(const std::string& src,
std::string::size_type Arg_script::add_function(const std::string& src,
std::string::size_type style_start,
std::string::size_type point,
unsigned max_soon) {
if (style_start != point)
args.push_back(Arg_spec(src, style_start, point, max_soon));
else
if (argfunction) throw Signal_argm(Argm::Multiple_argfunctions);
if (argfunction) throw Exception(Argm::Multiple_argfunctions);
else argfunction = new Command_block(src, point, max_soon+1);
return point;}
Arg_script::Arg_script(const Arg_script& src) :
Arg_script::Arg_script(const Arg_script& src) :
args(src.args), argfunction(src.argfunction->copy_pointer()),
argfunction_level(src.argfunction_level),
input(src.input), output(src.output), error(src.error),
......@@ -174,7 +175,7 @@ Arg_script::Arg_script(const Arg_script& src) :
Arg_script& Arg_script::operator=(const Arg_script& src) {
args.clear();
copy(src.args.begin(), src.args.end(), std::back_inserter(args));
delete argfunction;
delete argfunction;
argfunction = src.argfunction->copy_pointer();
argfunction_level = src.argfunction_level;
input = src.input;
......@@ -215,23 +216,30 @@ std::string Arg_script::str(void) const {
else if (argfunction_level == 2) return "rwsh.escaped_argfunction";
else {abort(); return "";}} // unhandled argfunction_level
Argm Arg_script::base_interpret(const Argm& src) const {
std::list<Argm> exceptions;
Argm ret = interpret(src, exceptions);
if (exceptions.size()) Base_executable::exception_handler(exceptions);
return ret;}
// produce a destination Argm from the source Argm according to this script
Argm Arg_script::interpret(const Argm& src) const {
Argm Arg_script::interpret(const Argm& src, std::list<Argm>& exceptions) const {
Argm result(src.parent_map(),
!input.is_default()? input: src.input.child_stream(),
!output.is_default()? output: src.output.child_stream(),
!error.is_default()? error: src.error.child_stream());
if (!argfunction_level) {
for (std::vector<Arg_spec>::const_iterator i = args.begin();
i != args.end(); ++i)
i->interpret(src, std::back_inserter(result));
i != args.end(); ++i)
i->interpret(src, std::back_inserter(result), exceptions);
if (!result.argc()) result.push_back("");
if (argfunction) result.set_argfunction(argfunction->apply(src, 0));}
if (argfunction)
result.set_argfunction(argfunction->apply(src, 0, exceptions));}
else if (is_argfunction()) {
result.push_back("rwsh.mapped_argfunction");
copy(src.begin()+1, src.end(), std::back_inserter(result));
result.set_argfunction(src.argfunction()->copy_pointer());}
else if (argfunction_level == 2)
else if (argfunction_level == 2)
result.push_back("rwsh.unescaped_argfunction");
else if (argfunction_level == 3) result.push_back("rwsh.argfunction");
else abort(); // unhandled argfunction_level
......@@ -240,7 +248,8 @@ Argm Arg_script::interpret(const Argm& src) const {
// produce a new Arg_script by unescaping argument functions and replacing
// unescaped_argfunction with argm.argfunction
void Arg_script::apply(const Argm& src, unsigned nesting,
std::back_insert_iterator<std::vector<Arg_script> > res) const {
std::back_insert_iterator<std::vector<Arg_script> > res,
std::list<Argm>& exceptions) const {
if (this->argfunction_level) {
Arg_script result(*this);
--result.argfunction_level;
......@@ -248,9 +257,10 @@ void Arg_script::apply(const Argm& src, unsigned nesting,
else {
Arg_script result(input, output, error, indent, terminator);
for (std::vector<Arg_spec>::const_iterator i = args.begin();
i != args.end(); ++i)
i->apply(src, nesting, std::back_inserter(result.args));
if (argfunction) result.argfunction = argfunction->apply(src, nesting+1);
i != args.end(); ++i)
i->apply(src, nesting, std::back_inserter(result.args), exceptions);
if (argfunction)
result.argfunction = argfunction->apply(src, nesting+1, exceptions);
*res++ = result;}}
void Arg_script::promote_soons(unsigned nesting) {
......@@ -261,7 +271,7 @@ void Arg_script::promote_soons(unsigned nesting) {
// test whether an executable name corresponds to one of those used for
// argument functions.
bool is_argfunction_name(const std::string& focus) {
return focus == "rwsh.mapped_argfunction" ||
return focus == "rwsh.mapped_argfunction" ||
focus == "rwsh.unescaped_argfunction" ||
focus == "rwsh.argfunction" ||
focus == "rwsh.escaped_argfunction";}
......
......@@ -37,9 +37,11 @@ class Arg_script {
std::string::size_type point, unsigned max_soon);
Argm argm(void) const;
void apply(const Argm& src, unsigned nesting,
std::back_insert_iterator<std::vector<Arg_script> > res) const;
std::back_insert_iterator<std::vector<Arg_script> > res,
std::list<Argm>& current_exceptions) const;
std::string str(void) const;
Argm interpret(const Argm& src) const;
Argm base_interpret(const Argm& src) const;
Argm interpret(const Argm& src, std::list<Argm>& exceptions) const;
void promote_soons(unsigned);
bool is_argfunction(void) const {return argfunction_level == 1;}; };
......
......@@ -5,6 +5,7 @@
#include <cstdlib>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <list>
#include <map>
......@@ -54,7 +55,7 @@ Arg_spec::Arg_spec(const std::string& script, unsigned max_soon) :
if (i < script.length())
try {word_selection = my_strtoi(script.substr(i));}
catch(...) {
throw Signal_argm(Argm::Invalid_word_selection,
throw Exception(Argm::Invalid_word_selection,
script.substr(key_end));}}
if (!script.length()) type=FIXED;
else if (script[0] == '$')
......@@ -70,7 +71,7 @@ Arg_spec::Arg_spec(const std::string& script, unsigned max_soon) :
if (script.length() < 2) type=SOON;
else
if (soon_level > max_soon)
throw Signal_argm(Argm::Not_soon_enough, script);
throw Exception(Argm::Not_soon_enough, script);
else if (script[key_start] == '*') {
type=STAR_SOON;
if (script.length() - key_start > 1)
......@@ -102,12 +103,12 @@ Arg_spec::Arg_spec(const std::string& src, std::string::size_type style_start,
type = SUBSTITUTION;
++tpoint, soon_level = max_soon;}
if (src[tpoint] != '{')
throw Signal_argm(Argm::Bad_argfunction_style,
throw Exception(Argm::Bad_argfunction_style,
src.substr(style_start, point-style_start));
substitution = new Command_block(src, tpoint, soon_level);
if (soon_level > max_soon) {
delete substitution; // needed to construct substitution to find its end
throw Signal_argm(Argm::Not_soon_enough,
throw Exception(Argm::Not_soon_enough,
src.substr(style_start, tpoint-style_start));}
if (tpoint >= src.length() || sub_term_char(src[tpoint])) point = tpoint;
else {
......@@ -124,7 +125,7 @@ Arg_spec::Arg_spec(const std::string& src, std::string::size_type style_start,
point = tpoint = token_end;
return;}
catch(...) {}} // fall through
throw Signal_argm(Argm::Invalid_word_selection,
throw Exception(Argm::Invalid_word_selection,
src.substr(tpoint, token_end-tpoint));}}
Arg_spec::Arg_spec(Arg_type type_i, unsigned soon_level_i,
......@@ -148,7 +149,8 @@ Arg_spec::Arg_spec(const std::string& src) :
Arg_spec::~Arg_spec() {delete substitution;}
void Arg_spec::apply(const Argm& src, unsigned nesting,
std::back_insert_iterator<std::vector<Arg_spec> > res) const {
std::back_insert_iterator<std::vector<Arg_spec> > res,
std::list<Argm>& exceptions) const {
switch(type) {
case SOON:
if (soon_level)
......@@ -164,10 +166,11 @@ void Arg_spec::apply(const Argm& src, unsigned nesting,
break;
case SUBSTITUTION: case SOON_SUBSTITUTION:
if (soon_level) {
Command_block* new_substitution = substitution->apply(src, nesting+1);
Command_block* new_substitution = substitution->apply(src, nesting+1,
exceptions);
*res++ = Arg_spec(type, soon_level-1, ref_level, expand_count,
word_selection, new_substitution, text, trailing);}
else evaluate_substitution(src, res);
else evaluate_substitution(src, res, exceptions);
break;
default: *res++ = *this;}} // most types are not affected by apply
......@@ -186,17 +189,18 @@ Out Arg_spec::evaluate_expansion(const std::string& value, Out res)
for (unsigned j=0; j<intermediate.size(); ++j)
tokenize_words(intermediate[j], res);
else if (word_selection >= intermediate.size())
throw Signal_argm(Argm::Undefined_variable, str());
throw Exception(Argm::Undefined_variable, str());
else *res++ = intermediate[word_selection];}
return res;}
template<class Out>
Out Arg_spec::evaluate_substitution(const Argm& src, Out res) const {
Out Arg_spec::evaluate_substitution(const Argm& src, Out res,
std::list<Argm>& exceptions) const {
Substitution_stream override_stream;
Argm temp_argm(src);
temp_argm.output = override_stream.child_stream();
if ((*substitution)(temp_argm))
throw Signal_argm(Argm::Failed_substitution, str());
if ((*substitution)(temp_argm, exceptions))
throw Exception(Argm::Failed_substitution, str());
return evaluate_expansion(override_stream.value(), res);}
template<class Out> Out Arg_spec::evaluate_var(const Argm& src, Out res) const {
......@@ -207,7 +211,8 @@ template<class Out> Out Arg_spec::evaluate_var(const Argm& src, Out res) const {
// produce one or more strings for destination Argm from Arg_spec and source
// Argm
void Arg_spec::interpret(const Argm& src,
std::back_insert_iterator<Argm> res) const {
std::back_insert_iterator<Argm> res,
std::list<Argm>& exceptions) const {
if (soon_level) std::abort(); // constructor guarantees SOONs already done
switch(type) {
case FIXED: *res++ = text; break;
......@@ -218,7 +223,7 @@ void Arg_spec::interpret(const Argm& src,
case SELECT_VAR: selection_read(src.get_var(text), res); break;
case SELECT_STAR_VAR: default_output <<"@$* not implemented yet\n"; break;
case SUBSTITUTION: case SOON_SUBSTITUTION:
evaluate_substitution(src, res); break;
evaluate_substitution(src, res, exceptions); break;
default: std::abort();}}
void Arg_spec::promote_soons(unsigned nesting) {
......
// Copyright (C) 2006-2015 Samuel Newbold
// Copyright (C) 2006-2016 Samuel Newbold
class Argm;
class Command_block;
......@@ -19,11 +19,12 @@ class Arg_spec {
void add_function_spec(const std::string& src);
template<class Out> Out evaluate_expansion(const std::string& value,
Out res) const;
template<class Out> Out evaluate_substitution(const Argm& src, Out res) const;
template<class Out> Out evaluate_substitution(const Argm& src, Out res,
std::list<Argm>& exceptions) const;
template<class Out> Out evaluate_var(const Argm& src, Out res) const;
public:
Arg_spec(const std::string& script, unsigned max_soon);
Arg_spec(const std::string& src, std::string::size_type style_start,
Arg_spec(const std::string& src, std::string::size_type style_start,
std::string::size_type& point, unsigned max_soon);
Arg_spec(Arg_type type, unsigned soon_level, unsigned ref_level,
unsigned expand_count, int word_selection,
......@@ -33,9 +34,11 @@ class Arg_spec {
Arg_spec(const std::string& src);
~Arg_spec();
void apply(const Argm& src, unsigned nesting,
std::back_insert_iterator<std::vector<Arg_spec> > res) const;
std::back_insert_iterator<std::vector<Arg_spec> > res,
std::list<Argm>& exceptions) const;
void interpret(const Argm& src,
std::back_insert_iterator<Argm> res) const;
std::back_insert_iterator<Argm> res,
std::list<Argm>& exceptions) const;
void promote_soons(unsigned nesting);
std::string str(void) const; };
......@@ -5,6 +5,7 @@
#include <cstring>
#include <cstdlib>
#include <list>
#include <map>
#include <set>
#include <sstream>
......@@ -23,17 +24,17 @@
Argm::Argm(Variable_map* parent_map_i, Rwsh_istream_p input_i,
Rwsh_ostream_p output_i, Rwsh_ostream_p error_i) :
argc_v(0), argfunction_v(0),
argc_v(0), argfunction_v(0),
input(input_i), output(output_i), error(error_i),
parent_map_v(parent_map_i) {}
Argm::Argm(const Argm& src) : Base(src), argc_v(src.argc()),
argfunction_v(src.argfunction()->copy_pointer()),
argfunction_v(src.argfunction()->copy_pointer()),
input(src.input), output(src.output), error(src.error),
parent_map_v(src.parent_map()) {}
Argm& Argm::operator=(const Argm& src) {
Base::clear();
Base::clear();
std::copy(src.begin(), src.end(), std::back_inserter(*this));
argc_v = src.argc_v;
delete argfunction_v;
......@@ -72,20 +73,20 @@ std::string Argm::get_var(const std::string& key) const {
int n = std::atoi(key.c_str());
if (size() > n) return (*this)[n];
else return std::string();}
//throw Signal_argm(Argm::Undefined_variable, key);}
//throw Exception(Argm::Undefined_variable, key);}
default: return parent_map()->get(key);}}
int Argm::set_var(const std::string& key, const std::string& value) const {
switch (key[0]) {
case '#': case '1': case '2': case '3': case '4': case '5': case '6':
case '#': case '1': case '2': case '3': case '4': case '5': case '6':
case '7': case '8': case '9': case '0': return 2;
default: parent_map()->set(key, value);
return 0;}}
bool Argm::var_exists(const std::string& key) const {
switch (key[0]) {
case '#': case '*': return true;
case '1': case '2': case '3': case '4': case '5': case '6':
case '#': case '*': return true;
case '1': case '2': case '3': case '4': case '5': case '6':
case '7': case '8': case '9': case '0': {
int n = std::atoi(key.c_str());
return size() > n;}
......@@ -93,13 +94,13 @@ bool Argm::var_exists(const std::string& key) const {
int Argm::global(const std::string& key, const std::string& value) const {
switch (key[0]) {
case '#': case '*': case '1': case '2': case '3': case '4': case '5':
case '#': case '*': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0': return 2;
default: return parent_map()->global(key, value);}}
int Argm::local(const std::string& key, const std::string& value) const {
switch (key[0]) {
case '#': case '*': case '1': case '2': case '3': case '4': case '5':
case '#': case '*': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0': return 2;
default: return parent_map()->local(key, value);}}
......@@ -111,12 +112,10 @@ Variable_map::iterator Argm::local_end(void) const {
int Argm::unset_var(const std::string& key) const {
switch (key[0]) {
case '#': case '*': case '1': case '2': case '3': case '4': case '5':
case '#': case '*': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0': return 3;
default: return parent_map()->unset(key);}}
unsigned Argm::max_nesting(void) const {return parent_map()->max_nesting();}
char** Argm::export_env(void) const {return parent_map()->export_env();}
// algorithm that is the meat of Old_argv constructor
......@@ -127,40 +126,58 @@ template<class In>char** copy_to_cstr(In first, In last, char** res) {
*res = 0;
return res;}
Signal_argm::Signal_argm(Sig_type signal_i) :
Exception::Exception(Exception_t exception_i) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
push_back(signal_names[signal]);}
exception(exception_i) {
push_back(exception_names[exception]);}
Signal_argm::Signal_argm(Sig_type signal_i, const std::string& value) :
Exception::Exception(Exception_t exception_i, const std::string& value) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
push_back(signal_names[signal]);
exception(exception_i) {
push_back(exception_names[exception]);
push_back(value);}
Signal_argm::Signal_argm(Sig_type signal_i, const std::string& x,
Exception::Exception(Exception_t exception_i, const std::string& value,
int errno_v) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
exception(exception_i) {
push_back(exception_names[exception]);
push_back(value);
std::ostringstream errno_str;
errno_str <<errno_v;
push_back(errno_str.str());}
Exception::Exception(Exception_t exception_i, const std::string& x,
const std::string& y) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
push_back(signal_names[signal]);
exception(exception_i) {
push_back(exception_names[exception]);
push_back(x);
push_back(y);}
Signal_argm::Signal_argm(Sig_type signal_i, const std::string& w,
Exception::Exception(Exception_t exception_i, const std::string& w,
const std::string& x, const std::string& y,
const std::string& z) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
push_back(signal_names[signal]);
exception(exception_i) {
push_back(exception_names[exception]);
push_back(w);
push_back(x);
push_back(y);
push_back(z);}
Signal_argm::Signal_argm(Sig_type signal_i, int x, int y, int z) :
Exception::Exception(Exception_t exception_i, int x) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
exception(exception_i) {
push_back(exception_names[exception]);
std::ostringstream x_str;
x_str <<x;
push_back(x_str.str());}
Exception::Exception(Exception_t exception_i, int x, int y, int z) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
push_back(signal_names[signal]);
exception(exception_i) {
push_back(exception_names[exception]);
std::ostringstream x_str, y_str, z_str;
x_str <<x;
push_back(x_str.str());
......@@ -169,10 +186,10 @@ Signal_argm::Signal_argm(Sig_type signal_i, int x, int y, int z) :
z_str <<z;
push_back(z_str.str());}
Signal_argm::Signal_argm(Sig_type signal_i, const Argm& src) :
Exception::Exception(Exception_t exception_i, const Argm& src) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
push_back(signal_names[signal]);
exception(exception_i) {
push_back(exception_names[exception]);
std::copy(src.begin(), src.end(), std::back_inserter(*this));}
Old_argv::Old_argv(const Argm& src) : argc_v(src.argc()) {
......
......@@ -31,8 +31,8 @@ class Argm : private std::vector<std::string> {
mutable Rwsh_istream_p input;
mutable Rwsh_ostream_p output, error;
enum Sig_type {
No_signal,
enum Exception_t {
No_exception,
Ambiguous_prototype_dash_dash,
Arguments_for_argfunction,
Bad_argc,
......@@ -49,6 +49,8 @@ class Argm : private std::vector<std::string> {
Elipsis_out_of_option_group,
Else_without_if,
Excess_argfunction,
Excessive_exceptions_collected,
Excessive_exceptions_in_catch,
Excessive_nesting,
Executable_not_found,
Failed_substitution,
......@@ -67,6 +69,7 @@ class Argm : private std::vector<std::string> {
Not_executable,
Not_soon_enough,
Raw_command,
Return_code,
Result_range,
Post_elipsis_option,
Post_dash_dash_flag,
......@@ -90,9 +93,9 @@ class Argm : private std::vector<std::string> {
Unrecognized_flag,
Vars,
Version_incompatible,
Signal_count};
Exception_count};
static std::string signal_names[Signal_count];
static std::string exception_names[Exception_count];
// variables
char** export_env(void) const;
......@@ -101,7 +104,6 @@ class Argm : private std::vector<std::string> {
int local(const std::string& key, const std::string& value) const;
Variable_map::iterator local_begin(void) const;
Variable_map::iterator local_end(void) const;
unsigned max_nesting(void) const;
int set_var(const std::string& key, const std::string& value) const;
template<class Out>
Out star_var(const std::string& key, unsigned reference_level, Out res) const;
......@@ -128,15 +130,17 @@ class Argm : private std::vector<std::string> {
reference operator[] (int i) {return Base::operator[](i);};
const_reference operator[] (int i) const {return Base::operator[](i);}; };
struct Signal_argm : public Argm {
Argm::Sig_type signal;
Signal_argm(Sig_type signal);
Signal_argm(Sig_type signal, const std::string& value);
Signal_argm(Sig_type signal, const std::string& x, const std::string& y);
Signal_argm(Sig_type signal, const std::string& w, const std::string& x,
struct Exception : public Argm {
Argm::Exception_t exception;
Exception(Exception_t exception);
Exception(Exception_t exception, const std::string& value);
Exception(Exception_t exception, const std::string& value, int errno_v);
Exception(Exception_t exception, const std::string& x, const std::string& y);
Exception(Exception_t exception, const std::string& w, const std::string& x,
const std::string& y, const std::string& z);
Signal_argm(Sig_type signal, int x, int y, int z);
Signal_argm(Sig_type signal, const Argm& src);};
Exception(Exception_t exception_i, int x);
Exception(Exception_t exception, int x, int y, int z);
Exception(Exception_t exception, const Argm& src);};
class Old_argv {
char** focus;
......
......@@ -5,26 +5,26 @@
// Copyright (C) 2006-2016 Samuel Newbold
// constructor of Argm from a pair of iterators
template <class String_it>
template <class String_it>
inline Argm::Argm(String_it first_string, String_it last_string,
Command_block* argfunction_i, Variable_map* parent_map_i,
Rwsh_istream_p input_i, Rwsh_ostream_p output_i,
Rwsh_ostream_p error_i) :
Base(first_string, last_string),
argfunction_v(argfunction_i->copy_pointer()),
argfunction_v(argfunction_i->copy_pointer()),
input(input_i), output(output_i), error(error_i),
parent_map_v(parent_map_i) {
argc_v = Base::size();};
// constructor of Argm from an initial argument and a pair of iterators
template <class String_it>
template <class String_it>
inline Argm::Argm(const std::string& first_string,
String_it second_string, String_it last_string,
Command_block* argfunction_i, Variable_map* parent_map_i,
Rwsh_istream_p input_i, Rwsh_ostream_p output_i,
Rwsh_ostream_p error_i) :
Base(second_string, last_string),
argfunction_v(argfunction_i->copy_pointer()),
argfunction_v(argfunction_i->copy_pointer()),
input(input_i), output(output_i), error(error_i),
parent_map_v(parent_map_i) {
Base::insert(Base::begin(), first_string);
......@@ -32,7 +32,7 @@ inline Argm::Argm(const std::string& first_string,
// write the strings corresponding to $*
template<class Out>
inline Out Argm::star_var(const std::string& key, unsigned reference_level,
inline Out Argm::star_var(const std::string& key, unsigned reference_level,
Out res) const {
int n = std::atoi(key.c_str());
if (n < 0) n = 0;
......@@ -51,14 +51,14 @@ Out tokenize_words(const std::string& in, Out res) {
for (; i<in.length(); ++i)
if (in[i] == '(') {if (!nesting++) ++token_start;}
else if (in[i] == ')') {if (!nesting--)
throw Signal_argm(Argm::Mismatched_parenthesis, in.substr(0, i+1));}
throw Exception(Argm::Mismatched_parenthesis, in.substr(0, i+1));}
else if (!nesting && isspace(in[i])) {
unsigned end = i;
while (i<in.length() && isspace(in[i])) ++i; // drop leading space
if (in[end-1] == ')') *res++ = in.substr(token_start, end-token_start-1);
else *res++ = in.substr(token_start, end-token_start);
token_start = i--;}
if (nesting) throw Signal_argm(Argm::Mismatched_parenthesis, in);
if (nesting) throw Exception(Argm::Mismatched_parenthesis, in);
if (token_start != i)
if (in[i-1] == ')') *res = in.substr(token_start, i-token_start-1);
else *res = in.substr(token_start, i-token_start);
......
This diff is collapsed.
// Copyright (C) 2006-2016 Samuel Newbold
int b_argc(const Argm& argm);
int b_cd(const Argm& argm);
int b_combine(const Argm& argm);
int b_echo(const Argm& argm);
int b_if(const Argm& argm);
int b_else_if(const Argm& argm);
int b_else_if_not(const Argm& argm);
int b_else(const Argm& argm);
int b_exec(const Argm& argm);
int b_exit(const Argm& argm);
int b_for(const Argm& argm);
int b_for_each_line(const Argm& argm);
int b_fork(const Argm& argm);
int b_function(const Argm& argm);
int b_function_all_flags(const Argm& argm);
int b_global(const Argm& argm);
int b_importenv_overwrite(const Argm& argm);
int b_importenv_preserve(const Argm& argm);
int b_internal_functions(const Argm& argm);
int b_is_default_input(const Argm& argm);
int b_is_default_output(const Argm& argm);
int b_is_default_error(const Argm& argm);
int b_list_locals(const Argm& argm);
int b_local(const Argm& argm);
int b_ls(const Argm& argm);
int b_nop(const Argm& argm);
int b_return(const Argm& argm);
int b_scope(const Argm& argm);
int b_set(const Argm& argm);
int b_selection_set(const Argm& argm);
int b_signal_handler(const Argm& argm);
int b_source(const Argm& argm);
int b_stepwise(const Argm& argm);
int b_store_output(const Argm& argm);
int b_test_string_equal(const Argm& argm);
int b_test_greater(const Argm& argm);
int b_test_less(const Argm& argm);
int b_test_is_number(const Argm& argm);
int b_test_not_empty(const Argm& argm);
int b_test_string_unequal(const Argm& argm);
int b_test_number_equal(const Argm& argm);
int b_unset(const Argm& argm);
int b_usleep(const Argm& argm);
int b_var_add(const Argm& argm);
int b_var_subtract(const Argm& argm);
int b_var_divide(const Argm& argm);
int b_var_exists(const Argm& argm);