diff --git a/src/env.cpp b/src/env.cpp index 22d4c5734..40af30bfb 100644 --- a/src/env.cpp +++ b/src/env.cpp @@ -1,353 +1,239 @@ -/** \file env.c - Functions for setting and getting environment variables. -*/ -#include -#include -#include -#include +// Functions for setting and getting environment variables. #include -#include +#include +#include #include #include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include -#include -#include -#include "fallback.h" // IWYU pragma: keep -#include "wutil.h" // IWYU pragma: keep -#include "proc.h" #include "common.h" #include "env.h" -#include "sanity.h" -#include "expand.h" -#include "history.h" -#include "reader.h" #include "env_universal_common.h" -#include "input.h" #include "event.h" -#include "path.h" +#include "expand.h" +#include "fallback.h" // IWYU pragma: keep #include "fish_version.h" +#include "history.h" +#include "input.h" #include "input_common.h" +#include "path.h" +#include "proc.h" +#include "reader.h" +#include "sanity.h" +#include "wutil.h" // IWYU pragma: keep -/** Value denoting a null string */ +/// Value denoting a null string. #define ENV_NULL L"\x1d" -/** Some configuration path environment variables */ +/// Some configuration path environment variables. #define FISH_DATADIR_VAR L"__fish_datadir" #define FISH_SYSCONFDIR_VAR L"__fish_sysconfdir" #define FISH_HELPDIR_VAR L"__fish_help_dir" #define FISH_BIN_DIR L"__fish_bin_dir" -/** - At init, we read all the environment variables from this array. -*/ +/// At init, we read all the environment variables from this array. extern char **environ; -/** - This should be the same thing as \c environ, but it is possible only one of the two work... -*/ +/// This should be the same thing as \c environ, but it is possible only one of the two work... extern char **__environ; - bool g_log_forks = false; -bool g_use_posix_spawn = false; //will usually be set to true +bool g_use_posix_spawn = false; // will usually be set to true - -/** - Struct representing one level in the function variable stack -*/ -struct env_node_t -{ - /** - Variable table - */ +/// Struct representing one level in the function variable stack. +struct env_node_t { + /// Variable table. var_table_t env; - /** - Does this node imply a new variable scope? If yes, all - non-global variables below this one in the stack are - invisible. If new_scope is set for the global variable node, - the universe will explode. - */ + /// Does this node imply a new variable scope? If yes, all non-global variables below this one + /// in the stack are invisible. If new_scope is set for the global variable node, the universe + /// will explode. bool new_scope; - /** - Does this node contain any variables which are exported to subshells - */ + /// Does this node contain any variables which are exported to subshells. bool exportv; - - /** - Pointer to next level - */ + /// Pointer to next level. struct env_node_t *next; + env_node_t() : new_scope(false), exportv(false), next(NULL) {} - env_node_t() : new_scope(false), exportv(false), next(NULL) { } - - /* Returns a pointer to the given entry if present, or NULL. */ + /// Returns a pointer to the given entry if present, or NULL. const var_entry_t *find_entry(const wcstring &key); - /* Returns the next scope to search in order, respecting the new_scope flag, or NULL if we're done. */ + /// Returns the next scope to search in order, respecting the new_scope flag, or NULL if we're + /// done. env_node_t *next_scope_to_search(); const env_node_t *next_scope_to_search() const; }; -class variable_entry_t -{ +class variable_entry_t { wcstring value; /**< Value of the variable */ }; static pthread_mutex_t env_lock = PTHREAD_MUTEX_INITIALIZER; -/** Top node on the function stack */ +/// Top node on the function stack. static env_node_t *top = NULL; -/** Bottom node on the function stack */ +/// Bottom node on the function stack. static env_node_t *global_env = NULL; -/** Universal variables global instance. Initialized in env_init. */ +/// Universal variables global instance. Initialized in env_init. static env_universal_t *s_universal_variables = NULL; -/* Getter for universal variables */ -static env_universal_t *uvars() { - return s_universal_variables; -} +/// Getter for universal variables. +static env_universal_t *uvars() { return s_universal_variables; } -/** - Table for global variables -*/ +/// Table for global variables. static var_table_t *global; -/* Helper class for storing constant strings, without needing to wrap them in a wcstring */ +// Helper class for storing constant strings, without needing to wrap them in a wcstring. -/* Comparer for const string set */ -struct const_string_set_comparer -{ - bool operator()(const wchar_t *a, const wchar_t *b) - { - return wcscmp(a, b) < 0; - } +// Comparer for const string set. +struct const_string_set_comparer { + bool operator()(const wchar_t *a, const wchar_t *b) { return wcscmp(a, b) < 0; } }; typedef std::set const_string_set_t; -/** Table of variables that may not be set using the set command. */ +/// Table of variables that may not be set using the set command. static const_string_set_t env_read_only; -static bool is_read_only(const wcstring &key) -{ +static bool is_read_only(const wcstring &key) { return env_read_only.find(key.c_str()) != env_read_only.end(); } -/** - Table of variables whose value is dynamically calculated, such as umask, status, etc -*/ +/// Table of variables whose value is dynamically calculated, such as umask, status, etc. static const_string_set_t env_electric; -static bool is_electric(const wcstring &key) -{ +static bool is_electric(const wcstring &key) { return env_electric.find(key.c_str()) != env_electric.end(); } -/** - Exported variable array used by execv -*/ +/// Exported variable array used by execv. static null_terminated_array_t export_array; -/** - Flag for checking if we need to regenerate the exported variable - array -*/ +/// Flag for checking if we need to regenerate the exported variable array. static bool has_changed_exported = true; -static void mark_changed_exported() -{ - has_changed_exported = true; -} +static void mark_changed_exported() { has_changed_exported = true; } -/** - List of all locale variable names -*/ -static const wchar_t * const locale_variable[] = -{ - L"LANG", - L"LC_ALL", - L"LC_COLLATE", - L"LC_CTYPE", - L"LC_MESSAGES", - L"LC_MONETARY", - L"LC_NUMERIC", - L"LC_TIME", - NULL -}; +/// List of all locale variable names. +static const wchar_t *const locale_variable[] = {L"LANG", L"LC_ALL", L"LC_COLLATE", + L"LC_CTYPE", L"LC_MESSAGES", L"LC_MONETARY", + L"LC_NUMERIC", L"LC_TIME", NULL}; - -const var_entry_t *env_node_t::find_entry(const wcstring &key) -{ +const var_entry_t *env_node_t::find_entry(const wcstring &key) { const var_entry_t *result = NULL; var_table_t::const_iterator where = env.find(key); - if (where != env.end()) - { + if (where != env.end()) { result = &where->second; } return result; } -env_node_t *env_node_t::next_scope_to_search() -{ +env_node_t *env_node_t::next_scope_to_search() { return this->new_scope ? global_env : this->next; } + +const env_node_t *env_node_t::next_scope_to_search() const { return this->new_scope ? global_env : this->next; } -const env_node_t *env_node_t::next_scope_to_search() const -{ - return this->new_scope ? global_env : this->next; -} - - -/** - Return the current umask value. -*/ -static mode_t get_umask() -{ +/// Return the current umask value. +static mode_t get_umask() { mode_t res; res = umask(0); umask(res); return res; } -/** Checks if the specified variable is a locale variable */ -static bool var_is_locale(const wcstring &key) -{ - for (size_t i=0; locale_variable[i]; i++) - { - if (key == locale_variable[i]) - { +/// Check if the specified variable is a locale variable. +static bool var_is_locale(const wcstring &key) { + for (size_t i = 0; locale_variable[i]; i++) { + if (key == locale_variable[i]) { return true; } } return false; } -/** - Properly sets all locale information -*/ -static void handle_locale() -{ +/// Properly sets all locale information. +static void handle_locale() { const env_var_t lc_all = env_get_string(L"LC_ALL"); const wcstring old_locale = wsetlocale(LC_MESSAGES, NULL); - /* - Array of locale constants corresponding to the local variable names defined in locale_variable - */ - static const int cat[] = - { - 0, - LC_ALL, - LC_COLLATE, - LC_CTYPE, - LC_MESSAGES, - LC_MONETARY, - LC_NUMERIC, - LC_TIME - } - ; + // Array of locale constants corresponding to the local variable names defined in + // locale_variable. + static const int cat[] = {0, LC_ALL, LC_COLLATE, LC_CTYPE, + LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME}; - if (!lc_all.missing()) - { + if (!lc_all.missing()) { wsetlocale(LC_ALL, lc_all.c_str()); - } - else - { + } else { const env_var_t lang = env_get_string(L"LANG"); - if (!lang.missing()) - { + if (!lang.missing()) { wsetlocale(LC_ALL, lang.c_str()); } - for (int i=2; locale_variable[i]; i++) - { + for (int i = 2; locale_variable[i]; i++) { const env_var_t val = env_get_string(locale_variable[i]); - if (!val.missing()) - { + if (!val.missing()) { wsetlocale(cat[i], val.c_str()); } } } const wcstring new_locale = wsetlocale(LC_MESSAGES, NULL); - if (old_locale != new_locale) - { - - /* - Try to make change known to gettext. Both changing - _nl_msg_cat_cntr and calling dcgettext might potentially - tell some gettext implementation that the translation - strings should be reloaded. We do both and hope for the - best. - */ - + if (old_locale != new_locale) { + // Try to make change known to gettext. Both changing _nl_msg_cat_cntr and calling dcgettext + // might potentially tell some gettext implementation that the translation strings should be + // reloaded. We do both and hope for the best. extern int _nl_msg_cat_cntr; _nl_msg_cat_cntr++; - fish_dcgettext("fish", "Changing language to English", LC_MESSAGES); } } - -/** React to modifying the given variable */ -static void react_to_variable_change(const wcstring &key) -{ - if (var_is_locale(key)) - { +/// React to modifying the given variable. +static void react_to_variable_change(const wcstring &key) { + if (var_is_locale(key)) { handle_locale(); - } - else if (key == L"fish_term256" || key == L"fish_term24bit") - { + } else if (key == L"fish_term256" || key == L"fish_term24bit") { update_fish_color_support(); reader_react_to_color_change(); - } - else if (string_prefixes_string(L"fish_color_", key)) - { + } else if (string_prefixes_string(L"fish_color_", key)) { reader_react_to_color_change(); - } - else if (key == L"fish_escape_delay_ms") - { + } else if (key == L"fish_escape_delay_ms") { update_wait_on_escape_ms(); } } -/** - Universal variable callback function. This function makes sure the - proper events are triggered when an event occurs. -*/ -static void universal_callback(fish_message_type_t type, const wchar_t *name, const wchar_t *val) -{ +/// Universal variable callback function. This function makes sure the proper events are triggered +/// when an event occurs. +static void universal_callback(fish_message_type_t type, const wchar_t *name, const wchar_t *val) { const wchar_t *str = NULL; - switch (type) - { + switch (type) { case SET: - case SET_EXPORT: - { - str=L"SET"; + case SET_EXPORT: { + str = L"SET"; break; } - - case ERASE: - { - str=L"ERASE"; + case ERASE: { + str = L"ERASE"; break; } - - default: - break; + default: { break; } } - if (str) - { + if (str) { mark_changed_exported(); event_t ev = event_t::variable_event(name); @@ -357,81 +243,59 @@ static void universal_callback(fish_message_type_t type, const wchar_t *name, co event_fire(&ev); } - if (name) - react_to_variable_change(name); + if (name) react_to_variable_change(name); } -/** - Make sure the PATH variable contains something -*/ -static void setup_path() -{ +/// Make sure the PATH variable contains something. +static void setup_path() { const env_var_t path = env_get_string(L"PATH"); - if (path.missing_or_empty()) - { + if (path.missing_or_empty()) { const wchar_t *value = L"/usr/bin" ARRAY_SEP_STR L"/bin"; env_set(L"PATH", value, ENV_GLOBAL | ENV_EXPORT); } } -int env_set_pwd() -{ +int env_set_pwd() { wcstring res = wgetcwd(); - if (res.empty()) - { - debug(0, _(L"Could not determine current working directory. Is your locale set correctly?")); + if (res.empty()) { + debug(0, + _(L"Could not determine current working directory. Is your locale set correctly?")); return 0; } env_set(L"PWD", res.c_str(), ENV_EXPORT | ENV_GLOBAL); return 1; } -wcstring env_get_pwd_slash(void) -{ +wcstring env_get_pwd_slash(void) { env_var_t pwd = env_get_string(L"PWD"); - if (pwd.missing_or_empty()) - { + if (pwd.missing_or_empty()) { return L""; } - if (! string_suffixes_string(L"/", pwd)) - { + if (!string_suffixes_string(L"/", pwd)) { pwd.push_back(L'/'); } return pwd; } -/* Here is the whitelist of variables that we colon-delimit, both incoming from the environment and outgoing back to it. This is deliberately very short - we don't want to add language-specific values like CLASSPATH. */ -static bool variable_is_colon_delimited_array(const wcstring &str) -{ +// Here is the whitelist of variables that we colon-delimit, both incoming from the environment and +// outgoing back to it. This is deliberately very short - we don't want to add language-specific +// values like CLASSPATH. +static bool variable_is_colon_delimited_array(const wcstring &str) { return contains(str, L"PATH", L"MANPATH", L"CDPATH"); } -void env_init(const struct config_paths_t *paths /* or NULL */) -{ - /* - env_read_only variables can not be altered directly by the user - */ - - const wchar_t * const ro_keys[] = - { - L"status", - L"history", - L"version", - L"_", - L"LINES", - L"COLUMNS", - L"PWD", - //L"SHLVL", // will be inserted a bit lower down +void env_init(const struct config_paths_t *paths /* or NULL */) { + // env_read_only variables can not be altered directly by the user. + const wchar_t *const ro_keys[] = { + L"status", L"history", L"version", L"_", L"LINES", L"COLUMNS", L"PWD", + // L"SHLVL", // will be inserted a bit lower down L"FISH_VERSION", }; - for (size_t i=0; i < sizeof ro_keys / sizeof *ro_keys; i++) - { + for (size_t i = 0; i < sizeof ro_keys / sizeof *ro_keys; i++) { env_read_only.insert(ro_keys[i]); } - /* - Names of all dynamically calculated variables - */ + // Names of all dynamically calculated variables. env_electric.insert(L"history"); env_electric.insert(L"status"); env_electric.insert(L"umask"); @@ -442,36 +306,28 @@ void env_init(const struct config_paths_t *paths /* or NULL */) global_env = top; global = &top->env; - /* - Now the environemnt variable handling is set up, the next step - is to insert valid data - */ + // Now the environemnt variable handling is set up, the next step is to insert valid data. - /* Import environment variables. Walk backwards so that the first one out of any duplicates wins (#2784) */ + // Import environment variables. Walk backwards so that the first one out of any duplicates wins + // (#2784). wcstring key, val; - const char * const * envp = (environ ? environ : __environ); + const char *const *envp = (environ ? environ : __environ); size_t i = 0; - while (envp && envp[i]) - { + while (envp && envp[i]) { i++; } - while (i--) - { - const wcstring key_and_val = str2wcstring(envp[i]); //like foo=bar + while (i--) { + const wcstring key_and_val = str2wcstring(envp[i]); // like foo=bar size_t eql = key_and_val.find(L'='); - if (eql == wcstring::npos) - { - // no equals found + if (eql == wcstring::npos) { + // No equals found. if (is_read_only(key_and_val) || is_electric(key_and_val)) continue; env_set(key_and_val, L"", ENV_EXPORT | ENV_GLOBAL); - } - else - { + } else { key.assign(key_and_val, 0, eql); if (is_read_only(key) || is_electric(key)) continue; val.assign(key_and_val, eql + 1, wcstring::npos); - if (variable_is_colon_delimited_array(key)) - { + if (variable_is_colon_delimited_array(key)) { std::replace(val.begin(), val.end(), L':', ARRAY_SEP); } @@ -479,111 +335,89 @@ void env_init(const struct config_paths_t *paths /* or NULL */) } } - /* Set the given paths in the environment, if we have any */ - if (paths != NULL) - { + // Set the given paths in the environment, if we have any. + if (paths != NULL) { env_set(FISH_DATADIR_VAR, paths->data.c_str(), ENV_GLOBAL); env_set(FISH_SYSCONFDIR_VAR, paths->sysconf.c_str(), ENV_GLOBAL); env_set(FISH_HELPDIR_VAR, paths->doc.c_str(), ENV_GLOBAL); env_set(FISH_BIN_DIR, paths->bin.c_str(), ENV_GLOBAL); } - /* - Set up the PATH variable - */ + // Set up the PATH variable. setup_path(); - /* - Set up the USER variable - */ - if (env_get_string(L"USER").missing_or_empty()) - { + // Set up the USER variable. + if (env_get_string(L"USER").missing_or_empty()) { const struct passwd *pw = getpwuid(getuid()); - if (pw && pw->pw_name) - { + if (pw && pw->pw_name) { const wcstring uname = str2wcstring(pw->pw_name); env_set(L"USER", uname.c_str(), ENV_GLOBAL | ENV_EXPORT); } } - /* - Set up the version variables - */ + // Set up the version variables. wcstring version = str2wcstring(get_fish_version()); env_set(L"version", version.c_str(), ENV_GLOBAL); env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL); - /* - Set up SHLVL variable - */ + // Set up SHLVL variable. const env_var_t shlvl_str = env_get_string(L"SHLVL"); wcstring nshlvl_str = L"1"; - if (! shlvl_str.missing()) - { + if (!shlvl_str.missing()) { wchar_t *end; long shlvl_i = wcstol(shlvl_str.c_str(), &end, 10); - while (iswspace(*end)) ++end; /* skip trailing whitespace */ - if (shlvl_i >= 0 && *end == '\0') - { + while (iswspace(*end)) ++end; // skip trailing whitespace + if (shlvl_i >= 0 && *end == '\0') { nshlvl_str = to_string(shlvl_i + 1); } } env_set(L"SHLVL", nshlvl_str.c_str(), ENV_GLOBAL | ENV_EXPORT); env_read_only.insert(L"SHLVL"); - /* Set up the HOME variable */ - if (env_get_string(L"HOME").missing_or_empty()) - { + // Set up the HOME variable. + if (env_get_string(L"HOME").missing_or_empty()) { const env_var_t unam = env_get_string(L"USER"); char *unam_narrow = wcs2str(unam.c_str()); struct passwd *pw = getpwnam(unam_narrow); - if (pw->pw_dir != NULL) - { + if (pw->pw_dir != NULL) { const wcstring dir = str2wcstring(pw->pw_dir); env_set(L"HOME", dir.c_str(), ENV_GLOBAL | ENV_EXPORT); } free(unam_narrow); } - /* Set PWD */ + // Set PWD. env_set_pwd(); - /* Set up universal variables. The empty string means to use the deafult path. */ + // Set up universal variables. The empty string means to use the deafult path. assert(s_universal_variables == NULL); s_universal_variables = new env_universal_t(L""); s_universal_variables->load(); - /* Set g_log_forks */ + // Set g_log_forks. env_var_t log_forks = env_get_string(L"fish_log_forks"); - g_log_forks = ! log_forks.missing_or_empty() && from_string(log_forks); + g_log_forks = !log_forks.missing_or_empty() && from_string(log_forks); - /* Set g_use_posix_spawn. Default to true. */ + // Set g_use_posix_spawn. Default to true. env_var_t use_posix_spawn = env_get_string(L"fish_use_posix_spawn"); - g_use_posix_spawn = (use_posix_spawn.missing_or_empty() ? true : from_string(use_posix_spawn)); + g_use_posix_spawn = + (use_posix_spawn.missing_or_empty() ? true : from_string(use_posix_spawn)); - /* Set fish_bind_mode to "default" */ + // Set fish_bind_mode to "default". env_set(FISH_BIND_MODE_VAR, DEFAULT_BIND_MODE, ENV_GLOBAL); - /* - Now that the global scope is fully initialized, add a toplevel local - scope. This same local scope will persist throughout the lifetime of the - fish process, and it will ensure that `set -l` commands run at the - command-line don't affect the global scope. - */ + // Now that the global scope is fully initialized, add a toplevel local scope. This same local + // scope will persist throughout the lifetime of the fish process, and it will ensure that `set + // -l` commands run at the command-line don't affect the global scope. env_push(false); } -/** - Search all visible scopes in order for the specified key. Return - the first scope in which it was found. -*/ -static env_node_t *env_get_node(const wcstring &key) -{ +/// Search all visible scopes in order for the specified key. Return the first scope in which it was +/// found. +static env_node_t *env_get_node(const wcstring &key) { env_node_t *env = top; - while (env != NULL) - { - if (env->find_entry(key) != NULL) - { + while (env != NULL) { + if (env->find_entry(key) != NULL) { break; } @@ -592,53 +426,42 @@ static env_node_t *env_get_node(const wcstring &key) return env; } -int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) -{ +int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) { ASSERT_IS_MAIN_THREAD(); bool has_changed_old = has_changed_exported; - int done=0; + int done = 0; - if (val && contains(key, L"PWD", L"HOME")) - { - /* Canoncalize our path; if it changes, recurse and try again. */ + if (val && contains(key, L"PWD", L"HOME")) { + // Canonicalize our path; if it changes, recurse and try again. wcstring val_canonical = val; path_make_canonical(val_canonical); - if (val != val_canonical) - { + if (val != val_canonical) { return env_set(key, val_canonical.c_str(), var_mode); } } - if ((var_mode & (ENV_LOCAL | ENV_UNIVERSAL)) && (is_read_only(key) || is_electric(key))) - { + if ((var_mode & (ENV_LOCAL | ENV_UNIVERSAL)) && (is_read_only(key) || is_electric(key))) { return ENV_SCOPE; } - if ((var_mode & ENV_EXPORT) && is_electric(key)) - { + if ((var_mode & ENV_EXPORT) && is_electric(key)) { return ENV_SCOPE; } - - if ((var_mode & ENV_USER) && is_read_only(key)) - { + if ((var_mode & ENV_USER) && is_read_only(key)) { return ENV_PERM; } - if (key == L"umask") - { + if (key == L"umask") { wchar_t *end; - /* - Set the new umask - */ - if (val && wcslen(val)) - { - errno=0; + // Set the new umask. + if (val && wcslen(val)) { + errno = 0; long mask = wcstol(val, &end, 8); - if (!errno && (!*end) && (mask <= 0777) && (mask >= 0)) - { + if (!errno && (!*end) && (mask <= 0777) && (mask >= 0)) { umask(mask); - /* Do not actually create a umask variable, on env_get, it will be calculated dynamically */ + // Do not actually create a umask variable, on env_get, it will be calculated + // dynamically. return 0; } } @@ -646,102 +469,71 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) return ENV_INVALID; } - /* - Zero element arrays are internaly not coded as null but as this - placeholder string - */ - if (!val) - { + // Zero element arrays are internaly not coded as null but as this placeholder string. + if (!val) { val = ENV_NULL; } - if (var_mode & ENV_UNIVERSAL) - { + if (var_mode & ENV_UNIVERSAL) { const bool old_export = uvars() && uvars()->get_export(key); bool new_export; - if (var_mode & ENV_EXPORT) - { - // export + if (var_mode & ENV_EXPORT) { + // Export the var. new_export = true; - } - else if (var_mode & ENV_UNEXPORT) - { - // unexport + } else if (var_mode & ENV_UNEXPORT) { + // Unexport the var. new_export = false; - } - else - { - // not changing the export + } else { + // Not changing the export status of the var. new_export = old_export; } - if (uvars()) - { + if (uvars()) { uvars()->set(key, val, new_export); env_universal_barrier(); - if (old_export || new_export) - { + if (old_export || new_export) { mark_changed_exported(); } } - } - else - { - // Determine the node + } else { + // Determine the node. bool has_changed_new = false; env_node_t *preexisting_node = env_get_node(key); bool preexisting_entry_exportv = false; - if (preexisting_node != NULL) - { + if (preexisting_node != NULL) { var_table_t::const_iterator result = preexisting_node->env.find(key); assert(result != preexisting_node->env.end()); const var_entry_t &entry = result->second; - if (entry.exportv) - { + if (entry.exportv) { preexisting_entry_exportv = true; has_changed_new = true; } } env_node_t *node = NULL; - if (var_mode & ENV_GLOBAL) - { + if (var_mode & ENV_GLOBAL) { node = global_env; - } - else if (var_mode & ENV_LOCAL) - { + } else if (var_mode & ENV_LOCAL) { node = top; - } - else if (preexisting_node != NULL) - { + } else if (preexisting_node != NULL) { node = preexisting_node; - if ((var_mode & (ENV_EXPORT | ENV_UNEXPORT)) == 0) - { + if ((var_mode & (ENV_EXPORT | ENV_UNEXPORT)) == 0) { // use existing entry's exportv var_mode = preexisting_entry_exportv ? ENV_EXPORT : 0; } - } - else - { - if (! get_proc_had_barrier()) - { + } else { + if (!get_proc_had_barrier()) { set_proc_had_barrier(true); env_universal_barrier(); } - if (uvars() && ! uvars()->get(key).missing()) - { + if (uvars() && !uvars()->get(key).missing()) { bool exportv; - if (var_mode & ENV_EXPORT) - { + if (var_mode & ENV_EXPORT) { exportv = true; - } - else if (var_mode & ENV_UNEXPORT) - { + } else if (var_mode & ENV_UNEXPORT) { exportv = false; - } - else - { + } else { exportv = uvars()->get_export(key); } @@ -750,48 +542,35 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) done = 1; - } - else - { - /* - New variable with unspecified scope. The default - scope is the innermost scope that is shadowing, - which will be either the current function or the - global scope. - */ + } else { + // New variable with unspecified scope. The default scope is the innermost scope + // that is shadowing, which will be either the current function or the global scope. node = top; - while (node->next && !node->new_scope) - { + while (node->next && !node->new_scope) { node = node->next; } } } - if (!done) - { - // Set the entry in the node - // Note that operator[] accesses the existing entry, or creates a new one + if (!done) { + // Set the entry in the node. Note that operator[] accesses the existing entry, or + // creates a new one. var_entry_t &entry = node->env[key]; - if (entry.exportv) - { - // this variable already existed, and was exported + if (entry.exportv) { + // This variable already existed, and was exported. has_changed_new = true; } entry.val = val; - if (var_mode & ENV_EXPORT) - { - // the new variable is exported + if (var_mode & ENV_EXPORT) { + // The new variable is exported. entry.exportv = true; node->exportv = true; has_changed_new = true; - } - else - { + } else { entry.exportv = false; } - if (has_changed_old || has_changed_new) - mark_changed_exported(); + if (has_changed_old || has_changed_new) mark_changed_exported(); } } @@ -801,79 +580,59 @@ int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t var_mode) ev.arguments.push_back(L"SET"); ev.arguments.push_back(key); - // debug( 1, L"env_set: fire events on variable %ls", key ); + // debug( 1, L"env_set: fire events on variable %ls", key ); event_fire(&ev); - // debug( 1, L"env_set: return from event firing" ); + // debug( 1, L"env_set: return from event firing" ); react_to_variable_change(key); - return 0; } - -/** - Attempt to remove/free the specified key/value pair from the - specified map. - - \return zero if the variable was not found, non-zero otherwise -*/ -static bool try_remove(env_node_t *n, const wchar_t *key, int var_mode) -{ - if (n == NULL) - { +/// Attempt to remove/free the specified key/value pair from the specified map. +/// +/// \return zero if the variable was not found, non-zero otherwise +static bool try_remove(env_node_t *n, const wchar_t *key, int var_mode) { + if (n == NULL) { return false; } var_table_t::iterator result = n->env.find(key); - if (result != n->env.end()) - { - if (result->second.exportv) - { + if (result != n->env.end()) { + if (result->second.exportv) { mark_changed_exported(); } n->env.erase(result); return true; } - if (var_mode & ENV_LOCAL) - { + if (var_mode & ENV_LOCAL) { return false; } - if (n->new_scope) - { + if (n->new_scope) { return try_remove(global_env, key, var_mode); - } - else - { + } else { return try_remove(n->next, key, var_mode); } } - -int env_remove(const wcstring &key, int var_mode) -{ +int env_remove(const wcstring &key, int var_mode) { ASSERT_IS_MAIN_THREAD(); env_node_t *first_node; int erased = 0; - if ((var_mode & ENV_USER) && is_read_only(key)) - { + if ((var_mode & ENV_USER) && is_read_only(key)) { return 2; } first_node = top; - if (!(var_mode & ENV_UNIVERSAL)) - { - - if (var_mode & ENV_GLOBAL) - { + if (!(var_mode & ENV_UNIVERSAL)) { + if (var_mode & ENV_GLOBAL) { first_node = global_env; } - if (try_remove(first_node, key.c_str(), var_mode)) - { + if (try_remove(first_node, key.c_str(), var_mode)) { event_t ev = event_t::variable_event(key); ev.arguments.push_back(L"VARIABLE"); ev.arguments.push_back(L"ERASE"); @@ -884,14 +643,10 @@ int env_remove(const wcstring &key, int var_mode) } } - if (!erased && - !(var_mode & ENV_GLOBAL) && - !(var_mode & ENV_LOCAL)) - { + if (!erased && !(var_mode & ENV_GLOBAL) && !(var_mode & ENV_LOCAL)) { bool is_exported = uvars()->get_export(key); erased = uvars() && uvars()->remove(key); - if (erased) - { + if (erased) { env_universal_barrier(); event_t ev = event_t::variable_event(key); ev.arguments.push_back(L"VARIABLE"); @@ -899,9 +654,8 @@ int env_remove(const wcstring &key, int var_mode) ev.arguments.push_back(key); event_fire(&ev); } - - if (is_exported) - mark_changed_exported(); + + if (is_exported) mark_changed_exported(); } react_to_variable_change(key); @@ -909,14 +663,12 @@ int env_remove(const wcstring &key, int var_mode) return !erased; } -const wchar_t *env_var_t::c_str(void) const -{ - assert(! is_missing); +const wchar_t *env_var_t::c_str(void) const { + assert(!is_missing); return wcstring::c_str(); } -env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) -{ +env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) { const bool has_scope = mode & (ENV_LOCAL | ENV_GLOBAL | ENV_UNIVERSAL); const bool search_local = !has_scope || (mode & ENV_LOCAL); const bool search_global = !has_scope || (mode & ENV_GLOBAL); @@ -925,41 +677,31 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) const bool search_exported = (mode & ENV_EXPORT) || !(mode & ENV_UNEXPORT); const bool search_unexported = (mode & ENV_UNEXPORT) || !(mode & ENV_EXPORT); - /* Make the assumption that electric keys can't be shadowed elsewhere, since we currently block that in env_set() */ - if (is_electric(key)) - { + // Make the assumption that electric keys can't be shadowed elsewhere, since we currently block + // that in env_set(). + if (is_electric(key)) { if (!search_global) return env_var_t::missing_var(); - /* Big hack...we only allow getting the history on the main thread. Note that history_t may ask for an environment variable, so don't take the lock here (we don't need it) */ - if (key == L"history" && is_main_thread()) - { + // Big hack. We only allow getting the history on the main thread. Note that history_t may + // ask for an environment variable, so don't take the lock here (we don't need it). + if (key == L"history" && is_main_thread()) { env_var_t result; history_t *history = reader_get_history(); - if (! history) - { + if (!history) { history = &history_t::history_with_name(L"fish"); } - if (history) - history->get_string_representation(&result, ARRAY_SEP_STR); + if (history) history->get_string_representation(&result, ARRAY_SEP_STR); return result; - } - else if (key == L"COLUMNS") - { + } else if (key == L"COLUMNS") { return to_string(common_get_width()); - } - else if (key == L"LINES") - { + } else if (key == L"LINES") { return to_string(common_get_height()); - } - else if (key == L"status") - { + } else if (key == L"status") { return to_string(proc_get_last_status()); - } - else if (key == L"umask") - { + } else if (key == L"umask") { return format_string(L"0%0.3o", get_umask()); } - // we should never get here unless the electric var list is out of sync + // We should never get here unless the electric var list is out of sync. } if (search_local || search_global) { @@ -968,28 +710,20 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) env_node_t *env = search_local ? top : global_env; - while (env != NULL) - { + while (env != NULL) { const var_entry_t *entry = env->find_entry(key); - if (entry != NULL && (entry->exportv ? search_exported : search_unexported)) - { - if (entry->val == ENV_NULL) - { + if (entry != NULL && (entry->exportv ? search_exported : search_unexported)) { + if (entry->val == ENV_NULL) { return env_var_t::missing_var(); - } - else - { + } else { return entry->val; } } - if (has_scope) - { + if (has_scope) { if (!search_global || env == global_env) break; env = global_env; - } - else - { + } else { env = env->next_scope_to_search(); } } @@ -997,19 +731,17 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) if (!search_universal) return env_var_t::missing_var(); - /* Another big hack - only do a universal barrier on the main thread (since it can change variable values) - Make sure we do this outside the env_lock because it may itself call env_get_string */ - if (is_main_thread() && ! get_proc_had_barrier()) - { + // Another hack. Only do a universal barrier on the main thread (since it can change variable + // values). Make sure we do this outside the env_lock because it may itself call env_get_string. + if (is_main_thread() && !get_proc_had_barrier()) { set_proc_had_barrier(true); env_universal_barrier(); } - if (uvars()) - { + if (uvars()) { env_var_t env_var = uvars()->get(key); - if (env_var == ENV_NULL || !(uvars()->get_export(key) ? search_exported : search_unexported)) - { + if (env_var == ENV_NULL || + !(uvars()->get_export(key) ? search_exported : search_unexported)) { env_var = env_var_t::missing_var(); } return env_var; @@ -1017,8 +749,7 @@ env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode) return env_var_t::missing_var(); } -bool env_exist(const wchar_t *key, env_mode_flags_t mode) -{ +bool env_exist(const wchar_t *key, env_mode_flags_t mode) { CHECK(key, false); const bool has_scope = mode & (ENV_LOCAL | ENV_GLOBAL | ENV_UNIVERSAL); @@ -1029,32 +760,24 @@ bool env_exist(const wchar_t *key, env_mode_flags_t mode) const bool test_exported = (mode & ENV_EXPORT) || !(mode & ENV_UNEXPORT); const bool test_unexported = (mode & ENV_UNEXPORT) || !(mode & ENV_EXPORT); - if (is_electric(key)) - { - /* - Electric variables all exist, and they are all global. A local or - universal version can not exist. They are also never exported. - */ - if (test_global && test_unexported) - { + if (is_electric(key)) { + // Electric variables all exist, and they are all global. A local or universal version can + // not exist. They are also never exported. + if (test_global && test_unexported) { return true; } return false; } - if (test_local || test_global) - { + if (test_local || test_global) { const env_node_t *env = test_local ? top : global_env; - while (env != NULL) - { - if (env == global_env && ! test_global) - { + while (env != NULL) { + if (env == global_env && !test_global) { break; } - + var_table_t::const_iterator result = env->env.find(key); - if (result != env->env.end()) - { + if (result != env->env.end()) { const var_entry_t &res = result->second; return res.exportv ? test_exported : test_unexported; } @@ -1062,16 +785,13 @@ bool env_exist(const wchar_t *key, env_mode_flags_t mode) } } - if (test_universal) - { - if (! get_proc_had_barrier()) - { + if (test_universal) { + if (!get_proc_had_barrier()) { set_proc_had_barrier(true); env_universal_barrier(); } - if (uvars() && ! uvars()->get(key).missing()) - { + if (uvars() && !uvars()->get(key).missing()) { return uvars()->get_export(key) ? test_exported : test_unexported; } } @@ -1079,73 +799,54 @@ bool env_exist(const wchar_t *key, env_mode_flags_t mode) return 0; } -/** - Returns true if the specified scope or any non-shadowed non-global subscopes contain an exported variable. -*/ -static int local_scope_exports(env_node_t *n) -{ +/// Returns true if the specified scope or any non-shadowed non-global subscopes contain an exported +/// variable. +static int local_scope_exports(env_node_t *n) { + if (n == global_env) return 0; - if (n==global_env) - return 0; + if (n->exportv) return 1; - if (n->exportv) - return 1; - - if (n->new_scope) - return 0; + if (n->new_scope) return 0; return local_scope_exports(n->next); } -void env_push(bool new_scope) -{ +void env_push(bool new_scope) { env_node_t *node = new env_node_t; node->next = top; - node->new_scope=new_scope; + node->new_scope = new_scope; - if (new_scope) - { - if (local_scope_exports(top)) - mark_changed_exported(); + if (new_scope) { + if (local_scope_exports(top)) mark_changed_exported(); } top = node; - } - -void env_pop() -{ - if (&top->env != global) - { +void env_pop() { + if (&top->env != global) { int i; int locale_changed = 0; env_node_t *killme = top; - for (i=0; locale_variable[i]; i++) - { - var_table_t::iterator result = killme->env.find(locale_variable[i]); - if (result != killme->env.end()) - { + for (i = 0; locale_variable[i]; i++) { + var_table_t::iterator result = killme->env.find(locale_variable[i]); + if (result != killme->env.end()) { locale_changed = 1; break; } } - if (killme->new_scope) - { - if (killme->exportv || local_scope_exports(killme->next)) - mark_changed_exported(); + if (killme->new_scope) { + if (killme->exportv || local_scope_exports(killme->next)) mark_changed_exported(); } top = top->next; var_table_t::iterator iter; - for (iter = killme->env.begin(); iter != killme->env.end(); ++iter) - { + for (iter = killme->env.begin(); iter != killme->env.end(); ++iter) { const var_entry_t &entry = iter->second; - if (entry.exportv) - { + if (entry.exportv) { mark_changed_exported(); break; } @@ -1153,40 +854,29 @@ void env_pop() delete killme; - if (locale_changed) - handle_locale(); + if (locale_changed) handle_locale(); - } - else - { - debug(0, - _(L"Tried to pop empty environment stack.")); + } else { + debug(0, _(L"Tried to pop empty environment stack.")); sanity_lose(); } } -/** - Function used with to insert keys of one table into a set::set -*/ -static void add_key_to_string_set(const var_table_t &envs, std::set *str_set, bool show_exported, bool show_unexported) -{ +/// Function used with to insert keys of one table into a set::set. +static void add_key_to_string_set(const var_table_t &envs, std::set *str_set, + bool show_exported, bool show_unexported) { var_table_t::const_iterator iter; - for (iter = envs.begin(); iter != envs.end(); ++iter) - { + for (iter = envs.begin(); iter != envs.end(); ++iter) { const var_entry_t &e = iter->second; - if ((e.exportv && show_exported) || - (!e.exportv && show_unexported)) - { - /* Insert this key */ + if ((e.exportv && show_exported) || (!e.exportv && show_unexported)) { + // Insert this key. str_set->insert(iter->first); } - } } -wcstring_list_t env_get_names(int flags) -{ +wcstring_list_t env_get_names(int flags) { scoped_lock lock(env_lock); wcstring_list_t result; @@ -1195,42 +885,34 @@ wcstring_list_t env_get_names(int flags) int show_global = flags & ENV_GLOBAL; int show_universal = flags & ENV_UNIVERSAL; - env_node_t *n=top; + env_node_t *n = top; const bool show_exported = (flags & ENV_EXPORT) || !(flags & ENV_UNEXPORT); const bool show_unexported = (flags & ENV_UNEXPORT) || !(flags & ENV_EXPORT); - if (!show_local && !show_global && !show_universal) - { - show_local =show_universal = show_global=1; + if (!show_local && !show_global && !show_universal) { + show_local = show_universal = show_global = 1; } - if (show_local) - { - while (n) - { - if (n == global_env) - break; + if (show_local) { + while (n) { + if (n == global_env) break; add_key_to_string_set(n->env, &names, show_exported, show_unexported); if (n->new_scope) break; else n = n->next; - } } - if (show_global) - { + if (show_global) { add_key_to_string_set(global_env->env, &names, show_exported, show_unexported); - if (show_unexported) - { + if (show_unexported) { result.insert(result.end(), env_electric.begin(), env_electric.end()); } } - if (show_universal && uvars()) - { + if (show_universal && uvars()) { const wcstring_list_t uni_list = uvars()->get_names(show_exported, show_unexported); names.insert(uni_list.begin(), uni_list.end()); } @@ -1239,14 +921,9 @@ wcstring_list_t env_get_names(int flags) return result; } -/** - Get list of all exported variables -*/ - -static void get_exported(const env_node_t *n, std::map *h) -{ - if (!n) - return; +/// Get list of all exported variables. +static void get_exported(const env_node_t *n, std::map *h) { + if (!n) return; if (n->new_scope) get_exported(global_env, h); @@ -1254,86 +931,73 @@ static void get_exported(const env_node_t *n, std::map *h) get_exported(n->next, h); var_table_t::const_iterator iter; - for (iter = n->env.begin(); iter != n->env.end(); ++iter) - { + for (iter = n->env.begin(); iter != n->env.end(); ++iter) { const wcstring &key = iter->first; const var_entry_t &val_entry = iter->second; - if (val_entry.exportv && val_entry.val != ENV_NULL) - { - // Export the variable - // Don't use std::map::insert here, since we need to overwrite existing - // values from previous scopes + if (val_entry.exportv && val_entry.val != ENV_NULL) { + // Export the variable. Don't use std::map::insert here, since we need to overwrite + // existing values from previous scopes. (*h)[key] = val_entry.val; - } - else - { - // We need to erase from the map if we are not exporting, - // since a lower scope may have exported. See #2132 + } else { + // We need to erase from the map if we are not exporting, since a lower scope may have + // exported. See #2132. h->erase(key); } } } -/* Given a map from key to value, add values to out of the form key=value */ -static void export_func(const std::map &envs, std::vector &out) -{ +// Given a map from key to value, add values to out of the form key=value. +static void export_func(const std::map &envs, std::vector &out) { out.reserve(out.size() + envs.size()); std::map::const_iterator iter; - for (iter = envs.begin(); iter != envs.end(); ++iter) - { + for (iter = envs.begin(); iter != envs.end(); ++iter) { const wcstring &key = iter->first; const std::string &ks = wcs2string(key); std::string vs = wcs2string(iter->second); - /* Arrays in the value are ASCII record separator (0x1e) delimited. But some variables should have colons. Add those. */ - if (variable_is_colon_delimited_array(key)) - { - /* Replace ARRAY_SEP with colon */ + // Arrays in the value are ASCII record separator (0x1e) delimited. But some variables + // should have colons. Add those. + if (variable_is_colon_delimited_array(key)) { + // Replace ARRAY_SEP with colon. std::replace(vs.begin(), vs.end(), (char)ARRAY_SEP, ':'); } - /* Put a string on the vector */ + // Put a string on the vector. out.push_back(std::string()); std::string &str = out.back(); str.reserve(ks.size() + 1 + vs.size()); - /* Append our environment variable data to it */ + // Append our environment variable data to it. str.append(ks); str.append("="); str.append(vs); } } -static void update_export_array_if_necessary(bool recalc) -{ +static void update_export_array_if_necessary(bool recalc) { ASSERT_IS_MAIN_THREAD(); - if (recalc && ! get_proc_had_barrier()) - { + if (recalc && !get_proc_had_barrier()) { set_proc_had_barrier(true); env_universal_barrier(); } - if (has_changed_exported) - { + if (has_changed_exported) { std::map vals; debug(4, L"env_export_arr() recalc"); get_exported(top, &vals); - if (uvars()) - { + if (uvars()) { const wcstring_list_t uni = uvars()->get_names(true, false); - for (size_t i=0; iget(key); - if (! val.missing() && val != ENV_NULL) - { + if (!val.missing() && val != ENV_NULL) { // Note that std::map::insert does NOT overwrite a value already in the map, - // which we depend on here + // which we depend on here. vals.insert(std::pair(key, val)); } } @@ -1342,107 +1006,83 @@ static void update_export_array_if_necessary(bool recalc) std::vector local_export_buffer; export_func(vals, local_export_buffer); export_array.set(local_export_buffer); - has_changed_exported=false; + has_changed_exported = false; } - } -const char * const *env_export_arr(bool recalc) -{ +const char *const *env_export_arr(bool recalc) { ASSERT_IS_MAIN_THREAD(); update_export_array_if_necessary(recalc); return export_array.get(); } -void env_set_argv(const wchar_t * const * argv) -{ - if (*argv) - { - const wchar_t * const *arg; +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) - { + 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 - { + } else { env_set(L"argv", 0, ENV_LOCAL); } } -env_vars_snapshot_t::env_vars_snapshot_t(const wchar_t * const *keys) -{ +env_vars_snapshot_t::env_vars_snapshot_t(const wchar_t *const *keys) { ASSERT_IS_MAIN_THREAD(); wcstring key; - for (size_t i=0; keys[i]; i++) - { + for (size_t i = 0; keys[i]; i++) { key.assign(keys[i]); const env_var_t val = env_get_string(key); - if (! val.missing()) - { + if (!val.missing()) { vars[key] = val; } } } - -void env_universal_barrier() -{ +void env_universal_barrier() { ASSERT_IS_MAIN_THREAD(); - if (uvars()) - { + if (uvars()) { callback_data_list_t changes; bool changed = uvars()->sync(&changes); - if (changed) - { + if (changed) { universal_notifier_t::default_notifier().post_notification(); } - - /* Post callbacks */ - for (size_t i=0; i < changes.size(); i++) - { + + // Post callbacks. + for (size_t i = 0; i < changes.size(); i++) { const callback_data_t &data = changes.at(i); universal_callback(data.type, data.key.c_str(), data.val.c_str()); } } } -env_vars_snapshot_t::env_vars_snapshot_t() { } +env_vars_snapshot_t::env_vars_snapshot_t() {} -/* The "current" variables are not a snapshot at all, but instead trampoline to env_get_string, etc. We identify the current snapshot based on pointer values. */ +// The "current" variables are not a snapshot at all, but instead trampoline to env_get_string, etc. +// We identify the current snapshot based on pointer values. static const env_vars_snapshot_t sCurrentSnapshot; -const env_vars_snapshot_t &env_vars_snapshot_t::current() -{ - return sCurrentSnapshot; -} +const env_vars_snapshot_t &env_vars_snapshot_t::current() { return sCurrentSnapshot; } -bool env_vars_snapshot_t::is_current() const -{ - return this == &sCurrentSnapshot; -} +bool env_vars_snapshot_t::is_current() const { return this == &sCurrentSnapshot; } -env_var_t env_vars_snapshot_t::get(const wcstring &key) const -{ - /* If we represent the current state, bounce to env_get_string */ - if (this->is_current()) - { +env_var_t env_vars_snapshot_t::get(const wcstring &key) const { + // If we represent the current state, bounce to env_get_string. + if (this->is_current()) { return env_get_string(key); - } - else - { + } else { std::map::const_iterator iter = vars.find(key); return (iter == vars.end() ? env_var_t::missing_var() : env_var_t(iter->second)); } } -const wchar_t * const env_vars_snapshot_t::highlighting_keys[] = {L"PATH", L"CDPATH", L"fish_function_path", NULL}; +const wchar_t *const env_vars_snapshot_t::highlighting_keys[] = {L"PATH", L"CDPATH", + L"fish_function_path", NULL}; -const wchar_t * const env_vars_snapshot_t::completing_keys[] = {L"PATH", L"CDPATH", NULL}; +const wchar_t *const env_vars_snapshot_t::completing_keys[] = {L"PATH", L"CDPATH", NULL}; diff --git a/src/env.h b/src/env.h index 4b14d548c..682cf88d3 100644 --- a/src/env.h +++ b/src/env.h @@ -1,250 +1,196 @@ -/** \file env.h - Prototypes for functions for setting and getting environment variables. -*/ +// Prototypes for functions for setting and getting environment variables. #ifndef FISH_ENV_H #define FISH_ENV_H -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include #include "common.h" -/* Flags that may be passed as the 'mode' in env_set / env_get_string */ -enum -{ - /* Default mode */ +// Flags that may be passed as the 'mode' in env_set / env_get_string. +enum { + /// Default mode. ENV_DEFAULT = 0, - - /** Flag for local (to the current block) variable */ + + /// Flag for local (to the current block) variable. ENV_LOCAL = 1, - - /** Flag for exported (to commands) variable */ + + /// Flag for exported (to commands) variable. ENV_EXPORT = 2, - - /** Flag for unexported variable */ + + /// Flag for unexported variable. ENV_UNEXPORT = 16, - - /** Flag for global variable */ + + /// Flag for global variable. ENV_GLOBAL = 4, - - /** Flag for variable update request from the user. All variable - changes that are made directly by the user, such as those from the - 'set' builtin must have this flag set. */ + + /// Flag for variable update request from the user. All variable changes that are made directly + /// by the user, such as those from the 'set' builtin must have this flag set. ENV_USER = 8, - - /** Flag for universal variable */ + + /// Flag for universal variable. ENV_UNIVERSAL = 32 }; typedef uint32_t env_mode_flags_t; -/** - Error code for trying to alter read-only variable -*/ -enum -{ - ENV_PERM = 1, - ENV_SCOPE, - ENV_INVALID -} -; +/// Error code for trying to alter read-only variable. +enum { ENV_PERM = 1, ENV_SCOPE, ENV_INVALID }; -/* A struct of configuration directories, determined in main() that fish will optionally pass to env_init. - */ -struct config_paths_t -{ - wcstring data; // e.g. /usr/local/share - wcstring sysconf; // e.g. /usr/local/etc - wcstring doc; // e.g. /usr/local/share/doc/fish - wcstring bin; // e.g. /usr/local/bin +/// A struct of configuration directories, determined in main() that fish will optionally pass to +/// env_init. +struct config_paths_t { + wcstring data; // e.g. /usr/local/share + wcstring sysconf; // e.g. /usr/local/etc + wcstring doc; // e.g. /usr/local/share/doc/fish + wcstring bin; // e.g. /usr/local/bin }; -/** - Initialize environment variable data -*/ +/// Initialize environment variable data. void env_init(const struct config_paths_t *paths = NULL); -/** - Set the value of the environment variable whose name matches key to val. - - Memory policy: All keys and values are copied, the parameters can and should be freed by the caller afterwards - - \param key The key - \param val The value - \param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed. - - \returns 0 on suicess or an error code on failiure. - - The current error codes are: - - * ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that the user tried to change a read-only variable. - * ENV_SCOPE, the variable cannot be set in the given scope. This applies to readonly/electric variables set from the local or universal scopes, or set as exported. - * ENV_INVALID, the variable value was invalid. This applies only to special variables. -*/ - +/// Set the value of the environment variable whose name matches key to val. +/// +/// Memory policy: All keys and values are copied, the parameters can and should be freed by the +/// caller afterwards +/// +/// \param key The key +/// \param val The value +/// \param mode The type of the variable. Can be any combination of ENV_GLOBAL, ENV_LOCAL, +/// ENV_EXPORT and ENV_USER. If mode is zero, the current variable space is searched and the current +/// mode is used. If no current variable with the same name is found, ENV_LOCAL is assumed. +/// +/// \returns 0 on success or an error code on failiure. +/// +/// The current error codes are: +/// +/// * ENV_PERM, can only be returned when setting as a user, e.g. ENV_USER is set. This means that +/// the user tried to change a read-only variable. +/// * ENV_SCOPE, the variable cannot be set in the given scope. This applies to readonly/electric +/// variables set from the local or universal scopes, or set as exported. +/// * ENV_INVALID, the variable value was invalid. This applies only to special variables. int env_set(const wcstring &key, const wchar_t *val, env_mode_flags_t mode); - -/** - Return the value of the variable with the specified name. Returns 0 - if the key does not exist. The returned string should not be - modified or freed. The returned string is only guaranteed to be - valid until the next call to env_get(), env_set(), env_push() or - env_pop() takes place. -*/ -//const wchar_t *env_get( const wchar_t *key ); - -class env_var_t : public wcstring -{ -private: +class env_var_t : public wcstring { + private: bool is_missing; -public: - static env_var_t missing_var() - { + + public: + static env_var_t missing_var() { env_var_t result((wcstring())); result.is_missing = true; return result; } - env_var_t(const env_var_t &x) : wcstring(x), is_missing(x.is_missing) { } - env_var_t(const wcstring & x) : wcstring(x), is_missing(false) { } - env_var_t(const wchar_t *x) : wcstring(x), is_missing(false) { } - env_var_t() : wcstring(L""), is_missing(false) { } + env_var_t(const env_var_t &x) : wcstring(x), is_missing(x.is_missing) {} + env_var_t(const wcstring &x) : wcstring(x), is_missing(false) {} + env_var_t(const wchar_t *x) : wcstring(x), is_missing(false) {} + env_var_t() : wcstring(L""), is_missing(false) {} - bool missing(void) const - { - return is_missing; - } + bool missing(void) const { return is_missing; } - bool missing_or_empty(void) const - { - return missing() || empty(); - } + bool missing_or_empty(void) const { return missing() || empty(); } const wchar_t *c_str(void) const; - env_var_t &operator=(const env_var_t &s) - { + env_var_t &operator=(const env_var_t &s) { is_missing = s.is_missing; wcstring::operator=(s); return *this; } - bool operator==(const env_var_t &s) const - { - return is_missing == s.is_missing && static_cast(*this) == static_cast(s); + bool operator==(const env_var_t &s) const { + return is_missing == s.is_missing && + static_cast(*this) == static_cast(s); } - bool operator==(const wcstring &s) const - { - return ! is_missing && static_cast(*this) == s; + bool operator==(const wcstring &s) const { + return !is_missing && static_cast(*this) == s; } - bool operator!=(const env_var_t &s) const - { - return !(*this == s); + bool operator!=(const env_var_t &s) const { return !(*this == s); } + + bool operator!=(const wcstring &s) const { return !(*this == s); } + + bool operator==(const wchar_t *s) const { + return !is_missing && static_cast(*this) == s; } - bool operator!=(const wcstring &s) const - { - return !(*this == s); - } - - bool operator==(const wchar_t *s) const - { - return ! is_missing && static_cast(*this) == s; - } - - bool operator!=(const wchar_t *s) const - { - return !(*this == s); - } - - + bool operator!=(const wchar_t *s) const { return !(*this == s); } }; -/** - Gets the variable with the specified name, or env_var_t::missing_var if it does not exist or is an empty array. - - \param key The name of the variable to get - \param mode An optional scope to search in. All scopes are searched if unset -*/ +/// Gets the variable with the specified name, or env_var_t::missing_var if it does not exist or is +/// an empty array. +/// +/// \param key The name of the variable to get +/// \param mode An optional scope to search in. All scopes are searched if unset env_var_t env_get_string(const wcstring &key, env_mode_flags_t mode = ENV_DEFAULT); -/** - Returns true if the specified key exists. This can't be reliably done - using env_get, since env_get returns null for 0-element arrays - - \param key The name of the variable to remove - \param mode the scope to search in. All scopes are searched if set to default -*/ +/// Returns true if the specified key exists. This can't be reliably done using env_get, since +/// env_get returns null for 0-element arrays. +/// +/// \param key The name of the variable to remove +/// \param mode the scope to search in. All scopes are searched if set to default bool env_exist(const wchar_t *key, env_mode_flags_t mode); -/** - Remove environemnt variable - - \param key The name of the variable to remove - \param mode should be ENV_USER if this is a remove request from the user, 0 otherwise. If this is a user request, read-only variables can not be removed. The mode may also specify the scope of the variable that should be erased. - - \return zero if the variable existed, and non-zero if the variable did not exist -*/ +/// Remove environment variable. +/// +/// \param key The name of the variable to remove +/// \param mode should be ENV_USER if this is a remove request from the user, 0 otherwise. If this +/// is a user request, read-only variables can not be removed. The mode may also specify the scope +/// of the variable that should be erased. +/// +/// \return zero if the variable existed, and non-zero if the variable did not exist int env_remove(const wcstring &key, int mode); -/** - Push the variable stack. Used for implementing local variables for functions and for-loops. -*/ +/// Push the variable stack. Used for implementing local variables for functions and for-loops. void env_push(bool new_scope); -/** - Pop the variable stack. Used for implementing local variables for functions and for-loops. -*/ +/// Pop the variable stack. Used for implementing local variables for functions and for-loops. void env_pop(); -/** Synchronizes all universal variable changes: writes everything out, reads stuff in */ +/// Synchronizes all universal variable changes: writes everything out, reads stuff in. 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); +/// 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); +/// Sets up argv as the given null terminated array of strings. +void env_set_argv(const wchar_t *const *argv); -/** - Returns all variable names. -*/ +/// Returns all variable names. wcstring_list_t env_get_names(int flags); -/** Update the PWD variable directory */ +/// Update the PWD variable directory. int env_set_pwd(); -/* Returns the PWD with a terminating slash */ +/// Returns the PWD with a terminating slash. wcstring env_get_pwd_slash(); -class env_vars_snapshot_t -{ +class env_vars_snapshot_t { std::map vars; bool is_current() const; - - env_vars_snapshot_t(const env_vars_snapshot_t&); + + env_vars_snapshot_t(const env_vars_snapshot_t &); void operator=(const env_vars_snapshot_t &); - -public: - env_vars_snapshot_t(const wchar_t * const * keys); + + public: + env_vars_snapshot_t(const wchar_t *const *keys); env_vars_snapshot_t(); env_var_t get(const wcstring &key) const; - // Returns the fake snapshot representing the live variables array + // Returns the fake snapshot representing the live variables array. static const env_vars_snapshot_t ¤t(); - // vars necessary for highlighting - static const wchar_t * const highlighting_keys[]; - - // vars necessary for completion - static const wchar_t * const completing_keys[]; + // Vars necessary for highlighting. + static const wchar_t *const highlighting_keys[]; + + // Vars necessary for completion. + static const wchar_t *const completing_keys[]; }; extern bool g_log_forks; @@ -252,18 +198,13 @@ extern int g_fork_count; extern bool g_use_posix_spawn; -/** - A variable entry. Stores the value of a variable and whether it - should be exported. - */ -struct var_entry_t -{ - wcstring val; /**< The value of the variable */ - bool exportv; /**< Whether the variable should be exported */ - - var_entry_t() : exportv(false) { } +/// A variable entry. Stores the value of a variable and whether it should be exported. +struct var_entry_t { + wcstring val; // the value of the variable + bool exportv; // whether the variable should be exported + + var_entry_t() : exportv(false) {} }; typedef std::map var_table_t; - #endif