From 9153062095f34ec8dcdc8862da1ab9abfe560e3f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 27 Jan 2018 12:50:10 +0100 Subject: os_setenv: use _wputenv_s; remove vestigial code #7920 _putenv_s variant was left over from 810d31a43001, should have been removed in cd5b1315757e. --- test/functional/eval/let_spec.lua | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/functional/eval/let_spec.lua b/test/functional/eval/let_spec.lua index 1bd3405698..050cff3c22 100644 --- a/test/functional/eval/let_spec.lua +++ b/test/functional/eval/let_spec.lua @@ -2,13 +2,15 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local clear = helpers.clear +local command = helpers.command +local eval = helpers.eval local meths = helpers.meths local redir_exec = helpers.redir_exec local source = helpers.source before_each(clear) -describe(':let command', function() +describe(':let', function() it('correctly lists variables with curly-braces', function() meths.set_var('v', {0}) eq('\nv [0]', redir_exec('let {"v"}')) @@ -42,4 +44,16 @@ describe(':let command', function() call feedkeys(":\e:echo l1 l3\n:echo 42\n:cq\n", "t") ]=]) end) + + it("sets environment variables", function() + local multibyte_multiline = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ + .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ + .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]] + command("let $NVIM_TEST1 = 'AìaB'") + command("let $NVIM_TEST2 = 'AaあB'") + command("let $NVIM_TEST3 = '"..multibyte_multiline.."'") + eq('AìaB', eval('$NVIM_TEST1')) + eq('AaあB', eval('$NVIM_TEST2')) + eq(multibyte_multiline, eval('$NVIM_TEST3')) + end) end) -- cgit From 1d8e7683604828592bd41cdac5a351145cd93487 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 28 Jan 2018 11:02:15 +0100 Subject: os_getenv, os_setenv: revert "widechar" impl It's reported that the Windows widechar variants do automatically convert from the current codepage to UTF16, which is very helpful. So the "widechar" impls are a good direction. But libuv v1.12 does that for us, so the next commit will use that instead. ref #8398 ref #9267 --- test/functional/eval/let_spec.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/functional/eval/let_spec.lua b/test/functional/eval/let_spec.lua index 050cff3c22..ff71daab74 100644 --- a/test/functional/eval/let_spec.lua +++ b/test/functional/eval/let_spec.lua @@ -45,15 +45,15 @@ describe(':let', function() ]=]) end) - it("sets environment variables", function() - local multibyte_multiline = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ - .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ - .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]] - command("let $NVIM_TEST1 = 'AìaB'") - command("let $NVIM_TEST2 = 'AaあB'") - command("let $NVIM_TEST3 = '"..multibyte_multiline.."'") - eq('AìaB', eval('$NVIM_TEST1')) - eq('AaあB', eval('$NVIM_TEST2')) - eq(multibyte_multiline, eval('$NVIM_TEST3')) + it("multibyte environment variables", function() + command("let $NVIM_TEST = 'AìaB'") + eq('AìaB', eval('$NVIM_TEST')) + command("let $NVIM_TEST = 'AaあB'") + eq('AaあB', eval('$NVIM_TEST')) + local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ + .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ + .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]] + command("let $NVIM_TEST = '"..mbyte.."'") + eq(mbyte, eval('$NVIM_TEST')) end) end) -- cgit From 89515304e4eb81ff9eb65f3a582136fc658de139 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 24 Feb 2019 20:09:14 +0100 Subject: os/env: use libuv v1.12 getenv/setenv API - Minimum required libuv is now v1.12 - Because `uv_os_getenv` requires allocating, we must manage a map (`envmap` in `env.c`) to maintain the old behavior of `os_getenv` . - free() map-items after removal. khash.h does not make copies of anything, so even its keys must be memory-managed by the caller. closes #8398 closes #9267 --- test/unit/helpers.lua | 12 +++---- test/unit/os/env_spec.lua | 79 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 28 deletions(-) (limited to 'test') diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua index f8143a0125..beb25f25db 100644 --- a/test/unit/helpers.lua +++ b/test/unit/helpers.lua @@ -645,16 +645,16 @@ local function itp_child(wr, func) s = s:sub(1, hook_msglen - 2) sc.write(wr, '>' .. s .. (' '):rep(hook_msglen - 2 - #s) .. '\n') end - local err, emsg = pcall(init) - if err then + local status, result = pcall(init) + if status then collectgarbage('stop') child_sethook(wr) - err, emsg = pcall(func) + status, result = pcall(func) debug.sethook() end - emsg = tostring(emsg) sc.write(wr, trace_end_msg) - if not err then + if not status then + local emsg = tostring(result) if #emsg > 99999 then emsg = emsg:sub(1, 99999) end @@ -668,7 +668,7 @@ local function itp_child(wr, func) collectgarbage() sc.write(wr, '$\n') sc.close(wr) - sc.exit(err and 0 or 1) + sc.exit(status and 0 or 1) end local function check_child_err(rd) diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua index c54d5a9b77..c543551607 100644 --- a/test/unit/os/env_spec.lua +++ b/test/unit/os/env_spec.lua @@ -8,17 +8,22 @@ local ffi = helpers.ffi local cstr = helpers.cstr local to_cstr = helpers.to_cstr local NULL = helpers.NULL +local OK = 0 require('lfs') local cimp = cimport('./src/nvim/os/os.h') describe('env.c', function() + local function os_env_exists(name) + return cimp.os_env_exists(to_cstr(name)) + end + local function os_setenv(name, value, override) return cimp.os_setenv(to_cstr(name), to_cstr(value), override) end - local function os_unsetenv(name, _, _) + local function os_unsetenv(name) return cimp.os_unsetenv(to_cstr(name)) end @@ -31,25 +36,44 @@ describe('env.c', function() end end - describe('os_setenv', function() - local OK = 0 + itp('os_env_exists', function() + eq(false, os_env_exists('')) + eq(false, os_env_exists(' ')) + eq(false, os_env_exists('\t')) + eq(false, os_env_exists('\n')) + eq(false, os_env_exists('AaあB <= very weird name...')) - itp('sets an env variable and returns OK', function() + local varname = 'NVIM_UNIT_TEST_os_env_exists' + eq(false, os_env_exists(varname)) + eq(OK, os_setenv(varname, 'foo bar baz ...', 1)) + eq(true, os_env_exists(varname)) + end) + + describe('os_setenv', function() + itp('sets an env var and returns success', function() local name = 'NVIM_UNIT_TEST_SETENV_1N' local value = 'NVIM_UNIT_TEST_SETENV_1V' eq(nil, os.getenv(name)) - eq(OK, (os_setenv(name, value, 1))) + eq(OK, os_setenv(name, value, 1)) eq(value, os.getenv(name)) + + -- Set empty, then set non-empty, then retrieve. + eq(OK, os_setenv(name, '', 1)) + eq('', os.getenv(name)) + eq(OK, os_setenv(name, 'non-empty', 1)) + eq('non-empty', os.getenv(name)) end) - itp("dosn't overwrite an env variable if overwrite is 0", function() + itp("`overwrite` behavior", function() local name = 'NVIM_UNIT_TEST_SETENV_2N' local value = 'NVIM_UNIT_TEST_SETENV_2V' local value_updated = 'NVIM_UNIT_TEST_SETENV_2V_UPDATED' - eq(OK, (os_setenv(name, value, 0))) + eq(OK, os_setenv(name, value, 0)) eq(value, os.getenv(name)) - eq(OK, (os_setenv(name, value_updated, 0))) + eq(OK, os_setenv(name, value_updated, 0)) eq(value, os.getenv(name)) + eq(OK, os_setenv(name, value_updated, 1)) + eq(value_updated, os.getenv(name)) end) end) @@ -93,31 +117,42 @@ describe('env.c', function() end) describe('os_getenv', function() - itp('reads an env variable', function() + itp('reads an env var', function() local name = 'NVIM_UNIT_TEST_GETENV_1N' local value = 'NVIM_UNIT_TEST_GETENV_1V' eq(NULL, os_getenv(name)) -- Use os_setenv because Lua dosen't have setenv. os_setenv(name, value, 1) eq(value, os_getenv(name)) + + -- Get a big value. + local bigval = ('x'):rep(256) + eq(OK, os_setenv(name, bigval, 1)) + eq(bigval, os_getenv(name)) + + -- Set non-empty, then set empty. + eq(OK, os_setenv(name, 'non-empty', 1)) + eq('non-empty', os_getenv(name)) + eq(OK, os_setenv(name, '', 1)) + eq(NULL, os_getenv(name)) end) - itp('returns NULL if the env variable is not found', function() - local name = 'NVIM_UNIT_TEST_GETENV_NOTFOUND' - return eq(NULL, os_getenv(name)) + itp('returns NULL if the env var is not found', function() + eq(NULL, os_getenv('NVIM_UNIT_TEST_GETENV_NOTFOUND')) end) end) - describe('os_unsetenv', function() - itp('unsets environment variable', function() - local name = 'TEST_UNSETENV' - local value = 'TESTVALUE' - os_setenv(name, value, 1) - os_unsetenv(name) - neq(os_getenv(name), value) - -- Depending on the platform the var might be unset or set as '' - assert.True(os_getenv(name) == nil or os_getenv(name) == '') - end) + itp('os_unsetenv', function() + local name = 'TEST_UNSETENV' + local value = 'TESTVALUE' + os_setenv(name, value, 1) + eq(OK, os_unsetenv(name)) + neq(os_getenv(name), value) + -- Depending on the platform the var might be unset or set as '' + assert.True(os_getenv(name) == nil or os_getenv(name) == '') + if os_getenv(name) == nil then + eq(false, os_env_exists(name)) + end end) describe('os_getenvname_at_index', function() -- cgit From 67535b5940b70de327d1a9ce6af4a311406eb62f Mon Sep 17 00:00:00 2001 From: erw7 Date: Thu, 28 Feb 2019 08:34:10 +0100 Subject: test/env: multibyte env var to child process Note: the test fails on non-Windows CI (Travis linux, Quickbuild bsd): even on master before the env.c changes in this patch-series. Maybe the unix part of printenv-test.c needs to be revisited. Signed-off-by: Justin M. Keyes --- test/functional/eval/let_spec.lua | 25 +++++++++++++- test/functional/fixtures/CMakeLists.txt | 4 +++ test/functional/fixtures/printenv-test.c | 59 ++++++++++++++++++++++++++++++++ test/helpers.lua | 1 + 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 test/functional/fixtures/printenv-test.c (limited to 'test') diff --git a/test/functional/eval/let_spec.lua b/test/functional/eval/let_spec.lua index ff71daab74..0cbf40137e 100644 --- a/test/functional/eval/let_spec.lua +++ b/test/functional/eval/let_spec.lua @@ -7,6 +7,7 @@ local eval = helpers.eval local meths = helpers.meths local redir_exec = helpers.redir_exec local source = helpers.source +local nvim_dir = helpers.nvim_dir before_each(clear) @@ -45,7 +46,7 @@ describe(':let', function() ]=]) end) - it("multibyte environment variables", function() + it("multibyte env var #8398 #9267", function() command("let $NVIM_TEST = 'AìaB'") eq('AìaB', eval('$NVIM_TEST')) command("let $NVIM_TEST = 'AaあB'") @@ -56,4 +57,26 @@ describe(':let', function() command("let $NVIM_TEST = '"..mbyte.."'") eq(mbyte, eval('$NVIM_TEST')) end) + + it("multibyte env var to child process #8398 #9267", function() + if (not helpers.iswin()) and require('test.helpers').isCI() then + -- Fails on non-Windows CI. Buffering/timing issue? + pending('fails on unix CI', function() end) + end + local cmd_get_child_env = "let g:env_from_child = system(['"..nvim_dir.."/printenv-test', 'NVIM_TEST'])" + command("let $NVIM_TEST = 'AìaB'") + command(cmd_get_child_env) + eq(eval('$NVIM_TEST'), eval('g:env_from_child')) + + command("let $NVIM_TEST = 'AaあB'") + command(cmd_get_child_env) + eq(eval('$NVIM_TEST'), eval('g:env_from_child')) + + local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ + .ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ + .ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]] + command("let $NVIM_TEST = '"..mbyte.."'") + command(cmd_get_child_env) + eq(eval('$NVIM_TEST'), eval('g:env_from_child')) + end) end) diff --git a/test/functional/fixtures/CMakeLists.txt b/test/functional/fixtures/CMakeLists.txt index 8537ea390f..a7cd214b6b 100644 --- a/test/functional/fixtures/CMakeLists.txt +++ b/test/functional/fixtures/CMakeLists.txt @@ -3,3 +3,7 @@ target_link_libraries(tty-test ${LIBUV_LIBRARIES}) add_executable(shell-test shell-test.c) add_executable(printargs-test printargs-test.c) +add_executable(printenv-test printenv-test.c) +if(WIN32) + set_target_properties(printenv-test PROPERTIES LINK_FLAGS -municode) +endif() diff --git a/test/functional/fixtures/printenv-test.c b/test/functional/fixtures/printenv-test.c new file mode 100644 index 0000000000..5ac076f653 --- /dev/null +++ b/test/functional/fixtures/printenv-test.c @@ -0,0 +1,59 @@ +// This is an open source non-commercial project. Dear PVS-Studio, please check +// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com + +#include + +#ifdef WIN32 +# include +#else +# include +#endif + +#ifdef WIN32 +int wmain(int argc, wchar_t **argv) +#else +int main(int argc, char **argv) +#endif +{ + if (argc != 2) { + return 1; + } + +#ifdef WIN32 + wchar_t *value = _wgetenv(argv[1]); + if (value == NULL) { + return 1; + } + int utf8_len = WideCharToMultiByte(CP_UTF8, + 0, + value, + -1, + NULL, + 0, + NULL, + NULL); + if (utf8_len == 0) { + return (int)GetLastError(); + } + char *utf8_value = (char *)calloc((size_t)utf8_len, sizeof(char)); + utf8_len = WideCharToMultiByte(CP_UTF8, + 0, + value, + -1, + utf8_value, + utf8_len, + NULL, + NULL); + fprintf(stderr, "%s", utf8_value); + free(utf8_value); +#else + char *value = getenv(argv[1]); + if (value == NULL) { + fprintf(stderr, "env var not found: %s", argv[1]); + return 1; + } + // Print to stderr to avoid buffering. + fprintf(stderr, "%s", value); +#endif + return 0; +} diff --git a/test/helpers.lua b/test/helpers.lua index 59da274e87..7c3654680a 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -751,6 +751,7 @@ local module = { hasenv = hasenv, hexdump = hexdump, intchar2lua = intchar2lua, + isCI = isCI, map = map, matches = matches, mergedicts_copy = mergedicts_copy, -- cgit From 403922b1b47c1f03272e2bdd600dcc02db481389 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 1 Mar 2019 01:48:21 +0100 Subject: test: fix isCI() for Quickbuild --- test/helpers.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/helpers.lua b/test/helpers.lua index 7c3654680a..9f998ef919 100644 --- a/test/helpers.lua +++ b/test/helpers.lua @@ -708,7 +708,7 @@ end local function isCI() local is_travis = nil ~= os.getenv('TRAVIS') local is_appveyor = nil ~= os.getenv('APPVEYOR') - local is_quickbuild = nil ~= os.getenv('PR_NUMBER') + local is_quickbuild = nil ~= lfs.attributes('/usr/home/quickbuild') return is_travis or is_appveyor or is_quickbuild end -- cgit