Commit 41954a49 by Russell Belfer

Switch search paths to classic delimited strings

This switches the APIs for setting and getting the global/system
search paths from using git_strarray to using a simple string with
GIT_PATH_LIST_SEPARATOR delimited paths, just as the environment
PATH variable would contain.  This makes it simpler to get and set
the value.

I also added code to expand "$PATH" when setting a new value to
embed the old value of the path.  This means that I no longer
require separate actions to PREPEND to the value.
parent 5540d947
...@@ -131,7 +131,6 @@ enum { ...@@ -131,7 +131,6 @@ enum {
GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, GIT_OPT_SET_MWINDOW_MAPPED_LIMIT,
GIT_OPT_GET_SEARCH_PATH, GIT_OPT_GET_SEARCH_PATH,
GIT_OPT_SET_SEARCH_PATH, GIT_OPT_SET_SEARCH_PATH,
GIT_OPT_PREPEND_SEARCH_PATH,
}; };
/** /**
...@@ -152,25 +151,21 @@ enum { ...@@ -152,25 +151,21 @@ enum {
* Set the maximum amount of memory that can be mapped at any time * Set the maximum amount of memory that can be mapped at any time
* by the library * by the library
* *
* opts(GIT_OPT_GET_SEARCH_PATH, const git_strarray **, int level) * opts(GIT_OPT_GET_SEARCH_PATH, int level, char *out, size_t len)
* Get a strarray of the search path for a given level of config * Get the search path for a given level of config data. "level" must
* data. "level" must be one of GIT_CONFIG_LEVEL_SYSTEM, * be one of GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL, or
* GIT_CONFIG_LEVEL_GLOBAL, or GIT_CONFIG_LEVEL_XDG. The search * GIT_CONFIG_LEVEL_XDG. The search path is written to the `out`
* path applies to shared attributes and ignore files, too. * buffer up to size `len`. Returns GIT_EBUFS if buffer is too small.
* *
* opts(GIT_OPT_SET_SEARCH_PATH, int level, const git_strarray *) * opts(GIT_OPT_SET_SEARCH_PATH, int level, const char *path)
* Set the search path for a given level of config data. Passing * Set the search path for a level of config data. The search path
* NULL for the git_strarray pointer resets the search path to the * applied to shared attributes and ignore files, too.
* default (which is generally based on environment variables). * - `path` lists directories delimited by GIT_PATH_LIST_SEPARATOR.
* "level" must be one of GIT_CONFIG_LEVEL_SYSTEM, * Pass NULL to reset to the default (generally based on environment
* GIT_CONFIG_LEVEL_GLOBAL, or GIT_CONFIG_LEVEL_XDG. The search * variables). Use magic path `$PATH` to include the old value
* path applies to shared attributes and ignore files, too. * of the path (if you want to prepend or append, for instance).
* * - `level` must be GIT_CONFIG_LEVEL_SYSTEM, GIT_CONFIG_LEVEL_GLOBAL,
* opts(GIT_OPT_PREPEND_SEARCH_PATH, int level, const git_strarray *) * or GIT_CONFIG_LEVEL_XDG.
* Prepend new directories to the search path for a given level of
* config data. "level" must be one of GIT_CONFIG_LEVEL_SYSTEM,
* GIT_CONFIG_LEVEL_GLOBAL, or GIT_CONFIG_LEVEL_XDG. The search
* path applies to shared attributes and ignore files, too.
* *
* @param option Option key * @param option Option key
* @param ... value to set the option * @param ... value to set the option
......
...@@ -521,7 +521,7 @@ static int git_config__find_file_to_path( ...@@ -521,7 +521,7 @@ static int git_config__find_file_to_path(
if (path.size >= outlen) { if (path.size >= outlen) {
giterr_set(GITERR_NOMEMORY, "Buffer is too short for the path"); giterr_set(GITERR_NOMEMORY, "Buffer is too short for the path");
error = -1; error = GIT_EBUFS;
goto done; goto done;
} }
......
...@@ -559,48 +559,46 @@ clean_up: ...@@ -559,48 +559,46 @@ clean_up:
} }
static int git_futils_guess_system_dirs(git_strarray *out) static int git_futils_guess_system_dirs(git_buf *out)
{ {
#ifdef GIT_WIN32 #ifdef GIT_WIN32
return win32_find_system_dirs(out); return win32_find_system_dirs(out);
#else #else
return git_strarray_set(out, 1, "/etc"); return git_buf_sets(out, "/etc");
#endif #endif
} }
static int git_futils_guess_global_dirs(git_strarray *out) static int git_futils_guess_global_dirs(git_buf *out)
{ {
#ifdef GIT_WIN32 #ifdef GIT_WIN32
return win32_find_global_dirs(out); return win32_find_global_dirs(out);
#else #else
return git_strarray_set(out, 1, getenv("HOME")); return git_buf_sets(out, getenv("HOME"));
#endif #endif
} }
static int git_futils_guess_xdg_dirs(git_strarray *out) static int git_futils_guess_xdg_dirs(git_buf *out)
{ {
#ifdef GIT_WIN32 #ifdef GIT_WIN32
return win32_find_xdg_dirs(out); return win32_find_xdg_dirs(out);
#else #else
int error = 0;
git_buf xdg = GIT_BUF_INIT;
const char *env = NULL; const char *env = NULL;
if ((env = getenv("XDG_CONFIG_HOME")) != NULL) if ((env = getenv("XDG_CONFIG_HOME")) != NULL)
git_buf_joinpath(&xdg, env, "git"); return git_buf_joinpath(out, env, "git");
else if ((env = getenv("HOME")) != NULL) else if ((env = getenv("HOME")) != NULL)
git_buf_joinpath(&xdg, env, ".config/git"); return git_buf_joinpath(out, env, ".config/git");
error = git_strarray_set(out, 1, xdg.ptr);
git_buf_free(&xdg);
return error; git_buf_clear(out);
return 0;
#endif #endif
} }
typedef int (*git_futils_dirs_guess_cb)(git_strarray *out); typedef int (*git_futils_dirs_guess_cb)(git_buf *out);
static git_buf git_futils__dirs[GIT_FUTILS_DIR__MAX] =
{ GIT_BUF_INIT, GIT_BUF_INIT, GIT_BUF_INIT };
static git_strarray git_futils__dirs[GIT_FUTILS_DIR__MAX];
static git_futils_dirs_guess_cb git_futils__dir_guess[GIT_FUTILS_DIR__MAX] = { static git_futils_dirs_guess_cb git_futils__dir_guess[GIT_FUTILS_DIR__MAX] = {
git_futils_guess_system_dirs, git_futils_guess_system_dirs,
git_futils_guess_global_dirs, git_futils_guess_global_dirs,
...@@ -615,53 +613,105 @@ static int git_futils_check_selector(git_futils_dir_t which) ...@@ -615,53 +613,105 @@ static int git_futils_check_selector(git_futils_dir_t which)
return -1; return -1;
} }
int git_futils_dirs_get(const git_strarray **out, git_futils_dir_t which) int git_futils_dirs_get(const git_buf **out, git_futils_dir_t which)
{ {
if (!out) { assert(out);
giterr_set(GITERR_INVALID, "Output git_strarray not provided");
return -1;
}
*out = NULL; *out = NULL;
GITERR_CHECK_ERROR(git_futils_check_selector(which)); GITERR_CHECK_ERROR(git_futils_check_selector(which));
if (!git_futils__dirs[which].count) { if (!git_buf_len(&git_futils__dirs[which]))
int error = git_futils__dir_guess[which](&git_futils__dirs[which]); GITERR_CHECK_ERROR(
if (error < 0) git_futils__dir_guess[which](&git_futils__dirs[which]));
return error;
}
*out = &git_futils__dirs[which]; *out = &git_futils__dirs[which];
return 0; return 0;
} }
int git_futils_dirs_set( int git_futils_dirs_get_str(char *out, size_t outlen, git_futils_dir_t which)
git_futils_dir_t which, const git_strarray *dirs, bool replace) {
const git_buf *path = NULL;
GITERR_CHECK_ERROR(git_futils_check_selector(which));
GITERR_CHECK_ERROR(git_futils_dirs_get(&path, which));
if (!out || path->size >= outlen) {
giterr_set(GITERR_NOMEMORY, "Buffer is too short for the path");
return GIT_EBUFS;
}
git_buf_copy_cstr(out, outlen, path);
return 0;
}
#define PATH_MAGIC "$PATH"
int git_futils_dirs_set(git_futils_dir_t which, const char *search_path)
{ {
const char *expand_path = NULL;
git_buf merge = GIT_BUF_INIT;
GITERR_CHECK_ERROR(git_futils_check_selector(which)); GITERR_CHECK_ERROR(git_futils_check_selector(which));
if (replace) if (search_path != NULL)
git_strarray_free(&git_futils__dirs[which]); expand_path = strstr(search_path, PATH_MAGIC);
/* init with defaults if it hasn't been done yet, but ignore error */ /* init with default if not yet done and needed (ignoring error) */
else if (!git_futils__dirs[which].count) if ((!search_path || expand_path) &&
!git_buf_len(&git_futils__dirs[which]))
git_futils__dir_guess[which](&git_futils__dirs[which]); git_futils__dir_guess[which](&git_futils__dirs[which]);
return git_strarray_prepend(&git_futils__dirs[which], dirs); /* if $PATH is not referenced, then just set the path */
if (!expand_path)
return git_buf_sets(&git_futils__dirs[which], search_path);
/* otherwise set to join(before $PATH, old value, after $PATH) */
if (expand_path > search_path)
git_buf_set(&merge, search_path, expand_path - search_path);
if (git_buf_len(&git_futils__dirs[which]))
git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR,
merge.ptr, git_futils__dirs[which].ptr);
expand_path += strlen(PATH_MAGIC);
if (*expand_path)
git_buf_join(&merge, GIT_PATH_LIST_SEPARATOR, merge.ptr, expand_path);
git_buf_swap(&git_futils__dirs[which], &merge);
git_buf_free(&merge);
return git_buf_oom(&git_futils__dirs[which]) ? -1 : 0;
}
void git_futils_dirs_free(void)
{
int i;
for (i = 0; i < GIT_FUTILS_DIR__MAX; ++i)
git_buf_free(&git_futils__dirs[i]);
} }
static int git_futils_find_in_dirlist( static int git_futils_find_in_dirlist(
git_buf *path, const char *name, git_futils_dir_t which, const char *label) git_buf *path, const char *name, git_futils_dir_t which, const char *label)
{ {
size_t i; size_t len;
const git_strarray *syspaths; const char *scan, *next = NULL;
const git_buf *syspath;
GITERR_CHECK_ERROR(git_futils_dirs_get(&syspaths, which)); GITERR_CHECK_ERROR(git_futils_dirs_get(&syspath, which));
for (i = 0; i < syspaths->count; ++i) { for (scan = git_buf_cstr(syspath); scan; scan = next) {
GITERR_CHECK_ERROR( for (next = strchr(scan, GIT_PATH_LIST_SEPARATOR);
git_buf_joinpath(path, syspaths->strings[i], name)); next && next > scan && next[-1] == '\\';
next = strchr(next + 1, GIT_PATH_LIST_SEPARATOR))
/* find unescaped separator or end of string */;
len = next ? (size_t)(next++ - scan) : strlen(scan);
if (!len)
continue;
GITERR_CHECK_ERROR(git_buf_set(path, scan, len));
GITERR_CHECK_ERROR(git_buf_joinpath(path, path->ptr, name));
if (git_path_exists(path->ptr)) if (git_path_exists(path->ptr))
return 0; return 0;
......
...@@ -306,25 +306,42 @@ typedef enum { ...@@ -306,25 +306,42 @@ typedef enum {
} git_futils_dir_t; } git_futils_dir_t;
/** /**
* Get the strarray of search paths for global/system files * Get the search path for global/system/xdg files
* *
* @param out git_strarray of search paths * @param out pointer to git_buf containing search path
* @param which which list of paths to return * @param which which list of paths to return
* @return 0 on success, <0 on failure (allocation error) * @return 0 on success, <0 on failure
*/
extern int git_futils_dirs_get(const git_buf **out, git_futils_dir_t which);
/**
* Get search path into a preallocated buffer
*
* @param out String buffer to write into
* @param outlen Size of string buffer
* @param which Which search path to return
* @return 0 on success, GIT_EBUFS if out is too small, <0 on other failure
*/ */
extern int git_futils_dirs_get(
const git_strarray **out, git_futils_dir_t which); extern int git_futils_dirs_get_str(
char *out, size_t outlen, git_futils_dir_t which);
/** /**
* Set or prepend strarray of search paths for global/system files * Set search paths for global/system/xdg files
*
* The first occurrence of the magic string "$PATH" in the new value will
* be replaced with the old value of the search path.
* *
* @param which which list of paths to modify * @param which Which search path to modify
* @param dirs new list of search paths * @param paths New search path (separated by GIT_PATH_LIST_SEPARATOR)
* @param replace true to replace old, false to prepend to old
* @return 0 on success, <0 on failure (allocation error) * @return 0 on success, <0 on failure (allocation error)
*/ */
extern int git_futils_dirs_set( extern int git_futils_dirs_set(git_futils_dir_t which, const char *paths);
git_futils_dir_t which, const git_strarray *dirs, bool replace);
/**
* Release / reset all search paths
*/
extern void git_futils_dirs_free(void);
/** /**
* Create a "fake" symlink (text file containing the target path). * Create a "fake" symlink (text file containing the target path).
......
...@@ -7,7 +7,8 @@ ...@@ -7,7 +7,8 @@
#include "common.h" #include "common.h"
#include "global.h" #include "global.h"
#include "hash.h" #include "hash.h"
#include "git2/threads.h" #include "fileops.h"
#include "git2/threads.h"
#include "thread-utils.h" #include "thread-utils.h"
...@@ -82,6 +83,7 @@ void git_threads_shutdown(void) ...@@ -82,6 +83,7 @@ void git_threads_shutdown(void)
/* Shut down any subsystems that have global state */ /* Shut down any subsystems that have global state */
git_hash_global_shutdown(); git_hash_global_shutdown();
git_futils_dirs_free();
} }
git_global_st *git__global_state(void) git_global_st *git__global_state(void)
...@@ -139,6 +141,7 @@ void git_threads_shutdown(void) ...@@ -139,6 +141,7 @@ void git_threads_shutdown(void)
/* Shut down any subsystems that have global state */ /* Shut down any subsystems that have global state */
git_hash_global_shutdown(); git_hash_global_shutdown();
git_futils_dirs_free();
} }
git_global_st *git__global_state(void) git_global_st *git__global_state(void)
...@@ -171,7 +174,9 @@ int git_threads_init(void) ...@@ -171,7 +174,9 @@ int git_threads_init(void)
void git_threads_shutdown(void) void git_threads_shutdown(void)
{ {
/* noop */ /* Shut down any subsystems that have global state */
git_hash_global_shutdown();
git_futils_dirs_free();
} }
git_global_st *git__global_state(void) git_global_st *git__global_state(void)
......
...@@ -39,7 +39,7 @@ int git_libgit2_capabilities() ...@@ -39,7 +39,7 @@ int git_libgit2_capabilities()
extern size_t git_mwindow__window_size; extern size_t git_mwindow__window_size;
extern size_t git_mwindow__mapped_limit; extern size_t git_mwindow__mapped_limit;
static int convert_config_level_to_futils_dir(int config_level) static int config_level_to_futils_dir(int config_level)
{ {
int val = -1; int val = -1;
...@@ -80,24 +80,18 @@ int git_libgit2_opts(int key, ...) ...@@ -80,24 +80,18 @@ int git_libgit2_opts(int key, ...)
break; break;
case GIT_OPT_GET_SEARCH_PATH: case GIT_OPT_GET_SEARCH_PATH:
{ if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0) {
const git_strarray **out = va_arg(ap, const git_strarray **); char *out = va_arg(ap, char *);
int which = convert_config_level_to_futils_dir(va_arg(ap, int)); size_t outlen = va_arg(ap, size_t);
error = (which < 0) ? which : git_futils_dirs_get(out, which); error = git_futils_dirs_get_str(out, outlen, error);
break;
} }
break;
case GIT_OPT_SET_SEARCH_PATH: case GIT_OPT_SET_SEARCH_PATH:
case GIT_OPT_PREPEND_SEARCH_PATH: if ((error = config_level_to_futils_dir(va_arg(ap, int))) >= 0)
{ error = git_futils_dirs_set(error, va_arg(ap, const char *));
int which = convert_config_level_to_futils_dir(va_arg(ap, int)); break;
const git_strarray *dirs = va_arg(ap, git_strarray *);
error = (which < 0) ? which : git_futils_dirs_set(
which, dirs, key == GIT_OPT_SET_SEARCH_PATH);
break;
}
} }
va_end(ap); va_end(ap);
......
...@@ -155,75 +155,59 @@ static int win32_find_git_in_registry( ...@@ -155,75 +155,59 @@ static int win32_find_git_in_registry(
return path16.len ? 0 : GIT_ENOTFOUND; return path16.len ? 0 : GIT_ENOTFOUND;
} }
static int win32_copy_to_strarray(
git_strarray *out, size_t count, char **strings)
{
size_t i, realcount;
if (!count)
return 0;
for (i = 0, realcount = 0; i < count; ++i)
if (strings[i]) realcount++;
out->strings = git__calloc(realcount, sizeof(char *));
GITERR_CHECK_ALLOC(out->strings);
for (i = 0, out->count = 0; i < count; ++i)
if (strings[i])
out->strings[out->count++] = strings[i];
return 0;
}
static int win32_find_existing_dirs( static int win32_find_existing_dirs(
git_strarray *out, const wchar_t *tmpl[], char *temp[]) git_buf *out, const wchar_t *tmpl[], char *temp[])
{ {
struct win32_path path16; struct win32_path path16;
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
size_t count;
for (count = 0; *tmpl != NULL; tmpl++) { git_buf_clear(out);
for (; *tmpl != NULL; tmpl++) {
if (!win32_expand_path(&path16, *tmpl) && if (!win32_expand_path(&path16, *tmpl) &&
path16.path[0] != L'%' && path16.path[0] != L'%' &&
!_waccess(path16.path, F_OK)) !_waccess(path16.path, F_OK))
{ {
win32_path_utf16_to_8(&buf, path16.path); win32_path_utf16_to_8(&buf, path16.path);
temp[count++] = git_buf_detach(&buf);
if (buf.size)
git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
} }
} }
return win32_copy_to_strarray(out, count, temp); git_buf_free(&buf);
return (git_buf_oom(out) ? -1 : 0);
} }
int win32_find_system_dirs(git_strarray *out) int win32_find_system_dirs(git_buf *out)
{ {
char *strings[4];
size_t count = 0;
git_buf buf = GIT_BUF_INIT; git_buf buf = GIT_BUF_INIT;
memset(out, 0, sizeof(*out));
/* directories where git.exe & git.cmd are found */ /* directories where git.exe & git.cmd are found */
if (!win32_find_git_in_path(&buf, L"git.exe")) if (!win32_find_git_in_path(&buf, L"git.exe") && buf.size)
strings[count++] = git_buf_detach(&buf); git_buf_set(out, buf.ptr, buf.size);
else
git_buf_clear(out);
if (!win32_find_git_in_path(&buf, L"git.cmd")) if (!win32_find_git_in_path(&buf, L"git.cmd") && buf.size)
strings[count++] = git_buf_detach(&buf); git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
/* directories where git is installed according to registry */ /* directories where git is installed according to registry */
if (!win32_find_git_in_registry( if (!win32_find_git_in_registry(
&buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL)) &buf, HKEY_CURRENT_USER, REG_MSYSGIT_INSTALL_LOCAL) && buf.size)
strings[count++] = git_buf_detach(&buf); git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
if (!win32_find_git_in_registry( if (!win32_find_git_in_registry(
&buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL)) &buf, HKEY_LOCAL_MACHINE, REG_MSYSGIT_INSTALL) && buf.size)
strings[count++] = git_buf_detach(&buf); git_buf_join(out, GIT_PATH_LIST_SEPARATOR, out->ptr, buf.ptr);
git_buf_free(&buf);
return win32_copy_to_strarray(out, count, strings); return (git_buf_oom(out) ? -1 : 0);
} }
int win32_find_global_dirs(git_strarray *out) int win32_find_global_dirs(git_buf *out)
{ {
char *temp[3]; char *temp[3];
static const wchar_t *global_tmpls[4] = { static const wchar_t *global_tmpls[4] = {
...@@ -236,7 +220,7 @@ int win32_find_global_dirs(git_strarray *out) ...@@ -236,7 +220,7 @@ int win32_find_global_dirs(git_strarray *out)
return win32_find_existing_dirs(out, global_tmpls, temp); return win32_find_existing_dirs(out, global_tmpls, temp);
} }
int win32_find_xdg_dirs(git_strarray *out) int win32_find_xdg_dirs(git_buf *out)
{ {
char *temp[6]; char *temp[6];
static const wchar_t *global_tmpls[7] = { static const wchar_t *global_tmpls[7] = {
......
...@@ -18,9 +18,9 @@ extern int win32_expand_path(struct win32_path *s_root, const wchar_t *templ); ...@@ -18,9 +18,9 @@ extern int win32_expand_path(struct win32_path *s_root, const wchar_t *templ);
extern int win32_find_file( extern int win32_find_file(
git_buf *path, const struct win32_path *root, const char *filename); git_buf *path, const struct win32_path *root, const char *filename);
extern int win32_find_system_dirs(git_strarray *out); extern int win32_find_system_dirs(git_buf *out);
extern int win32_find_global_dirs(git_strarray *out); extern int win32_find_global_dirs(git_buf *out);
extern int win32_find_xdg_dirs(git_strarray *out); extern int win32_find_xdg_dirs(git_buf *out);
#endif #endif
...@@ -136,7 +136,7 @@ int cl_rename(const char *source, const char *dest) ...@@ -136,7 +136,7 @@ int cl_rename(const char *source, const char *dest)
#include <stdlib.h> #include <stdlib.h>
char *cl_getenv(const char *name) char *cl_getenv(const char *name)
{ {
return getenv(name); return getenv(name);
} }
int cl_setenv(const char *name, const char *value) int cl_setenv(const char *name, const char *value)
......
...@@ -29,8 +29,24 @@ static char *home_values[] = { ...@@ -29,8 +29,24 @@ static char *home_values[] = {
void test_core_env__initialize(void) void test_core_env__initialize(void)
{ {
int i; int i;
for (i = 0; i < NUM_VARS; ++i) for (i = 0; i < NUM_VARS; ++i) {
env_save[i] = cl_getenv(env_vars[i]); const char *original = cl_getenv(env_vars[i]);
#ifdef GIT_WIN32
env_save[i] = original;
#else
env_save[i] = original ? git__strdup(original) : NULL;
#endif
}
}
static void reset_global_search_path(void)
{
cl_git_pass(git_futils_dirs_set(GIT_FUTILS_DIR_GLOBAL, NULL));
}
static void reset_system_search_path(void)
{
cl_git_pass(git_futils_dirs_set(GIT_FUTILS_DIR_SYSTEM, NULL));
} }
void test_core_env__cleanup(void) void test_core_env__cleanup(void)
...@@ -40,9 +56,7 @@ void test_core_env__cleanup(void) ...@@ -40,9 +56,7 @@ void test_core_env__cleanup(void)
for (i = 0; i < NUM_VARS; ++i) { for (i = 0; i < NUM_VARS; ++i) {
cl_setenv(env_vars[i], env_save[i]); cl_setenv(env_vars[i], env_save[i]);
#ifdef GIT_WIN32
git__free(env_save[i]); git__free(env_save[i]);
#endif
env_save[i] = NULL; env_save[i] = NULL;
} }
...@@ -55,8 +69,8 @@ void test_core_env__cleanup(void) ...@@ -55,8 +69,8 @@ void test_core_env__cleanup(void)
} }
/* reset search paths to default */ /* reset search paths to default */
git_futils_dirs_set(GIT_FUTILS_DIR_GLOBAL, NULL, true); reset_global_search_path();
git_futils_dirs_set(GIT_FUTILS_DIR_SYSTEM, NULL, true); reset_system_search_path();
} }
static void setenv_and_check(const char *name, const char *value) static void setenv_and_check(const char *name, const char *value)
...@@ -64,21 +78,10 @@ static void setenv_and_check(const char *name, const char *value) ...@@ -64,21 +78,10 @@ static void setenv_and_check(const char *name, const char *value)
char *check; char *check;
cl_git_pass(cl_setenv(name, value)); cl_git_pass(cl_setenv(name, value));
check = cl_getenv(name); check = cl_getenv(name);
cl_assert_equal_s(value, check); cl_assert_equal_s(value, check);
#ifdef GIT_WIN32
git__free(check); git__free(check);
#endif
}
static void reset_global_search_path(void)
{
cl_git_pass(git_futils_dirs_set(GIT_FUTILS_DIR_GLOBAL, NULL, true));
}
static void reset_system_search_path(void)
{
cl_git_pass(git_futils_dirs_set(GIT_FUTILS_DIR_SYSTEM, NULL, true));
} }
void test_core_env__0(void) void test_core_env__0(void)
...@@ -216,7 +219,7 @@ void test_core_env__2(void) ...@@ -216,7 +219,7 @@ void test_core_env__2(void)
char **val; char **val;
const char *testname = "alternate"; const char *testname = "alternate";
size_t testlen = strlen(testname); size_t testlen = strlen(testname);
git_strarray arr; char out[GIT_PATH_MAX];
strncpy(testfile, testname, sizeof(testfile)); strncpy(testfile, testname, sizeof(testfile));
cl_assert_equal_s(testname, testfile); cl_assert_equal_s(testname, testfile);
...@@ -227,7 +230,7 @@ void test_core_env__2(void) ...@@ -227,7 +230,7 @@ void test_core_env__2(void)
* we are on a filesystem that doesn't support the * we are on a filesystem that doesn't support the
* characters in question and skip this test... * characters in question and skip this test...
*/ */
if (p_mkdir(*val, 0777) != 0) { if (p_mkdir(*val, 0777) != 0 && errno != EEXIST) {
*val = ""; /* mark as not created */ *val = ""; /* mark as not created */
continue; continue;
} }
...@@ -243,31 +246,67 @@ void test_core_env__2(void) ...@@ -243,31 +246,67 @@ void test_core_env__2(void)
cl_git_mkfile(path.ptr, "find me"); cl_git_mkfile(path.ptr, "find me");
git_buf_rtruncate_at_char(&path, '/'); git_buf_rtruncate_at_char(&path, '/');
arr.count = 1; /* default should be NOTFOUND */
arr.strings = &path.ptr;
cl_assert_equal_i( cl_assert_equal_i(
GIT_ENOTFOUND, git_futils_find_global_file(&found, testfile)); GIT_ENOTFOUND, git_futils_find_global_file(&found, testfile));
/* set search path */
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
cl_git_pass(git_libgit2_opts( cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &arr)); GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, out, sizeof(out)));
cl_assert_equal_s(out, path.ptr);
cl_git_pass(git_futils_find_global_file(&found, testfile)); cl_git_pass(git_futils_find_global_file(&found, testfile));
/* reset */
cl_git_pass(git_libgit2_opts( cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL)); GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
cl_assert_equal_i(
GIT_ENOTFOUND, git_futils_find_global_file(&found, testfile));
/* try prepend behavior */
cl_git_pass(git_buf_putc(&path, GIT_PATH_LIST_SEPARATOR));
cl_git_pass(git_buf_puts(&path, "$PATH"));
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, path.ptr));
git_buf_rtruncate_at_char(&path, GIT_PATH_LIST_SEPARATOR);
cl_git_pass(git_libgit2_opts(
GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, out, sizeof(out)));
cl_assert(git__prefixcmp(out, path.ptr) == 0);
cl_git_pass(git_futils_find_global_file(&found, testfile));
/* reset */
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
cl_assert_equal_i( cl_assert_equal_i(
GIT_ENOTFOUND, git_futils_find_global_file(&found, testfile)); GIT_ENOTFOUND, git_futils_find_global_file(&found, testfile));
/* try append behavior */
cl_git_pass(git_buf_join(
&found, GIT_PATH_LIST_SEPARATOR, "$PATH", path.ptr));
cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, found.ptr));
cl_git_pass(git_libgit2_opts( cl_git_pass(git_libgit2_opts(
GIT_OPT_PREPEND_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &arr)); GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, out, sizeof(out)));
cl_assert(git__suffixcmp(out, path.ptr) == 0);
cl_git_pass(git_futils_find_global_file(&found, testfile)); cl_git_pass(git_futils_find_global_file(&found, testfile));
/* reset */
cl_git_pass(git_libgit2_opts( cl_git_pass(git_libgit2_opts(
GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL)); GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, NULL));
cl_git_pass(git_buf_joinpath(&path, path.ptr, testfile));
(void)p_unlink(path.ptr);
(void)p_rmdir(*val); (void)p_rmdir(*val);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment