diff options
author | 2014-10-02 15:59:24 -0700 | |
---|---|---|
committer | 2014-10-02 18:41:39 -0700 | |
commit | cfc06203e7ad7707acadd160292d47b25d6daba6 (patch) | |
tree | 387a4aa8149477309f9c545dfb9c6ccf1ea24ac1 /builtin.cpp | |
parent | 6d7a7b00d77098c93aa2b6c0deba4c18029b5a32 (diff) |
Add new `functions` flag -V/--inherit-variable
--inherit-variable takes a variable name and snapshots its current
value. When the function is executed, it will have a local variable with
this value already defined. Printing the function source will include
synthesized `set -l` lines for the values.
This is primarily useful for functions that are created on the fly, such
as in `psub`.
Diffstat (limited to 'builtin.cpp')
-rw-r--r-- | builtin.cpp | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/builtin.cpp b/builtin.cpp index 97a5c932..a01c2519 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -1391,6 +1391,26 @@ static void functions_def(const wcstring &name, wcstring &out) out.append(escape_string(name, true)); } + /* Output any inherited variables as `set -l` lines */ + std::map<wcstring,env_var_t> inherit_vars = function_get_inherit_vars(name); + for (std::map<wcstring,env_var_t>::const_iterator it = inherit_vars.begin(), end = inherit_vars.end(); it != end; ++it) + { + wcstring_list_t lst; + if (!it->second.missing()) + { + tokenize_variable_array(it->second, lst); + } + + /* This forced tab is crummy, but we don't know what indentation style the function uses */ + append_format(out, L"\n\tset -l %ls", it->first.c_str()); + for (wcstring_list_t::const_iterator arg_it = lst.begin(), arg_end = lst.end(); arg_it != arg_end; ++arg_it) + { + wcstring earg = escape_string(*arg_it, ESCAPE_ALL); + out.push_back(L' '); + out.append(earg); + } + } + /* This forced tab is sort of crummy - not all functions start with a tab */ append_format(out, L"\n\t%ls", def.c_str()); @@ -1976,6 +1996,7 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr wchar_t *desc=0; std::vector<event_t> events; std::auto_ptr<wcstring_list_t> named_arguments(NULL); + wcstring_list_t inherit_vars; wchar_t *name = 0; bool shadows = true; @@ -1996,6 +2017,7 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr { L"help", no_argument, 0, 'h' }, { L"argument-names", no_argument, 0, 'a' }, { L"no-scope-shadowing", no_argument, 0, 'S' }, + { L"inherit-variable", required_argument, 0, 'V' }, { 0, 0, 0, 0 } }; @@ -2005,7 +2027,7 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr int opt = wgetopt_long(argc, argv, - L"d:s:j:p:v:e:haS", + L"d:s:j:p:v:e:haSV:", long_options, &opt_index); if (opt == -1) @@ -2154,11 +2176,24 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr case 'S': shadows = 0; break; - + case 'w': wrap_targets.push_back(woptarg); break; + case 'V': + { + if (wcsvarname(woptarg)) + { + append_format(*out_err, _(L"%ls: Invalid variable name '%ls'\n"), argv[0], woptarg); + res = STATUS_BUILTIN_ERROR; + break; + } + + inherit_vars.push_back(woptarg); + break; + } + case 'h': builtin_print_help(parser, argv[0], stdout_buffer); return STATUS_BUILTIN_OK; @@ -2255,6 +2290,7 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr d.shadows = shadows; if (named_arguments.get()) d.named_arguments.swap(*named_arguments); + d.inherit_vars.swap(inherit_vars); for (size_t i=0; i<d.events.size(); i++) { @@ -2265,7 +2301,7 @@ int define_function(parser_t &parser, const wcstring_list_t &c_args, const wcstr d.definition = contents.c_str(); function_add(d, parser, definition_line_offset); - + // Handle wrap targets for (size_t w=0; w < wrap_targets.size(); w++) { |