Commit d18ef87f authored by Samuel Newbold's avatar Samuel Newbold

.global .local & .unset throw exceptions

... rather than returning integers that they hope you will check
parent 541e20f3
......@@ -117,6 +117,10 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .function_not_found -- cmd [stack ...] {
echo $cmd : command not found \( $cmd $stack$ \)}
.function_all_flags .global_would_be_masked name stack ... {
.echo requested global $name already exists as a local
echo . It would be masked by the local and inaccessible from here
echo call stack $stack$}
.function_all_flags .help [args ...] {
.nop $args$
.echo this is the default configuration for rwsh \(or something copied from it
......@@ -236,6 +240,9 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .unused_variable -- var [stack ...] {
echo $var was unused with call stack $stack$}
.function_all_flags .variable_already_exists name stack ... {
echo variable $name already exists
echo call stack $stack$}
.function_all_flags .version_incompatible version stack ... {
echo this shell is not compatible with requested version $version
echo call stack: $stack$}
......@@ -309,9 +316,12 @@ polish / .var_divide
.else_if .test_string_equal $2 -c {
.for ${.list_environment}$ {
.scope $1$ (-- var val) {
.global $var $val
.nop $$var}}
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
.nop $FIGNORE
.function_all_flags .if_before_else stack ... {.nop $stack}
.function_all_flags .shutdown -- args ... {.nop $args; .return 0}
.collect_errors_except .nop {
......
......@@ -118,26 +118,29 @@ bool Argm::var_exists(const std::string& key) const {
return argv_v.size() > n;}
default: return parent_map()->exists(key, true);}}
int Argm::global(const std::string& key, const std::string& value) const {
void 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 '6': case '7': case '8': case '9': case '0': return 2;
default: return parent_map()->global(key, value);}}
case '6': case '7': case '8': case '9': case '0':
throw Exception(Argm::Illegal_variable_name, key);
default: parent_map()->global(key, value);}}
int Argm::local(const std::string& key, const std::string& value) const {
void 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 '6': case '7': case '8': case '9': case '0': return 2;
default: return parent_map()->local(key, value);}}
case '6': case '7': case '8': case '9': case '0':
throw Exception(Argm::Illegal_variable_name, key);
default: parent_map()->local(key, value);}}
void Argm::locals_listed(void) const {
parent_map()->locals_listed = true;}
int Argm::unset_var(const std::string& key) const {
void Argm::unset_var(const std::string& key) const {
switch (key[0]) {
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);}}
case '6': case '7': case '8': case '9': case '0':
throw Exception(Argm::Illegal_variable_name, key);
default: parent_map()->unset(key);}}
// algorithm that is the meat of Old_argv constructor
template<class In>char** copy_to_cstr(In first, In last, char** res) {
......
......@@ -58,6 +58,7 @@ class Argm {
File_not_found,
Flag_in_elipsis,
Function_not_found,
Global_would_be_masked,
If_before_else,
Illegal_function_name,
Illegal_variable_name,
......@@ -102,6 +103,7 @@ class Argm {
Unrecognized_flag,
Unused_before_set,
Unused_variable,
Variable_already_exists,
Version_incompatible,
Exception_count};
......@@ -112,13 +114,13 @@ class Argm {
parent_map()->export_env(env);}
std::string get_var(const std::string& key) const;
int global(const std::string& key, const std::string& value) const;
int local(const std::string& key, const std::string& value) const;
void global(const std::string& key, const std::string& value) const;
void local(const std::string& key, const std::string& value) const;
void locals_listed(void) const;
void 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;
int unset_var(const std::string& key) const;
void unset_var(const std::string& key) const;
bool var_exists(const std::string& key) const;
// map semantics
......
......@@ -335,7 +335,8 @@ int b_get_max_nesting(const Argm& argm, Error_list& exceptions) {
int b_global(const Argm& argm, Error_list& exceptions) {
if (argm.argc() != 3) throw Exception(Argm::Bad_argc, argm.argc()-1, 2, 0);
if (argm.argfunction()) throw Exception(Argm::Excess_argfunction);
else return argm.global(argm[1], argm[2]);}
argm.global(argm[1], argm[2]);
return 0;}
namespace {
bool in_if_block = false, successful_condition = false,
......@@ -521,7 +522,8 @@ int b_list_locals(const Argm& argm, Error_list& exceptions) {
int b_local(const Argm& argm, Error_list& exceptions) {
if (argm.argc() != 3) throw Exception(Argm::Bad_argc, argm.argc()-1, 2, 0);
if (argm.argfunction()) throw Exception(Argm::Excess_argfunction);
else return argm.local(argm[1], argm[2]);}
argm.local(argm[1], argm[2]);
return 0;}
// list the files specified by the arguments if they exist
int b_ls(const Argm& argm, Error_list& exceptions) {
......@@ -724,14 +726,13 @@ int b_stepwise(const Argm& argm, Error_list& exceptions) {
int b_store_output(const Argm& argm, Error_list& exceptions) {
if (argm.argc() != 2) throw Exception(Argm::Bad_argc, argm.argc()-1, 1, 0);
if (!argm.argfunction()) throw Exception(Argm::Missing_argfunction);
if (isargvar(argm[1])) return 2;
if (isargvar(argm[1])) throw Exception(Argm::Illegal_variable_name, argm[1]);
Substitution_stream text;
Argm mapped_argm(argm.parent_map(),
argm.input, text.child_stream(), argm.error);
mapped_argm.push_back(".mapped_argfunction");
int ret = (*argm.argfunction())(mapped_argm, exceptions);
if (Named_executable::unwind_stack()) return -1;
if (ret) return ret;
if (Named_executable::unwind_stack() || ret) return ret;
argm.set_var(argm[1], text.value());
return 0;}
......@@ -919,7 +920,8 @@ int b_type(const Argm& argm, Error_list& exceptions) {
int b_unset(const Argm& argm, Error_list& exceptions) {
if (argm.argc() != 2) throw Exception(Argm::Bad_argc, argm.argc()-1, 1, 0);
if (argm.argfunction()) throw Exception(Argm::Excess_argfunction);
else return argm.unset_var(argm[1]);}
argm.unset_var(argm[1]);
return 0;}
namespace {double sleep_requested = 0.0;}
......
......@@ -74,6 +74,7 @@ std::string Argm::exception_names[Argm::Exception_count] = {
".file_not_found",
".flag_in_elipsis",
".function_not_found",
".global_would_be_masked",
".if_before_else",
".illegal_function_name",
".illegal_variable_name",
......@@ -118,6 +119,7 @@ std::string Argm::exception_names[Argm::Exception_count] = {
".unrecognized_flag",
".unused_before_set",
".unused_variable",
".variable_already_exists",
".version_incompatible"};
bool readline_enabled = false;
Variable_map root_variable_map(nullptr);
......
......@@ -23,9 +23,12 @@
.else_if .test_string_equal $2 -c {
.for ${.list_environment}$ {
.scope $1$ (-- var val) {
.global $var $val
.nop $$var}}
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
.nop $FIGNORE
.function_all_flags .if_before_else stack ... {.nop $stack}
.function_all_flags .shutdown -- args ... {.nop $args; .return 0}
.collect_errors_except .nop {
......
......@@ -93,6 +93,10 @@
echo call stack $stack$}
.function_all_flags .function_not_found -- cmd [stack ...] {
echo $cmd : command not found \( $cmd $stack$ \)}
.function_all_flags .global_would_be_masked name stack ... {
.echo requested global $name already exists as a local
echo . It would be masked by the local and inaccessible from here
echo call stack $stack$}
.function_all_flags .help [args ...] {
.nop $args$
.echo this is the default configuration for rwsh \(or something copied from it
......@@ -212,6 +216,9 @@
echo call stack $stack$}
.function_all_flags .unused_variable -- var [stack ...] {
echo $var was unused with call stack $stack$}
.function_all_flags .variable_already_exists name stack ... {
echo variable $name already exists
echo call stack $stack$}
.function_all_flags .version_incompatible version stack ... {
echo this shell is not compatible with requested version $version
echo call stack: $stack$}
......
.for ${.list_environment}$ {
.scope $1$ (-- var val) {.global $var $val; .nop $$var}}
.scope $1$ (-- var val) {
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
# only the last line is actually needed, but this is the only test of these
......
......@@ -117,6 +117,10 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .function_not_found -- cmd [stack ...] {
echo $cmd : command not found \( $cmd $stack$ \)}
.function_all_flags .global_would_be_masked name stack ... {
.echo requested global $name already exists as a local
echo . It would be masked by the local and inaccessible from here
echo call stack $stack$}
.function_all_flags .help [args ...] {
.nop $args$
.echo this is the default configuration for rwsh \(or something copied from it
......@@ -236,6 +240,9 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .unused_variable -- var [stack ...] {
echo $var was unused with call stack $stack$}
.function_all_flags .variable_already_exists name stack ... {
echo variable $name already exists
echo call stack $stack$}
.function_all_flags .version_incompatible version stack ... {
echo this shell is not compatible with requested version $version
echo call stack: $stack$}
......@@ -309,9 +316,12 @@ polish / .var_divide
.else_if .test_string_equal $2 -c {
.for ${.list_environment}$ {
.scope $1$ (-- var val) {
.global $var $val
.nop $$var}}
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
.nop $FIGNORE
.function_all_flags .if_before_else stack ... {.nop $stack}
.function_all_flags .shutdown -- args ... {.nop $args; .return 0}
.collect_errors_except .nop {
......@@ -901,6 +911,7 @@ hello world
.file_not_found not defined
.flag_in_elipsis not defined
.function_not_found not defined
.global_would_be_masked not defined
.if_before_else not defined
.illegal_function_name not defined
.illegal_variable_name not defined
......@@ -943,6 +954,7 @@ hello world
.unrecognized_flag not defined
.unused_before_set not defined
.unused_variable not defined
.variable_already_exists not defined
.version_incompatible not defined
.help not defined
Exception for failed handler. Original exception with call stack:
......@@ -1045,9 +1057,12 @@ $./rwsh test_files/signal_triggered.rwsh <test_files/pause_hello.rwsh
signal triggered: .raw_command ( .else_if .test_string_equal $2 -c {
.for ${.list_environment}$ {
.scope $1$ (-- var val) {
.global $var $val
.nop $$var}}
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
.nop $FIGNORE
.function_all_flags .if_before_else stack ... {.nop $stack}
.function_all_flags .shutdown -- args ... {.nop $args; .return 0}
.collect_errors_except .nop {
......@@ -3653,6 +3668,11 @@ $.unset x {excess argfunc}
$.unset x y
unacceptable argument count: received 2 non-optional, but needed 1 (with 0 optional) for .unset
-1
$.unset ?
$? cannot be set
call stack .unset
-1
$.var_exists
unacceptable argument count: received 0 non-optional, but needed 1 (with 0 optional) for .var_exists
......@@ -3663,8 +3683,15 @@ $.var_exists x {excess argfunc}
-1
$.global 100 nihilism
$100 cannot be set
call stack .global
-1
$.local 0 nihilism
$0 cannot be set
call stack .local
2
-1
$.global .var_exists (must be requested to be checked)
0
......@@ -3672,20 +3699,30 @@ $e $.var_exists
must be requested to be checked
0
$.unset #
$# cannot be set
call stack .unset
3
-1
$.unset #
$# cannot be set
call stack .unset
3
-1
$.unset *
$* cannot be set
call stack .unset
3
-1
$.unset 1
$1 cannot be set
call stack .unset
3
-1
$.unset MAX_NESTING
MAX_NESTING was not declared
call stack: .unset
1
-1
$.var_exists #
0
......@@ -3719,8 +3756,10 @@ call stack .var_exists
-1
$.unset x
x was not declared
call stack: .unset
1
-1
$.global x nihilism
0
......@@ -3735,7 +3774,12 @@ nihilism
0
$.global x nihilism
1
0
$.global x ubernihilism
variable x already exists
call stack .global
-1
$.function_all_flags a {if_only .var_exists x {e in a x \( $x \) $nl}
if_only .var_exists y {e in a y \( $y \) $nl}
.local x (first level not global)
......@@ -3758,8 +3802,8 @@ $.function_all_flags c {if_only .var_exists x {e in c x \( $x \) $nl}
if_only .var_exists y {e in c y \( $y \) $nl}
# can unset a local, but only one at a time
.unset x
.global y (attempting to create global masked by local)
e $? $nl
.try_catch_recursive .global_would_be_masked {
.global y (attempting to create global masked by local)}
.set x (third level overwrites first)
.local x (third level masks first)
.set y (level three overwrites one)
......@@ -3773,7 +3817,8 @@ in b x ( first level not global )
in b y ( level one not global )
in c x ( second level masks first )
in c y ( level two overwrites one )
3
requested global y already exists as a local. It would be masked by the local and inaccessible from here
call stack .global .try_catch_recursive(body)
out c x ( third level masks first )
out c y ( level three overwrites one )
out b x ( third level overwrites first )
......@@ -3791,7 +3836,8 @@ in b x ( first level not global )
in b y ( level one not global )
in c x ( second level masks first )
in c y ( level two overwrites one )
3
requested global y already exists as a local. It would be masked by the local and inaccessible from here
call stack .global .try_catch_recursive(body)
out c x ( third level masks first )
out c y ( level three overwrites one )
out b x ( third level overwrites first )
......@@ -3832,6 +3878,11 @@ $.store_output x
$.store_output {e some text}
unacceptable argument count: received 0 non-optional, but needed 1 (with 0 optional) for .store_output
-1
$.store_output # {e some text}
$# cannot be set
call stack .store_output
-1
$.store_output x {e some text}
x was not declared
......@@ -4556,6 +4607,7 @@ $.internal_functions
.file_not_found
.flag_in_elipsis
.function_not_found
.global_would_be_masked
.if_before_else
.illegal_function_name
.illegal_variable_name
......@@ -4599,6 +4651,7 @@ $.internal_functions
.unrecognized_flag
.unused_before_set
.unused_variable
.variable_already_exists
.version_incompatible
0
$.internal_vars
......@@ -4744,6 +4797,7 @@ $.for ${.list_executables}$ {.combine $1 $nl}
.getpid
.getppid
.global
.global_would_be_masked
.help
.if
.if_before_else
......@@ -4839,6 +4893,7 @@ $.for ${.list_executables}$ {.combine $1 $nl}
.var_divide
.var_exists
.var_subtract
.variable_already_exists
.vars
.version
.version_compatible
......@@ -6811,7 +6866,8 @@ $whence .prompt
0
$whence .raw_command
.function_all_flags .raw_command -- cmd {.echo $cmd; .echo $nl}
.function_all_flags .raw_command -- cmd {.echo $cmd; .echo (
)}
0
$
......@@ -7309,7 +7365,11 @@ $.list_environment {excess argfunc}
-1
$for ${.list_environment}$ {
.scope $1$ (var val) {
.global $var $val}}
.if .test_in $var ? FIGNORE SHELL {echo $var : $$var to $val}
.else {.global $var $val}}}
? : 0 to 0
FIGNORE : *de* to ()
SHELL : unmodified to /bin/rwsh
0
$e $TESTABILITY
......
......@@ -117,6 +117,10 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .function_not_found -- cmd [stack ...] {
echo $cmd : command not found \( $cmd $stack$ \)}
.function_all_flags .global_would_be_masked name stack ... {
.echo requested global $name already exists as a local
echo . It would be masked by the local and inaccessible from here
echo call stack $stack$}
.function_all_flags .help [args ...] {
.nop $args$
.echo this is the default configuration for rwsh \(or something copied from it
......@@ -236,6 +240,9 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .unused_variable -- var [stack ...] {
echo $var was unused with call stack $stack$}
.function_all_flags .variable_already_exists name stack ... {
echo variable $name already exists
echo call stack $stack$}
.function_all_flags .version_incompatible version stack ... {
echo this shell is not compatible with requested version $version
echo call stack: $stack$}
......@@ -309,9 +316,12 @@ polish / .var_divide
.else_if .test_string_equal $2 -c {
.for ${.list_environment}$ {
.scope $1$ (-- var val) {
.global $var $val
.nop $$var}}
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
.nop $FIGNORE
.function_all_flags .if_before_else stack ... {.nop $stack}
.function_all_flags .shutdown -- args ... {.nop $args; .return 0}
.collect_errors_except .nop {
......@@ -417,6 +427,10 @@ $.source /etc/rwshrc-basic
echo call stack $stack$}
.function_all_flags .function_not_found -- cmd [stack ...] {
echo $cmd : command not found \( $cmd $stack$ \)}
.function_all_flags .global_would_be_masked name stack ... {
.echo requested global $name already exists as a local
echo . It would be masked by the local and inaccessible from here
echo call stack $stack$}
.function_all_flags .help [args ...] {
.nop $args$
.echo this is the default configuration for rwsh \(or something copied from it
......@@ -536,6 +550,9 @@ $.source /etc/rwshrc-basic
echo call stack $stack$}
.function_all_flags .unused_variable -- var [stack ...] {
echo $var was unused with call stack $stack$}
.function_all_flags .variable_already_exists name stack ... {
echo variable $name already exists
echo call stack $stack$}
.function_all_flags .version_incompatible version stack ... {
echo this shell is not compatible with requested version $version
echo call stack: $stack$}
......@@ -612,7 +629,7 @@ $.global PATH /bin:/usr/bin
0
$.getpid
24875
21045
0
$.getppid
4926
......@@ -636,22 +653,22 @@ $.function_all_flags clock-watch {
$clock-watch
timings: last(0.000000) total(0.000000) count(0)
clock-watch: last(0.000000) total(0.000000) count(0)
usleep overhead: 8.3e-05
.usleep: last(0.000683) total(0.000683) count(1)
/bin/true: last(0.001328) total(0.001328) count(1)
usleep overhead: 5.7e-05
.usleep: last(0.000657) total(0.000657) count(1)
/bin/true: last(0.002399) total(0.002399) count(1)
0
$clock-watch
timings: last(0.000137) total(0.000771) count(4)
clock-watch: last(0.003378) total(0.003378) count(1)
usleep overhead: 7.1e-05
.usleep: last(0.000659) total(0.001342) count(2)
/bin/true: last(0.000792) total(0.002120) count(2)
timings: last(0.000120) total(0.000552) count(4)
clock-watch: last(0.004244) total(0.004244) count(1)
usleep overhead: 6.8e-05
.usleep: last(0.000679) total(0.001336) count(2)
/bin/true: last(0.000874) total(0.003273) count(2)
0
$.mapped_argfunction {timings timings; timings clock-watch}
timings: last(0.000104) total(0.001263) count(8)
clock-watch: last(0.002052) total(0.005430) count(2)
timings: last(0.000111) total(0.001076) count(8)
clock-watch: last(0.002192) total(0.006436) count(2)
0
$.error a stderr print will come before the diff $nl
......
.global nl (
)
.try_catch_recursive .file_open_failure {
.source /non-existent/file/to/test/failure}
.function_all_flags .raw_command -- cmd {.echo $cmd; .echo $nl}
.function_all_flags .raw_command -- cmd {.echo $cmd; .echo (
)}
.global last_command_return -10
.global A \
......
......@@ -846,9 +846,11 @@ se {.fork se {/bin/kill ${.getpid}
.unset
.unset x {excess argfunc}
.unset x y
.unset ?
.var_exists
.var_exists x {excess argfunc}
.global 100 nihilism
.local 0 nihilism
.global .var_exists (must be requested to be checked)
e $.var_exists
.unset #
......@@ -870,6 +872,7 @@ e $.var_exists
.var_exists x y
e $x
.global x nihilism
.global x ubernihilism
.function_all_flags a {if_only .var_exists x {e in a x \( $x \) $nl}
if_only .var_exists y {e in a y \( $y \) $nl}
.local x (first level not global)
......@@ -888,8 +891,8 @@ e $x
if_only .var_exists y {e in c y \( $y \) $nl}
# can unset a local, but only one at a time
.unset x
.global y (attempting to create global masked by local)
e $? $nl
.try_catch_recursive .global_would_be_masked {
.global y (attempting to create global masked by local)}
.set x (third level overwrites first)
.local x (third level masks first)
.set y (level three overwrites one)
......@@ -907,6 +910,7 @@ e $x
# .store_output
.store_output x
.store_output {e some text}
.store_output # {e some text}
.store_output x {e some text}
.global x ()
.store_output x {e some text; .return 1}
......@@ -1794,7 +1798,8 @@ echo-comments excessive-commentary #
.list_environment {excess argfunc}
for ${.list_environment}$ {
.scope $1$ (var val) {
.global $var $val}}
.if .test_in $var ? FIGNORE SHELL {echo $var : $$var to $val}
.else {.global $var $val}}}
e $TESTABILITY
e $SHELL
.unset TESTABILITY
......
......@@ -117,6 +117,10 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .function_not_found -- cmd [stack ...] {
echo $cmd : command not found \( $cmd $stack$ \)}
.function_all_flags .global_would_be_masked name stack ... {
.echo requested global $name already exists as a local
echo . It would be masked by the local and inaccessible from here
echo call stack $stack$}
.function_all_flags .help [args ...] {
.nop $args$
.echo this is the default configuration for rwsh \(or something copied from it
......@@ -236,6 +240,9 @@ call stack .source .try_catch_recursive(body)
echo call stack $stack$}
.function_all_flags .unused_variable -- var [stack ...] {
echo $var was unused with call stack $stack$}
.function_all_flags .variable_already_exists name stack ... {
echo variable $name already exists
echo call stack $stack$}
.function_all_flags .version_incompatible version stack ... {
echo this shell is not compatible with requested version $version
echo call stack: $stack$}
......@@ -309,9 +316,12 @@ polish / .var_divide
.else_if .test_string_equal $2 -c {
.for ${.list_environment}$ {
.scope $1$ (-- var val) {
.global $var $val
.nop $$var}}
.if .var_exists $var {.nop $val}
.else {
.global $var $val
.nop $$var}}}
.source /etc/rwshrc-basic
.nop $FIGNORE
.function_all_flags .if_before_else stack ... {.nop $stack}
.function_all_flags .shutdown -- args ... {.nop $args; .return 0}
.collect_errors_except .nop {
......
......@@ -86,28 +86,29 @@ const std::string& Variable_map::get(const std::string& key) {
else if (parent) return parent->get(key);
else throw Exception(Argm::Undeclared_variable, key);}
int Variable_map::global(const std::string& key, const std::string& value) {
void Variable_map::global(const std::string& key, const std::string& value) {
if (parent)
if (find(key) != end()) return 3;
if (find(key) != end()) throw Exception(Argm::Global_would_be_masked, key);
else if (usage_checked)
throw Exception(Argm::Internal_error,
"variable map added to after usage checked");
else return parent->global(key, value);
else return local(key, value);}
else parent->global(key, value);
else local(key, value);}
// params have their usage checked by the prototype (to properly handle -* etc)
int Variable_map::param(const std::string& key, const std::string& value) {
void Variable_map::param(const std::string& key, const std::string& value) {
std::pair<std::string, std::string> entry(key, value);
std::pair<iterator, bool> ret = insert(entry);
return !ret.second;} // yeah, you need to do this
if (!ret.second && value != ret.first->second)
throw Exception(Argm::Variable_already_exists, key);}
// locals have their usage checked directly
int Variable_map::local(const std::string& key, const std::string& value) {
void Variable_map::local(const std::string& key, const std::string& value) {
if (usage_checked)
throw Exception(Argm::Internal_error,
"variable map added to after usage checked");
local_vars.insert(key);
return param(key, value);} // yeah, you need to do this
param(key, value);}
void Variable_map::set(const std::string& key, const std::string& value) {
auto i = find(key);
......@@ -120,12 +121,13 @@ void Variable_map::set(const std::string& key, const std::string& value) {
else if (parent) parent->set(key, value);
else throw Exception(Argm::Undeclared_variable, key);}
int Variable_map::unset(const std::string& key) {
if (key == "FIGNORE" || key == "?") return 2;
void Variable_map::unset(const std::string& key) {
if (key == "FIGNORE" || key == "?")
throw Exception(Argm::Illegal_variable_name, key);
auto i = find(key);
if (i != end()) {erase(i); return 0;}
else if (parent) return parent->unset(key);
else return 1;}
if (i != end()) erase(i);
else if (parent) parent->unset(key);
else throw Exception(Argm::Undeclared_variable, key);}
const Variable_map* Variable_map::parent_with(const std::string& key) const {
auto i = find(key);
......
......@@ -43,13 +43,13 @@ public:
bool exists(const std::string& key, bool check);
void export_env(std::vector<char*>& env);
const std::string& get(const std::string& key);
int global(const std::string& key, const std::string& value);
int param(const std::string& key, const std::string& value);
int local(const std::string& key, const std::string& value);
void global(const std::string& key, const std::string& value);
void param(const std::string& key, const std::string& value);
void local(const std::string& key, const std::string& value);
const std::set<std::string>& locals(void) const {return local_vars;};
void set(const std::string& key, const std::string& value);
bool simple_exists(const std::string& key) const {return find(key) != end();}
int unset(const std::string& key);
void unset(const std::string& key);
bool used_vars_contains(const std::string& key) const {
return used_vars.find(key) != used_vars.end();};
bool checked_vars_contains(const std::string& key) const {
......
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