Commit 674b1b74 authored by Samuel Newbold's avatar Samuel Newbold

replacing function_flag_ignorant with syntax plus better error messages ...

for arguments not matching prototypes and some refactoring.
parent 0ed885f6
......@@ -146,6 +146,17 @@ Signal_argm::Signal_argm(Sig_type signal_i, const std::string& x,
push_back(x);
push_back(y);}
Signal_argm::Signal_argm(Sig_type signal_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]);
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) :
Argm(Variable_map::global_map, default_input,default_output,default_error),
signal(signal_i) {
......
......@@ -33,9 +33,11 @@ class Argm : private std::vector<std::string> {
enum Sig_type {
No_signal,
Ambiguous_prototype_dash_dash,
Arguments_for_argfunction,
Bad_argc,
Bad_argfunction_style,
Bad_args,
Bad_if_nest,
Binary_not_found,
Dash_dash_argument,
......@@ -44,14 +46,15 @@ class Argm : private std::vector<std::string> {
Double_redirection,
Duplicate_parameter,
Elipsis_first_arg,
Elipsis_out_of_option_group,
Else_without_if,
Excess_argfunction,
Excessive_nesting,
Executable_not_found,
Failed_substitution,
File_open_failure,
Flag_in_elipsis,
If_before_else,
Ignored_flag,
Input_range,
Invalid_word_selection,
// Line_continuation,
......@@ -66,6 +69,7 @@ class Argm : private std::vector<std::string> {
Raw_command,
Result_range,
Post_elipsis_option,
Post_dash_dash_flag,
Prompt,
Selection_not_found,
Shutdown,
......@@ -80,6 +84,7 @@ class Argm : private std::vector<std::string> {
Sigusr1,
Sigusr2,
Sigunknown,
Tardy_flag,
Undefined_variable,
Unreadable_dir,
Unrecognized_flag,
......@@ -128,6 +133,8 @@ struct Signal_argm : public Argm {
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,
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);};
......
......@@ -45,6 +45,12 @@ extern char** environ;
#include "function.h"
#include "argm_star_var.cc"
// print the number of arguments passed
int b_argc(const Argm& argm) {
if (argm.argfunction()) throw Signal_argm(Argm::Excess_argfunction);
argm.output <<argm.argc()-1;
return 0;}
// change the current directory to the one given
// returns the error returned from chdir
int b_cd(const Argm& argm) {
......@@ -168,7 +174,7 @@ int b_function(const Argm& argm) {
return 4 * !executable_map.erase(*(argm.begin()+1));}
else {
executable_map.set(new Function(argm[1], argm.end(), argm.end(), true,
IGNORANT, *argm.argfunction()));
ALL, *argm.argfunction()));
return 0;}}
namespace {
......@@ -194,12 +200,6 @@ int function_core(const Argm& argm, Flag_type all_flags) {
int b_function_all_flags(const Argm& argm) {
return function_core(argm, ALL);}
// add argfunction to executable map with name $1 and arguments $*2
// all arguments will be treated as positional arguments whether they begin
// with a dash or not.
int b_function_flag_ignorant(const Argm& argm) {
return function_core(argm, IGNORANT);}
// add a variable to the variable map that will remain after the enclosing
// function terminates
int b_global(const Argm& argm) {
......
// 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);
......@@ -14,7 +15,6 @@ 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_function_flag_ignorant(const Argm& argm);
int b_global(const Argm& argm);
int b_importenv_overwrite(const Argm& argm);
int b_importenv_preserve(const Argm& argm);
......
......@@ -77,15 +77,6 @@ std::string Command_block::str() const {
for (const_iterator i = begin(); i != end()-1; ++i) body += i->str() + "";
return "{" + body + back().str() + "}";} //+ trailing + ",";}
std::string Parameter_group::str() const {
if (required) return names[0] + (elipsis? "": " ...");
else {
std::string result("[");
if (elipsis == -1) result.append("... ");
for (std::vector<std::string>::size_type j = 0; j < names.size(); ++j)
result.append((j? " ": "") + names[j] + (elipsis == j? " ...": ""));
return result + "]";}}
Command_block::Command_block(const std::string& src,
std::string::size_type& point,
unsigned max_soon) {
......@@ -155,4 +146,7 @@ void Function::promote_soons(unsigned nesting) {
// convert the function to a string. except for the handling of the name this
// is the inverse of the string constructor.
std::string Function::str() const {
return prototype.str(name()) + body.str();}
if (prototype.non_prototype)
return ".function " + escape(name()) + " " + body.str();
else return ".function_all_flags " + escape(name()) +
" " + prototype.str() + " " + body.str();}
This diff is collapsed.
// Copyright (C) 2015-2016 Samuel Newbold
enum Flag_type {ALL, SOME, IGNORANT};
enum Flag_type {ALL, SOME};
enum Dash_dash_type {UNSEEN, BRACKET, BARE};
std::string escape(const std::string& src);
struct Parameter_group {
bool required;
......@@ -8,20 +11,34 @@ struct Parameter_group {
std::vector<std::string> names;
Parameter_group() : required(true), elipsis(-2), names() {};
Parameter_group(bool required_i): required(required_i),elipsis(-2),names() {};
Parameter_group(Argm::const_iterator& fp, Argm::const_iterator end,
std::set<std::string>& parameter_names);
void arg_to_param(Variable_map& locals, int& available, int& needed,
std::string& missing,
Argm::const_iterator& f_arg,
const Argm::const_iterator end,
const std::string* flag,
const std::string& elipsis_var,
enum Dash_dash_type dash_dash) const;
std::string str() const; };
class Prototype {
bool non_prototype;
bool explicit_dash_dash;
bool bare_dash_dash;
int dash_dash_position;
Flag_type flags;
unsigned required_argc;
std::string elipsis_var;
std::map<std::string, Parameter_group> flag_options;
std::set<std::string> parameter_names;
std::vector<Parameter_group> positional;
public:
bool non_prototype;
Prototype(bool non_prototype);
Prototype(Argm::const_iterator first_parameter,
Argm::const_iterator parameter_end,
bool non_prototype_i, Flag_type flags_i);
Variable_map arg_to_param(const Argm& invoking_argm) const;
std::string str(const std::string &function_name) const;};
Argm bad_args(std::string& missing, const Variable_map& locals,
Argm::const_iterator f_arg, Argm::const_iterator end,
std::vector<Parameter_group>::const_iterator param) const;
std::string str() const;};
......@@ -38,9 +38,11 @@ Argm::Sig_type Base_executable::caught_signal(Argm::No_signal);
bool Base_executable::in_signal_handler(false);
std::string Argm::signal_names[Argm::Signal_count] = {
"no signal",
"rwsh.ambiguous_prototype_dash_dash",
"rwsh.arguments_for_argfunction",
"rwsh.bad_argc",
"rwsh.bad_argfunction_style",
"rwsh.bad_args",
"rwsh.bad_if_nest",
"rwsh.binary_not_found",
"rwsh.dash_dash_argument",
......@@ -49,14 +51,15 @@ std::string Argm::signal_names[Argm::Signal_count] = {
"rwsh.double_redirection",
"rwsh.duplicate_parameter",
"rwsh.elipsis_first_arg",
"rwsh.elipsis_out_of_option_group",
"rwsh.else_without_if",
"rwsh.excess_argfunction",
"rwsh.excessive_nesting",
"rwsh.executable_not_found",
"rwsh.failed_substitution",
"rwsh.file_open_failure",
"rwsh.flag_in_elipsis",
"rwsh.if_before_else",
"rwsh.ignored_flag",
"rwsh.input_range",
"rwsh.invalid_word_selection",
// "rwsh.line_continuation",
......@@ -71,6 +74,7 @@ std::string Argm::signal_names[Argm::Signal_count] = {
"rwsh.raw_command",
"rwsh.result_range",
"rwsh.post_elipsis_option",
"rwsh.post_dash_dash_flag",
"rwsh.prompt",
"rwsh.selection_not_found",
"rwsh.shutdown",
......@@ -85,6 +89,7 @@ std::string Argm::signal_names[Argm::Signal_count] = {
"rwsh.sigusr1",
"rwsh.sigusr2",
"rwsh.sigunknown",
"rwsh.tardy_flag",
"rwsh.undefined_variable",
"rwsh.unreadable_dir",
"rwsh.unrecognized_flag",
......
......@@ -21,6 +21,7 @@
#include "function.h"
void internal_init(void) {
executable_map.set(new Builtin(".argc", b_argc));
executable_map.set(new Builtin(".cd", b_cd));
executable_map.set(new Builtin(".combine", b_combine));
executable_map.set(new Builtin(".echo", b_echo));
......@@ -35,8 +36,6 @@ void internal_init(void) {
executable_map.set(new Builtin(".function", b_function));
executable_map.set(new Builtin(".function_all_flags",
b_function_all_flags));
executable_map.set(new Builtin(".function_flag_ignorant",
b_function_flag_ignorant));
executable_map.set(new Builtin(".global", b_global));
executable_map.set(new Builtin(".if", b_if));
executable_map.set(new Builtin(".importenv_overwrite",
......
.function_flag_ignorant # [ignored ...] {
.function_all_flags # -- [ignored ...] {
.local ret $?
.if .var_exists argv {.nop $ignored}
.else {.nop}
......@@ -9,13 +9,13 @@
)
# ability of functions to act as builtin wrappers
.function_flag_ignorant af [argv ...] {rwsh.argfunction}
.function_flag_ignorant c text ... {.combine $text$}
.function_flag_ignorant e text ... {.echo $text}
.function_flag_ignorant echo text ... {.echo $text $nl}
.function_flag_ignorant elif command ... {.else_if $command$ {rwsh.argfunction}}
.function_flag_ignorant else {.else {rwsh.argfunction}}
.function_flag_ignorant fn prototype ... {
.function_all_flags af -- [argv ...] {rwsh.argfunction}
.function_all_flags c -- text ... {.combine $text$}
.function_all_flags e -- text ... {.echo $text}
.function_all_flags echo -- text ... {.echo $text $nl}
.function_all_flags elif command ... {.else_if $command$ {rwsh.argfunction}}
.function_all_flags else {.else {rwsh.argfunction}}
.function_all_flags fn -- prototype ... {
.function_all_flags $prototype$ {rwsh.argfunction}
.local ret $?
.if .test_number_equal $ret 1 {echo cannot set paths as functions}
......@@ -23,16 +23,16 @@
.else_if .test_number_equal $ret 3 {echo cannot set argfunctions in executable map}
.else_if .test_number_equal $ret 4 {echo function &&1 did not exist to be erased}
.else {.return $ret}}
.function_flag_ignorant fni prototype ... {
.function_flag_ignorant $prototype$ {rwsh.argfunction}
.function_all_flags fni -- name args ... {
.function_all_flags $name -- $args$ {rwsh.argfunction}
.local ret $?
.if .test_number_equal $ret 1 {echo cannot set paths as functions}
.else_if .test_number_equal $ret 2 {echo cannot set builtins as functions}
.else_if .test_number_equal $ret 3 {echo cannot set argfunctions in executable map}
.else_if .test_number_equal $ret 4 {echo function &&1 did not exist to be erased}
.else {.return $ret}}
.function_flag_ignorant fns name prototype ... {
.function_all_flags $name [-*] $prototype$ {rwsh.argfunction}
.function_all_flags fns -- name args ... {
.function_all_flags $name [-*] $args$ {rwsh.argfunction}
.local ret $?
.if .test_number_equal $ret 1 {echo cannot set paths as functions}
.else_if .test_number_equal $ret 2 {echo cannot set builtins as functions}
......@@ -40,7 +40,8 @@
.else_if .test_number_equal $ret 4 {echo function &&1 did not exist to be erased}
.else {.return $ret}}
.function if {.if $* {rwsh.argfunction}}
.function if_only {.if $* {rwsh.argfunction}; .else {.nop}}
.function_all_flags if_only -- args ... {
.if $args$ {rwsh.argfunction}; .else {.nop}}
.function if_only_not {.if $* {.nop}; .else {rwsh.argfunction}}
.function timings {
.echo last time (); .which_last_execution_time $*; c $nl
......@@ -50,12 +51,12 @@
.function setf {
.if .var_exists $1 {.set &&1 &&2}
.else {.global &&1 &&2}}
.function_flag_ignorant set_if_undefined var [value] {
.function_all_flags set_if_undefined -- var [value] {
.if .var_exists $var {.nop}
.else_if .var_exists value {.global $var $value}
.else {.global $var ()}}
fn test_var_not_equal var value {.test_string_unequal $$var $value}
fn test_var_greater var value {.test_greater $$var $value}
.function_all_flags test_var_greater -- var value {.test_greater $$var $value}
fn ntimes n {
.while test_var_greater n 0 {
rwsh.mapped_argfunction {rwsh.argfunction}
......@@ -72,5 +73,20 @@ fn whichp binary {
.if .test_number_equal $? 0 {.nop}
.else {echo &&binary not found in $PATH; .return 1}}
.function while {.while $* {rwsh.argfunction}}
fn var_exists var {.var_exists $var}
.function_all_flags var_exists -- var {.var_exists $var}
.function_all_flags paren_if_words -- value {
.if .test_number_equal ${.argc $value$} 1 {.combine $value}
.else {.combine \( $value \)}}
.function_all_flags rwsh.bad_args -- proto assigned needed excess call_stack ... {
.combine (unacceptable arguments: for prototype ) $proto , $nl
if_only .test_not_empty $assigned {
.combine ( assigned )
.for $assigned$ {.combine $1$0 = ${paren_if_words $1$1} ( )}
.combine , $nl ( but)}
if_only .test_not_empty $needed {
.combine ( needed \() $needed \), $nl
if_only .test_not_empty $excess {.combine ( and)}}
if_only .test_not_empty $excess {
.combine ( found \() $excess (\) excess) $nl}
.echo \ call stack: $call_stack $nl
.return -1}
......@@ -145,6 +145,9 @@ fn unselect {.set s ()}
.function rwsh.autofunction {
.function $1 {&&{.which_path &&1 $PATH} $*}
# if_only .return 0 {.echo added &&1 to executable map $nl}}
.function rwsh.ambiguous_prototype_dash_dash {
.echo $1 is an ambiguous location for a prototype -- (it requests reading the user's mind) $nl
.return -1}
.function rwsh.bad_argfunction_style {
.echo $1 is neither an argfunction nor a substitution $nl
.return -1}
......@@ -174,6 +177,10 @@ fn unselect {.set s ()}
.echo $1: elipsis cannot be the first argument in a prototype $nl
.echo call stack: $*2 $nl
.return -1}
.function rwsh.elipsis_out_of_option_group {
.echo $1: for elipsis to apply to option it must occur within the brackets $nl
.echo call stack: $*2 $nl
.return -1}
.function rwsh.else_without_if {
.echo else without if with call stack: $* $nl
.return -1}
......@@ -189,15 +196,14 @@ fn unselect {.set s ()}
.function rwsh.failed_substitution {
echo substitution $1 failed
echo call stack $*2}
.function rwsh.flag_in_elipsis {
echo found flag $1 while collecting arguments for elipsis
echo call stack $*2}
.function rwsh.help {
.echo this is the default configuration for rwsh \(or something copied from it\), documentation should be available at rwsh.sf.net $nl}
.function rwsh.if_before_else {
.echo two .if commands without a .else between them with call stack : $* $nl
.return -1}
.function rwsh.ignored_flag {
.echo flag options such as $1 are not accepted by .function_flag_ignorant $nl
.echo call stack: $*2 $nl
.return -1}
.function rwsh.input_range {
.echo value $1 is out of usable numeric range $nl
.return -1}
......@@ -240,6 +246,10 @@ fn unselect {.set s ()}
.echo option $1 coming after an elipsis has no meaning $nl
.echo call stack: $*2 $nl
.return -1}
.function rwsh.post_dash_dash_flag {
.echo flag option $1 occurs after -- in the prototype $nl
.echo call stack: $*2 $nl
.return -1}
.function rwsh.selection_not_found {
.echo no file matching pattern $1
.if .test_string_unequal $1 $2 {.echo () for selection &&2 $nl}
......@@ -257,6 +267,10 @@ fn unselect {.set s ()}
.function rwsh.sigusr1 {.echo $nl received SIGUSR1: $* $nl}
.function rwsh.sigusr2 {.echo $nl received SIGUSR2: $* $nl}
.function rwsh.sigunknown {.echo $nl received unknown unix signal: $* $nl}
.function rwsh.tardy_flag {
.echo $1 flag comes too late in command $nl
.echo call stack: $*2 $nl
.return -1}
.function rwsh.undefined_variable {
.echo $1 was undefined with call stack $*2 $nl}
.function rwsh.unreadable_dir {.echo cannot read directory $1 $nl}
......@@ -275,11 +289,11 @@ fn unselect {.set s ()}
echo s $s}
# misc
.function_flag_ignorant . command ... {.source $command$}
.function_all_flags . -- command ... {.source $command$}
.function ! {if $* {.return 1}; else {.return 0}}
.function_flag_ignorant ex_count cmd {.which_execution_count $cmd; c $nl}
.function_flag_ignorant exec command ... {.exec $command$ }
.function_flag_ignorant exit {.exit}
.function_all_flags ex_count -- cmd {.which_execution_count $cmd; c $nl}
.function_all_flags exec -- command ... {.exec $command$ }
.function_all_flags exit {.exit}
.function last_time {.which_last_execution_time $*; c $nl}
.function total_time {.which_total_execution_time $*; c $nl}
.function user_shell_ratio {
......
This diff is collapsed.
.set MAX_NESTING 7
.global nl (
)
.for &{.internal_functions}$ {.function $1 {.echo signal triggered: $0 \( $* \) $nl; .return -1}}
......
......@@ -41,8 +41,6 @@ w e
w () {}
e text that does not have a prompt appended
m {e again}
.function_all_flags if_only first_argument second_argument {
.if $first_argument $second_argument {rwsh.argfunction}; .else {.nop}}
if_only .return 1 {e not printed}
if_only .return 0 {e printed without error}
.function for {
......@@ -95,9 +93,9 @@ e @/etc/rw*ic
e @/etc/rwsh*a*
.set FIGNORE *de*
e @/etc/rwsh*a*
e @*r*w*s*r*c*b*a*
e @test_files/*i*x*y*y*x*
e @test_main.sh
m {m {.for @*hrc* {e $1 $nl}} >test_files/tmp}
m {m {.for @test_files/*x* {e $1 $nl}} >test_files/tmp}
sort test_files/tmp
.scope r*h.cc sel*.h (A ...) {e @$A}
......@@ -233,6 +231,12 @@ f x
.unset OLD_NESTING
# builtin tests
# .argc
.argc {excess argfunc}
.argc
.argc ()
.argc (1 a) (2 b (c d)) (3 ((e () f)))
# .cd
.cd
.cd /bin {excess argfunc}
......@@ -295,7 +299,7 @@ b
f g {e hi $nl; f g {e there $nl}; f h {e nothing here}; g}
g
# .function_all_flags .function_flag_ignorant
# .function_all_flags
.function_all_flags
.function_all_flags /bin/echo {e cannot define a path to be a function}
.function_all_flags .exit {e cannot redefine a builtin as a function}
......@@ -306,28 +310,30 @@ g
.function_all_flags a [x x] {e illegal duplicate optional parameter}
.function_all_flags a [-x arg bar] [-y arg] {e illegal duplicate flag argument}
.function_all_flags a -x [-x] {e evil duplication between flags positional}
.function_all_flags a -- {e -- cannot be a required parameter}
.function_all_flags a [--] [--] {e even -- cannot be a duplicate flag parameter}
.function_all_flags a -- -- {e -- cannot be a duplicate parameter}
.function_all_flags a [--] [--] {e [--] cannot be a duplicate parameter}
.function_all_flags a [--] -- {e -- and [--] cannot both be parameters}
.function_all_flags a [-- arg] {e -- cannot take arguments}
.function_all_flags a [arg -- foo] {e -- cannot take arguments}
.function_all_flags nonsense
w test_var_greater
.set A $MAX_NESTING
.set MAX_NESTING 15
test_var_greater MAX_NESTING
test_var_greater MAX_NESTING 3 12
test_var_greater MAX_NESTING 3
w ntimes
ntimes -- 3 {e $n remaining $nl}
ntimes 3 -- {e -- must preceed all positional arguments}
ntimes 2 {ntimes 3 {e &&n and $n remaining $nl}}
.set MAX_NESTING $A
.function_all_flags a [-x] [-] [--long-opt y second {
e mismatched bracket (i.e. missing close brakcet)}
.function_all_flags a [-x] {
e unrecognized_flag, not undefined_variable $nl
test_var_greater -x 1}
.function_all_flags a [-*] [--] {.list_locals}
.function_all_flags a [-x] [--] foo {.list_locals}
.function_all_flags a [-*] -- foo {.list_locals}
.function_all_flags a [-x] -- {.list_locals}
.function_all_flags a [--] {.list_locals}
w a
a
a --
a foo
.function_all_flags a [-x] [--long-opt y] second {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
......@@ -344,11 +350,13 @@ a
a single
a -q one two
a -q opt and req
a -x opt and req
a -x opt and
a -x first second third fourth req
a -q one two -q three four five
a -x one two three four -q five six seven
.function_all_flags a [optional0] [optional1 optional2 optional3] required {
a -x one two three four five -q six seven
a one -x two three four five -q six seven
.function_all_flags a [optional0] -- [optional1 optional2 optional3] required {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
a
......@@ -364,7 +372,7 @@ a
a 1
a 1 2
a 1 2 3
.function_all_flags a [-x] [-] [--long-opt] -y second {
.function_all_flags a [-x] -y [--long-opt] second [--] [-] {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
a --long-opt -xx over-long flag
......@@ -373,29 +381,35 @@ a --long-op short flag
a - --long-op short flag
a no flags
a deficient
a flagless excess argument
a flagless but_has excess argument
a -x with flag
a -x -x doubled flag
a unaccepted -x interlaced_flag
a accepted -x interlaced_flag -
a tardy flags_last - -x
a -x -- - flag_made_fixed_argument
a -- - flag_again_made_fixed_argument
a -x with excess argument
a -x -- flag_and_fixed-x -x
a -x just flags-x --long-opt
a -x just flags-x -- --long-opt
a -x just flags-x --other
a -x just flags-x -- --other
a -x with one excess argument
a - with flag
a --long-opt with flag
a -x - some_flags in_order
a - -x some_flags reversed
a --long-opt -x - some_flags in_order
a - -x --long-opt some_flags reversed
a - --long-opt some_flags in_order
a --long-opt - some_flags reversed
a -x --long-opt some_flags in_order
a --long-opt -x some_flags reversed
a -x - --long-opt deficient
a -x --long-opt deficient
a -x - --long-opt all_flags in_order
a --long-opt - -x all_flags reversed
a - --long-opt -x all_flags shuffled
a - --long-opt -x - -x some_flags doubled
a - -x - -x - one_doubled one_tripled
a --long-opt - -x -x - --long-opt all_flags doubled
.function_all_flags a [-first] [-to] [--] {
a - --long-opt -x -x some_flags doubled
a -x --long-opt -x --long-opt -x one_doubled one_tripled
a --long-opt -x -x - --long-opt all_flags doubled
.function_all_flags a [-first] [-to] {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }
e nothing_required}
w a
......@@ -427,6 +441,10 @@ a
.function_all_flags a [...] x {}
.function_all_flags a [... y] x {}
.function_all_flags a x ... [y z] {}
.function_all_flags a x [... y] z ... {}
.function_all_flags a [y z] ... x {}
.function_all_flags a [y] ... x {}
w a
.function_all_flags a x ... y ... {}
.function_all_flags a [x ...] [y z] {}
.function_all_flags a [x ...] y ... {}
......@@ -435,9 +453,15 @@ a
.function_all_flags a [x ... a ...] {}
.function_all_flags a [x ... a ... b] {}
.function_all_flags a [-x ...] b [c] {}
.function_all_flags a -* x ... y {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
a -c -a -b first second third
a -c first -a second -b third
.function_all_flags a [-*] x ... y {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
a
a first
a first (se cond)
a first (se cond) third
......@@ -447,7 +471,7 @@ a first (se cond) third fourth (fi fth)
w a
a
a first second third fourth fifth
.function_all_flags a [-*] x [y ...] {
.function_all_flags a [-*] x [--] [y ...] {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
a
......@@ -479,6 +503,8 @@ a first
a -x first
a -x (fi rst) second
a -x first (sec ond) third
a -x first -x (sec ond) third
a -x first -y (sec ond) third
a -x (fi rst) (sec ond) third fourth
.function_all_flags a [-x ... b] c {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }
......@@ -529,8 +555,8 @@ a (fi rst) second
a (fi rst) (sec ond) (thi rd)
a (fi rst) (sec ond) third (fou rth)
a (fi rst) (sec ond) (thi rd) (fou rth) (fi fth)
.function_flag_ignorant a [-x] y z {}
.function_flag_ignorant a [x y] z {
.function_all_flags a -- [-x] y z {}
.function_all_flags a -- [x y] z {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
a
......@@ -701,12 +727,15 @@ m {.is_default_error}
.scope a ([x x]) {e illegal duplicate optional parameter}
.scope a ([-x arg bar] [-y arg]) {e illegal duplicate flag argument}
.scope a (-x [-x]) {e evil duplication between flags positional}
.scope a -- {e -- cannot be a required parameter}
.scope a ([--] [--]) {e even -- cannot be a duplicate flag parameter}
.scope -- -- {e -- as a prototype forbids even -- as arguments}
.scope -- () {e but ${.list_locals} is acceptable for empty prototype}
.scope a (-- --) {e -- cannot be a duplicate parameter}
.scope a ([--] [--]) {e [--] cannot be a duplicate flag parameter}
.scope a ([--] --) {e -- and [--] cannot both be parameters}
.scope a ([-- arg]) {e -- cannot take arguments}
.scope a ([arg -- foo]) {e -- cannot be an argument}
.scope -x -y a b ([-*] args ...) {for ${.list_locals}$ {.combine $1 = $$1 \ }}
.scope a ([-* bad] args ...) {e -* cannot currently take arguments}
.scope a ([-* bad] arg) {e -* cannot currently take arguments}
.scope -a -* -b a ([-*] a) {for ${.list_locals}$ {.combine $1 = $$1 \ }}
.scope bar foo {e aa $foo bb}
.scope baz bax (foo bar) {for ${.list_locals}$ {.combine $1 = $$1 \ }}
......@@ -715,7 +744,7 @@ m {.is_default_error}
.function_all_flags a [-x] [--long-opt y] second {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
w a
.function_flag_ignorant pt args ... {
.function_all_flags pt -- args ... {
.scope $args$ ([-x] [--long-opt y] second) {
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
.combine $nl
......@@ -737,7 +766,7 @@ pt --long-opt first -x --long-opt second single
for ${.list_locals}$ {.combine $1 \( $$1 \) \ }
e nothing_required}
w a
.function_flag_ignorant pts [args ...] {
.function_all_flags pts -- [args ...] {
.if var_exists args {
.scope $args$ ([-first] [-*]) {
.for ${.list_locals}$ {.combine $1 \( $$1 \) \ }}
......@@ -816,10 +845,6 @@ f wrapper {a $* one; a $* two; a $* three}
wrapper 1 2
.stepwise wrapper 1 2 {d $*}
.stepwise wrapper 1 2 {e $* $nl}
.set A $MAX_NESTING
.set MAX_NESTING 15
.stepwise wrapper 1 2 {d $*}
.set MAX_NESTING $A
# .test_string_equal .test_string_unequal .test_not_empty
.test_string_equal x
......@@ -1121,6 +1146,7 @@ g {}
f g {h}
f h {g}
g
.stepwise g {e $* $nl; $*}
f rwsh.excessive_nesting {h}
g
......
......@@ -18,13 +18,11 @@
char** env;
namespace {
std::string word_from_value(const std::string& value) {
if (value == "") return std::string("()");
else if (value.find_first_of(" \t\n") != std::string::npos)
return "(" + value + ")";
else return value;}
} // close unnamed namespace
Variable_map::Variable_map(Variable_map* parent_i) : parent(parent_i) {
if (parent_i == NULL) {
......
// Copyright (C) 2006-2016 Samuel Newbold
extern const char* WSPACE;
std::string word_from_value(const std::string& value);
class Variable_map : private std::map<std::string, std::string> {
typedef std::map<std::string, std::string> Base;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment