Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-03-19 01:19:35 +0400
committerRussell Belfer <rb@github.com>2013-03-19 01:19:35 +0400
commit41954a49c12a72eda3b3fe02c2752f6831b5dbf9 (patch)
tree4b9cff17fbd7172efddde4dba8e1d2f6b31e0c45 /src/fileops.c
parent5540d9477ed143707435324e785336d254b12e47 (diff)
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.
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c126
1 files changed, 88 insertions, 38 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 4ed46ce85..9700eed3c 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -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
return win32_find_system_dirs(out);
#else
- return git_strarray_set(out, 1, "/etc");
+ return git_buf_sets(out, "/etc");
#endif
}
-static int git_futils_guess_global_dirs(git_strarray *out)
+static int git_futils_guess_global_dirs(git_buf *out)
{
#ifdef GIT_WIN32
return win32_find_global_dirs(out);
#else
- return git_strarray_set(out, 1, getenv("HOME"));
+ return git_buf_sets(out, getenv("HOME"));
#endif
}
-static int git_futils_guess_xdg_dirs(git_strarray *out)
+static int git_futils_guess_xdg_dirs(git_buf *out)
{
#ifdef GIT_WIN32
return win32_find_xdg_dirs(out);
#else
- int error = 0;
- git_buf xdg = GIT_BUF_INIT;
const char *env = 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)
- git_buf_joinpath(&xdg, env, ".config/git");
-
- error = git_strarray_set(out, 1, xdg.ptr);
- git_buf_free(&xdg);
+ return git_buf_joinpath(out, env, ".config/git");
- return error;
+ git_buf_clear(out);
+ return 0;
#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] = {
git_futils_guess_system_dirs,
git_futils_guess_global_dirs,
@@ -615,53 +613,105 @@ static int git_futils_check_selector(git_futils_dir_t which)
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) {
- giterr_set(GITERR_INVALID, "Output git_strarray not provided");
- return -1;
- }
+ assert(out);
*out = NULL;
GITERR_CHECK_ERROR(git_futils_check_selector(which));
- if (!git_futils__dirs[which].count) {
- int error = git_futils__dir_guess[which](&git_futils__dirs[which]);
- if (error < 0)
- return error;
- }
+ if (!git_buf_len(&git_futils__dirs[which]))
+ GITERR_CHECK_ERROR(
+ git_futils__dir_guess[which](&git_futils__dirs[which]));
*out = &git_futils__dirs[which];
return 0;
}
-int git_futils_dirs_set(
- git_futils_dir_t which, const git_strarray *dirs, bool replace)
+int git_futils_dirs_get_str(char *out, size_t outlen, git_futils_dir_t which)
+{
+ 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));
- if (replace)
- git_strarray_free(&git_futils__dirs[which]);
+ if (search_path != NULL)
+ expand_path = strstr(search_path, PATH_MAGIC);
- /* init with defaults if it hasn't been done yet, but ignore error */
- else if (!git_futils__dirs[which].count)
+ /* init with default if not yet done and needed (ignoring error) */
+ if ((!search_path || expand_path) &&
+ !git_buf_len(&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(
git_buf *path, const char *name, git_futils_dir_t which, const char *label)
{
- size_t i;
- const git_strarray *syspaths;
+ size_t len;
+ 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) {
- GITERR_CHECK_ERROR(
- git_buf_joinpath(path, syspaths->strings[i], name));
+ for (scan = git_buf_cstr(syspath); scan; scan = next) {
+ for (next = strchr(scan, GIT_PATH_LIST_SEPARATOR);
+ 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))
return 0;