Cython has moved to github.
cython-devel
view Cython/Compiler/ModuleNode.py @ 3091:1a2e04bc1395
remove dependency on structmember.h
| author | Lisandro Dalcin <dalcinl@gmail.com> |
|---|---|
| date | Thu Mar 11 17:21:13 2010 -0300 (2 years ago) |
| parents | 6fd7d210d482 |
| children | 9c647a057180 |
line source
1 #
2 # Pyrex - Module parse tree node
3 #
5 import os, time
6 from PyrexTypes import CPtrType
7 import Future
9 try:
10 set
11 except NameError: # Python 2.3
12 from sets import Set as set
14 import Annotate
15 import Code
16 import Naming
17 import Nodes
18 import Options
19 import PyrexTypes
20 import TypeSlots
21 import Version
22 import DebugFlags
24 from Errors import error, warning
25 from PyrexTypes import py_object_type
26 from Cython.Utils import open_new_file, replace_suffix
27 from Code import UtilityCode
28 from StringEncoding import escape_byte_string, EncodedString
31 def check_c_declarations_pxd(module_node):
32 module_node.scope.check_c_classes_pxd()
33 return module_node
35 def check_c_declarations(module_node):
36 module_node.scope.check_c_classes()
37 module_node.scope.check_c_functions()
38 return module_node
40 class ModuleNode(Nodes.Node, Nodes.BlockNode):
41 # doc string or None
42 # body StatListNode
43 #
44 # referenced_modules [ModuleScope]
45 # full_module_name string
46 #
47 # scope The module scope.
48 # compilation_source A CompilationSource (see Main)
49 # directives Top-level compiler directives
51 child_attrs = ["body"]
52 directives = None
54 def analyse_declarations(self, env):
55 if Options.embed_pos_in_docstring:
56 env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
57 if not self.doc is None:
58 env.doc = EncodedString(env.doc + u'\n' + self.doc)
59 env.doc.encoding = self.doc.encoding
60 else:
61 env.doc = self.doc
62 env.directives = self.directives
63 self.body.analyse_declarations(env)
65 def process_implementation(self, options, result):
66 env = self.scope
67 env.return_type = PyrexTypes.c_void_type
68 self.referenced_modules = []
69 self.find_referenced_modules(env, self.referenced_modules, {})
70 if options.recursive:
71 self.generate_dep_file(env, result)
72 self.generate_c_code(env, options, result)
73 self.generate_h_code(env, options, result)
74 self.generate_api_code(env, result)
76 def has_imported_c_functions(self):
77 for module in self.referenced_modules:
78 for entry in module.cfunc_entries:
79 if entry.defined_in_pxd:
80 return 1
81 return 0
83 def generate_dep_file(self, env, result):
84 modules = self.referenced_modules
85 if len(modules) > 1 or env.included_files:
86 dep_file = replace_suffix(result.c_file, ".dep")
87 f = open(dep_file, "w")
88 try:
89 for module in modules:
90 if module is not env:
91 f.write("cimport %s\n" % module.qualified_name)
92 for path in module.included_files:
93 f.write("include %s\n" % path)
94 finally:
95 f.close()
97 def generate_h_code(self, env, options, result):
98 def h_entries(entries, pxd = 0):
99 return [entry for entry in entries
100 if entry.visibility == 'public' or pxd and entry.defined_in_pxd]
101 h_types = h_entries(env.type_entries)
102 h_vars = h_entries(env.var_entries)
103 h_funcs = h_entries(env.cfunc_entries)
104 h_extension_types = h_entries(env.c_class_entries)
105 if h_types or h_vars or h_funcs or h_extension_types:
106 result.h_file = replace_suffix(result.c_file, ".h")
107 h_code = Code.CCodeWriter()
108 Code.GlobalState(h_code)
109 if options.generate_pxi:
110 result.i_file = replace_suffix(result.c_file, ".pxi")
111 i_code = Code.PyrexCodeWriter(result.i_file)
112 else:
113 i_code = None
114 guard = Naming.h_guard_prefix + env.qualified_name.replace(".", "__")
115 h_code.put_h_guard(guard)
116 self.generate_extern_c_macro_definition(h_code)
117 self.generate_type_header_code(h_types, h_code)
118 h_code.putln("")
119 h_code.putln("#ifndef %s" % Naming.api_guard_prefix + self.api_name(env))
120 if h_vars:
121 h_code.putln("")
122 for entry in h_vars:
123 self.generate_public_declaration(entry, h_code, i_code)
124 if h_funcs:
125 h_code.putln("")
126 for entry in h_funcs:
127 self.generate_public_declaration(entry, h_code, i_code)
128 if h_extension_types:
129 h_code.putln("")
130 for entry in h_extension_types:
131 self.generate_cclass_header_code(entry.type, h_code)
132 if i_code:
133 self.generate_cclass_include_code(entry.type, i_code)
134 h_code.putln("")
135 h_code.putln("#endif")
136 h_code.putln("")
137 h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
138 h_code.putln("")
139 h_code.putln("#endif")
141 h_code.copyto(open_new_file(result.h_file))
143 def generate_public_declaration(self, entry, h_code, i_code):
144 h_code.putln("%s %s;" % (
145 Naming.extern_c_macro,
146 entry.type.declaration_code(
147 entry.cname, dll_linkage = "DL_IMPORT")))
148 if i_code:
149 i_code.putln("cdef extern %s" %
150 entry.type.declaration_code(entry.cname, pyrex = 1))
152 def api_name(self, env):
153 return env.qualified_name.replace(".", "__")
155 def generate_api_code(self, env, result):
156 api_funcs = []
157 public_extension_types = []
158 has_api_extension_types = 0
159 for entry in env.cfunc_entries:
160 if entry.api:
161 api_funcs.append(entry)
162 for entry in env.c_class_entries:
163 if entry.visibility == 'public':
164 public_extension_types.append(entry)
165 if entry.api:
166 has_api_extension_types = 1
167 if api_funcs or has_api_extension_types:
168 result.api_file = replace_suffix(result.c_file, "_api.h")
169 h_code = Code.CCodeWriter()
170 Code.GlobalState(h_code)
171 name = self.api_name(env)
172 guard = Naming.api_guard_prefix + name
173 h_code.put_h_guard(guard)
174 h_code.putln('#include "Python.h"')
175 if result.h_file:
176 h_code.putln('#include "%s"' % os.path.basename(result.h_file))
177 for entry in public_extension_types:
178 type = entry.type
179 h_code.putln("")
180 h_code.putln("static PyTypeObject *%s;" % type.typeptr_cname)
181 h_code.putln("#define %s (*%s)" % (
182 type.typeobj_cname, type.typeptr_cname))
183 if api_funcs:
184 h_code.putln("")
185 for entry in api_funcs:
186 type = CPtrType(entry.type)
187 h_code.putln("static %s;" % type.declaration_code(entry.cname))
188 h_code.putln("")
189 h_code.put_h_guard(Naming.api_func_guard + "import_module")
190 h_code.put(import_module_utility_code.impl)
191 h_code.putln("")
192 h_code.putln("#endif")
193 if api_funcs:
194 h_code.putln("")
195 h_code.put(function_import_utility_code.impl)
196 if public_extension_types:
197 h_code.putln("")
198 h_code.put(type_import_utility_code.impl)
199 h_code.putln("")
200 h_code.putln("static int import_%s(void) {" % name)
201 h_code.putln("PyObject *module = 0;")
202 h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
203 h_code.putln("if (!module) goto bad;")
204 for entry in api_funcs:
205 sig = entry.type.signature_string()
206 h_code.putln(
207 'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;' % (
208 entry.name,
209 entry.cname,
210 sig))
211 h_code.putln("Py_DECREF(module); module = 0;")
212 for entry in public_extension_types:
213 self.generate_type_import_call(
214 entry.type, h_code,
215 "if (!%s) goto bad;" % entry.type.typeptr_cname)
216 h_code.putln("return 0;")
217 h_code.putln("bad:")
218 h_code.putln("Py_XDECREF(module);")
219 h_code.putln("return -1;")
220 h_code.putln("}")
221 h_code.putln("")
222 h_code.putln("#endif")
224 h_code.copyto(open_new_file(result.api_file))
226 def generate_cclass_header_code(self, type, h_code):
227 h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
228 Naming.extern_c_macro,
229 type.typeobj_cname))
230 #self.generate_obj_struct_definition(type, h_code)
232 def generate_cclass_include_code(self, type, i_code):
233 i_code.putln("cdef extern class %s.%s:" % (
234 type.module_name, type.name))
235 i_code.indent()
236 var_entries = type.scope.var_entries
237 if var_entries:
238 for entry in var_entries:
239 i_code.putln("cdef %s" %
240 entry.type.declaration_code(entry.cname, pyrex = 1))
241 else:
242 i_code.putln("pass")
243 i_code.dedent()
245 def generate_c_code(self, env, options, result):
246 modules = self.referenced_modules
248 if Options.annotate or options.annotate:
249 emit_linenums = False
250 rootwriter = Annotate.AnnotationCCodeWriter()
251 else:
252 emit_linenums = options.emit_linenums
253 rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums)
254 globalstate = Code.GlobalState(rootwriter, emit_linenums)
255 globalstate.initialize_main_c_code()
256 h_code = globalstate['h_code']
258 self.generate_module_preamble(env, modules, h_code)
260 globalstate.module_pos = self.pos
261 globalstate.directives = self.directives
263 globalstate.use_utility_code(refnanny_utility_code)
265 code = globalstate['before_global_var']
266 code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
267 code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
268 code.putln("")
269 code.putln("/* Implementation of %s */" % env.qualified_name)
271 code = globalstate['all_the_rest']
273 self.generate_cached_builtins_decls(env, code)
274 self.body.generate_function_definitions(env, code)
275 code.mark_pos(None)
276 self.generate_typeobj_definitions(env, code)
277 self.generate_method_table(env, code)
278 self.generate_filename_init_prototype(code)
279 if env.has_import_star:
280 self.generate_import_star(env, code)
281 self.generate_pymoduledef_struct(env, code)
283 # init_globals is inserted before this
284 self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
285 self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
286 if Options.embed:
287 self.generate_main_method(env, globalstate['main_method'])
288 self.generate_filename_table(globalstate['filename_table'])
290 self.generate_declarations_for_modules(env, modules, globalstate)
291 h_code.write('\n')
293 for utilcode in env.utility_code_list:
294 globalstate.use_utility_code(utilcode)
295 globalstate.finalize_main_c_code()
297 f = open_new_file(result.c_file)
298 rootwriter.copyto(f)
299 f.close()
300 result.c_file_generated = 1
301 if Options.annotate or options.annotate:
302 self.annotate(rootwriter)
303 rootwriter.save_annotation(result.main_source_file, result.c_file)
305 def find_referenced_modules(self, env, module_list, modules_seen):
306 if env not in modules_seen:
307 modules_seen[env] = 1
308 for imported_module in env.cimported_modules:
309 self.find_referenced_modules(imported_module, module_list, modules_seen)
310 module_list.append(env)
312 def sort_types_by_inheritance(self, type_dict, getkey):
313 # copy the types into a list moving each parent type before
314 # its first child
315 type_items = type_dict.items()
316 type_list = []
317 for i, item in enumerate(type_items):
318 key, new_entry = item
320 # collect all base classes to check for children
321 hierarchy = set()
322 base = new_entry
323 while base:
324 base_type = base.type.base_type
325 if not base_type:
326 break
327 base_key = getkey(base_type)
328 hierarchy.add(base_key)
329 base = type_dict.get(base_key)
330 new_entry.base_keys = hierarchy
332 # find the first (sub-)subclass and insert before that
333 for j in range(i):
334 entry = type_list[j]
335 if key in entry.base_keys:
336 type_list.insert(j, new_entry)
337 break
338 else:
339 type_list.append(new_entry)
340 return type_list
342 def sort_type_hierarchy(self, module_list, env):
343 vtab_dict = {}
344 vtabslot_dict = {}
345 for module in module_list:
346 for entry in module.c_class_entries:
347 if not entry.in_cinclude:
348 type = entry.type
349 if type.vtabstruct_cname:
350 vtab_dict[type.vtabstruct_cname] = entry
351 all_defined_here = module is env
352 for entry in module.type_entries:
353 if all_defined_here or entry.defined_in_pxd:
354 type = entry.type
355 if type.is_extension_type and not entry.in_cinclude:
356 type = entry.type
357 vtabslot_dict[type.objstruct_cname] = entry
359 def vtabstruct_cname(entry_type):
360 return entry_type.vtabstruct_cname
361 vtab_list = self.sort_types_by_inheritance(
362 vtab_dict, vtabstruct_cname)
364 def objstruct_cname(entry_type):
365 return entry_type.objstruct_cname
366 vtabslot_list = self.sort_types_by_inheritance(
367 vtabslot_dict, objstruct_cname)
369 return (vtab_list, vtabslot_list)
371 def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
372 vtabslot_entries = set(vtabslot_list)
373 for module in modules:
374 definition = module is env
375 if definition:
376 type_entries = module.type_entries
377 else:
378 type_entries = []
379 for entry in module.type_entries:
380 if entry.defined_in_pxd:
381 type_entries.append(entry)
382 for entry in type_entries:
383 if not entry.in_cinclude:
384 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
385 type = entry.type
386 if type.is_typedef: # Must test this first!
387 self.generate_typedef(entry, code)
388 elif type.is_struct_or_union:
389 self.generate_struct_union_definition(entry, code)
390 elif type.is_enum:
391 self.generate_enum_definition(entry, code)
392 elif type.is_extension_type and entry not in vtabslot_entries:
393 self.generate_obj_struct_definition(type, code)
394 for entry in vtabslot_list:
395 self.generate_obj_struct_definition(entry.type, code)
396 for entry in vtab_list:
397 self.generate_typeobject_predeclaration(entry, code)
398 self.generate_exttype_vtable_struct(entry, code)
399 self.generate_exttype_vtabptr_declaration(entry, code)
401 def generate_declarations_for_modules(self, env, modules, globalstate):
402 typecode = globalstate['type_declarations']
403 typecode.putln("")
404 typecode.putln("/* Type declarations */")
405 vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
406 self.generate_type_definitions(
407 env, modules, vtab_list, vtabslot_list, typecode)
408 modulecode = globalstate['module_declarations']
409 for module in modules:
410 defined_here = module is env
411 modulecode.putln("/* Module declarations from %s */" %
412 module.qualified_name.encode("ASCII", "ignore"))
413 self.generate_global_declarations(module, modulecode, defined_here)
414 self.generate_cfunction_predeclarations(module, modulecode, defined_here)
416 def generate_module_preamble(self, env, cimported_modules, code):
417 code.putln("/* Generated by Cython %s on %s */" % (
418 Version.version, time.asctime()))
419 code.putln("")
420 code.putln("#define PY_SSIZE_T_CLEAN")
421 for filename in env.python_include_files:
422 code.putln('#include "%s"' % filename)
423 code.putln("#ifndef Py_PYTHON_H")
424 code.putln(" #error Python headers needed to compile C extensions, please install development version of Python.")
425 code.putln("#else")
426 code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
428 code.put("""
429 #include <stddef.h> /* For offsetof */
430 #ifndef offsetof
431 #define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
432 #endif
434 #ifndef PY_LONG_LONG
435 #define PY_LONG_LONG LONG_LONG
436 #endif
437 #ifndef DL_EXPORT
438 #define DL_EXPORT(t) t
439 #endif
440 #if PY_VERSION_HEX < 0x02040000
441 #define METH_COEXIST 0
442 #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
443 #define PyDict_Contains(d,o) PySequence_Contains(d,o)
444 #endif
446 #if PY_VERSION_HEX < 0x02050000
447 typedef int Py_ssize_t;
448 #define PY_SSIZE_T_MAX INT_MAX
449 #define PY_SSIZE_T_MIN INT_MIN
450 #define PY_FORMAT_SIZE_T \"\"
451 #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
452 #define PyInt_AsSsize_t(o) PyInt_AsLong(o)
453 #define PyNumber_Index(o) PyNumber_Int(o)
454 #define PyIndex_Check(o) PyNumber_Check(o)
455 #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
456 #endif
458 #if PY_VERSION_HEX < 0x02060000
459 #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
460 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
461 #define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
462 #define PyVarObject_HEAD_INIT(type, size) \\
463 PyObject_HEAD_INIT(type) size,
464 #define PyType_Modified(t)
466 typedef struct {
467 void *buf;
468 PyObject *obj;
469 Py_ssize_t len;
470 Py_ssize_t itemsize;
471 int readonly;
472 int ndim;
473 char *format;
474 Py_ssize_t *shape;
475 Py_ssize_t *strides;
476 Py_ssize_t *suboffsets;
477 void *internal;
478 } Py_buffer;
480 #define PyBUF_SIMPLE 0
481 #define PyBUF_WRITABLE 0x0001
482 #define PyBUF_FORMAT 0x0004
483 #define PyBUF_ND 0x0008
484 #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
485 #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
486 #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
487 #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
488 #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
490 #endif
492 #if PY_MAJOR_VERSION < 3
493 #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
494 #else
495 #define __Pyx_BUILTIN_MODULE_NAME "builtins"
496 #endif
498 #if PY_MAJOR_VERSION >= 3
499 #define Py_TPFLAGS_CHECKTYPES 0
500 #define Py_TPFLAGS_HAVE_INDEX 0
501 #endif
503 #if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
504 #define Py_TPFLAGS_HAVE_NEWBUFFER 0
505 #endif
507 #if PY_MAJOR_VERSION >= 3
508 #define PyBaseString_Type PyUnicode_Type
509 #define PyString_Type PyUnicode_Type
510 #define PyString_CheckExact PyUnicode_CheckExact
511 #else
512 #define PyBytes_Type PyString_Type
513 #define PyBytes_CheckExact PyString_CheckExact
514 #endif
516 #if PY_MAJOR_VERSION >= 3
517 #define PyInt_Type PyLong_Type
518 #define PyInt_Check(op) PyLong_Check(op)
519 #define PyInt_CheckExact(op) PyLong_CheckExact(op)
520 #define PyInt_FromString PyLong_FromString
521 #define PyInt_FromUnicode PyLong_FromUnicode
522 #define PyInt_FromLong PyLong_FromLong
523 #define PyInt_FromSize_t PyLong_FromSize_t
524 #define PyInt_FromSsize_t PyLong_FromSsize_t
525 #define PyInt_AsLong PyLong_AsLong
526 #define PyInt_AS_LONG PyLong_AS_LONG
527 #define PyInt_AsSsize_t PyLong_AsSsize_t
528 #define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
529 #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
530 #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)
531 #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)
532 #else
533 """)
534 if Future.division in env.context.future_directives:
535 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y)")
536 code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y)")
537 else:
538 code.putln(" #define __Pyx_PyNumber_Divide(x,y) PyNumber_Divide(x,y)")
539 code.putln(" #define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceDivide(x,y)")
540 code.put("""
541 #endif
543 #if PY_MAJOR_VERSION >= 3
544 #define PyMethod_New(func, self, klass) PyInstanceMethod_New(func)
545 #endif
547 #if !defined(WIN32) && !defined(MS_WINDOWS)
548 #ifndef __stdcall
549 #define __stdcall
550 #endif
551 #ifndef __cdecl
552 #define __cdecl
553 #endif
554 #ifndef __fastcall
555 #define __fastcall
556 #endif
557 #else
558 #define _USE_MATH_DEFINES
559 #endif
561 #if PY_VERSION_HEX < 0x02050000
562 #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),((char *)(n)))
563 #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
564 #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),((char *)(n)))
565 #else
566 #define __Pyx_GetAttrString(o,n) PyObject_GetAttrString((o),(n))
567 #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
568 #define __Pyx_DelAttrString(o,n) PyObject_DelAttrString((o),(n))
569 #endif
571 #if PY_VERSION_HEX < 0x02050000
572 #define __Pyx_NAMESTR(n) ((char *)(n))
573 #define __Pyx_DOCSTR(n) ((char *)(n))
574 #else
575 #define __Pyx_NAMESTR(n) (n)
576 #define __Pyx_DOCSTR(n) (n)
577 #endif
578 """)
580 self.generate_extern_c_macro_definition(code)
581 code.putln("#include <math.h>")
582 code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
583 self.generate_includes(env, cimported_modules, code)
584 if env.directives['ccomplex']:
585 code.putln("")
586 code.putln("#if !defined(CYTHON_CCOMPLEX)")
587 code.putln("#define CYTHON_CCOMPLEX 1")
588 code.putln("#endif")
589 code.putln("")
590 code.put(Nodes.utility_function_predeclarations)
591 code.put(PyrexTypes.type_conversion_predeclarations)
592 code.put(Nodes.branch_prediction_macros)
593 code.putln('')
594 code.putln('static PyObject *%s;' % env.module_cname)
595 code.putln('static PyObject *%s;' % Naming.builtins_cname)
596 code.putln('static PyObject *%s;' % Naming.empty_tuple)
597 code.putln('static PyObject *%s;' % Naming.empty_bytes)
598 if Options.pre_import is not None:
599 code.putln('static PyObject *%s;' % Naming.preimport_cname)
600 code.putln('static int %s;' % Naming.lineno_cname)
601 code.putln('static int %s = 0;' % Naming.clineno_cname)
602 code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
603 code.putln('static const char *%s;' % Naming.filename_cname)
604 code.putln('static const char **%s;' % Naming.filetable_cname)
606 # XXX this is a mess
607 for utility_code in PyrexTypes.c_int_from_py_function.specialize_list:
608 env.use_utility_code(utility_code)
609 for utility_code in PyrexTypes.c_long_from_py_function.specialize_list:
610 env.use_utility_code(utility_code)
612 def generate_extern_c_macro_definition(self, code):
613 name = Naming.extern_c_macro
614 code.putln("#ifdef __cplusplus")
615 code.putln('#define %s extern "C"' % name)
616 code.putln("#else")
617 code.putln("#define %s extern" % name)
618 code.putln("#endif")
620 def generate_includes(self, env, cimported_modules, code):
621 includes = []
622 for filename in env.include_files:
623 # fake decoding of filenames to their original byte sequence
624 if filename[0] == '<' and filename[-1] == '>':
625 code.putln('#include %s' % filename)
626 else:
627 code.putln('#include "%s"' % filename)
629 def generate_filename_table(self, code):
630 code.putln("")
631 code.putln("static const char *%s[] = {" % Naming.filenames_cname)
632 if code.globalstate.filename_list:
633 for source_desc in code.globalstate.filename_list:
634 filename = os.path.basename(source_desc.get_filenametable_entry())
635 escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
636 code.putln('"%s",' %
637 escaped_filename)
638 else:
639 # Some C compilers don't like an empty array
640 code.putln("0")
641 code.putln("};")
643 def generate_type_predeclarations(self, env, code):
644 pass
646 def generate_type_header_code(self, type_entries, code):
647 # Generate definitions of structs/unions/enums/typedefs/objstructs.
648 #self.generate_gcc33_hack(env, code) # Is this still needed?
649 #for entry in env.type_entries:
650 for entry in type_entries:
651 if not entry.in_cinclude:
652 #print "generate_type_header_code:", entry.name, repr(entry.type) ###
653 type = entry.type
654 if type.is_typedef: # Must test this first!
655 self.generate_typedef(entry, code)
656 elif type.is_struct_or_union:
657 self.generate_struct_union_definition(entry, code)
658 elif type.is_enum:
659 self.generate_enum_definition(entry, code)
660 elif type.is_extension_type:
661 self.generate_obj_struct_definition(type, code)
663 def generate_gcc33_hack(self, env, code):
664 # Workaround for spurious warning generation in gcc 3.3
665 code.putln("")
666 for entry in env.c_class_entries:
667 type = entry.type
668 if not type.typedef_flag:
669 name = type.objstruct_cname
670 if name.startswith("__pyx_"):
671 tail = name[6:]
672 else:
673 tail = name
674 code.putln("typedef struct %s __pyx_gcc33_%s;" % (
675 name, tail))
677 def generate_typedef(self, entry, code):
678 base_type = entry.type.typedef_base_type
679 if base_type.is_numeric:
680 writer = code.globalstate['numeric_typedefs']
681 else:
682 writer = code
683 writer.putln("")
684 writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
686 def sue_header_footer(self, type, kind, name):
687 if type.typedef_flag:
688 header = "typedef %s {" % kind
689 footer = "} %s;" % name
690 else:
691 header = "%s %s {" % (kind, name)
692 footer = "};"
693 return header, footer
695 def generate_struct_union_definition(self, entry, code):
696 code.mark_pos(entry.pos)
697 type = entry.type
698 scope = type.scope
699 if scope:
700 kind = type.kind
701 packed = type.is_struct and type.packed
702 if packed:
703 kind = "%s %s" % (type.kind, "__Pyx_PACKED")
704 code.globalstate.use_utility_code(packed_struct_utility_code)
705 header, footer = \
706 self.sue_header_footer(type, kind, type.cname)
707 code.putln("")
708 if packed:
709 code.putln("#if !defined(__GNUC__)")
710 code.putln("#pragma pack(push, 1)")
711 code.putln("#endif")
712 code.putln(header)
713 var_entries = scope.var_entries
714 if not var_entries:
715 error(entry.pos,
716 "Empty struct or union definition not allowed outside a"
717 " 'cdef extern from' block")
718 for attr in var_entries:
719 code.putln(
720 "%s;" %
721 attr.type.declaration_code(attr.cname))
722 code.putln(footer)
723 if packed:
724 code.putln("#if !defined(__GNUC__)")
725 code.putln("#pragma pack(pop)")
726 code.putln("#endif")
728 def generate_enum_definition(self, entry, code):
729 code.mark_pos(entry.pos)
730 type = entry.type
731 name = entry.cname or entry.name or ""
732 header, footer = \
733 self.sue_header_footer(type, "enum", name)
734 code.putln("")
735 code.putln(header)
736 enum_values = entry.enum_values
737 if not enum_values:
738 error(entry.pos,
739 "Empty enum definition not allowed outside a"
740 " 'cdef extern from' block")
741 else:
742 last_entry = enum_values[-1]
743 # this does not really generate code, just builds the result value
744 for value_entry in enum_values:
745 if value_entry.value_node is not None:
746 value_entry.value_node.generate_evaluation_code(code)
748 for value_entry in enum_values:
749 if value_entry.value_node is None:
750 value_code = value_entry.cname
751 else:
752 value_code = ("%s = %s" % (
753 value_entry.cname,
754 value_entry.value_node.result()))
755 if value_entry is not last_entry:
756 value_code += ","
757 code.putln(value_code)
758 code.putln(footer)
760 def generate_typeobject_predeclaration(self, entry, code):
761 code.putln("")
762 name = entry.type.typeobj_cname
763 if name:
764 if entry.visibility == 'extern' and not entry.in_cinclude:
765 code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
766 Naming.extern_c_macro,
767 name))
768 elif entry.visibility == 'public':
769 #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
770 code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
771 Naming.extern_c_macro,
772 name))
773 # ??? Do we really need the rest of this? ???
774 #else:
775 # code.putln("staticforward PyTypeObject %s;" % name)
777 def generate_exttype_vtable_struct(self, entry, code):
778 code.mark_pos(entry.pos)
779 # Generate struct declaration for an extension type's vtable.
780 type = entry.type
781 scope = type.scope
782 if type.vtabstruct_cname:
783 code.putln("")
784 code.putln(
785 "struct %s {" %
786 type.vtabstruct_cname)
787 if type.base_type and type.base_type.vtabstruct_cname:
788 code.putln("struct %s %s;" % (
789 type.base_type.vtabstruct_cname,
790 Naming.obj_base_cname))
791 for method_entry in scope.cfunc_entries:
792 if not method_entry.is_inherited:
793 code.putln(
794 "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
795 code.putln(
796 "};")
798 def generate_exttype_vtabptr_declaration(self, entry, code):
799 code.mark_pos(entry.pos)
800 # Generate declaration of pointer to an extension type's vtable.
801 type = entry.type
802 if type.vtabptr_cname:
803 code.putln("static struct %s *%s;" % (
804 type.vtabstruct_cname,
805 type.vtabptr_cname))
807 def generate_obj_struct_definition(self, type, code):
808 code.mark_pos(type.pos)
809 # Generate object struct definition for an
810 # extension type.
811 if not type.scope:
812 return # Forward declared but never defined
813 header, footer = \
814 self.sue_header_footer(type, "struct", type.objstruct_cname)
815 code.putln("")
816 code.putln(header)
817 base_type = type.base_type
818 if base_type:
819 code.putln(
820 "%s%s %s;" % (
821 ("struct ", "")[base_type.typedef_flag],
822 base_type.objstruct_cname,
823 Naming.obj_base_cname))
824 else:
825 code.putln(
826 "PyObject_HEAD")
827 if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
828 code.putln(
829 "struct %s *%s;" % (
830 type.vtabstruct_cname,
831 type.vtabslot_cname))
832 for attr in type.scope.var_entries:
833 code.putln(
834 "%s;" %
835 attr.type.declaration_code(attr.cname))
836 code.putln(footer)
837 if type.objtypedef_cname is not None:
838 # Only for exposing public typedef name.
839 code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
841 def generate_global_declarations(self, env, code, definition):
842 code.putln("")
843 for entry in env.c_class_entries:
844 if definition or entry.defined_in_pxd:
845 code.putln("static PyTypeObject *%s = 0;" %
846 entry.type.typeptr_cname)
847 code.put_var_declarations(env.var_entries, static = 1,
848 dll_linkage = "DL_EXPORT", definition = definition)
850 def generate_cfunction_predeclarations(self, env, code, definition):
851 for entry in env.cfunc_entries:
852 if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
853 or entry.defined_in_pxd or entry.visibility == 'extern')):
854 if entry.visibility in ('public', 'extern'):
855 dll_linkage = "DL_EXPORT"
856 else:
857 dll_linkage = None
858 type = entry.type
859 if not definition and entry.defined_in_pxd:
860 type = CPtrType(type)
861 header = type.declaration_code(entry.cname,
862 dll_linkage = dll_linkage)
863 if entry.visibility == 'private':
864 storage_class = "static "
865 elif entry.visibility == 'public':
866 storage_class = ""
867 else:
868 storage_class = "%s " % Naming.extern_c_macro
869 if entry.func_modifiers:
870 modifiers = '%s ' % ' '.join([
871 modifier.upper() for modifier in entry.func_modifiers])
872 else:
873 modifiers = ''
874 code.putln("%s%s%s; /*proto*/" % (
875 storage_class,
876 modifiers,
877 header))
879 def generate_typeobj_definitions(self, env, code):
880 full_module_name = env.qualified_name
881 for entry in env.c_class_entries:
882 #print "generate_typeobj_definitions:", entry.name
883 #print "...visibility =", entry.visibility
884 if entry.visibility != 'extern':
885 type = entry.type
886 scope = type.scope
887 if scope: # could be None if there was an error
888 self.generate_exttype_vtable(scope, code)
889 self.generate_new_function(scope, code)
890 self.generate_dealloc_function(scope, code)
891 if scope.needs_gc():
892 self.generate_traverse_function(scope, code)
893 self.generate_clear_function(scope, code)
894 if scope.defines_any(["__getitem__"]):
895 self.generate_getitem_int_function(scope, code)
896 if scope.defines_any(["__setitem__", "__delitem__"]):
897 self.generate_ass_subscript_function(scope, code)
898 if scope.defines_any(["__setslice__", "__delslice__"]):
899 warning(self.pos, "__setslice__ and __delslice__ are not supported by Python 3, use __setitem__ and __getitem__ instead", 1)
900 self.generate_ass_slice_function(scope, code)
901 if scope.defines_any(["__getattr__","__getattribute__"]):
902 self.generate_getattro_function(scope, code)
903 if scope.defines_any(["__setattr__", "__delattr__"]):
904 self.generate_setattro_function(scope, code)
905 if scope.defines_any(["__get__"]):
906 self.generate_descr_get_function(scope, code)
907 if scope.defines_any(["__set__", "__delete__"]):
908 self.generate_descr_set_function(scope, code)
909 self.generate_property_accessors(scope, code)
910 self.generate_method_table(scope, code)
911 self.generate_getset_table(scope, code)
912 self.generate_typeobj_definition(full_module_name, entry, code)
914 def generate_exttype_vtable(self, scope, code):
915 # Generate the definition of an extension type's vtable.
916 type = scope.parent_type
917 if type.vtable_cname:
918 code.putln("static struct %s %s;" % (
919 type.vtabstruct_cname,
920 type.vtable_cname))
922 def generate_self_cast(self, scope, code):
923 type = scope.parent_type
924 code.putln(
925 "%s = (%s)o;" % (
926 type.declaration_code("p"),
927 type.declaration_code("")))
929 def generate_new_function(self, scope, code):
930 tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
931 slot_func = scope.mangle_internal("tp_new")
932 type = scope.parent_type
933 base_type = type.base_type
934 py_attrs = []
935 for entry in scope.var_entries:
936 if entry.type.is_pyobject:
937 py_attrs.append(entry)
938 need_self_cast = type.vtabslot_cname or py_attrs
939 code.putln("")
940 code.putln(
941 "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
942 % scope.mangle_internal("tp_new"))
943 if need_self_cast:
944 code.putln(
945 "%s;"
946 % scope.parent_type.declaration_code("p"))
947 if base_type:
948 tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
949 if tp_new is None:
950 tp_new = "%s->tp_new" % base_type.typeptr_cname
951 code.putln(
952 "PyObject *o = %s(t, a, k);" % tp_new)
953 else:
954 code.putln(
955 "PyObject *o = (*t->tp_alloc)(t, 0);")
956 code.putln(
957 "if (!o) return 0;")
958 if need_self_cast:
959 code.putln(
960 "p = %s;"
961 % type.cast_code("o"))
962 #if need_self_cast:
963 # self.generate_self_cast(scope, code)
964 if type.vtabslot_cname:
965 vtab_base_type = type
966 while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
967 vtab_base_type = vtab_base_type.base_type
968 if vtab_base_type is not type:
969 struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
970 else:
971 struct_type_cast = ""
972 code.putln("p->%s = %s%s;" % (
973 type.vtabslot_cname,
974 struct_type_cast, type.vtabptr_cname))
975 for entry in py_attrs:
976 if entry.name == "__weakref__":
977 code.putln("p->%s = 0;" % entry.cname)
978 else:
979 code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
980 entry = scope.lookup_here("__new__")
981 if entry and entry.is_special:
982 if entry.trivial_signature:
983 cinit_args = "o, %s, NULL" % Naming.empty_tuple
984 else:
985 cinit_args = "o, a, k"
986 code.putln(
987 "if (%s(%s) < 0) {" %
988 (entry.func_cname, cinit_args))
989 code.put_decref_clear("o", py_object_type, nanny=False);
990 code.putln(
991 "}")
992 code.putln(
993 "return o;")
994 code.putln(
995 "}")
997 def generate_dealloc_function(self, scope, code):
998 tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
999 slot_func = scope.mangle_internal("tp_dealloc")
1000 base_type = scope.parent_type.base_type
1001 if tp_slot.slot_code(scope) != slot_func:
1002 return # never used
1003 code.putln("")
1004 code.putln(
1005 "static void %s(PyObject *o) {"
1006 % scope.mangle_internal("tp_dealloc"))
1007 py_attrs = []
1008 weakref_slot = scope.lookup_here("__weakref__")
1009 for entry in scope.var_entries:
1010 if entry.type.is_pyobject and entry is not weakref_slot:
1011 py_attrs.append(entry)
1012 if py_attrs or weakref_slot in scope.var_entries:
1013 self.generate_self_cast(scope, code)
1014 self.generate_usr_dealloc_call(scope, code)
1015 if weakref_slot in scope.var_entries:
1016 code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1017 for entry in py_attrs:
1018 code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
1019 if base_type:
1020 tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
1021 if tp_dealloc is None:
1022 tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
1023 code.putln(
1024 "%s(o);" % tp_dealloc)
1025 else:
1026 code.putln(
1027 "(*Py_TYPE(o)->tp_free)(o);")
1028 code.putln(
1029 "}")
1031 def generate_usr_dealloc_call(self, scope, code):
1032 entry = scope.lookup_here("__dealloc__")
1033 if entry:
1034 code.putln(
1035 "{")
1036 code.putln(
1037 "PyObject *etype, *eval, *etb;")
1038 code.putln(
1039 "PyErr_Fetch(&etype, &eval, &etb);")
1040 code.putln(
1041 "++Py_REFCNT(o);")
1042 code.putln(
1043 "%s(o);" %
1044 entry.func_cname)
1045 code.putln(
1046 "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
1047 code.putln(
1048 "--Py_REFCNT(o);")
1049 code.putln(
1050 "PyErr_Restore(etype, eval, etb);")
1051 code.putln(
1052 "}")
1054 def generate_traverse_function(self, scope, code):
1055 tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
1056 slot_func = scope.mangle_internal("tp_traverse")
1057 base_type = scope.parent_type.base_type
1058 if tp_slot.slot_code(scope) != slot_func:
1059 return # never used
1060 code.putln("")
1061 code.putln(
1062 "static int %s(PyObject *o, visitproc v, void *a) {"
1063 % slot_func)
1064 py_attrs = []
1065 for entry in scope.var_entries:
1066 if entry.type.is_pyobject and entry.name != "__weakref__":
1067 py_attrs.append(entry)
1068 if base_type or py_attrs:
1069 code.putln("int e;")
1070 if py_attrs:
1071 self.generate_self_cast(scope, code)
1072 if base_type:
1073 # want to call it explicitly if possible so inlining can be performed
1074 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1075 if static_call:
1076 code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1077 else:
1078 code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
1079 code.putln(
1080 "e = %s->tp_traverse(o, v, a); if (e) return e;" %
1081 base_type.typeptr_cname)
1082 code.putln("}")
1083 for entry in py_attrs:
1084 var_code = "p->%s" % entry.cname
1085 code.putln(
1086 "if (%s) {"
1087 % var_code)
1088 if entry.type.is_extension_type:
1089 var_code = "((PyObject*)%s)" % var_code
1090 code.putln(
1091 "e = (*v)(%s, a); if (e) return e;"
1092 % var_code)
1093 code.putln(
1094 "}")
1095 code.putln(
1096 "return 0;")
1097 code.putln(
1098 "}")
1100 def generate_clear_function(self, scope, code):
1101 tp_slot = TypeSlots.GCDependentSlot("tp_clear")
1102 slot_func = scope.mangle_internal("tp_clear")
1103 base_type = scope.parent_type.base_type
1104 if tp_slot.slot_code(scope) != slot_func:
1105 return # never used
1106 code.putln("")
1107 code.putln("static int %s(PyObject *o) {" % slot_func)
1108 py_attrs = []
1109 for entry in scope.var_entries:
1110 if entry.type.is_pyobject and entry.name != "__weakref__":
1111 py_attrs.append(entry)
1112 if py_attrs:
1113 self.generate_self_cast(scope, code)
1114 code.putln("PyObject* tmp;")
1115 if base_type:
1116 # want to call it explicitly if possible so inlining can be performed
1117 static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
1118 if static_call:
1119 code.putln("%s(o);" % static_call)
1120 else:
1121 code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
1122 code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
1123 code.putln("}")
1124 for entry in py_attrs:
1125 name = "p->%s" % entry.cname
1126 code.putln("tmp = ((PyObject*)%s);" % name)
1127 code.put_init_to_py_none(name, entry.type, nanny=False)
1128 code.putln("Py_XDECREF(tmp);")
1129 code.putln(
1130 "return 0;")
1131 code.putln(
1132 "}")
1134 def generate_getitem_int_function(self, scope, code):
1135 # This function is put into the sq_item slot when
1136 # a __getitem__ method is present. It converts its
1137 # argument to a Python integer and calls mp_subscript.
1138 code.putln(
1139 "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1140 scope.mangle_internal("sq_item"))
1141 code.putln(
1142 "PyObject *r;")
1143 code.putln(
1144 "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1145 code.putln(
1146 "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1147 code.putln(
1148 "Py_DECREF(x);")
1149 code.putln(
1150 "return r;")
1151 code.putln(
1152 "}")
1154 def generate_ass_subscript_function(self, scope, code):
1155 # Setting and deleting an item are both done through
1156 # the ass_subscript method, so we dispatch to user's __setitem__
1157 # or __delitem__, or raise an exception.
1158 base_type = scope.parent_type.base_type
1159 set_entry = scope.lookup_here("__setitem__")
1160 del_entry = scope.lookup_here("__delitem__")
1161 code.putln("")
1162 code.putln(
1163 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1164 scope.mangle_internal("mp_ass_subscript"))
1165 code.putln(
1166 "if (v) {")
1167 if set_entry:
1168 code.putln(
1169 "return %s(o, i, v);" %
1170 set_entry.func_cname)
1171 else:
1172 self.generate_guarded_basetype_call(
1173 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1174 code.putln(
1175 "PyErr_Format(PyExc_NotImplementedError,")
1176 code.putln(
1177 ' "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1178 code.putln(
1179 "return -1;")
1180 code.putln(
1181 "}")
1182 code.putln(
1183 "else {")
1184 if del_entry:
1185 code.putln(
1186 "return %s(o, i);" %
1187 del_entry.func_cname)
1188 else:
1189 self.generate_guarded_basetype_call(
1190 base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
1191 code.putln(
1192 "PyErr_Format(PyExc_NotImplementedError,")
1193 code.putln(
1194 ' "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1195 code.putln(
1196 "return -1;")
1197 code.putln(
1198 "}")
1199 code.putln(
1200 "}")
1202 def generate_guarded_basetype_call(
1203 self, base_type, substructure, slot, args, code):
1204 if base_type:
1205 base_tpname = base_type.typeptr_cname
1206 if substructure:
1207 code.putln(
1208 "if (%s->%s && %s->%s->%s)" % (
1209 base_tpname, substructure, base_tpname, substructure, slot))
1210 code.putln(
1211 " return %s->%s->%s(%s);" % (
1212 base_tpname, substructure, slot, args))
1213 else:
1214 code.putln(
1215 "if (%s->%s)" % (
1216 base_tpname, slot))
1217 code.putln(
1218 " return %s->%s(%s);" % (
1219 base_tpname, slot, args))
1221 def generate_ass_slice_function(self, scope, code):
1222 # Setting and deleting a slice are both done through
1223 # the ass_slice method, so we dispatch to user's __setslice__
1224 # or __delslice__, or raise an exception.
1225 code.putln("#if PY_MAJOR_VERSION >= 3")
1226 code.putln("#error __setslice__ and __delslice__ not supported in Python 3.")
1227 code.putln("#endif")
1228 base_type = scope.parent_type.base_type
1229 set_entry = scope.lookup_here("__setslice__")
1230 del_entry = scope.lookup_here("__delslice__")
1231 code.putln("")
1232 code.putln(
1233 "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1234 scope.mangle_internal("sq_ass_slice"))
1235 code.putln(
1236 "if (v) {")
1237 if set_entry:
1238 code.putln(
1239 "return %s(o, i, j, v);" %
1240 set_entry.func_cname)
1241 else:
1242 self.generate_guarded_basetype_call(
1243 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1244 code.putln(
1245 "PyErr_Format(PyExc_NotImplementedError,")
1246 code.putln(
1247 ' "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1248 code.putln(
1249 "return -1;")
1250 code.putln(
1251 "}")
1252 code.putln(
1253 "else {")
1254 if del_entry:
1255 code.putln(
1256 "return %s(o, i, j);" %
1257 del_entry.func_cname)
1258 else:
1259 self.generate_guarded_basetype_call(
1260 base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
1261 code.putln(
1262 "PyErr_Format(PyExc_NotImplementedError,")
1263 code.putln(
1264 ' "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1265 code.putln(
1266 "return -1;")
1267 code.putln(
1268 "}")
1269 code.putln(
1270 "}")
1272 def generate_getattro_function(self, scope, code):
1273 # First try to get the attribute using __getattribute__, if defined, or
1274 # PyObject_GenericGetAttr.
1275 #
1276 # If that raises an AttributeError, call the __getattr__ if defined.
1277 #
1278 # In both cases, defined can be in this class, or any base class.
1279 def lookup_here_or_base(n,type=None):
1280 # Recursive lookup
1281 if type is None:
1282 type = scope.parent_type
1283 r = type.scope.lookup_here(n)
1284 if r is None and \
1285 type.base_type is not None:
1286 return lookup_here_or_base(n,type.base_type)
1287 else:
1288 return r
1289 getattr_entry = lookup_here_or_base("__getattr__")
1290 getattribute_entry = lookup_here_or_base("__getattribute__")
1291 code.putln("")
1292 code.putln(
1293 "static PyObject *%s(PyObject *o, PyObject *n) {"
1294 % scope.mangle_internal("tp_getattro"))
1295 if getattribute_entry is not None:
1296 code.putln(
1297 "PyObject *v = %s(o, n);" %
1298 getattribute_entry.func_cname)
1299 else:
1300 code.putln(
1301 "PyObject *v = PyObject_GenericGetAttr(o, n);")
1302 if getattr_entry is not None:
1303 code.putln(
1304 "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1305 code.putln(
1306 "PyErr_Clear();")
1307 code.putln(
1308 "v = %s(o, n);" %
1309 getattr_entry.func_cname)
1310 code.putln(
1311 "}")
1312 code.putln(
1313 "return v;")
1314 code.putln(
1315 "}")
1317 def generate_setattro_function(self, scope, code):
1318 # Setting and deleting an attribute are both done through
1319 # the setattro method, so we dispatch to user's __setattr__
1320 # or __delattr__ or fall back on PyObject_GenericSetAttr.
1321 base_type = scope.parent_type.base_type
1322 set_entry = scope.lookup_here("__setattr__")
1323 del_entry = scope.lookup_here("__delattr__")
1324 code.putln("")
1325 code.putln(
1326 "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
1327 scope.mangle_internal("tp_setattro"))
1328 code.putln(
1329 "if (v) {")
1330 if set_entry:
1331 code.putln(
1332 "return %s(o, n, v);" %
1333 set_entry.func_cname)
1334 else:
1335 self.generate_guarded_basetype_call(
1336 base_type, None, "tp_setattro", "o, n, v", code)
1337 code.putln(
1338 "return PyObject_GenericSetAttr(o, n, v);")
1339 code.putln(
1340 "}")
1341 code.putln(
1342 "else {")
1343 if del_entry:
1344 code.putln(
1345 "return %s(o, n);" %
1346 del_entry.func_cname)
1347 else:
1348 self.generate_guarded_basetype_call(
1349 base_type, None, "tp_setattro", "o, n, v", code)
1350 code.putln(
1351 "return PyObject_GenericSetAttr(o, n, 0);")
1352 code.putln(
1353 "}")
1354 code.putln(
1355 "}")
1357 def generate_descr_get_function(self, scope, code):
1358 # The __get__ function of a descriptor object can be
1359 # called with NULL for the second or third arguments
1360 # under some circumstances, so we replace them with
1361 # None in that case.
1362 user_get_entry = scope.lookup_here("__get__")
1363 code.putln("")
1364 code.putln(
1365 "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
1366 scope.mangle_internal("tp_descr_get"))
1367 code.putln(
1368 "PyObject *r = 0;")
1369 code.putln(
1370 "if (!i) i = Py_None;")
1371 code.putln(
1372 "if (!c) c = Py_None;")
1373 #code.put_incref("i", py_object_type)
1374 #code.put_incref("c", py_object_type)
1375 code.putln(
1376 "r = %s(o, i, c);" %
1377 user_get_entry.func_cname)
1378 #code.put_decref("i", py_object_type)
1379 #code.put_decref("c", py_object_type)
1380 code.putln(
1381 "return r;")
1382 code.putln(
1383 "}")
1385 def generate_descr_set_function(self, scope, code):
1386 # Setting and deleting are both done through the __set__
1387 # method of a descriptor, so we dispatch to user's __set__
1388 # or __delete__ or raise an exception.
1389 base_type = scope.parent_type.base_type
1390 user_set_entry = scope.lookup_here("__set__")
1391 user_del_entry = scope.lookup_here("__delete__")
1392 code.putln("")
1393 code.putln(
1394 "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
1395 scope.mangle_internal("tp_descr_set"))
1396 code.putln(
1397 "if (v) {")
1398 if user_set_entry:
1399 code.putln(
1400 "return %s(o, i, v);" %
1401 user_set_entry.func_cname)
1402 else:
1403 self.generate_guarded_basetype_call(
1404 base_type, None, "tp_descr_set", "o, i, v", code)
1405 code.putln(
1406 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1407 code.putln(
1408 "return -1;")
1409 code.putln(
1410 "}")
1411 code.putln(
1412 "else {")
1413 if user_del_entry:
1414 code.putln(
1415 "return %s(o, i);" %
1416 user_del_entry.func_cname)
1417 else:
1418 self.generate_guarded_basetype_call(
1419 base_type, None, "tp_descr_set", "o, i, v", code)
1420 code.putln(
1421 'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
1422 code.putln(
1423 "return -1;")
1424 code.putln(
1425 "}")
1426 code.putln(
1427 "}")
1429 def generate_property_accessors(self, cclass_scope, code):
1430 for entry in cclass_scope.property_entries:
1431 property_scope = entry.scope
1432 if property_scope.defines_any(["__get__"]):
1433 self.generate_property_get_function(entry, code)
1434 if property_scope.defines_any(["__set__", "__del__"]):
1435 self.generate_property_set_function(entry, code)
1437 def generate_property_get_function(self, property_entry, code):
1438 property_scope = property_entry.scope
1439 property_entry.getter_cname = property_scope.parent_scope.mangle(
1440 Naming.prop_get_prefix, property_entry.name)
1441 get_entry = property_scope.lookup_here("__get__")
1442 code.putln("")
1443 code.putln(
1444 "static PyObject *%s(PyObject *o, void *x) {" %
1445 property_entry.getter_cname)
1446 code.putln(
1447 "return %s(o);" %
1448 get_entry.func_cname)
1449 code.putln(
1450 "}")
1452 def generate_property_set_function(self, property_entry, code):
1453 property_scope = property_entry.scope
1454 property_entry.setter_cname = property_scope.parent_scope.mangle(
1455 Naming.prop_set_prefix, property_entry.name)
1456 set_entry = property_scope.lookup_here("__set__")
1457 del_entry = property_scope.lookup_here("__del__")
1458 code.putln("")
1459 code.putln(
1460 "static int %s(PyObject *o, PyObject *v, void *x) {" %
1461 property_entry.setter_cname)
1462 code.putln(
1463 "if (v) {")
1464 if set_entry:
1465 code.putln(
1466 "return %s(o, v);" %
1467 set_entry.func_cname)
1468 else:
1469 code.putln(
1470 'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
1471 code.putln(
1472 "return -1;")
1473 code.putln(
1474 "}")
1475 code.putln(
1476 "else {")
1477 if del_entry:
1478 code.putln(
1479 "return %s(o);" %
1480 del_entry.func_cname)
1481 else:
1482 code.putln(
1483 'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
1484 code.putln(
1485 "return -1;")
1486 code.putln(
1487 "}")
1488 code.putln(
1489 "}")
1491 def generate_typeobj_definition(self, modname, entry, code):
1492 type = entry.type
1493 scope = type.scope
1494 for suite in TypeSlots.substructures:
1495 suite.generate_substructure(scope, code)
1496 code.putln("")
1497 if entry.visibility == 'public':
1498 header = "DL_EXPORT(PyTypeObject) %s = {"
1499 else:
1500 #header = "statichere PyTypeObject %s = {"
1501 header = "PyTypeObject %s = {"
1502 #code.putln(header % scope.parent_type.typeobj_cname)
1503 code.putln(header % type.typeobj_cname)
1504 code.putln(
1505 "PyVarObject_HEAD_INIT(0, 0)")
1506 code.putln(
1507 '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1508 self.full_module_name, scope.class_name))
1509 if type.typedef_flag:
1510 objstruct = type.objstruct_cname
1511 else:
1512 #objstruct = "struct %s" % scope.parent_type.objstruct_cname
1513 objstruct = "struct %s" % type.objstruct_cname
1514 code.putln(
1515 "sizeof(%s), /*tp_basicsize*/" %
1516 objstruct)
1517 code.putln(
1518 "0, /*tp_itemsize*/")
1519 for slot in TypeSlots.slot_table:
1520 slot.generate(scope, code)
1521 code.putln(
1522 "};")
1524 def generate_method_table(self, env, code):
1525 code.putln("")
1526 code.putln(
1527 "static struct PyMethodDef %s[] = {" %
1528 env.method_table_cname)
1529 for entry in env.pyfunc_entries:
1530 code.put_pymethoddef(entry, ",")
1531 code.putln(
1532 "{0, 0, 0, 0}")
1533 code.putln(
1534 "};")
1536 def generate_getset_table(self, env, code):
1537 if env.property_entries:
1538 code.putln("")
1539 code.putln(
1540 "static struct PyGetSetDef %s[] = {" %
1541 env.getset_table_cname)
1542 for entry in env.property_entries:
1543 if entry.doc:
1544 doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
1545 else:
1546 doc_code = "0"
1547 code.putln(
1548 '{(char *)"%s", %s, %s, %s, 0},' % (
1549 entry.name,
1550 entry.getter_cname or "0",
1551 entry.setter_cname or "0",
1552 doc_code))
1553 code.putln(
1554 "{0, 0, 0, 0, 0}")
1555 code.putln(
1556 "};")
1558 def generate_filename_init_prototype(self, code):
1559 code.putln("");
1560 code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
1562 def generate_import_star(self, env, code):
1563 env.use_utility_code(streq_utility_code)
1564 code.putln()
1565 code.putln("char* %s_type_names[] = {" % Naming.import_star)
1566 for name, entry in env.entries.items():
1567 if entry.is_type:
1568 code.putln('"%s",' % name)
1569 code.putln("0")
1570 code.putln("};")
1571 code.putln()
1572 code.enter_cfunc_scope() # as we need labels
1573 code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
1574 code.putln("char** type_name = %s_type_names;" % Naming.import_star)
1575 code.putln("while (*type_name) {")
1576 code.putln("if (__Pyx_StrEq(name, *type_name)) {")
1577 code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
1578 code.putln('goto bad;')
1579 code.putln("}")
1580 code.putln("type_name++;")
1581 code.putln("}")
1582 old_error_label = code.new_error_label()
1583 code.putln("if (0);") # so the first one can be "else if"
1584 for name, entry in env.entries.items():
1585 if entry.is_cglobal and entry.used:
1586 code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
1587 if entry.type.is_pyobject:
1588 if entry.type.is_extension_type or entry.type.is_builtin_type:
1589 code.putln("if (!(%s)) %s;" % (
1590 entry.type.type_test_code("o"),
1591 code.error_goto(entry.pos)))
1592 code.put_var_decref(entry)
1593 code.putln("%s = %s;" % (
1594 entry.cname,
1595 PyrexTypes.typecast(entry.type, py_object_type, "o")))
1596 elif entry.type.from_py_function:
1597 rhs = "%s(o)" % entry.type.from_py_function
1598 if entry.type.is_enum:
1599 rhs = typecast(entry.type, c_long_type, rhs)
1600 code.putln("%s = %s; if (%s) %s;" % (
1601 entry.cname,
1602 rhs,
1603 entry.type.error_condition(entry.cname),
1604 code.error_goto(entry.pos)))
1605 code.putln("Py_DECREF(o);")
1606 else:
1607 code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
1608 code.putln(code.error_goto(entry.pos))
1609 code.putln("}")
1610 code.putln("else {")
1611 code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
1612 code.putln("}")
1613 code.putln("return 0;")
1614 code.put_label(code.error_label)
1615 # This helps locate the offending name.
1616 code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
1617 code.error_label = old_error_label
1618 code.putln("bad:")
1619 code.putln("Py_DECREF(o);")
1620 code.putln("return -1;")
1621 code.putln("}")
1622 code.putln(import_star_utility_code)
1623 code.exit_cfunc_scope() # done with labels
1625 def generate_module_init_func(self, imported_modules, env, code):
1626 code.enter_cfunc_scope()
1627 code.putln("")
1628 header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
1629 header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
1630 code.putln("#if PY_MAJOR_VERSION < 3")
1631 code.putln("%s; /*proto*/" % header2)
1632 code.putln(header2)
1633 code.putln("#else")
1634 code.putln("%s; /*proto*/" % header3)
1635 code.putln(header3)
1636 code.putln("#endif")
1637 code.putln("{")
1638 tempdecl_code = code.insertion_point()
1640 code.putln("#if CYTHON_REFNANNY")
1641 code.putln("void* __pyx_refnanny = NULL;")
1642 code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
1643 code.putln("if (!__Pyx_RefNanny) {")
1644 code.putln(" PyErr_Clear();")
1645 code.putln(" __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
1646 code.putln(" if (!__Pyx_RefNanny)")
1647 code.putln(" Py_FatalError(\"failed to import 'refnanny' module\");")
1648 code.putln("}")
1649 code.putln("__pyx_refnanny = __Pyx_RefNanny->SetupContext(\"%s\", __LINE__, __FILE__);"% header3)
1650 code.putln("#endif")
1652 self.generate_filename_init_call(code)
1654 code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1655 code.putln("#if PY_MAJOR_VERSION < 3");
1656 code.putln("%s = PyString_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
1657 code.putln("#else");
1658 code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
1659 code.putln("#endif");
1661 code.putln("/*--- Library function declarations ---*/")
1662 env.generate_library_function_declarations(code)
1664 code.putln("/*--- Threads initialization code ---*/")
1665 code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1666 code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
1667 code.putln("PyEval_InitThreads();")
1668 code.putln("#endif")
1669 code.putln("#endif")
1671 code.putln("/*--- Module creation code ---*/")
1672 self.generate_module_creation_code(env, code)
1674 code.putln("/*--- Initialize various global constants etc. ---*/")
1675 code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))
1677 __main__name = code.globalstate.get_py_string_const(
1678 EncodedString("__main__"), identifier=True)
1679 code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
1680 code.putln(
1681 'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % (
1682 env.module_cname,
1683 __main__name.cname,
1684 code.error_goto(self.pos)))
1685 code.putln("}")
1687 if Options.cache_builtins:
1688 code.putln("/*--- Builtin init code ---*/")
1689 code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()",
1690 self.pos))
1692 code.putln("/*--- Global init code ---*/")
1693 self.generate_global_init_code(env, code)
1695 code.putln("/*--- Function export code ---*/")
1696 self.generate_c_function_export_code(env, code)
1698 code.putln("/*--- Type init code ---*/")
1699 self.generate_type_init_code(env, code)
1701 code.putln("/*--- Type import code ---*/")
1702 for module in imported_modules:
1703 self.generate_type_import_code_for_module(module, env, code)
1705 code.putln("/*--- Function import code ---*/")
1706 for module in imported_modules:
1707 self.generate_c_function_import_code_for_module(module, env, code)
1709 code.putln("/*--- Execution code ---*/")
1710 code.mark_pos(None)
1712 self.body.generate_execution_code(code)
1714 if Options.generate_cleanup_code:
1715 # this should be replaced by the module's tp_clear in Py3
1716 env.use_utility_code(import_module_utility_code)
1717 code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1719 code.put_goto(code.return_label)
1720 code.put_label(code.error_label)
1721 for cname, type in code.funcstate.all_managed_temps():
1722 code.put_xdecref(cname, type)
1723 code.putln('if (%s) {' % env.module_cname)
1724 code.putln('__Pyx_AddTraceback("init %s");' % env.qualified_name)
1725 env.use_utility_code(Nodes.traceback_utility_code)
1726 code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
1727 code.putln('} else if (!PyErr_Occurred()) {')
1728 code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
1729 code.putln('}')
1730 code.put_label(code.return_label)
1732 code.put_finish_refcount_context()
1734 code.putln("#if PY_MAJOR_VERSION < 3")
1735 code.putln("return;")
1736 code.putln("#else")
1737 code.putln("return %s;" % env.module_cname)
1738 code.putln("#endif")
1739 code.putln('}')
1741 tempdecl_code.put_temp_declarations(code.funcstate)
1743 code.exit_cfunc_scope()
1745 def generate_module_cleanup_func(self, env, code):
1746 if not Options.generate_cleanup_code:
1747 return
1748 code.globalstate.use_utility_code(register_cleanup_utility_code)
1749 code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
1750 if Options.generate_cleanup_code >= 2:
1751 code.putln("/*--- Global cleanup code ---*/")
1752 rev_entries = list(env.var_entries)
1753 rev_entries.reverse()
1754 for entry in rev_entries:
1755 if entry.visibility != 'extern':
1756 if entry.type.is_pyobject and entry.used:
1757 code.putln("Py_DECREF(%s); %s = 0;" % (
1758 code.entry_as_pyobject(entry), entry.cname))
1759 code.putln("__Pyx_CleanupGlobals();")
1760 if Options.generate_cleanup_code >= 3:
1761 code.putln("/*--- Type import cleanup code ---*/")
1762 for type, _ in env.types_imported.items():
1763 code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname)
1764 if Options.cache_builtins:
1765 code.putln("/*--- Builtin cleanup code ---*/")
1766 for entry in env.cached_builtins:
1767 code.put_decref_clear(entry.cname,
1768 PyrexTypes.py_object_type,
1769 nanny=False)
1770 code.putln("/*--- Intern cleanup code ---*/")
1771 code.put_decref_clear(Naming.empty_tuple,
1772 PyrexTypes.py_object_type,
1773 nanny=False)
1774 # for entry in env.pynum_entries:
1775 # code.put_decref_clear(entry.cname,
1776 # PyrexTypes.py_object_type,
1777 # nanny=False)
1778 # for entry in env.all_pystring_entries:
1779 # if entry.is_interned:
1780 # code.put_decref_clear(entry.pystring_cname,
1781 # PyrexTypes.py_object_type,
1782 # nanny=False)
1783 # for entry in env.default_entries:
1784 # if entry.type.is_pyobject and entry.used:
1785 # code.putln("Py_DECREF(%s); %s = 0;" % (
1786 # code.entry_as_pyobject(entry), entry.cname))
1787 code.putln("Py_INCREF(Py_None); return Py_None;")
1789 def generate_main_method(self, env, code):
1790 module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
1791 code.globalstate.use_utility_code(main_method.specialize(module_name=env.module_name, module_is_main=module_is_main))
1793 def generate_filename_init_call(self, code):
1794 code.putln("%s();" % Naming.fileinit_cname)
1796 def generate_pymoduledef_struct(self, env, code):
1797 if env.doc:
1798 doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
1799 else:
1800 doc = "0"
1801 code.putln("")
1802 code.putln("#if PY_MAJOR_VERSION >= 3")
1803 code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
1804 code.putln(" PyModuleDef_HEAD_INIT,")
1805 code.putln(' __Pyx_NAMESTR("%s"),' % env.module_name)
1806 code.putln(" %s, /* m_doc */" % doc)
1807 code.putln(" -1, /* m_size */")
1808 code.putln(" %s /* m_methods */," % env.method_table_cname)
1809 code.putln(" NULL, /* m_reload */")
1810 code.putln(" NULL, /* m_traverse */")
1811 code.putln(" NULL, /* m_clear */")
1812 code.putln(" NULL /* m_free */")
1813 code.putln("};")
1814 code.putln("#endif")
1816 def generate_module_creation_code(self, env, code):
1817 # Generate code to create the module object and
1818 # install the builtins.
1819 if env.doc:
1820 doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
1821 else:
1822 doc = "0"
1823 code.putln("#if PY_MAJOR_VERSION < 3")
1824 code.putln(
1825 '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
1826 env.module_cname,
1827 env.module_name,
1828 env.method_table_cname,
1829 doc))
1830 code.putln("#else")
1831 code.putln(
1832 "%s = PyModule_Create(&%s);" % (
1833 env.module_cname,
1834 Naming.pymoduledef_cname))
1835 code.putln("#endif")
1836 code.putln(
1837 "if (!%s) %s;" % (
1838 env.module_cname,
1839 code.error_goto(self.pos)));
1840 code.putln("#if PY_MAJOR_VERSION < 3")
1841 code.putln(
1842 "Py_INCREF(%s);" %
1843 env.module_cname)
1844 code.putln("#endif")
1845 code.putln(
1846 '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
1847 Naming.builtins_cname)
1848 code.putln(
1849 "if (!%s) %s;" % (
1850 Naming.builtins_cname,
1851 code.error_goto(self.pos)));
1852 code.putln(
1853 'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
1854 env.module_cname,
1855 Naming.builtins_cname,
1856 code.error_goto(self.pos)))
1857 if Options.pre_import is not None:
1858 code.putln(
1859 '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
1860 Naming.preimport_cname,
1861 Options.pre_import))
1862 code.putln(
1863 "if (!%s) %s;" % (
1864 Naming.preimport_cname,
1865 code.error_goto(self.pos)));
1867 def generate_global_init_code(self, env, code):
1868 # Generate code to initialise global PyObject *
1869 # variables to None.
1870 for entry in env.var_entries:
1871 if entry.visibility != 'extern':
1872 if entry.type.is_pyobject and entry.used:
1873 code.put_init_var_to_py_none(entry, nanny=False)
1875 def generate_c_function_export_code(self, env, code):
1876 # Generate code to create PyCFunction wrappers for exported C functions.
1877 for entry in env.cfunc_entries:
1878 if entry.api or entry.defined_in_pxd:
1879 env.use_utility_code(function_export_utility_code)
1880 signature = entry.type.signature_string()
1881 code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
1882 entry.name,
1883 entry.cname,
1884 signature,
1885 code.error_goto(self.pos)))
1887 def generate_type_import_code_for_module(self, module, env, code):
1888 # Generate type import code for all exported extension types in
1889 # an imported module.
1890 #if module.c_class_entries:
1891 for entry in module.c_class_entries:
1892 if entry.defined_in_pxd:
1893 self.generate_type_import_code(env, entry.type, entry.pos, code)
1895 def generate_c_function_import_code_for_module(self, module, env, code):
1896 # Generate import code for all exported C functions in a cimported module.
1897 entries = []
1898 for entry in module.cfunc_entries:
1899 if entry.defined_in_pxd:
1900 entries.append(entry)
1901 if entries:
1902 env.use_utility_code(import_module_utility_code)
1903 env.use_utility_code(function_import_utility_code)
1904 temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
1905 code.putln(
1906 '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
1907 temp,
1908 module.qualified_name,
1909 temp,
1910 code.error_goto(self.pos)))
1911 for entry in entries:
1912 code.putln(
1913 'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
1914 temp,
1915 entry.name,
1916 entry.cname,
1917 entry.type.signature_string(),
1918 code.error_goto(self.pos)))
1919 code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
1921 def generate_type_init_code(self, env, code):
1922 # Generate type import code for extern extension types
1923 # and type ready code for non-extern ones.
1924 for entry in env.c_class_entries:
1925 if entry.visibility == 'extern':
1926 self.generate_type_import_code(env, entry.type, entry.pos, code)
1927 else:
1928 self.generate_base_type_import_code(env, entry, code)
1929 self.generate_exttype_vtable_init_code(entry, code)
1930 self.generate_type_ready_code(env, entry, code)
1931 self.generate_typeptr_assignment_code(entry, code)
1933 def generate_base_type_import_code(self, env, entry, code):
1934 base_type = entry.type.base_type
1935 if base_type and base_type.module_name != env.qualified_name:
1936 self.generate_type_import_code(env, base_type, self.pos, code)
1938 def use_type_import_utility_code(self, env):
1939 env.use_utility_code(type_import_utility_code)
1940 env.use_utility_code(import_module_utility_code)
1942 def generate_type_import_code(self, env, type, pos, code):
1943 # If not already done, generate code to import the typeobject of an
1944 # extension type defined in another module, and extract its C method
1945 # table pointer if any.
1946 if type in env.types_imported:
1947 return
1948 if type.typedef_flag:
1949 objstruct = type.objstruct_cname
1950 else:
1951 objstruct = "struct %s" % type.objstruct_cname
1952 self.generate_type_import_call(type, code,
1953 code.error_goto_if_null(type.typeptr_cname, pos))
1954 self.use_type_import_utility_code(env)
1955 if type.vtabptr_cname:
1956 code.putln(
1957 "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
1958 type.typeptr_cname,
1959 type.vtabptr_cname,
1960 code.error_goto(pos)))
1961 env.use_utility_code(Nodes.get_vtable_utility_code)
1962 env.types_imported[type] = 1
1964 py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}
1966 def generate_type_import_call(self, type, code, error_code):
1967 if type.typedef_flag:
1968 objstruct = type.objstruct_cname
1969 else:
1970 objstruct = "struct %s" % type.objstruct_cname
1971 module_name = type.module_name
1972 if module_name not in ('__builtin__', 'builtins'):
1973 module_name = '"%s"' % module_name
1974 else:
1975 module_name = '__Pyx_BUILTIN_MODULE_NAME'
1976 if type.name in self.py3_type_name_map:
1977 code.putln("#if PY_MAJOR_VERSION >= 3")
1978 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), 1); %s' % (
1979 type.typeptr_cname,
1980 module_name,
1981 self.py3_type_name_map[type.name],
1982 objstruct,
1983 error_code))
1984 code.putln("#else")
1985 code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), %i); %s' % (
1986 type.typeptr_cname,
1987 module_name,
1988 type.name,
1989 objstruct,
1990 not type.is_external or type.is_subclassed,
1991 error_code))
1992 if type.name in self.py3_type_name_map:
1993 code.putln("#endif")
1995 def generate_type_ready_code(self, env, entry, code):
1996 # Generate a call to PyType_Ready for an extension
1997 # type defined in this module.
1998 type = entry.type
1999 typeobj_cname = type.typeobj_cname
2000 scope = type.scope
2001 if scope: # could be None if there was an error
2002 if entry.visibility != 'extern':
2003 for slot in TypeSlots.slot_table:
2004 slot.generate_dynamic_init_code(scope, code)
2005 code.putln(
2006 "if (PyType_Ready(&%s) < 0) %s" % (
2007 typeobj_cname,
2008 code.error_goto(entry.pos)))
2009 if type.vtable_cname:
2010 code.putln(
2011 "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
2012 typeobj_cname,
2013 type.vtabptr_cname,
2014 code.error_goto(entry.pos)))
2015 env.use_utility_code(Nodes.set_vtable_utility_code)
2016 code.putln(
2017 'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
2018 Naming.module_cname,
2019 scope.class_name,
2020 typeobj_cname,
2021 code.error_goto(entry.pos)))
2022 weakref_entry = scope.lookup_here("__weakref__")
2023 if weakref_entry:
2024 if weakref_entry.type is py_object_type:
2025 tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
2026 if type.typedef_flag:
2027 objstruct = type.objstruct_cname
2028 else:
2029 objstruct = "struct %s" % type.objstruct_cname
2030 code.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2031 tp_weaklistoffset,
2032 tp_weaklistoffset,
2033 objstruct,
2034 weakref_entry.cname))
2035 else:
2036 error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
2038 def generate_exttype_vtable_init_code(self, entry, code):
2039 # Generate code to initialise the C method table of an
2040 # extension type.
2041 type = entry.type
2042 if type.vtable_cname:
2043 code.putln(
2044 "%s = &%s;" % (
2045 type.vtabptr_cname,
2046 type.vtable_cname))
2047 if type.base_type and type.base_type.vtabptr_cname:
2048 code.putln(
2049 "%s.%s = *%s;" % (
2050 type.vtable_cname,
2051 Naming.obj_base_cname,
2052 type.base_type.vtabptr_cname))
2054 c_method_entries = [
2055 entry for entry in type.scope.cfunc_entries
2056 if entry.func_cname ]
2057 if c_method_entries:
2058 code.putln('#if PY_MAJOR_VERSION >= 3')
2059 for meth_entry in c_method_entries:
2060 cast = meth_entry.type.signature_cast_string()
2061 code.putln(
2062 "%s.%s = %s%s;" % (
2063 type.vtable_cname,
2064 meth_entry.cname,
2065 cast,
2066 meth_entry.func_cname))
2067 code.putln('#else')
2068 for meth_entry in c_method_entries:
2069 code.putln(
2070 "*(void(**)(void))&%s.%s = (void(*)(void))%s;" % (
2071 type.vtable_cname,
2072 meth_entry.cname,
2073 meth_entry.func_cname))
2074 code.putln('#endif')
2076 def generate_typeptr_assignment_code(self, entry, code):
2077 # Generate code to initialise the typeptr of an extension
2078 # type defined in this module to point to its type object.
2079 type = entry.type
2080 if type.typeobj_cname:
2081 code.putln(
2082 "%s = &%s;" % (
2083 type.typeptr_cname, type.typeobj_cname))
2085 #------------------------------------------------------------------------------------
2086 #
2087 # Runtime support code
2088 #
2089 #------------------------------------------------------------------------------------
2091 streq_utility_code = UtilityCode(
2092 proto = """
2093 static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2094 """,
2095 impl = """
2096 static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2097 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2098 return *s1 == *s2;
2099 }
2100 """)
2102 #------------------------------------------------------------------------------------
2104 import_module_utility_code = UtilityCode(
2105 proto = """
2106 static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2107 """,
2108 impl = """
2109 #ifndef __PYX_HAVE_RT_ImportModule
2110 #define __PYX_HAVE_RT_ImportModule
2111 static PyObject *__Pyx_ImportModule(const char *name) {
2112 PyObject *py_name = 0;
2113 PyObject *py_module = 0;
2115 #if PY_MAJOR_VERSION < 3
2116 py_name = PyString_FromString(name);
2117 #else
2118 py_name = PyUnicode_FromString(name);
2119 #endif
2120 if (!py_name)
2121 goto bad;
2122 py_module = PyImport_Import(py_name);
2123 Py_DECREF(py_name);
2124 return py_module;
2125 bad:
2126 Py_XDECREF(py_name);
2127 return 0;
2128 }
2129 #endif
2130 """)
2132 #------------------------------------------------------------------------------------
2134 type_import_utility_code = UtilityCode(
2135 proto = """
2136 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size, int strict); /*proto*/
2137 """,
2138 impl = """
2139 #ifndef __PYX_HAVE_RT_ImportType
2140 #define __PYX_HAVE_RT_ImportType
2141 static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2142 long size, int strict)
2143 {
2144 PyObject *py_module = 0;
2145 PyObject *result = 0;
2146 PyObject *py_name = 0;
2147 char warning[200];
2149 py_module = __Pyx_ImportModule(module_name);
2150 if (!py_module)
2151 goto bad;
2152 #if PY_MAJOR_VERSION < 3
2153 py_name = PyString_FromString(class_name);
2154 #else
2155 py_name = PyUnicode_FromString(class_name);
2156 #endif
2157 if (!py_name)
2158 goto bad;
2159 result = PyObject_GetAttr(py_module, py_name);
2160 Py_DECREF(py_name);
2161 py_name = 0;
2162 Py_DECREF(py_module);
2163 py_module = 0;
2164 if (!result)
2165 goto bad;
2166 if (!PyType_Check(result)) {
2167 PyErr_Format(PyExc_TypeError,
2168 "%s.%s is not a type object",
2169 module_name, class_name);
2170 goto bad;
2171 }
2172 if (!strict && ((PyTypeObject *)result)->tp_basicsize > size) {
2173 PyOS_snprintf(warning, sizeof(warning),
2174 "%s.%s size changed, may indicate binary incompatibility",
2175 module_name, class_name);
2176 PyErr_WarnEx(NULL, warning, 0);
2177 }
2178 else if (((PyTypeObject *)result)->tp_basicsize != size) {
2179 PyErr_Format(PyExc_ValueError,
2180 "%s.%s has the wrong size, try recompiling",
2181 module_name, class_name);
2182 goto bad;
2183 }
2184 return (PyTypeObject *)result;
2185 bad:
2186 Py_XDECREF(py_module);
2187 Py_XDECREF(result);
2188 return 0;
2189 }
2190 #endif
2191 """)
2193 #------------------------------------------------------------------------------------
2195 function_export_utility_code = UtilityCode(
2196 proto = """
2197 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
2198 """,
2199 impl = r"""
2200 static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
2201 PyObject *d = 0;
2202 PyObject *cobj = 0;
2203 union {
2204 void (*fp)(void);
2205 void *p;
2206 } tmp;
2208 d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
2209 if (!d) {
2210 PyErr_Clear();
2211 d = PyDict_New();
2212 if (!d)
2213 goto bad;
2214 Py_INCREF(d);
2215 if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
2216 goto bad;
2217 }
2218 tmp.fp = f;
2219 #if PY_VERSION_HEX < 0x03010000
2220 cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
2221 #else
2222 cobj = PyCapsule_New(tmp.p, sig, 0);
2223 #endif
2224 if (!cobj)
2225 goto bad;
2226 if (PyDict_SetItemString(d, name, cobj) < 0)
2227 goto bad;
2228 Py_DECREF(cobj);
2229 Py_DECREF(d);
2230 return 0;
2231 bad:
2232 Py_XDECREF(cobj);
2233 Py_XDECREF(d);
2234 return -1;
2235 }
2236 """ % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
2237 )
2239 function_import_utility_code = UtilityCode(
2240 proto = """
2241 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
2242 """,
2243 impl = """
2244 #ifndef __PYX_HAVE_RT_ImportFunction
2245 #define __PYX_HAVE_RT_ImportFunction
2246 static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
2247 PyObject *d = 0;
2248 PyObject *cobj = 0;
2249 union {
2250 void (*fp)(void);
2251 void *p;
2252 } tmp;
2253 #if PY_VERSION_HEX < 0x03010000
2254 const char *desc, *s1, *s2;
2255 #endif
2257 d = PyObject_GetAttrString(module, (char *)"%(API)s");
2258 if (!d)
2259 goto bad;
2260 cobj = PyDict_GetItemString(d, funcname);
2261 if (!cobj) {
2262 PyErr_Format(PyExc_ImportError,
2263 "%%s does not export expected C function %%s",
2264 PyModule_GetName(module), funcname);
2265 goto bad;
2266 }
2267 #if PY_VERSION_HEX < 0x03010000
2268 desc = (const char *)PyCObject_GetDesc(cobj);
2269 if (!desc)
2270 goto bad;
2271 s1 = desc; s2 = sig;
2272 while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
2273 if (*s1 != *s2) {
2274 PyErr_Format(PyExc_TypeError,
2275 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2276 PyModule_GetName(module), funcname, sig, desc);
2277 goto bad;
2278 }
2279 tmp.p = PyCObject_AsVoidPtr(cobj);
2280 #else
2281 if (!PyCapsule_IsValid(cobj, sig)) {
2282 PyErr_Format(PyExc_TypeError,
2283 "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2284 PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj));
2285 goto bad;
2286 }
2287 tmp.p = PyCapsule_GetPointer(cobj, sig);
2288 #endif
2289 *f = tmp.fp;
2290 if (!(*f))
2291 goto bad;
2292 Py_DECREF(d);
2293 return 0;
2294 bad:
2295 Py_XDECREF(d);
2296 return -1;
2297 }
2298 #endif
2299 """ % dict(API = Naming.api_name)
2300 )
2302 #------------------------------------------------------------------------------------
2304 register_cleanup_utility_code = UtilityCode(
2305 proto = """
2306 static int __Pyx_RegisterCleanup(void); /*proto*/
2307 static PyObject* __pyx_module_cleanup(PyObject *self, PyObject *unused); /*proto*/
2308 static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&__pyx_module_cleanup, METH_NOARGS, 0};
2309 """,
2310 impl = """
2311 static int __Pyx_RegisterCleanup(void) {
2312 /* Don't use Py_AtExit because that has a 32-call limit
2313 * and is called after python finalization.
2314 */
2316 PyObject *cleanup_func = 0;
2317 PyObject *atexit = 0;
2318 PyObject *reg = 0;
2319 PyObject *args = 0;
2320 PyObject *res = 0;
2321 int ret = -1;
2323 cleanup_func = PyCFunction_New(&cleanup_def, 0);
2324 args = PyTuple_New(1);
2325 if (!cleanup_func || !args)
2326 goto bad;
2327 PyTuple_SET_ITEM(args, 0, cleanup_func);
2328 cleanup_func = 0;
2330 atexit = __Pyx_ImportModule("atexit");
2331 if (!atexit)
2332 goto bad;
2333 reg = __Pyx_GetAttrString(atexit, "register");
2334 if (!reg)
2335 goto bad;
2336 res = PyObject_CallObject(reg, args);
2337 if (!res)
2338 goto bad;
2339 ret = 0;
2340 bad:
2341 Py_XDECREF(cleanup_func);
2342 Py_XDECREF(atexit);
2343 Py_XDECREF(reg);
2344 Py_XDECREF(args);
2345 Py_XDECREF(res);
2346 return ret;
2347 }
2348 """)
2350 import_star_utility_code = """
2352 /* import_all_from is an unexposed function from ceval.c */
2354 static int
2355 __Pyx_import_all_from(PyObject *locals, PyObject *v)
2356 {
2357 PyObject *all = __Pyx_GetAttrString(v, "__all__");
2358 PyObject *dict, *name, *value;
2359 int skip_leading_underscores = 0;
2360 int pos, err;
2362 if (all == NULL) {
2363 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2364 return -1; /* Unexpected error */
2365 PyErr_Clear();
2366 dict = __Pyx_GetAttrString(v, "__dict__");
2367 if (dict == NULL) {
2368 if (!PyErr_ExceptionMatches(PyExc_AttributeError))
2369 return -1;
2370 PyErr_SetString(PyExc_ImportError,
2371 "from-import-* object has no __dict__ and no __all__");
2372 return -1;
2373 }
2374 all = PyMapping_Keys(dict);
2375 Py_DECREF(dict);
2376 if (all == NULL)
2377 return -1;
2378 skip_leading_underscores = 1;
2379 }
2381 for (pos = 0, err = 0; ; pos++) {
2382 name = PySequence_GetItem(all, pos);
2383 if (name == NULL) {
2384 if (!PyErr_ExceptionMatches(PyExc_IndexError))
2385 err = -1;
2386 else
2387 PyErr_Clear();
2388 break;
2389 }
2390 if (skip_leading_underscores &&
2391 #if PY_MAJOR_VERSION < 3
2392 PyString_Check(name) &&
2393 PyString_AS_STRING(name)[0] == '_')
2394 #else
2395 PyUnicode_Check(name) &&
2396 PyUnicode_AS_UNICODE(name)[0] == '_')
2397 #endif
2398 {
2399 Py_DECREF(name);
2400 continue;
2401 }
2402 value = PyObject_GetAttr(v, name);
2403 if (value == NULL)
2404 err = -1;
2405 else if (PyDict_CheckExact(locals))
2406 err = PyDict_SetItem(locals, name, value);
2407 else
2408 err = PyObject_SetItem(locals, name, value);
2409 Py_DECREF(name);
2410 Py_XDECREF(value);
2411 if (err != 0)
2412 break;
2413 }
2414 Py_DECREF(all);
2415 return err;
2416 }
2419 static int %(IMPORT_STAR)s(PyObject* m) {
2421 int i;
2422 int ret = -1;
2423 char* s;
2424 PyObject *locals = 0;
2425 PyObject *list = 0;
2426 PyObject *name;
2427 PyObject *item;
2429 locals = PyDict_New(); if (!locals) goto bad;
2430 if (__Pyx_import_all_from(locals, m) < 0) goto bad;
2431 list = PyDict_Items(locals); if (!list) goto bad;
2433 for(i=0; i<PyList_GET_SIZE(list); i++) {
2434 name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
2435 item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2436 #if PY_MAJOR_VERSION < 3
2437 s = PyString_AsString(name);
2438 #else
2439 s = PyUnicode_AsString(name);
2440 #endif
2441 if (!s) goto bad;
2442 if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2443 }
2444 ret = 0;
2446 bad:
2447 Py_XDECREF(locals);
2448 Py_XDECREF(list);
2449 return ret;
2450 }
2451 """ % {'IMPORT_STAR' : Naming.import_star,
2452 'IMPORT_STAR_SET' : Naming.import_star_set }
2454 refnanny_utility_code = UtilityCode(proto="""
2455 #ifndef CYTHON_REFNANNY
2456 #define CYTHON_REFNANNY 0
2457 #endif
2459 #if CYTHON_REFNANNY
2460 typedef struct {
2461 void (*INCREF)(void*, PyObject*, int);
2462 void (*DECREF)(void*, PyObject*, int);
2463 void (*GOTREF)(void*, PyObject*, int);
2464 void (*GIVEREF)(void*, PyObject*, int);
2465 void* (*SetupContext)(const char*, int, const char*);
2466 void (*FinishContext)(void**);
2467 } __Pyx_RefNannyAPIStruct;
2468 static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
2469 static __Pyx_RefNannyAPIStruct * __Pyx_RefNannyImportAPI(const char *modname) {
2470 PyObject *m = NULL, *p = NULL;
2471 void *r = NULL;
2472 m = PyImport_ImportModule((char *)modname);
2473 if (!m) goto end;
2474 p = PyObject_GetAttrString(m, (char *)\"RefNannyAPI\");
2475 if (!p) goto end;
2476 r = PyLong_AsVoidPtr(p);
2477 end:
2478 Py_XDECREF(p);
2479 Py_XDECREF(m);
2480 return (__Pyx_RefNannyAPIStruct *)r;
2481 }
2482 #define __Pyx_RefNannySetupContext(name) \
2483 void *__pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
2484 #define __Pyx_RefNannyFinishContext() \
2485 __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
2486 #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2487 #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2488 #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2489 #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2490 #define __Pyx_XDECREF(r) do { if((r) != NULL) {__Pyx_DECREF(r);} } while(0)
2491 #else
2492 #define __Pyx_RefNannySetupContext(name)
2493 #define __Pyx_RefNannyFinishContext()
2494 #define __Pyx_INCREF(r) Py_INCREF(r)
2495 #define __Pyx_DECREF(r) Py_DECREF(r)
2496 #define __Pyx_GOTREF(r)
2497 #define __Pyx_GIVEREF(r)
2498 #define __Pyx_XDECREF(r) Py_XDECREF(r)
2499 #endif /* CYTHON_REFNANNY */
2500 #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);} } while(0)
2501 #define __Pyx_XGOTREF(r) do { if((r) != NULL) {__Pyx_GOTREF(r);} } while(0)
2502 """)
2505 main_method = UtilityCode(
2506 impl = """
2507 #ifdef __FreeBSD__
2508 #include <floatingpoint.h>
2509 #endif
2511 #if PY_MAJOR_VERSION < 3
2512 int main(int argc, char** argv) {
2513 #elif defined(WIN32) || defined(MS_WINDOWS)
2514 int wmain(int argc, wchar_t **argv) {
2515 #else
2516 static int __Pyx_main(int argc, wchar_t **argv) {
2517 #endif
2518 int r = 0;
2519 PyObject* m = NULL;
2520 /* 754 requires that FP exceptions run in "no stop" mode by default,
2521 * and until C vendors implement C99's ways to control FP exceptions,
2522 * Python requires non-stop mode. Alas, some platforms enable FP
2523 * exceptions by default. Here we disable them.
2524 */
2525 #ifdef __FreeBSD__
2526 fp_except_t m;
2528 m = fpgetmask();
2529 fpsetmask(m & ~FP_X_OFL);
2530 #endif
2531 Py_SetProgramName(argv[0]);
2532 Py_Initialize();
2533 PySys_SetArgv(argc, argv);
2534 %(module_is_main)s = 1;
2535 #if PY_MAJOR_VERSION < 3
2536 init%(module_name)s();
2537 #else
2538 m = PyInit_%(module_name)s();
2539 #endif
2540 if (PyErr_Occurred() != NULL) {
2541 r = 1;
2542 PyErr_Print(); /* This exits with the right code if SystemExit. */
2543 #if PY_MAJOR_VERSION < 3
2544 if (Py_FlushLine()) PyErr_Clear();
2545 #endif
2546 }
2547 Py_XDECREF(m);
2548 Py_Finalize();
2549 return r;
2550 }
2553 #if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
2554 #include <locale.h>
2556 static wchar_t*
2557 __Pyx_char2wchar(char* arg)
2558 {
2559 wchar_t *res;
2560 #ifdef HAVE_BROKEN_MBSTOWCS
2561 /* Some platforms have a broken implementation of
2562 * mbstowcs which does not count the characters that
2563 * would result from conversion. Use an upper bound.
2564 */
2565 size_t argsize = strlen(arg);
2566 #else
2567 size_t argsize = mbstowcs(NULL, arg, 0);
2568 #endif
2569 size_t count;
2570 unsigned char *in;
2571 wchar_t *out;
2572 #ifdef HAVE_MBRTOWC
2573 mbstate_t mbs;
2574 #endif
2575 if (argsize != (size_t)-1) {
2576 res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
2577 if (!res)
2578 goto oom;
2579 count = mbstowcs(res, arg, argsize+1);
2580 if (count != (size_t)-1) {
2581 wchar_t *tmp;
2582 /* Only use the result if it contains no
2583 surrogate characters. */
2584 for (tmp = res; *tmp != 0 &&
2585 (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
2586 ;
2587 if (*tmp == 0)
2588 return res;
2589 }
2590 free(res);
2591 }
2592 /* Conversion failed. Fall back to escaping with surrogateescape. */
2593 #ifdef HAVE_MBRTOWC
2594 /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */
2596 /* Overallocate; as multi-byte characters are in the argument, the
2597 actual output could use less memory. */
2598 argsize = strlen(arg) + 1;
2599 res = malloc(argsize*sizeof(wchar_t));
2600 if (!res) goto oom;
2601 in = (unsigned char*)arg;
2602 out = res;
2603 memset(&mbs, 0, sizeof mbs);
2604 while (argsize) {
2605 size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
2606 if (converted == 0)
2607 /* Reached end of string; null char stored. */
2608 break;
2609 if (converted == (size_t)-2) {
2610 /* Incomplete character. This should never happen,
2611 since we provide everything that we have -
2612 unless there is a bug in the C library, or I
2613 misunderstood how mbrtowc works. */
2614 fprintf(stderr, "unexpected mbrtowc result -2\\n");
2615 return NULL;
2616 }
2617 if (converted == (size_t)-1) {
2618 /* Conversion error. Escape as UTF-8b, and start over
2619 in the initial shift state. */
2620 *out++ = 0xdc00 + *in++;
2621 argsize--;
2622 memset(&mbs, 0, sizeof mbs);
2623 continue;
2624 }
2625 if (*out >= 0xd800 && *out <= 0xdfff) {
2626 /* Surrogate character. Escape the original
2627 byte sequence with surrogateescape. */
2628 argsize -= converted;
2629 while (converted--)
2630 *out++ = 0xdc00 + *in++;
2631 continue;
2632 }
2633 /* successfully converted some bytes */
2634 in += converted;
2635 argsize -= converted;
2636 out++;
2637 }
2638 #else
2639 /* Cannot use C locale for escaping; manually escape as if charset
2640 is ASCII (i.e. escape all bytes > 128. This will still roundtrip
2641 correctly in the locale's charset, which must be an ASCII superset. */
2642 res = malloc((strlen(arg)+1)*sizeof(wchar_t));
2643 if (!res) goto oom;
2644 in = (unsigned char*)arg;
2645 out = res;
2646 while(*in)
2647 if(*in < 128)
2648 *out++ = *in++;
2649 else
2650 *out++ = 0xdc00 + *in++;
2651 *out = 0;
2652 #endif
2653 return res;
2654 oom:
2655 fprintf(stderr, "out of memory\\n");
2656 return NULL;
2657 }
2659 int
2660 main(int argc, char **argv)
2661 {
2662 wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
2663 /* We need a second copies, as Python might modify the first one. */
2664 wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
2665 int i, res;
2666 char *oldloc;
2667 if (!argv_copy || !argv_copy2) {
2668 fprintf(stderr, "out of memory\\n");
2669 return 1;
2670 }
2671 oldloc = strdup(setlocale(LC_ALL, NULL));
2672 setlocale(LC_ALL, "");
2673 for (i = 0; i < argc; i++) {
2674 argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
2675 if (!argv_copy[i])
2676 return 1;
2677 }
2678 setlocale(LC_ALL, oldloc);
2679 free(oldloc);
2680 res = __Pyx_main(argc, argv_copy);
2681 for (i = 0; i < argc; i++) {
2682 free(argv_copy2[i]);
2683 }
2684 free(argv_copy);
2685 free(argv_copy2);
2686 return res;
2687 }
2688 #endif
2689 """)
2691 packed_struct_utility_code = UtilityCode(proto="""
2692 #if defined(__GNUC__)
2693 #define __Pyx_PACKED __attribute__((__packed__))
2694 #else
2695 #define __Pyx_PACKED
2696 #endif
2697 """, impl="", proto_block='utility_code_proto_before_types')
