diff options
-rw-r--r-- | sysif.c | 61 | ||||
-rw-r--r-- | txr.1 | 66 |
2 files changed, 108 insertions, 19 deletions
@@ -148,7 +148,7 @@ static val at_exit_list; static val dirent_st; -static val env_list; +static val env_list, env_hash; static val errno_wrap(val newval) { @@ -322,20 +322,27 @@ val env(void) } } -static val env_hash(void) +static val get_env_hash(void) { - val env_strings = env(); - val hash = make_hash(nil, nil, t); + if (env_hash) { + return env_hash; + } else { + val env_strings = env(); + val hash = make_hash(nil, nil, t); + + for (; env_strings; env_strings = cdr(env_strings)) { + val estr = car(env_strings); + val eqpos = break_str(estr, lit("=")); + val key = sub(estr, 0, eqpos); + val val = sub(estr, succ(eqpos), t); + sethash(hash, key, val); + } - for (; env_strings; env_strings = cdr(env_strings)) { - val estr = car(env_strings); - val eqpos = break_str(estr, lit("=")); - val key = sub(estr, 0, eqpos); - val val = sub(estr, succ(eqpos), t); - sethash(hash, key, val); - } + if (!opt_compat || opt_compat > 244) + env_hash = hash; - return hash; + return hash; + } } val errno_to_file_error(int err) @@ -1386,20 +1393,39 @@ val getenv_wrap(val name) char *lookup = getenv(nameu8); val result = lookup ? string_utf8(lookup) : nil; free(nameu8); + if (env_hash) + sethash(env_hash, name, result); return result; } static val setenv_wrap(val name, val value, val overwrite) { + val self = lit("setenv"); const wchar_t *wname = c_str(name); const wchar_t *wvalu = value ? c_str(value) : 0; int ovw = default_arg_strict(overwrite, t) != nil; char *nameu8 = utf8_dup_to(wname); char *valu8 = wvalu ? utf8_dup_to(wvalu) : 0; - if (valu8) + if (valu8) { setenv(nameu8, valu8, ovw); - else if (ovw) + env_list = nil; + + if (env_hash) { + if (ovw) { + sethash(env_hash, name, value); + } else { + val new_p; + val cell = gethash_c(self, env_hash, name, mkcloc(new_p)); + if (new_p) + us_rplacd(cell, value); + } + } + } else if (ovw) { unsetenv(nameu8); + env_list = nil; + if (env_hash) + remhash(env_hash, name); + } free(valu8); free(nameu8); return value; @@ -1410,6 +1436,9 @@ static val unsetenv_wrap(val name) char *nameu8 = utf8_dup_to(c_str(name)); unsetenv(nameu8); free(nameu8); + env_list = nil; + if (env_hash) + remhash(env_hash, name); return name; } @@ -2389,7 +2418,7 @@ static val dirstat(val dirent, val dir_path, val stat_opt) void sysif_init(void) { - protect(&at_exit_list, dirent_st, &env_list, convert(val *, 0)); + protect(&at_exit_list, dirent_st, &env_list, &env_hash, convert(val *, 0)); atexit(at_exit_handler); @@ -2585,7 +2614,7 @@ void sysif_init(void) #endif reg_fun(intern(lit("env"), user_package), func_n0(env)); - reg_fun(intern(lit("env-hash"), user_package), func_n0(env_hash)); + reg_fun(intern(lit("env-hash"), user_package), func_n0(get_env_hash)); #if HAVE_DAEMON reg_fun(intern(lit("daemon"), user_package), func_n2(daemon_wrap)); @@ -58879,10 +58879,28 @@ function. .desc The .code env-hash -function constructs and returns an +function returns an .code :equal-based -hash. The hash is -populated with the environment variables, represented as key-value pairs. +hash whose keys and values are strings. The hash table is populated populated +with the environment variables, represented as key-value character string +pairs. + +The +.code env-hash +function allocates the hash table when it is first invoked; thereafter, +it returns the same hash table. + +The hash table is updated by the functions +.codn setenv , +.code unsetenv +and +.codn getenv . + +Note: calls to the underlying C library functions +.code setenv +and +.codn getenv , +and other direct manipulations of the environment, will not update the hash table. .coNP Functions @, getenv @ setenv and @ unsetenv .synb @@ -58989,6 +59007,43 @@ is restored by the .code unwind-protect cleanup form. +These functions interact with the list returned by the +.code env +function and with the hash table returned by the +.code env-hash +function as follows. + +A previously returned list returned by +.code env +is not modified. The +.code setenv +and +.code unsetenv +functions may cause a subsequent call to +.code env +to return a different list. The +.code getenv +function has no effect on the list. + +The hash table previously returned by +.code env-hash +is modified by +.code setenv +in the manner consistent with its semantics. A new entry is created in the table, +if required, and an existing entry is overwritten only if the +.code overwrite-p +flag is specified. Likewise, if +.code setenv +is invoked in a way that causes the environment variable to be deleted, it +is removed from the hash also. +The +.code unsetenv +function causes the variable to be removed from the hash table also. +The +.code getenv +function accesses the underlying environment, and updates the hash +table with the name-value pair which is retrieved. + .SS* Command Line Option Processing \*(TL provides a support for recognizing, extracting and validating @@ -75551,6 +75606,11 @@ of these version values, the described behaviors are provided if is given an argument which is equal or lower. For instance .code "-C 103" selects the behaviors described below for version 105, but not those for 102. +.IP 244 +Until \*(TX 244, the +.code env-hash +function returned a new hash table each time it was called. The behavior is +restored if 244 or older compatibility is selected. .IP 243 Two mistakes in the pseudo-random-number generator (PRNG) were discovered, affecting \*(TX 243 and older. Using this compatibility value, or lower, will |