ModuleNode.py 114 KB
Newer Older
1 2 3 4
#
#   Pyrex - Module parse tree node
#

5 6 7 8
import cython
from cython import set
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
9
               EncodedString=object)
10

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

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

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

Gary Furnish's avatar
Gary Furnish committed
31

32 33 34 35
def check_c_declarations_pxd(module_node):
    module_node.scope.check_c_classes_pxd()
    return module_node

36
def check_c_declarations(module_node):
37
    module_node.scope.check_c_classes()
38
    module_node.scope.check_c_functions()
39 40
    return module_node

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

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

55
    def analyse_declarations(self, env):
56
        if Options.embed_pos_in_docstring:
Robert Bradshaw's avatar
Robert Bradshaw committed
57
            env.doc = EncodedString(u'File: %s (starting at line %s)' % Nodes.relative_position(self.pos))
58
            if not self.doc is None:
59
                env.doc = EncodedString(env.doc + u'\n' + self.doc)
Robert Bradshaw's avatar
Robert Bradshaw committed
60
                env.doc.encoding = self.doc.encoding
61 62
        else:
            env.doc = self.doc
63
        env.directives = self.directives
64
        self.body.analyse_declarations(env)
65

66 67
    def process_implementation(self, options, result):
        env = self.scope
68
        env.return_type = PyrexTypes.c_void_type
69 70
        self.referenced_modules = []
        self.find_referenced_modules(env, self.referenced_modules, {})
71 72
        if options.recursive:
            self.generate_dep_file(env, result)
73
        self.generate_c_code(env, options, result)
74 75
        self.generate_h_code(env, options, result)
        self.generate_api_code(env, result)
Robert Bradshaw's avatar
Robert Bradshaw committed
76

77 78 79 80 81 82
    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
83

84 85 86 87 88 89 90 91 92 93 94 95 96 97
    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()

98
    def generate_h_code(self, env, options, result):
99
        def h_entries(entries, api=0, pxd=0):
Stefan Behnel's avatar
Stefan Behnel committed
100
            return [entry for entry in entries
101 102 103 104
                    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
105 106 107
        h_vars = h_entries(env.var_entries)
        h_funcs = h_entries(env.cfunc_entries)
        h_extension_types = h_entries(env.c_class_entries)
108
        if (h_types or  h_vars or h_funcs or h_extension_types):
109
            result.h_file = replace_suffix(result.c_file, ".h")
110
            h_code = Code.CCodeWriter()
111
            Code.GlobalState(h_code)
112 113 114 115 116
            if options.generate_pxi:
                result.i_file = replace_suffix(result.c_file, ".pxi")
                i_code = Code.PyrexCodeWriter(result.i_file)
            else:
                i_code = None
117 118 119

            h_guard = Naming.h_guard_prefix + self.api_name(env)
            h_code.put_h_guard(h_guard)
120
            h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
121
            self.generate_type_header_code(h_types, h_code)
122
            h_code.putln("")
123 124
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.putln("#ifndef %s" % api_guard)
125 126
            h_code.putln("")
            self.generate_extern_c_macro_definition(h_code)
Stefan Behnel's avatar
Stefan Behnel committed
127
            if h_extension_types:
128
                h_code.putln("")
Stefan Behnel's avatar
Stefan Behnel committed
129
                for entry in h_extension_types:
130 131 132
                    self.generate_cclass_header_code(entry.type, h_code)
                    if i_code:
                        self.generate_cclass_include_code(entry.type, i_code)
133 134 135 136 137 138 139 140
            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)
141
            h_code.putln("")
142
            h_code.putln("#endif /* !%s */" % api_guard)
143
            h_code.putln("")
144
            h_code.putln("#if PY_MAJOR_VERSION < 3")
145
            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
146 147
            h_code.putln("#else")
            h_code.putln("PyMODINIT_FUNC PyInit_%s(void);" % env.module_name)
148
            h_code.putln("#endif")
149 150
            h_code.putln("")
            h_code.putln("#endif /* !%s */" % h_guard)
151

152 153 154 155 156
            f = open_new_file(result.h_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
157

158 159 160 161 162 163
    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:
164
            i_code.putln("cdef extern %s" %
165
                entry.type.declaration_code(entry.cname, pyrex = 1))
166

167 168
    def api_name(self, env):
        return env.qualified_name.replace(".", "__")
Robert Bradshaw's avatar
Robert Bradshaw committed
169

170
    def generate_api_code(self, env, result):
171
        def api_entries(entries, pxd=0):
172 173 174 175 176 177
            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:
178
            result.api_file = replace_suffix(result.c_file, "_api.h")
179
            h_code = Code.CCodeWriter()
180
            Code.GlobalState(h_code)
181 182
            api_guard = Naming.api_guard_prefix + self.api_name(env)
            h_code.put_h_guard(api_guard)
183 184 185
            h_code.putln('#include "Python.h"')
            if result.h_file:
                h_code.putln('#include "%s"' % os.path.basename(result.h_file))
186
            if api_extension_types:
187
                h_code.putln("")
188 189 190 191 192
                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))
193 194 195 196
            if api_funcs:
                h_code.putln("")
                for entry in api_funcs:
                    type = CPtrType(entry.type)
197 198 199 200 201 202 203 204 205 206
                    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)
                    cname = env.mangle(Naming.var_prefix, entry.name)
                    h_code.putln("static %s = 0;" %  type.declaration_code(cname))
                    h_code.putln("#define %s (*%s)" % (entry.name, cname))
207
            h_code.put(import_module_utility_code.impl)
208 209
            if api_vars:
                h_code.put(voidptr_import_utility_code.impl)
210
            if api_funcs:
211
                h_code.put(function_import_utility_code.impl)
212
            if api_extension_types:
213
                h_code.put(type_import_utility_code.impl)
214
            h_code.putln("")
215
            h_code.putln("static int import_%s(void) {" % self.api_name(env))
216
            h_code.putln("PyObject *module = 0;")
217
            h_code.putln('module = __Pyx_ImportModule("%s");' % env.qualified_name)
218 219
            h_code.putln("if (!module) goto bad;")
            for entry in api_funcs:
220
                cname = env.mangle(Naming.func_prefix, entry.name)
221 222
                sig = entry.type.signature_string()
                h_code.putln(
223 224 225 226 227 228 229 230
                    'if (__Pyx_ImportFunction(module, "%s", (void (**)(void))&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
            for entry in api_vars:
                cname = env.mangle(Naming.var_prefix, entry.name)
                sig = entry.type.declaration_code("")
                h_code.putln(
                    'if (__Pyx_ImportVoidPtr(module, "%s", (void **)&%s, "%s") < 0) goto bad;'
                    % (entry.name, cname, sig))
231
            h_code.putln("Py_DECREF(module); module = 0;")
232
            for entry in api_extension_types:
233 234 235
                self.generate_type_import_call(
                    entry.type, h_code,
                    "if (!%s) goto bad;" % entry.type.typeptr_cname)
236 237 238 239 240 241
            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("")
242
            h_code.putln("#endif /* !%s */" % api_guard)
243

244 245 246 247 248
            f = open_new_file(result.api_file)
            try:
                h_code.copyto(f)
            finally:
                f.close()
249

250
    def generate_cclass_header_code(self, type, h_code):
251
        h_code.putln("%s %s %s;" % (
Robert Bradshaw's avatar
Robert Bradshaw committed
252
            Naming.extern_c_macro,
253
            PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
254
            type.typeobj_cname))
255

256 257 258 259 260 261 262
    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:
263
                i_code.putln("cdef %s" %
264 265 266 267
                    entry.type.declaration_code(entry.cname, pyrex = 1))
        else:
            i_code.putln("pass")
        i_code.dedent()
268

269
    def generate_c_code(self, env, options, result):
270
        modules = self.referenced_modules
271

272
        if Options.annotate or options.annotate:
273 274
            emit_linenums = False
            rootwriter = Annotate.AnnotationCCodeWriter()
275
        else:
276
            emit_linenums = options.emit_linenums
277
            rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback)
278
        globalstate = Code.GlobalState(rootwriter, emit_linenums)
279
        globalstate.initialize_main_c_code()
280
        h_code = globalstate['h_code']
281

282
        self.generate_module_preamble(env, modules, h_code)
283

284 285
        globalstate.module_pos = self.pos
        globalstate.directives = self.directives
286

287
        globalstate.use_utility_code(refnanny_utility_code)
288

289
        code = globalstate['before_global_var']
290
        code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
291
        code.putln("int %s%s = 0;" % (Naming.module_is_main, self.full_module_name.replace('.', '__')))
292 293
        code.putln("")
        code.putln("/* Implementation of %s */" % env.qualified_name)
294

295
        code = globalstate['all_the_rest']
296

297
        self.generate_cached_builtins_decls(env, code)
298
        self.generate_lambda_definitions(env, code)
Stefan Behnel's avatar
Stefan Behnel committed
299
        # generate normal function definitions
300
        self.body.generate_function_definitions(env, code)
Robert Bradshaw's avatar
Robert Bradshaw committed
301
        code.mark_pos(None)
302 303
        self.generate_typeobj_definitions(env, code)
        self.generate_method_table(env, code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
304 305
        if env.has_import_star:
            self.generate_import_star(env, code)
306
        self.generate_pymoduledef_struct(env, code)
307

308 309 310
        # 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'])
311
        if Options.embed:
312 313
            self.generate_main_method(env, globalstate['main_method'])
        self.generate_filename_table(globalstate['filename_table'])
314

315
        self.generate_declarations_for_modules(env, modules, globalstate)
316
        h_code.write('\n')
Gary Furnish's avatar
Gary Furnish committed
317

318 319
        for utilcode in env.utility_code_list:
            globalstate.use_utility_code(utilcode)
320
        globalstate.finalize_main_c_code()
321

322
        f = open_new_file(result.c_file)
323
        rootwriter.copyto(f)
324
        if options.gdb_debug:
Mark Florisson's avatar
Mark Florisson committed
325
            self._serialize_lineno_map(env, rootwriter)
326 327
        f.close()
        result.c_file_generated = 1
328
        if Options.annotate or options.annotate:
329 330
            self.annotate(rootwriter)
            rootwriter.save_annotation(result.main_source_file, result.c_file)
331

Mark Florisson's avatar
Mark Florisson committed
332
    def _serialize_lineno_map(self, env, ccodewriter):
333
        tb = env.context.gdb_debug_outputwriter
Mark Florisson's avatar
Mark Florisson committed
334
        markers = ccodewriter.buffer.allmarkers()
335

Mark Florisson's avatar
Mark Florisson committed
336
        d = {}
337
        for c_lineno, cython_lineno in enumerate(markers):
Mark Florisson's avatar
Mark Florisson committed
338 339
            if cython_lineno > 0:
                d.setdefault(cython_lineno, []).append(c_lineno + 1)
340

Mark Florisson's avatar
Mark Florisson committed
341 342 343 344 345 346 347 348 349 350
        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()
351

352 353 354 355 356 357
    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
358

359 360 361 362 363 364 365 366 367
    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
368
            hierarchy = set()
369
            base = new_entry
370 371 372 373 374 375 376
            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)
377
            new_entry.base_keys = hierarchy
378

379
            # find the first (sub-)subclass and insert before that
380 381
            for j in range(i):
                entry = type_list[j]
382
                if key in entry.base_keys:
383 384 385 386 387 388 389
                    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
390
        vtab_dict = {}
391
        vtabslot_dict = {}
Gary Furnish's avatar
Gary Furnish committed
392 393 394 395 396
        for module in module_list:
            for entry in module.c_class_entries:
                if not entry.in_cinclude:
                    type = entry.type
                    if type.vtabstruct_cname:
397 398 399 400
                        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
401
                    type = entry.type
402 403 404
                    if type.is_extension_type and not entry.in_cinclude:
                        type = entry.type
                        vtabslot_dict[type.objstruct_cname] = entry
405

406 407
        def vtabstruct_cname(entry_type):
            return entry_type.vtabstruct_cname
408 409
        vtab_list = self.sort_types_by_inheritance(
            vtab_dict, vtabstruct_cname)
410 411 412

        def objstruct_cname(entry_type):
            return entry_type.objstruct_cname
413 414
        vtabslot_list = self.sort_types_by_inheritance(
            vtabslot_dict, objstruct_cname)
415

416
        return (vtab_list, vtabslot_list)
417

Gary Furnish's avatar
Gary Furnish committed
418
    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
419
        vtabslot_entries = set(vtabslot_list)
Gary Furnish's avatar
Gary Furnish committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
        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)
            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)
                    elif type.is_struct_or_union:
                        self.generate_struct_union_definition(entry, code)
                    elif type.is_enum:
                        self.generate_enum_definition(entry, code)
439
                    elif type.is_extension_type and entry not in vtabslot_entries:
440
                        self.generate_objstruct_definition(type, code)
Gary Furnish's avatar
Gary Furnish committed
441
        for entry in vtabslot_list:
442
            self.generate_objstruct_definition(entry.type, code)
443
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
444
        for entry in vtab_list:
445
            self.generate_typeobj_predeclaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
446 447
            self.generate_exttype_vtable_struct(entry, code)
            self.generate_exttype_vtabptr_declaration(entry, code)
Gary Furnish's avatar
Gary Furnish committed
448

449 450 451 452
    def generate_declarations_for_modules(self, env, modules, globalstate):
        typecode = globalstate['type_declarations']
        typecode.putln("")
        typecode.putln("/* Type declarations */")
453 454
        vtab_list, vtabslot_list = self.sort_type_hierarchy(modules, env)
        self.generate_type_definitions(
455 456
            env, modules, vtab_list, vtabslot_list, typecode)
        modulecode = globalstate['module_declarations']
Gary Furnish's avatar
Gary Furnish committed
457
        for module in modules:
458
            defined_here = module is env
459
            modulecode.putln("/* Module declarations from %s */" %
Stefan Behnel's avatar
Stefan Behnel committed
460
                             module.qualified_name)
461 462
            self.generate_global_declarations(module, modulecode, defined_here)
            self.generate_cfunction_predeclarations(module, modulecode, defined_here)
Gary Furnish's avatar
Gary Furnish committed
463

464
    def generate_module_preamble(self, env, cimported_modules, code):
465
        code.putln("/* Generated by Cython %s on %s */" % (
466
            Version.version, time.asctime()))
467 468
        code.putln("")
        code.putln("#define PY_SSIZE_T_CLEAN")
469 470
        for filename in env.python_include_files:
            code.putln('#include "%s"' % filename)
471 472
        code.putln("#ifndef Py_PYTHON_H")
        code.putln("    #error Python headers needed to compile C extensions, please install development version of Python.")
473 474
        code.putln("#else")
        code.globalstate["end"].putln("#endif /* Py_PYTHON_H */")
475

476
        code.put("""
477 478 479 480 481
#include <stddef.h> /* For offsetof */
#ifndef offsetof
#define offsetof(type, member) ( (size_t) & ((type*)0) -> member )
#endif

482 483 484 485 486 487 488 489 490 491 492 493 494 495
#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
496 497 498 499
#endif
#ifndef DL_EXPORT
  #define DL_EXPORT(t) t
#endif
500 501 502 503 504

#ifndef PY_LONG_LONG
  #define PY_LONG_LONG LONG_LONG
#endif

505 506 507 508 509
#if PY_VERSION_HEX < 0x02040000
  #define METH_COEXIST 0
  #define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
  #define PyDict_Contains(d,o)   PySequence_Contains(d,o)
#endif
510

511 512 513 514 515 516 517 518 519 520 521
#if PY_VERSION_HEX < 0x02050000
  typedef int Py_ssize_t;
  #define PY_SSIZE_T_MAX INT_MAX
  #define PY_SSIZE_T_MIN INT_MIN
  #define PY_FORMAT_SIZE_T \"\"
  #define PyInt_FromSsize_t(z) PyInt_FromLong(z)
  #define PyInt_AsSsize_t(o)   PyInt_AsLong(o)
  #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
522

523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
#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)
554

555
#endif
556

557 558 559 560 561
#if PY_MAJOR_VERSION < 3
  #define __Pyx_BUILTIN_MODULE_NAME "__builtin__"
#else
  #define __Pyx_BUILTIN_MODULE_NAME "builtins"
#endif
562

563 564 565 566
#if PY_MAJOR_VERSION >= 3
  #define Py_TPFLAGS_CHECKTYPES 0
  #define Py_TPFLAGS_HAVE_INDEX 0
#endif
567

568 569 570
#if (PY_VERSION_HEX < 0x02060000) || (PY_MAJOR_VERSION >= 3)
  #define Py_TPFLAGS_HAVE_NEWBUFFER 0
#endif
571

572 573
#if PY_MAJOR_VERSION >= 3
  #define PyBaseString_Type            PyUnicode_Type
574
  #define PyStringObject               PyUnicodeObject
575
  #define PyString_Type                PyUnicode_Type
576
  #define PyString_Check               PyUnicode_Check
577
  #define PyString_CheckExact          PyUnicode_CheckExact
578 579 580 581
#endif

#if PY_VERSION_HEX < 0x02060000
  #define PyBytesObject                PyStringObject
582
  #define PyBytes_Type                 PyString_Type
583
  #define PyBytes_Check                PyString_Check
584
  #define PyBytes_CheckExact           PyString_CheckExact
585 586 587 588 589 590 591 592 593 594 595 596
  #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
597 598 599
#endif

#if PY_VERSION_HEX < 0x02060000
600 601 602 603
  #define PySet_Check(obj)             PyObject_TypeCheck(obj, &PySet_Type)
  #define PyFrozenSet_Check(obj)       PyObject_TypeCheck(obj, &PyFrozenSet_Type)
#endif
#ifndef PySet_CheckExact
604
  #define PySet_CheckExact(obj)        (Py_TYPE(obj) == &PySet_Type)
605 606
#endif

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

609
#if PY_MAJOR_VERSION >= 3
610
  #define PyIntObject                  PyLongObject
611 612 613 614 615 616 617 618 619 620 621 622 623
  #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
624
#endif
625 626

#if PY_MAJOR_VERSION >= 3
627
  #define PyBoolObject                 PyLongObject
628 629
#endif

630 631 632 633 634 635 636 637 638
#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

639 640 641 642
""")

        code.put("""
#if PY_MAJOR_VERSION >= 3
643 644 645 646
  #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
647 648
        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
649
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceTrueDivide(x,y)")
Robert Bradshaw's avatar
Robert Bradshaw committed
650 651
        else:
            code.putln("  #define __Pyx_PyNumber_Divide(x,y)         PyNumber_Divide(x,y)")
Stefan Behnel's avatar
Stefan Behnel committed
652
            code.putln("  #define __Pyx_PyNumber_InPlaceDivide(x,y)  PyNumber_InPlaceDivide(x,y)")
653
        code.putln("#endif")
654

655
        code.put("""
656 657 658 659 660
#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
661
  #define __Pyx_PySequence_GetSlice(obj, a, b) (unlikely(!(obj)) ? \\
662
        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), (PyObject*)0) : \\
663
        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_GetSlice(obj, a, b)) : \\
664
            (PyErr_Format(PyExc_TypeError, "'%.200s' object is unsliceable", (obj)->ob_type->tp_name), (PyObject*)0)))
665
  #define __Pyx_PySequence_SetSlice(obj, a, b, value) (unlikely(!(obj)) ? \\
666
        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \\
667
        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_SetSlice(obj, a, b, value)) : \\
668
            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice assignment", (obj)->ob_type->tp_name), -1)))
669
  #define __Pyx_PySequence_DelSlice(obj, a, b) (unlikely(!(obj)) ? \\
670
        (PyErr_SetString(PyExc_SystemError, "null argument to internal routine"), -1) : \\
671
        (likely((obj)->ob_type->tp_as_mapping) ? (PySequence_DelSlice(obj, a, b)) : \\
672 673 674
            (PyErr_Format(PyExc_TypeError, "'%.200s' object doesn't support slice deletion", (obj)->ob_type->tp_name), -1)))
#endif

675
#if PY_MAJOR_VERSION >= 3
676
  #define PyMethod_New(func, self, klass) ((self) ? PyMethod_New(func, self) : PyInstanceMethod_New(func))
677
#endif
678

679 680 681 682 683 684 685 686 687
#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
688

689 690 691 692 693 694 695 696
#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
""")
697

698
        code.putln("")
699
        self.generate_extern_c_macro_definition(code)
700 701 702 703
        code.putln("")
        code.putln("#if defined(WIN32) || defined(MS_WINDOWS)")
        code.putln("#define _USE_MATH_DEFINES")
        code.putln("#endif")
704
        code.putln("#include <math.h>")
705
        code.putln("#define %s" % Naming.h_guard_prefix + self.api_name(env))
706
        code.putln("#define %s" % Naming.api_guard_prefix + self.api_name(env))
707
        self.generate_includes(env, cimported_modules, code)
708 709 710 711 712
        code.putln("")
        code.putln("#ifdef PYREX_WITHOUT_ASSERTIONS")
        code.putln("#define CYTHON_WITHOUT_ASSERTIONS")
        code.putln("#endif")
        code.putln("")
713 714 715 716
        if env.directives['ccomplex']:
            code.putln("")
            code.putln("#if !defined(CYTHON_CCOMPLEX)")
            code.putln("#define CYTHON_CCOMPLEX 1")
717
            code.putln("#endif")
718
            code.putln("")
719
        code.put(Nodes.utility_function_predeclarations)
720
        code.put(PyrexTypes.type_conversion_predeclarations)
Robert Bradshaw's avatar
Robert Bradshaw committed
721
        code.put(Nodes.branch_prediction_macros)
722 723 724
        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
725
        code.putln('static PyObject *%s;' % Naming.empty_tuple)
Robert Bradshaw's avatar
Robert Bradshaw committed
726
        code.putln('static PyObject *%s;' % Naming.empty_bytes)
727 728
        if Options.pre_import is not None:
            code.putln('static PyObject *%s;' % Naming.preimport_cname)
729
        code.putln('static int %s;' % Naming.lineno_cname)
730
        code.putln('static int %s = 0;' % Naming.clineno_cname)
731 732
        code.putln('static const char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
        code.putln('static const char *%s;' % Naming.filename_cname)
733

734 735 736 737 738 739
        # 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)

740 741
    def generate_extern_c_macro_definition(self, code):
        name = Naming.extern_c_macro
742 743 744 745 746 747
        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")
748 749 750
        code.putln("#endif")

    def generate_includes(self, env, cimported_modules, code):
751
        includes = []
Robert Bradshaw's avatar
Robert Bradshaw committed
752
        for filename in env.include_files:
Stefan Behnel's avatar
Stefan Behnel committed
753 754 755
            byte_decoded_filenname = str(filename)
            if byte_decoded_filenname[0] == '<' and byte_decoded_filenname[-1] == '>':
                code.putln('#include %s' % byte_decoded_filenname)
756
            else:
Stefan Behnel's avatar
Stefan Behnel committed
757
                code.putln('#include "%s"' % byte_decoded_filenname)
758

759 760
    def generate_filename_table(self, code):
        code.putln("")
Robert Bradshaw's avatar
Robert Bradshaw committed
761
        code.putln("static const char *%s[] = {" % Naming.filetable_cname)
762 763
        if code.globalstate.filename_list:
            for source_desc in code.globalstate.filename_list:
764
                filename = os.path.basename(source_desc.get_filenametable_entry())
765
                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
Robert Bradshaw's avatar
Robert Bradshaw committed
766
                code.putln('"%s",' % escaped_filename)
767 768 769 770
        else:
            # Some C compilers don't like an empty array
            code.putln("0")
        code.putln("};")
771 772 773 774

    def generate_type_predeclarations(self, env, code):
        pass

775
    def generate_type_header_code(self, type_entries, code):
776 777
        # Generate definitions of structs/unions/enums/typedefs/objstructs.
        #self.generate_gcc33_hack(env, code) # Is this still needed?
778 779
        #for entry in env.type_entries:
        for entry in type_entries:
780
            if not entry.in_cinclude:
781
                #print "generate_type_header_code:", entry.name, repr(entry.type) ###
782
                type = entry.type
783 784 785
                if type.is_typedef: # Must test this first!
                    self.generate_typedef(entry, code)
                elif type.is_struct_or_union:
786
                    self.generate_struct_union_definition(entry, code)
787
                elif type.is_enum:
788
                    self.generate_enum_definition(entry, code)
789
                elif type.is_extension_type:
790
                    self.generate_objstruct_definition(type, code)
791

792 793 794 795 796 797 798 799 800 801 802 803 804
    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))
805

806 807
    def generate_typedef(self, entry, code):
        base_type = entry.type.typedef_base_type
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
808
        if base_type.is_numeric:
809 810 811 812
            try:
                writer = code.globalstate['numeric_typedefs']
            except KeyError:
                writer = code
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
813 814
        else:
            writer = code
815
        writer.mark_pos(entry.pos)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
816
        writer.putln("typedef %s;" % base_type.declaration_code(entry.cname))
817

818 819 820 821 822 823 824 825
    def sue_header_footer(self, type, kind, name):
        if type.typedef_flag:
            header = "typedef %s {" % kind
            footer = "} %s;" % name
        else:
            header = "%s %s {" % (kind, name)
            footer = "};"
        return header, footer
826

827
    def generate_struct_union_definition(self, entry, code):
828
        code.mark_pos(entry.pos)
829 830 831
        type = entry.type
        scope = type.scope
        if scope:
832 833 834 835 836
            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)
837
            header, footer = \
838 839
                self.sue_header_footer(type, kind, type.cname)
            if packed:
840 841 842 843
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack(1)")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(push, 1)")
844
                code.putln("#endif")
845 846 847 848 849 850 851 852 853 854 855
            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)
856
            if packed:
857 858 859 860
                code.putln("#if defined(__SUNPRO_C)")
                code.putln("  #pragma pack()")
                code.putln("#elif !defined(__GNUC__)")
                code.putln("  #pragma pack(pop)")
861
                code.putln("#endif")
862 863

    def generate_enum_definition(self, entry, code):
864
        code.mark_pos(entry.pos)
865 866 867 868 869 870 871 872 873 874 875 876
        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]
877
            # this does not really generate code, just builds the result value
878
            for value_entry in enum_values:
879 880 881 882 883
                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:
884 885 886 887
                    value_code = value_entry.cname
                else:
                    value_code = ("%s = %s" % (
                        value_entry.cname,
888
                        value_entry.value_node.result()))
889 890 891 892
                if value_entry is not last_entry:
                    value_code += ","
                code.putln(value_code)
        code.putln(footer)
893

894
    def generate_typeobj_predeclaration(self, entry, code):
895 896 897 898
        code.putln("")
        name = entry.type.typeobj_cname
        if name:
            if entry.visibility == 'extern' and not entry.in_cinclude:
899
                code.putln("%s %s %s;" % (
900
                    Naming.extern_c_macro,
901
                    PyrexTypes.public_decl("PyTypeObject", "DL_IMPORT"),
902 903
                    name))
            elif entry.visibility == 'public':
904
                code.putln("%s %s %s;" % (
905
                    Naming.extern_c_macro,
906
                    PyrexTypes.public_decl("PyTypeObject", "DL_EXPORT"),
907 908 909
                    name))
            # ??? Do we really need the rest of this? ???
            #else:
910
            #    code.putln("static PyTypeObject %s;" % name)
911

912
    def generate_exttype_vtable_struct(self, entry, code):
913
        code.mark_pos(entry.pos)
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
        # 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(
                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
            code.putln(
                "};")
932

933
    def generate_exttype_vtabptr_declaration(self, entry, code):
934
        code.mark_pos(entry.pos)
935 936 937 938 939 940
        # 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))
941

942
    def generate_objstruct_definition(self, type, code):
943
        code.mark_pos(type.pos)
944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
        # 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:
967 968 969 970
            if attr.is_declared_generic:
                attr_type = py_object_type
            else:
                attr_type = attr.type
971 972
            code.putln(
                "%s;" %
973
                    attr_type.declaration_code(attr.cname))
974
        code.putln(footer)
975 976 977
        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))
978 979 980 981

    def generate_global_declarations(self, env, code, definition):
        code.putln("")
        for entry in env.c_class_entries:
982
            if definition or entry.defined_in_pxd:
983
                code.putln("static PyTypeObject *%s = 0;" %
984
                    entry.type.typeptr_cname)
985
        code.put_var_declarations(env.var_entries, static = 1,
986
            dll_linkage = "DL_EXPORT", definition = definition)
987

988
    def generate_cfunction_predeclarations(self, env, code, definition):
989
        for entry in env.cfunc_entries:
990 991
            if entry.inline_func_in_pxd or (not entry.in_cinclude and (definition
                    or entry.defined_in_pxd or entry.visibility == 'extern')):
992 993
                if entry.visibility == 'public':
                    storage_class = "%s " % Naming.extern_c_macro
994
                    dll_linkage = "DL_EXPORT"
995 996 997 998 999 1000
                elif entry.visibility == 'extern':
                    storage_class = "%s " % Naming.extern_c_macro
                    dll_linkage = "DL_IMPORT"
                elif entry.visibility == 'private':
                    storage_class = "static "
                    dll_linkage = None
1001
                else:
1002
                    storage_class = "static "
1003
                    dll_linkage = None
1004
                type = entry.type
Robert Bradshaw's avatar
Robert Bradshaw committed
1005

1006 1007
                if not definition and entry.defined_in_pxd:
                    type = CPtrType(type)
1008
                header = type.declaration_code(entry.cname,
1009
                                               dll_linkage = dll_linkage)
1010
                if entry.func_modifiers:
1011
                    modifiers = "%s " % ' '.join(entry.func_modifiers).upper()
1012 1013 1014
                else:
                    modifiers = ''
                code.putln("%s%s%s; /*proto*/" % (
1015
                    storage_class,
1016
                    modifiers,
1017
                    header))
1018

1019 1020 1021 1022 1023
    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
1024
            if entry.visibility != 'extern':
1025 1026 1027 1028 1029 1030
                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)
1031 1032 1033
                    if scope.needs_gc():
                        self.generate_traverse_function(scope, code)
                        self.generate_clear_function(scope, code)
1034 1035 1036 1037
                    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)
1038 1039 1040 1041 1042
                    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")
1043 1044
                    if scope.defines_any(["__setslice__", "__delslice__"]):
                        self.generate_ass_slice_function(scope, code)
1045
                    if scope.defines_any(["__getattr__","__getattribute__"]):
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
                        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)
1057

1058 1059 1060 1061 1062 1063 1064
    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))
1065

1066 1067 1068 1069 1070 1071
    def generate_self_cast(self, scope, code):
        type = scope.parent_type
        code.putln(
            "%s = (%s)o;" % (
                type.declaration_code("p"),
                type.declaration_code("")))
1072

1073
    def generate_new_function(self, scope, code):
1074 1075
        tp_slot = TypeSlots.ConstructorSlot("tp_new", '__new__')
        slot_func = scope.mangle_internal("tp_new")
1076 1077 1078 1079 1080 1081 1082
        type = scope.parent_type
        base_type = type.base_type
        py_attrs = []
        for entry in scope.var_entries:
            if entry.type.is_pyobject:
                py_attrs.append(entry)
        need_self_cast = type.vtabslot_cname or py_attrs
1083 1084 1085 1086
        code.putln("")
        code.putln(
            "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
                % scope.mangle_internal("tp_new"))
1087 1088 1089 1090
        if need_self_cast:
            code.putln(
                "%s;"
                    % scope.parent_type.declaration_code("p"))
1091
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1092 1093
            tp_new = TypeSlots.get_base_slot_function(scope, tp_slot)
            if tp_new is None:
1094
                tp_new = "%s->tp_new" % base_type.typeptr_cname
1095
            code.putln(
1096
                "PyObject *o = %s(t, a, k);" % tp_new)
1097 1098 1099
        else:
            code.putln(
                "PyObject *o = (*t->tp_alloc)(t, 0);")
1100 1101 1102 1103 1104 1105 1106
        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
1107
        #    self.generate_self_cast(scope, code)
1108
        if type.vtabslot_cname:
1109 1110 1111 1112 1113
            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
1114 1115 1116
            else:
                struct_type_cast = ""
            code.putln("p->%s = %s%s;" % (
1117
                type.vtabslot_cname,
1118
                struct_type_cast, type.vtabptr_cname))
1119
        for entry in py_attrs:
1120 1121
            if scope.is_internal or entry.name == "__weakref__":
                # internal classes do not need None inits
1122
                code.putln("p->%s = 0;" % entry.cname)
1123
            else:
1124
                code.put_init_var_to_py_none(entry, "p->%s", nanny=False)
1125
        entry = scope.lookup_here("__new__")
1126
        if entry and entry.is_special:
1127 1128 1129 1130
            if entry.trivial_signature:
                cinit_args = "o, %s, NULL" % Naming.empty_tuple
            else:
                cinit_args = "o, a, k"
1131
            code.putln(
1132
                "if (%s(%s) < 0) {" %
1133
                    (entry.func_cname, cinit_args))
1134
            code.put_decref_clear("o", py_object_type, nanny=False);
1135 1136 1137 1138 1139 1140
            code.putln(
                "}")
        code.putln(
            "return o;")
        code.putln(
            "}")
1141

1142
    def generate_dealloc_function(self, scope, code):
1143 1144
        tp_slot = TypeSlots.ConstructorSlot("tp_dealloc", '__dealloc__')
        slot_func = scope.mangle_internal("tp_dealloc")
1145
        base_type = scope.parent_type.base_type
1146 1147
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1148 1149 1150 1151 1152
        code.putln("")
        code.putln(
            "static void %s(PyObject *o) {"
                % scope.mangle_internal("tp_dealloc"))
        py_attrs = []
1153
        weakref_slot = scope.lookup_here("__weakref__")
1154
        for entry in scope.var_entries:
1155
            if entry.type.is_pyobject and entry is not weakref_slot:
1156
                py_attrs.append(entry)
1157
        if py_attrs or weakref_slot in scope.var_entries:
1158 1159
            self.generate_self_cast(scope, code)
        self.generate_usr_dealloc_call(scope, code)
1160
        if weakref_slot in scope.var_entries:
1161
            code.putln("if (p->__weakref__) PyObject_ClearWeakRefs(o);")
1162
        for entry in py_attrs:
1163
            code.put_xdecref("p->%s" % entry.cname, entry.type, nanny=False)
1164
        if base_type:
Robert Bradshaw's avatar
Robert Bradshaw committed
1165 1166
            tp_dealloc = TypeSlots.get_base_slot_function(scope, tp_slot)
            if tp_dealloc is None:
1167
                tp_dealloc = "%s->tp_dealloc" % base_type.typeptr_cname
1168
            code.putln(
1169
                    "%s(o);" % tp_dealloc)
1170 1171
        else:
            code.putln(
1172
                    "(*Py_TYPE(o)->tp_free)(o);")
1173 1174
        code.putln(
            "}")
1175

1176 1177 1178 1179 1180 1181 1182 1183 1184 1185
    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(
1186
                    "++Py_REFCNT(o);")
1187
            code.putln(
1188
                    "%s(o);" %
1189 1190 1191 1192
                        entry.func_cname)
            code.putln(
                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
            code.putln(
1193
                    "--Py_REFCNT(o);")
1194 1195 1196 1197
            code.putln(
                    "PyErr_Restore(etype, eval, etb);")
            code.putln(
                "}")
1198

1199
    def generate_traverse_function(self, scope, code):
1200 1201
        tp_slot = TypeSlots.GCDependentSlot("tp_traverse")
        slot_func = scope.mangle_internal("tp_traverse")
1202
        base_type = scope.parent_type.base_type
1203 1204
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1205 1206 1207
        code.putln("")
        code.putln(
            "static int %s(PyObject *o, visitproc v, void *a) {"
1208
                % slot_func)
1209 1210
        py_attrs = []
        for entry in scope.var_entries:
1211
            if entry.type.is_pyobject and entry.name != "__weakref__":
1212 1213
                py_attrs.append(entry)
        if base_type or py_attrs:
1214
            code.putln("int e;")
1215 1216 1217
        if py_attrs:
            self.generate_self_cast(scope, code)
        if base_type:
1218
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1219 1220 1221
            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)
1222 1223 1224 1225 1226 1227
            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("}")
1228 1229 1230 1231 1232 1233 1234 1235
        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(
1236
                        "e = (*v)(%s, a); if (e) return e;"
1237 1238 1239 1240 1241 1242 1243
                            % var_code)
            code.putln(
                    "}")
        code.putln(
                "return 0;")
        code.putln(
            "}")
1244

1245
    def generate_clear_function(self, scope, code):
1246 1247
        tp_slot = TypeSlots.GCDependentSlot("tp_clear")
        slot_func = scope.mangle_internal("tp_clear")
1248
        base_type = scope.parent_type.base_type
1249 1250
        if tp_slot.slot_code(scope) != slot_func:
            return # never used
1251
        code.putln("")
1252
        code.putln("static int %s(PyObject *o) {" % slot_func)
1253 1254
        py_attrs = []
        for entry in scope.var_entries:
1255
            if entry.type.is_pyobject and entry.name != "__weakref__":
1256 1257 1258
                py_attrs.append(entry)
        if py_attrs:
            self.generate_self_cast(scope, code)
1259
            code.putln("PyObject* tmp;")
1260
        if base_type:
1261
            # want to call it explicitly if possible so inlining can be performed
Robert Bradshaw's avatar
Robert Bradshaw committed
1262 1263 1264
            static_call = TypeSlots.get_base_slot_function(scope, tp_slot)
            if static_call:
                code.putln("%s(o);" % static_call)
1265 1266 1267 1268
            else:
                code.putln("if (%s->tp_clear) {" % base_type.typeptr_cname)
                code.putln("%s->tp_clear(o);" % base_type.typeptr_cname)
                code.putln("}")
1269 1270
        for entry in py_attrs:
            name = "p->%s" % entry.cname
1271
            code.putln("tmp = ((PyObject*)%s);" % name)
1272 1273 1274 1275
            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)
1276
            code.putln("Py_XDECREF(tmp);")
1277 1278 1279 1280
        code.putln(
            "return 0;")
        code.putln(
            "}")
1281

1282 1283 1284 1285 1286
    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(
1287
            "static PyObject *%s(PyObject *o, Py_ssize_t i) {" %
1288 1289 1290 1291
                scope.mangle_internal("sq_item"))
        code.putln(
                "PyObject *r;")
        code.putln(
1292
                "PyObject *x = PyInt_FromSsize_t(i); if(!x) return 0;")
1293
        code.putln(
1294
                "r = Py_TYPE(o)->tp_as_mapping->mp_subscript(o, x);")
1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
        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(
1325
                    '  "Subscript assignment not supported by %s", Py_TYPE(o)->tp_name);')
1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341
            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(
1342
                    '  "Subscript deletion not supported by %s", Py_TYPE(o)->tp_name);')
1343 1344 1345 1346 1347 1348
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")
1349

1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377
    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(
1378
            "static int %s(PyObject *o, Py_ssize_t i, Py_ssize_t j, PyObject *v) {" %
1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
                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(
1392
                    '  "2-element slice assignment not supported by %s", Py_TYPE(o)->tp_name);')
1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
            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(
1409
                    '  "2-element slice deletion not supported by %s", Py_TYPE(o)->tp_name);')
1410 1411 1412 1413 1414 1415 1416 1417
            code.putln(
                    "return -1;")
        code.putln(
                "}")
        code.putln(
            "}")

    def generate_getattro_function(self, scope, code):
1418 1419 1420
        # First try to get the attribute using __getattribute__, if defined, or
        # PyObject_GenericGetAttr.
        #
1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
        # 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__")
1436 1437 1438 1439
        code.putln("")
        code.putln(
            "static PyObject *%s(PyObject *o, PyObject *n) {"
                % scope.mangle_internal("tp_getattro"))
1440 1441 1442 1443 1444 1445
        if getattribute_entry is not None:
            code.putln(
                "PyObject *v = %s(o, n);" %
                    getattribute_entry.func_cname)
        else:
            code.putln(
1446
                "PyObject *v = PyObject_GenericGetAttr(o, n);")
1447 1448
        if getattr_entry is not None:
            code.putln(
1449
                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
1450 1451 1452 1453 1454 1455
            code.putln(
                "PyErr_Clear();")
            code.putln(
                "v = %s(o, n);" %
                    getattr_entry.func_cname)
            code.putln(
1456 1457
                "}")
        code.putln(
1458
            "return v;")
1459 1460
        code.putln(
            "}")
1461

1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500
    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(
            "}")
1501

1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528
    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(
            "}")
1529

1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569
    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(
1570
                "}")
1571 1572
        code.putln(
            "}")
1573

1574 1575 1576 1577 1578 1579 1580
    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)
1581

1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595
    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(
            "}")
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 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644
    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:
1645
            header = "static PyTypeObject %s = {"
1646 1647 1648
        #code.putln(header % scope.parent_type.typeobj_cname)
        code.putln(header % type.typeobj_cname)
        code.putln(
1649
            "PyVarObject_HEAD_INIT(0, 0)")
1650
        code.putln(
1651
            '__Pyx_NAMESTR("%s.%s"), /*tp_name*/' % (
1652
                self.full_module_name, scope.class_name))
1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665
        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(
            "};")
1666

1667 1668 1669
    def generate_method_table(self, env, code):
        code.putln("")
        code.putln(
1670
            "static PyMethodDef %s[] = {" %
1671 1672
                env.method_table_cname)
        for entry in env.pyfunc_entries:
1673
            code.put_pymethoddef(entry, ",")
1674 1675 1676 1677
        code.putln(
                "{0, 0, 0, 0}")
        code.putln(
            "};")
1678

1679 1680 1681 1682 1683 1684 1685
    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:
1686 1687 1688 1689
                if entry.doc:
                    doc_code = "__Pyx_DOCSTR(%s)" % code.get_string_const(entry.doc)
                else:
                    doc_code = "0"
1690
                code.putln(
1691
                    '{(char *)"%s", %s, %s, %s, 0},' % (
1692 1693 1694
                        entry.name,
                        entry.getter_cname or "0",
                        entry.setter_cname or "0",
1695
                        doc_code))
1696 1697 1698 1699
            code.putln(
                    "{0, 0, 0, 0, 0}")
            code.putln(
                "};")
1700

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1701
    def generate_import_star(self, env, code):
1702
        env.use_utility_code(streq_utility_code)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1703 1704 1705 1706 1707 1708 1709 1710
        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()
1711
        code.enter_cfunc_scope() # as we need labels
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1712 1713 1714
        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) {")
1715
        code.putln("if (__Pyx_StrEq(name, *type_name)) {")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1716 1717 1718 1719 1720 1721 1722 1723 1724
        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:
1725
                code.putln('else if (__Pyx_StrEq(name, "%s")) {' % name)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1726 1727 1728 1729 1730
                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)))
1731 1732
                    code.putln("Py_INCREF(o);")
                    code.put_decref(entry.cname, entry.type, nanny=False)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1733
                    code.putln("%s = %s;" % (
1734
                        entry.cname,
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1735 1736 1737 1738
                        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:
1739
                        rhs = PyrexTypes.typecast(entry.type, PyrexTypes.c_long_type, rhs)
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752
                    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;")
1753 1754 1755 1756
        if code.label_used(code.error_label):
            code.put_label(code.error_label)
            # This helps locate the offending name.
            code.putln('__Pyx_AddTraceback("%s");' % self.full_module_name);
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1757 1758 1759 1760 1761
        code.error_label = old_error_label
        code.putln("bad:")
        code.putln("return -1;")
        code.putln("}")
        code.putln(import_star_utility_code)
1762
        code.exit_cfunc_scope() # done with labels
1763 1764

    def generate_module_init_func(self, imported_modules, env, code):
1765
        code.enter_cfunc_scope()
1766
        code.putln("")
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776
        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("{")
1777
        tempdecl_code = code.insertion_point()
Robert Bradshaw's avatar
Robert Bradshaw committed
1778

1779
        code.put_declare_refcount_context()
1780 1781 1782
        code.putln("#if CYTHON_REFNANNY")
        code.putln("__Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"refnanny\");")
        code.putln("if (!__Pyx_RefNanny) {")
1783
        code.putln("  PyErr_Clear();")
1784 1785 1786
        code.putln("  __Pyx_RefNanny = __Pyx_RefNannyImportAPI(\"Cython.Runtime.refnanny\");")
        code.putln("  if (!__Pyx_RefNanny)")
        code.putln("      Py_FatalError(\"failed to import 'refnanny' module\");")
1787
        code.putln("}")
1788
        code.putln("#endif")
1789
        code.put_setup_refcount_context(header3)
1790

1791
        env.use_utility_code(check_binary_version_utility_code)
1792
        code.putln("if ( __Pyx_check_binary_version() < 0) %s" % code.error_goto(self.pos))
1793

1794
        code.putln("%s = PyTuple_New(0); %s" % (Naming.empty_tuple, code.error_goto_if_null(Naming.empty_tuple, self.pos)));
1795
        code.putln("%s = PyBytes_FromStringAndSize(\"\", 0); %s" % (Naming.empty_bytes, code.error_goto_if_null(Naming.empty_bytes, self.pos)));
1796

Robert Bradshaw's avatar
Robert Bradshaw committed
1797 1798 1799
        code.putln("#ifdef %s_USED" % Naming.binding_cfunc)
        code.putln("if (%s_init() < 0) %s" % (Naming.binding_cfunc, code.error_goto(self.pos)))
        code.putln("#endif")
1800

1801
        code.putln("/*--- Library function declarations ---*/")
1802
        env.generate_library_function_declarations(code)
1803

1804 1805
        code.putln("/*--- Threads initialization code ---*/")
        code.putln("#if defined(__PYX_FORCE_INIT_THREADS) && __PYX_FORCE_INIT_THREADS")
1806
        code.putln("#ifdef WITH_THREAD /* Python build with threading support? */")
1807 1808 1809 1810
        code.putln("PyEval_InitThreads();")
        code.putln("#endif")
        code.putln("#endif")

1811
        code.putln("/*--- Module creation code ---*/")
1812
        self.generate_module_creation_code(env, code)
1813

1814 1815 1816
        code.putln("/*--- Initialize various global constants etc. ---*/")
        code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos))

1817 1818
        __main__name = code.globalstate.get_py_string_const(
            EncodedString("__main__"), identifier=True)
1819 1820 1821 1822
        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,
1823
                __main__name.cname,
1824 1825
                code.error_goto(self.pos)))
        code.putln("}")
1826

Robert Bradshaw's avatar
Robert Bradshaw committed
1827 1828
        if Options.cache_builtins:
            code.putln("/*--- Builtin init code ---*/")
1829 1830 1831 1832
            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))
1833

1834
        code.putln("/*--- Global init code ---*/")
1835
        self.generate_global_init_code(env, code)
Gary Furnish's avatar
Gary Furnish committed
1836

1837 1838 1839
        code.putln("/*--- Variable export code ---*/")
        self.generate_c_variable_export_code(env, code)

1840
        code.putln("/*--- Function export code ---*/")
1841 1842
        self.generate_c_function_export_code(env, code)

1843
        code.putln("/*--- Type init code ---*/")
1844
        self.generate_type_init_code(env, code)
1845

1846
        code.putln("/*--- Type import code ---*/")
1847 1848 1849
        for module in imported_modules:
            self.generate_type_import_code_for_module(module, env, code)

Gary Furnish's avatar
Gary Furnish committed
1850 1851 1852 1853
        code.putln("/*--- Function import code ---*/")
        for module in imported_modules:
            self.generate_c_function_import_code_for_module(module, env, code)

1854
        code.putln("/*--- Execution code ---*/")
Robert Bradshaw's avatar
Robert Bradshaw committed
1855
        code.mark_pos(None)
1856

1857
        self.body.generate_execution_code(code)
1858

1859
        if Options.generate_cleanup_code:
1860
            # this should be replaced by the module's tp_clear in Py3
1861
            env.use_utility_code(import_module_utility_code)
1862
            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
1863

1864
        code.put_goto(code.return_label)
1865
        code.put_label(code.error_label)
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1866 1867
        for cname, type in code.funcstate.all_managed_temps():
            code.put_xdecref(cname, type)
1868 1869
        code.putln('if (%s) {' % env.module_cname)
        code.putln('__Pyx_AddTraceback("init %s");' % env.qualified_name)
1870
        env.use_utility_code(Nodes.traceback_utility_code)
1871
        code.put_decref_clear(env.module_cname, py_object_type, nanny=False)
1872 1873 1874
        code.putln('} else if (!PyErr_Occurred()) {')
        code.putln('PyErr_SetString(PyExc_ImportError, "init %s");' % env.qualified_name)
        code.putln('}')
1875
        code.put_label(code.return_label)
1876 1877 1878

        code.put_finish_refcount_context()

1879 1880 1881
        code.putln("#if PY_MAJOR_VERSION < 3")
        code.putln("return;")
        code.putln("#else")
1882
        code.putln("return %s;" % env.module_cname)
1883
        code.putln("#endif")
1884
        code.putln('}')
1885

1886
        tempdecl_code.put_temp_declarations(code.funcstate)
1887

1888
        code.exit_cfunc_scope()
1889

1890 1891 1892
    def generate_module_cleanup_func(self, env, code):
        if not Options.generate_cleanup_code:
            return
1893
        code.globalstate.use_utility_code(register_cleanup_utility_code)
1894
        code.putln('static PyObject *%s(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *unused) {' %
1895
                   Naming.cleanup_cname)
1896 1897
        if Options.generate_cleanup_code >= 2:
            code.putln("/*--- Global cleanup code ---*/")
1898 1899 1900
            rev_entries = list(env.var_entries)
            rev_entries.reverse()
            for entry in rev_entries:
1901
                if entry.visibility != 'extern':
1902
                    if entry.type.is_pyobject and entry.used:
1903 1904
                        code.putln("Py_DECREF(%s); %s = 0;" % (
                            code.entry_as_pyobject(entry), entry.cname))
1905
        code.putln("__Pyx_CleanupGlobals();")
1906 1907 1908
        if Options.generate_cleanup_code >= 3:
            code.putln("/*--- Type import cleanup code ---*/")
            for type, _ in env.types_imported.items():
1909
                code.putln("Py_DECREF((PyObject *)%s);" % type.typeptr_cname)
1910 1911
        if Options.cache_builtins:
            code.putln("/*--- Builtin cleanup code ---*/")
1912
            for entry in env.cached_builtins:
1913 1914 1915
                code.put_decref_clear(entry.cname,
                                      PyrexTypes.py_object_type,
                                      nanny=False)
1916
        code.putln("/*--- Intern cleanup code ---*/")
1917 1918 1919
        code.put_decref_clear(Naming.empty_tuple,
                              PyrexTypes.py_object_type,
                              nanny=False)
1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932
#        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))
1933 1934
        code.putln("Py_INCREF(Py_None); return Py_None;")

1935
    def generate_main_method(self, env, code):
1936
        module_is_main = "%s%s" % (Naming.module_is_main, self.full_module_name.replace('.', '__'))
1937 1938 1939 1940 1941 1942 1943 1944 1945 1946
        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))
1947

1948 1949
    def generate_pymoduledef_struct(self, env, code):
        if env.doc:
1950
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
1951 1952 1953 1954 1955 1956
        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,")
1957
        code.putln('  __Pyx_NAMESTR("%s"),' % env.module_name)
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967
        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")

1968 1969 1970 1971
    def generate_module_creation_code(self, env, code):
        # Generate code to create the module object and
        # install the builtins.
        if env.doc:
1972
            doc = "__Pyx_DOCSTR(%s)" % code.get_string_const(env.doc)
1973 1974
        else:
            doc = "0"
1975
        code.putln("#if PY_MAJOR_VERSION < 3")
1976
        code.putln(
1977
            '%s = Py_InitModule4(__Pyx_NAMESTR("%s"), %s, %s, 0, PYTHON_API_VERSION);' % (
1978 1979 1980
                env.module_cname,
                env.module_name,
                env.method_table_cname,
1981
                doc))
1982 1983 1984 1985 1986 1987
        code.putln("#else")
        code.putln(
            "%s = PyModule_Create(&%s);" % (
                env.module_cname,
                Naming.pymoduledef_cname))
        code.putln("#endif")
1988 1989 1990 1991
        code.putln(
            "if (!%s) %s;" % (
                env.module_cname,
                code.error_goto(self.pos)));
1992
        code.putln("#if PY_MAJOR_VERSION < 3")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
1993 1994 1995
        code.putln(
            "Py_INCREF(%s);" %
                env.module_cname)
1996
        code.putln("#endif")
1997
        code.putln(
1998
            '%s = PyImport_AddModule(__Pyx_NAMESTR(__Pyx_BUILTIN_MODULE_NAME));' %
1999 2000 2001 2002 2003 2004
                Naming.builtins_cname)
        code.putln(
            "if (!%s) %s;" % (
                Naming.builtins_cname,
                code.error_goto(self.pos)));
        code.putln(
2005
            'if (__Pyx_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
2006 2007 2008
                env.module_cname,
                Naming.builtins_cname,
                code.error_goto(self.pos)))
2009 2010
        if Options.pre_import is not None:
            code.putln(
2011
                '%s = PyImport_AddModule(__Pyx_NAMESTR("%s"));' % (
2012
                    Naming.preimport_cname,
2013 2014 2015 2016 2017
                    Options.pre_import))
            code.putln(
                "if (!%s) %s;" % (
                    Naming.preimport_cname,
                    code.error_goto(self.pos)));
2018

2019 2020 2021 2022
    def generate_global_init_code(self, env, code):
        # Generate code to initialise global PyObject *
        # variables to None.
        for entry in env.var_entries:
2023
            if entry.visibility != 'extern':
2024
                if entry.type.is_pyobject and entry.used:
2025
                    code.put_init_var_to_py_none(entry, nanny=False)
2026

2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038
    def generate_c_variable_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
        for entry in env.var_entries:
            if entry.api or entry.defined_in_pxd:
                env.use_utility_code(voidptr_export_utility_code)
                signature = entry.type.declaration_code("")
                code.putln('if (__Pyx_ExportVoidPtr("%s", (void *)&%s, "%s") < 0) %s' % (
                    entry.name,
                    entry.cname,
                    signature,
                    code.error_goto(self.pos)))

2039 2040 2041 2042 2043 2044
    def generate_c_function_export_code(self, env, code):
        # Generate code to create PyCFunction wrappers for exported C functions.
        for entry in env.cfunc_entries:
            if entry.api or entry.defined_in_pxd:
                env.use_utility_code(function_export_utility_code)
                signature = entry.type.signature_string()
2045
                code.putln('if (__Pyx_ExportFunction("%s", (void (*)(void))%s, "%s") < 0) %s' % (
2046 2047
                    entry.name,
                    entry.cname,
2048
                    signature,
2049
                    code.error_goto(self.pos)))
2050

2051
    def generate_type_import_code_for_module(self, module, env, code):
2052
        # Generate type import code for all exported extension types in
2053
        # an imported module.
2054 2055 2056
        #if module.c_class_entries:
        for entry in module.c_class_entries:
            if entry.defined_in_pxd:
2057
                self.generate_type_import_code(env, entry.type, entry.pos, code)
2058

2059 2060 2061 2062 2063 2064 2065 2066 2067
    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)
2068
            temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2069 2070 2071 2072 2073 2074
            code.putln(
                '%s = __Pyx_ImportModule("%s"); if (!%s) %s' % (
                    temp,
                    module.qualified_name,
                    temp,
                    code.error_goto(self.pos)))
2075 2076
            for entry in entries:
                code.putln(
2077
                    'if (__Pyx_ImportFunction(%s, "%s", (void (**)(void))&%s, "%s") < 0) %s' % (
2078
                        temp,
2079 2080 2081 2082
                        entry.name,
                        entry.cname,
                        entry.type.signature_string(),
                        code.error_goto(self.pos)))
2083
            code.putln("Py_DECREF(%s); %s = 0;" % (temp, temp))
2084

2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095
    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:
            if entry.visibility == 'extern':
                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)
2096

2097 2098
    def generate_base_type_import_code(self, env, entry, code):
        base_type = entry.type.base_type
2099 2100
        if base_type and base_type.module_name != env.qualified_name \
               and not base_type.is_builtin_type:
2101
            self.generate_type_import_code(env, base_type, self.pos, code)
2102

2103
    def use_type_import_utility_code(self, env):
2104 2105
        env.use_utility_code(type_import_utility_code)
        env.use_utility_code(import_module_utility_code)
2106

2107 2108 2109 2110 2111 2112 2113 2114 2115 2116
    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
2117 2118
        self.generate_type_import_call(type, code,
                                       code.error_goto_if_null(type.typeptr_cname, pos))
2119 2120 2121
        self.use_type_import_utility_code(env)
        if type.vtabptr_cname:
            env.use_utility_code(Nodes.get_vtable_utility_code)
2122 2123 2124 2125 2126
            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)))
2127
        env.types_imported[type] = 1
2128

2129 2130
    py3_type_name_map = {'str' : 'bytes', 'unicode' : 'str'}

2131 2132 2133 2134 2135
    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
2136
        module_name = type.module_name
2137
        condition = None
2138 2139 2140 2141
        if module_name not in ('__builtin__', 'builtins'):
            module_name = '"%s"' % module_name
        else:
            module_name = '__Pyx_BUILTIN_MODULE_NAME'
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151
            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")
2152
        code.putln('%s = __Pyx_ImportType(%s, "%s", sizeof(%s), %i); %s' % (
2153 2154 2155 2156
                type.typeptr_cname,
                module_name,
                type.name,
                objstruct,
2157
                not type.is_external or type.is_subclassed,
2158
                error_code))
2159
        if condition:
2160
            code.putln("#endif")
2161

2162 2163 2164 2165 2166 2167 2168
    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
2169
            if entry.visibility != 'extern':
2170 2171 2172 2173 2174 2175
                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)))
2176
                # Fix special method docstrings. This is a bit of a hack, but
2177
                # unless we let PyType_Ready create the slot wrappers we have
2178
                # a significant performance hit. (See trac #561.)
2179
                for func in entry.type.scope.pyfunc_entries:
2180
                    if func.is_special and Options.docstrings and func.wrapperbase_cname:
Stefan Behnel's avatar
Stefan Behnel committed
2181
                        code.putln("{")
2182
                        code.putln(
2183
                            'PyObject *wrapper = __Pyx_GetAttrString((PyObject *)&%s, "%s"); %s' % (
2184 2185
                                typeobj_cname,
                                func.name,
Stefan Behnel's avatar
Stefan Behnel committed
2186
                                code.error_goto_if_null('wrapper', entry.pos)))
2187
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2188
                            "if (Py_TYPE(wrapper) == &PyWrapperDescr_Type) {")
2189 2190
                        code.putln(
                            "%s = *((PyWrapperDescrObject *)wrapper)->d_base;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2191
                                func.wrapperbase_cname))
2192
                        code.putln(
Stefan Behnel's avatar
Stefan Behnel committed
2193
                            "%s.doc = %s;" % (func.wrapperbase_cname, func.doc_cname))
2194 2195
                        code.putln(
                            "((PyWrapperDescrObject *)wrapper)->d_base = &%s;" % (
Stefan Behnel's avatar
Stefan Behnel committed
2196 2197 2198
                                func.wrapperbase_cname))
                        code.putln("}")
                        code.putln("}")
2199 2200 2201 2202 2203 2204 2205
                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)
2206 2207 2208 2209 2210 2211 2212 2213 2214 2215
                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)))
2216 2217 2218 2219
                weakref_entry = scope.lookup_here("__weakref__")
                if weakref_entry:
                    if weakref_entry.type is py_object_type:
                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
2220 2221 2222 2223 2224
                        if type.typedef_flag:
                            objstruct = type.objstruct_cname
                        else:
                            objstruct = "struct %s" % type.objstruct_cname
                        code.putln("if (%s == 0) %s = offsetof(%s, %s);" % (
2225 2226
                            tp_weaklistoffset,
                            tp_weaklistoffset,
2227
                            objstruct,
2228 2229 2230
                            weakref_entry.cname))
                    else:
                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
2231

2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246
    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))
2247 2248 2249 2250

            c_method_entries = [
                entry for entry in type.scope.cfunc_entries
                if entry.func_cname ]
2251 2252 2253 2254 2255 2256 2257 2258 2259
            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))
2260

2261 2262 2263 2264 2265 2266 2267 2268
    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))
2269

2270
#------------------------------------------------------------------------------------
Stefan Behnel's avatar
Stefan Behnel committed
2271 2272 2273
#
#  Runtime support code
#
2274 2275
#------------------------------------------------------------------------------------

2276 2277
streq_utility_code = UtilityCode(
proto = """
2278
static CYTHON_INLINE int __Pyx_StrEq(const char *, const char *); /*proto*/
2279 2280
""",
impl = """
2281
static CYTHON_INLINE int __Pyx_StrEq(const char *s1, const char *s2) {
2282 2283 2284 2285 2286 2287 2288
     while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
     return *s1 == *s2;
}
""")

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

2289 2290
import_module_utility_code = UtilityCode(
proto = """
2291
static PyObject *__Pyx_ImportModule(const char *name); /*proto*/
2292 2293
""",
impl = """
2294 2295
#ifndef __PYX_HAVE_RT_ImportModule
#define __PYX_HAVE_RT_ImportModule
2296
static PyObject *__Pyx_ImportModule(const char *name) {
2297
    PyObject *py_name = 0;
2298
    PyObject *py_module = 0;
2299 2300

    #if PY_MAJOR_VERSION < 3
2301
    py_name = PyString_FromString(name);
2302 2303 2304
    #else
    py_name = PyUnicode_FromString(name);
    #endif
2305 2306
    if (!py_name)
        goto bad;
2307 2308 2309
    py_module = PyImport_Import(py_name);
    Py_DECREF(py_name);
    return py_module;
2310 2311 2312 2313
bad:
    Py_XDECREF(py_name);
    return 0;
}
2314
#endif
2315
""")
2316 2317 2318

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

2319 2320
type_import_utility_code = UtilityCode(
proto = """
2321
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name, long size, int strict);  /*proto*/
2322 2323
""",
impl = """
Stefan Behnel's avatar
Stefan Behnel committed
2324 2325
#ifndef __PYX_HAVE_RT_ImportType
#define __PYX_HAVE_RT_ImportType
2326
static PyTypeObject *__Pyx_ImportType(const char *module_name, const char *class_name,
2327
    long size, int strict)
2328 2329
{
    PyObject *py_module = 0;
2330
    PyObject *result = 0;
Gary Furnish's avatar
Gary Furnish committed
2331
    PyObject *py_name = 0;
2332
    char warning[200];
2333

2334 2335 2336
    py_module = __Pyx_ImportModule(module_name);
    if (!py_module)
        goto bad;
2337
    #if PY_MAJOR_VERSION < 3
2338
    py_name = PyString_FromString(class_name);
2339
    #else
2340
    py_name = PyUnicode_FromString(class_name);
2341
    #endif
Gary Furnish's avatar
Gary Furnish committed
2342 2343
    if (!py_name)
        goto bad;
2344 2345
    result = PyObject_GetAttr(py_module, py_name);
    Py_DECREF(py_name);
2346 2347 2348
    py_name = 0;
    Py_DECREF(py_module);
    py_module = 0;
2349 2350 2351
    if (!result)
        goto bad;
    if (!PyType_Check(result)) {
2352
        PyErr_Format(PyExc_TypeError,
2353 2354 2355 2356
            "%s.%s is not a type object",
            module_name, class_name);
        goto bad;
    }
2357
    if (!strict && ((PyTypeObject *)result)->tp_basicsize > size) {
2358
        PyOS_snprintf(warning, sizeof(warning),
2359 2360
            "%s.%s size changed, may indicate binary incompatibility",
            module_name, class_name);
2361 2362 2363
        #if PY_VERSION_HEX < 0x02050000
        PyErr_Warn(NULL, warning);
        #else
2364
        PyErr_WarnEx(NULL, warning, 0);
2365
        #endif
2366
    }
2367
    else if (((PyTypeObject *)result)->tp_basicsize != size) {
2368
        PyErr_Format(PyExc_ValueError,
2369
            "%s.%s has the wrong size, try recompiling",
2370 2371 2372 2373 2374
            module_name, class_name);
        goto bad;
    }
    return (PyTypeObject *)result;
bad:
2375
    Py_XDECREF(py_module);
2376 2377 2378
    Py_XDECREF(result);
    return 0;
}
Stefan Behnel's avatar
Stefan Behnel committed
2379
#endif
2380
""")
2381 2382 2383

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

2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422
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}
)

2423 2424
function_export_utility_code = UtilityCode(
proto = """
2425
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig); /*proto*/
2426 2427
""",
impl = r"""
2428
static int __Pyx_ExportFunction(const char *name, void (*f)(void), const char *sig) {
2429
    PyObject *d = 0;
2430 2431 2432 2433 2434 2435
    PyObject *cobj = 0;
    union {
        void (*fp)(void);
        void *p;
    } tmp;

2436
    d = PyObject_GetAttrString(%(MODULE)s, (char *)"%(API)s");
2437 2438 2439 2440 2441 2442
    if (!d) {
        PyErr_Clear();
        d = PyDict_New();
        if (!d)
            goto bad;
        Py_INCREF(d);
2443
        if (PyModule_AddObject(%(MODULE)s, (char *)"%(API)s", d) < 0)
2444 2445
            goto bad;
    }
2446
    tmp.fp = f;
2447
#if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
2448
    cobj = PyCapsule_New(tmp.p, sig, 0);
2449 2450
#else
    cobj = PyCObject_FromVoidPtrAndDesc(tmp.p, (void *)sig, 0);
2451
#endif
2452
    if (!cobj)
2453
        goto bad;
2454
    if (PyDict_SetItemString(d, name, cobj) < 0)
2455
        goto bad;
2456
    Py_DECREF(cobj);
2457
    Py_DECREF(d);
2458 2459
    return 0;
bad:
2460
    Py_XDECREF(cobj);
2461
    Py_XDECREF(d);
2462 2463
    return -1;
}
2464 2465
""" % {'MODULE': Naming.module_cname, 'API': Naming.api_name}
)
2466

2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522
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)
)

2523 2524
function_import_utility_code = UtilityCode(
proto = """
2525
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig); /*proto*/
2526 2527
""",
impl = """
Stefan Behnel's avatar
Stefan Behnel committed
2528 2529
#ifndef __PYX_HAVE_RT_ImportFunction
#define __PYX_HAVE_RT_ImportFunction
2530
static int __Pyx_ImportFunction(PyObject *module, const char *funcname, void (**f)(void), const char *sig) {
2531
    PyObject *d = 0;
2532
    PyObject *cobj = 0;
2533 2534 2535 2536
    union {
        void (*fp)(void);
        void *p;
    } tmp;
2537

2538
    d = PyObject_GetAttrString(module, (char *)"%(API)s");
2539 2540 2541
    if (!d)
        goto bad;
    cobj = PyDict_GetItemString(d, funcname);
2542 2543
    if (!cobj) {
        PyErr_Format(PyExc_ImportError,
2544
            "%%s does not export expected C function %%s",
2545 2546 2547
                PyModule_GetName(module), funcname);
        goto bad;
    }
2548 2549 2550 2551 2552 2553 2554 2555 2556 2557
#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;
2558
    desc = (const char *)PyCObject_GetDesc(cobj);
2559 2560
    if (!desc)
        goto bad;
2561 2562 2563
    s1 = desc; s2 = sig;
    while (*s1 != '\\0' && *s1 == *s2) { s1++; s2++; }
    if (*s1 != *s2) {
2564
        PyErr_Format(PyExc_TypeError,
2565
            "C function %%s.%%s has wrong signature (expected %%s, got %%s)",
2566
             PyModule_GetName(module), funcname, sig, desc);
2567 2568
        goto bad;
    }
2569
    tmp.p = PyCObject_AsVoidPtr(cobj);}
2570
#endif
2571
    *f = tmp.fp;
2572 2573
    if (!(*f))
        goto bad;
2574
    Py_DECREF(d);
2575 2576
    return 0;
bad:
2577
    Py_XDECREF(d);
2578 2579
    return -1;
}
Stefan Behnel's avatar
Stefan Behnel committed
2580
#endif
2581 2582
""" % dict(API = Naming.api_name)
)
2583

2584 2585
#------------------------------------------------------------------------------------

2586 2587
register_cleanup_utility_code = UtilityCode(
proto = """
2588
static int __Pyx_RegisterCleanup(void); /*proto*/
2589 2590 2591
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},
2592
impl = """
2593
static int __Pyx_RegisterCleanup(void) {
2594 2595
    /* Don't use Py_AtExit because that has a 32-call limit
     * and is called after python finalization.
2596 2597 2598 2599 2600 2601 2602 2603
     */

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

2605 2606 2607 2608 2609 2610 2611 2612 2613 2614
    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;
2615
    reg = __Pyx_GetAttrString(atexit, "register");
2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629
    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;
}
2630
""")
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2631 2632 2633 2634 2635 2636 2637 2638

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
2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672
    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;
        }
        all = PyMapping_Keys(dict);
        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 &&
2673
#if PY_MAJOR_VERSION < 3
Robert Bradshaw's avatar
Robert Bradshaw committed
2674 2675
            PyString_Check(name) &&
            PyString_AS_STRING(name)[0] == '_')
2676
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2677 2678
            PyUnicode_Check(name) &&
            PyUnicode_AS_UNICODE(name)[0] == '_')
2679
#endif
Robert Bradshaw's avatar
Robert Bradshaw committed
2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697
        {
            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
2698 2699 2700
}


2701
static int %(IMPORT_STAR)s(PyObject* m) {
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2702 2703 2704

    int i;
    int ret = -1;
2705
    char* s;
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2706 2707
    PyObject *locals = 0;
    PyObject *list = 0;
2708 2709 2710
#if PY_MAJOR_VERSION >= 3
    PyObject *utf8_name = 0;
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2711 2712
    PyObject *name;
    PyObject *item;
2713

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2714 2715 2716
    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;
2717

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2718 2719 2720
    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);
2721 2722 2723 2724 2725 2726
#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;
2727
#else
2728
        s = PyString_AsString(name);
2729 2730
        if (!s) goto bad;
        if (%(IMPORT_STAR_SET)s(item, name, s) < 0) goto bad;
2731
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2732 2733
    }
    ret = 0;
2734

Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2735 2736 2737
bad:
    Py_XDECREF(locals);
    Py_XDECREF(list);
2738 2739 2740
#if PY_MAJOR_VERSION >= 3
    Py_XDECREF(utf8_name);
#endif
Dag Sverre Seljebotn's avatar
Merge  
Dag Sverre Seljebotn committed
2741 2742
    return ret;
}
2743 2744
""" % {'IMPORT_STAR'     : Naming.import_star,
       'IMPORT_STAR_SET' : Naming.import_star_set }
2745

2746 2747
refnanny_utility_code = UtilityCode(
proto="""
2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761
#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;
2762
  static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); /*proto*/
2763
  #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL;
2764
  #define __Pyx_RefNannySetupContext(name) \
2765
          __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), __LINE__, __FILE__)
2766 2767
  #define __Pyx_RefNannyFinishContext() \
          __Pyx_RefNanny->FinishContext(&__pyx_refnanny)
2768 2769 2770
  #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__)
2771
  #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), __LINE__)
2772 2773 2774 2775
  #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)
2776
#else
2777
  #define __Pyx_RefNannyDeclarations
2778 2779 2780 2781 2782 2783
  #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)
2784
  #define __Pyx_XINCREF(r) Py_XINCREF(r)
2785
  #define __Pyx_XDECREF(r) Py_XDECREF(r)
2786 2787
  #define __Pyx_XGOTREF(r)
  #define __Pyx_XGIVEREF(r)
2788
#endif /* CYTHON_REFNANNY */
2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807
""",
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
2808

2809 2810
main_method = UtilityCode(
impl = """
2811 2812 2813 2814 2815
#ifdef __FreeBSD__
#include <floatingpoint.h>
#endif

#if PY_MAJOR_VERSION < 3
2816
int %(main_method)s(int argc, char** argv) {
2817
#elif defined(WIN32) || defined(MS_WINDOWS)
2818
int %(wmain_method)s(int argc, wchar_t **argv) {
2819 2820
#else
static int __Pyx_main(int argc, wchar_t **argv) {
2821
#endif
2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832
    /* 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
2833
    if (argc && argv)
2834
        Py_SetProgramName(argv[0]);
2835
    Py_Initialize();
2836
    if (argc && argv)
2837
        PySys_SetArgv(argc, argv);
2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853
    { /* 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);
2854
    }
2855
    Py_Finalize();
2856
    return 0;
2857
}
2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882


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

static wchar_t*
__Pyx_char2wchar(char* arg)
{
	wchar_t *res;
#ifdef HAVE_BROKEN_MBSTOWCS
	/* 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);
#else
	size_t argsize = mbstowcs(NULL, arg, 0);
#endif
	size_t count;
	unsigned char *in;
	wchar_t *out;
#ifdef HAVE_MBRTOWC
	mbstate_t mbs;
#endif
	if (argsize != (size_t)-1) {
2883
		res = (wchar_t *)malloc((argsize+1)*sizeof(wchar_t));
2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896
		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;
		}
2897
		free(res);
2898 2899 2900 2901 2902 2903 2904 2905
	}
	/* Conversion failed. Fall back to escaping with surrogateescape. */
#ifdef HAVE_MBRTOWC
	/* 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;
2906
	res = malloc(argsize*sizeof(wchar_t));
2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948
	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++;
	}
#else
	/* 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. */
2949
	res = malloc((strlen(arg)+1)*sizeof(wchar_t));
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966
	if (!res) goto oom;
	in = (unsigned char*)arg;
	out = res;
	while(*in)
		if(*in < 128)
			*out++ = *in++;
		else
			*out++ = 0xdc00 + *in++;
	*out = 0;
#endif
	return res;
oom:
	fprintf(stderr, "out of memory\\n");
	return NULL;
}

int
2967
%(main_method)s(int argc, char **argv)
2968
{
2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998
    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;
    }
2999 3000
}
#endif
3001
""")
3002 3003 3004 3005 3006 3007 3008

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
3009
""", impl="", proto_block='utility_code_proto_before_types')
3010 3011 3012 3013 3014

check_binary_version_utility_code = UtilityCode(proto="""
static int __Pyx_check_binary_version(void);
""", impl="""
static int __Pyx_check_binary_version(void) {
3015 3016 3017 3018
    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]) {
3019 3020
        char message[200];
        PyOS_snprintf(message, sizeof(message),
3021 3022 3023
                      "compiletime version %s of module '%.100s' "
                      "does not match runtime version %s",
                      ctversion, __Pyx_MODULE_NAME, rtversion);
3024
        #if PY_VERSION_HEX < 0x02050000
3025
        return PyErr_Warn(NULL, message);
3026
        #else
3027
        return PyErr_WarnEx(NULL, message, 1);
3028 3029
        #endif
    }
3030
    return 0;
3031 3032
}
""")