Loading [MathJax]/extensions/tex2jax.js
Free Electron
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
win_main_utf8.h
1 #ifndef WIN_MAIN_UTF8_H
2 #define WIN_MAIN_UTF8_H
3 
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).
9  *
10  * For MinGW, you must link with -municode
11  */
12 #ifdef _WIN32
13 #define WIN32_LEAN_AND_MEAN
14 #include <windows.h>
15 #include <shellapi.h>
16 
17 static FILE *my_fopen(const char *fname, const char *mode)
18 {
19  WCHAR *wname=NULL, *wmode=NULL;
20  int namelen, modelen;
21  FILE *file = NULL;
22  errno_t err;
23 
24  namelen = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0);
25  modelen = MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
26 
27  if(namelen <= 0 || modelen <= 0)
28  {
29  fprintf(stderr, "Failed to convert UTF-8 fname \"%s\", mode \"%s\"\n", fname, mode);
30  return NULL;
31  }
32 
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);
37 
38  err = _wfopen_s(&file, wname, wmode);
39  if(err)
40  {
41  errno = err;
42  file = NULL;
43  }
44 
45  free(wname);
46 
47  return file;
48 }
49 #define fopen my_fopen
50 
51 
52 static char **arglist;
53 static void cleanup_arglist(void)
54 {
55  free(arglist);
56 }
57 
58 static void GetUnicodeArgs(int *argc, char ***argv)
59 {
60  size_t total;
61  wchar_t **args;
62  int nargs, i;
63 
64  args = CommandLineToArgvW(GetCommandLineW(), &nargs);
65  if(!args)
66  {
67  fprintf(stderr, "Failed to get command line args: %ld\n", GetLastError());
68  exit(EXIT_FAILURE);
69  }
70 
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);
74 
75  atexit(cleanup_arglist);
76  arglist = *argv = calloc(1, total);
77  (*argv)[0] = (char*)(*argv + nargs);
78  for(i = 0;i < nargs-1;i++)
79  {
80  int len = WideCharToMultiByte(CP_UTF8, 0, args[i], -1, (*argv)[i], 65535, NULL, NULL);
81  (*argv)[i+1] = (*argv)[i] + len;
82  }
83  WideCharToMultiByte(CP_UTF8, 0, args[i], -1, (*argv)[i], 65535, NULL, NULL);
84  *argc = nargs;
85 
86  LocalFree(args);
87 }
88 #define GET_UNICODE_ARGS(argc, argv) GetUnicodeArgs(argc, argv)
89 
90 #else
91 
92 /* Do nothing. */
93 #define GET_UNICODE_ARGS(argc, argv)
94 
95 #endif
96 
97 #endif /* WIN_MAIN_UTF8_H */