1 #ifndef WIN_MAIN_UTF8_H
2 #define WIN_MAIN_UTF8_H
4 /* For Windows systems this overrides main() so that the argv strings are UTF-8
5 * encoded, and also overrides fopen to accept UTF-8 filenames. Working with
6 * wmain directly complicates cross-platform compatibility, while normal main()
7 * in Windows uses the current codepage (which has limited availability of
10 * For MinGW, you must link with -municode
13 #define WIN32_LEAN_AND_MEAN
17 static FILE *my_fopen(const char *fname
, const char *mode
)
19 WCHAR
*wname
=NULL
, *wmode
=NULL
;
23 namelen
= MultiByteToWideChar(CP_UTF8
, 0, fname
, -1, NULL
, 0);
24 modelen
= MultiByteToWideChar(CP_UTF8
, 0, mode
, -1, NULL
, 0);
26 if(namelen
<= 0 || modelen
<= 0)
28 fprintf(stderr
, "Failed to convert UTF-8 fname \"%s\", mode \"%s\"\n", fname
, mode
);
32 wname
= calloc(sizeof(WCHAR
), namelen
+modelen
);
33 wmode
= wname
+ namelen
;
34 MultiByteToWideChar(CP_UTF8
, 0, fname
, -1, wname
, namelen
);
35 MultiByteToWideChar(CP_UTF8
, 0, mode
, -1, wmode
, modelen
);
37 file
= _wfopen(wname
, wmode
);
43 #define fopen my_fopen
46 static char **arglist
;
47 static void cleanup_arglist(void)
52 static void GetUnicodeArgs(int *argc
, char ***argv
)
58 args
= CommandLineToArgvW(GetCommandLineW(), &nargs
);
61 fprintf(stderr
, "Failed to get command line args: %ld\n", GetLastError());
65 total
= sizeof(**argv
) * nargs
;
66 for(i
= 0;i
< nargs
;i
++)
67 total
+= WideCharToMultiByte(CP_UTF8
, 0, args
[i
], -1, NULL
, 0, NULL
, NULL
);
69 atexit(cleanup_arglist
);
70 arglist
= *argv
= calloc(1, total
);
71 (*argv
)[0] = (char*)(*argv
+ nargs
);
72 for(i
= 0;i
< nargs
-1;i
++)
74 int len
= WideCharToMultiByte(CP_UTF8
, 0, args
[i
], -1, (*argv
)[i
], 65535, NULL
, NULL
);
75 (*argv
)[i
+1] = (*argv
)[i
] + len
;
77 WideCharToMultiByte(CP_UTF8
, 0, args
[i
], -1, (*argv
)[i
], 65535, NULL
, NULL
);
82 #define GET_UNICODE_ARGS(argc, argv) GetUnicodeArgs(argc, argv)
87 #define GET_UNICODE_ARGS(argc, argv)
91 #endif /* WIN_MAIN_UTF8_H */