From 0291b5b76bd8dcbac1118533c7a79a619ade766c Mon Sep 17 00:00:00 2001 From: Vicent Marti Date: Fri, 3 Jun 2011 19:59:16 +0200 Subject: [PATCH] odb: Fix loading ODB alternates Fixed an issue with the `strtokz implementation and added support for comments and relative paths in the alternates file. --- src/odb.c | 20 ++++++++++++++++---- src/util.c | 34 ++++++++++++++++++---------------- src/util.h | 3 +-- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/odb.c b/src/odb.c index 1f3848ff0..8953ec658 100644 --- a/src/odb.c +++ b/src/odb.c @@ -321,8 +321,7 @@ static int add_default_backends(git_odb *db, const char *objects_dir, int as_alt static int load_alternates(git_odb *odb, const char *objects_dir) { char alternates_path[GIT_PATH_MAX]; - char alternate[GIT_PATH_MAX]; - char *buffer; + char *buffer, *alternate; gitfo_buf alternates_buf = GITFO_BUF_INIT; int error; @@ -339,8 +338,21 @@ static int load_alternates(git_odb *odb, const char *objects_dir) error = GIT_SUCCESS; /* add each alternate as a new backend; one alternate per line */ - while ((error == GIT_SUCCESS) && (buffer = git__strtok(alternate, buffer, "\r\n")) != NULL) - error = add_default_backends(odb, alternate, 1); + while ((alternate = git__strtok(&buffer, "\r\n")) != NULL) { + char full_path[GIT_PATH_MAX]; + + if (*alternate == '\0' || *alternate == '#') + continue; + + /* relative path: build based on the current `objects` folder */ + if (*alternate == '.') { + git__joinpath(full_path, objects_dir, alternate); + alternate = full_path; + } + + if ((error = add_default_backends(odb, alternate, 1)) < GIT_SUCCESS) + break; + } gitfo_free_buf(&alternates_buf); if (error < GIT_SUCCESS) diff --git a/src/util.c b/src/util.c index ebc1f43d5..560c40dbb 100644 --- a/src/util.c +++ b/src/util.c @@ -337,27 +337,29 @@ void git__joinpath_n(char *buffer_out, int count, ...) *buffer_out = '\0'; } -static char *strtok_raw(char *output, char *src, char *delimit, int keep) +char *git__strtok(char **end, const char *sep) { - while (*src && strchr(delimit, *src) == NULL) - *output++ = *src++; + char *ptr = *end; - *output = 0; + while (*ptr && strchr(sep, *ptr)) + ++ptr; - if (keep) - return src; - else - return *src ? src+1 : src; -} + if (*ptr) { + char *start = ptr; + *end = start + 1; -char *git__strtok(char *output, char *src, char *delimit) -{ - return strtok_raw(output, src, delimit, 0); -} + while (**end && !strchr(sep, **end)) + ++*end; -char *git__strtok_keep(char *output, char *src, char *delimit) -{ - return strtok_raw(output, src, delimit, 1); + if (**end) { + **end = '\0'; + ++*end; + } + + return start; + } + + return NULL; } void git__hexdump(const char *buffer, size_t len) diff --git a/src/util.h b/src/util.h index e5a2ebe5f..72e3a9c68 100644 --- a/src/util.h +++ b/src/util.h @@ -139,8 +139,7 @@ GIT_INLINE(int) git__is_sizet(git_off_t p) # define git__rotl(v, s) (uint32_t)(((uint32_t)(v) << (s)) | ((uint32_t)(v) >> (32 - (s)))) #endif -extern char *git__strtok(char *output, char *src, char *delimit); -extern char *git__strtok_keep(char *output, char *src, char *delimit); +extern char *git__strtok(char **end, const char *sep); extern void git__strntolower(char *str, int len); extern void git__strtolower(char *str);