diff options
-rw-r--r-- | src/diff.c | 2 | ||||
-rw-r--r-- | src/eval.c | 2 | ||||
-rw-r--r-- | src/ex_cmds2.c | 6 | ||||
-rw-r--r-- | src/hangulin.c | 7 | ||||
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/mbyte.c | 7 | ||||
-rw-r--r-- | src/message.c | 5 | ||||
-rw-r--r-- | src/misc1.c | 61 | ||||
-rw-r--r-- | src/misc2.c | 148 | ||||
-rw-r--r-- | src/option.c | 9 | ||||
-rw-r--r-- | src/os/env.c | 65 | ||||
-rw-r--r-- | src/os/os.h | 3 | ||||
-rw-r--r-- | src/os_unix.c | 33 | ||||
-rw-r--r-- | src/os_unix_defs.h | 8 | ||||
-rw-r--r-- | src/term.c | 3 | ||||
-rw-r--r-- | test/unit/os/env.moon | 95 |
16 files changed, 207 insertions, 250 deletions
diff --git a/src/diff.c b/src/diff.c index ff375c9296..f59ba8015a 100644 --- a/src/diff.c +++ b/src/diff.c @@ -737,7 +737,7 @@ static void diff_file(char_u *tmp_orig, char_u *tmp_new, char_u *tmp_diff) cmd = alloc((unsigned)len); if (cmd != NULL) { /* We don't want $DIFF_OPTIONS to get in the way. */ - if (getenv("DIFF_OPTIONS")) + if (mch_getenv("DIFF_OPTIONS")) vim_setenv((char_u *)"DIFF_OPTIONS", (char_u *)""); /* Build the diff command and execute it. Always use -a, binary diff --git a/src/eval.c b/src/eval.c index cfcf4ce712..9630976056 100644 --- a/src/eval.c +++ b/src/eval.c @@ -8552,7 +8552,7 @@ static void f_exists(typval_T *argvars, typval_T *rettv) p = get_tv_string(&argvars[0]); if (*p == '$') { /* environment variable */ /* first try "normal" environment variables (fast) */ - if (mch_getenv(p + 1) != NULL) + if (mch_getenv((char *)(p + 1)) != NULL) n = TRUE; else { /* try expanding things like $VIM and ${HOME} */ diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index f08aab0300..e005472695 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -3322,11 +3322,11 @@ static char_u *get_mess_env(void); static char_u *get_mess_env(void) { char_u *p; - p = mch_getenv((char_u *)"LC_ALL"); + p = (char_u *)mch_getenv("LC_ALL"); if (p == NULL || *p == NUL) { - p = mch_getenv((char_u *)"LC_MESSAGES"); + p = (char_u *)mch_getenv("LC_MESSAGES"); if (p == NULL || *p == NUL) { - p = mch_getenv((char_u *)"LANG"); + p = (char_u *)mch_getenv("LANG"); if (p != NULL && VIM_ISDIGIT(*p)) p = NULL; /* ignore something like "1043" */ # ifdef HAVE_GET_LOCALE_VAL diff --git a/src/hangulin.c b/src/hangulin.c index 4f84312cad..74972d23e2 100644 --- a/src/hangulin.c +++ b/src/hangulin.c @@ -14,6 +14,7 @@ #include "screen.h" #include "term.h" #include "ui.h" +#include "os/os.h" #ifndef HANGUL_DEFAULT_KEYBOARD # define HANGUL_DEFAULT_KEYBOARD 3 @@ -653,12 +654,12 @@ static int hangul_automata3(char_u *buf, int_u *c) void hangul_keyboard_set(void) { int keyboard; - char *s; + const char *s; hangul_input_clear(); - if ((s = getenv("VIM_KEYBOARD")) == NULL) - s = getenv("HANGUL_KEYBOARD_TYPE"); + if ((s = mch_getenv("VIM_KEYBOARD")) == NULL) + s = mch_getenv("HANGUL_KEYBOARD_TYPE"); if (s) { if (*s == '2') diff --git a/src/main.c b/src/main.c index 13b1179711..d6a09b504c 100644 --- a/src/main.c +++ b/src/main.c @@ -2114,7 +2114,8 @@ process_env ( linenr_T save_sourcing_lnum; scid_T save_sid; - if ((initstr = mch_getenv(env)) != NULL && *initstr != NUL) { + initstr = (char_u *)mch_getenv((char *)env); + if (initstr != NULL && *initstr != NUL) { if (is_viminit) vimrc_found(NULL, NULL); save_sourcing_name = sourcing_name; diff --git a/src/mbyte.c b/src/mbyte.c index 2ebf3cd98f..44f0f9d643 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -89,6 +89,7 @@ #include "screen.h" #include "spell.h" #include "ui.h" +#include "os/os.h" # define WINBYTE BYTE @@ -3483,9 +3484,9 @@ char_u * enc_locale() { # if defined(HAVE_LOCALE_H) || defined(X_LOCALE) if ((s = setlocale(LC_CTYPE, NULL)) == NULL || *s == NUL) # endif - if ((s = getenv("LC_ALL")) == NULL || *s == NUL) - if ((s = getenv("LC_CTYPE")) == NULL || *s == NUL) - s = getenv("LANG"); + if ((s = (char *)mch_getenv("LC_ALL")) == NULL || *s == NUL) + if ((s = (char *)mch_getenv("LC_CTYPE")) == NULL || *s == NUL) + s = (char *)mch_getenv("LANG"); if (s == NULL || *s == NUL) return FAIL; diff --git a/src/message.c b/src/message.c index f6e8d3d9bd..6948cefe12 100644 --- a/src/message.c +++ b/src/message.c @@ -30,6 +30,7 @@ #include "screen.h" #include "term.h" #include "ui.h" +#include "os/os.h" #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H) # include <math.h> @@ -736,11 +737,11 @@ int delete_first_msg(void) { void ex_messages(exarg_T *eap) { struct msg_hist *p; - char_u *s; + const char *s; msg_hist_off = TRUE; - s = mch_getenv((char_u *)"LANG"); + s = mch_getenv("LANG"); if (s != NULL && *s != NUL) msg_attr((char_u *) _("Messages maintainer: Bram Moolenaar <Bram@vim.org>"), diff --git a/src/misc1.c b/src/misc1.c index ab21f8d6a5..b391cb1ee4 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -45,11 +45,6 @@ #include "undo.h" #include "window.h" #include "os/os.h" - -#ifdef HAVE_CRT_EXTERNS_H -#include <crt_externs.h> -#endif - static char_u *vim_version_dir(char_u *vimdir); static char_u *remove_tail(char_u *p, char_u *pend, char_u *name); static void init_users(void); @@ -2727,7 +2722,7 @@ void init_homedir(void) { vim_free(homedir); homedir = NULL; - var = mch_getenv((char_u *)"HOME"); + var = (char_u *)mch_getenv("HOME"); if (var != NULL && *var == NUL) /* empty is same as not set */ var = NULL; @@ -3052,7 +3047,7 @@ char_u *vim_getenv(char_u *name, int *mustfree) int vimruntime; - p = mch_getenv(name); + p = (char_u *)mch_getenv((char *)name); if (p != NULL && *p == NUL) /* empty is the same as not set */ p = NULL; @@ -3073,7 +3068,7 @@ char_u *vim_getenv(char_u *name, int *mustfree) && *default_vimruntime_dir == NUL #endif ) { - p = mch_getenv((char_u *)"VIM"); + p = (char_u *)mch_getenv("VIM"); if (p != NULL && *p == NUL) /* empty is the same as not set */ p = NULL; if (p != NULL) { @@ -3081,7 +3076,7 @@ char_u *vim_getenv(char_u *name, int *mustfree) if (p != NULL) *mustfree = TRUE; else - p = mch_getenv((char_u *)"VIM"); + p = (char_u *)mch_getenv("VIM"); } } @@ -3223,21 +3218,7 @@ static char_u *remove_tail(char_u *p, char_u *pend, char_u *name) */ void vim_setenv(char_u *name, char_u *val) { -#ifdef HAVE_SETENV mch_setenv((char *)name, (char *)val, 1); -#else - char_u *envbuf; - - /* - * Putenv does not copy the string, it has to remain - * valid. The allocated memory will never be freed. - */ - envbuf = alloc((unsigned)(STRLEN(name) + STRLEN(val) + 2)); - if (envbuf != NULL) { - sprintf((char *)envbuf, "%s=%s", name, val); - putenv((char *)envbuf); - } -#endif /* * When setting $VIMRUNTIME adjust the directory to find message * translations to $VIMRUNTIME/lang. @@ -3258,35 +3239,17 @@ void vim_setenv(char_u *name, char_u *val) */ char_u *get_env_name(expand_T *xp, int idx) { -# if defined(AMIGA) || defined(__MRC__) || defined(__SC__) - /* - * No environ[] on the Amiga and on the Mac (using MPW). - */ - return NULL; -# else -# if !defined(__WIN32__) && !defined(HAVE__NSGETENVIRON) - /* Borland C++ 5.2 has this in a header file. */ - extern char **environ; -# else - char **environ = *_NSGetEnviron(); -# endif # define ENVNAMELEN 100 + // this static buffer is needed to avoid a memory leak in ExpandGeneric static char_u name[ENVNAMELEN]; - char_u *str; - int n; - - str = (char_u *)environ[idx]; - if (str == NULL) + char *envname = mch_getenvname_at_index(idx); + if (envname) { + vim_strncpy(name, (char_u *)envname, ENVNAMELEN - 1); + vim_free(envname); + return name; + } else { return NULL; - - for (n = 0; n < ENVNAMELEN - 1; ++n) { - if (str[n] == '=' || str[n] == NUL) - break; - name[n] = str[n]; } - name[n] = NUL; - return name; -# endif } /* @@ -3396,7 +3359,7 @@ home_replace ( if (homedir != NULL) dirlen = STRLEN(homedir); - homedir_env_orig = homedir_env = mch_getenv((char_u *)"HOME"); + homedir_env_orig = homedir_env = (char_u *)mch_getenv("HOME"); /* Empty is the same as not set. */ if (homedir_env != NULL && *homedir_env == NUL) homedir_env = NULL; diff --git a/src/misc2.c b/src/misc2.c index 1b1693a72a..92a6af598b 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -2250,154 +2250,6 @@ int pathcmp(const char *p, const char *q, int maxlen) #endif /* - * The putenv() implementation below comes from the "screen" program. - * Included with permission from Juergen Weigert. - * See pty.c for the copyright notice. - */ - -/* - * putenv -- put value into environment - * - * Usage: i = putenv (string) - * int i; - * char *string; - * - * where string is of the form <name>=<value>. - * Putenv returns 0 normally, -1 on error (not enough core for malloc). - * - * Putenv may need to add a new name into the environment, or to - * associate a value longer than the current value with a particular - * name. So, to make life simpler, putenv() copies your entire - * environment into the heap (i.e. malloc()) from the stack - * (i.e. where it resides when your process is initiated) the first - * time you call it. - * - * (history removed, not very interesting. See the "screen" sources.) - */ - -#if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) - -#define EXTRASIZE 5 /* increment to add to env. size */ - -static int envsize = -1; /* current size of environment */ -extern -char **environ; /* the global which is your env. */ - -static int findenv(char *name); /* look for a name in the env. */ -static int newenv(void); /* copy env. from stack to heap */ -static int moreenv(void); /* incr. size of env. */ - -int putenv(const char *string) -{ - int i; - char *p; - - if (envsize < 0) { /* first time putenv called */ - if (newenv() < 0) /* copy env. to heap */ - return -1; - } - - i = findenv((char *)string); /* look for name in environment */ - - if (i < 0) { /* name must be added */ - for (i = 0; environ[i]; i++) ; - if (i >= (envsize - 1)) { /* need new slot */ - if (moreenv() < 0) - return -1; - } - p = (char *)alloc((unsigned)(strlen(string) + 1)); - if (p == NULL) /* not enough core */ - return -1; - environ[i + 1] = 0; /* new end of env. */ - } else { /* name already in env. */ - p = vim_realloc(environ[i], strlen(string) + 1); - if (p == NULL) - return -1; - } - sprintf(p, "%s", string); /* copy into env. */ - environ[i] = p; - - return 0; -} - -static int findenv(char *name) -{ - char *namechar, *envchar; - int i, found; - - found = 0; - for (i = 0; environ[i] && !found; i++) { - envchar = environ[i]; - namechar = name; - while (*namechar && *namechar != '=' && (*namechar == *envchar)) { - namechar++; - envchar++; - } - found = ((*namechar == '\0' || *namechar == '=') && *envchar == '='); - } - return found ? i - 1 : -1; -} - -static int newenv(void) { - char **env, *elem; - int i, esize; - - for (i = 0; environ[i]; i++) - ; - esize = i + EXTRASIZE + 1; - env = (char **)alloc((unsigned)(esize * sizeof (elem))); - if (env == NULL) - return -1; - - for (i = 0; environ[i]; i++) { - elem = (char *)alloc((unsigned)(strlen(environ[i]) + 1)); - if (elem == NULL) - return -1; - env[i] = elem; - strcpy(elem, environ[i]); - } - - env[i] = 0; - environ = env; - envsize = esize; - return 0; -} - -static int moreenv(void) { - int esize; - char **env; - - esize = envsize + EXTRASIZE; - env = (char **)vim_realloc((char *)environ, esize * sizeof (*env)); - if (env == 0) - return -1; - environ = env; - envsize = esize; - return 0; -} - -# ifdef USE_VIMPTY_GETENV -char_u *vimpty_getenv(const char_u *string) -{ - int i; - char_u *p; - - if (envsize < 0) - return NULL; - - i = findenv((char *)string); - - if (i < 0) - return NULL; - - p = vim_strchr((char_u *)environ[i], '='); - return p + 1; -} -# endif - -#endif /* !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) */ - -/* * Return 0 for not writable, 1 for writable file, 2 for a dir which we have * rights to write into. */ diff --git a/src/option.c b/src/option.c index 8daac5b5e1..e257186cf2 100644 --- a/src/option.c +++ b/src/option.c @@ -67,6 +67,7 @@ #include "ui.h" #include "undo.h" #include "window.h" +#include "os/os.h" /* * The options that are local to a window or buffer have "indir" set to one of @@ -1961,7 +1962,7 @@ void set_init_1(void) { p_cp = TRUE; /* Use POSIX compatibility when $VIM_POSIX is set. */ - if (mch_getenv((char_u *)"VIM_POSIX") != NULL) { + if (mch_getenv("VIM_POSIX") != NULL) { set_string_default("cpo", (char_u *)CPO_ALL); set_string_default("shm", (char_u *)"A"); } @@ -1970,7 +1971,7 @@ void set_init_1(void) { * Find default value for 'shell' option. * Don't use it if it is empty. */ - if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL) + if (((p = (char_u *)mch_getenv("SHELL")) != NULL && *p != NUL) ) set_string_default("sh", p); @@ -2170,7 +2171,7 @@ void set_init_1(void) { * NOTE: mlterm's author is being asked to 'set' a variable * instead of an environment variable due to inheritance. */ - if (mch_getenv((char_u *)"MLTERM") != NULL) + if (mch_getenv("MLTERM") != NULL) set_option_value((char_u *)"tbidi", 1L, NULL, 0); /* Parse default for 'fillchars'. */ @@ -2447,7 +2448,7 @@ static char_u *term_bg_default(void) { || STRCMP(T_NAME, "screen.linux") == 0 || STRCMP(T_NAME, "cygwin") == 0 || STRCMP(T_NAME, "putty") == 0 - || ((p = mch_getenv((char_u *)"COLORFGBG")) != NULL + || ((p = (char_u *)mch_getenv("COLORFGBG")) != NULL && (p = vim_strrchr(p, ';')) != NULL && ((p[1] >= '0' && p[1] <= '6') || p[1] == '8') && p[2] == NUL)) diff --git a/src/os/env.c b/src/os/env.c new file mode 100644 index 0000000000..9025b1c8ac --- /dev/null +++ b/src/os/env.c @@ -0,0 +1,65 @@ +/* vi:set ts=2 sts=2 sw=2: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * env.c -- environment variable access + */ + +#include <uv.h> + +#include "os.h" +#include "../misc2.h" + +#ifdef HAVE_CRT_EXTERNS_H +#include <crt_externs.h> +#endif + +const char *mch_getenv(const char *name) +{ + return getenv(name); +} + +int mch_setenv(const char *name, const char *value, int overwrite) +{ + return setenv(name, value, overwrite); +} + +char *mch_getenvname_at_index(size_t index) +{ +# if defined(AMIGA) || defined(__MRC__) || defined(__SC__) + /* + * No environ[] on the Amiga and on the Mac (using MPW). + */ + return NULL; +# else +# if defined(HAVE__NSGETENVIRON) + char **environ = *_NSGetEnviron(); +# elif !defined(__WIN32__) + /* Borland C++ 5.2 has this in a header file. */ + extern char **environ; +# endif + // check if index is inside the environ array + for (size_t i = 0; i < index; i++) { + if (environ[i] == NULL) { + return NULL; + } + } + char *str = environ[index]; + if (str == NULL) { + return NULL; + } + int namesize = 0; + while (str[namesize] != '=' && str[namesize] != NUL) { + namesize++; + } + char *name = (char *)vim_strnsave((char_u *)str, namesize); + return name; +# endif +} + diff --git a/src/os/os.h b/src/os/os.h index bc7496ed58..266b253e86 100644 --- a/src/os/os.h +++ b/src/os/os.h @@ -9,5 +9,8 @@ int mch_dirname(char_u *buf, int len); int mch_get_absolute_path(char_u *fname, char_u *buf, int len, int force); int mch_is_absolute_path(char_u *fname); int mch_isdir(char_u *name); +const char *mch_getenv(const char *name); +int mch_setenv(const char *name, const char *value, int overwrite); +char *mch_getenvname_at_index(size_t index); #endif diff --git a/src/os_unix.c b/src/os_unix.c index 40eba52da8..5a01f07c36 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1349,7 +1349,7 @@ int mch_can_exe(char_u *name) name[2] == '/')))) return executable_file(name); - p = (char_u *)getenv("PATH"); + p = (char_u *)mch_getenv("PATH"); if (p == NULL || *p == NUL) return -1; buf = alloc((unsigned)(STRLEN(name) + STRLEN(p) + 2)); @@ -1837,9 +1837,9 @@ int mch_get_shellsize() { * the ioctl() values! */ if (columns == 0 || rows == 0 || vim_strchr(p_cpo, CPO_TSIZE) != NULL) { - if ((p = (char_u *)getenv("LINES"))) + if ((p = (char_u *)mch_getenv("LINES"))) rows = atoi((char *)p); - if ((p = (char_u *)getenv("COLUMNS"))) + if ((p = (char_u *)mch_getenv("COLUMNS"))) columns = atoi((char *)p); } @@ -1950,12 +1950,7 @@ int options; /* SHELL_*, see vim.h */ int fd_toshell[2]; /* for pipes */ int fd_fromshell[2]; int pipe_error = FALSE; -# ifdef HAVE_SETENV char envbuf[50]; -# else - static char envbuf_Rows[20]; - static char envbuf_Columns[20]; -# endif int did_settmode = FALSE; /* settmode(TMODE_RAW) called */ newcmd = vim_strsave(p_sh); @@ -2125,27 +2120,13 @@ int options; /* SHELL_*, see vim.h */ } # endif /* Simulate to have a dumb terminal (for now) */ -# ifdef HAVE_SETENV - setenv("TERM", "dumb", 1); + mch_setenv("TERM", "dumb", 1); sprintf((char *)envbuf, "%ld", Rows); - setenv("ROWS", (char *)envbuf, 1); + mch_setenv("ROWS", (char *)envbuf, 1); sprintf((char *)envbuf, "%ld", Rows); - setenv("LINES", (char *)envbuf, 1); + mch_setenv("LINES", (char *)envbuf, 1); sprintf((char *)envbuf, "%ld", Columns); - setenv("COLUMNS", (char *)envbuf, 1); -# else - /* - * Putenv does not copy the string, it has to remain valid. - * Use a static array to avoid losing allocated memory. - */ - putenv("TERM=dumb"); - sprintf(envbuf_Rows, "ROWS=%ld", Rows); - putenv(envbuf_Rows); - sprintf(envbuf_Rows, "LINES=%ld", Rows); - putenv(envbuf_Rows); - sprintf(envbuf_Columns, "COLUMNS=%ld", Columns); - putenv(envbuf_Columns); -# endif + mch_setenv("COLUMNS", (char *)envbuf, 1); /* * stderr is only redirected when using the GUI, so that a diff --git a/src/os_unix_defs.h b/src/os_unix_defs.h index 3aacac69a0..74b98ef68a 100644 --- a/src/os_unix_defs.h +++ b/src/os_unix_defs.h @@ -280,14 +280,6 @@ # else int mch_rename(const char *src, const char *dest); # endif -# ifdef __MVS__ -/* on OS390 Unix getenv() doesn't return a pointer to persistent - * storage -> use __getenv() */ -# define mch_getenv(x) (char_u *)__getenv((char *)(x)) -# else -# define mch_getenv(x) (char_u *)getenv((char *)(x)) -# endif -# define mch_setenv(name, val, x) setenv(name, val, x) #if !defined(S_ISDIR) && defined(S_IFDIR) # define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) diff --git a/src/term.c b/src/term.c index 15a4320db4..4e405f732a 100644 --- a/src/term.c +++ b/src/term.c @@ -45,6 +45,7 @@ #include "syntax.h" #include "ui.h" #include "window.h" +#include "os/os.h" #ifdef HAVE_TGETENT # ifdef HAVE_TERMIOS_H @@ -2021,7 +2022,7 @@ void termcapinit(char_u *name) term = name; if (term == NULL) - term = mch_getenv((char_u *)"TERM"); + term = (char_u *)mch_getenv("TERM"); if (term == NULL || *term == NUL) term = DEFAULT_TERM; set_string_option_direct((char_u *)"term", -1, term, OPT_FREE, 0); diff --git a/test/unit/os/env.moon b/test/unit/os/env.moon new file mode 100644 index 0000000000..b83fcac5f1 --- /dev/null +++ b/test/unit/os/env.moon @@ -0,0 +1,95 @@ +{:cimport, :internalize, :eq, :ffi, :lib, :cstr} = require 'test.unit.helpers' +require 'lfs' + +-- fs = cimport './src/os/os.h' +-- remove these statements once 'cimport' is working properly for misc1.h +env = lib +ffi.cdef [[ +const char *mch_getenv(const char *name); +int mch_setenv(const char *name, const char *value, int override); +char *mch_getenvname_at_index(size_t index); +]] + +str_to_charp = (str) -> + cstr (string.len str), str + +NULL = ffi.cast 'void*', 0 + +describe 'env function', -> + + mch_setenv = (name, value, override) -> + env.mch_setenv (str_to_charp name), (str_to_charp value), override + + mch_getenv = (name) -> + rval = env.mch_getenv (str_to_charp name) + if rval != NULL + ffi.string rval + else + NULL + + describe 'mch_setenv', -> + + OK = 0 + + it 'sets an env variable and returns OK', -> + name = 'NEOVIM_UNIT_TEST_SETENV_1N' + value = 'NEOVIM_UNIT_TEST_SETENV_1V' + eq nil, os.getenv name + eq OK, (mch_setenv name, value, 1) + eq value, os.getenv name + + it "dosn't overwrite an env variable if overwrite is 0", -> + name = 'NEOVIM_UNIT_TEST_SETENV_2N' + value = 'NEOVIM_UNIT_TEST_SETENV_2V' + value_updated = 'NEOVIM_UNIT_TEST_SETENV_2V_UPDATED' + eq OK, (mch_setenv name, value, 0) + eq value, os.getenv name + eq OK, (mch_setenv name, value_updated, 0) + eq value, os.getenv name + + describe 'mch_getenv', -> + + it 'reads an env variable', -> + name = 'NEOVIM_UNIT_TEST_GETENV_1N' + value = 'NEOVIM_UNIT_TEST_GETENV_1V' + eq NULL, mch_getenv name + -- need to use mch_setenv, because lua dosn't have a setenv function + mch_setenv name, value, 1 + eq value, mch_getenv name + + it 'returns NULL if the env variable is not found', -> + name = 'NEOVIM_UNIT_TEST_GETENV_NOTFOUND' + eq NULL, mch_getenv name + + describe 'mch_getenvname_at_index', -> + + it 'returns names of environment variables', -> + test_name = 'NEOVIM_UNIT_TEST_GETENVNAME_AT_INDEX_1N' + test_value = 'NEOVIM_UNIT_TEST_GETENVNAME_AT_INDEX_1V' + mch_setenv test_name, test_value, 1 + i = 0 + names = {} + found_name = false + name = env.mch_getenvname_at_index i + while name != NULL + table.insert names, ffi.string name + if (ffi.string name) == test_name + found_name = true + i += 1 + name = env.mch_getenvname_at_index i + + eq true, (table.getn names) > 0 + eq true, found_name + + it 'returns NULL if the index is out of bounds', -> + huge = ffi.new 'size_t', 10000 + maxuint32 = ffi.new 'size_t', 4294967295 + eq NULL, env.mch_getenvname_at_index huge + eq NULL, env.mch_getenvname_at_index maxuint32 + if ffi.abi '64bit' + -- couldn't use a bigger number because it gets converted to + -- double somewere, should be big enough anyway + -- maxuint64 = ffi.new 'size_t', 18446744073709551615 + maxuint64 = ffi.new 'size_t', 18446744073709000000 + eq NULL, env.mch_getenvname_at_index maxuint64 + |