diff --git a/include/git2/windows.h b/include/git2/windows.h new file mode 100644 index 000000000..6a2e9e2cd --- /dev/null +++ b/include/git2/windows.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2009-2011 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 + diff --git a/src/config.c b/src/config.c index f53afa145..ad6f88575 100644 --- a/src/config.c +++ b/src/config.c @@ -370,7 +370,7 @@ static int win32_find_system(char *system_config_path) return GIT_ENOTFOUND; } - apphome_utf8 = conv_utf16_to_utf8(apphome_utf16); + apphome_utf8 = gitwin_from_utf16(apphome_utf16); free(apphome_utf16); if (strlen(apphome_utf8) >= GIT_PATH_MAX) { diff --git a/src/win32/dir.c b/src/win32/dir.c index ab50318e3..fea74b4eb 100644 --- a/src/win32/dir.c +++ b/src/win32/dir.c @@ -6,7 +6,8 @@ */ #define GIT__WIN32_NO_WRAP_DIR #include "dir.h" -#include "utf8-conv.h" +#include "utf-conv.h" +#include "git2/windows.h" static int init_filter(char *filter, size_t n, const char *dir) { @@ -43,7 +44,7 @@ git__DIR *git__opendir(const char *dir) } strcpy(new->dir, dir); - filter_w = conv_utf8_to_utf16(filter); + filter_w = gitwin_to_utf16(filter); new->h = FindFirstFileW(filter_w, &new->f); free(filter_w); @@ -73,7 +74,7 @@ struct git__dirent *git__readdir(git__DIR *d) return NULL; d->entry.d_ino = 0; - WideCharToMultiByte(CP_UTF8, 0, d->f.cFileName, -1, d->entry.d_name, GIT_PATH_MAX, NULL, NULL); + WideCharToMultiByte(gitwin_get_codepage(), 0, d->f.cFileName, -1, d->entry.d_name, GIT_PATH_MAX, NULL, NULL); return &d->entry; } @@ -90,7 +91,7 @@ void git__rewinddir(git__DIR *d) d->first = 0; if (init_filter(filter, sizeof(filter), d->dir)) { - filter_w = conv_utf8_to_utf16(filter); + filter_w = gitwin_to_utf16(filter); d->h = FindFirstFileW(filter_w, &d->f); free(filter_w); diff --git a/src/win32/posix.h b/src/win32/posix.h index 442717e42..3774e7883 100644 --- a/src/win32/posix.h +++ b/src/win32/posix.h @@ -9,7 +9,7 @@ #include "common.h" #include "fnmatch.h" -#include "utf8-conv.h" +#include "utf-conv.h" GIT_INLINE(int) p_link(const char *GIT_UNUSED(old), const char *GIT_UNUSED(new)) { @@ -21,7 +21,7 @@ GIT_INLINE(int) p_link(const char *GIT_UNUSED(old), const char *GIT_UNUSED(new)) GIT_INLINE(int) p_mkdir(const char *path, int GIT_UNUSED(mode)) { - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); int ret = _wmkdir(buf); GIT_UNUSED_ARG(mode) diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index cc17cc71f..a05aafcca 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -6,7 +6,7 @@ */ #include "posix.h" #include "path.h" -#include "utf8-conv.h" +#include "utf-conv.h" #include #include #include @@ -17,7 +17,7 @@ int p_unlink(const char *path) int ret = 0; wchar_t* buf; - buf = conv_utf8_to_utf16(path); + buf = gitwin_to_utf16(path); _wchmod(buf, 0666); ret = _wunlink(buf); free(buf); @@ -59,7 +59,7 @@ 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 = conv_utf8_to_utf16(file_name); + wchar_t* fbuf = gitwin_to_utf16(file_name); if (GetFileAttributesExW(fbuf, GetFileExInfoStandard, &fdata)) { int fMode = S_IREAD; @@ -161,7 +161,7 @@ int p_readlink(const char *link, char *target, size_t target_len) "'GetFinalPathNameByHandleW' is not available in this platform"); } - link_w = conv_utf8_to_utf16(link); + link_w = gitwin_to_utf16(link); hFile = CreateFileW(link_w, // file to open GENERIC_READ, // open for reading @@ -223,7 +223,7 @@ int p_readlink(const char *link, char *target, size_t target_len) int p_open(const char *path, int flags) { int fd; - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); fd = _wopen(buf, flags | _O_BINARY); free(buf); @@ -233,7 +233,7 @@ int p_open(const char *path, int flags) int p_creat(const char *path, int mode) { int fd; - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); fd = _wopen(buf, _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY, mode); free(buf); @@ -261,7 +261,7 @@ int p_stat(const char* path, struct stat* buf) int p_chdir(const char* path) { - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); int ret = _wchdir(buf); free(buf); @@ -270,7 +270,7 @@ int p_chdir(const char* path) int p_chmod(const char* path, int mode) { - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); int ret = _wchmod(buf, mode); free(buf); @@ -279,7 +279,7 @@ int p_chmod(const char* path, int mode) int p_rmdir(const char* path) { - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); int ret = _wrmdir(buf); free(buf); @@ -289,7 +289,7 @@ int p_rmdir(const char* path) int p_hide_directory__w32(const char *path) { int error; - wchar_t* buf = conv_utf8_to_utf16(path); + wchar_t* buf = gitwin_to_utf16(path); error = SetFileAttributesW(buf, FILE_ATTRIBUTE_HIDDEN) != 0 ? GIT_SUCCESS : GIT_ERROR; /* MSDN states a "non zero" value indicates a success */ @@ -305,7 +305,7 @@ int p_hide_directory__w32(const char *path) char *p_realpath(const char *orig_path, char *buffer) { int ret, alloc = 0; - wchar_t* orig_path_w = conv_utf8_to_utf16(orig_path); + 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 (buffer == NULL) { @@ -380,7 +380,7 @@ int p_setenv(const char* name, const char* value, int overwrite) int p_access(const char* path, int mode) { - wchar_t *buf = conv_utf8_to_utf16(path); + wchar_t *buf = gitwin_to_utf16(path); int ret; ret = _waccess(buf, mode); diff --git a/src/win32/utf8-conv.c b/src/win32/utf-conv.c similarity index 61% rename from src/win32/utf8-conv.c rename to src/win32/utf-conv.c index dec6f8e79..cb607839e 100644 --- a/src/win32/utf8-conv.c +++ b/src/win32/utf-conv.c @@ -6,9 +6,29 @@ */ #include "common.h" -#include "utf8-conv.h" +#include "utf-conv.h" -wchar_t* conv_utf8_to_utf16(const char* str) +/* + * 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; +} + +wchar_t* gitwin_to_utf16(const char* str) { wchar_t* ret; int cb; @@ -29,7 +49,7 @@ wchar_t* conv_utf8_to_utf16(const char* str) ret = (wchar_t*)git__malloc(cb); - if (MultiByteToWideChar(CP_UTF8, 0, str, -1, ret, cb) == 0) { + if (MultiByteToWideChar(_active_codepage, 0, str, -1, ret, cb) == 0) { free(ret); ret = NULL; } @@ -37,7 +57,7 @@ wchar_t* conv_utf8_to_utf16(const char* str) return ret; } -char* conv_utf16_to_utf8(const wchar_t* str) +char* gitwin_from_utf16(const wchar_t* str) { char* ret; int cb; @@ -58,7 +78,7 @@ char* conv_utf16_to_utf8(const wchar_t* str) ret = (char*)git__malloc(cb); - if (WideCharToMultiByte(CP_UTF8, 0, str, -1, ret, cb, NULL, NULL) == 0) { + if (WideCharToMultiByte(_active_codepage, 0, str, -1, ret, cb, NULL, NULL) == 0) { free(ret); ret = NULL; } diff --git a/src/win32/utf8-conv.h b/src/win32/utf-conv.h similarity index 59% rename from src/win32/utf8-conv.h rename to src/win32/utf-conv.h index 1967ac3a1..da03e3385 100644 --- a/src/win32/utf8-conv.h +++ b/src/win32/utf-conv.h @@ -7,11 +7,11 @@ #include -#ifndef INCLUDE_git_utf8conv_h__ -#define INCLUDE_git_utf8conv_h__ +#ifndef INCLUDE_git_utfconv_h__ +#define INCLUDE_git_utfconv_h__ -wchar_t* conv_utf8_to_utf16(const char* str); -char* conv_utf16_to_utf8(const wchar_t* str); +wchar_t* gitwin_to_utf16(const char* str); +char* gitwin_from_utf16(const wchar_t* str); #endif