mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-27 05:13:10 +00:00
Instantize env_get
This commit is contained in:
parent
6f52e6bb1c
commit
3b1709180f
14 changed files with 98 additions and 85 deletions
|
@ -66,8 +66,12 @@ int autoload_t::load(const wcstring &cmd, bool reload) {
|
|||
CHECK_BLOCK(0);
|
||||
ASSERT_IS_MAIN_THREAD();
|
||||
|
||||
// TODO: Justify this principal_parser.
|
||||
auto &parser = parser_t::principal_parser();
|
||||
auto &vars = parser.vars();
|
||||
|
||||
if (!this->paths) {
|
||||
auto path_var = env_get(env_var_name);
|
||||
auto path_var = vars.get(env_var_name);
|
||||
if (path_var.missing_or_empty()) return 0;
|
||||
this->paths = path_var->as_list();
|
||||
}
|
||||
|
@ -257,6 +261,7 @@ bool autoload_t::locate_file_and_maybe_load_it(const wcstring &cmd, bool really_
|
|||
// If we have a script, either built-in or a file source, then run it.
|
||||
if (really_load && !script_source.empty()) {
|
||||
// Do nothing on failure.
|
||||
// TODO: rationalize this use of principal_parser, or inject the loading from outside.
|
||||
exec_subshell(script_source, parser_t::principal_parser(),
|
||||
false /* do not apply exit status */);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ int builtin_cd(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
if (argv[optind]) {
|
||||
dir_in = argv[optind];
|
||||
} else {
|
||||
auto maybe_dir_in = env_get(L"HOME");
|
||||
auto maybe_dir_in = parser.vars().get(L"HOME");
|
||||
if (maybe_dir_in.missing_or_empty()) {
|
||||
streams.err.append_format(_(L"%ls: Could not find home directory\n"), cmd);
|
||||
return STATUS_CMD_ERROR;
|
||||
|
|
|
@ -96,7 +96,7 @@ int builtin_command(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
for (int idx = optind; argv[idx]; ++idx) {
|
||||
const wchar_t *command_name = argv[idx];
|
||||
if (opts.all_paths) {
|
||||
wcstring_list_t paths = path_get_paths(command_name);
|
||||
wcstring_list_t paths = path_get_paths(command_name, parser.vars());
|
||||
for (auto path : paths) {
|
||||
if (!opts.quiet) streams.out.append_format(L"%ls\n", path.c_str());
|
||||
++found;
|
||||
|
|
|
@ -204,7 +204,8 @@ static int read_interactive(wcstring &buff, int nchars, bool shell, bool silent,
|
|||
int exit_res = STATUS_CMD_OK;
|
||||
const wchar_t *line;
|
||||
|
||||
auto &vars = env_stack_t::principal();
|
||||
// TODO: rationalize this.
|
||||
const auto &vars = env_stack_t::principal();
|
||||
wcstring read_history_ID = history_session_id(vars);
|
||||
if (!read_history_ID.empty()) read_history_ID += L"_read";
|
||||
reader_push(read_history_ID);
|
||||
|
@ -490,7 +491,7 @@ int builtin_read(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
}
|
||||
|
||||
if (!opts.have_delimiter) {
|
||||
auto ifs = env_get(L"IFS");
|
||||
auto ifs = parser.vars().get(L"IFS");
|
||||
if (!ifs.missing_or_empty()) opts.delimiter = ifs->as_string();
|
||||
}
|
||||
|
||||
|
|
|
@ -234,9 +234,9 @@ static int validate_cmd_opts(const wchar_t *cmd, set_cmd_opts_t &opts, //!OCLIN
|
|||
// Check if we are setting a uvar and a global of the same name exists. See
|
||||
// https://github.com/fish-shell/fish-shell/issues/806
|
||||
static int check_global_scope_exists(const wchar_t *cmd, set_cmd_opts_t &opts, const wchar_t *dest,
|
||||
io_streams_t &streams) {
|
||||
io_streams_t &streams, const environment_t &vars) {
|
||||
if (opts.universal) {
|
||||
auto global_dest = env_get(dest, ENV_GLOBAL);
|
||||
auto global_dest = vars.get(dest, ENV_GLOBAL);
|
||||
if (global_dest && shell_is_interactive()) {
|
||||
streams.err.append_format(BUILTIN_SET_UVAR_ERR, cmd, dest);
|
||||
}
|
||||
|
@ -249,7 +249,8 @@ static int check_global_scope_exists(const wchar_t *cmd, set_cmd_opts_t &opts, c
|
|||
// contain a colon, then complain. Return true if any path element was valid, false if not.
|
||||
static bool validate_path_warning_on_colons(const wchar_t *cmd,
|
||||
const wchar_t *key, //!OCLINT(npath complexity)
|
||||
const wcstring_list_t &list, io_streams_t &streams) {
|
||||
const wcstring_list_t &list, io_streams_t &streams,
|
||||
const environment_t &vars) {
|
||||
// Always allow setting an empty value.
|
||||
if (list.empty()) return true;
|
||||
|
||||
|
@ -265,7 +266,7 @@ static bool validate_path_warning_on_colons(const wchar_t *cmd,
|
|||
// not the (missing) local value. Also don't bother to complain about relative paths, which
|
||||
// don't start with /.
|
||||
wcstring_list_t existing_values;
|
||||
const auto existing_variable = env_get(key, ENV_DEFAULT);
|
||||
const auto existing_variable = vars.get(key, ENV_DEFAULT);
|
||||
if (!existing_variable.missing_or_empty()) existing_variable->to_list(existing_values);
|
||||
|
||||
for (const wcstring &dir : list) {
|
||||
|
@ -346,7 +347,7 @@ static void handle_env_return(int retval, const wchar_t *cmd, const wchar_t *key
|
|||
static int env_set_reporting_errors(const wchar_t *cmd, const wchar_t *key, int scope,
|
||||
const wcstring_list_t &list, io_streams_t &streams,
|
||||
env_stack_t &vars) {
|
||||
if (is_path_variable(key) && !validate_path_warning_on_colons(cmd, key, list, streams)) {
|
||||
if (is_path_variable(key) && !validate_path_warning_on_colons(cmd, key, list, streams, vars)) {
|
||||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
|
||||
|
@ -365,13 +366,14 @@ static int env_set_reporting_errors(const wchar_t *cmd, const wchar_t *key, int
|
|||
/// Returns:
|
||||
/// The total number of indexes parsed, or -1 on error. If any indexes were found the `src` string
|
||||
/// is modified to omit the index expression leaving just the var name.
|
||||
static int parse_index(std::vector<long> &indexes, wchar_t *src, int scope, io_streams_t &streams) {
|
||||
static int parse_index(std::vector<long> &indexes, wchar_t *src, int scope, io_streams_t &streams,
|
||||
const environment_t &vars) {
|
||||
wchar_t *p = wcschr(src, L'[');
|
||||
if (!p) return 0; // no slices so nothing for us to do
|
||||
*p = L'\0'; // split the var name from the indexes/slices
|
||||
p++;
|
||||
|
||||
auto var_str = env_get(src, scope);
|
||||
auto var_str = vars.get(src, scope);
|
||||
wcstring_list_t var;
|
||||
if (var_str) var_str->to_list(var);
|
||||
|
||||
|
@ -484,7 +486,7 @@ static int builtin_set_list(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
streams.out.append(e_key);
|
||||
|
||||
if (!names_only) {
|
||||
auto var = env_get(key, compute_scope(opts));
|
||||
auto var = parser.vars().get(key, compute_scope(opts));
|
||||
if (!var.missing_or_empty()) {
|
||||
bool shorten = false;
|
||||
wcstring val = expand_escape_variable(*var);
|
||||
|
@ -517,7 +519,7 @@ static int builtin_set_query(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
assert(dest);
|
||||
|
||||
std::vector<long> indexes;
|
||||
int idx_count = parse_index(indexes, dest, scope, streams);
|
||||
int idx_count = parse_index(indexes, dest, scope, streams, parser.vars());
|
||||
if (idx_count == -1) {
|
||||
free(dest);
|
||||
builtin_print_help(parser, streams, cmd, streams.err);
|
||||
|
@ -526,14 +528,14 @@ static int builtin_set_query(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
|
||||
if (idx_count) {
|
||||
wcstring_list_t result;
|
||||
auto dest_str = env_get(dest, scope);
|
||||
auto dest_str = parser.vars().get(dest, scope);
|
||||
if (dest_str) dest_str->to_list(result);
|
||||
|
||||
for (auto idx : indexes) {
|
||||
if (idx < 1 || (size_t)idx > result.size()) retval++;
|
||||
}
|
||||
} else {
|
||||
if (! env_get(arg, scope)) retval++;
|
||||
if (!parser.vars().get(arg, scope)) retval++;
|
||||
}
|
||||
|
||||
free(dest);
|
||||
|
@ -542,7 +544,8 @@ static int builtin_set_query(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
return retval;
|
||||
}
|
||||
|
||||
static void show_scope(const wchar_t *var_name, int scope, io_streams_t &streams) {
|
||||
static void show_scope(const wchar_t *var_name, int scope, io_streams_t &streams,
|
||||
const environment_t &vars) {
|
||||
const wchar_t *scope_name;
|
||||
switch (scope) {
|
||||
case ENV_LOCAL: {
|
||||
|
@ -563,7 +566,7 @@ static void show_scope(const wchar_t *var_name, int scope, io_streams_t &streams
|
|||
}
|
||||
}
|
||||
|
||||
const auto var = env_get(var_name, scope);
|
||||
const auto var = vars.get(var_name, scope);
|
||||
if (!var) {
|
||||
streams.out.append_format(_(L"$%ls: not set in %ls scope\n"), var_name, scope_name);
|
||||
return;
|
||||
|
@ -590,14 +593,14 @@ static void show_scope(const wchar_t *var_name, int scope, io_streams_t &streams
|
|||
static int builtin_set_show(const wchar_t *cmd, set_cmd_opts_t &opts, int argc, wchar_t **argv,
|
||||
parser_t &parser, io_streams_t &streams) {
|
||||
UNUSED(opts);
|
||||
|
||||
auto &vars = parser.vars();
|
||||
if (argc == 0) { // show all vars
|
||||
wcstring_list_t names = parser.vars().get_names(ENV_USER);
|
||||
sort(names.begin(), names.end());
|
||||
for (auto it : names) {
|
||||
show_scope(it.c_str(), ENV_LOCAL, streams);
|
||||
show_scope(it.c_str(), ENV_GLOBAL, streams);
|
||||
show_scope(it.c_str(), ENV_UNIVERSAL, streams);
|
||||
show_scope(it.c_str(), ENV_LOCAL, streams, vars);
|
||||
show_scope(it.c_str(), ENV_GLOBAL, streams, vars);
|
||||
show_scope(it.c_str(), ENV_UNIVERSAL, streams, vars);
|
||||
streams.out.push_back(L'\n');
|
||||
}
|
||||
} else {
|
||||
|
@ -616,9 +619,9 @@ static int builtin_set_show(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
return STATUS_CMD_ERROR;
|
||||
}
|
||||
|
||||
show_scope(arg, ENV_LOCAL, streams);
|
||||
show_scope(arg, ENV_GLOBAL, streams);
|
||||
show_scope(arg, ENV_UNIVERSAL, streams);
|
||||
show_scope(arg, ENV_LOCAL, streams, vars);
|
||||
show_scope(arg, ENV_GLOBAL, streams, vars);
|
||||
show_scope(arg, ENV_UNIVERSAL, streams, vars);
|
||||
streams.out.push_back(L'\n');
|
||||
}
|
||||
}
|
||||
|
@ -639,7 +642,7 @@ static int builtin_set_erase(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
wchar_t *dest = argv[0];
|
||||
|
||||
std::vector<long> indexes;
|
||||
int idx_count = parse_index(indexes, dest, scope, streams);
|
||||
int idx_count = parse_index(indexes, dest, scope, streams, parser.vars());
|
||||
if (idx_count == -1) {
|
||||
builtin_print_help(parser, streams, cmd, streams.err);
|
||||
return STATUS_CMD_ERROR;
|
||||
|
@ -660,7 +663,7 @@ static int builtin_set_erase(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
handle_env_return(retval, cmd, dest, streams);
|
||||
}
|
||||
} else { // remove just the specified indexes of the var
|
||||
const auto dest_var = env_get(dest, scope);
|
||||
const auto dest_var = parser.vars().get(dest, scope);
|
||||
if (!dest_var) return STATUS_CMD_ERROR;
|
||||
wcstring_list_t result;
|
||||
dest_var->to_list(result);
|
||||
|
@ -669,7 +672,7 @@ static int builtin_set_erase(const wchar_t *cmd, set_cmd_opts_t &opts, int argc,
|
|||
}
|
||||
|
||||
if (retval != STATUS_CMD_OK) return retval;
|
||||
return check_global_scope_exists(cmd, opts, dest, streams);
|
||||
return check_global_scope_exists(cmd, opts, dest, streams, parser.vars());
|
||||
}
|
||||
|
||||
/// This handles the common case of setting the entire var to a set of values.
|
||||
|
@ -684,8 +687,7 @@ static int set_var_array(const wchar_t *cmd, set_cmd_opts_t &opts, const wchar_t
|
|||
if (opts.prepend) {
|
||||
for (int i = 0; i < argc; i++) new_values.push_back(argv[i]);
|
||||
}
|
||||
|
||||
auto var_str = env_get(varname, ENV_DEFAULT);
|
||||
auto var_str = parser.vars().get(varname, ENV_DEFAULT);
|
||||
wcstring_list_t var_array;
|
||||
if (var_str) var_str->to_list(var_array);
|
||||
new_values.insert(new_values.end(), var_array.begin(), var_array.end());
|
||||
|
@ -719,7 +721,7 @@ static int set_var_slices(const wchar_t *cmd, set_cmd_opts_t &opts, const wchar_
|
|||
}
|
||||
|
||||
int scope = compute_scope(opts); // calculate the variable scope based on the provided options
|
||||
const auto var_str = env_get(varname, scope);
|
||||
const auto var_str = parser.vars().get(varname, scope);
|
||||
if (var_str) var_str->to_list(new_values);
|
||||
|
||||
// Slice indexes have been calculated, do the actual work.
|
||||
|
@ -750,7 +752,7 @@ static int builtin_set_set(const wchar_t *cmd, set_cmd_opts_t &opts, int argc, w
|
|||
argc--;
|
||||
|
||||
std::vector<long> indexes;
|
||||
int idx_count = parse_index(indexes, varname, scope, streams);
|
||||
int idx_count = parse_index(indexes, varname, scope, streams, parser.vars());
|
||||
if (idx_count == -1) {
|
||||
builtin_print_help(parser, streams, cmd, streams.err);
|
||||
return STATUS_INVALID_ARGS;
|
||||
|
@ -776,7 +778,7 @@ static int builtin_set_set(const wchar_t *cmd, set_cmd_opts_t &opts, int argc, w
|
|||
|
||||
retval = env_set_reporting_errors(cmd, varname, scope, new_values, streams, parser.vars());
|
||||
if (retval != STATUS_CMD_OK) return retval;
|
||||
return check_global_scope_exists(cmd, opts, varname, streams);
|
||||
return check_global_scope_exists(cmd, opts, varname, streams, parser.vars());
|
||||
}
|
||||
|
||||
/// The set builtin creates, updates, and erases (removes, deletes) variables.
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "env.h"
|
||||
#include "io.h"
|
||||
#include "output.h"
|
||||
#include "parser.h"
|
||||
#include "wgetopt.h"
|
||||
#include "wutil.h" // IWYU pragma: keep
|
||||
|
||||
|
@ -75,10 +76,10 @@ int builtin_set_color(parser_t &parser, io_streams_t &streams, wchar_t **argv) {
|
|||
// Hack in missing italics and dim capabilities omitted from MacOS xterm-256color terminfo
|
||||
// Helps Terminal.app/iTerm
|
||||
#if __APPLE__
|
||||
const auto term_prog = env_get(L"TERM_PROGRAM");
|
||||
const auto term_prog = parser.vars().get(L"TERM_PROGRAM");
|
||||
if (!term_prog.missing_or_empty() && (term_prog->as_string() == L"Apple_Terminal"
|
||||
|| term_prog->as_string() == L"iTerm.app")) {
|
||||
const auto term = env_get(L"TERM");
|
||||
const auto term = parser.vars().get(L"TERM");
|
||||
if (!term.missing_or_empty() && (term->as_string() == L"xterm-256color")) {
|
||||
enter_italics_mode = sitm_esc;
|
||||
exit_italics_mode = ritm_esc;
|
||||
|
|
|
@ -1721,7 +1721,7 @@ void common_handle_winch(int signal) {
|
|||
|
||||
/// Validate the new terminal size. Fallback to the env vars if necessary. Ensure the values are
|
||||
/// sane and if not fallback to a default of 80x24.
|
||||
static void validate_new_termsize(struct winsize *new_termsize) {
|
||||
static void validate_new_termsize(struct winsize *new_termsize, const environment_t &vars) {
|
||||
if (new_termsize->ws_col == 0 || new_termsize->ws_row == 0) {
|
||||
#ifdef HAVE_WINSIZE
|
||||
if (shell_is_interactive()) {
|
||||
|
@ -1731,8 +1731,8 @@ static void validate_new_termsize(struct winsize *new_termsize) {
|
|||
}
|
||||
#endif
|
||||
// Fallback to the environment vars.
|
||||
maybe_t<env_var_t> col_var = env_get(L"COLUMNS");
|
||||
maybe_t<env_var_t> row_var = env_get(L"LINES");
|
||||
maybe_t<env_var_t> col_var = vars.get(L"COLUMNS");
|
||||
maybe_t<env_var_t> row_var = vars.get(L"LINES");
|
||||
if (!col_var.missing_or_empty() && !row_var.missing_or_empty()) {
|
||||
// Both vars have to have valid values.
|
||||
int col = fish_wcstoi(col_var->as_string().c_str());
|
||||
|
@ -1757,16 +1757,15 @@ static void validate_new_termsize(struct winsize *new_termsize) {
|
|||
}
|
||||
|
||||
/// Export the new terminal size as env vars and to the kernel if possible.
|
||||
static void export_new_termsize(struct winsize *new_termsize) {
|
||||
auto &vars = env_stack_t::globals();
|
||||
static void export_new_termsize(struct winsize *new_termsize, env_stack_t &vars) {
|
||||
wchar_t buf[64];
|
||||
|
||||
auto cols = env_get(L"COLUMNS", ENV_EXPORT);
|
||||
auto cols = vars.get(L"COLUMNS", ENV_EXPORT);
|
||||
swprintf(buf, 64, L"%d", (int)new_termsize->ws_col);
|
||||
vars.set_one(L"COLUMNS", ENV_GLOBAL | (cols.missing_or_empty() ? ENV_DEFAULT : ENV_EXPORT),
|
||||
buf);
|
||||
|
||||
auto lines = env_get(L"LINES", ENV_EXPORT);
|
||||
auto lines = vars.get(L"LINES", ENV_EXPORT);
|
||||
swprintf(buf, 64, L"%d", (int)new_termsize->ws_row);
|
||||
vars.set_one(L"LINES", ENV_GLOBAL | (lines.missing_or_empty() ? ENV_DEFAULT : ENV_EXPORT), buf);
|
||||
|
||||
|
@ -1793,9 +1792,9 @@ struct winsize get_current_winsize() {
|
|||
return termsize;
|
||||
}
|
||||
#endif
|
||||
|
||||
validate_new_termsize(&new_termsize);
|
||||
export_new_termsize(&new_termsize);
|
||||
auto &vars = env_stack_t::globals();
|
||||
validate_new_termsize(&new_termsize, vars);
|
||||
export_new_termsize(&new_termsize, vars);
|
||||
termsize.ws_col = new_termsize.ws_col;
|
||||
termsize.ws_row = new_termsize.ws_row;
|
||||
termsize_valid = true;
|
||||
|
|
|
@ -410,7 +410,7 @@ bool completer_t::condition_test(const wcstring &condition) {
|
|||
condition_cache_t::iterator cached_entry = condition_cache.find(condition);
|
||||
if (cached_entry == condition_cache.end()) {
|
||||
// Compute new value and reinsert it.
|
||||
// TODO: rationalize this parser_t usage.
|
||||
// TODO: rationalize this principal_parser.
|
||||
test_res = (0 == exec_subshell(condition, parser_t::principal_parser(),
|
||||
false /* don't apply exit status */));
|
||||
condition_cache[condition] = test_res;
|
||||
|
@ -593,7 +593,7 @@ void completer_t::complete_cmd_desc(const wcstring &str) {
|
|||
// search if we know the location of the whatis database. This can take some time on slower
|
||||
// systems with a large set of manuals, but it should be ok since apropos is only called once.
|
||||
wcstring_list_t list;
|
||||
// TODO: rationalize this use of principal_parser.
|
||||
// TODO: justify this use of parser_t::principal_parser.
|
||||
if (exec_subshell(lookup_cmd, parser_t::principal_parser(), list,
|
||||
false /* don't apply exit status */) != -1) {
|
||||
std::unordered_map<wcstring, wcstring> lookup;
|
||||
|
@ -1140,7 +1140,7 @@ bool completer_t::complete_variable(const wcstring &str, size_t start_offset) {
|
|||
wcstring desc;
|
||||
if (this->wants_descriptions()) {
|
||||
// Can't use this->vars here, it could be any variable.
|
||||
auto var = env_get(env_name);
|
||||
auto var = vars.get(env_name);
|
||||
if (!var) continue;
|
||||
|
||||
wcstring value = expand_escape_variable(*var);
|
||||
|
|
|
@ -364,12 +364,13 @@ int main(int argc, char **argv) {
|
|||
save_term_foreground_process_group();
|
||||
}
|
||||
|
||||
auto &globals = env_stack_t::globals();
|
||||
const struct config_paths_t paths = determine_config_directory_paths(argv[0]);
|
||||
env_init(&paths);
|
||||
// Set features early in case other initialization depends on them.
|
||||
// Start with the ones set in the environment, then those set on the command line (so the
|
||||
// command line takes precedence).
|
||||
if (auto features_var = env_get(L"fish_features")) {
|
||||
if (auto features_var = globals.get(L"fish_features")) {
|
||||
for (const wcstring &s : features_var->as_list()) {
|
||||
mutable_fish_features().set_from_string(s);
|
||||
}
|
||||
|
|
|
@ -25,29 +25,31 @@
|
|||
#include "fallback.h" // IWYU pragma: keep
|
||||
#include "function.h"
|
||||
#include "intern.h"
|
||||
#include "parser.h"
|
||||
#include "parser_keywords.h"
|
||||
#include "reader.h"
|
||||
#include "wutil.h" // IWYU pragma: keep
|
||||
|
||||
class function_info_t {
|
||||
public:
|
||||
/// Immutable properties of the function.
|
||||
std::shared_ptr<const function_properties_t> props;
|
||||
/// Function description. This may be changed after the function is created.
|
||||
wcstring description;
|
||||
/// File where this function was defined (intern'd string).
|
||||
const wchar_t *const definition_file;
|
||||
/// Mapping of all variables that were inherited from the function definition scope to their
|
||||
/// values.
|
||||
const std::map<wcstring, env_var_t> inherit_vars;
|
||||
/// Flag for specifying that this function was automatically loaded.
|
||||
const bool is_autoload;
|
||||
public:
|
||||
/// Immutable properties of the function.
|
||||
std::shared_ptr<const function_properties_t> props;
|
||||
/// Function description. This may be changed after the function is created.
|
||||
wcstring description;
|
||||
/// File where this function was defined (intern'd string).
|
||||
const wchar_t *const definition_file;
|
||||
/// Mapping of all variables that were inherited from the function definition scope to their
|
||||
/// values.
|
||||
const std::map<wcstring, env_var_t> inherit_vars;
|
||||
/// Flag for specifying that this function was automatically loaded.
|
||||
const bool is_autoload;
|
||||
|
||||
/// Constructs relevant information from the function_data.
|
||||
function_info_t(function_data_t data, const wchar_t *filename, bool autoload);
|
||||
/// Constructs relevant information from the function_data.
|
||||
function_info_t(function_data_t data, const environment_t &vars, const wchar_t *filename,
|
||||
bool autoload);
|
||||
|
||||
/// Used by function_copy.
|
||||
function_info_t(const function_info_t &data, const wchar_t *filename, bool autoload);
|
||||
/// Used by function_copy.
|
||||
function_info_t(const function_info_t &data, const wchar_t *filename, bool autoload);
|
||||
};
|
||||
|
||||
/// Table containing all functions.
|
||||
|
@ -101,7 +103,9 @@ static int load(const wcstring &name) {
|
|||
static void autoload_names(std::unordered_set<wcstring> &names, int get_hidden) {
|
||||
size_t i;
|
||||
|
||||
const auto path_var = env_get(L"fish_function_path");
|
||||
// TODO: justfy this.
|
||||
auto &vars = env_stack_t::principal();
|
||||
const auto path_var = vars.get(L"fish_function_path");
|
||||
if (path_var.missing_or_empty()) return;
|
||||
|
||||
wcstring_list_t path_list;
|
||||
|
@ -127,20 +131,22 @@ static void autoload_names(std::unordered_set<wcstring> &names, int get_hidden)
|
|||
}
|
||||
}
|
||||
|
||||
static std::map<wcstring, env_var_t> snapshot_vars(const wcstring_list_t &vars) {
|
||||
static std::map<wcstring, env_var_t> snapshot_vars(const wcstring_list_t &vars,
|
||||
const environment_t &src) {
|
||||
std::map<wcstring, env_var_t> result;
|
||||
for (const wcstring &name : vars) {
|
||||
auto var = env_get(name);
|
||||
auto var = src.get(name);
|
||||
if (var) result[name] = std::move(*var);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function_info_t::function_info_t(function_data_t data, const wchar_t *filename, bool autoload)
|
||||
function_info_t::function_info_t(function_data_t data, const environment_t &vars,
|
||||
const wchar_t *filename, bool autoload)
|
||||
: props(std::make_shared<const function_properties_t>(std::move(data.props))),
|
||||
description(std::move(data.description)),
|
||||
definition_file(intern(filename)),
|
||||
inherit_vars(snapshot_vars(data.inherit_vars)),
|
||||
inherit_vars(snapshot_vars(data.inherit_vars, vars)),
|
||||
is_autoload(autoload) {}
|
||||
|
||||
function_info_t::function_info_t(const function_info_t &data, const wchar_t *filename,
|
||||
|
@ -164,8 +170,8 @@ void function_add(const function_data_t &data, const parser_t &parser) {
|
|||
// Create and store a new function.
|
||||
const wchar_t *filename = reader_current_filename();
|
||||
|
||||
const function_map_t::value_type new_pair(data.name,
|
||||
function_info_t(data, filename, is_autoload));
|
||||
const function_map_t::value_type new_pair(
|
||||
data.name, function_info_t(data, parser.vars(), filename, is_autoload));
|
||||
loaded_functions.insert(new_pair);
|
||||
|
||||
// Add event handlers.
|
||||
|
|
|
@ -554,7 +554,7 @@ void writembs_check(const char *mbs, const char *mbs_name, bool critical, const
|
|||
if (mbs != NULL) {
|
||||
tputs(mbs, 1, &writeb);
|
||||
} else if (critical) {
|
||||
auto term = env_get(L"TERM");
|
||||
auto term = env_stack_t::globals().get(L"TERM");
|
||||
const wchar_t *fmt =
|
||||
_(L"Tried to use terminfo string %s on line %ld of %s, which is "
|
||||
L"undefined in terminal of type \"%ls\". Please report this error to %s");
|
||||
|
|
|
@ -385,8 +385,9 @@ parse_execution_result_t parse_execution_context_t::run_for_statement(
|
|||
return ret;
|
||||
}
|
||||
|
||||
auto var = env_get(for_var_name, ENV_LOCAL);
|
||||
if (!var && !is_function_context()) var = env_get(for_var_name, ENV_DEFAULT);
|
||||
auto &vars = parser->vars();
|
||||
auto var = vars.get(for_var_name, ENV_LOCAL);
|
||||
if (!var && !is_function_context()) var = vars.get(for_var_name, ENV_DEFAULT);
|
||||
if (!var || var->read_only()) {
|
||||
int retval = parser->vars().set_empty(for_var_name, ENV_LOCAL | ENV_USER);
|
||||
if (retval != ENV_OK) {
|
||||
|
|
15
src/path.cpp
15
src/path.cpp
|
@ -119,12 +119,8 @@ bool path_get_path(const wcstring &cmd, wcstring *out_path, const environment_t
|
|||
return path_get_path_core(cmd, out_path, vars.get(L"PATH"));
|
||||
}
|
||||
|
||||
bool path_get_path(const wcstring &cmd, wcstring *out_path) {
|
||||
return path_get_path_core(cmd, out_path, env_get(L"PATH"));
|
||||
}
|
||||
|
||||
wcstring_list_t path_get_paths(const wcstring &cmd) {
|
||||
debug(5, L"path_get_paths('%ls')", cmd.c_str());
|
||||
wcstring_list_t path_get_paths(const wcstring &cmd, const environment_t &vars) {
|
||||
debug(3, L"path_get_paths('%ls')", cmd.c_str());
|
||||
wcstring_list_t paths;
|
||||
|
||||
// If the command has a slash, it must be an absolute or relative path and thus we don't bother
|
||||
|
@ -138,7 +134,7 @@ wcstring_list_t path_get_paths(const wcstring &cmd) {
|
|||
return paths;
|
||||
}
|
||||
|
||||
auto path_var = env_get(L"PATH");
|
||||
auto path_var = vars.get(L"PATH");
|
||||
std::vector<wcstring> pathsv;
|
||||
if (path_var) path_var->to_list(pathsv);
|
||||
for (auto path : pathsv) {
|
||||
|
@ -291,7 +287,8 @@ static void path_create(wcstring &path, const wcstring &xdg_var, const wcstring
|
|||
// The vars we fetch must be exported. Allowing them to be universal doesn't make sense and
|
||||
// allowing that creates a lock inversion that deadlocks the shell since we're called before
|
||||
// uvars are available.
|
||||
const auto xdg_dir = env_get(xdg_var, ENV_GLOBAL | ENV_EXPORT);
|
||||
const auto &vars = env_stack_t::globals();
|
||||
const auto xdg_dir = vars.get(xdg_var, ENV_GLOBAL | ENV_EXPORT);
|
||||
if (!xdg_dir.missing_or_empty()) {
|
||||
using_xdg = true;
|
||||
path = xdg_dir->as_string() + L"/fish";
|
||||
|
@ -301,7 +298,7 @@ static void path_create(wcstring &path, const wcstring &xdg_var, const wcstring
|
|||
saved_errno = errno;
|
||||
}
|
||||
} else {
|
||||
const auto home = env_get(L"HOME", ENV_GLOBAL | ENV_EXPORT);
|
||||
const auto home = vars.get(L"HOME", ENV_GLOBAL | ENV_EXPORT);
|
||||
if (!home.missing_or_empty()) {
|
||||
path = home->as_string() +
|
||||
(which_dir == L"config" ? L"/.config/fish" : L"/.local/share/fish");
|
||||
|
|
|
@ -42,7 +42,7 @@ bool path_get_data(wcstring &path);
|
|||
bool path_get_path(const wcstring &cmd, wcstring *output_or_NULL, const environment_t &vars);
|
||||
|
||||
/// Return all the paths that match the given command.
|
||||
wcstring_list_t path_get_paths(const wcstring &cmd);
|
||||
wcstring_list_t path_get_paths(const wcstring &cmd, const environment_t &vars);
|
||||
|
||||
/// Returns the full path of the specified directory, using the CDPATH variable as a list of base
|
||||
/// directories for relative paths.
|
||||
|
|
Loading…
Reference in a new issue