diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2013-01-19 13:16:21 -0800 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2013-01-19 13:32:06 -0800 |
commit | e07de09460a81fcf020ff989041ec2116992c02f (patch) | |
tree | 74686a9e53c7fbe168b2ced427d8fa7f4f284199 /env.cpp | |
parent | 98a17f4046f8098d04727f9cb1891d15a27ba13f (diff) |
Big cleanup of env_set. Changed var_table_t to use direct var_entry_t instead of pointers. Changed some ints to bools.
Diffstat (limited to 'env.cpp')
-rw-r--r-- | env.cpp | 344 |
1 files changed, 150 insertions, 194 deletions
@@ -97,7 +97,7 @@ struct var_entry_t var_entry_t() : exportv(false) { } }; -typedef std::map<wcstring, var_entry_t*> var_table_t; +typedef std::map<wcstring, var_entry_t> var_table_t; bool g_log_forks = false; bool g_use_posix_spawn = false; //will usually be set to true @@ -122,7 +122,7 @@ struct env_node_t /** Does this node contain any variables which are exported to subshells */ - int exportv; + bool exportv; /** Pointer to next level @@ -130,7 +130,7 @@ struct env_node_t struct env_node_t *next; - env_node_t() : new_scope(0), exportv(0), next(NULL) { } + env_node_t() : new_scope(0), exportv(false), next(NULL) { } }; class variable_entry_t @@ -201,17 +201,6 @@ static void mark_changed_exported() static wcstring dyn_var; /** - Variable used by env_get_names to communicate auxiliary information - to add_key_to_string_set -*/ -static int get_names_show_exported; -/** - Variable used by env_get_names to communicate auxiliary information - to add_key_to_string_set -*/ -static int get_names_show_unexported; - -/** List of all locale variable names */ static const wchar_t * const locale_variable[] = @@ -678,7 +667,7 @@ void env_init(const struct config_paths_t *paths /* or NULL */) long shlvl_i = wcstol(shlvl_str.c_str(), NULL, 10); if (shlvl_i >= 0) { - nshlvl_str = format_string(L"%ld", 1 + shlvl_i); + nshlvl_str = to_string<long>(shlvl_i + 1); } } env_set(L"SHLVL", nshlvl_str.c_str(), ENV_GLOBAL | ENV_EXPORT); @@ -707,17 +696,15 @@ void env_destroy() env_read_only.clear(); env_electric.clear(); - var_table_t::iterator iter; for (iter = global->begin(); iter != global->end(); ++iter) { - var_entry_t *entry = iter->second; - if (entry->exportv) + const var_entry_t &entry = iter->second; + if (entry.exportv) { mark_changed_exported(); + break; } - - delete entry; } delete top; @@ -752,14 +739,12 @@ static env_node_t *env_get_node(const wcstring &key) int env_set(const wcstring &key, const wchar_t *val, int var_mode) { ASSERT_IS_MAIN_THREAD(); - env_node_t *node = NULL; bool has_changed_old = has_changed_exported; bool has_changed_new = false; - var_entry_t *e=0; int done=0; - + int is_universal = 0; - + if (val && contains(key, L"PWD", L"HOME")) { /* Canoncalize our path; if it changes, recurse and try again. */ @@ -770,204 +755,190 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode) return env_set(key, val_canonical.c_str(), var_mode); } } - + if ((var_mode & ENV_USER) && is_read_only(key)) { return ENV_PERM; } - + if (key == L"umask") { wchar_t *end; - + /* - Set the new umask - */ + Set the new umask + */ if (val && wcslen(val)) { errno=0; long mask = wcstol(val, &end, 8); - + 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; } - + /* - Zero element arrays are internaly not coded as null but as this - placeholder string - */ + Zero element arrays are internaly not coded as null but as this + placeholder string + */ if (!val) { val = ENV_NULL; } - + if (var_mode & ENV_UNIVERSAL) { - int exportv; - - if (!(var_mode & ENV_EXPORT) && - !(var_mode & ENV_UNEXPORT)) + bool exportv; + if (var_mode & ENV_EXPORT) { - exportv = env_universal_get_export(key); + // export + exportv = true; + } + else if (var_mode & ENV_UNEXPORT) + { + // unexport + exportv = false; } else { - exportv = (var_mode & ENV_EXPORT); + // not changing the export + exportv = env_universal_get_export(key); } - env_universal_set(key, val, exportv); is_universal = 1; - + } else { - - node = env_get_node(key); - if (node) + // Determine the node + + env_node_t *preexisting_node = env_get_node(key); + bool preexisting_entry_exportv = false; + if (preexisting_node != NULL) { - var_table_t::iterator result = node->env.find(key); - assert(result != node->env.end()); - e = result->second; - - if (e->exportv) + 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) { + preexisting_entry_exportv = true; has_changed_new = true; } } - - if ((var_mode & ENV_LOCAL) || - (var_mode & ENV_GLOBAL)) + + env_node_t *node = NULL; + if (var_mode & ENV_GLOBAL) + { + node = global_env; + } + else if (var_mode & ENV_LOCAL) + { + node = top; + } + else if (preexisting_node != NULL) { - node = (var_mode & ENV_GLOBAL)?global_env:top; + node = preexisting_node; + + if ((var_mode & (ENV_EXPORT | ENV_UNEXPORT)) == 0) + { + // use existing entry's exportv + var_mode = preexisting_entry_exportv ? ENV_EXPORT : 0; + } } else { - if (node) + if (! get_proc_had_barrier()) { - if (!(var_mode & ENV_EXPORT) && - !(var_mode & ENV_UNEXPORT)) - { - var_mode = e->exportv?ENV_EXPORT:0; - } + set_proc_had_barrier(true); + env_universal_barrier(); } - else + + if (env_universal_get(key)) { - if (! get_proc_had_barrier()) + bool exportv; + if (var_mode & ENV_EXPORT) { - set_proc_had_barrier(true); - env_universal_barrier(); + exportv = true; } - - if (env_universal_get(key)) + else if (var_mode & ENV_UNEXPORT) { - int exportv; - - if (!(var_mode & ENV_EXPORT) && - !(var_mode & ENV_UNEXPORT)) - { - exportv = env_universal_get_export(key); - } - else - { - exportv = (var_mode & ENV_EXPORT); - } - - env_universal_set(key, val, exportv); - is_universal = 1; - - done = 1; - + exportv = false; } 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) - { - node = node->next; - } + exportv = env_universal_get_export(key); + } + + env_universal_set(key, val, exportv); + is_universal = 1; + + 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. + */ + node = top; + while (node->next && !node->new_scope) + { + node = node->next; } } } - + if (!done) { - var_entry_t *old_entry = NULL; - var_table_t::iterator result = node->env.find(key); - if (result != node->env.end()) + // 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) { - old_entry = result->second; - node->env.erase(result); + // this variable already existed, and was exported + has_changed_new = true; } - - var_entry_t *entry = NULL; - if (old_entry) + entry.val = val; + if (var_mode & ENV_EXPORT) { - entry = old_entry; - - if ((var_mode & ENV_EXPORT) || entry->exportv) - { - entry->exportv = !!(var_mode & ENV_EXPORT); - has_changed_new = true; - } + // the new variable is exported + entry.exportv = true; + node->exportv = true; + has_changed_new = true; } else { - entry = new var_entry_t; - - if (var_mode & ENV_EXPORT) - { - entry->exportv = 1; - has_changed_new = true; - } - else - { - entry->exportv = 0; - } - - } - - entry->val = val; - node->env[key] = entry; - - if (entry->exportv) - { - node->exportv=1; + entry.exportv = false; } - + if (has_changed_old || has_changed_new) mark_changed_exported(); } - + } - + if (!is_universal) { event_t ev = event_t::variable_event(key); ev.arguments.push_back(L"VARIABLE"); ev.arguments.push_back(L"SET"); ev.arguments.push_back(key); - + // debug( 1, L"env_set: fire events on variable %ls", key ); event_fire(&ev); // debug( 1, L"env_set: return from event firing" ); } - + react_to_variable_change(key); - + return 0; } @@ -978,33 +949,27 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode) \return zero if the variable was not found, non-zero otherwise */ -static int try_remove(env_node_t *n, - const wchar_t *key, - int var_mode) +static bool try_remove(env_node_t *n, const wchar_t *key, int var_mode) { - if (n == 0) + if (n == NULL) { - return 0; + return false; } var_table_t::iterator result = n->env.find(key); if (result != n->env.end()) { - var_entry_t *v = result->second; - - if (v->exportv) + if (result->second.exportv) { mark_changed_exported(); } - n->env.erase(result); - delete v; - return 1; + return true; } if (var_mode & ENV_LOCAL) { - return 0; + return false; } if (n->new_scope) @@ -1116,7 +1081,6 @@ env_var_t env_get_string(const wcstring &key) /* Lock around a local region */ scoped_lock lock(env_lock); - var_entry_t *res = NULL; env_node_t *env = top; wcstring result; @@ -1124,18 +1088,15 @@ env_var_t env_get_string(const wcstring &key) { var_table_t::iterator result = env->env.find(key); if (result != env->env.end()) - res = result->second; - - - if (res != NULL) { - if (res->val == ENV_NULL) + const var_entry_t &res = result->second; + if (res.val == ENV_NULL) { return env_var_t::missing_var(); } else { - return res->val; + return res.val; } } @@ -1171,13 +1132,12 @@ env_var_t env_get_string(const wcstring &key) } } -int env_exist(const wchar_t *key, int mode) +bool env_exist(const wchar_t *key, int mode) { - var_entry_t *res; env_node_t *env; wchar_t *item=0; - CHECK(key, 0); + CHECK(key, false); /* Read only variables all exist, and they are all global. A local @@ -1190,13 +1150,13 @@ int env_exist(const wchar_t *key, int mode) //Such variables are never exported if (mode & ENV_EXPORT) { - return 0; + return false; } else if (mode & ENV_UNEXPORT) { - return 1; + return true; } - return 1; + return true; } } @@ -1210,18 +1170,18 @@ int env_exist(const wchar_t *key, int mode) if (result != env->env.end()) { - res = result->second; + const var_entry_t &res = result->second; if (mode & ENV_EXPORT) { - return res->exportv == 1; + return res.exportv; } else if (mode & ENV_UNEXPORT) { - return res->exportv == 0; + return ! res.exportv; } - return 1; + return true; } if (mode & ENV_LOCAL) @@ -1330,12 +1290,12 @@ void env_pop() var_table_t::iterator iter; for (iter = killme->env.begin(); iter != killme->env.end(); ++iter) { - var_entry_t *entry = iter->second; - if (entry->exportv) + const var_entry_t &entry = iter->second; + if (entry.exportv) { mark_changed_exported(); + break; } - delete entry; } delete killme; @@ -1355,18 +1315,18 @@ void env_pop() /** Function used with to insert keys of one table into a set::set<wcstring> */ -static void add_key_to_string_set(const var_table_t &envs, std::set<wcstring> &strSet) +static void add_key_to_string_set(const var_table_t &envs, std::set<wcstring> *str_set, bool show_exported, bool show_unexported) { var_table_t::const_iterator iter; for (iter = envs.begin(); iter != envs.end(); ++iter) { - var_entry_t *e = iter->second; + const var_entry_t &e = iter->second; - if ((e->exportv && get_names_show_exported) || - (!e->exportv && get_names_show_unexported)) + if ((e.exportv && show_exported) || + (!e.exportv && show_unexported)) { - /*Insert Key*/ - strSet.insert(iter->first); + /* Insert this key */ + str_set->insert(iter->first); } } @@ -1383,12 +1343,8 @@ wcstring_list_t env_get_names(int flags) int show_universal = flags & ENV_UNIVERSAL; env_node_t *n=top; - - - get_names_show_exported = - (flags & ENV_EXPORT) || !(flags & ENV_UNEXPORT); - get_names_show_unexported = - (flags & ENV_UNEXPORT) || !(flags & ENV_EXPORT); + 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) { @@ -1402,7 +1358,7 @@ wcstring_list_t env_get_names(int flags) if (n == global_env) break; - add_key_to_string_set(n->env, names); + add_key_to_string_set(n->env, &names, show_exported, show_unexported); if (n->new_scope) break; else @@ -1413,13 +1369,13 @@ wcstring_list_t env_get_names(int flags) if (show_global) { - add_key_to_string_set(global_env->env, names); - if (get_names_show_unexported) + add_key_to_string_set(global_env->env, &names, show_exported, show_unexported); + if (show_unexported) { result.insert(result.end(), env_electric.begin(), env_electric.end()); } - if (get_names_show_exported) + if (show_exported) { result.push_back(L"COLUMNS"); result.push_back(L"LINES"); @@ -1432,8 +1388,8 @@ wcstring_list_t env_get_names(int flags) wcstring_list_t uni_list; env_universal_get_names2(uni_list, - get_names_show_exported, - get_names_show_unexported); + show_exported, + show_unexported); names.insert(uni_list.begin(), uni_list.end()); } @@ -1459,11 +1415,11 @@ static void get_exported(const env_node_t *n, std::map<wcstring, wcstring> &h) for (iter = n->env.begin(); iter != n->env.end(); ++iter) { const wcstring &key = iter->first; - var_entry_t *val_entry = iter->second; - if (val_entry->exportv && (val_entry->val != ENV_NULL)) + const var_entry_t &val_entry = iter->second; + if (val_entry.exportv && (val_entry.val != ENV_NULL)) { // Don't use std::map::insert here, since we need to overwrite existing values from previous scopes - h[key] = val_entry->val; + h[key] = val_entry.val; } } } |