ModuleNode.py 123 KB
Newer Older
1
#
2
#   Module parse tree node
3 4
#

5 6 7
import cython
cython.declare(Naming=object, Options=object, PyrexTypes=object, TypeSlots=object,
               error=object, warning=object, py_object_type=object, UtilityCode=object,
Stefan Behnel's avatar
Stefan Behnel committed
8
               EncodedString=object)
9

10
import os, time
11
from PyrexTypes import CPtrType
Robert Bradshaw's avatar
Robert Bradshaw committed
12
import Future
13

14
import Annotate
15 16 17 18 19 20 21
import Code
import Naming
import Nodes
import Options
import PyrexTypes
import TypeSlots
import Version
22
import DebugFlags
23

24
from Errors import error, warning
25
from PyrexTypes import py_object_type
26 27
from Cython.Utils import open_new_file, replace_suffix
from Code import UtilityCode
Stefan Behnel's avatar
Stefan Behnel committed
28
from StringEncoding import EncodedString
29

Gary Furnish's avatar
Gary Furnish committed
30

31 32 33 34
def check_c_declarations_pxd(module_node):
    module_node.scope.check_c_classes_pxd()
    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 39
    return module_node

40 41 42
class ModuleNode(Nodes.Node, Nodes.BlockNode):
    #  doc       string or None
    #  body      StatListNode
43 44
    #
    #  referenced_modules   [ModuleScope]
45
    #  full_module_name     string
46 47 48
    #
    #  scope                The module scope.
    #  compilation_source   A CompilationSource (see Main)
49
    #  directives           Top-level compiler directives
50

51
    child_attrs = ["body"]
52
    directives = None
53

54 55 56 57 58 59 60 61 62 63 64 65 66 67
    def merge_in(self, tree, scope, merge_scope=False):
        # Merges in the contents of another tree, and possibly scope. With the
        # current implementation below, this must be done right prior
        # to code generation.
        #
        # Note: This way of doing it seems strange -- I believe the
        # right concept is to split ModuleNode into a ModuleNode and a
        # CodeGenerator, and tell that CodeGenerator to generate code
        # from multiple sources.
        assert isinstance(self.body, Nodes.StatListNode)
        if isinstance(tree, Nodes.StatListNode):
            self.body.stats.extend(tree.stats)
        else:
            self.body.stats.append(tree)
68 69 70 71 72 73 74 75 76 77 78 79 80

        self.scope.utility_code_list.extend(scope.utility_code_list)

        def extend_if_not_in(L1, L2):
            for x in L2:
                if x not in L1:
                    L1.append(x)

        extend_if_not_in(self.scope.include_files, scope.include_files)
        extend_if_not_in(self.scope.included_files, scope.included_files)
        extend_if_not_in(self.scope.python_include_files,
                         scope.python_include_files)

81
        if merge_scope:
82 83 84 85
            # Ensure that we don't generate import code for these entries!
            for entry in scope.c_class_entries:
                entry.type.module_name = self.full_module_name

86
            self.scope.merge_in(scope)
87

88
    def analyse_declarations(self, env):
89
        if Options.embed_pos_in_docstring:
Robert Bradshaw's avatar
Robert Bradshaw committed
90
            env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
91
            if not self.doc is None:
92
                env.doc = EncodedString(env.doc + u'\n' + self.doc)
Robert Bradshaw's avatar
Robert Bradshaw committed
93
                env.doc.encoding = self.doc.encoding
94 95
        else:
            env.doc = self.doc
96
        env.directives = self.directives
97
        self.body.analyse_declarations(env)
98

99 100
    def process_implementation(self, options, result):
        env = self.scope
101
        env.return_type = PyrexTypes.c_void_type
102 103
        self.referenced_modules = []
        self.find_referenced_modules(env, self.referenced_modules, {})
104 105
        if options.recursive:
            self.generate_dep_file(env, result)
106
        self.generate_c_code(env, options, result)
107 108
        self.generate_h_code(env, options, result)
        self.generate_api_code(env, result)
Robert Bradshaw's avatar
Robert Bradshaw committed
109

110 111 112 113 114 115
    def has_imported_c_functions(self):
        for module in self.referenced_modules:
            for entry in module.cfunc_entries:
                if entry.defined_in_pxd:
                    return 1
        return 0
116

117 118 119 120 121 122 123 124 125 126 127 128 129 130
    def generate_dep_file(self, env, result):
        modules = self.referenced_modules
        if len(modules) > 1 or env.included_files:
            dep_file = replace_suffix(result.c_file, ".dep")
            f = open(dep_file, "w")
            try:
                for module in modules:
                    if module is not env:
                        f.write("cimport %s\n" % module.qualified_name)
                    for path in module.included_files:
                        f.write("include %s\n" % path)
            finally:
                f.close()

131
    def generate_h_code(self, env, options, result):
132
        def h_entries(entries, api=0, pxd=0):
Stefan Behnel's avatar
Stefan Behnel committed
133
            return [entry for entry in entries
134 135 136 137
                    if ((entry.visibility == 'public') or
                        (api and entry.api) or
                        (pxd and entry.defined_in_pxd))]
        h_types = h_entries(env.type_entries, api=1)
Stefan Behnel's avatar
Stefan Behnel committed
138 139 140
        h_vars = h_entries(env.var_entries)
        h_funcs = h_entries(env.cfunc_entries)
        h_extension_types = h_entries(env.c_class_entries)
141
        if (h_types or  h_vars or h_funcs or h_extension_types):
142
            result.h_file = replace_suffix(result.c_file, ".h")
143
            h_code = Code.CCodeWriter()
144
            Code.GlobalState(h_code, self)
145 146 147 148 149
            if options.generate_pxi:
                result.i_file = replace_suffix(result.c_file, ".pxi")
                i_code = Code.PyrexCodeWriter(result.i_file)
            else:
                i_code = None
150 151 152

            h_guard = Naming.h_guard_prefix + self.api_name(env)
            h_code.put_h_guard(h_guard)
153
            h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
154
            self.generate_type_header_code(h_types, h_code)
155
            h_code.putln("")
156 157
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.putln("#ifndef %s" % api_guard)
158 159
            h_code.putln("")
            self.generate_extern_c_macro_definition(h_code)
Stefan Behnel's avatar
Stefan Behnel committed
160
            if h_extension_types:
161
                h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
162
                for entry in h_extension_types:
163 164 165
                    self.generate_cclass_header_code(entry.type, h_code)
                    if i_code:
                        self.generate_cclass_include_code(entry.type, i_code)
166 167 168 169 170 171 172 173
            if h_funcs:
                h_code.putln("")
                for entry in h_funcs:
                    self.generate_public_declaration(entry, h_code, i_code)
            if h_vars:
                h_code.putln("")
                for entry in h_vars:
                    self.generate_public_declaration(entry, h_code, i_code)
174
            h_code.putln("")
175
            h_code.putln("#endif /* !%s */" % api_guard)
176
            h_code.putln("")
177
            h_code.putln("#if PY_MAJOR_VERSION < 3")
178
            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
179 180
            h_code.putln("#else")
            h_code.putln("PyMODINIT_FUNC PyInit_%s(void);" % env.module_name)
181
            h_code.putln("#endif")
182 183
            h_code.putln("")
            h_code.putln("#endif /* !%s */" % h_guard)
184

185 186 187 188 189
            f = open_new_file(result.h_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
190

191 192 193 194 195 196
    def generate_public_declaration(self, entry, h_code, i_code):
        h_code.putln("%s %s;" % (
            Naming.extern_c_macro,
            entry.type.declaration_code(
                entry.cname, dll_linkage = "DL_IMPORT")))
        if i_code:
197
            i_code.putln("cdef extern %s" %
198
                entry.type.declaration_code(entry.cname, pyrex = 1))
199

200 201
    def api_name(self, env):
        return env.qualified_name.replace(".", "__")
Robert Bradshaw's avatar
Robert Bradshaw committed
202

203
    def generate_api_code(self, env, result):
204
        def api_entries(entries, pxd=0):
205 206 207 208 209 210
            return [entry for entry in entries
                    if entry.api or (pxd and entry.defined_in_pxd)]
        api_vars = api_entries(env.var_entries)
        api_funcs = api_entries(env.cfunc_entries)
        api_extension_types = api_entries(env.c_class_entries)
        if api_vars or api_funcs or api_extension_types:
211
            result.api_file = replace_suffix(result.c_file, "_api.h")
212
            h_code = Code.CCodeWriter()
213
            Code.GlobalState(h_code, self)
214 215
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.put_h_guard(api_guard)
216 217 218
            h_code.putln('#include "Python.h"')
            if result.h_file:
                h_code.putln('#include "%s"' % os.path.basename(result.h_file))
219
            if api_extension_types:
220
                h_code.putln("")
221 222 223 224 225
                for entry in api_extension_types:
                    type = entry.type
                    h_code.putln("static PyTypeObject *%s = 0;" % type.typeptr_cname)
                    h_code.putln("#define %s (*%s)" % (
                        type.typeobj_cname, type.typeptr_cname))
226 227 228 229
            if api_funcs:
                h_code.putln("")
                for entry in api_funcs:
                    type = CPtrType(entry.type)
230 231 232 233 234 235 236
                    cname = env.mangle(Naming.func_prefix, entry.name)
                    h_code.putln("static %s = 0;" % type.declaration_code(cname))
                    h_code.putln("#define %s %s" % (entry.name, cname))
            if api_vars:
                h_code.putln("")
                for entry in api_vars:
                    type = CPtrType(entry.type)
237
                    cname = env.mangle(Naming.varptr_prefix, entry.name)
238 239
                    h_code.putln("static %s = 0;" %  type.declaration_code(cname))
                    h_code.putln("#define %s (*%s)" % (entry.name, cname))
240
            h_code.put(import_module_utility_code.impl)
241 242
            if api_vars:
                h_code.put(voidptr_import_utility_code.impl)
243
            if api_funcs:
244
                h_code.put(function_import_utility_code.impl)
245
            if api_extension_types:
246
                h_code.put(type_import_utility_code.impl)
247
            h_code.putln("")
248
            h_code.putln("static int import_%s(void) {" % self.api_name(env))
249
            h_code.putln("PyObject *module = 0;")
250
            h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
251 252
            h_code.putln("if (!module) goto bad;")
            for entry in api_funcs:
253
                cname = env.mangle(Naming.func_prefix, entry.name)
254 255
                sig = entry.type.signature_string()
                h_code.putln(
256 257 258
                    'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
            for entry in api_vars:
259
                cname = env.mangle(Naming.varptr_prefix, entry.name)
260 261 262 263
                sig = entry.type.declaration_code("")
                h_code.putln(
                    'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
264
            h_code.putln("Py_DECREF(module); module = 0;")
265
            for entry in api_extension_types:
266 267 268
                self.generate_type_import_call(
                    entry.type, h_code,
                    "if (!%s) goto bad;" % entry.type.typeptr_cname)
269 270 271 272 273 274
            h_code.putln("return 0;")
            h_code.putln("bad:")
            h_code.putln("Py_XDECREF(module);")
            h_code.putln("return -1;")
            h_code.putln("}")
            h_code.putln("")
275
            h_code.putln("#endif /* !%s */" % api_guard)
276

277 278 279 280 281
            f = open_new_file(result.api_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
282

283
    def generate_cclass_header_code(self, type, h_code):
284
        h_code.putln("%s %s %s;" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
285
            Naming.extern_c_macro,
286
            PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
287
            type.typeobj_cname))
288

289 290 291 292 293 294 295
    def generate_cclass_include_code(self, type, i_code):
        i_code.putln("cdef extern class %s.%s:" % (
            type.module_name, type.name))
        i_code.indent()
        var_entries = type.scope.var_entries
        if var_entries:
            for entry in var_entries:
296
                i_code.putln("cdef %s" %
297 298 299 300
                    entry.type.declaration_code(entry.cname, pyrex = 1))
        else:
            i_code.putln("pass")
        i_code.dedent()
301

302
    def generate_c_code(self, env, options, result):
303
        modules = self.referenced_modules
304

305
        if Options.annotate or options.annotate:
306 307
            emit_linenums = False
            rootwriter = Annotate.AnnotationCCodeWriter()
308
        else:
309
            emit_linenums = options.emit_linenums
310
            rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback)
311
        globalstate = Code.GlobalState(rootwriter, self, emit_linenums)
312
        globalstate.initialize_main_c_code()
313
        h_code = globalstate['h_code']
314

315
        self.generate_module_preamble(env, modules, h_code)
316

317 318
        globalstate.module_pos = self.pos
        globalstate.directives = self.directives
319

320
        globalstate.use_utility_code(refnanny_utility_code)
321

322
        code = globalstate['before_global_var']
323
        code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
324
        code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
325
        code.putln("")
326
        code.putln("/* Implementation of '%s' */" % env.qualified_name)
327

328
        code = globalstate['all_the_rest']
329

330
        self.generate_cached_builtins_decls(env, code)
331
        self.generate_lambda_definitions(env, code)
332 333
        # generate normal variable and function definitions
        self.generate_variable_definitions(env, code)
334
        self.body.generate_function_definitions(env, code)
Robert Bradshaw's avatar
Robert Bradshaw committed
335
        code.mark_pos(None)
336 337
        self.generate_typeobj_definitions(env, code)
        self.generate_method_table(env, code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
338 339
        if env.has_import_star:
            self.generate_import_star(env, code)
340
        self.generate_pymoduledef_struct(env, code)
341

342 343 344
        # init_globals is inserted before this
        self.generate_module_init_func(modules[:-1], env, globalstate['init_module'])
        self.generate_module_cleanup_func(env, globalstate['cleanup_module'])
345
        if Options.embed:
346 347
            self.generate_main_method(env, globalstate['main_method'])
        self.generate_filename_table(globalstate['filename_table'])
348

349
        self.generate_declarations_for_modules(env, modules, globalstate)
350
        h_code.write('\n')
Gary Furnish's avatar
Gary Furnish committed
351

352
        for utilcode in env.utility_code_list[:]:
353
            globalstate.use_utility_code(utilcode)
354
        globalstate.finalize_main_c_code()
355

356
        f = open_new_file(result.c_file)
357
        rootwriter.copyto(f)
358
        if options.gdb_debug:
Mark Florisson's avatar
Mark Florisson committed
359
            self._serialize_lineno_map(env, rootwriter)
360 361
        f.close()
        result.c_file_generated = 1
362
        if Options.annotate or options.annotate:
363 364
            self.annotate(rootwriter)
            rootwriter.save_annotation(result.main_source_file, result.c_file)
365

Mark Florisson's avatar
Mark Florisson committed
366
    def _serialize_lineno_map(self, env, ccodewriter):
367
        tb = env.context.gdb_debug_outputwriter
Mark Florisson's avatar
Mark Florisson committed
368
        markers = ccodewriter.buffer.allmarkers()
369

Mark Florisson's avatar
Mark Florisson committed
370
        d = {}
371
        for c_lineno, cython_lineno in enumerate(markers):
Mark Florisson's avatar
Mark Florisson committed
372 373
            if cython_lineno > 0:
                d.setdefault(cython_lineno, []).append(c_lineno + 1)
374

Mark Florisson's avatar
Mark Florisson committed
375 376 377 378 379 380 381 382 383 384
        tb.start('LineNumberMapping')
        for cython_lineno, c_linenos in sorted(d.iteritems()):
                attrs = {
                    'c_linenos': ' '.join(map(str, c_linenos)),
                    'cython_lineno': str(cython_lineno),
                }
                tb.start('LineNumber', attrs)
                tb.end('LineNumber')
        tb.end('LineNumberMapping')
        tb.serialize()
385

386 387 388 389 390 391
    def find_referenced_modules(self, env, module_list, modules_seen):
        if env not in modules_seen:
            modules_seen[env] = 1
            for imported_module in env.cimported_modules:
                self.find_referenced_modules(imported_module, module_list, modules_seen)
            module_list.append(env)
Gary Furnish's avatar
Gary Furnish committed
392

393 394 395 396 397 398 399 400 401
    def sort_types_by_inheritance(self, type_dict, getkey):
        # copy the types into a list moving each parent type before
        # its first child
        type_items = type_dict.items()
        type_list = []
        for i, item in enumerate(type_items):
            key, new_entry = item

            # collect all base classes to check for children
402
            hierarchy = set()
403
            base = new_entry
404 405 406 407 408 409 410
            while base:
                base_type = base.type.base_type
                if not base_type:
                    break
                base_key = getkey(base_type)
                hierarchy.add(base_key)
                base = type_dict.get(base_key)
411
            new_entry.base_keys = hierarchy
412

413
            # find the first (sub-)subclass and insert before that
414 415
            for j in range(i):
                entry = type_list[j]
416
                if key in entry.base_keys:
417 418 419 420 421 422 423
                    type_list.insert(j, new_entry)
                    break
            else:
                type_list.append(new_entry)
        return type_list

    def sort_type_hierarchy(self, module_list, env):
Gary Furnish's avatar
Gary Furnish committed
424
        vtab_dict = {}
425
        vtabslot_dict = {}
Gary Furnish's avatar
Gary Furnish committed
426 427 428 429 430
        for module in module_list:
            for entry in module.c_class_entries:
                if not entry.in_cinclude:
                    type = entry.type
                    if type.vtabstruct_cname:
431 432 433 434
                        vtab_dict[type.vtabstruct_cname] = entry
            all_defined_here = module is env
            for entry in module.type_entries:
                if all_defined_here or entry.defined_in_pxd:
Gary Furnish's avatar
Gary Furnish committed
435
                    type = entry.type
436 437 438
                    if type.is_extension_type and not entry.in_cinclude:
                        type = entry.type
                        vtabslot_dict[type.objstruct_cname] = entry
439

440 441
        def vtabstruct_cname(entry_type):
            return entry_type.vtabstruct_cname
442 443
        vtab_list = self.sort_types_by_inheritance(
            vtab_dict, vtabstruct_cname)
444 445 446

        def objstruct_cname(entry_type):
            return entry_type.objstruct_cname
447 448
        vtabslot_list = self.sort_types_by_inheritance(
            vtabslot_dict, objstruct_cname)
449

450
        return (vtab_list, vtabslot_list)
451

Gary Furnish's avatar
Gary Furnish committed
452
    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
453 454 455
        # TODO: Why are these separated out?
        for entry in vtabslot_list:
            self.generate_objstruct_predeclaration(entry.type, code)
456
        vtabslot_entries = set(vtabslot_list)
Gary Furnish's avatar
Gary Furnish committed
457 458 459 460 461 462 463 464 465
        for module in modules:
            definition = module is env
            if definition:
                type_entries = module.type_entries
            else:
                type_entries = []
                for entry in module.type_entries:
                    if entry.defined_in_pxd:
                        type_entries.append(entry)
466
            type_entries = [t for t in type_entries if t not in vtabslot_entries]
467
            self.generate_type_header_code(type_entries, code)
Gary Furnish's avatar
Gary Furnish committed
468
        for entry in vtabslot_list:
469
            self.generate_objstruct_definition(entry.type, code)
470
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
471
        for entry in vtab_list:
472
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
473 474
            self.generate_exttype_vtable_struct(entry, code)
            self.generate_exttype_vtabptr_declaration(entry, code)
475
            self.generate_exttype_final_methods_declaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
476

477 478 479
    def generate_declarations_for_modules(self, env, modules, globalstate):
        typecode = globalstate['type_declarations']
        typecode.putln("")
480
        typecode.putln("/*--- Type declarations ---*/")
481 482
        vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
        self.generate_type_definitions(
483 484
            env, modules, vtab_list, vtabslot_list, typecode)
        modulecode = globalstate['module_declarations']
Gary Furnish's avatar
Gary Furnish committed
485
        for module in modules:
486
            defined_here = module is env
487 488 489 490 491
            modulecode.putln("")
            modulecode.putln("/* Module declarations from '%s' */" % module.qualified_name)
            self.generate_c_class_declarations(module, modulecode, defined_here)
            self.generate_cvariable_declarations(module, modulecode, defined_here)
            self.generate_cfunction_declarations(module, modulecode, defined_here)
Gary Furnish's avatar
Gary Furnish committed
492

493
    def generate_module_preamble(self, env, cimported_modules, code):
494
        code.putln("/* Generated by Cython %s on %s */" % (
495
            Version.version, time.asctime()))
496 497
        code.putln("")
        code.putln("#define PY_SSIZE_T_CLEAN")
498 499
        for filename in env.python_include_files:
            code.putln('#include "%s"' % filename)
500 501
        code.putln("#ifndef Py_PYTHON_H")
        code.putln("    #error Python headers needed to compile C extensions, please install development version of Python.")
Robert Bradshaw's avatar
Robert Bradshaw committed
502
        code.putln("#elif PY_VERSION_HEX < 0x02040000")
503 504
        code.putln("    #error Cython requires Python 2.4+.")
        code.putln("#else")
505
        code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
506

507
        code.put("""
508 509 510 511 512
#include <stddef.h> /* For offsetof */
#ifndef offsetof
#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
#endif

513 514 515 516 517 518 519 520 521 522 523 524 525 526
#if !defined(WIN32) && !defined(MS_WINDOWS)
  #ifndef __stdcall
    #define __stdcall
  #endif
  #ifndef __cdecl
    #define __cdecl
  #endif
  #ifndef __fastcall
    #define __fastcall
  #endif
#endif

#ifndef DL_IMPORT
  #define DL_IMPORT(t) t
527 528 529 530
#endif
#ifndef DL_EXPORT
  #define DL_EXPORT(t) t
#endif
531

532 533
#ifndef PY_LONG_LONG
  #define PY_LONG_LONG LONG_LONG
534 535
#endif

536
#if PY_VERSION_HEX < 0x02050000
Robert Bradshaw's avatar
Robert Bradshaw committed
537 538 539
  typedef int Py_ssize_t;
  #define PY_SSIZE_T_MAX INT_MAX
  #define PY_SSIZE_T_MIN INT_MIN
540 541
  #define PY_FORMAT_SIZE_T \"\"
  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
542
  #define PyInt_AsSsize_t(o)   __Pyx_PyInt_AsInt(o)
543 544 545 546
  #define PyNumber_Index(o)    PyNumber_Int(o)
  #define PyIndex_Check(o)     PyNumber_Check(o)
  #define PyErr_WarnEx(category, message, stacklevel) PyErr_Warn(category, message)
#endif
547

548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578
#if PY_VERSION_HEX < 0x02060000
  #define Py_REFCNT(ob) (((PyObject*)(ob))->ob_refcnt)
  #define Py_TYPE(ob)   (((PyObject*)(ob))->ob_type)
  #define Py_SIZE(ob)   (((PyVarObject*)(ob))->ob_size)
  #define PyVarObject_HEAD_INIT(type, size) \\
          PyObject_HEAD_INIT(type) size,
  #define PyType_Modified(t)

  typedef struct {
     void *buf;
     PyObject *obj;
     Py_ssize_t len;
     Py_ssize_t itemsize;
     int readonly;
     int ndim;
     char *format;
     Py_ssize_t *shape;
     Py_ssize_t *strides;
     Py_ssize_t *suboffsets;
     void *internal;
  } Py_buffer;

  #define PyBUF_SIMPLE 0
  #define PyBUF_WRITABLE 0x0001
  #define PyBUF_FORMAT 0x0004
  #define PyBUF_ND 0x0008
  #define PyBUF_STRIDES (0x0010 | PyBUF_ND)
  #define PyBUF_C_CONTIGUOUS (0x0020 | PyBUF_STRIDES)
  #define PyBUF_F_CONTIGUOUS (0x0040 | PyBUF_STRIDES)
  #define PyBUF_ANY_CONTIGUOUS (0x0080 | PyBUF_STRIDES)
  #define PyBUF_INDIRECT (0x0100 | PyBUF_STRIDES)
579

580
#endif
581

582 583
#if PY_MAJOR_VERSION < 3
  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
584
  #define __Pyx_PyIdentifier_FromString(s) PyString_FromString(s)
585 586
  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \\
          PyCode_New(a, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
587 588
#else
  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
589
  #define __Pyx_PyIdentifier_FromString(s) PyUnicode_FromString(s)
590 591
  #define __Pyx_PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) \\
          PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)
592
#endif
593

594 595 596 597
#if PY_MAJOR_VERSION >= 3
  #define Py_TPFLAGS_CHECKTYPES 0
  #define Py_TPFLAGS_HAVE_INDEX 0
#endif
598

599 600 601
#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
#endif
602

603
/* new Py3.3 unicode representation (PEP 393) */
604
#if PY_VERSION_HEX > 0x03030000 && defined(PyUnicode_GET_LENGTH)
605
  #define CYTHON_PEP393_ENABLED
606 607
  #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_LENGTH(u)
  #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i)
608
#else
609
  #define __Pyx_PyUnicode_GET_LENGTH(u) PyUnicode_GET_SIZE(u)
610
  #define __Pyx_PyUnicode_READ_CHAR(u, i) ((Py_UCS4)(PyUnicode_AS_UNICODE(u)[i]))
611 612
#endif

613 614
#if PY_MAJOR_VERSION >= 3
  #define PyBaseString_Type            PyUnicode_Type
615
  #define PyStringObject               PyUnicodeObject
616
  #define PyString_Type                PyUnicode_Type
617
  #define PyString_Check               PyUnicode_Check
618
  #define PyString_CheckExact          PyUnicode_CheckExact
619 620 621 622
#endif

#if PY_VERSION_HEX < 0x02060000
  #define PyBytesObject                PyStringObject
623
  #define PyBytes_Type                 PyString_Type
624
  #define PyBytes_Check                PyString_Check
625
  #define PyBytes_CheckExact           PyString_CheckExact
626 627 628 629 630 631 632 633 634 635 636 637
  #define PyBytes_FromString           PyString_FromString
  #define PyBytes_FromStringAndSize    PyString_FromStringAndSize
  #define PyBytes_FromFormat           PyString_FromFormat
  #define PyBytes_DecodeEscape         PyString_DecodeEscape
  #define PyBytes_AsString             PyString_AsString
  #define PyBytes_AsStringAndSize      PyString_AsStringAndSize
  #define PyBytes_Size                 PyString_Size
  #define PyBytes_AS_STRING            PyString_AS_STRING
  #define PyBytes_GET_SIZE             PyString_GET_SIZE
  #define PyBytes_Repr                 PyString_Repr
  #define PyBytes_Concat               PyString_Concat
  #define PyBytes_ConcatAndDel         PyString_ConcatAndDel
638 639 640
#endif

#if PY_VERSION_HEX < 0x02060000
641 642 643 644
  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
#endif
#ifndef PySet_CheckExact
645
  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
646 647
#endif

Robert Bradshaw's avatar
Robert Bradshaw committed
648 649
#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type)

650
#if PY_MAJOR_VERSION >= 3
651
  #define PyIntObject                  PyLongObject
652 653 654 655 656 657 658 659 660 661 662 663 664
  #define PyInt_Type                   PyLong_Type
  #define PyInt_Check(op)              PyLong_Check(op)
  #define PyInt_CheckExact(op)         PyLong_CheckExact(op)
  #define PyInt_FromString             PyLong_FromString
  #define PyInt_FromUnicode            PyLong_FromUnicode
  #define PyInt_FromLong               PyLong_FromLong
  #define PyInt_FromSize_t             PyLong_FromSize_t
  #define PyInt_FromSsize_t            PyLong_FromSsize_t
  #define PyInt_AsLong                 PyLong_AsLong
  #define PyInt_AS_LONG                PyLong_AS_LONG
  #define PyInt_AsSsize_t              PyLong_AsSsize_t
  #define PyInt_AsUnsignedLongMask     PyLong_AsUnsignedLongMask
  #define PyInt_AsUnsignedLongLongMask PyLong_AsUnsignedLongLongMask
665
#endif
666 667

#if PY_MAJOR_VERSION >= 3
668
  #define PyBoolObject                 PyLongObject
669 670
#endif

671 672 673 674 675 676 677 678 679
#if PY_VERSION_HEX < 0x03020000
  typedef long Py_hash_t;
  #define __Pyx_PyInt_FromHash_t PyInt_FromLong
  #define __Pyx_PyInt_AsHash_t   PyInt_AsLong
#else
  #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
  #define __Pyx_PyInt_AsHash_t   PyInt_AsSsize_t
#endif

680
""")
681 682 683

        code.put("""
#if PY_MAJOR_VERSION >= 3
684 685 686 687
  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)
  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)
#else
""")
Robert Bradshaw's avatar
Robert Bradshaw committed
688 689
        if Future.division in env.context.future_directives:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_TrueDivide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
690
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)")
Robert Bradshaw's avatar
Robert Bradshaw committed
691 692
        else:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
693
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)")
694
        code.putln("#endif")
695

696
        code.put("""
697 698 699 700 701
#if (PY_MAJOR_VERSION < 3) || (PY_VERSION_HEX >= 0x03010300)
  #define __Pyx_PySequence_GetSlice(obj, a, b) PySequence_GetSlice(obj, a, b)
  #define __Pyx_PySequence_SetSlice(obj, a, b, value) PySequence_SetSlice(obj, a, b, value)
  #define __Pyx_PySequence_DelSlice(obj, a, b) PySequence_DelSlice(obj, a, b)
#else
702
  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \\
703
        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \\
704
        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \\
705
            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
706
  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \\
707
        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \\
708
        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \\
709
            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
710
  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \\
711
        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \\
712
        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \\
713 714 715
            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
#endif

716
#if PY_MAJOR_VERSION >= 3
717
  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
718
#endif
719

720 721 722 723 724 725 726 727 728
#if PY_VERSION_HEX < 0x02050000
  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),((char *)(n)))
  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),((char *)(n)),(a))
  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),((char *)(n)))
#else
  #define __Pyx_GetAttrString(o,n)   PyObject_GetAttrString((o),(n))
  #define __Pyx_SetAttrString(o,n,a) PyObject_SetAttrString((o),(n),(a))
  #define __Pyx_DelAttrString(o,n)   PyObject_DelAttrString((o),(n))
#endif
729

730 731 732 733 734 735 736 737
#if PY_VERSION_HEX < 0x02050000
  #define __Pyx_NAMESTR(n) ((char *)(n))
  #define __Pyx_DOCSTR(n)  ((char *)(n))
#else
  #define __Pyx_NAMESTR(n) (n)
  #define __Pyx_DOCSTR(n)  (n)
#endif
""")
738

739
        code.putln("")
740
        self.generate_extern_c_macro_definition(code)
741
        code.putln("")
742

743 744 745
        code.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
        code.putln("#define _USE_MATH_DEFINES")
        code.putln("#endif")
746
        code.putln("#include <math.h>")
747

748
        code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env))
749
        code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
750
        self.generate_includes(env, cimported_modules, code)
751 752 753 754 755
        code.putln("")
        code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS")
        code.putln("#define CYTHON_WITHOUT_ASSERTIONS")
        code.putln("#endif")
        code.putln("")
756

757 758 759 760
        if env.directives['ccomplex']:
            code.putln("")
            code.putln("#if !defined(CYTHON_CCOMPLEX)")
            code.putln("#define CYTHON_CCOMPLEX 1")
761
            code.putln("#endif")
762
            code.putln("")
763
        code.put(Nodes.utility_function_predeclarations)
764
        code.put(PyrexTypes.type_conversion_predeclarations)
Robert Bradshaw's avatar
Robert Bradshaw committed
765
        code.put(Nodes.branch_prediction_macros)
766 767 768
        code.putln('')
        code.putln('static PyObject *%s;' % env.module_cname)
        code.putln('static PyObject *%s;' % Naming.builtins_cname)
Robert Bradshaw's avatar
Robert Bradshaw committed
769
        code.putln('static PyObject *%s;' % Naming.empty_tuple)
Robert Bradshaw's avatar
Robert Bradshaw committed
770
        code.putln('static PyObject *%s;' % Naming.empty_bytes)
771 772
        if Options.pre_import is not None:
            code.putln('static PyObject *%s;' % Naming.preimport_cname)
773
        code.putln('static int %s;' % Naming.lineno_cname)
774
        code.putln('static int %s = 0;' % Naming.clineno_cname)
775 776
        code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
        code.putln('static const char *%s;' % Naming.filename_cname)
777

778 779 780 781 782 783
        # XXX this is a mess
        for utility_code in PyrexTypes.c_int_from_py_function.specialize_list:
            env.use_utility_code(utility_code)
        for utility_code in PyrexTypes.c_long_from_py_function.specialize_list:
            env.use_utility_code(utility_code)

784 785
    def generate_extern_c_macro_definition(self, code):
        name = Naming.extern_c_macro
786 787 788 789 790 791
        code.putln("#ifndef %s" % name)
        code.putln("  #ifdef __cplusplus")
        code.putln('    #define %s extern "C"' % name)
        code.putln("  #else")
        code.putln("    #define %s extern" % name)
        code.putln("  #endif")
792 793 794
        code.putln("#endif")

    def generate_includes(self, env, cimported_modules, code):
795
        includes = []
Robert Bradshaw's avatar
Robert Bradshaw committed
796
        for filename in env.include_files:
Stefan Behnel's avatar
Stefan Behnel committed
797 798 799
            byte_decoded_filenname = str(filename)
            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
                code.putln('#include %s' % byte_decoded_filenname)
800
            else:
Stefan Behnel's avatar
Stefan Behnel committed
801
                code.putln('#include "%s"' % byte_decoded_filenname)
802

803 804
        code.putln_openmp("#include <omp.h>")

805 806
    def generate_filename_table(self, code):
        code.putln("")
Robert Bradshaw's avatar
Robert Bradshaw committed
807
        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
808 809
        if code.globalstate.filename_list:
            for source_desc in code.globalstate.filename_list:
810
                filename = os.path.basename(source_desc.get_filenametable_entry())
811
                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
Robert Bradshaw's avatar
Robert Bradshaw committed
812
                code.putln('"%s",' % escaped_filename)
813 814 815 816
        else:
            # Some C compilers don't like an empty array
            code.putln("0")
        code.putln("};")
817 818 819 820

    def generate_type_predeclarations(self, env, code):
        pass

821
    def generate_type_header_code(self, type_entries, code):
822 823
        # Generate definitions of structs/unions/enums/typedefs/objstructs.
        #self.generate_gcc33_hack(env, code) # Is this still needed?
824
        # Forward declarations
825
        for entry in type_entries:
826
            if not entry.in_cinclude:
827
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
828
                type = entry.type
829
                if type.is_typedef: # Must test this first!
830
                    pass
831
                elif type.is_struct_or_union:
832 833 834 835 836 837 838 839 840 841
                    self.generate_struct_union_predeclaration(entry, code)
                elif type.is_extension_type:
                    self.generate_objstruct_predeclaration(type, code)
        # Actual declarations
        for entry in type_entries:
            if not entry.in_cinclude:
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
                type = entry.type
                if type.is_typedef: # Must test this first!
                    self.generate_typedef(entry, code)
842
                elif type.is_enum:
843
                    self.generate_enum_definition(entry, code)
844 845
                elif type.is_struct_or_union:
                    self.generate_struct_union_definition(entry, code)
846
                elif type.is_extension_type:
847
                    self.generate_objstruct_definition(type, code)
848

849 850 851 852 853 854 855 856 857 858 859 860 861
    def generate_gcc33_hack(self, env, code):
        # Workaround for spurious warning generation in gcc 3.3
        code.putln("")
        for entry in env.c_class_entries:
            type = entry.type
            if not type.typedef_flag:
                name = type.objstruct_cname
                if name.startswith("__pyx_"):
                    tail = name[6:]
                else:
                    tail = name
                code.putln("typedef struct %s __pyx_gcc33_%s;" % (
                    name, tail))
862

863 864
    def generate_typedef(self, entry, code):
        base_type = entry.type.typedef_base_type
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
865
        if base_type.is_numeric:
866 867 868 869
            try:
                writer = code.globalstate['numeric_typedefs']
            except KeyError:
                writer = code
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
870 871
        else:
            writer = code
872
        writer.mark_pos(entry.pos)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
873
        writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
874

875
    def sue_predeclaration(self, type, kind, name):
876
        if type.typedef_flag:
877 878 879
            return "%s %s;\ntypedef %s %s %s;" % (
                kind, name,
                kind, name, name)
880
        else:
881 882 883 884 885 886 887 888 889
            return "%s %s;" % (kind, name)

    def generate_struct_union_predeclaration(self, entry, code):
        type = entry.type
        code.putln(self.sue_predeclaration(type, type.kind, type.cname))

    def sue_header_footer(self, type, kind, name):
        header = "%s %s {" % (kind, name)
        footer = "};"
890
        return header, footer
891

892
    def generate_struct_union_definition(self, entry, code):
893
        code.mark_pos(entry.pos)
894 895 896
        type = entry.type
        scope = type.scope
        if scope:
897 898 899 900 901
            kind = type.kind
            packed = type.is_struct and type.packed
            if packed:
                kind = "%s %s" % (type.kind, "__Pyx_PACKED")
                code.globalstate.use_utility_code(packed_struct_utility_code)
902
            header, footer = \
903 904
                self.sue_header_footer(type, kind, type.cname)
            if packed:
905 906 907 908
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack(1)")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(push, 1)")
909
                code.putln("#endif")
910 911 912 913 914 915 916 917 918 919 920
            code.putln(header)
            var_entries = scope.var_entries
            if not var_entries:
                error(entry.pos,
                    "Empty struct or union definition not allowed outside a"
                    " 'cdef extern from' block")
            for attr in var_entries:
                code.putln(
                    "%s;" %
                        attr.type.declaration_code(attr.cname))
            code.putln(footer)
921
            if packed:
922 923 924 925
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack()")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(pop)")
926
                code.putln("#endif")
927 928

    def generate_enum_definition(self, entry, code):
929
        code.mark_pos(entry.pos)
930 931 932 933 934 935 936 937 938 939 940 941
        type = entry.type
        name = entry.cname or entry.name or ""
        header, footer = \
            self.sue_header_footer(type, "enum", name)
        code.putln(header)
        enum_values = entry.enum_values
        if not enum_values:
            error(entry.pos,
                "Empty enum definition not allowed outside a"
                " 'cdef extern from' block")
        else:
            last_entry = enum_values[-1]
942
            # this does not really generate code, just builds the result value
943
            for value_entry in enum_values:
944 945 946 947 948
                if value_entry.value_node is not None:
                    value_entry.value_node.generate_evaluation_code(code)

            for value_entry in enum_values:
                if value_entry.value_node is None:
949 950 951 952
                    value_code = value_entry.cname
                else:
                    value_code = ("%s = %s" % (
                        value_entry.cname,
953
                        value_entry.value_node.result()))
954 955 956 957
                if value_entry is not last_entry:
                    value_code += ","
                code.putln(value_code)
        code.putln(footer)
958 959 960
        if entry.type.typedef_flag:
            # Not pre-declared.
            code.putln("typedef enum %s %s;" % (name, name))
961

962
    def generate_typeobj_predeclaration(self, entry, code):
963 964 965 966
        code.putln("")
        name = entry.type.typeobj_cname
        if name:
            if entry.visibility == 'extern' and not entry.in_cinclude:
967
                code.putln("%s %s %s;" % (
968
                    Naming.extern_c_macro,
969
                    PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
970 971
                    name))
            elif entry.visibility == 'public':
972
                code.putln("%s %s %s;" % (
973
                    Naming.extern_c_macro,
974
                    PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
975 976 977
                    name))
            # ??? Do we really need the rest of this? ???
            #else:
978
            #    code.putln("static PyTypeObject %s;" % name)
979

980
    def generate_exttype_vtable_struct(self, entry, code):
981 982 983
        if not entry.used:
            return

984
        code.mark_pos(entry.pos)
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
        # Generate struct declaration for an extension type's vtable.
        type = entry.type
        scope = type.scope
        if type.vtabstruct_cname:
            code.putln("")
            code.putln(
                "struct %s {" %
                    type.vtabstruct_cname)
            if type.base_type and type.base_type.vtabstruct_cname:
                code.putln("struct %s %s;" % (
                    type.base_type.vtabstruct_cname,
                    Naming.obj_base_cname))
            for method_entry in scope.cfunc_entries:
                if not method_entry.is_inherited:
                    code.putln(
1000
                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.cname))
1001 1002
            code.putln(
                "};")
1003

1004
    def generate_exttype_vtabptr_declaration(self, entry, code):
1005 1006 1007
        if not entry.used:
            return

1008
        code.mark_pos(entry.pos)
1009 1010 1011 1012 1013 1014
        # Generate declaration of pointer to an extension type's vtable.
        type = entry.type
        if type.vtabptr_cname:
            code.putln("static struct %s *%s;" % (
                type.vtabstruct_cname,
                type.vtabptr_cname))
1015

1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032
    def generate_exttype_final_methods_declaration(self, entry, code):
        if not entry.used:
            return

        code.mark_pos(entry.pos)
        # Generate final methods prototypes
        type = entry.type
        for method_entry in entry.type.scope.cfunc_entries:
            if not method_entry.is_inherited and method_entry.final_func_cname:
                declaration = method_entry.type.declaration_code(
                    method_entry.final_func_cname)
                if entry.func_modifiers:
                    modifiers = "%s " % ' '.join(entry.func_modifiers).upper()
                else:
                    modifiers = ''
                code.putln("static %s%s;" % (modifiers, declaration))

1033 1034 1035 1036
    def generate_objstruct_predeclaration(self, type, code):
        if not type.scope:
            return
        code.putln(self.sue_predeclaration(type, "struct", type.objstruct_cname))
Vitja Makarov's avatar
Vitja Makarov committed
1037

1038
    def generate_objstruct_definition(self, type, code):
1039
        code.mark_pos(type.pos)
1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
        # Generate object struct definition for an
        # extension type.
        if not type.scope:
            return # Forward declared but never defined
        header, footer = \
            self.sue_header_footer(type, "struct", type.objstruct_cname)
        code.putln(header)
        base_type = type.base_type
        if base_type:
            code.putln(
                "%s%s %s;" % (
                    ("struct ", "")[base_type.typedef_flag],
                    base_type.objstruct_cname,
                    Naming.obj_base_cname))
        else:
            code.putln(
                "PyObject_HEAD")
        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
            code.putln(
                "struct %s *%s;" % (
                    type.vtabstruct_cname,
                    type.vtabslot_cname))
        for attr in type.scope.var_entries:
1063 1064 1065 1066
            if attr.is_declared_generic:
                attr_type = py_object_type
            else:
                attr_type = attr.type
1067 1068
            code.putln(
                "%s;" %
1069
                    attr_type.declaration_code(attr.cname))
1070
        code.putln(footer)
1071 1072 1073
        if type.objtypedef_cname is not None:
            # Only for exposing public typedef name.
            code.putln("typedef struct %s %s;" % (type.objstruct_cname, type.objtypedef_cname))
1074

1075
    def generate_c_class_declarations(self, env, code, definition):
1076
        for entry in env.c_class_entries:
1077
            if definition or entry.defined_in_pxd:
1078
                code.putln("static PyTypeObject *%s = 0;" %
1079
                    entry.type.typeptr_cname)
1080

1081
    def generate_cvariable_declarations(self, env, code, definition):
1082 1083
        if env.is_cython_builtin:
            return
1084 1085 1086 1087
        for entry in env.var_entries:
            if (entry.in_cinclude or entry.in_closure or
                (entry.visibility == 'private' and
                 not (entry.defined_in_pxd or entry.used))):
1088
                continue
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098

            storage_class = None
            dll_linkage = None
            cname = None
            init = None

            if entry.visibility == 'extern':
                storage_class = Naming.extern_c_macro
                dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'public':
1099
                storage_class = Naming.extern_c_macro
1100 1101 1102 1103 1104 1105
                if definition:
                    dll_linkage = "DL_EXPORT"
                else:
                    dll_linkage = "DL_IMPORT"
            elif entry.visibility == 'private':
                storage_class = "static"
1106 1107 1108 1109 1110
                dll_linkage = None
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
            type = entry.type
            cname = entry.cname
1111 1112 1113 1114

            if entry.defined_in_pxd and not definition:
                storage_class = "static"
                dll_linkage = None
1115
                type = CPtrType(type)
1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
                cname = env.mangle(Naming.varptr_prefix, entry.name)
                init = 0

            if storage_class:
                code.put("%s " % storage_class)
            code.put(type.declaration_code(
                cname, dll_linkage = dll_linkage))
            if init is not None:
                code.put_safe(" = %s" % init)
            code.putln(";")
            if entry.cname != cname:
                code.putln("#define %s (*%s)" % (entry.cname, cname))

    def generate_cfunction_declarations(self, env, code, definition):
1130
        for entry in env.cfunc_entries:
1131
            generate_cfunction_declaration(entry, env, code, definition)
1132

1133 1134
    def generate_variable_definitions(self, env, code):
        for entry in env.var_entries:
Vitja Makarov's avatar
Vitja Makarov committed
1135
            if (not entry.in_cinclude and
1136 1137 1138 1139 1140 1141 1142
                entry.visibility == "public"):
                code.put(entry.type.declaration_code(entry.cname))
                if entry.init is not None:
                    init =  entry.type.literal_code(entry.init)
                    code.put_safe(" = %s" % init)
                code.putln(";")

1143 1144 1145 1146 1147
    def generate_typeobj_definitions(self, env, code):
        full_module_name = env.qualified_name
        for entry in env.c_class_entries:
            #print "generate_typeobj_definitions:", entry.name
            #print "...visibility =", entry.visibility
Stefan Behnel's avatar
Stefan Behnel committed
1148
            if entry.visibility != 'extern':
1149 1150 1151 1152 1153 1154
                type = entry.type
                scope = type.scope
                if scope: # could be None if there was an error
                    self.generate_exttype_vtable(scope, code)
                    self.generate_new_function(scope, code)
                    self.generate_dealloc_function(scope, code)
1155 1156 1157
                    if scope.needs_gc():
                        self.generate_traverse_function(scope, code)
                        self.generate_clear_function(scope, code)
1158 1159 1160 1161
                    if scope.defines_any(["__getitem__"]):
                        self.generate_getitem_int_function(scope, code)
                    if scope.defines_any(["__setitem__", "__delitem__"]):
                        self.generate_ass_subscript_function(scope, code)
1162 1163 1164 1165 1166
                    if scope.defines_any(["__getslice__", "__setslice__", "__delslice__"]):
                        warning(self.pos, "__getslice__, __setslice__, and __delslice__ are not supported by Python 3, use __getitem__, __setitem__, and __delitem__ instead", 1)
                        code.putln("#if PY_MAJOR_VERSION >= 3")
                        code.putln("#error __getslice__, __setslice__, and __delslice__ not supported in Python 3.")
                        code.putln("#endif")
1167 1168
                    if scope.defines_any(["__setslice__", "__delslice__"]):
                        self.generate_ass_slice_function(scope, code)
1169
                    if scope.defines_any(["__getattr__","__getattribute__"]):
1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
                        self.generate_getattro_function(scope, code)
                    if scope.defines_any(["__setattr__", "__delattr__"]):
                        self.generate_setattro_function(scope, code)
                    if scope.defines_any(["__get__"]):
                        self.generate_descr_get_function(scope, code)
                    if scope.defines_any(["__set__", "__delete__"]):
                        self.generate_descr_set_function(scope, code)
                    self.generate_property_accessors(scope, code)
                    self.generate_method_table(scope, code)
                    self.generate_getset_table(scope, code)
                    self.generate_typeobj_definition(full_module_name, entry, code)
1181

1182 1183 1184 1185 1186 1187 1188
    def generate_exttype_vtable(self, scope, code):
        # Generate the definition of an extension type's vtable.
        type = scope.parent_type
        if type.vtable_cname:
            code.putln("static struct %s %s;" % (
                type.vtabstruct_cname,
                type.vtable_cname))
1189

1190 1191 1192 1193 1194 1195
    def generate_self_cast(self, scope, code):
        type = scope.parent_type
        code.putln(
            "%s = (%s)o;" % (
                type.declaration_code("p"),
                type.declaration_code("")))
1196

1197
    def generate_new_function(self, scope, code):
1198 1199
        tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
        slot_func = scope.mangle_internal("tp_new")
1200 1201 1202
        type = scope.parent_type
        base_type = type.base_type
        py_attrs = []
1203
        memviewslice_attrs = []
1204 1205 1206
        for entry in scope.var_entries:
            if entry.type.is_pyobject:
                py_attrs.append(entry)
1207 1208 1209
            elif entry.type.is_memoryviewslice:
                memviewslice_attrs.append(entry)
        need_self_cast = type.vtabslot_cname or py_attrs or memviewslice_attrs
1210 1211 1212 1213
        code.putln("")
        code.putln(
            "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
                % scope.mangle_internal("tp_new"))
1214 1215 1216 1217
        if need_self_cast:
            code.putln(
                "%s;"
                    % scope.parent_type.declaration_code("p"))
1218
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1219 1220
            tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
            if tp_new is None:
1221
                tp_new = "%s->tp_new" % base_type.typeptr_cname
1222
            code.putln(
1223
                "PyObject *o = %s(t, a, k);" % tp_new)
1224 1225 1226
        else:
            code.putln(
                "PyObject *o = (*t->tp_alloc)(t, 0);")
1227 1228 1229 1230 1231 1232 1233
        code.putln(
                "if (!o) return 0;")
        if need_self_cast:
            code.putln(
                "p = %s;"
                    % type.cast_code("o"))
        #if need_self_cast:
Robert Bradshaw's avatar
Robert Bradshaw committed
1234
        #    self.generate_self_cast(scope, code)
1235
        if type.vtabslot_cname:
1236 1237 1238 1239 1240
            vtab_base_type = type
            while vtab_base_type.base_type and vtab_base_type.base_type.vtabstruct_cname:
                vtab_base_type = vtab_base_type.base_type
            if vtab_base_type is not type:
                struct_type_cast = "(struct %s*)" % vtab_base_type.vtabstruct_cname
1241 1242 1243
            else:
                struct_type_cast = ""
            code.putln("p->%s = %s%s;" % (
1244
                type.vtabslot_cname,
1245
                struct_type_cast, type.vtabptr_cname))
1246
        for entry in py_attrs:
1247 1248
            if scope.is_internal or entry.name == "__weakref__":
                # internal classes do not need None inits
1249
                code.putln("p->%s = 0;" % entry.cname)
1250
            else:
1251
                code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
1252
        for entry in memviewslice_attrs:
1253
            code.putln("p->%s.data = NULL;" % entry.cname)
1254
            code.putln("p->%s.memview = NULL;" % entry.cname)
1255
        entry = scope.lookup_here("__new__")
1256
        if entry and entry.is_special:
1257 1258 1259 1260
            if entry.trivial_signature:
                cinit_args = "o, %s, NULL" % Naming.empty_tuple
            else:
                cinit_args = "o, a, k"
1261
            code.putln(
1262
                "if (%s(%s) < 0) {" %
1263
                    (entry.func_cname, cinit_args))
1264
            code.put_decref_clear("o", py_object_type, nanny=False);
1265 1266 1267 1268 1269 1270
            code.putln(
                "}")
        code.putln(
            "return o;")
        code.putln(
            "}")
1271

1272
    def generate_dealloc_function(self, scope, code):
1273 1274
        tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
        slot_func = scope.mangle_internal("tp_dealloc")
1275
        base_type = scope.parent_type.base_type
1276 1277
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1278 1279 1280 1281 1282
        code.putln("")
        code.putln(
            "static void %s(PyObject *o) {"
                % scope.mangle_internal("tp_dealloc"))
        py_attrs = []
1283
        weakref_slot = scope.lookup_here("__weakref__")
1284
        for entry in scope.var_entries:
1285
            if entry.type.is_pyobject and entry is not weakref_slot:
1286
                py_attrs.append(entry)
1287
        if py_attrs or weakref_slot in scope.var_entries:
1288 1289
            self.generate_self_cast(scope, code)
        self.generate_usr_dealloc_call(scope, code)
1290
        if weakref_slot in scope.var_entries:
1291
            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1292
        for entry in py_attrs:
1293
            code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
1294
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1295 1296
            tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
            if tp_dealloc is None:
1297
                tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
1298
            code.putln(
1299
                    "%s(o);" % tp_dealloc)
1300 1301
        else:
            code.putln(
1302
                    "(*Py_TYPE(o)->tp_free)(o);")
1303 1304
        code.putln(
            "}")
1305

1306 1307 1308 1309 1310 1311 1312 1313 1314 1315
    def generate_usr_dealloc_call(self, scope, code):
        entry = scope.lookup_here("__dealloc__")
        if entry:
            code.putln(
                "{")
            code.putln(
                    "PyObject *etype, *eval, *etb;")
            code.putln(
                    "PyErr_Fetch(&etype, &eval, &etb);")
            code.putln(
1316
                    "++Py_REFCNT(o);")
1317
            code.putln(
1318
                    "%s(o);" %
1319 1320 1321 1322
                        entry.func_cname)
            code.putln(
                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
            code.putln(
1323
                    "--Py_REFCNT(o);")
1324 1325 1326 1327
            code.putln(
                    "PyErr_Restore(etype, eval, etb);")
            code.putln(
                "}")
1328

1329
    def generate_traverse_function(self, scope, code):
1330 1331
        tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
        slot_func = scope.mangle_internal("tp_traverse")
1332
        base_type = scope.parent_type.base_type
1333 1334
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1335 1336 1337
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, visitproc v, void *a) {"
1338
                % slot_func)
1339 1340
        py_attrs = []
        for entry in scope.var_entries:
1341
            if entry.type.is_pyobject and entry.name != "__weakref__":
1342 1343
                py_attrs.append(entry)
        if base_type or py_attrs:
1344
            code.putln("int e;")
1345 1346 1347
        if py_attrs:
            self.generate_self_cast(scope, code)
        if base_type:
1348
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1349 1350 1351
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("e = %s(o, v, a); if (e) return e;" % static_call)
1352 1353 1354 1355 1356 1357
            else:
                code.putln("if (%s->tp_traverse) {" % base_type.typeptr_cname)
                code.putln(
                        "e = %s->tp_traverse(o, v, a); if (e) return e;" %
                            base_type.typeptr_cname)
                code.putln("}")
1358 1359 1360 1361 1362 1363 1364 1365
        for entry in py_attrs:
            var_code = "p->%s" % entry.cname
            code.putln(
                    "if (%s) {"
                        % var_code)
            if entry.type.is_extension_type:
                var_code = "((PyObject*)%s)" % var_code
            code.putln(
1366
                        "e = (*v)(%s, a); if (e) return e;"
1367 1368 1369 1370 1371 1372 1373
                            % var_code)
            code.putln(
                    "}")
        code.putln(
                "return 0;")
        code.putln(
            "}")
1374

1375
    def generate_clear_function(self, scope, code):
1376 1377
        tp_slot = TypeSlots.GCDependentSlot("tp_clear")
        slot_func = scope.mangle_internal("tp_clear")
1378
        base_type = scope.parent_type.base_type
1379 1380
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1381
        code.putln("")
1382
        code.putln("static int %s(PyObject *o) {" % slot_func)
1383 1384
        py_attrs = []
        for entry in scope.var_entries:
1385
            if entry.type.is_pyobject and entry.name != "__weakref__":
1386 1387 1388
                py_attrs.append(entry)
        if py_attrs:
            self.generate_self_cast(scope, code)
1389
            code.putln("PyObject* tmp;")
1390
        if base_type:
1391
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1392 1393 1394
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("%s(o);" % static_call)
1395 1396 1397 1398
            else:
                code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
                code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
                code.putln("}")
1399 1400
        for entry in py_attrs:
            name = "p->%s" % entry.cname
1401
            code.putln("tmp = ((PyObject*)%s);" % name)
1402 1403 1404 1405
            if entry.is_declared_generic:
                code.put_init_to_py_none(name, py_object_type, nanny=False)
            else:
                code.put_init_to_py_none(name, entry.type, nanny=False)
1406
            code.putln("Py_XDECREF(tmp);")
1407 1408 1409 1410
        code.putln(
            "return 0;")
        code.putln(
            "}")
1411

1412 1413 1414 1415 1416
    def generate_getitem_int_function(self, scope, code):
        # This function is put into the sq_item slot when
        # a __getitem__ method is present. It converts its
        # argument to a Python integer and calls mp_subscript.
        code.putln(
1417
            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1418 1419 1420 1421
                scope.mangle_internal("sq_item"))
        code.putln(
                "PyObject *r;")
        code.putln(
1422
                "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1423
        code.putln(
1424
                "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454
        code.putln(
                "Py_DECREF(x);")
        code.putln(
                "return r;")
        code.putln(
            "}")

    def generate_ass_subscript_function(self, scope, code):
        # Setting and deleting an item are both done through
        # the ass_subscript method, so we dispatch to user's __setitem__
        # or __delitem__, or raise an exception.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setitem__")
        del_entry = scope.lookup_here("__delitem__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
                scope.mangle_internal("mp_ass_subscript"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, i, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1455
                    '  "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, i);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1472
                    '  "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1473 1474 1475 1476 1477 1478
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")
1479

1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507
    def generate_guarded_basetype_call(
            self, base_type, substructure, slot, args, code):
        if base_type:
            base_tpname = base_type.typeptr_cname
            if substructure:
                code.putln(
                    "if (%s->%s && %s->%s->%s)" % (
                        base_tpname, substructure, base_tpname, substructure, slot))
                code.putln(
                    "  return %s->%s->%s(%s);" % (
                        base_tpname, substructure, slot, args))
            else:
                code.putln(
                    "if (%s->%s)" % (
                        base_tpname, slot))
                code.putln(
                    "  return %s->%s(%s);" % (
                        base_tpname, slot, args))

    def generate_ass_slice_function(self, scope, code):
        # Setting and deleting a slice are both done through
        # the ass_slice method, so we dispatch to user's __setslice__
        # or __delslice__, or raise an exception.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setslice__")
        del_entry = scope.lookup_here("__delslice__")
        code.putln("")
        code.putln(
1508
            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
                scope.mangle_internal("sq_ass_slice"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, i, j, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1522
                    '  "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, i, j);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
            code.putln(
                    "PyErr_Format(PyExc_NotImplementedError,")
            code.putln(
1539
                    '  "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1540 1541 1542 1543 1544 1545 1546 1547
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_getattro_function(self, scope, code):
1548 1549 1550
        # First try to get the attribute using __getattribute__, if defined, or
        # PyObject_GenericGetAttr.
        #
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565
        # If that raises an AttributeError, call the __getattr__ if defined.
        #
        # In both cases, defined can be in this class, or any base class.
        def lookup_here_or_base(n,type=None):
            # Recursive lookup
            if type is None:
                type = scope.parent_type
            r = type.scope.lookup_here(n)
            if r is None and \
               type.base_type is not None:
                return lookup_here_or_base(n,type.base_type)
            else:
                return r
        getattr_entry = lookup_here_or_base("__getattr__")
        getattribute_entry = lookup_here_or_base("__getattribute__")
1566 1567 1568 1569
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *n) {"
                % scope.mangle_internal("tp_getattro"))
1570 1571 1572 1573 1574 1575
        if getattribute_entry is not None:
            code.putln(
                "PyObject *v = %s(o, n);" %
                    getattribute_entry.func_cname)
        else:
            code.putln(
1576
                "PyObject *v = PyObject_GenericGetAttr(o, n);")
1577 1578
        if getattr_entry is not None:
            code.putln(
1579
                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1580 1581 1582 1583 1584 1585
            code.putln(
                "PyErr_Clear();")
            code.putln(
                "v = %s(o, n);" %
                    getattr_entry.func_cname)
            code.putln(
1586 1587
                "}")
        code.putln(
1588
            "return v;")
1589 1590
        code.putln(
            "}")
1591

1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630
    def generate_setattro_function(self, scope, code):
        # Setting and deleting an attribute are both done through
        # the setattro method, so we dispatch to user's __setattr__
        # or __delattr__ or fall back on PyObject_GenericSetAttr.
        base_type = scope.parent_type.base_type
        set_entry = scope.lookup_here("__setattr__")
        del_entry = scope.lookup_here("__delattr__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
                scope.mangle_internal("tp_setattro"))
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, n, v);" %
                        set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_setattro", "o, n, v", code)
            code.putln(
                    "return PyObject_GenericSetAttr(o, n, v);")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o, n);" %
                        del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_setattro", "o, n, v", code)
            code.putln(
                    "return PyObject_GenericSetAttr(o, n, 0);")
        code.putln(
                "}")
        code.putln(
            "}")
1631

1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658
    def generate_descr_get_function(self, scope, code):
        # The __get__ function of a descriptor object can be
        # called with NULL for the second or third arguments
        # under some circumstances, so we replace them with
        # None in that case.
        user_get_entry = scope.lookup_here("__get__")
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
                scope.mangle_internal("tp_descr_get"))
        code.putln(
            "PyObject *r = 0;")
        code.putln(
            "if (!i) i = Py_None;")
        code.putln(
            "if (!c) c = Py_None;")
        #code.put_incref("i", py_object_type)
        #code.put_incref("c", py_object_type)
        code.putln(
            "r = %s(o, i, c);" %
                user_get_entry.func_cname)
        #code.put_decref("i", py_object_type)
        #code.put_decref("c", py_object_type)
        code.putln(
            "return r;")
        code.putln(
            "}")
1659

1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699
    def generate_descr_set_function(self, scope, code):
        # Setting and deleting are both done through the __set__
        # method of a descriptor, so we dispatch to user's __set__
        # or __delete__ or raise an exception.
        base_type = scope.parent_type.base_type
        user_set_entry = scope.lookup_here("__set__")
        user_del_entry = scope.lookup_here("__delete__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
                scope.mangle_internal("tp_descr_set"))
        code.putln(
                "if (v) {")
        if user_set_entry:
            code.putln(
                    "return %s(o, i, v);" %
                        user_set_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_descr_set", "o, i, v", code)
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if user_del_entry:
            code.putln(
                    "return %s(o, i);" %
                        user_del_entry.func_cname)
        else:
            self.generate_guarded_basetype_call(
                base_type, None, "tp_descr_set", "o, i, v", code)
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
            code.putln(
                    "return -1;")
        code.putln(
1700
                "}")
1701 1702
        code.putln(
            "}")
1703

1704 1705 1706 1707 1708 1709 1710
    def generate_property_accessors(self, cclass_scope, code):
        for entry in cclass_scope.property_entries:
            property_scope = entry.scope
            if property_scope.defines_any(["__get__"]):
                self.generate_property_get_function(entry, code)
            if property_scope.defines_any(["__set__", "__del__"]):
                self.generate_property_set_function(entry, code)
1711

1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725
    def generate_property_get_function(self, property_entry, code):
        property_scope = property_entry.scope
        property_entry.getter_cname = property_scope.parent_scope.mangle(
            Naming.prop_get_prefix, property_entry.name)
        get_entry = property_scope.lookup_here("__get__")
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, void *x) {" %
                property_entry.getter_cname)
        code.putln(
                "return %s(o);" %
                    get_entry.func_cname)
        code.putln(
            "}")
1726

1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
    def generate_property_set_function(self, property_entry, code):
        property_scope = property_entry.scope
        property_entry.setter_cname = property_scope.parent_scope.mangle(
            Naming.prop_set_prefix, property_entry.name)
        set_entry = property_scope.lookup_here("__set__")
        del_entry = property_scope.lookup_here("__del__")
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, PyObject *v, void *x) {" %
                property_entry.setter_cname)
        code.putln(
                "if (v) {")
        if set_entry:
            code.putln(
                    "return %s(o, v);" %
                        set_entry.func_cname)
        else:
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
                "else {")
        if del_entry:
            code.putln(
                    "return %s(o);" %
                        del_entry.func_cname)
        else:
            code.putln(
                    'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_typeobj_definition(self, modname, entry, code):
        type = entry.type
        scope = type.scope
        for suite in TypeSlots.substructures:
            suite.generate_substructure(scope, code)
        code.putln("")
        if entry.visibility == 'public':
            header = "DL_EXPORT(PyTypeObject) %s = {"
        else:
1775
            header = "static PyTypeObject %s = {"
1776 1777 1778
        #code.putln(header % scope.parent_type.typeobj_cname)
        code.putln(header % type.typeobj_cname)
        code.putln(
1779
            "PyVarObject_HEAD_INIT(0, 0)")
1780
        code.putln(
1781
            '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1782
                self.full_module_name, scope.class_name))
1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
        code.putln(
            "sizeof(%s), /*tp_basicsize*/" %
                objstruct)
        code.putln(
            "0, /*tp_itemsize*/")
        for slot in TypeSlots.slot_table:
            slot.generate(scope, code)
        code.putln(
            "};")
1796

1797 1798 1799
    def generate_method_table(self, env, code):
        code.putln("")
        code.putln(
1800
            "static PyMethodDef %s[] = {" %
1801 1802
                env.method_table_cname)
        for entry in env.pyfunc_entries:
1803
            code.put_pymethoddef(entry, ",")
1804 1805 1806 1807
        code.putln(
                "{0, 0, 0, 0}")
        code.putln(
            "};")
1808

1809 1810 1811 1812 1813 1814 1815
    def generate_getset_table(self, env, code):
        if env.property_entries:
            code.putln("")
            code.putln(
                "static struct PyGetSetDef %s[] = {" %
                    env.getset_table_cname)
            for entry in env.property_entries:
1816 1817 1818 1819
                if entry.doc:
                    doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
                else:
                    doc_code = "0"
1820
                code.putln(
1821
                    '{(char *)"%s", %s, %s, %s, 0},' % (
1822 1823 1824
                        entry.name,
                        entry.getter_cname or "0",
                        entry.setter_cname or "0",
1825
                        doc_code))
1826 1827 1828 1829
            code.putln(
                    "{0, 0, 0, 0, 0}")
            code.putln(
                "};")
1830

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1831
    def generate_import_star(self, env, code):
1832
        env.use_utility_code(streq_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1833 1834 1835 1836 1837 1838 1839 1840
        code.putln()
        code.putln("char* %s_type_names[] = {" % Naming.import_star)
        for name, entry in env.entries.items():
            if entry.is_type:
                code.putln('"%s",' % name)
        code.putln("0")
        code.putln("};")
        code.putln()
1841
        code.enter_cfunc_scope() # as we need labels
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1842 1843 1844
        code.putln("static int %s(PyObject *o, PyObject* py_name, char *name) {" % Naming.import_star_set)
        code.putln("char** type_name = %s_type_names;" % Naming.import_star)
        code.putln("while (*type_name) {")
1845
        code.putln("if (__Pyx_StrEq(name, *type_name)) {")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1846 1847 1848 1849 1850 1851 1852 1853 1854
        code.putln('PyErr_Format(PyExc_TypeError, "Cannot overwrite C type %s", name);')
        code.putln('goto bad;')
        code.putln("}")
        code.putln("type_name++;")
        code.putln("}")
        old_error_label = code.new_error_label()
        code.putln("if (0);") # so the first one can be "else if"
        for name, entry in env.entries.items():
            if entry.is_cglobal and entry.used:
1855
                code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1856 1857 1858 1859 1860
                if entry.type.is_pyobject:
                    if entry.type.is_extension_type or entry.type.is_builtin_type:
                        code.putln("if (!(%s)) %s;" % (
                            entry.type.type_test_code("o"),
                            code.error_goto(entry.pos)))
1861 1862
                    code.putln("Py_INCREF(o);")
                    code.put_decref(entry.cname, entry.type, nanny=False)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1863
                    code.putln("%s = %s;" % (
1864
                        entry.cname,
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1865 1866 1867 1868
                        PyrexTypes.typecast(entry.type, py_object_type, "o")))
                elif entry.type.from_py_function:
                    rhs = "%s(o)" % entry.type.from_py_function
                    if entry.type.is_enum:
1869
                        rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882
                    code.putln("%s = %s; if (%s) %s;" % (
                        entry.cname,
                        rhs,
                        entry.type.error_condition(entry.cname),
                        code.error_goto(entry.pos)))
                else:
                    code.putln('PyErr_Format(PyExc_TypeError, "Cannot convert Python object %s to %s");' % (name, entry.type))
                    code.putln(code.error_goto(entry.pos))
                code.putln("}")
        code.putln("else {")
        code.putln("if (PyObject_SetAttr(%s, py_name, o) < 0) goto bad;" % Naming.module_cname)
        code.putln("}")
        code.putln("return 0;")
1883 1884 1885
        if code.label_used(code.error_label):
            code.put_label(code.error_label)
            # This helps locate the offending name.
1886
            code.put_add_traceback(self.full_module_name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1887 1888 1889 1890 1891
        code.error_label = old_error_label
        code.putln("bad:")
        code.putln("return -1;")
        code.putln("}")
        code.putln(import_star_utility_code)
1892
        code.exit_cfunc_scope() # done with labels
1893 1894

    def generate_module_init_func(self, imported_modules, env, code):
1895
        code.enter_cfunc_scope()
1896
        code.putln("")
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906
        header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name
        header3 = "PyMODINIT_FUNC PyInit_%s(void)" % env.module_name
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("%s; /*proto*/" % header2)
        code.putln(header2)
        code.putln("#else")
        code.putln("%s; /*proto*/" % header3)
        code.putln(header3)
        code.putln("#endif")
        code.putln("{")
1907
        tempdecl_code = code.insertion_point()
Robert Bradshaw's avatar
Robert Bradshaw committed
1908

1909
        code.put_declare_refcount_context()
1910 1911 1912
        code.putln("#if CYTHON_REFNANNY")
        code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
        code.putln("if (!__Pyx_RefNanny) {")
1913
        code.putln("  PyErr_Clear();")
1914 1915 1916
        code.putln("  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
        code.putln("  if (!__Pyx_RefNanny)")
        code.putln("      Py_FatalError(\"failed to import 'refnanny' module\");")
1917
        code.putln("}")
1918
        code.putln("#endif")
1919
        code.put_setup_refcount_context(header3)
1920

1921
        env.use_utility_code(check_binary_version_utility_code)
1922
        code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos))
1923

1924
        code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1925
        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
1926

1927 1928
        code.putln("#ifdef __Pyx_CyFunction_USED")
        code.putln("if (__Pyx_CyFunction_init() < 0) %s" % code.error_goto(self.pos))
Robert Bradshaw's avatar
Robert Bradshaw committed
1929
        code.putln("#endif")
1930

1931
        code.putln("/*--- Library function declarations ---*/")
1932
        env.generate_library_function_declarations(code)
1933

1934 1935
        code.putln("/*--- Threads initialization code ---*/")
        code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1936
        code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
1937 1938 1939 1940
        code.putln("PyEval_InitThreads();")
        code.putln("#endif")
        code.putln("#endif")

1941
        code.putln("/*--- Module creation code ---*/")
1942
        self.generate_module_creation_code(env, code)
1943

1944 1945 1946
        code.putln("/*--- Initialize various global constants etc. ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))

1947 1948
        __main__name = code.globalstate.get_py_string_const(
            EncodedString("__main__"), identifier=True)
1949 1950 1951 1952
        code.putln("if (%s%s) {" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
        code.putln(
            'if (__Pyx_SetAttrString(%s, "__name__", %s) < 0) %s;' % (
                env.module_cname,
1953
                __main__name.cname,
1954 1955
                code.error_goto(self.pos)))
        code.putln("}")
1956

Robert Bradshaw's avatar
Robert Bradshaw committed
1957 1958
        if Options.cache_builtins:
            code.putln("/*--- Builtin init code ---*/")
1959 1960 1961 1962
            code.putln(code.error_goto_if_neg("__Pyx_InitCachedBuiltins()", self.pos))

        code.putln("/*--- Constants init code ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitCachedConstants()", self.pos))
1963

1964
        code.putln("/*--- Global init code ---*/")
1965
        self.generate_global_init_code(env, code)
Gary Furnish's avatar
Gary Furnish committed
1966

1967 1968 1969
        code.putln("/*--- Variable export code ---*/")
        self.generate_c_variable_export_code(env, code)

1970
        code.putln("/*--- Function export code ---*/")
1971 1972
        self.generate_c_function_export_code(env, code)

1973
        code.putln("/*--- Type init code ---*/")
1974
        self.generate_type_init_code(env, code)
1975

1976
        code.putln("/*--- Type import code ---*/")
1977 1978 1979
        for module in imported_modules:
            self.generate_type_import_code_for_module(module, env, code)

1980 1981 1982 1983
        code.putln("/*--- Variable import code ---*/")
        for module in imported_modules:
            self.generate_c_variable_import_code_for_module(module, env, code)

Gary Furnish's avatar
Gary Furnish committed
1984 1985 1986 1987
        code.putln("/*--- Function import code ---*/")
        for module in imported_modules:
            self.generate_c_function_import_code_for_module(module, env, code)

1988
        code.putln("/*--- Execution code ---*/")
Robert Bradshaw's avatar
Robert Bradshaw committed
1989
        code.mark_pos(None)
1990

1991
        self.body.generate_execution_code(code)
1992

1993
        if Options.generate_cleanup_code:
1994
            # this should be replaced by the module's tp_clear in Py3
1995
            env.use_utility_code(import_module_utility_code)
1996
            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1997

1998
        code.put_goto(code.return_label)
1999
        code.put_label(code.error_label)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2000 2001
        for cname, type in code.funcstate.all_managed_temps():
            code.put_xdecref(cname, type)
2002
        code.putln('if (%s) {' % env.module_cname)
2003
        code.put_add_traceback("init %s" % env.qualified_name)
2004
        env.use_utility_code(Nodes.traceback_utility_code)
2005
        code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
2006 2007 2008
        code.putln('} else if (!PyErr_Occurred()) {')
        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
        code.putln('}')
2009
        code.put_label(code.return_label)
2010 2011 2012

        code.put_finish_refcount_context()

2013 2014 2015
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("return;")
        code.putln("#else")
2016
        code.putln("return %s;" % env.module_cname)
2017
        code.putln("#endif")
2018
        code.putln('}')
2019

2020
        tempdecl_code.put_temp_declarations(code.funcstate)
2021

2022
        code.exit_cfunc_scope()
2023

2024 2025 2026
    def generate_module_cleanup_func(self, env, code):
        if not Options.generate_cleanup_code:
            return
2027
        code.globalstate.use_utility_code(register_cleanup_utility_code)
2028
        code.putln('static PyObject *%s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused) {' %
2029
                   Naming.cleanup_cname)
2030 2031
        if Options.generate_cleanup_code >= 2:
            code.putln("/*--- Global cleanup code ---*/")
2032 2033 2034
            rev_entries = list(env.var_entries)
            rev_entries.reverse()
            for entry in rev_entries:
2035
                if entry.visibility != 'extern':
2036
                    if entry.type.is_pyobject and entry.used:
2037 2038
                        code.putln("Py_DECREF(%s); %s = 0;" % (
                            code.entry_as_pyobject(entry), entry.cname))
2039
        code.putln("__Pyx_CleanupGlobals();")
2040 2041 2042
        if Options.generate_cleanup_code >= 3:
            code.putln("/*--- Type import cleanup code ---*/")
            for type, _ in env.types_imported.items():
2043
                code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname)
2044 2045
        if Options.cache_builtins:
            code.putln("/*--- Builtin cleanup code ---*/")
2046
            for entry in env.cached_builtins:
2047 2048 2049
                code.put_decref_clear(entry.cname,
                                      PyrexTypes.py_object_type,
                                      nanny=False)
2050
        code.putln("/*--- Intern cleanup code ---*/")
2051 2052 2053
        code.put_decref_clear(Naming.empty_tuple,
                              PyrexTypes.py_object_type,
                              nanny=False)
2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066
#        for entry in env.pynum_entries:
#            code.put_decref_clear(entry.cname,
#                                  PyrexTypes.py_object_type,
#                                  nanny=False)
#        for entry in env.all_pystring_entries:
#            if entry.is_interned:
#                code.put_decref_clear(entry.pystring_cname,
#                                      PyrexTypes.py_object_type,
#                                      nanny=False)
#        for entry in env.default_entries:
#            if entry.type.is_pyobject and entry.used:
#                code.putln("Py_DECREF(%s); %s = 0;" % (
#                    code.entry_as_pyobject(entry), entry.cname))
2067 2068
        code.putln("Py_INCREF(Py_None); return Py_None;")

2069
    def generate_main_method(self, env, code):
2070
        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
2071 2072 2073 2074 2075 2076 2077 2078 2079 2080
        if Options.embed == "main":
            wmain = "wmain"
        else:
            wmain = Options.embed
        code.globalstate.use_utility_code(
            main_method.specialize(
                module_name = env.module_name,
                module_is_main = module_is_main,
                main_method = Options.embed,
                wmain_method = wmain))
2081

2082 2083
    def generate_pymoduledef_struct(self, env, code):
        if env.doc:
2084
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2085 2086 2087 2088 2089 2090
        else:
            doc = "0"
        code.putln("")
        code.putln("#if PY_MAJOR_VERSION >= 3")
        code.putln("static struct PyModuleDef %s = {" % Naming.pymoduledef_cname)
        code.putln("  PyModuleDef_HEAD_INIT,")
2091
        code.putln('  __Pyx_NAMESTR("%s"),' % env.module_name)
2092 2093 2094 2095 2096 2097 2098 2099 2100 2101
        code.putln("  %s, /* m_doc */" % doc)
        code.putln("  -1, /* m_size */")
        code.putln("  %s /* m_methods */," % env.method_table_cname)
        code.putln("  NULL, /* m_reload */")
        code.putln("  NULL, /* m_traverse */")
        code.putln("  NULL, /* m_clear */")
        code.putln("  NULL /* m_free */")
        code.putln("};")
        code.putln("#endif")

2102 2103 2104 2105
    def generate_module_creation_code(self, env, code):
        # Generate code to create the module object and
        # install the builtins.
        if env.doc:
2106
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
2107 2108
        else:
            doc = "0"
2109
        code.putln("#if PY_MAJOR_VERSION < 3")
2110
        code.putln(
2111
            '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
2112 2113 2114
                env.module_cname,
                env.module_name,
                env.method_table_cname,
2115
                doc))
2116 2117 2118 2119 2120 2121
        code.putln("#else")
        code.putln(
            "%s = PyModule_Create(&%s);" % (
                env.module_cname,
                Naming.pymoduledef_cname))
        code.putln("#endif")
2122 2123 2124 2125
        code.putln(
            "if (!%s) %s;" % (
                env.module_cname,
                code.error_goto(self.pos)));
2126
        code.putln("#if PY_MAJOR_VERSION < 3")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2127 2128 2129
        code.putln(
            "Py_INCREF(%s);" %
                env.module_cname)
2130
        code.putln("#endif")
2131
        code.putln(
2132
            '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
2133 2134 2135 2136 2137 2138
                Naming.builtins_cname)
        code.putln(
            "if (!%s) %s;" % (
                Naming.builtins_cname,
                code.error_goto(self.pos)));
        code.putln(
2139
            'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
2140 2141 2142
                env.module_cname,
                Naming.builtins_cname,
                code.error_goto(self.pos)))
2143 2144
        if Options.pre_import is not None:
            code.putln(
2145
                '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
2146
                    Naming.preimport_cname,
2147 2148 2149 2150 2151
                    Options.pre_import))
            code.putln(
                "if (!%s) %s;" % (
                    Naming.preimport_cname,
                    code.error_goto(self.pos)));
2152

2153 2154 2155 2156
    def generate_global_init_code(self, env, code):
        # Generate code to initialise global PyObject *
        # variables to None.
        for entry in env.var_entries:
2157
            if entry.visibility != 'extern':
2158 2159
                if entry.used:
                    entry.type.global_init_code(entry, code)
2160

2161 2162
    def generate_c_variable_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2163
        entries = []
2164
        for entry in env.var_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2165 2166 2167
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2168 2169 2170 2171
                entries.append(entry)
        if entries:
            env.use_utility_code(voidptr_export_utility_code)
            for entry in entries:
2172 2173
                signature = entry.type.declaration_code("")
                code.putln('if (__Pyx_ExportVoidPtr("%s", (void *)&%s, "%s") < 0) %s' % (
2174
                    entry.name, entry.cname, signature,
2175 2176
                    code.error_goto(self.pos)))

2177 2178
    def generate_c_function_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
2179
        entries = []
2180
        for entry in env.cfunc_entries:
Robert Bradshaw's avatar
Robert Bradshaw committed
2181 2182 2183
            if (entry.api
                or entry.defined_in_pxd
                or (Options.cimport_from_pyx and not entry.visibility == 'extern')):
2184 2185 2186 2187
                entries.append(entry)
        if entries:
            env.use_utility_code(function_export_utility_code)
            for entry in entries:
2188
                signature = entry.type.signature_string()
2189
                code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
2190 2191
                    entry.name,
                    entry.cname,
2192
                    signature,
2193
                    code.error_goto(self.pos)))
2194

2195
    def generate_type_import_code_for_module(self, module, env, code):
2196
        # Generate type import code for all exported extension types in
2197
        # an imported module.
2198 2199 2200
        #if module.c_class_entries:
        for entry in module.c_class_entries:
            if entry.defined_in_pxd:
2201
                self.generate_type_import_code(env, entry.type, entry.pos, code)
2202

2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230
    def generate_c_variable_import_code_for_module(self, module, env, code):
        # Generate import code for all exported C functions in a cimported module.
        entries = []
        for entry in module.var_entries:
            if entry.defined_in_pxd:
                entries.append(entry)
        if entries:
            env.use_utility_code(import_module_utility_code)
            env.use_utility_code(voidptr_import_utility_code)
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
            for entry in entries:
                if env is module:
                    cname = entry.cname
                else:
                    cname = module.mangle(Naming.varptr_prefix, entry.name)
                signature = entry.type.declaration_code("")
                code.putln(
                    'if (__Pyx_ImportVoidPtr(%s, "%s", (void **)&%s, "%s") < 0) %s' % (
                        temp, entry.name, cname, signature,
                        code.error_goto(self.pos)))
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))

2231 2232 2233 2234 2235 2236 2237 2238 2239
    def generate_c_function_import_code_for_module(self, module, env, code):
        # Generate import code for all exported C functions in a cimported module.
        entries = []
        for entry in module.cfunc_entries:
            if entry.defined_in_pxd:
                entries.append(entry)
        if entries:
            env.use_utility_code(import_module_utility_code)
            env.use_utility_code(function_import_utility_code)
2240
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2241 2242 2243 2244 2245 2246
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
2247 2248
            for entry in entries:
                code.putln(
2249
                    'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
2250
                        temp,
2251 2252 2253 2254
                        entry.name,
                        entry.cname,
                        entry.type.signature_string(),
                        code.error_goto(self.pos)))
2255
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
2256

2257 2258 2259 2260
    def generate_type_init_code(self, env, code):
        # Generate type import code for extern extension types
        # and type ready code for non-extern ones.
        for entry in env.c_class_entries:
2261
            if entry.visibility == 'extern' and not entry.utility_code_definition:
2262 2263 2264 2265 2266 2267
                self.generate_type_import_code(env, entry.type, entry.pos, code)
            else:
                self.generate_base_type_import_code(env, entry, code)
                self.generate_exttype_vtable_init_code(entry, code)
                self.generate_type_ready_code(env, entry, code)
                self.generate_typeptr_assignment_code(entry, code)
2268

2269 2270
    def generate_base_type_import_code(self, env, entry, code):
        base_type = entry.type.base_type
2271 2272
        if (base_type and base_type.module_name != env.qualified_name and not
               base_type.is_builtin_type and not entry.utility_code_definition):
2273
            self.generate_type_import_code(env, base_type, self.pos, code)
2274

2275
    def use_type_import_utility_code(self, env):
2276 2277
        env.use_utility_code(type_import_utility_code)
        env.use_utility_code(import_module_utility_code)
2278

2279 2280 2281 2282 2283 2284 2285 2286 2287 2288
    def generate_type_import_code(self, env, type, pos, code):
        # If not already done, generate code to import the typeobject of an
        # extension type defined in another module, and extract its C method
        # table pointer if any.
        if type in env.types_imported:
            return
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
2289 2290
        self.generate_type_import_call(type, code,
                                       code.error_goto_if_null(type.typeptr_cname, pos))
2291 2292 2293
        self.use_type_import_utility_code(env)
        if type.vtabptr_cname:
            env.use_utility_code(Nodes.get_vtable_utility_code)
2294 2295 2296 2297 2298
            code.putln("%s = (struct %s*)__Pyx_GetVtable(%s->tp_dict); %s" % (
                type.vtabptr_cname,
                type.vtabstruct_cname,
                type.typeptr_cname,
                code.error_goto_if_null(type.vtabptr_cname, pos)))
2299
        env.types_imported[type] = 1
2300

2301 2302
    py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}

2303 2304 2305 2306 2307
    def generate_type_import_call(self, type, code, error_code):
        if type.typedef_flag:
            objstruct = type.objstruct_cname
        else:
            objstruct = "struct %s" % type.objstruct_cname
2308
        module_name = type.module_name
2309
        condition = None
2310 2311 2312 2313
        if module_name not in ('__builtin__', 'builtins'):
            module_name = '"%s"' % module_name
        else:
            module_name = '__Pyx_BUILTIN_MODULE_NAME'
2314 2315 2316 2317 2318 2319 2320 2321 2322 2323
            if type.name in Code.non_portable_builtins_map:
                condition, replacement = Code.non_portable_builtins_map[entry.name]
                code.putln("#if %s" % condition)
                code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), 1); %s' % (
                        type.typeptr_cname,
                        module_name,
                        replacement,
                        objstruct,
                        error_code))
                code.putln("#else")
2324
        code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), %i); %s' % (
2325 2326 2327 2328
                type.typeptr_cname,
                module_name,
                type.name,
                objstruct,
2329
                not type.is_external or type.is_subclassed,
2330
                error_code))
2331
        if condition:
2332
            code.putln("#endif")
2333

2334 2335 2336 2337 2338 2339 2340
    def generate_type_ready_code(self, env, entry, code):
        # Generate a call to PyType_Ready for an extension
        # type defined in this module.
        type = entry.type
        typeobj_cname = type.typeobj_cname
        scope = type.scope
        if scope: # could be None if there was an error
Stefan Behnel's avatar
Stefan Behnel committed
2341
            if entry.visibility != 'extern':
2342 2343 2344 2345 2346 2347
                for slot in TypeSlots.slot_table:
                    slot.generate_dynamic_init_code(scope, code)
                code.putln(
                    "if (PyType_Ready(&%s) < 0) %s" % (
                        typeobj_cname,
                        code.error_goto(entry.pos)))
2348
                # Fix special method docstrings. This is a bit of a hack, but
2349
                # unless we let PyType_Ready create the slot wrappers we have
2350
                # a significant performance hit. (See trac #561.)
2351
                for func in entry.type.scope.pyfunc_entries:
2352
                    if func.is_special and Options.docstrings and func.wrapperbase_cname:
Stefan Behnel's avatar
Stefan Behnel committed
2353
                        code.putln("{")
2354
                        code.putln(
2355
                            'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
2356 2357
                                typeobj_cname,
                                func.name,
Stefan Behnel's avatar
Stefan Behnel committed
2358
                                code.error_goto_if_null('wrapper', entry.pos)))
2359
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2360
                            "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
2361 2362
                        code.putln(
                            "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2363
                                func.wrapperbase_cname))
2364
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2365
                            "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname))
2366 2367
                        code.putln(
                            "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2368 2369 2370
                                func.wrapperbase_cname))
                        code.putln("}")
                        code.putln("}")
2371 2372 2373 2374 2375 2376 2377
                if type.vtable_cname:
                    code.putln(
                        "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
                            typeobj_cname,
                            type.vtabptr_cname,
                            code.error_goto(entry.pos)))
                    env.use_utility_code(Nodes.set_vtable_utility_code)
2378 2379 2380 2381 2382 2383 2384 2385 2386 2387
                if not type.scope.is_internal and not type.scope.directives['internal']:
                    # scope.is_internal is set for types defined by
                    # Cython (such as closures), the 'internal'
                    # directive is set by users
                    code.putln(
                        'if (__Pyx_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
                            Naming.module_cname,
                            scope.class_name,
                            typeobj_cname,
                            code.error_goto(entry.pos)))
2388 2389 2390 2391
                weakref_entry = scope.lookup_here("__weakref__")
                if weakref_entry:
                    if weakref_entry.type is py_object_type:
                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
2392 2393 2394 2395 2396
                        if type.typedef_flag:
                            objstruct = type.objstruct_cname
                        else:
                            objstruct = "struct %s" % type.objstruct_cname
                        code.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2397 2398
                            tp_weaklistoffset,
                            tp_weaklistoffset,
2399
                            objstruct,
2400 2401 2402
                            weakref_entry.cname))
                    else:
                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
2403

2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418
    def generate_exttype_vtable_init_code(self, entry, code):
        # Generate code to initialise the C method table of an
        # extension type.
        type = entry.type
        if type.vtable_cname:
            code.putln(
                "%s = &%s;" % (
                    type.vtabptr_cname,
                    type.vtable_cname))
            if type.base_type and type.base_type.vtabptr_cname:
                code.putln(
                    "%s.%s = *%s;" % (
                        type.vtable_cname,
                        Naming.obj_base_cname,
                        type.base_type.vtabptr_cname))
2419 2420 2421 2422

            c_method_entries = [
                entry for entry in type.scope.cfunc_entries
                if entry.func_cname ]
2423 2424 2425 2426 2427 2428 2429 2430 2431
            if c_method_entries:
                for meth_entry in c_method_entries:
                    cast = meth_entry.type.signature_cast_string()
                    code.putln(
                        "%s.%s = %s%s;" % (
                            type.vtable_cname,
                            meth_entry.cname,
                            cast,
                            meth_entry.func_cname))
2432

2433 2434 2435 2436 2437 2438 2439 2440
    def generate_typeptr_assignment_code(self, entry, code):
        # Generate code to initialise the typeptr of an extension
        # type defined in this module to point to its type object.
        type = entry.type
        if type.typeobj_cname:
            code.putln(
                "%s = &%s;" % (
                    type.typeptr_cname, type.typeobj_cname))
2441

2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474
def generate_cfunction_declaration(entry, env, code, definition):
    if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
            or entry.defined_in_pxd or entry.visibility == 'extern')):
        if entry.visibility == 'extern':
            storage_class = "%s " % Naming.extern_c_macro
            dll_linkage = "DL_IMPORT"
        elif entry.visibility == 'public':
            storage_class = "%s " % Naming.extern_c_macro
            dll_linkage = "DL_EXPORT"
        elif entry.visibility == 'private':
            storage_class = "static "
            dll_linkage = None
        else:
            storage_class = "static "
            dll_linkage = None
        type = entry.type

        if entry.defined_in_pxd and not definition:
            storage_class = "static "
            dll_linkage = None
            type = CPtrType(type)

        header = type.declaration_code(entry.cname,
                                       dll_linkage = dll_linkage)
        if entry.func_modifiers:
            modifiers = "%s " % ' '.join(entry.func_modifiers).upper()
        else:
            modifiers = ''
        code.putln("%s%s%s; /*proto*/" % (
            storage_class,
            modifiers,
            header))

2475
#------------------------------------------------------------------------------------
Stefan Behnel's avatar
Stefan Behnel committed
2476 2477 2478
#
#  Runtime support code
#
2479 2480
#------------------------------------------------------------------------------------

2481 2482
streq_utility_code = UtilityCode(
proto = """
2483
static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2484 2485
""",
impl = """
2486
static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2487 2488 2489 2490 2491 2492 2493
     while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
     return *s1 == *s2;
}
""")

#------------------------------------------------------------------------------------

2494 2495
import_module_utility_code = UtilityCode(
proto = """
2496
static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2497 2498
""",
impl = """
2499 2500
#ifndef __PYX_HAVE_RT_ImportModule
#define __PYX_HAVE_RT_ImportModule
2501
static PyObject *__Pyx_ImportModule(const char *name) {
2502
    PyObject *py_name = 0;
2503
    PyObject *py_module = 0;
2504

2505
    py_name = __Pyx_PyIdentifier_FromString(name);
2506 2507
    if (!py_name)
        goto bad;
2508 2509 2510
    py_module = PyImport_Import(py_name);
    Py_DECREF(py_name);
    return py_module;
2511 2512 2513 2514
bad:
    Py_XDECREF(py_name);
    return 0;
}
2515
#endif
2516
""")
2517 2518 2519

#------------------------------------------------------------------------------------

2520 2521
type_import_utility_code = UtilityCode(
proto = """
2522
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, size_t size, int strict);  /*proto*/
2523 2524
""",
impl = """
Stefan Behnel's avatar
Stefan Behnel committed
2525 2526
#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
2527
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2528
    size_t size, int strict)
2529 2530
{
    PyObject *py_module = 0;
2531
    PyObject *result = 0;
Gary Furnish's avatar
Gary Furnish committed
2532
    PyObject *py_name = 0;
2533
    char warning[200];
2534

2535 2536 2537
    py_module = __Pyx_ImportModule(module_name);
    if (!py_module)
        goto bad;
2538
    py_name = __Pyx_PyIdentifier_FromString(class_name);
Gary Furnish's avatar
Gary Furnish committed
2539 2540
    if (!py_name)
        goto bad;
2541 2542
    result = PyObject_GetAttr(py_module, py_name);
    Py_DECREF(py_name);
2543 2544 2545
    py_name = 0;
    Py_DECREF(py_module);
    py_module = 0;
2546 2547 2548
    if (!result)
        goto bad;
    if (!PyType_Check(result)) {
2549
        PyErr_Format(PyExc_TypeError,
2550 2551 2552 2553
            "%s.%s is not a type object",
            module_name, class_name);
        goto bad;
    }
2554
    if (!strict && ((PyTypeObject *)result)->tp_basicsize > (Py_ssize_t)size) {
2555
        PyOS_snprintf(warning, sizeof(warning),
2556 2557
            "%s.%s size changed, may indicate binary incompatibility",
            module_name, class_name);
2558
        #if PY_VERSION_HEX < 0x02050000
2559
        if (PyErr_Warn(NULL, warning) < 0) goto bad;
2560
        #else
2561
        if (PyErr_WarnEx(NULL, warning, 0) < 0) goto bad;
2562
        #endif
2563
    }
2564
    else if (((PyTypeObject *)result)->tp_basicsize != (Py_ssize_t)size) {
2565
        PyErr_Format(PyExc_ValueError,
2566
            "%s.%s has the wrong size, try recompiling",
2567 2568 2569 2570 2571
            module_name, class_name);
        goto bad;
    }
    return (PyTypeObject *)result;
bad:
2572
    Py_XDECREF(py_module);
2573
    Py_XDECREF(result);
2574
    return NULL;
2575
}
Stefan Behnel's avatar
Stefan Behnel committed
2576
#endif
2577
""")
2578 2579 2580

#------------------------------------------------------------------------------------

2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619
voidptr_export_utility_code = UtilityCode(
proto = """
static int __Pyx_ExportVoidPtr(const char *name, void *p, const char *sig); /*proto*/
""",
impl = r"""
static int __Pyx_ExportVoidPtr(const char *name, void *p, const char *sig) {
    PyObject *d = 0;
    PyObject *cobj = 0;

    d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
    if (!d) {
        PyErr_Clear();
        d = PyDict_New();
        if (!d)
            goto bad;
        Py_INCREF(d);
        if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
            goto bad;
    }
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
    cobj = PyCapsule_New(p, sig, 0);
#else
    cobj = PyCObject_FromVoidPtrAndDesc(p, (void *)sig, 0);
#endif
    if (!cobj)
        goto bad;
    if (PyDict_SetItemString(d, name, cobj) < 0)
        goto bad;
    Py_DECREF(cobj);
    Py_DECREF(d);
    return 0;
bad:
    Py_XDECREF(cobj);
    Py_XDECREF(d);
    return -1;
}
""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
)

2620 2621
function_export_utility_code = UtilityCode(
proto = """
2622
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
2623 2624
""",
impl = r"""
2625
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
2626
    PyObject *d = 0;
2627 2628 2629 2630 2631 2632
    PyObject *cobj = 0;
    union {
        void (*fp)(void);
        void *p;
    } tmp;

2633
    d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
2634 2635 2636 2637 2638 2639
    if (!d) {
        PyErr_Clear();
        d = PyDict_New();
        if (!d)
            goto bad;
        Py_INCREF(d);
2640
        if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
2641 2642
            goto bad;
    }
2643
    tmp.fp = f;
2644
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
2645
    cobj = PyCapsule_New(tmp.p, sig, 0);
2646 2647
#else
    cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
2648
#endif
2649
    if (!cobj)
2650
        goto bad;
2651
    if (PyDict_SetItemString(d, name, cobj) < 0)
2652
        goto bad;
2653
    Py_DECREF(cobj);
2654
    Py_DECREF(d);
2655 2656
    return 0;
bad:
2657
    Py_XDECREF(cobj);
2658
    Py_XDECREF(d);
2659 2660
    return -1;
}
2661 2662
""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
)
2663

2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719
voidptr_import_utility_code = UtilityCode(
proto = """
static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig); /*proto*/
""",
impl = """
#ifndef __PYX_HAVE_RT_ImportVoidPtr
#define __PYX_HAVE_RT_ImportVoidPtr
static int __Pyx_ImportVoidPtr(PyObject *module, const char *name, void **p, const char *sig) {
    PyObject *d = 0;
    PyObject *cobj = 0;

    d = PyObject_GetAttrString(module, (char *)"%(API)s");
    if (!d)
        goto bad;
    cobj = PyDict_GetItemString(d, name);
    if (!cobj) {
        PyErr_Format(PyExc_ImportError,
            "%%s does not export expected C variable %%s",
                PyModule_GetName(module), name);
        goto bad;
    }
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
    if (!PyCapsule_IsValid(cobj, sig)) {
        PyErr_Format(PyExc_TypeError,
            "C variable %%s.%%s has wrong signature (expected %%s, got %%s)",
             PyModule_GetName(module), name, sig, PyCapsule_GetName(cobj));
        goto bad;
    }
    *p = PyCapsule_GetPointer(cobj, sig);
#else
    {const char *desc, *s1, *s2;
    desc = (const char *)PyCObject_GetDesc(cobj);
    if (!desc)
        goto bad;
    s1 = desc; s2 = sig;
    while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
    if (*s1 != *s2) {
        PyErr_Format(PyExc_TypeError,
            "C variable %%s.%%s has wrong signature (expected %%s, got %%s)",
             PyModule_GetName(module), name, sig, desc);
        goto bad;
    }
    *p = PyCObject_AsVoidPtr(cobj);}
#endif
    if (!(*p))
        goto bad;
    Py_DECREF(d);
    return 0;
bad:
    Py_XDECREF(d);
    return -1;
}
#endif
""" % dict(API = Naming.api_name)
)

2720 2721
function_import_utility_code = UtilityCode(
proto = """
2722
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
2723 2724
""",
impl = """
Stefan Behnel's avatar
Stefan Behnel committed
2725 2726
#ifndef __PYX_HAVE_RT_ImportFunction
#define __PYX_HAVE_RT_ImportFunction
2727
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
2728
    PyObject *d = 0;
2729
    PyObject *cobj = 0;
2730 2731 2732 2733
    union {
        void (*fp)(void);
        void *p;
    } tmp;
2734

2735
    d = PyObject_GetAttrString(module, (char *)"%(API)s");
2736 2737 2738
    if (!d)
        goto bad;
    cobj = PyDict_GetItemString(d, funcname);
2739 2740
    if (!cobj) {
        PyErr_Format(PyExc_ImportError,
2741
            "%%s does not export expected C function %%s",
2742 2743 2744
                PyModule_GetName(module), funcname);
        goto bad;
    }
2745 2746 2747 2748 2749 2750 2751 2752 2753 2754
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
    if (!PyCapsule_IsValid(cobj, sig)) {
        PyErr_Format(PyExc_TypeError,
            "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
             PyModule_GetName(module), funcname, sig, PyCapsule_GetName(cobj));
        goto bad;
    }
    tmp.p = PyCapsule_GetPointer(cobj, sig);
#else
    {const char *desc, *s1, *s2;
2755
    desc = (const char *)PyCObject_GetDesc(cobj);
2756 2757
    if (!desc)
        goto bad;
2758 2759 2760
    s1 = desc; s2 = sig;
    while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
    if (*s1 != *s2) {
2761
        PyErr_Format(PyExc_TypeError,
2762
            "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2763
             PyModule_GetName(module), funcname, sig, desc);
2764 2765
        goto bad;
    }
2766
    tmp.p = PyCObject_AsVoidPtr(cobj);}
2767
#endif
2768
    *f = tmp.fp;
2769 2770
    if (!(*f))
        goto bad;
2771
    Py_DECREF(d);
2772 2773
    return 0;
bad:
2774
    Py_XDECREF(d);
2775 2776
    return -1;
}
Stefan Behnel's avatar
Stefan Behnel committed
2777
#endif
2778 2779
""" % dict(API = Naming.api_name)
)
2780

2781 2782
#------------------------------------------------------------------------------------

2783 2784
register_cleanup_utility_code = UtilityCode(
proto = """
2785
static int __Pyx_RegisterCleanup(void); /*proto*/
2786 2787 2788
static PyObject* %(module_cleanup)s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyMethodDef cleanup_def = {__Pyx_NAMESTR("__cleanup"), (PyCFunction)&%(module_cleanup)s, METH_NOARGS, 0};
""" % {'module_cleanup': Naming.cleanup_cname},
2789
impl = """
2790
static int __Pyx_RegisterCleanup(void) {
2791 2792
    /* Don't use Py_AtExit because that has a 32-call limit
     * and is called after python finalization.
2793 2794 2795 2796 2797 2798 2799 2800
     */

    PyObject *cleanup_func = 0;
    PyObject *atexit = 0;
    PyObject *reg = 0;
    PyObject *args = 0;
    PyObject *res = 0;
    int ret = -1;
2801

2802 2803 2804 2805 2806 2807 2808 2809 2810 2811
    cleanup_func = PyCFunction_New(&cleanup_def, 0);
    args = PyTuple_New(1);
    if (!cleanup_func || !args)
        goto bad;
    PyTuple_SET_ITEM(args, 0, cleanup_func);
    cleanup_func = 0;

    atexit = __Pyx_ImportModule("atexit");
    if (!atexit)
        goto bad;
2812
    reg = __Pyx_GetAttrString(atexit, "register");
2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826
    if (!reg)
        goto bad;
    res = PyObject_CallObject(reg, args);
    if (!res)
        goto bad;
    ret = 0;
bad:
    Py_XDECREF(cleanup_func);
    Py_XDECREF(atexit);
    Py_XDECREF(reg);
    Py_XDECREF(args);
    Py_XDECREF(res);
    return ret;
}
2827
""")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2828 2829 2830 2831 2832 2833 2834 2835

import_star_utility_code = """

/* import_all_from is an unexposed function from ceval.c */

static int
__Pyx_import_all_from(PyObject *locals, PyObject *v)
{
Robert Bradshaw's avatar
Robert Bradshaw committed
2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852
    PyObject *all = __Pyx_GetAttrString(v, "__all__");
    PyObject *dict, *name, *value;
    int skip_leading_underscores = 0;
    int pos, err;

    if (all == NULL) {
        if (!PyErr_ExceptionMatches(PyExc_AttributeError))
            return -1; /* Unexpected error */
        PyErr_Clear();
        dict = __Pyx_GetAttrString(v, "__dict__");
        if (dict == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_AttributeError))
                return -1;
            PyErr_SetString(PyExc_ImportError,
            "from-import-* object has no __dict__ and no __all__");
            return -1;
        }
2853 2854 2855
#if PY_MAJOR_VERSION < 3
        all = PyObject_CallMethod(dict, (char *)"keys", NULL);
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2856
        all = PyMapping_Keys(dict);
2857
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873
        Py_DECREF(dict);
        if (all == NULL)
            return -1;
        skip_leading_underscores = 1;
    }

    for (pos = 0, err = 0; ; pos++) {
        name = PySequence_GetItem(all, pos);
        if (name == NULL) {
            if (!PyErr_ExceptionMatches(PyExc_IndexError))
                err = -1;
            else
                PyErr_Clear();
            break;
        }
        if (skip_leading_underscores &&
2874
#if PY_MAJOR_VERSION < 3
Robert Bradshaw's avatar
Robert Bradshaw committed
2875 2876
            PyString_Check(name) &&
            PyString_AS_STRING(name)[0] == '_')
2877
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2878 2879
            PyUnicode_Check(name) &&
            PyUnicode_AS_UNICODE(name)[0] == '_')
2880
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898
        {
            Py_DECREF(name);
            continue;
        }
        value = PyObject_GetAttr(v, name);
        if (value == NULL)
            err = -1;
        else if (PyDict_CheckExact(locals))
            err = PyDict_SetItem(locals, name, value);
        else
            err = PyObject_SetItem(locals, name, value);
        Py_DECREF(name);
        Py_XDECREF(value);
        if (err != 0)
            break;
    }
    Py_DECREF(all);
    return err;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2899 2900 2901
}


2902
static int %(IMPORT_STAR)s(PyObject* m) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2903 2904 2905

    int i;
    int ret = -1;
2906
    char* s;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2907 2908
    PyObject *locals = 0;
    PyObject *list = 0;
2909 2910 2911
#if PY_MAJOR_VERSION >= 3
    PyObject *utf8_name = 0;
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2912 2913
    PyObject *name;
    PyObject *item;
2914

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2915 2916 2917
    locals = PyDict_New();              if (!locals) goto bad;
    if (__Pyx_import_all_from(locals, m) < 0) goto bad;
    list = PyDict_Items(locals);        if (!list) goto bad;
2918

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2919 2920 2921
    for(i=0; i<PyList_GET_SIZE(list); i++) {
        name = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 0);
        item = PyTuple_GET_ITEM(PyList_GET_ITEM(list, i), 1);
2922 2923 2924 2925 2926 2927
#if PY_MAJOR_VERSION >= 3
        utf8_name = PyUnicode_AsUTF8String(name);
        if (!utf8_name) goto bad;
        s = PyBytes_AS_STRING(utf8_name);
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
        Py_DECREF(utf8_name); utf8_name = 0;
2928
#else
2929
        s = PyString_AsString(name);
2930 2931
        if (!s) goto bad;
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2932
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2933 2934
    }
    ret = 0;
2935

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2936 2937 2938
bad:
    Py_XDECREF(locals);
    Py_XDECREF(list);
2939 2940 2941
#if PY_MAJOR_VERSION >= 3
    Py_XDECREF(utf8_name);
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2942 2943
    return ret;
}
2944 2945
""" % {'IMPORT_STAR'     : Naming.import_star,
       'IMPORT_STAR_SET' : Naming.import_star_set }
2946

2947 2948
refnanny_utility_code = UtilityCode(
proto="""
2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962
#ifndef CYTHON_REFNANNY
  #define CYTHON_REFNANNY 0
#endif

#if CYTHON_REFNANNY
  typedef struct {
    void (*INCREF)(void*, PyObject*, int);
    void (*DECREF)(void*, PyObject*, int);
    void (*GOTREF)(void*, PyObject*, int);
    void (*GIVEREF)(void*, PyObject*, int);
    void* (*SetupContext)(const char*, int, const char*);
    void (*FinishContext)(void**);
  } __Pyx_RefNannyAPIStruct;
  static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL;
2963
  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
2964
  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
2965
  #define __Pyx_RefNannySetupContext(name) \
2966
          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
2967 2968
  #define __Pyx_RefNannyFinishContext() \
          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
2969 2970 2971
  #define __Pyx_INCREF(r)  __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
  #define __Pyx_DECREF(r)  __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
  #define __Pyx_GOTREF(r)  __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2972
  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2973 2974 2975 2976
  #define __Pyx_XINCREF(r)  do { if((r) != NULL) {__Pyx_INCREF(r); }} while(0)
  #define __Pyx_XDECREF(r)  do { if((r) != NULL) {__Pyx_DECREF(r); }} while(0)
  #define __Pyx_XGOTREF(r)  do { if((r) != NULL) {__Pyx_GOTREF(r); }} while(0)
  #define __Pyx_XGIVEREF(r) do { if((r) != NULL) {__Pyx_GIVEREF(r);}} while(0)
2977
#else
2978
  #define __Pyx_RefNannyDeclarations
2979 2980 2981 2982 2983 2984
  #define __Pyx_RefNannySetupContext(name)
  #define __Pyx_RefNannyFinishContext()
  #define __Pyx_INCREF(r) Py_INCREF(r)
  #define __Pyx_DECREF(r) Py_DECREF(r)
  #define __Pyx_GOTREF(r)
  #define __Pyx_GIVEREF(r)
2985
  #define __Pyx_XINCREF(r) Py_XINCREF(r)
2986
  #define __Pyx_XDECREF(r) Py_XDECREF(r)
2987 2988
  #define __Pyx_XGOTREF(r)
  #define __Pyx_XGIVEREF(r)
2989
#endif /* CYTHON_REFNANNY */
2990 2991 2992

#define __Pyx_CLEAR(r)    do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0)
#define __Pyx_XCLEAR(r)   do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0)
2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011
""",
impl="""
#if CYTHON_REFNANNY
static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) {
    PyObject *m = NULL, *p = NULL;
    void *r = NULL;
    m = PyImport_ImportModule((char *)modname);
    if (!m) goto end;
    p = PyObject_GetAttrString(m, (char *)\"RefNannyAPI\");
    if (!p) goto end;
    r = PyLong_AsVoidPtr(p);
end:
    Py_XDECREF(p);
    Py_XDECREF(m);
    return (__Pyx_RefNannyAPIStruct *)r;
}
#endif /* CYTHON_REFNANNY */
""",
)
Robert Bradshaw's avatar
Robert Bradshaw committed
3012

3013 3014
main_method = UtilityCode(
impl = """
3015 3016 3017 3018 3019
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif

#if PY_MAJOR_VERSION < 3
3020
int %(main_method)s(int argc, char** argv) {
3021
#elif defined(WIN32) || defined(MS_WINDOWS)
3022
int %(wmain_method)s(int argc, wchar_t **argv) {
3023 3024
#else
static int __Pyx_main(int argc, wchar_t **argv) {
3025
#endif
3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036
    /* 754 requires that FP exceptions run in "no stop" mode by default,
     * and until C vendors implement C99's ways to control FP exceptions,
     * Python requires non-stop mode.  Alas, some platforms enable FP
     * exceptions by default.  Here we disable them.
     */
#ifdef __FreeBSD__
    fp_except_t m;

    m = fpgetmask();
    fpsetmask(m & ~FP_X_OFL);
#endif
3037
    if (argc && argv)
3038
        Py_SetProgramName(argv[0]);
3039
    Py_Initialize();
3040
    if (argc && argv)
3041
        PySys_SetArgv(argc, argv);
3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057
    { /* init module '%(module_name)s' as '__main__' */
      PyObject* m = NULL;
      %(module_is_main)s = 1;
      #if PY_MAJOR_VERSION < 3
          init%(module_name)s();
      #else
          m = PyInit_%(module_name)s();
      #endif
      if (PyErr_Occurred()) {
          PyErr_Print(); /* This exits with the right code if SystemExit. */
          #if PY_MAJOR_VERSION < 3
          if (Py_FlushLine()) PyErr_Clear();
          #endif
          return 1;
      }
      Py_XDECREF(m);
3058
    }
3059
    Py_Finalize();
3060
    return 0;
3061
}
3062 3063 3064 3065 3066 3067 3068 3069


#if PY_MAJOR_VERSION >= 3 && !defined(WIN32) && !defined(MS_WINDOWS)
#include <locale.h>

static wchar_t*
__Pyx_char2wchar(char* arg)
{
Vitja Makarov's avatar
Vitja Makarov committed
3070
    wchar_t *res;
3071
#ifdef HAVE_BROKEN_MBSTOWCS
Vitja Makarov's avatar
Vitja Makarov committed
3072 3073 3074 3075 3076
    /* Some platforms have a broken implementation of
     * mbstowcs which does not count the characters that
     * would result from conversion.  Use an upper bound.
     */
    size_t argsize = strlen(arg);
3077
#else
Vitja Makarov's avatar
Vitja Makarov committed
3078
    size_t argsize = mbstowcs(NULL, arg, 0);
3079
#endif
Vitja Makarov's avatar
Vitja Makarov committed
3080 3081 3082
    size_t count;
    unsigned char *in;
    wchar_t *out;
3083
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
3084
    mbstate_t mbs;
3085
#endif
Vitja Makarov's avatar
Vitja Makarov committed
3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103
    if (argsize != (size_t)-1) {
        res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
        if (!res)
            goto oom;
        count = mbstowcs(res, arg, argsize+1);
        if (count != (size_t)-1) {
            wchar_t *tmp;
            /* Only use the result if it contains no
               surrogate characters. */
            for (tmp = res; *tmp != 0 &&
                     (*tmp < 0xd800 || *tmp > 0xdfff); tmp++)
                ;
            if (*tmp == 0)
                return res;
        }
        free(res);
    }
    /* Conversion failed. Fall back to escaping with surrogateescape. */
3104
#ifdef HAVE_MBRTOWC
Vitja Makarov's avatar
Vitja Makarov committed
3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148
    /* Try conversion with mbrtwoc (C99), and escape non-decodable bytes. */

    /* Overallocate; as multi-byte characters are in the argument, the
       actual output could use less memory. */
    argsize = strlen(arg) + 1;
    res = malloc(argsize*sizeof(wchar_t));
    if (!res) goto oom;
    in = (unsigned char*)arg;
    out = res;
    memset(&mbs, 0, sizeof mbs);
    while (argsize) {
        size_t converted = mbrtowc(out, (char*)in, argsize, &mbs);
        if (converted == 0)
            /* Reached end of string; null char stored. */
            break;
        if (converted == (size_t)-2) {
            /* Incomplete character. This should never happen,
               since we provide everything that we have -
               unless there is a bug in the C library, or I
               misunderstood how mbrtowc works. */
            fprintf(stderr, "unexpected mbrtowc result -2\\n");
            return NULL;
        }
        if (converted == (size_t)-1) {
            /* Conversion error. Escape as UTF-8b, and start over
               in the initial shift state. */
            *out++ = 0xdc00 + *in++;
            argsize--;
            memset(&mbs, 0, sizeof mbs);
            continue;
        }
        if (*out >= 0xd800 && *out <= 0xdfff) {
            /* Surrogate character.  Escape the original
               byte sequence with surrogateescape. */
            argsize -= converted;
            while (converted--)
                *out++ = 0xdc00 + *in++;
            continue;
        }
        /* successfully converted some bytes */
        in += converted;
        argsize -= converted;
        out++;
    }
3149
#else
Vitja Makarov's avatar
Vitja Makarov committed
3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162
    /* Cannot use C locale for escaping; manually escape as if charset
       is ASCII (i.e. escape all bytes > 128. This will still roundtrip
       correctly in the locale's charset, which must be an ASCII superset. */
    res = malloc((strlen(arg)+1)*sizeof(wchar_t));
    if (!res) goto oom;
    in = (unsigned char*)arg;
    out = res;
    while(*in)
        if(*in < 128)
            *out++ = *in++;
        else
            *out++ = 0xdc00 + *in++;
    *out = 0;
3163
#endif
Vitja Makarov's avatar
Vitja Makarov committed
3164
    return res;
3165
oom:
Vitja Makarov's avatar
Vitja Makarov committed
3166 3167
    fprintf(stderr, "out of memory\\n");
    return NULL;
3168 3169 3170
}

int
3171
%(main_method)s(int argc, char **argv)
3172
{
3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202
    if (!argc) {
        return __Pyx_main(0, NULL);
    }
    else {
        wchar_t **argv_copy = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
        /* We need a second copies, as Python might modify the first one. */
        wchar_t **argv_copy2 = (wchar_t **)malloc(sizeof(wchar_t*)*argc);
        int i, res;
        char *oldloc;
        if (!argv_copy || !argv_copy2) {
            fprintf(stderr, "out of memory\\n");
            return 1;
        }
        oldloc = strdup(setlocale(LC_ALL, NULL));
        setlocale(LC_ALL, "");
        for (i = 0; i < argc; i++) {
            argv_copy2[i] = argv_copy[i] = __Pyx_char2wchar(argv[i]);
            if (!argv_copy[i])
                return 1;
        }
        setlocale(LC_ALL, oldloc);
        free(oldloc);
        res = __Pyx_main(argc, argv_copy);
        for (i = 0; i < argc; i++) {
            free(argv_copy2[i]);
        }
        free(argv_copy);
        free(argv_copy2);
        return res;
    }
3203 3204
}
#endif
3205
""")
3206 3207 3208 3209 3210 3211 3212

packed_struct_utility_code = UtilityCode(proto="""
#if defined(__GNUC__)
#define __Pyx_PACKED __attribute__((__packed__))
#else
#define __Pyx_PACKED
#endif
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
3213
""", impl="", proto_block='utility_code_proto_before_types')
3214 3215 3216 3217 3218

check_binary_version_utility_code = UtilityCode(proto="""
static int __Pyx_check_binary_version(void);
""", impl="""
static int __Pyx_check_binary_version(void) {
3219 3220 3221 3222
    char ctversion[4], rtversion[4];
    PyOS_snprintf(ctversion, 4, "%d.%d", PY_MAJOR_VERSION, PY_MINOR_VERSION);
    PyOS_snprintf(rtversion, 4, "%s", Py_GetVersion());
    if (ctversion[0] != rtversion[0] || ctversion[2] != rtversion[2]) {
3223 3224
        char message[200];
        PyOS_snprintf(message, sizeof(message),
3225 3226 3227
                      "compiletime version %s of module '%.100s' "
                      "does not match runtime version %s",
                      ctversion, __Pyx_MODULE_NAME, rtversion);
3228
        #if PY_VERSION_HEX < 0x02050000
3229
        return PyErr_Warn(NULL, message);
3230
        #else
3231
        return PyErr_WarnEx(NULL, message, 1);
3232 3233
        #endif
    }
3234
    return 0;
3235 3236
}
""")