Migrate global functions out of env_universal. Have env operate directly

on an env_universal_t.
This commit is contained in:
ridiculousfish
2014-06-15 17:30:50 -07:00
parent 84faa60c4e
commit 6277a2e4a4
8 changed files with 118 additions and 339 deletions

141
env.cpp
View File

@@ -50,6 +50,7 @@
#include "reader.h"
#include "parser.h"
#include "env_universal.h"
#include "env_universal_common.h"
#include "input.h"
#include "event.h"
#include "path.h"
@@ -129,6 +130,13 @@ static env_node_t *top = NULL;
/** Bottom node on the function stack */
static env_node_t *global_env = NULL;
/** 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;
}
/**
Table for global variables
@@ -331,9 +339,7 @@ static void react_to_variable_change(const wcstring &key)
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)
static void universal_callback(fish_message_type_t type, const wchar_t *name, const wchar_t *val)
{
const wchar_t *str = NULL;
@@ -554,7 +560,9 @@ void env_init(const struct config_paths_t *paths /* or NULL */)
env_set(L"version", version.c_str(), ENV_GLOBAL);
env_set(L"FISH_VERSION", version.c_str(), ENV_GLOBAL);
env_universal_init(universal_callback);
/* 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"");
/*
Set up SHLVL variable
@@ -586,32 +594,6 @@ void env_init(const struct config_paths_t *paths /* or NULL */)
env_set(FISH_BIND_MODE_VAR, DEFAULT_BIND_MODE, ENV_GLOBAL);
}
void env_destroy()
{
env_universal_destroy();
while (&top->env != global)
{
env_pop();
}
env_read_only.clear();
env_electric.clear();
var_table_t::iterator iter;
for (iter = global->begin(); iter != global->end(); ++iter)
{
const var_entry_t &entry = iter->second;
if (entry.exportv)
{
mark_changed_exported();
break;
}
}
delete top;
}
/**
Search all visible scopes in order for the specified key. Return
the first scope in which it was found.
@@ -688,23 +670,32 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
if (var_mode & ENV_UNIVERSAL)
{
bool exportv;
const bool old_export = uvars() && uvars()->get_export(key);
bool new_export;
if (var_mode & ENV_EXPORT)
{
// export
exportv = true;
new_export = true;
}
else if (var_mode & ENV_UNEXPORT)
{
// unexport
exportv = false;
new_export = false;
}
else
{
// not changing the export
exportv = env_universal_get_export(key);
new_export = old_export;
}
if (uvars())
{
uvars()->set(key, val, new_export);
env_universal_barrier();
if (old_export || new_export)
{
mark_changed_exported();
}
}
env_universal_set(key, val, exportv);
is_universal = 1;
}
@@ -753,7 +744,7 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
env_universal_barrier();
}
if (! env_universal_get(key).missing())
if (uvars() && ! uvars()->get(key).missing())
{
bool exportv;
if (var_mode & ENV_EXPORT)
@@ -766,10 +757,11 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
}
else
{
exportv = env_universal_get_export(key);
exportv = uvars()->get_export(key);
}
env_universal_set(key, val, exportv);
uvars()->set(key, val, exportv);
env_universal_barrier();
is_universal = 1;
done = 1;
@@ -817,7 +809,6 @@ int env_set(const wcstring &key, const wchar_t *val, int var_mode)
if (has_changed_old || has_changed_new)
mark_changed_exported();
}
}
if (!is_universal)
@@ -917,7 +908,7 @@ int env_remove(const wcstring &key, int var_mode)
!(var_mode & ENV_GLOBAL) &&
!(var_mode & ENV_LOCAL))
{
erased = env_universal_remove(key);
erased = uvars() && uvars()->remove(key);
}
react_to_variable_change(key);
@@ -1000,16 +991,12 @@ env_var_t env_get_string(const wcstring &key)
env_universal_barrier();
}
env_var_t item = env_universal_get(key);
if (item.missing() || (wcscmp(item.c_str(), ENV_NULL)==0))
env_var_t env_var = uvars() ? uvars()->get(key) : env_var_t::missing_var();
if (env_var == ENV_NULL)
{
return env_var_t::missing_var();
}
else
{
return item;
env_var = env_var_t::missing_var();
}
return env_var;
}
}
@@ -1079,15 +1066,15 @@ bool env_exist(const wchar_t *key, int mode)
env_universal_barrier();
}
if (! env_universal_get(key).missing())
if (uvars() && ! uvars()->get(key).missing())
{
if (mode & ENV_EXPORT)
{
return env_universal_get_export(key) == 1;
return uvars()->get_export(key);
}
else if (mode & ENV_UNEXPORT)
{
return env_universal_get_export(key) == 0;
return ! uvars()->get_export(key);
}
return 1;
@@ -1254,13 +1241,9 @@ wcstring_list_t env_get_names(int flags)
}
if (show_universal)
if (show_universal && uvars())
{
wcstring_list_t uni_list;
env_universal_get_names(uni_list,
show_exported,
show_unexported);
const wcstring_list_t uni_list = uvars()->get_names(show_exported, show_unexported);
names.insert(uni_list.begin(), uni_list.end());
}
@@ -1340,18 +1323,20 @@ static void update_export_array_if_necessary(bool recalc)
get_exported(top, vals);
wcstring_list_t uni;
env_universal_get_names(uni, 1, 0);
for (i=0; i<uni.size(); i++)
if (uvars())
{
const wcstring &key = uni.at(i);
const env_var_t val = env_universal_get(key);
if (! val.missing() && wcscmp(val.c_str(), ENV_NULL))
const wcstring_list_t uni = uvars()->get_names(true, false);
for (i=0; i<uni.size(); i++)
{
// Note that std::map::insert does NOT overwrite a value already in the map,
// which we depend on here
vals.insert(std::pair<wcstring, wcstring>(key, val));
const wcstring &key = uni.at(i);
const env_var_t val = uvars()->get(key);
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
vals.insert(std::pair<wcstring, wcstring>(key, val));
}
}
}
@@ -1385,6 +1370,28 @@ env_vars_snapshot_t::env_vars_snapshot_t(const wchar_t * const *keys)
}
}
void env_universal_barrier()
{
ASSERT_IS_MAIN_THREAD();
if (uvars())
{
callback_data_list_t changes;
bool changed = uvars()->sync(&changes);
if (changed)
{
universal_notifier_t::default_notifier().post_notification();
}
/* 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() { }
/* 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. */