1 //////////////////// MainFunction //////////////////// 2 3 #ifdef __FreeBSD__ 4 #include <floatingpoint.h> 5 #endif 6 7 #if PY_MAJOR_VERSION < 3 8 int %(main_method)s(int argc, char** argv) { 9 #elif defined(WIN32) || defined(MS_WINDOWS) 10 int %(wmain_method)s(int argc, wchar_t **argv) { 11 #else 12 static int __Pyx_main(int argc, wchar_t **argv) { 13 #endif 14 /* 754 requires that FP exceptions run in "no stop" mode by default, 15 * and until C vendors implement C99's ways to control FP exceptions, 16 * Python requires non-stop mode. Alas, some platforms enable FP 17 * exceptions by default. Here we disable them. 18 */ 19 #ifdef __FreeBSD__ 20 fp_except_t m; 21 22 m = fpgetmask(); 23 fpsetmask(m & ~FP_X_OFL); 24 #endif 25 if (argc && argv) 26 Py_SetProgramName(argv[0]); 27 Py_Initialize(); 28 if (argc && argv) 29 PySys_SetArgv(argc, argv); 30 { /* init module '%(module_name)s' as '__main__' */ 31 PyObject* m = NULL; 32 %(module_is_main)s = 1; 33 #if PY_MAJOR_VERSION < 3 34 init%(module_name)s(); 35 #else 36 m = PyInit_%(module_name)s(); 37 #endif 38 if (PyErr_Occurred()) { 39 PyErr_Print(); /* This exits with the right code if SystemExit. */ 40 #if PY_MAJOR_VERSION < 3 41 if (Py_FlushLine()) PyErr_Clear(); 42 #endif 43 return 1; 44 } 45 Py_XDECREF(m); 46 } 47 Py_Finalize(); 48 return 0; 49 } 50 51 52 #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS) 53 #include <locale.h> 54 55 static wchar_t* 56 __Pyx_char2wchar(char* arg) 57 { 58 wchar_t *res; 59 #ifdef HAVE_BROKEN_MBSTOWCS 60 /* Some platforms have a broken implementation of 61 * mbstowcs which does not count the characters that 62 * would result from conversion. Use an upper bound. 63 */ 64 size_t argsize = strlen(arg); 65 #else 66 size_t argsize = mbstowcs(NULL, arg, 0); 67 #endif 68 size_t count; 69 unsigned char *in; 70 wchar_t *out; 71 #ifdef HAVE_MBRTOWC 72 mbstate_t mbs; 73 #endif 74 if (argsize != (size_t)-1) { 75 res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t)); 76 if (!res) 77 goto oom; 78 count = mbstowcs(res, arg, argsize+1); 79 if (count != (size_t)-1) { 80 wchar_t *tmp; 81 /* Only use the result if it contains no 82 surrogate characters. */ 83 for (tmp = res; *tmp != 0 && 84 (*tmp < 0xd800 || *tmp > 0xdfff); tmp++) 85 ; 86 if (*tmp == 0) 87 return res; 88 } 89 free(res); 90 } 91 /* Conversion failed. Fall back to escaping with surrogateescape. */ 92 #ifdef HAVE_MBRTOWC 93 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */ 94 95 /* Overallocate; as multi-byte characters are in the argument, the 96 actual output could use less memory. */ 97 argsize = strlen(arg) + 1; 98 res = malloc(argsize*sizeof(wchar_t)); 99 if (!res) goto oom; 100 in = (unsigned char*)arg; 101 out = res; 102 memset(&mbs, 0, sizeof mbs); 103 while (argsize) { 104 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs); 105 if (converted == 0) 106 /* Reached end of string; null char stored. */ 107 break; 108 if (converted == (size_t)-2) { 109 /* Incomplete character. This should never happen, 110 since we provide everything that we have - 111 unless there is a bug in the C library, or I 112 misunderstood how mbrtowc works. */ 113 fprintf(stderr, "unexpected mbrtowc result -2\\n"); 114 return NULL; 115 } 116 if (converted == (size_t)-1) { 117 /* Conversion error. Escape as UTF-8b, and start over 118 in the initial shift state. */ 119 *out++ = 0xdc00 + *in++; 120 argsize--; 121 memset(&mbs, 0, sizeof mbs); 122 continue; 123 } 124 if (*out >= 0xd800 && *out <= 0xdfff) { 125 /* Surrogate character. Escape the original 126 byte sequence with surrogateescape. */ 127 argsize -= converted; 128 while (converted--) 129 *out++ = 0xdc00 + *in++; 130 continue; 131 } 132 /* successfully converted some bytes */ 133 in += converted; 134 argsize -= converted; 135 out++; 136 } 137 #else 138 /* Cannot use C locale for escaping; manually escape as if charset 139 is ASCII (i.e. escape all bytes > 128. This will still roundtrip 140 correctly in the locale's charset, which must be an ASCII superset. */ 141 res = malloc((strlen(arg)+1)*sizeof(wchar_t)); 142 if (!res) goto oom; 143 in = (unsigned char*)arg; 144 out = res; 145 while(*in) 146 if(*in < 128) 147 *out++ = *in++; 148 else 149 *out++ = 0xdc00 + *in++; 150 *out = 0; 151 #endif 152 return res; 153 oom: 154 fprintf(stderr, "out of memory\\n"); 155 return NULL; 156 } 157 158 int 159 %(main_method)s(int argc, char **argv) 160 { 161 if (!argc) { 162 return __Pyx_main(0, NULL); 163 } 164 else { 165 wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc); 166 /* We need a second copies, as Python might modify the first one. */ 167 wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc); 168 int i, res; 169 char *oldloc; 170 if (!argv_copy || !argv_copy2) { 171 fprintf(stderr, "out of memory\\n"); 172 return 1; 173 } 174 oldloc = strdup(setlocale(LC_ALL, NULL)); 175 setlocale(LC_ALL, ""); 176 for (i = 0; i < argc; i++) { 177 argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]); 178 if (!argv_copy[i]) 179 return 1; 180 } 181 setlocale(LC_ALL, oldloc); 182 free(oldloc); 183 res = __Pyx_main(argc, argv_copy); 184 for (i = 0; i < argc; i++) { 185 free(argv_copy2[i]); 186 } 187 free(argv_copy); 188 free(argv_copy2); 189 return res; 190 } 191 } 192 #endif 193