Commit 0291b5b76bd8dcbac1118533c7a79a619ade766c

Vicent Marti 2011-06-03T19:59:16

odb: Fix loading ODB alternates Fixed an issue with the `strtokz implementation and added support for comments and relative paths in the alternates file.

diff --git a/src/odb.c b/src/odb.c
index 1f3848f..8953ec6 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 ebc1f43..560c40d 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 e5a2ebe..72e3a9c 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);