aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-08-15 13:37:17 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2015-08-15 13:37:17 -0700
commit93d57bd73a885df46f45a1e771a8f9568144fd6a (patch)
tree8a08e090c232692f7cdc7b31d87f976f7efad07e
parent60798798ef37fc0dcee3edece62ca11fb2d1ced8 (diff)
Factor function environment preparation into its own function
-rw-r--r--src/builtin.cpp2
-rw-r--r--src/env.cpp24
-rw-r--r--src/env.h3
-rw-r--r--src/exec.cpp18
-rw-r--r--src/function.cpp29
-rw-r--r--src/function.h5
-rw-r--r--src/parse_util.cpp37
-rw-r--r--src/parse_util.h6
8 files changed, 68 insertions, 56 deletions
diff --git a/src/builtin.cpp b/src/builtin.cpp
index 039dc7bc..bc1b18de 100644
--- a/src/builtin.cpp
+++ b/src/builtin.cpp
@@ -3446,7 +3446,7 @@ static int builtin_source(parser_t &parser, wchar_t ** argv)
parser.push_block(new source_block_t(fn_intern));
reader_push_current_filename(fn_intern);
- parse_util_set_argv((argc>2)?(argv+2):(argv+1), wcstring_list_t());
+ env_set_argv((argc>2)?(argv+2):(argv+1));
res = reader_read(fd, real_io ? *real_io : io_chain_t());
diff --git a/src/env.cpp b/src/env.cpp
index 649e0f2a..9c6e21fb 100644
--- a/src/env.cpp
+++ b/src/env.cpp
@@ -1354,6 +1354,30 @@ const char * const *env_export_arr(bool recalc)
return export_array.get();
}
+void env_set_argv(const wchar_t * const * argv)
+{
+ if (*argv)
+ {
+ const wchar_t * const *arg;
+ wcstring sb;
+
+ for (arg=argv; *arg; arg++)
+ {
+ if (arg != argv)
+ {
+ sb.append(ARRAY_SEP_STR);
+ }
+ sb.append(*arg);
+ }
+
+ env_set(L"argv", sb.c_str(), ENV_LOCAL);
+ }
+ else
+ {
+ env_set(L"argv", 0, ENV_LOCAL);
+ }
+}
+
env_vars_snapshot_t::env_vars_snapshot_t(const wchar_t * const *keys)
{
ASSERT_IS_MAIN_THREAD();
diff --git a/src/env.h b/src/env.h
index 411b51ec..d7b4c23d 100644
--- a/src/env.h
+++ b/src/env.h
@@ -209,6 +209,9 @@ void env_universal_barrier();
/** Returns an array containing all exported variables in a format suitable for execv. */
const char * const * env_export_arr(bool recalc);
+/** Sets up argv as the given null terminated array of strings */
+void env_set_argv(const wchar_t * const * argv);
+
/**
Returns all variable names.
*/
diff --git a/src/exec.cpp b/src/exec.cpp
index d6df94e6..39385b06 100644
--- a/src/exec.cpp
+++ b/src/exec.cpp
@@ -774,12 +774,12 @@ void exec_job(parser_t &parser, job_t *j)
*/
signal_unblock();
+ const wcstring func_name = p->argv0();
wcstring def;
- bool function_exists = function_get_definition(p->argv0(), &def);
+ bool function_exists = function_get_definition(func_name, &def);
- wcstring_list_t named_arguments = function_get_named_arguments(p->argv0());
- bool shadows = function_get_shadows(p->argv0());
- std::map<wcstring,env_var_t> inherit_vars = function_get_inherit_vars(p->argv0());
+ bool shadows = function_get_shadows(func_name);
+ const std::map<wcstring,env_var_t> inherit_vars = function_get_inherit_vars(func_name);
signal_block();
@@ -788,7 +788,7 @@ void exec_job(parser_t &parser, job_t *j)
debug(0, _(L"Unknown function '%ls'"), p->argv0());
break;
}
- function_block_t *newv = new function_block_t(p, p->argv0(), shadows);
+ function_block_t *newv = new function_block_t(p, func_name, shadows);
parser.push_block(newv);
/*
@@ -797,14 +797,10 @@ void exec_job(parser_t &parser, job_t *j)
signals.
*/
signal_unblock();
- parse_util_set_argv(p->get_argv()+1, named_arguments);
- for (std::map<wcstring,env_var_t>::const_iterator it = inherit_vars.begin(), end = inherit_vars.end(); it != end; ++it)
- {
- env_set(it->first, it->second.missing() ? NULL : it->second.c_str(), ENV_LOCAL | ENV_USER);
- }
+ function_prepare_environment(func_name, p->get_argv()+1, inherit_vars);
signal_block();
- parser.forbid_function(p->argv0());
+ parser.forbid_function(func_name);
if (p->next)
{
diff --git a/src/function.cpp b/src/function.cpp
index 2a8c20be..a06e2993 100644
--- a/src/function.cpp
+++ b/src/function.cpp
@@ -387,3 +387,32 @@ int function_get_definition_offset(const wcstring &name)
const function_info_t *func = function_get(name);
return func ? func->definition_offset : -1;
}
+
+void function_prepare_environment(const wcstring &name, const wchar_t * const * argv, const std::map<wcstring, env_var_t> &inherited_vars)
+{
+ /* Three components of the environment:
+ 1. argv
+ 2. named arguments
+ 3. inherited variables
+ */
+ env_set_argv(argv);
+
+ const wcstring_list_t named_arguments = function_get_named_arguments(name);
+ if (! named_arguments.empty())
+ {
+ const wchar_t * const *arg;
+ size_t i;
+ for (i=0, arg=argv; i < named_arguments.size(); i++)
+ {
+ env_set(named_arguments.at(i).c_str(), *arg, ENV_LOCAL | ENV_USER);
+
+ if (*arg)
+ arg++;
+ }
+ }
+
+ for (std::map<wcstring,env_var_t>::const_iterator it = inherited_vars.begin(), end = inherited_vars.end(); it != end; ++it)
+ {
+ env_set(it->first, it->second.missing() ? NULL : it->second.c_str(), ENV_LOCAL | ENV_USER);
+ }
+}
diff --git a/src/function.h b/src/function.h
index cd3f6f5a..1dd9d613 100644
--- a/src/function.h
+++ b/src/function.h
@@ -179,10 +179,13 @@ std::map<wcstring,env_var_t> function_get_inherit_vars(const wcstring &name);
*/
bool function_copy(const wcstring &name, const wcstring &new_name);
-
/**
Returns whether this function shadows variables of the underlying function
*/
int function_get_shadows(const wcstring &name);
+/** Prepares the environment for executing a function.
+*/
+void function_prepare_environment(const wcstring &name, const wchar_t * const * argv, const std::map<wcstring, env_var_t> &inherited_vars);
+
#endif
diff --git a/src/parse_util.cpp b/src/parse_util.cpp
index b5d549ba..594416bf 100644
--- a/src/parse_util.cpp
+++ b/src/parse_util.cpp
@@ -561,43 +561,6 @@ void parse_util_token_extent(const wchar_t *buff,
}
-void parse_util_set_argv(const wchar_t * const *argv, const wcstring_list_t &named_arguments)
-{
- if (*argv)
- {
- const wchar_t * const *arg;
- wcstring sb;
-
- for (arg=argv; *arg; arg++)
- {
- if (arg != argv)
- {
- sb.append(ARRAY_SEP_STR);
- }
- sb.append(*arg);
- }
-
- env_set(L"argv", sb.c_str(), ENV_LOCAL);
- }
- else
- {
- env_set(L"argv", 0, ENV_LOCAL);
- }
-
- if (! named_arguments.empty())
- {
- const wchar_t * const *arg;
- size_t i;
- for (i=0, arg=argv; i < named_arguments.size(); i++)
- {
- env_set(named_arguments.at(i).c_str(), *arg, ENV_LOCAL | ENV_USER);
-
- if (*arg)
- arg++;
- }
- }
-}
-
wchar_t *parse_util_unescape_wildcards(const wchar_t *str)
{
wchar_t *in, *out;
diff --git a/src/parse_util.h b/src/parse_util.h
index 0d02ab17..7c65fc71 100644
--- a/src/parse_util.h
+++ b/src/parse_util.h
@@ -138,12 +138,6 @@ size_t parse_util_get_offset_from_line(const wcstring &str, int line);
size_t parse_util_get_offset(const wcstring &str, int line, long line_offset);
/**
- Set the argv environment variable to the specified null-terminated
- array of strings.
-*/
-void parse_util_set_argv(const wchar_t * const *argv, const wcstring_list_t &named_arguments);
-
-/**
Make a duplicate of the specified string, unescape wildcard
characters but not performing any other character transformation.
*/