mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #14579 from jamessan/windows-env-vars
Deduplicate env var names on Windows
This commit is contained in:
commit
216bfa1d6b
@ -1850,15 +1850,30 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
|||||||
ptrdiff_t len = end - str;
|
ptrdiff_t len = end - str;
|
||||||
assert(len > 0);
|
assert(len > 0);
|
||||||
const char * value = str + len + 1;
|
const char * value = str + len + 1;
|
||||||
if (tv_dict_find(rettv->vval.v_dict, str, len) != NULL) {
|
|
||||||
|
char c = env[i][len];
|
||||||
|
env[i][len] = NUL;
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
// Upper-case all the keys for Windows so we can detect duplicates
|
||||||
|
char *const key = strcase_save(str, true);
|
||||||
|
#else
|
||||||
|
char *const key = xstrdup(str);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
env[i][len] = c;
|
||||||
|
|
||||||
|
if (tv_dict_find(rettv->vval.v_dict, key, len) != NULL) {
|
||||||
// Since we're traversing from the end of the env block to the front, any
|
// Since we're traversing from the end of the env block to the front, any
|
||||||
// duplicate names encountered should be ignored. This preserves the
|
// duplicate names encountered should be ignored. This preserves the
|
||||||
// semantics of env vars defined later in the env block taking precedence.
|
// semantics of env vars defined later in the env block taking precedence.
|
||||||
|
xfree(key);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tv_dict_add_str(rettv->vval.v_dict,
|
tv_dict_add_str(rettv->vval.v_dict,
|
||||||
str, len,
|
key, len,
|
||||||
value);
|
value);
|
||||||
|
xfree(key);
|
||||||
}
|
}
|
||||||
os_free_fullenv(env);
|
os_free_fullenv(env);
|
||||||
}
|
}
|
||||||
@ -5096,7 +5111,21 @@ static dict_T *create_environment(const dictitem_T *job_env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (job_env) {
|
if (job_env) {
|
||||||
|
#ifdef WIN32
|
||||||
|
TV_DICT_ITER(job_env->di_tv.vval.v_dict, var, {
|
||||||
|
// Always use upper-case keys for Windows so we detect duplicate keys
|
||||||
|
char *const key = strcase_save((const char *)var->di_key, true);
|
||||||
|
size_t len = strlen(key);
|
||||||
|
dictitem_T *dv = tv_dict_find(env, key, len);
|
||||||
|
if (dv) {
|
||||||
|
tv_dict_item_remove(env, dv);
|
||||||
|
}
|
||||||
|
tv_dict_add_str(env, key, len, tv_get_string(&var->di_tv));
|
||||||
|
xfree(key);
|
||||||
|
});
|
||||||
|
#else
|
||||||
tv_dict_extend(env, job_env->di_tv.vval.v_dict, "force");
|
tv_dict_extend(env, job_env->di_tv.vval.v_dict, "force");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pty) {
|
if (pty) {
|
||||||
|
@ -118,6 +118,32 @@ describe('jobs', function()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('handles case-insensitively matching #env vars', function()
|
||||||
|
nvim('command', "let $TOTO = 'abc'")
|
||||||
|
-- Since $Toto is being set in the job, it should take precedence over the
|
||||||
|
-- global $TOTO on Windows
|
||||||
|
nvim('command', "let g:job_opts = {'env': {'Toto': 'def'}, 'stdout_buffered': v:true}")
|
||||||
|
if iswin() then
|
||||||
|
nvim('command', [[let j = jobstart('set | find /I "toto="', g:job_opts)]])
|
||||||
|
else
|
||||||
|
nvim('command', [[let j = jobstart('env | grep -i toto=', g:job_opts)]])
|
||||||
|
end
|
||||||
|
nvim('command', "call jobwait([j])")
|
||||||
|
nvim('command', "let g:output = Normalize(g:job_opts.stdout)")
|
||||||
|
local actual = eval('g:output')
|
||||||
|
local expected
|
||||||
|
if iswin() then
|
||||||
|
-- Toto is normalized to TOTO so we can detect duplicates, and because
|
||||||
|
-- Windows doesn't care about case
|
||||||
|
expected = {'TOTO=def', ''}
|
||||||
|
else
|
||||||
|
expected = {'TOTO=abc', 'Toto=def', ''}
|
||||||
|
end
|
||||||
|
table.sort(actual)
|
||||||
|
table.sort(expected)
|
||||||
|
eq(expected, actual)
|
||||||
|
end)
|
||||||
|
|
||||||
it('uses &shell and &shellcmdflag if passed a string', function()
|
it('uses &shell and &shellcmdflag if passed a string', function()
|
||||||
nvim('command', "let $VAR = 'abc'")
|
nvim('command', "let $VAR = 'abc'")
|
||||||
if iswin() then
|
if iswin() then
|
||||||
|
Loading…
Reference in New Issue
Block a user