1 #ifndef WIN_MAIN_UTF8_H
2 #define WIN_MAIN_UTF8_H
4 /* For Windows systems this provides a way to get UTF-8 encoded argv strings,
5 * and also overrides fopen to accept UTF-8 filenames. Working with wmain
6 * directly complicates cross-platform compatibility, while normal main() in
7 * 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
;
24 namelen
= MultiByteToWideChar(CP_UTF8
, 0, fname
, -1, NULL
, 0);
25 modelen
= MultiByteToWideChar(CP_UTF8
, 0, mode
, -1, NULL
, 0);
27 if(namelen
<= 0 || modelen
<= 0)
29 fprintf(stderr
, "Failed to convert UTF-8 fname \"%s\", mode \"%s\"\n", fname
, mode
);
33 wname
= (WCHAR
*)calloc(sizeof(WCHAR
), namelen
+modelen
);
34 wmode
= wname
+ namelen
;
35 MultiByteToWideChar(CP_UTF8
, 0, fname
, -1, wname
, namelen
);
36 MultiByteToWideChar(CP_UTF8
, 0, mode
, -1, wmode
, modelen
);
38 err
= _wfopen_s(&file
, wname
, wmode
);
49 #define fopen my_fopen
52 static char **arglist
;
53 static void cleanup_arglist(void)
58 static void GetUnicodeArgs(int *argc
, char ***argv
)
64 args
= CommandLineToArgvW(GetCommandLineW(), &nargs
);
67 fprintf(stderr
, "Failed to get command line args: %ld\n", GetLastError());
71 total
= sizeof(**argv
) * nargs
;
72 for(i
= 0;i
< nargs
;i
++)
73 total
+= WideCharToMultiByte(CP_UTF8
, 0, args
[i
], -1, NULL
, 0, NULL
, NULL
);
75 atexit(cleanup_arglist
);
76 arglist
= *argv
= (char**)calloc(1, total
);
77 (*argv
)[0] = (char*)(*argv
+ nargs
);
78 for(i
= 0;i
< nargs
-1;i
++)
80 int len
= WideCharToMultiByte(CP_UTF8
, 0, args
[i
], -1, (*argv
)[i
], 65535, NULL
, NULL
);
81 (*argv
)[i
+1] = (*argv
)[i
] + len
;
83 WideCharToMultiByte(CP_UTF8
, 0, args
[i
], -1, (*argv
)[i
], 65535, NULL
, NULL
);
88 #define GET_UNICODE_ARGS(argc, argv) GetUnicodeArgs(argc, argv)
93 #define GET_UNICODE_ARGS(argc, argv)
97 #endif /* WIN_MAIN_UTF8_H */