summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorLibravatar Karsten Blees <blees@dcon.de>2011-01-16 18:28:27 +0100
committerLibravatar Junio C Hamano <gitster@pobox.com>2014-06-16 10:56:47 -0700
commit3f046148d92e1aa6c0872a6f11f39a4a5740f939 (patch)
treea2cfdfed809979002d5caa0c8099588e22f1baee /compat
parentWin32: Unicode arguments (outgoing) (diff)
downloadtgif-3f046148d92e1aa6c0872a6f11f39a4a5740f939.tar.xz
Win32: Unicode arguments (incoming)
Convert command line arguments from UTF-16 to UTF-8 on startup. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat')
-rw-r--r--compat/mingw.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 8a7b0476c2..3baaa4dfae 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1943,10 +1943,48 @@ int xwcstoutf(char *utf, const wchar_t *wcs, size_t utflen)
*/
int _CRT_glob = 0;
+typedef struct {
+ int newmode;
+} _startupinfo;
+
+extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***env, int glob,
+ _startupinfo *si);
+
+static NORETURN void die_startup()
+{
+ fputs("fatal: not enough memory for initialization", stderr);
+ exit(128);
+}
+
void mingw_startup()
{
- /* copy executable name to argv[0] */
- __argv[0] = xstrdup(_pgmptr);
+ int i, len, maxlen, argc;
+ char *buffer;
+ wchar_t **wenv, **wargv;
+ _startupinfo si;
+
+ /* get wide char arguments and environment */
+ si.newmode = 0;
+ if (__wgetmainargs(&argc, &wargv, &wenv, _CRT_glob, &si) < 0)
+ die_startup();
+
+ /* determine size of argv and environ conversion buffer */
+ maxlen = wcslen(_wpgmptr);
+ for (i = 1; i < argc; i++)
+ maxlen = max(maxlen, wcslen(wargv[i]));
+
+ /* allocate buffer (wchar_t encodes to max 3 UTF-8 bytes) */
+ maxlen = 3 * maxlen + 1;
+ buffer = xmalloc(maxlen);
+
+ /* convert command line arguments and environment to UTF-8 */
+ len = xwcstoutf(buffer, _wpgmptr, maxlen);
+ __argv[0] = xmemdupz(buffer, len);
+ for (i = 1; i < argc; i++) {
+ len = xwcstoutf(buffer, wargv[i], maxlen);
+ __argv[i] = xmemdupz(buffer, len);
+ }
+ free(buffer);
/* initialize critical section for waitpid pinfo_t list */
InitializeCriticalSection(&pinfo_cs);