Commit ee0656012c213a9589c7a0892f3e4a11caebc664

Russell Belfer 2013-08-13T09:53:56

Minor win32 fixes and improvements This is just a bunch of small fixes that I noticed while looking at the UTF8 and UTF16 path stuff. It fixes a slowdown in looking for an empty directory (not exiting loop asap), makes the dir name in the git__DIR structure be a GIT_FLEX_ARRAY to save an allocation, and fixes some slightly odd assumptions in the cl_getenv helper.

diff --git a/src/path.c b/src/path.c
index 9a4b8c4..d64a5b3 100644
--- a/src/path.c
+++ b/src/path.c
@@ -497,12 +497,14 @@ bool git_path_is_empty_dir(const char *path)
 	hFind = FindFirstFileW(wbuf, &ffd);
 	if (INVALID_HANDLE_VALUE == hFind) {
 		giterr_set(GITERR_OS, "Couldn't open '%s'", path);
+		git_buf_free(&pathbuf);
 		return false;
 	}
 
 	do {
 		if (!git_path_is_dot_or_dotdotW(ffd.cFileName)) {
 			retval = false;
+			break;
 		}
 	} while (FindNextFileW(hFind, &ffd) != 0);
 
diff --git a/src/win32/dir.c b/src/win32/dir.c
index 22050e8..b03c1d5 100644
--- a/src/win32/dir.c
+++ b/src/win32/dir.c
@@ -27,33 +27,29 @@ git__DIR *git__opendir(const char *dir)
 	git_win32_path_as_utf8 filter;
 	git_win32_path filter_w;
 	git__DIR *new = NULL;
+	size_t dirlen;
 
 	if (!dir || !init_filter(filter, sizeof(filter), dir))
 		return NULL;
 
-	new = git__calloc(1, sizeof(*new));
+	dirlen = strlen(dir);
+
+	new = git__calloc(sizeof(*new) + dirlen + 1, 1);
 	if (!new)
 		return NULL;
-
-	new->dir = git__strdup(dir);
-	if (!new->dir)
-		goto fail;
+	memcpy(new->dir, dir, dirlen);
 
 	git_win32_path_from_c(filter_w, filter);
 	new->h = FindFirstFileW(filter_w, &new->f);
 
 	if (new->h == INVALID_HANDLE_VALUE) {
 		giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
-		goto fail;
+		git__free(new);
+		return NULL;
 	}
 
 	new->first = 1;
 	return new;
-
-fail:
-	git__free(new->dir);
-	git__free(new);
-	return NULL;
 }
 
 int git__readdir_ext(
@@ -133,8 +129,7 @@ int git__closedir(git__DIR *d)
 		FindClose(d->h);
 		d->h = INVALID_HANDLE_VALUE;
 	}
-	git__free(d->dir);
-	d->dir = NULL;
+
 	git__free(d);
 	return 0;
 }
diff --git a/src/win32/dir.h b/src/win32/dir.h
index 60883ff..24d48f6 100644
--- a/src/win32/dir.h
+++ b/src/win32/dir.h
@@ -18,8 +18,8 @@ typedef struct {
 	HANDLE h;
 	WIN32_FIND_DATAW f;
 	struct git__dirent entry;
-	char *dir;
 	int first;
+	char dir[GIT_FLEX_ARRAY];
 } git__DIR;
 
 extern git__DIR *git__opendir(const char *);
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index 2d54794..9d5b8d8 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -514,10 +514,10 @@ p_gmtime_r (const time_t *timer, struct tm *result)
 #else
 #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
 #endif
- 
+
 #ifndef _TIMEZONE_DEFINED
 #define _TIMEZONE_DEFINED
-struct timezone 
+struct timezone
 {
 	int  tz_minuteswest; /* minutes W of Greenwich */
 	int  tz_dsttime;     /* type of dst correction */
diff --git a/tests-clar/clar_libgit2.c b/tests-clar/clar_libgit2.c
index 305581e..bf35a68 100644
--- a/tests-clar/clar_libgit2.c
+++ b/tests-clar/clar_libgit2.c
@@ -66,12 +66,13 @@ char *cl_getenv(const char *name)
 	if (alloc_len <= 0)
 		return NULL;
 
-	alloc_len = GIT_WIN_PATH_UTF8;
 	cl_assert(value_utf16 = git__calloc(alloc_len, sizeof(wchar_t)));
 
 	GetEnvironmentVariableW(name_utf16, value_utf16, alloc_len);
 
-	cl_assert(value_utf8 = git__malloc(alloc_len));
+	alloc_len = alloc_len * 4 + 1; /* worst case UTF16->UTF8 growth */
+	cl_assert(value_utf8 = git__calloc(alloc_len, 1));
+
 	git__utf16_to_8(value_utf8, alloc_len, value_utf16);
 
 	git__free(value_utf16);