Remove some more explicit loops
[openal-soft.git] / common / win_main_utf8.h
blobfaddc25794b40d55a6ae5281fd9b03294a98fe66
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
8 * characters).
10 * For MinGW, you must link with -municode
12 #ifdef _WIN32
13 #define WIN32_LEAN_AND_MEAN
14 #include <windows.h>
15 #include <shellapi.h>
17 static FILE *my_fopen(const char *fname, const char *mode)
19 WCHAR *wname=NULL, *wmode=NULL;
20 int namelen, modelen;
21 FILE *file = NULL;
22 errno_t err;
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);
30 return NULL;
33 wname = 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);
39 if(err)
41 errno = err;
42 file = NULL;
45 free(wname);
47 return file;
49 #define fopen my_fopen
52 static char **arglist;
53 static void cleanup_arglist(void)
55 free(arglist);
58 static void GetUnicodeArgs(int *argc, char ***argv)
60 size_t total;
61 wchar_t **args;
62 int nargs, i;
64 args = CommandLineToArgvW(GetCommandLineW(), &nargs);
65 if(!args)
67 fprintf(stderr, "Failed to get command line args: %ld\n", GetLastError());
68 exit(EXIT_FAILURE);
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 = 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);
84 *argc = nargs;
86 LocalFree(args);
88 #define GET_UNICODE_ARGS(argc, argv) GetUnicodeArgs(argc, argv)
90 #else
92 /* Do nothing. */
93 #define GET_UNICODE_ARGS(argc, argv)
95 #endif
97 #endif /* WIN_MAIN_UTF8_H */