Roll src/third_party/skia c6f3e2c:efb7e42
[chromium-blink-merge.git] / third_party / cython / src / bin / cython_freeze
blob74f365689ab1169274b9ec21761fcd096371d8f8
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).
6 See Demos/freeze/README.txt for more details.
7 """
9 import optparse
10 from os.path import splitext, basename
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__')
20 options, args = p.parse_args()
22 if len(args) < 1:
23 p.print_help()
24 p.exit(1)
26 if options.output:
27 import sys
28 old_stdout = sys.stdout
29 sys.stdout = open(options.output, 'w')
31 modules = [basename(splitext(x)[0]).replace('.', '_') for x in args]
33 print """\
34 #include <Python.h>
35 #include <locale.h>
36 #include <stdio.h>
37 #include <stdlib.h>
39 #ifdef __FreeBSD__
40 #include <floatingpoint.h>
41 #endif
43 #if PY_MAJOR_VERSION < 3
44 # define MODINIT(name) init ## name
45 #else
46 # define MODINIT(name) PyInit_ ## name
47 #endif
48 """
50 for name in modules:
51 print "PyMODINIT_FUNC MODINIT(%s) (void);" % name
53 print """
54 static struct _inittab inittab[] = {"""
56 for name in modules:
57 print ' {"%(name)s", MODINIT(%(name)s)},' % {'name' : name}
59 print """ {NULL, NULL}
61 """,
63 if not options.pymain:
64 print "\nextern int __pyx_module_is_main_%s;" % modules[0]
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.
86 #ifdef __FreeBSD__
87 fp_except_t m;
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);
96 """,
97 if options.pymain:
98 print """\
99 return Py_Main(argc, argv);
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
117 Py_XDECREF(m);
118 Py_Finalize();
119 return r;
121 """ % {'main' : modules[0]},
123 print r"""
124 #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
125 static wchar_t*
126 char2wchar(char* arg)
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.
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++)
156 if (*tmp == 0)
157 return res;
159 free(res);
161 /* Conversion failed. Fall back to escaping with surrogateescape. */
162 #ifdef HAVE_MBRTOWC
163 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
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;
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;
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;
202 /* successfully converted some bytes */
203 in += converted;
204 argsize -= converted;
205 out++;
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;
229 main(int argc, char **argv)
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;
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;
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]);
253 free(argv_copy);
254 free(argv_copy2);
255 return res;
257 #endif"""