1//////////////////// MainFunction ////////////////////
2
3#ifdef __FreeBSD__
4#include <floatingpoint.h>
5#endif
6
7#if PY_MAJOR_VERSION < 3
8int %(main_method)s(int argc, char** argv) {
9#elif defined(WIN32) || defined(MS_WINDOWS)
10int %(wmain_method)s(int argc, wchar_t **argv) {
11#else
12static 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
55static 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;
153oom:
154    fprintf(stderr, "out of memory\\n");
155    return NULL;
156}
157
158int
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