aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/misc1.c29
-rw-r--r--src/os/os.h1
-rw-r--r--src/os/users.c57
-rw-r--r--test/unit/os/users.moon52
4 files changed, 116 insertions, 23 deletions
diff --git a/src/misc1.c b/src/misc1.c
index b391cb1ee4..e78343291b 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -3256,34 +3256,17 @@ char_u *get_env_name(expand_T *xp, int idx)
* Find all user names for user completion.
* Done only once and then cached.
*/
-static void init_users(void) {
+static void init_users(void)
+{
static int lazy_init_done = FALSE;
- if (lazy_init_done)
+ if (lazy_init_done) {
return;
+ }
lazy_init_done = TRUE;
- ga_init2(&ga_users, sizeof(char_u *), 20);
-
-# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
- {
- char_u* user;
- struct passwd* pw;
-
- setpwent();
- while ((pw = getpwent()) != NULL)
- /* pw->pw_name shouldn't be NULL but just in case... */
- if (pw->pw_name != NULL) {
- if (ga_grow(&ga_users, 1) == FAIL)
- break;
- user = vim_strsave((char_u*)pw->pw_name);
- if (user == NULL)
- break;
- ((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user;
- }
- endpwent();
- }
-# endif
+
+ mch_get_usernames(&ga_users);
}
/*
diff --git a/src/os/os.h b/src/os/os.h
index 48e3ffd0dd..87323fb025 100644
--- a/src/os/os.h
+++ b/src/os/os.h
@@ -13,5 +13,6 @@ int mch_can_exe(const 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);
+int mch_get_usernames(garray_T *usernames);
#endif
diff --git a/src/os/users.c b/src/os/users.c
new file mode 100644
index 0000000000..b392118f1b
--- /dev/null
+++ b/src/os/users.c
@@ -0,0 +1,57 @@
+/* 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.
+ */
+
+/*
+ * users.c -- operating system user information
+ */
+
+#include <uv.h>
+
+#include "os.h"
+#include "../garray.h"
+#include "../misc2.h"
+#ifdef HAVE_PWD_H
+# include <pwd.h>
+#endif
+
+/*
+ * Initialize users garray and fill it with os usernames.
+ * Return Ok for success, FAIL for failure.
+ */
+int mch_get_usernames(garray_T *users)
+{
+ if (users == NULL) {
+ return FALSE;
+ }
+ ga_init2(users, sizeof(char *), 20);
+
+# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H)
+ char *user;
+ struct passwd *pw;
+
+ setpwent();
+ while ((pw = getpwent()) != NULL) {
+ /* pw->pw_name shouldn't be NULL but just in case... */
+ if (pw->pw_name != NULL) {
+ if (ga_grow(users, 1) == FAIL) {
+ return FAIL;
+ }
+ user = (char *)vim_strsave((char_u*)pw->pw_name);
+ if (user == NULL) {
+ return FAIL;
+ }
+ ((char **)(users->ga_data))[users->ga_len++] = user;
+ }
+ }
+ endpwent();
+# endif
+
+ return OK;
+}
+
diff --git a/test/unit/os/users.moon b/test/unit/os/users.moon
new file mode 100644
index 0000000000..366407d5c8
--- /dev/null
+++ b/test/unit/os/users.moon
@@ -0,0 +1,52 @@
+{:cimport, :internalize, :eq, :ffi, :lib, :cstr} = require 'test.unit.helpers'
+
+-- fs = cimport './src/os/os.h'
+-- remove these statements once 'cimport' is working properly for misc1.h
+users = lib
+ffi.cdef [[
+typedef struct growarray {
+ int ga_len;
+ int ga_maxlen;
+ int ga_itemsize;
+ int ga_growsize;
+ void *ga_data;
+} garray_T;
+int mch_get_usernames(garray_T *usernames);
+]]
+
+NULL = ffi.cast 'void*', 0
+OK = 1
+FAIL = 0
+
+garray_new = () ->
+ ffi.new 'garray_T[1]'
+
+garray_get_len = (array) ->
+ array[0].ga_len
+
+garray_get_item = (array, index) ->
+ (ffi.cast 'void **', array[0].ga_data)[index]
+
+
+describe 'users function', ->
+
+ describe 'mch_get_usernames', ->
+
+ -- will probably not work on windows
+ current_username = os.getenv 'USER'
+
+ it 'returns FAIL if called with NULL', ->
+ eq FAIL, users.mch_get_usernames NULL
+
+ it 'fills the names garray with os usernames and returns OK', ->
+ ga_users = garray_new!
+ eq OK, users.mch_get_usernames ga_users
+ user_count = garray_get_len ga_users
+ assert.is_true user_count > 0
+ current_username_found = false
+ for i = 0, user_count - 1
+ name = ffi.string (garray_get_item ga_users, i)
+ if name == current_username
+ current_username_found = true
+ assert.is_true current_username_found
+