Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / cython / src / bin / cython_freeze
1 #!/usr/bin/env python
2 """
3 Create a C file for embedding one or more Cython source files.
4 Requires Cython 0.11.2 (or perhaps newer).
5
6 See Demos/freeze/README.txt for more details.
7 """
8
9 import optparse
10 from os.path import splitext, basename
11
12 usage= '%prog [-o outfile] [-p] module [module ...]'
13 description = 'Create a C file for embedding Cython modules.'
14 p = optparse.OptionParser(usage=usage, description=description)
15 p.add_option('-o', '--output', metavar='FILE',
16         help='write output to FILE instead of standard output')
17 p.add_option('-p', '--pymain', action='store_true', default=False,
18         help='do not automatically run the first module as __main__')
19
20 options, args = p.parse_args()
21
22 if len(args) < 1:
23     p.print_help()
24     p.exit(1)
25
26 if options.output:
27     import sys
28     old_stdout = sys.stdout
29     sys.stdout = open(options.output, 'w')
30
31 modules = [basename(splitext(x)[0]).replace('.', '_') for x in args]
32
33 print """\
34 #include <Python.h>
35 #include <locale.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #ifdef __FreeBSD__
40 #include <floatingpoint.h>
41 #endif
42
43 #if PY_MAJOR_VERSION < 3
44 # define MODINIT(name)  init ## name
45 #else
46 # define MODINIT(name)  PyInit_ ## name
47 #endif
48 """
49
50 for name in modules:
51     print "PyMODINIT_FUNC MODINIT(%s) (void);" % name
52
53 print """
54 static struct _inittab inittab[] = {"""
55
56 for name in modules:
57     print '    {"%(name)s", MODINIT(%(name)s)},' % {'name' : name}
58
59 print """    {NULL, NULL}
60 };
61 """,
62
63 if not options.pymain:
64     print "\nextern int __pyx_module_is_main_%s;" % modules[0]
65
66 print """
67 #if PY_MAJOR_VERSION < 3
68 int main(int argc, char** argv) {
69 #elif defined(WIN32) || defined(MS_WINDOWS)
70 int wmain(int argc, wchar_t **argv) {
71 #else
72 static int python_main(int argc, wchar_t **argv) {
73 #endif
74 """,
75 if not options.pymain:
76     print """\
77     PyObject *m = NULL;
78     int r = 0;
79 """,
80 print """\
81     /* 754 requires that FP exceptions run in "no stop" mode by default,
82      * and until C vendors implement C99's ways to control FP exceptions,
83      * Python requires non-stop mode.  Alas, some platforms enable FP
84      * exceptions by default.  Here we disable them.
85      */
86 #ifdef __FreeBSD__
87     fp_except_t m;
88
89     m = fpgetmask();
90     fpsetmask(m & ~FP_X_OFL);
91 #endif
92     if (PyImport_ExtendInittab(inittab)) {
93         fprintf(stderr, "No memory\\n");
94         exit(1);
95     }
96 """,
97 if options.pymain:
98     print """\
99     return Py_Main(argc, argv);
100 }
101 """
102 else:
103     print """\
104     Py_SetProgramName(argv[0]);
105     Py_Initialize();
106     PySys_SetArgv(argc, argv);
107     __pyx_module_is_main_%(main)s = 1;
108     m = PyImport_ImportModule(inittab[0].name);
109     if (!m) {
110         r = 1;
111         PyErr_Print(); /* This exits with the right code if SystemExit. */
112 #if PY_MAJOR_VERSION < 3
113         if (Py_FlushLine())
114             PyErr_Clear();
115 #endif
116     }
117     Py_XDECREF(m);
118     Py_Finalize();
119     return r;
120 }
121 """ % {'main' : modules[0]},
122
123 print r"""
124 #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
125 static wchar_t*
126 char2wchar(char* arg)
127 {
128         wchar_t *res;
129 #ifdef HAVE_BROKEN_MBSTOWCS
130         /* Some platforms have a broken implementation of
131          * mbstowcs which does not count the characters that
132          * would result from conversion.  Use an upper bound.
133          */
134         size_t argsize = strlen(arg);
135 #else
136         size_t argsize = mbstowcs(NULL, arg, 0);
137 #endif
138         size_t count;
139         unsigned char *in;
140         wchar_t *out;
141 #ifdef HAVE_MBRTOWC
142         mbstate_t mbs;
143 #endif
144         if (argsize != (size_t)-1) {
145                 res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
146                 if (!res)
147                         goto oom;
148                 count = mbstowcs(res, arg, argsize+1);
149                 if (count != (size_t)-1) {
150                         wchar_t *tmp;
151                         /* Only use the result if it contains no
152                            surrogate characters. */
153                         for (tmp = res; *tmp != 0 &&
154                                      (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
155                                 ;
156                         if (*tmp == 0)
157                                 return res;
158                 }
159                 free(res);
160         }
161         /* Conversion failed. Fall back to escaping with surrogateescape. */
162 #ifdef HAVE_MBRTOWC
163         /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
164
165         /* Overallocate; as multi-byte characters are in the argument, the
166            actual output could use less memory. */
167         argsize = strlen(arg) + 1;
168         res = malloc(argsize*sizeof(wchar_t));
169         if (!res) goto oom;
170         in = (unsigned char*)arg;
171         out = res;
172         memset(&mbs, 0, sizeof mbs);
173         while (argsize) {
174                 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
175                 if (converted == 0)
176                         /* Reached end of string; null char stored. */
177                         break;
178                 if (converted == (size_t)-2) {
179                         /* Incomplete character. This should never happen,
180                            since we provide everything that we have -
181                            unless there is a bug in the C library, or I
182                            misunderstood how mbrtowc works. */
183                         fprintf(stderr, "unexpected mbrtowc result -2\n");
184                         return NULL;
185                 }
186                 if (converted == (size_t)-1) {
187                         /* Conversion error. Escape as UTF-8b, and start over
188                            in the initial shift state. */
189                         *out++ = 0xdc00 + *in++;
190                         argsize--;
191                         memset(&mbs, 0, sizeof mbs);
192                         continue;
193                 }
194                 if (*out >= 0xd800 && *out <= 0xdfff) {
195                         /* Surrogate character.  Escape the original
196                            byte sequence with surrogateescape. */
197                         argsize -= converted;
198                         while (converted--)
199                                 *out++ = 0xdc00 + *in++;
200                         continue;
201                 }
202                 /* successfully converted some bytes */
203                 in += converted;
204                 argsize -= converted;
205                 out++;
206         }
207 #else
208         /* Cannot use C locale for escaping; manually escape as if charset
209            is ASCII (i.e. escape all bytes > 128. This will still roundtrip
210            correctly in the locale's charset, which must be an ASCII superset. */
211         res = malloc((strlen(arg)+1)*sizeof(wchar_t));
212         if (!res) goto oom;
213         in = (unsigned char*)arg;
214         out = res;
215         while(*in)
216                 if(*in < 128)
217                         *out++ = *in++;
218                 else
219                         *out++ = 0xdc00 + *in++;
220         *out = 0;
221 #endif
222         return res;
223 oom:
224         fprintf(stderr, "out of memory\n");
225         return NULL;
226 }
227
228 int
229 main(int argc, char **argv)
230 {
231         wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
232         /* We need a second copies, as Python might modify the first one. */
233         wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
234         int i, res;
235         char *oldloc;
236         if (!argv_copy || !argv_copy2) {
237                 fprintf(stderr, "out of memory\n");
238                 return 1;
239         }
240         oldloc = strdup(setlocale(LC_ALL, NULL));
241         setlocale(LC_ALL, "");
242         for (i = 0; i < argc; i++) {
243                 argv_copy2[i] = argv_copy[i] = char2wchar(argv[i]);
244                 if (!argv_copy[i])
245                         return 1;
246         }
247         setlocale(LC_ALL, oldloc);
248         free(oldloc);
249         res = python_main(argc, argv_copy);
250         for (i = 0; i < argc; i++) {
251                 free(argv_copy2[i]);
252         }
253         free(argv_copy);
254         free(argv_copy2);
255         return res;
256 }
257 #endif"""