Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
  • 10 commits
  • 15 files changed
  • 0 commit comments
  • 4 contributors
Commits on Aug 29, 2012
@vmg vmg UTF-8 changes yo 3b73a03
@vmg vmg windows: Keep UTF-8 on the stack yo 6813169
@vmg vmg Add bounds checking to UTF-8 conversion 0f4c617
Commits on Sep 04, 2012
@nulltoken nulltoken Fix MSVC compilation warnings b97c169
@vmg vmg Merge pull request #913 from nulltoken/fix/warnings
Fix MSVC compilation warnings
af6bcd8
@vmg vmg clar: Clear errors on shutdown 925be04
@carlosmn carlosmn travis: use a valgrind suppressions file
We don't care about the supposed zlib errors, and the leak from
giterr_set isn't interesting, as it gets freed each time an error is
set.

Give valgrind a suppressions file so it doesn't tell us about them.
064ee42
@carlosmn carlosmn odb: pass the user's data pointer correctly in foreach f9988d4
@vmg vmg branch: Add missing include c9d223f
@vmg vmg Merge pull request #856 from libgit2/utf8-win
Windows: Perform UTF-8 path conversion on the Stack
4d38340
Showing with 165 additions and 305 deletions.
  1. +1 −1 .travis.yml
  2. +1 −0 include/git2/branch.h
  3. +0 −59 include/git2/windows.h
  4. +12 −0 libgit2_clar.supp
  5. +1 −1 src/diff_output.c
  6. +13 −23 src/fileops.c
  7. +1 −1 src/odb_pack.c
  8. +2 −3 src/path.c
  9. +1 −1 src/signature.c
  10. +8 −21 src/win32/dir.c
  11. +3 −6 src/win32/posix.h
  12. +44 −102 src/win32/posix_w32.c
  13. +60 −71 src/win32/utf-conv.c
  14. +4 −3 src/win32/utf-conv.h
  15. +14 −13 tests-clar/clar_helpers.c
View
2 .travis.yml
@@ -32,7 +32,7 @@ script:
# Run Tests
after_script:
- ctest -V .
- - if [ -f ./libgit2_clar ]; then valgrind --leak-check=full --show-reachable=yes ./libgit2_clar; else echo "Skipping valgrind"; fi
+ - if [ -f ./libgit2_clar ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=../libgit2_clar.supp ./libgit2_clar; else echo "Skipping valgrind"; fi
# Only watch the development branch
branches:
View
1 include/git2/branch.h
@@ -8,6 +8,7 @@
#define INCLUDE_git_branch_h__
#include "common.h"
+#include "oid.h"
#include "types.h"
/**
View
59 include/git2/windows.h
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2009-2012 the libgit2 contributors
- *
- * This file is part of libgit2, distributed under the GNU GPL v2 with
- * a Linking Exception. For full terms see the included COPYING file.
- */
-#ifndef INCLUDE_git_windows_h__
-#define INCLUDE_git_windows_h__
-
-#include "common.h"
-
-/**
- * @file git2/windows.h
- * @brief Windows-specific functions
- * @ingroup Git
- * @{
- */
-GIT_BEGIN_DECL
-
-/**
- * Set the active codepage for Windows syscalls
- *
- * All syscalls performed by the library will assume
- * this codepage when converting paths and strings
- * to use by the Windows kernel.
- *
- * The default value of UTF-8 will work automatically
- * with most Git repositories created on Unix systems.
- *
- * This settings needs only be changed when working
- * with repositories that contain paths in specific,
- * non-UTF codepages.
- *
- * A full list of all available codepage identifiers may
- * be found at:
- *
- * http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
- *
- * @param codepage numeric codepage identifier
- */
-GIT_EXTERN(void) gitwin_set_codepage(unsigned int codepage);
-
-/**
- * Return the active codepage for Windows syscalls
- *
- * @return numeric codepage identifier
- */
-GIT_EXTERN(unsigned int) gitwin_get_codepage(void);
-
-/**
- * Set the active Windows codepage to UTF-8 (this is
- * the default value)
- */
-GIT_EXTERN(void) gitwin_set_utf8(void);
-
-/** @} */
-GIT_END_DECL
-#endif
-
View
12 libgit2_clar.supp
@@ -0,0 +1,12 @@
+{
+ ignore-zlib-errors-cond
+ Memcheck:Cond
+ obj:*libz.so*
+}
+
+{
+ ignore-giterr-set-leak
+ Memcheck:Leak
+ ...
+ fun:giterr_set
+}
View
2 src/diff_output.c
@@ -727,7 +727,7 @@ int git_diff_entrycount(git_diff_list *diff, int delta_t)
assert(diff);
if (delta_t < 0)
- return diff->deltas.length;
+ return (int)diff->deltas.length;
git_vector_foreach(&diff->deltas, i, delta) {
if (delta->status == (git_delta_t)delta_t)
View
36 src/fileops.c
@@ -54,11 +54,10 @@ int git_futils_creat_locked(const char *path, const mode_t mode)
int fd;
#ifdef GIT_WIN32
- wchar_t* buf;
+ wchar_t buf[GIT_WIN_PATH];
- buf = gitwin_to_utf16(path);
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
fd = _wopen(buf, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, mode);
- git__free(buf);
#else
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_EXCL, mode);
#endif
@@ -382,16 +381,16 @@ static int win32_expand_path(struct win32_path *s_root, const wchar_t *templ)
static int win32_find_file(git_buf *path, const struct win32_path *root, const char *filename)
{
- int error = 0;
- size_t len;
+ size_t len, alloc_len;
wchar_t *file_utf16 = NULL;
- char *file_utf8 = NULL;
+ char file_utf8[GIT_PATH_MAX];
if (!root || !filename || (len = strlen(filename)) == 0)
return GIT_ENOTFOUND;
/* allocate space for wchar_t path to file */
- file_utf16 = git__calloc(root->len + len + 2, sizeof(wchar_t));
+ alloc_len = root->len + len + 2;
+ file_utf16 = git__calloc(alloc_len, sizeof(wchar_t));
GITERR_CHECK_ALLOC(file_utf16);
/* append root + '\\' + filename as wchar_t */
@@ -400,29 +399,20 @@ static int win32_find_file(git_buf *path, const struct win32_path *root, const c
if (*filename == '/' || *filename == '\\')
filename++;
- if (gitwin_append_utf16(file_utf16 + root->len - 1, filename, len + 1) !=
- (int)len + 1) {
- error = -1;
- goto cleanup;
- }
+ git__utf8_to_16(file_utf16 + root->len - 1, alloc_len, filename);
/* check access */
if (_waccess(file_utf16, F_OK) < 0) {
- error = GIT_ENOTFOUND;
- goto cleanup;
+ git__free(file_utf16);
+ return GIT_ENOTFOUND;
}
- /* convert to utf8 */
- if ((file_utf8 = gitwin_from_utf16(file_utf16)) == NULL)
- error = -1;
- else {
- git_path_mkposix(file_utf8);
- git_buf_attach(path, file_utf8, 0);
- }
+ git__utf16_to_8(file_utf8, file_utf16);
+ git_path_mkposix(file_utf8);
+ git_buf_sets(path, file_utf8);
-cleanup:
git__free(file_utf16);
- return error;
+ return 0;
}
#endif
View
2 src/odb_pack.c
@@ -435,7 +435,7 @@ static int pack_backend__foreach(git_odb_backend *_backend, int (*cb)(git_oid *o
return error;
git_vector_foreach(&backend->packs, i, p) {
- if ((error = git_pack_foreach_entry(p, cb, &data)) < 0)
+ if ((error = git_pack_foreach_entry(p, cb, data)) < 0)
return error;
}
View
5 src/path.c
@@ -432,14 +432,14 @@ bool git_path_is_empty_dir(const char *path)
{
git_buf pathbuf = GIT_BUF_INIT;
HANDLE hFind = INVALID_HANDLE_VALUE;
- wchar_t *wbuf;
+ wchar_t wbuf[GIT_WIN_PATH];
WIN32_FIND_DATAW ffd;
bool retval = true;
if (!git_path_isdir(path)) return false;
git_buf_printf(&pathbuf, "%s\\*", path);
- wbuf = gitwin_to_utf16(git_buf_cstr(&pathbuf));
+ git__utf8_to_16(wbuf, GIT_WIN_PATH, git_buf_cstr(&pathbuf));
hFind = FindFirstFileW(wbuf, &ffd);
if (INVALID_HANDLE_VALUE == hFind) {
@@ -455,7 +455,6 @@ bool git_path_is_empty_dir(const char *path)
FindClose(hFind);
git_buf_free(&pathbuf);
- git__free(wbuf);
return retval;
}
View
2 src/signature.c
@@ -142,7 +142,7 @@ int git_signature_now(git_signature **sig_out, const char *name, const char *ema
time(&now);
utc_tm = p_gmtime_r(&now, &_utc);
utc_tm->tm_isdst = -1;
- offset = difftime(now, mktime(utc_tm));
+ offset = (time_t)difftime(now, mktime(utc_tm));
offset /= 60;
if (git_signature_new(&sig, name, email, now, (int)offset) < 0)
View
29 src/win32/dir.c
@@ -7,7 +7,6 @@
#define GIT__WIN32_NO_WRAP_DIR
#include "dir.h"
#include "utf-conv.h"
-#include "git2/windows.h"
static int init_filter(char *filter, size_t n, const char *dir)
{
@@ -26,8 +25,8 @@ static int init_filter(char *filter, size_t n, const char *dir)
git__DIR *git__opendir(const char *dir)
{
- char filter[4096];
- wchar_t* filter_w = NULL;
+ char filter[GIT_WIN_PATH];
+ wchar_t filter_w[GIT_WIN_PATH];
git__DIR *new = NULL;
if (!dir || !init_filter(filter, sizeof(filter), dir))
@@ -41,12 +40,8 @@ git__DIR *git__opendir(const char *dir)
if (!new->dir)
goto fail;
- filter_w = gitwin_to_utf16(filter);
- if (!filter_w)
- goto fail;
-
+ git__utf8_to_16(filter_w, GIT_WIN_PATH, filter);
new->h = FindFirstFileW(filter_w, &new->f);
- git__free(filter_w);
if (new->h == INVALID_HANDLE_VALUE) {
giterr_set(GITERR_OS, "Could not open directory '%s'", dir);
@@ -85,16 +80,9 @@ int git__readdir_ext(
if (wcslen(d->f.cFileName) >= sizeof(entry->d_name))
return -1;
+ git__utf16_to_8(entry->d_name, d->f.cFileName);
entry->d_ino = 0;
- if (WideCharToMultiByte(
- gitwin_get_codepage(), 0, d->f.cFileName, -1,
- entry->d_name, GIT_PATH_MAX, NULL, NULL) == 0)
- {
- giterr_set(GITERR_OS, "Could not convert filename to UTF-8");
- return -1;
- }
-
*result = entry;
if (is_dir != NULL)
@@ -113,8 +101,8 @@ struct git__dirent *git__readdir(git__DIR *d)
void git__rewinddir(git__DIR *d)
{
- char filter[4096];
- wchar_t* filter_w;
+ char filter[GIT_WIN_PATH];
+ wchar_t filter_w[GIT_WIN_PATH];
if (!d)
return;
@@ -125,12 +113,11 @@ void git__rewinddir(git__DIR *d)
d->first = 0;
}
- if (!init_filter(filter, sizeof(filter), d->dir) ||
- (filter_w = gitwin_to_utf16(filter)) == NULL)
+ if (!init_filter(filter, sizeof(filter), d->dir))
return;
+ git__utf8_to_16(filter_w, GIT_WIN_PATH, filter);
d->h = FindFirstFileW(filter_w, &d->f);
- git__free(filter_w);
if (d->h == INVALID_HANDLE_VALUE)
giterr_set(GITERR_OS, "Could not open directory '%s'", d->dir);
View
9 src/win32/posix.h
@@ -21,13 +21,10 @@ GIT_INLINE(int) p_link(const char *old, const char *new)
GIT_INLINE(int) p_mkdir(const char *path, mode_t mode)
{
- wchar_t* buf = gitwin_to_utf16(path);
- int ret = _wmkdir(buf);
-
+ wchar_t buf[GIT_WIN_PATH];
GIT_UNUSED(mode);
-
- git__free(buf);
- return ret;
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return _wmkdir(buf);
}
extern int p_unlink(const char *path);
View
146 src/win32/posix_w32.c
@@ -15,16 +15,10 @@
int p_unlink(const char *path)
{
- int ret = 0;
- wchar_t* buf;
-
- if ((buf = gitwin_to_utf16(path)) != NULL) {
- _wchmod(buf, 0666);
- ret = _wunlink(buf);
- git__free(buf);
- }
-
- return ret;
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ _wchmod(buf, 0666);
+ return _wunlink(buf);
}
int p_fsync(int fd)
@@ -61,10 +55,10 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft)
static int do_lstat(const char *file_name, struct stat *buf)
{
WIN32_FILE_ATTRIBUTE_DATA fdata;
+ wchar_t fbuf[GIT_WIN_PATH];
DWORD last_error;
- wchar_t* fbuf = gitwin_to_utf16(file_name);
- if (!fbuf)
- return -1;
+
+ git__utf8_to_16(fbuf, GIT_WIN_PATH, file_name);
if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) {
int fMode = S_IREAD;
@@ -90,8 +84,6 @@ static int do_lstat(const char *file_name, struct stat *buf)
buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
-
- git__free(fbuf);
return 0;
}
@@ -101,7 +93,6 @@ static int do_lstat(const char *file_name, struct stat *buf)
else if (last_error == ERROR_PATH_NOT_FOUND)
errno = ENOTDIR;
- git__free(fbuf);
return -1;
}
@@ -143,7 +134,7 @@ int p_readlink(const char *link, char *target, size_t target_len)
static fpath_func pGetFinalPath = NULL;
HANDLE hFile;
DWORD dwRet;
- wchar_t* link_w;
+ wchar_t link_w[GIT_WIN_PATH];
wchar_t* target_w;
int error = 0;
@@ -166,8 +157,7 @@ int p_readlink(const char *link, char *target, size_t target_len)
}
}
- link_w = gitwin_to_utf16(link);
- GITERR_CHECK_ALLOC(link_w);
+ git__utf8_to_16(link_w, GIT_WIN_PATH, link);
hFile = CreateFileW(link_w, // file to open
GENERIC_READ, // open for reading
@@ -177,8 +167,6 @@ int p_readlink(const char *link, char *target, size_t target_len)
FILE_FLAG_BACKUP_SEMANTICS, // normal file
NULL); // no attr. template
- git__free(link_w);
-
if (hFile == INVALID_HANDLE_VALUE) {
giterr_set(GITERR_OS, "Cannot open '%s' for reading", link);
return -1;
@@ -235,16 +223,12 @@ int p_symlink(const char *old, const char *new)
int p_open(const char *path, int flags, ...)
{
- int fd;
- wchar_t* buf;
+ wchar_t buf[GIT_WIN_PATH];
mode_t mode = 0;
- buf = gitwin_to_utf16(path);
- if (!buf)
- return -1;
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
- if (flags & O_CREAT)
- {
+ if (flags & O_CREAT) {
va_list arg_list;
va_start(arg_list, flags);
@@ -252,27 +236,20 @@ int p_open(const char *path, int flags, ...)
va_end(arg_list);
}
- fd = _wopen(buf, flags | _O_BINARY, mode);
-
- git__free(buf);
- return fd;
+ return _wopen(buf, flags | _O_BINARY, mode);
}
int p_creat(const char *path, mode_t mode)
{
- int fd;
- wchar_t* buf = gitwin_to_utf16(path);
- if (!buf)
- return -1;
- fd = _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode);
- git__free(buf);
- return fd;
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode);
}
int p_getcwd(char *buffer_out, size_t size)
{
int ret;
- wchar_t* buf;
+ wchar_t *buf;
if ((size_t)((int)size) != size)
return -1;
@@ -296,64 +273,43 @@ int p_stat(const char* path, struct stat* buf)
int p_chdir(const char* path)
{
- wchar_t* buf = gitwin_to_utf16(path);
- int ret;
- if (!buf)
- return -1;
- ret = _wchdir(buf);
- git__free(buf);
- return ret;
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return _wchdir(buf);
}
int p_chmod(const char* path, mode_t mode)
{
- wchar_t* buf = gitwin_to_utf16(path);
- int ret;
- if (!buf)
- return -1;
- ret = _wchmod(buf, mode);
- git__free(buf);
- return ret;
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return _wchmod(buf, mode);
}
int p_rmdir(const char* path)
{
- wchar_t* buf = gitwin_to_utf16(path);
- int ret;
- if (!buf)
- return -1;
- ret = _wrmdir(buf);
- git__free(buf);
- return ret;
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return _wrmdir(buf);
}
int p_hide_directory__w32(const char *path)
{
- int res;
- wchar_t* buf = gitwin_to_utf16(path);
- if (!buf)
- return -1;
-
- res = SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN);
- git__free(buf);
-
- return (res != 0) ? 0 : -1; /* MSDN states a "non zero" value indicates a success */
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return (SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN) != 0) ? 0 : -1;
}
char *p_realpath(const char *orig_path, char *buffer)
{
int ret, buffer_sz = 0;
- wchar_t* orig_path_w = gitwin_to_utf16(orig_path);
- wchar_t* buffer_w = (wchar_t*)git__malloc(GIT_PATH_MAX * sizeof(wchar_t));
-
- if (!orig_path_w || !buffer_w)
- return NULL;
+ wchar_t orig_path_w[GIT_WIN_PATH];
+ wchar_t buffer_w[GIT_WIN_PATH];
- ret = GetFullPathNameW(orig_path_w, GIT_PATH_MAX, buffer_w, NULL);
- git__free(orig_path_w);
+ git__utf8_to_16(orig_path_w, GIT_WIN_PATH, orig_path);
+ ret = GetFullPathNameW(orig_path_w, GIT_WIN_PATH, buffer_w, NULL);
/* According to MSDN, a return value equals to zero means a failure. */
- if (ret == 0 || ret > GIT_PATH_MAX) {
+ if (ret == 0 || ret > GIT_WIN_PATH) {
buffer = NULL;
goto done;
}
@@ -376,8 +332,7 @@ char *p_realpath(const char *orig_path, char *buffer)
}
}
- if (!git_path_exists(buffer))
- {
+ if (!git_path_exists(buffer)) {
if (buffer_sz > 0)
git__free(buffer);
@@ -386,9 +341,9 @@ char *p_realpath(const char *orig_path, char *buffer)
}
done:
- git__free(buffer_w);
if (buffer)
git_path_mkposix(buffer);
+
return buffer;
}
@@ -443,32 +398,19 @@ int p_setenv(const char* name, const char* value, int overwrite)
int p_access(const char* path, mode_t mode)
{
- wchar_t *buf = gitwin_to_utf16(path);
- int ret;
- if (!buf)
- return -1;
-
- ret = _waccess(buf, mode);
- git__free(buf);
-
- return ret;
+ wchar_t buf[GIT_WIN_PATH];
+ git__utf8_to_16(buf, GIT_WIN_PATH, path);
+ return _waccess(buf, mode);
}
int p_rename(const char *from, const char *to)
{
- wchar_t *wfrom = gitwin_to_utf16(from);
- wchar_t *wto = gitwin_to_utf16(to);
- int ret;
-
- if (!wfrom || !wto)
- return -1;
-
- ret = MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1;
-
- git__free(wfrom);
- git__free(wto);
+ wchar_t wfrom[GIT_WIN_PATH];
+ wchar_t wto[GIT_WIN_PATH];
- return ret;
+ git__utf8_to_16(wfrom, GIT_WIN_PATH, from);
+ git__utf8_to_16(wto, GIT_WIN_PATH, to);
+ return MoveFileExW(wfrom, wto, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) ? 0 : -1;
}
int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags)
View
131 src/win32/utf-conv.c
@@ -7,86 +7,75 @@
#include "common.h"
#include "utf-conv.h"
-#include "git2/windows.h"
-/*
- * Default codepage value
- */
-static int _active_codepage = CP_UTF8;
-
-void gitwin_set_codepage(unsigned int codepage)
-{
- _active_codepage = codepage;
-}
-
-unsigned int gitwin_get_codepage(void)
-{
- return _active_codepage;
-}
-
-void gitwin_set_utf8(void)
-{
- _active_codepage = CP_UTF8;
-}
+#define U16_LEAD(c) (wchar_t)(((c)>>10)+0xd7c0)
+#define U16_TRAIL(c) (wchar_t)(((c)&0x3ff)|0xdc00)
-wchar_t* gitwin_to_utf16(const char* str)
+#if 0
+void git__utf8_to_16(wchar_t *dest, size_t length, const char *src)
{
- wchar_t* ret;
- int cb;
-
- if (!str)
- return NULL;
-
- cb = MultiByteToWideChar(_active_codepage, 0, str, -1, NULL, 0);
- if (cb == 0)
- return (wchar_t *)git__calloc(1, sizeof(wchar_t));
-
- ret = (wchar_t *)git__malloc(cb * sizeof(wchar_t));
- if (!ret)
- return NULL;
-
- if (MultiByteToWideChar(_active_codepage, 0, str, -1, ret, (int)cb) == 0) {
- giterr_set(GITERR_OS, "Could not convert string to UTF-16");
- git__free(ret);
- ret = NULL;
+ wchar_t *pDest = dest;
+ uint32_t ch;
+ const uint8_t* pSrc = (uint8_t*) src;
+
+ assert(dest && src && length);
+
+ length--;
+
+ while(*pSrc && length > 0) {
+ ch = *pSrc++;
+ length--;
+
+ if(ch < 0xc0) {
+ /*
+ * ASCII, or a trail byte in lead position which is treated like
+ * a single-byte sequence for better character boundary
+ * resynchronization after illegal sequences.
+ */
+ *pDest++ = (wchar_t)ch;
+ continue;
+ } else if(ch < 0xe0) { /* U+0080..U+07FF */
+ if (pSrc[0]) {
+ /* 0x3080 = (0xc0 << 6) + 0x80 */
+ *pDest++ = (wchar_t)((ch << 6) + *pSrc++ - 0x3080);
+ continue;
+ }
+ } else if(ch < 0xf0) { /* U+0800..U+FFFF */
+ if (pSrc[0] && pSrc[1]) {
+ /* no need for (ch & 0xf) because the upper bits are truncated after <<12 in the cast to (UChar) */
+ /* 0x2080 = (0x80 << 6) + 0x80 */
+ ch = (ch << 12) + (*pSrc++ << 6);
+ *pDest++ = (wchar_t)(ch + *pSrc++ - 0x2080);
+ continue;
+ }
+ } else /* f0..f4 */ { /* U+10000..U+10FFFF */
+ if (length >= 1 && pSrc[0] && pSrc[1] && pSrc[2]) {
+ /* 0x3c82080 = (0xf0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80 */
+ ch = (ch << 18) + (*pSrc++ << 12);
+ ch += *pSrc++ << 6;
+ ch += *pSrc++ - 0x3c82080;
+ *(pDest++) = U16_LEAD(ch);
+ *(pDest++) = U16_TRAIL(ch);
+ length--; /* two bytes for this character */
+ continue;
+ }
+ }
+
+ /* truncated character at the end */
+ *pDest++ = 0xfffd;
+ break;
}
- return ret;
+ *pDest++ = 0x0;
}
+#endif
-int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len)
+void git__utf8_to_16(wchar_t *dest, size_t length, const char *src)
{
- int result = MultiByteToWideChar(
- _active_codepage, 0, str, -1, buffer, (int)len);
- if (result == 0)
- giterr_set(GITERR_OS, "Could not convert string to UTF-16");
- return result;
+ MultiByteToWideChar(CP_UTF8, 0, src, -1, dest, length);
}
-char* gitwin_from_utf16(const wchar_t* str)
+void git__utf16_to_8(char *out, const wchar_t *input)
{
- char* ret;
- int cb;
-
- if (!str)
- return NULL;
-
- cb = WideCharToMultiByte(_active_codepage, 0, str, -1, NULL, 0, NULL, NULL);
- if (cb == 0)
- return (char *)git__calloc(1, sizeof(char));
-
- ret = (char*)git__malloc(cb);
- if (!ret)
- return NULL;
-
- if (WideCharToMultiByte(
- _active_codepage, 0, str, -1, ret, (int)cb, NULL, NULL) == 0)
- {
- giterr_set(GITERR_OS, "Could not convert string to UTF-8");
- git__free(ret);
- ret = NULL;
- }
-
- return ret;
-
+ WideCharToMultiByte(CP_UTF8, 0, input, -1, out, GIT_WIN_PATH, NULL, NULL);
}
View
7 src/win32/utf-conv.h
@@ -10,9 +10,10 @@
#ifndef INCLUDE_git_utfconv_h__
#define INCLUDE_git_utfconv_h__
-wchar_t* gitwin_to_utf16(const char* str);
-int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len);
-char* gitwin_from_utf16(const wchar_t* str);
+#define GIT_WIN_PATH (260 + 1)
+
+void git__utf8_to_16(wchar_t *dest, size_t length, const char *src);
+void git__utf16_to_8(char *dest, const wchar_t *src);
#endif
View
27 tests-clar/clar_helpers.c
@@ -9,6 +9,7 @@ void clar_on_init(void)
void clar_on_shutdown(void)
{
git_threads_shutdown();
+ giterr_clear();
}
void cl_git_mkfile(const char *filename, const char *content)
@@ -55,22 +56,23 @@ void cl_git_rewritefile(const char *filename, const char *new_content)
char *cl_getenv(const char *name)
{
- wchar_t *name_utf16 = gitwin_to_utf16(name);
- DWORD value_len, alloc_len;
+ wchar_t name_utf16[GIT_WIN_PATH];
+ DWORD alloc_len;
wchar_t *value_utf16;
char *value_utf8;
- cl_assert(name_utf16);
+ git__utf8_to_16(name_utf16, GIT_WIN_PATH, name);
alloc_len = GetEnvironmentVariableW(name_utf16, NULL, 0);
if (alloc_len <= 0)
return NULL;
+ alloc_len = GIT_WIN_PATH;
cl_assert(value_utf16 = git__calloc(alloc_len, sizeof(wchar_t)));
- value_len = GetEnvironmentVariableW(name_utf16, value_utf16, alloc_len);
- cl_assert_equal_i(value_len, alloc_len - 1);
+ GetEnvironmentVariableW(name_utf16, value_utf16, alloc_len);
- cl_assert(value_utf8 = gitwin_from_utf16(value_utf16));
+ cl_assert(value_utf8 = git__malloc(alloc_len));
+ git__utf16_to_8(value_utf8, value_utf16);
git__free(value_utf16);
@@ -79,17 +81,16 @@ char *cl_getenv(const char *name)
int cl_setenv(const char *name, const char *value)
{
- wchar_t *name_utf16 = gitwin_to_utf16(name);
- wchar_t *value_utf16 = value ? gitwin_to_utf16(value) : NULL;
+ wchar_t name_utf16[GIT_WIN_PATH];
+ wchar_t value_utf16[GIT_WIN_PATH];
- cl_assert(name_utf16);
- cl_assert(SetEnvironmentVariableW(name_utf16, value_utf16));
+ git__utf8_to_16(name_utf16, GIT_WIN_PATH, name);
- git__free(name_utf16);
- git__free(value_utf16);
+ if (value != NULL)
+ git__utf8_to_16(value_utf16, GIT_WIN_PATH, value);
+ cl_assert(SetEnvironmentVariableW(name_utf16, value ? value_utf16 : NULL));
return 0;
-
}
#else

No commit comments for this range

Something went wrong with that request. Please try again.