PyrexTypes.py 73.3 KB
Newer Older
William Stein's avatar
William Stein committed
1 2 3 4
#
#   Pyrex - Types
#

5
from Code import UtilityCode
6
import StringEncoding
William Stein's avatar
William Stein committed
7
import Naming
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
8
import copy
William Stein's avatar
William Stein committed
9

10
class BaseType(object):
11 12 13 14 15 16
    #
    #  Base class for all Pyrex types including pseudo-types.

    def cast_code(self, expr_code):
        return "((%s)%s)" % (self.declaration_code(""), expr_code)
    
17 18 19
    def specalization_name(self):
        return self.declaration_code("").replace(" ", "__")
    
20 21 22 23 24 25 26
    def base_declaration_code(self, base_code, entity_code):
        if entity_code:
            return "%s %s" % (base_code, entity_code)
        else:
            return base_code

class PyrexType(BaseType):
William Stein's avatar
William Stein committed
27 28 29 30 31 32 33 34
    #
    #  Base class for all Pyrex types.
    #
    #  is_pyobject           boolean     Is a Python object type
    #  is_extension_type     boolean     Is a Python extension type
    #  is_numeric            boolean     Is a C numeric type
    #  is_int                boolean     Is a C integer type
    #  is_float              boolean     Is a C floating point type
35
    #  is_complex            boolean     Is a C complex type
William Stein's avatar
William Stein committed
36 37 38 39 40 41
    #  is_void               boolean     Is the C void type
    #  is_array              boolean     Is a C array type
    #  is_ptr                boolean     Is a C pointer type
    #  is_null_ptr           boolean     Is the type of NULL
    #  is_cfunction          boolean     Is a C function type
    #  is_struct_or_union    boolean     Is a C struct or union type
Robert Bradshaw's avatar
Robert Bradshaw committed
42
    #  is_struct             boolean     Is a C struct type
William Stein's avatar
William Stein committed
43
    #  is_enum               boolean     Is a C enum type
44
    #  is_typedef            boolean     Is a typedef type
William Stein's avatar
William Stein committed
45
    #  is_string             boolean     Is a C char * type
46
    #  is_unicode            boolean     Is a UTF-8 encoded C char * type
William Stein's avatar
William Stein committed
47 48
    #  is_returncode         boolean     Is used only to signal exceptions
    #  is_error              boolean     Is the dummy error type
49
    #  is_buffer             boolean     Is buffer access type
William Stein's avatar
William Stein committed
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
    #  has_attributes        boolean     Has C dot-selectable attributes
    #  default_value         string      Initial value
    #  pymemberdef_typecode  string      Type code for PyMemberDef struct
    #
    #  declaration_code(entity_code, 
    #      for_display = 0, dll_linkage = None, pyrex = 0)
    #    Returns a code fragment for the declaration of an entity
    #    of this type, given a code fragment for the entity.
    #    * If for_display, this is for reading by a human in an error
    #      message; otherwise it must be valid C code.
    #    * If dll_linkage is not None, it must be 'DL_EXPORT' or
    #      'DL_IMPORT', and will be added to the base type part of
    #      the declaration.
    #    * If pyrex = 1, this is for use in a 'cdef extern'
    #      statement of a Pyrex include file.
    #
    #  assignable_from(src_type)
    #    Tests whether a variable of this type can be
    #    assigned a value of type src_type.
    #
    #  same_as(other_type)
    #    Tests whether this type represents the same type
    #    as other_type.
    #
    #  as_argument_type():
    #    Coerces array type into pointer type for use as
    #    a formal argument type.
    #
        
    is_pyobject = 0
Robert Bradshaw's avatar
Robert Bradshaw committed
80
    is_unspecified = 0
William Stein's avatar
William Stein committed
81
    is_extension_type = 0
Robert Bradshaw's avatar
Robert Bradshaw committed
82
    is_builtin_type = 0
William Stein's avatar
William Stein committed
83 84 85
    is_numeric = 0
    is_int = 0
    is_float = 0
86
    is_complex = 0
William Stein's avatar
William Stein committed
87 88 89 90 91 92
    is_void = 0
    is_array = 0
    is_ptr = 0
    is_null_ptr = 0
    is_cfunction = 0
    is_struct_or_union = 0
Robert Bradshaw's avatar
Robert Bradshaw committed
93
    is_struct = 0
William Stein's avatar
William Stein committed
94
    is_enum = 0
95
    is_typedef = 0
William Stein's avatar
William Stein committed
96
    is_string = 0
97
    is_unicode = 0
William Stein's avatar
William Stein committed
98 99
    is_returncode = 0
    is_error = 0
100
    is_buffer = 0
William Stein's avatar
William Stein committed
101 102 103 104 105 106 107 108 109 110 111 112 113 114
    has_attributes = 0
    default_value = ""
    pymemberdef_typecode = None
    
    def resolve(self):
        # If a typedef, returns the base type.
        return self
    
    def literal_code(self, value):
        # Returns a C code fragment representing a literal
        # value of this type.
        return str(value)
    
    def __str__(self):
115
        return self.declaration_code("", for_display = 1).strip()
William Stein's avatar
William Stein committed
116 117 118 119 120
    
    def same_as(self, other_type, **kwds):
        return self.same_as_resolved_type(other_type.resolve(), **kwds)
    
    def same_as_resolved_type(self, other_type):
121
        return self == other_type or other_type is error_type
William Stein's avatar
William Stein committed
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
    
    def subtype_of(self, other_type):
        return self.subtype_of_resolved_type(other_type.resolve())
    
    def subtype_of_resolved_type(self, other_type):
        return self.same_as(other_type)
    
    def assignable_from(self, src_type):
        return self.assignable_from_resolved_type(src_type.resolve())
    
    def assignable_from_resolved_type(self, src_type):
        return self.same_as(src_type)
    
    def as_argument_type(self):
        return self
    
    def is_complete(self):
        # A type is incomplete if it is an unsized array,
        # a struct whose attributes are not defined, etc.
        return 1

143
    def is_simple_buffer_dtype(self):
144
        return (self.is_int or self.is_float or self.is_complex or self.is_pyobject or
145 146
                self.is_extension_type or self.is_ptr)

147 148 149 150 151 152
    def struct_nesting_depth(self):
        # Returns the number levels of nested structs. This is
        # used for constructing a stack for walking the run-time
        # type information of the struct.
        return 1

153 154 155 156 157 158 159 160 161

def create_typedef_type(cname, base_type, is_external=0):
    if base_type.is_complex:
        if is_external:
            raise ValueError("Complex external typedefs not supported")
        return base_type
    else:
        return CTypedefType(cname, base_type, is_external)

162
class CTypedefType(BaseType):
William Stein's avatar
William Stein committed
163
    #
164
    #  Pseudo-type defined with a ctypedef statement in a
William Stein's avatar
William Stein committed
165
    #  'cdef extern from' block. Delegates most attribute
166 167
    #  lookups to the base type. ANYTHING NOT DEFINED
    #  HERE IS DELEGATED!
William Stein's avatar
William Stein committed
168
    #
169 170 171
    #  qualified_name      string
    #  typedef_cname       string
    #  typedef_base_type   PyrexType
172
    #  typedef_is_external bool
173 174
    
    is_typedef = 1
175
    typedef_is_external = 0
176 177 178 179

    to_py_utility_code = None
    from_py_utility_code = None
    
William Stein's avatar
William Stein committed
180
    
181
    def __init__(self, cname, base_type, is_external=0):
182
        assert not base_type.is_complex
William Stein's avatar
William Stein committed
183 184
        self.typedef_cname = cname
        self.typedef_base_type = base_type
185
        self.typedef_is_external = is_external
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
186 187 188 189 190 191 192 193 194 195 196 197
        # Make typecodes in external typedefs use typesize-neutral macros
        if is_external:
            typecode = None
            if base_type.is_int:
                if base_type.signed == 0:
                    typecode = "__Pyx_T_UNSIGNED_INT"
                else:
                    typecode = "__Pyx_T_SIGNED_INT"
            elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
                typecode = "__Pyx_T_FLOATING"
            if typecode:
                self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
William Stein's avatar
William Stein committed
198 199 200 201 202 203
    
    def resolve(self):
        return self.typedef_base_type.resolve()
    
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
204 205 206 207 208 209 210 211 212 213 214 215
        name = self.declaration_name(for_display, pyrex)
        return self.base_declaration_code(name, entity_code)
    
    def declaration_name(self, for_display = 0, pyrex = 0):
        if pyrex or for_display:
            return self.qualified_name
        else:
            return self.typedef_cname
    
    def as_argument_type(self):
        return self

216 217 218 219 220 221 222
    def cast_code(self, expr_code):
        # If self is really an array (rather than pointer), we can't cast.
        # For example, the gmp mpz_t. 
        if self.typedef_base_type.is_ptr:
            return self.typedef_base_type.cast_code(expr_code)
        else:
            return BaseType.cast_code(self, expr_code)
223

224 225
    def __repr__(self):
        return "<CTypedefType %s>" % self.typedef_cname
William Stein's avatar
William Stein committed
226 227
    
    def __str__(self):
228
        return self.declaration_name(for_display = 1)
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286

    def _create_utility_code(self, template_utility_code,
                             template_function_name):
        type_name = self.typedef_cname.replace(" ","_")
        utility_code = template_utility_code.specialize(
            type     = self.typedef_cname,
            TypeName = type_name)
        function_name = template_function_name % type_name
        return utility_code, function_name

    def create_to_py_utility_code(self, env):
        if self.typedef_is_external:
            if not self.to_py_utility_code:
                base_type = self.typedef_base_type
                if base_type.is_int:
                    self.to_py_utility_code, self.to_py_function = \
                        self._create_utility_code(c_typedef_int_to_py_function,
                                                  '__Pyx_PyInt_to_py_%s')
                elif base_type.is_float:
                    pass # XXX implement!
                elif base_type.is_complex:
                    pass # XXX implement!
                    pass
            if self.to_py_utility_code:
                env.use_utility_code(self.to_py_utility_code)
                return True
        # delegation
        return self.typedef_base_type.create_to_py_utility_code(env)

    def create_from_py_utility_code(self, env):
        if self.typedef_is_external:
            if not self.from_py_utility_code:
                base_type = self.typedef_base_type
                if base_type.is_int:
                    self.from_py_utility_code, self.from_py_function = \
                        self._create_utility_code(c_typedef_int_from_py_function,
                                                  '__Pyx_PyInt_from_py_%s')
                elif base_type.is_float:
                    pass # XXX implement!
                elif base_type.is_complex:
                    pass # XXX implement!
            if self.from_py_utility_code:
                env.use_utility_code(self.from_py_utility_code)
                return True
        # delegation
        return self.typedef_base_type.create_from_py_utility_code(env)

    def error_condition(self, result_code):
        if self.typedef_is_external:
            if self.exception_value:
                condition = "(%s == (%s)%s)" % (
                    result_code, self.typedef_cname, self.exception_value)
                if self.exception_check:
                    condition += " && PyErr_Occurred()"
                return condition
        # delegation
        return self.typedef_base_type.error_condition(result_code)

William Stein's avatar
William Stein committed
287 288 289
    def __getattr__(self, name):
        return getattr(self.typedef_base_type, name)

290 291 292 293 294 295
class BufferType(BaseType):
    #
    #  Delegates most attribute
    #  lookups to the base type. ANYTHING NOT DEFINED
    #  HERE IS DELEGATED!
    
296 297 298 299 300 301 302
    # dtype            PyrexType
    # ndim             int
    # mode             str
    # negative_indices bool
    # cast             bool
    # is_buffer        bool
    # writable         bool
303 304

    is_buffer = 1
305
    writable = True
306
    def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
307 308 309
        self.base = base
        self.dtype = dtype
        self.ndim = ndim
310
        self.buffer_ptr_type = CPtrType(dtype)
311
        self.mode = mode
312
        self.negative_indices = negative_indices
313
        self.cast = cast
314
    
315 316 317
    def as_argument_type(self):
        return self

318 319 320
    def __getattr__(self, name):
        return getattr(self.base, name)

321 322 323
    def __repr__(self):
        return "<BufferType %r>" % self.base

324 325 326 327 328
def public_decl(base, dll_linkage):
    if dll_linkage:
        return "%s(%s)" % (dll_linkage, base)
    else:
        return base
329
    
William Stein's avatar
William Stein committed
330 331 332 333
class PyObjectType(PyrexType):
    #
    #  Base class for all Python object types (reference-counted).
    #
334
    #  buffer_defaults  dict or None     Default options for bu
335 336

    name = "object"
William Stein's avatar
William Stein committed
337 338 339
    is_pyobject = 1
    default_value = "0"
    pymemberdef_typecode = "T_OBJECT"
340
    buffer_defaults = None
William Stein's avatar
William Stein committed
341 342 343 344 345
    
    def __str__(self):
        return "Python object"
    
    def __repr__(self):
346
        return "<PyObjectType>"
William Stein's avatar
William Stein committed
347 348
    
    def assignable_from(self, src_type):
349 350
        # except for pointers, conversion will be attempted
        return not src_type.is_ptr or src_type.is_string
William Stein's avatar
William Stein committed
351 352 353
        
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
354 355
        if pyrex or for_display:
            return self.base_declaration_code("object", entity_code)
William Stein's avatar
William Stein committed
356 357 358
        else:
            return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)

359 360 361 362 363
    def as_pyobject(self, cname):
        if (not self.is_complete()) or self.is_extension_type:
            return "(PyObject *)" + cname
        else:
            return cname
William Stein's avatar
William Stein committed
364

Robert Bradshaw's avatar
Robert Bradshaw committed
365 366 367 368 369 370 371
class BuiltinObjectType(PyObjectType):

    is_builtin_type = 1
    has_attributes = 1
    base_type = None
    module_name = '__builtin__'

372 373
    alternative_name = None # used for str/bytes duality

Robert Bradshaw's avatar
Robert Bradshaw committed
374 375
    def __init__(self, name, cname):
        self.name = name
376 377 378 379
        if name == 'str':
            self.alternative_name = 'bytes'
        elif name == 'bytes':
            self.alternative_name = 'str'
Robert Bradshaw's avatar
Robert Bradshaw committed
380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
        self.cname = cname
        self.typeptr_cname = "&" + cname
                                 
    def set_scope(self, scope):
        self.scope = scope
        if scope:
            scope.parent_type = self
        
    def __str__(self):
        return "%s object" % self.name
    
    def __repr__(self):
        return "<%s>"% self.cname
        
    def assignable_from(self, src_type):
        if isinstance(src_type, BuiltinObjectType):
396 397 398
            return src_type.name == self.name or (
                src_type.name == self.alternative_name and
                src_type.name is not None)
Robert Bradshaw's avatar
Robert Bradshaw committed
399 400 401 402 403 404 405 406 407 408 409 410
        else:
            return not src_type.is_extension_type
            
    def typeobj_is_available(self):
        return True
        
    def attributes_known(self):
        return True
        
    def subtype_of(self, type):
        return type.is_pyobject and self.assignable_from(type)
        
411
    def type_test_code(self, arg, notnone=False):
412 413
        type_name = self.name
        if type_name == 'str':
414
            type_check = 'PyString_CheckExact'
415
        elif type_name == 'set':
416
            type_check = 'PyAnySet_CheckExact'
417
        elif type_name == 'frozenset':
418
            type_check = 'PyFrozenSet_CheckExact'
419
        elif type_name == 'bool':
420
            type_check = 'PyBool_Check'
421
        else:
422 423 424 425 426 427 428
            type_check = 'Py%s_CheckExact' % type_name.capitalize()

        check = 'likely(%s(%s))' % (type_check, arg)
        if not notnone:
            check = check + ('||((%s) == Py_None)' % arg)
        error = '(PyErr_Format(PyExc_TypeError, "Expected %s, got %%.200s", Py_TYPE(%s)->tp_name), 0)' % (self.name, arg)
        return check + '||' + error
Robert Bradshaw's avatar
Robert Bradshaw committed
429

430 431 432 433 434 435 436
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        if pyrex or for_display:
            return self.base_declaration_code(self.name, entity_code)
        else:
            return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)

Robert Bradshaw's avatar
Robert Bradshaw committed
437

William Stein's avatar
William Stein committed
438 439 440 441 442 443 444 445 446 447 448
class PyExtensionType(PyObjectType):
    #
    #  A Python extension type.
    #
    #  name             string
    #  scope            CClassScope      Attribute namespace
    #  visibility       string
    #  typedef_flag     boolean
    #  base_type        PyExtensionType or None
    #  module_name      string or None   Qualified name of defining module
    #  objstruct_cname  string           Name of PyObject struct
449
    #  objtypedef_cname string           Name of PyObject struct typedef
William Stein's avatar
William Stein committed
450 451 452 453 454 455 456 457 458 459
    #  typeobj_cname    string or None   C code fragment referring to type object
    #  typeptr_cname    string or None   Name of pointer to external type object
    #  vtabslot_cname   string           Name of C method table member
    #  vtabstruct_cname string           Name of C method table struct
    #  vtabptr_cname    string           Name of pointer to C method table
    #  vtable_cname     string           Name of C method table definition
    
    is_extension_type = 1
    has_attributes = 1
    
460 461
    objtypedef_cname = None
    
William Stein's avatar
William Stein committed
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
    def __init__(self, name, typedef_flag, base_type):
        self.name = name
        self.scope = None
        self.typedef_flag = typedef_flag
        self.base_type = base_type
        self.module_name = None
        self.objstruct_cname = None
        self.typeobj_cname = None
        self.typeptr_cname = None
        self.vtabslot_cname = None
        self.vtabstruct_cname = None
        self.vtabptr_cname = None
        self.vtable_cname = None
    
    def set_scope(self, scope):
        self.scope = scope
        if scope:
            scope.parent_type = self
    
    def subtype_of_resolved_type(self, other_type):
        if other_type.is_extension_type:
            return self is other_type or (
                self.base_type and self.base_type.subtype_of(other_type))
        else:
            return other_type is py_object_type
    
    def typeobj_is_available(self):
        # Do we have a pointer to the type object?
        return self.typeptr_cname
    
    def typeobj_is_imported(self):
        # If we don't know the C name of the type object but we do
        # know which module it's defined in, it will be imported.
        return self.typeobj_cname is None and self.module_name is not None
    
    def declaration_code(self, entity_code, 
498
            for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
499 500
        if pyrex or for_display:
            return self.base_declaration_code(self.name, entity_code)
William Stein's avatar
William Stein committed
501 502 503 504 505 506
        else:
            if self.typedef_flag:
                base_format = "%s"
            else:
                base_format = "struct %s"
            base = public_decl(base_format % self.objstruct_cname, dll_linkage)
507 508 509 510
            if deref:
                return "%s %s" % (base,  entity_code)
            else:
                return "%s *%s" % (base,  entity_code)
William Stein's avatar
William Stein committed
511

512 513 514 515 516 517 518 519 520 521
    def type_test_code(self, py_arg, notnone=False):

        none_check = "((%s) == Py_None)" % py_arg
        type_check = "likely(__Pyx_TypeTest(%s, %s))" % (
            py_arg, self.typeptr_cname)
        if notnone:
            return type_check
        else:
            return "likely(%s || %s)" % (none_check, type_check)

William Stein's avatar
William Stein committed
522 523 524 525 526 527 528
    def attributes_known(self):
        return self.scope is not None
    
    def __str__(self):
        return self.name
    
    def __repr__(self):
529 530
        return "<PyExtensionType %s%s>" % (self.scope.class_name,
            ("", " typedef")[self.typedef_flag])
William Stein's avatar
William Stein committed
531 532 533 534 535 536 537 538 539 540 541 542
    

class CType(PyrexType):
    #
    #  Base class for all C types (non-reference-counted).
    #
    #  to_py_function     string     C function for converting to Python object
    #  from_py_function   string     C function for constructing from Python object
    #
    
    to_py_function = None
    from_py_function = None
543 544
    exception_value = None
    exception_check = 1
Robert Bradshaw's avatar
Robert Bradshaw committed
545

546
    def create_to_py_utility_code(self, env):
547
        return self.to_py_function is not None
548 549
        
    def create_from_py_utility_code(self, env):
550
        return self.from_py_function is not None
Robert Bradshaw's avatar
Robert Bradshaw committed
551
        
552 553 554 555 556 557 558 559 560 561 562 563
    def error_condition(self, result_code):
        conds = []
        if self.is_string:
            conds.append("(!%s)" % result_code)
        elif self.exception_value is not None:
            conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
        if self.exception_check:
            conds.append("PyErr_Occurred()")
        if len(conds) > 0:
            return " && ".join(conds)
        else:
            return 0
William Stein's avatar
William Stein committed
564 565


566
class CVoidType(CType):
William Stein's avatar
William Stein committed
567 568 569 570 571 572 573 574
    is_void = 1
    
    def __repr__(self):
        return "<CVoidType>"
    
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        base = public_decl("void", dll_linkage)
575
        return self.base_declaration_code(base, entity_code)
William Stein's avatar
William Stein committed
576 577 578 579 580 581 582 583 584 585
    
    def is_complete(self):
        return 0


class CNumericType(CType):
    #
    #   Base class for all C numeric types.
    #
    #   rank      integer     Relative size
586
    #   signed    integer     0 = unsigned, 1 = unspecified, 2 = explicitly signed
William Stein's avatar
William Stein committed
587 588 589 590 591
    #
    
    is_numeric = 1
    default_value = "0"
    
592 593
    sign_words = ("unsigned ", "", "signed ")
    
594
    def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
William Stein's avatar
William Stein committed
595 596 597 598
        self.rank = rank
        self.signed = signed
        self.pymemberdef_typecode = pymemberdef_typecode
    
599 600 601 602 603
    def sign_and_name(self):
        s = self.sign_words[self.signed]
        n = rank_to_type_name[self.rank]
        return s + n
    
William Stein's avatar
William Stein committed
604
    def __repr__(self):
605
        return "<CNumericType %s>" % self.sign_and_name()
William Stein's avatar
William Stein committed
606 607 608
    
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
609
        base = public_decl(self.sign_and_name(), dll_linkage)
610
        if for_display:
611
            base = base.replace('PY_LONG_LONG', 'long long')
612
        return self.base_declaration_code(base,  entity_code)
613 614 615


type_conversion_predeclarations = ""
616 617 618 619 620 621 622 623
type_conversion_functions = ""

c_int_from_py_function = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
Robert Bradshaw's avatar
Robert Bradshaw committed
624 625
    const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
    const int is_unsigned = neg_one > const_zero;
626 627 628
    if (sizeof(%(type)s) < sizeof(long)) {
        long val = __Pyx_PyInt_AsLong(x);
        if (unlikely(val != (long)(%(type)s)val)) {
629
            if (!unlikely(val == -1 && PyErr_Occurred())) {
630
                PyErr_SetString(PyExc_OverflowError,
631
                    (is_unsigned && unlikely(val < 0)) ?
632 633
                    "can't convert negative value to %(type)s" :
                    "value too large to convert to %(type)s");
634
            }
635 636 637 638 639 640
            return (%(type)s)-1;
        }
        return (%(type)s)val;
    }
    return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x);
}
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
641
""") #fool emacs: '
642 643 644 645 646 647 648

c_long_from_py_function = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
Robert Bradshaw's avatar
Robert Bradshaw committed
649 650
    const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
    const int is_unsigned = neg_one > const_zero;
651
#if PY_VERSION_HEX < 0x03000000
652 653
    if (likely(PyInt_Check(x))) {
        long val = PyInt_AS_LONG(x);
654
        if (is_unsigned && unlikely(val < 0)) {
655 656 657 658
            PyErr_SetString(PyExc_OverflowError,
                            "can't convert negative value to %(type)s");
            return (%(type)s)-1;
        }
659 660 661
        return (%(type)s)val;
    } else
#endif
662
    if (likely(PyLong_Check(x))) {
663 664 665 666 667 668 669 670 671
        if (is_unsigned) {
            if (unlikely(Py_SIZE(x) < 0)) {
                PyErr_SetString(PyExc_OverflowError,
                                "can't convert negative value to %(type)s");
                return (%(type)s)-1;
            }
            return PyLong_AsUnsigned%(TypeName)s(x);
        } else {
            return PyLong_As%(TypeName)s(x);
672
        }
673 674 675 676 677 678 679 680 681 682 683
    } else {
        %(type)s val;
        PyObject *tmp = __Pyx_PyNumber_Int(x);
        if (!tmp) return (%(type)s)-1;
        val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp);
        Py_DECREF(tmp);
        return val;
    }
}
""")

684 685 686 687 688 689
c_typedef_int_from_py_function = UtilityCode(
proto="""
static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
""",
impl="""
static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
Robert Bradshaw's avatar
Robert Bradshaw committed
690 691
    const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
    const int is_unsigned = neg_one > const_zero;
692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716
    if (sizeof(%(type)s) == sizeof(char)) {
        if (is_unsigned)
            return (%(type)s)__Pyx_PyInt_AsUnsignedChar(x);
        else
            return (%(type)s)__Pyx_PyInt_AsSignedChar(x);
    } else if (sizeof(%(type)s) == sizeof(short)) {
        if (is_unsigned)
            return (%(type)s)__Pyx_PyInt_AsUnsignedShort(x);
        else
            return (%(type)s)__Pyx_PyInt_AsSignedShort(x);
    } else if (sizeof(%(type)s) == sizeof(int)) {
        if (is_unsigned)
            return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
        else
            return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
    } else if (sizeof(%(type)s) == sizeof(long)) {
        if (is_unsigned)
            return (%(type)s)__Pyx_PyInt_AsUnsignedLong(x);
        else
            return (%(type)s)__Pyx_PyInt_AsSignedLong(x);
    } else if (sizeof(%(type)s) == sizeof(PY_LONG_LONG)) {
        if (is_unsigned)
            return (%(type)s)__Pyx_PyInt_AsUnsignedLongLong(x);
        else
            return (%(type)s)__Pyx_PyInt_AsSignedLongLong(x);
717
#if 0
718 719 720 721 722 723
    } else if (sizeof(%(type)s) > sizeof(short) &&
               sizeof(%(type)s) < sizeof(int)) { /*  __int32 ILP64 ? */
        if (is_unsigned)
            return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
        else
            return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
724
#endif
725 726 727
    }
    PyErr_SetString(PyExc_TypeError, "%(TypeName)s");
    return (%(type)s)-1;
728 729
}
""")
730

731 732 733 734 735 736
c_typedef_int_to_py_function = UtilityCode(
proto="""
static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
""",
impl="""
static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
Robert Bradshaw's avatar
Robert Bradshaw committed
737 738
    const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
    const int is_unsigned = neg_one > const_zero;
739 740 741 742 743 744 745 746 747 748 749 750 751
    if (sizeof(%(type)s) <  sizeof(long)) {
        return PyInt_FromLong((long)val);
    } else if (sizeof(%(type)s) == sizeof(long)) {
        if (is_unsigned)
            return PyLong_FromUnsignedLong((unsigned long)val);
        else
            return PyInt_FromLong((long)val);
    } else { /* (sizeof(%(type)s) > sizeof(long)) */
        if (is_unsigned)
            return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
        else
            return PyLong_FromLongLong((PY_LONG_LONG)val);
    }
752 753
}
""")
William Stein's avatar
William Stein committed
754 755

class CIntType(CNumericType):
756

William Stein's avatar
William Stein committed
757 758 759
    is_int = 1
    typedef_flag = 0
    to_py_function = "PyInt_FromLong"
760
    from_py_function = "__Pyx_PyInt_AsInt"
761
    exception_value = -1
William Stein's avatar
William Stein committed
762

763 764
    def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
        CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
William Stein's avatar
William Stein committed
765
        self.is_returncode = is_returncode
766
        if self.from_py_function == "__Pyx_PyInt_AsInt":
767 768 769
            self.from_py_function = self.get_type_conversion()

    def get_type_conversion(self):
770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
        ctype = self.declaration_code('')
        bits = ctype.split(" ", 1)
        if len(bits) == 1:
            sign_word, type_name = "", bits[0]
        else:
            sign_word, type_name = bits
        type_name = type_name.replace("PY_LONG_LONG","long long")
        SignWord  = sign_word.title()
        TypeName  = type_name.title().replace(" ", "")
        if "Long" in TypeName:
            utility_code = c_long_from_py_function
        else:
            utility_code = c_int_from_py_function
        utility_code.specialize(self,
                                SignWord=SignWord,
785
                                TypeName=TypeName)
786
        func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
787
        return func_name
788

789 790
    def assignable_from_resolved_type(self, src_type):
        return src_type.is_int or src_type.is_enum or src_type is error_type
791

William Stein's avatar
William Stein committed
792

793
class CBIntType(CIntType):
Robert Bradshaw's avatar
Robert Bradshaw committed
794

795 796
    to_py_function = "__Pyx_PyBool_FromLong"
    from_py_function = "__Pyx_PyObject_IsTrue"
797
    exception_check = 0
William Stein's avatar
William Stein committed
798

799

800 801
class CAnonEnumType(CIntType):

802 803 804 805
    is_enum = 1

    def sign_and_name(self):
        return 'int'
806

807

William Stein's avatar
William Stein committed
808 809 810
class CUIntType(CIntType):

    to_py_function = "PyLong_FromUnsignedLong"
811
    exception_value = -1
William Stein's avatar
William Stein committed
812 813


814 815 816 817 818
class CLongType(CIntType):

    to_py_function = "PyInt_FromLong"


819
class CULongType(CUIntType):
William Stein's avatar
William Stein committed
820 821 822 823

    to_py_function = "PyLong_FromUnsignedLong"


824
class CLongLongType(CIntType):
William Stein's avatar
William Stein committed
825 826 827 828

    to_py_function = "PyLong_FromLongLong"


829
class CULongLongType(CUIntType):
William Stein's avatar
William Stein committed
830 831 832 833

    to_py_function = "PyLong_FromUnsignedLongLong"


834 835 836
class CPySSizeTType(CIntType):

    to_py_function = "PyInt_FromSsize_t"
837
    from_py_function = "__Pyx_PyIndex_AsSsize_t"
838

839 840 841
    def sign_and_name(self):
        return rank_to_type_name[self.rank]

842

843 844
class CSizeTType(CUIntType):

845 846
    to_py_function = "__Pyx_PyInt_FromSize_t"
    from_py_function = "__Pyx_PyInt_AsSize_t"
847

848 849 850
    def sign_and_name(self):
        return rank_to_type_name[self.rank]

851

William Stein's avatar
William Stein committed
852 853 854 855
class CFloatType(CNumericType):

    is_float = 1
    to_py_function = "PyFloat_FromDouble"
856
    from_py_function = "__pyx_PyFloat_AsDouble"
William Stein's avatar
William Stein committed
857
    
858
    def __init__(self, rank, pymemberdef_typecode = None, math_h_modifier = ''):
859
        CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
860
        self.math_h_modifier = math_h_modifier
William Stein's avatar
William Stein committed
861
    
862
    def assignable_from_resolved_type(self, src_type):
863 864
        return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type

865

866
class CComplexType(CNumericType):
867 868
    
    is_complex = 1
869
    to_py_function = "__pyx_PyComplex_FromComplex"
870 871
    has_attributes = 1
    scope = None
872 873 874 875
    
    def __init__(self, real_type):
        self.real_type = real_type
        CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
876
        self.binops = {}
877
        self.from_parts = "%s_from_parts" % self.specalization_name()
878
        self.default_value = "%s(0, 0)" % self.from_parts
879
    
880
    def __eq__(self, other):
881
        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
882
            return self.real_type == other.real_type
883
        else:
884
            return False
885 886 887 888 889 890
    
    def __ne__(self, other):
        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
            return self.real_type != other.real_type
        else:
            return True
891 892 893 894 895 896 897 898 899

    def __lt__(self, other):
        if isinstance(self, CComplexType) and isinstance(other, CComplexType):
            return self.real_type < other.real_type
        else:
            # this is arbitrary, but it makes sure we always have
            # *some* kind of order
            return False

900 901 902
    def __hash__(self):
        return ~hash(self.real_type)
    
903 904 905 906 907 908 909 910
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        if for_display:
            base = public_decl(self.real_type.sign_and_name() + " complex", dll_linkage)
        else:
            base = public_decl(self.sign_and_name(), dll_linkage)
        return self.base_declaration_code(base,  entity_code)

911
    def sign_and_name(self):
912 913 914
        real_type_name = self.real_type.specalization_name()
        real_type_name = real_type_name.replace('long__double','long_double')
        return Naming.type_prefix + real_type_name + "_complex"
915
    
916 917 918 919 920 921 922
    def assignable_from(self, src_type):
        # Temporary hack/feature disabling, see #441
        if not src_type.is_complex and src_type.is_numeric and src_type.is_typedef:
            return False
        else:
            return super(CComplexType, self).assignable_from(src_type)
        
923 924 925 926
    def assignable_from_resolved_type(self, src_type):
        return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
                    or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type) 
                    or src_type is error_type)
927 928 929 930
                    
    def attributes_known(self):
        if self.scope is None:
            import Symtab
931 932 933 934 935 936 937 938 939 940 941 942 943 944
            self.scope = scope = Symtab.CClassScope(
                    '',
                    None,
                    visibility="extern")
            scope.parent_type = self
            scope.declare_var("real", self.real_type, None, "real", is_cdef=True)
            scope.declare_var("imag", self.real_type, None, "imag", is_cdef=True)
            entry = scope.declare_cfunction(
                    "conjugate",
                    CFuncType(self, [CFuncTypeArg("self", self, None)]),
                    pos=None,
                    defining=1,
                    cname="__Pyx_c_conj%s" % self.real_type.math_h_modifier)

945
        return True
946

947
    def create_declaration_utility_code(self, env):
948 949
        # This must always be run, because a single CComplexType instance can be shared
        # across multiple compilations (the one created in the module scope)
950 951 952 953 954 955 956 957 958 959 960 961 962 963 964
        env.use_utility_code(complex_header_utility_code)
        env.use_utility_code(complex_real_imag_utility_code)
        for utility_code in (complex_type_utility_code,
                             complex_from_parts_utility_code,
                             complex_arithmatic_utility_code):
            env.use_utility_code(
                utility_code.specialize(
                    self, 
                    real_type = self.real_type.declaration_code(''),
                    m = self.real_type.math_h_modifier))
        return True

    def create_to_py_utility_code(self, env):
        env.use_utility_code(complex_real_imag_utility_code)
        env.use_utility_code(complex_to_py_utility_code)
965 966 967 968
        return True

    def create_from_py_utility_code(self, env):
        self.real_type.create_from_py_utility_code(env)
969 970 971 972 973 974 975 976 977

        for utility_code in (complex_from_parts_utility_code,
                             complex_from_py_utility_code):
            env.use_utility_code(
                utility_code.specialize(
                    self, 
                    real_type = self.real_type.declaration_code(''),
                    m = self.real_type.math_h_modifier))
        self.from_py_function = "__Pyx_PyComplex_As_" + self.specalization_name()
978
        return True
979
    
980
    def lookup_op(self, nargs, op):
981
        try:
982
            return self.binops[nargs, op]
983
        except KeyError:
984 985 986
            pass
        try:
            op_name = complex_ops[nargs, op]
987 988
            modifier = self.real_type.math_h_modifier
            self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, modifier)
989 990 991 992 993 994 995 996 997 998 999 1000 1001
            return func_name
        except KeyError:
            return None

    def unary_op(self, op):
        return self.lookup_op(1, op)
        
    def binary_op(self, op):
        return self.lookup_op(2, op)
        
complex_ops = {
    (1, '-'): 'neg',
    (1, 'zero'): 'is_zero',
1002 1003 1004 1005
    (2, '+'): 'sum',
    (2, '-'): 'diff',
    (2, '*'): 'prod',
    (2, '/'): 'quot',
1006 1007
    (2, '=='): 'eq',
}
1008

1009
complex_header_utility_code = UtilityCode(
1010
proto_block='h_code',
1011
proto="""
1012 1013 1014 1015 1016 1017 1018 1019
#if !defined(CYTHON_CCOMPLEX)
  #if defined(__cplusplus)
    #define CYTHON_CCOMPLEX 1
  #elif defined(_Complex_I)
    #define CYTHON_CCOMPLEX 1
  #else
    #define CYTHON_CCOMPLEX 0
  #endif
1020 1021
#endif

1022 1023 1024 1025 1026 1027 1028
#if CYTHON_CCOMPLEX
  #ifdef __cplusplus
    #include <complex>
  #else
    #include <complex.h>
  #endif
#endif
1029 1030
""")

1031
complex_real_imag_utility_code = UtilityCode(
1032
proto="""
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044
#if CYTHON_CCOMPLEX
  #ifdef __cplusplus
    #define __Pyx_CREAL(z) ((z).real())
    #define __Pyx_CIMAG(z) ((z).imag())
  #else
    #define __Pyx_CREAL(z) (__real__(z))
    #define __Pyx_CIMAG(z) (__imag__(z))
  #endif
#else
    #define __Pyx_CREAL(z) ((z).real)
    #define __Pyx_CIMAG(z) ((z).imag)
#endif
1045 1046
""")

1047 1048
complex_type_utility_code = UtilityCode(
proto_block='utility_code_proto_before_types',
1049
proto="""
1050 1051 1052 1053
#if CYTHON_CCOMPLEX
  #ifdef __cplusplus
    typedef ::std::complex< %(real_type)s > %(type_name)s;
  #else
1054
    typedef %(real_type)s _Complex %(type_name)s;
1055 1056 1057 1058 1059 1060 1061
  #endif
#else
    typedef struct { %(real_type)s real, imag; } %(type_name)s;
#endif
""")

complex_from_parts_utility_code = UtilityCode(
1062
proto_block='utility_code_proto',
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080
proto="""
#if CYTHON_CCOMPLEX
  #ifdef __cplusplus
    static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
  #else
    static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
  #endif
#else
    static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
#endif
""",
impl="""
#if CYTHON_CCOMPLEX
  #ifdef __cplusplus
    static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
      return ::std::complex< %(real_type)s >(x, y);
    }
  #else
1081 1082 1083
    static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
      return x + y*(%(type)s)_Complex_I;
    }
1084
  #endif
1085
#else
1086
    static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1087 1088 1089 1090
      %(type)s z;
       z.real = x;
       z.imag = y;
       return z;
1091
    }
1092 1093
#endif
""")
1094

1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117
complex_to_py_utility_code = UtilityCode(
proto="""
#define __pyx_PyComplex_FromComplex(z) \\
        PyComplex_FromDoubles((double)__Pyx_CREAL(z), \\
                              (double)__Pyx_CIMAG(z))
""")

complex_from_py_utility_code = UtilityCode(
proto="""
static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*);
""",
impl="""
static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) {
    Py_complex cval;
    if (PyComplex_CheckExact(o))
        cval = ((PyComplexObject *)o)->cval;
    else
        cval = PyComplex_AsCComplex(o);
    return %(type_name)s_from_parts(
               (%(real_type)s)cval.real,
               (%(real_type)s)cval.imag);
}
""")
1118

1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155
complex_arithmatic_utility_code = UtilityCode(
proto="""
#if CYTHON_CCOMPLEX
    #define __Pyx_c_eq%(m)s(a, b)   ((a)==(b))
    #define __Pyx_c_sum%(m)s(a, b)  ((a)+(b))
    #define __Pyx_c_diff%(m)s(a, b) ((a)-(b))
    #define __Pyx_c_prod%(m)s(a, b) ((a)*(b))
    #define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
    #define __Pyx_c_neg%(m)s(a)     (-(a))
  #ifdef __cplusplus
    #define __Pyx_c_is_zero%(m)s(z) ((z)==0.0)
    #define __Pyx_c_conj%(m)s(z)    (::std::conj(z))
    /*#define __Pyx_c_abs%(m)s(z)     (::std::abs(z))*/
  #else
    #define __Pyx_c_is_zero%(m)s(z) ((z)==0)
    #define __Pyx_c_conj%(m)s(z)    (conj%(m)s(z))
    /*#define __Pyx_c_abs%(m)s(z)     (cabs%(m)s(z))*/
 #endif
#else
    static INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
    static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
    static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
    static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
    static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
    static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
    static INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
    static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
    /*static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
#endif
""",
impl="""
#if CYTHON_CCOMPLEX
#else
    static INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
       return (a.real == b.real) && (a.imag == b.imag);
    }
    static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
1156 1157 1158 1159 1160
        %(type)s z;
        z.real = a.real + b.real;
        z.imag = a.imag + b.imag;
        return z;
    }
1161
    static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
1162 1163 1164 1165 1166
        %(type)s z;
        z.real = a.real - b.real;
        z.imag = a.imag - b.imag;
        return z;
    }
1167
    static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
1168 1169 1170 1171 1172
        %(type)s z;
        z.real = a.real * b.real - a.imag * b.imag;
        z.imag = a.real * b.imag + a.imag * b.real;
        return z;
    }
1173
    static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
1174
        %(type)s z;
1175
        %(real_type)s denom = b.real * b.real + b.imag * b.imag;
1176 1177 1178 1179
        z.real = (a.real * b.real + a.imag * b.imag) / denom;
        z.imag = (a.imag * b.real - a.real * b.imag) / denom;
        return z;
    }
1180
    static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
1181 1182 1183 1184 1185
        %(type)s z;
        z.real = -a.real;
        z.imag = -a.imag;
        return z;
    }
1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
    static INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
       return (a.real == 0) && (a.imag == 0);
    }
    static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
        %(type)s z;
        z.real =  a.real;
        z.imag = -a.imag;
        return z;
    }
/*
    static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
#if HAVE_HYPOT
        return hypot%(m)s(z.real, z.imag);
#else
        return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
#endif
    }
*/
1204
#endif
1205
""")
1206

William Stein's avatar
William Stein committed
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220

class CArrayType(CType):
    #  base_type     CType              Element type
    #  size          integer or None    Number of elements
    
    is_array = 1
    
    def __init__(self, base_type, size):
        self.base_type = base_type
        self.size = size
        if base_type is c_char_type:
            self.is_string = 1
    
    def __repr__(self):
1221
        return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
William Stein's avatar
William Stein committed
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
    
    def same_as_resolved_type(self, other_type):
        return ((other_type.is_array and
            self.base_type.same_as(other_type.base_type))
                or other_type is error_type)
    
    def assignable_from_resolved_type(self, src_type):
        # Can't assign to a variable of an array type
        return 0
    
    def element_ptr_type(self):
        return c_ptr_type(self.base_type)

    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        if self.size is not None:
            dimension_code = self.size
        else:
            dimension_code = ""
1241 1242
        if entity_code.startswith("*"):
            entity_code = "(%s)" % entity_code
William Stein's avatar
William Stein committed
1243
        return self.base_type.declaration_code(
1244
            "%s[%s]" % (entity_code, dimension_code),
William Stein's avatar
William Stein committed
1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257
            for_display, dll_linkage, pyrex)
    
    def as_argument_type(self):
        return c_ptr_type(self.base_type)
    
    def is_complete(self):
        return self.size is not None


class CPtrType(CType):
    #  base_type     CType    Referenced type
    
    is_ptr = 1
1258
    default_value = "0"
William Stein's avatar
William Stein committed
1259 1260 1261 1262 1263
    
    def __init__(self, base_type):
        self.base_type = base_type
    
    def __repr__(self):
1264
        return "<CPtrType %s>" % repr(self.base_type)
William Stein's avatar
William Stein committed
1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
    
    def same_as_resolved_type(self, other_type):
        return ((other_type.is_ptr and
            self.base_type.same_as(other_type.base_type))
                or other_type is error_type)
    
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        #print "CPtrType.declaration_code: pointer to", self.base_type ###
        return self.base_type.declaration_code(
1275
            "*%s" % entity_code,
William Stein's avatar
William Stein committed
1276 1277 1278 1279 1280
            for_display, dll_linkage, pyrex)
    
    def assignable_from_resolved_type(self, other_type):
        if other_type is error_type:
            return 1
1281
        if other_type.is_null_ptr:
William Stein's avatar
William Stein committed
1282
            return 1
1283 1284 1285 1286 1287 1288 1289 1290
        if self.base_type.is_cfunction:
            if other_type.is_ptr:
                other_type = other_type.base_type.resolve()
            if other_type.is_cfunction:
                return self.base_type.pointer_assignable_from_resolved_type(other_type)
            else:
                return 0
        if other_type.is_array or other_type.is_ptr:
1291
            return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
1292
        return 0
William Stein's avatar
William Stein committed
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304


class CNullPtrType(CPtrType):

    is_null_ptr = 1
    

class CFuncType(CType):
    #  return_type      CType
    #  args             [CFuncTypeArg]
    #  has_varargs      boolean
    #  exception_value  string
1305 1306 1307 1308
    #  exception_check  boolean    True if PyErr_Occurred check needed
    #  calling_convention  string  Function calling convention
    #  nogil            boolean    Can be called without gil
    #  with_gil         boolean    Acquire gil around function body
William Stein's avatar
William Stein committed
1309 1310
    
    is_cfunction = 1
1311
    original_sig = None
William Stein's avatar
William Stein committed
1312
    
1313 1314
    def __init__(self, return_type, args, has_varargs = 0,
            exception_value = None, exception_check = 0, calling_convention = "",
1315
            nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
William Stein's avatar
William Stein committed
1316 1317 1318
        self.return_type = return_type
        self.args = args
        self.has_varargs = has_varargs
1319
        self.optional_arg_count = optional_arg_count
William Stein's avatar
William Stein committed
1320 1321
        self.exception_value = exception_value
        self.exception_check = exception_check
1322 1323
        self.calling_convention = calling_convention
        self.nogil = nogil
1324
        self.with_gil = with_gil
1325
        self.is_overridable = is_overridable
William Stein's avatar
William Stein committed
1326 1327 1328 1329 1330
    
    def __repr__(self):
        arg_reprs = map(repr, self.args)
        if self.has_varargs:
            arg_reprs.append("...")
1331 1332 1333 1334 1335 1336 1337
        if self.exception_value:
            except_clause = " %r" % self.exception_value
        else:
            except_clause = ""
        if self.exception_check:
            except_clause += "?"
        return "<CFuncType %s %s[%s]%s>" % (
William Stein's avatar
William Stein committed
1338
            repr(self.return_type),
1339
            self.calling_convention_prefix(),
1340 1341
            ",".join(arg_reprs),
            except_clause)
William Stein's avatar
William Stein committed
1342
    
1343 1344 1345 1346 1347 1348 1349
    def calling_convention_prefix(self):
        cc = self.calling_convention
        if cc:
            return cc + " "
        else:
            return ""
    
William Stein's avatar
William Stein committed
1350 1351 1352 1353
    def same_c_signature_as(self, other_type, as_cmethod = 0):
        return self.same_c_signature_as_resolved_type(
            other_type.resolve(), as_cmethod)

1354
    def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
1355
        #print "CFuncType.same_c_signature_as_resolved_type:", \
Robert Bradshaw's avatar
Robert Bradshaw committed
1356
        #    self, other_type, "as_cmethod =", as_cmethod ###
William Stein's avatar
William Stein committed
1357 1358 1359 1360
        if other_type is error_type:
            return 1
        if not other_type.is_cfunction:
            return 0
1361
        if self.is_overridable != other_type.is_overridable:
1362
            return 0
William Stein's avatar
William Stein committed
1363
        nargs = len(self.args)
Stefan Behnel's avatar
Stefan Behnel committed
1364
        if nargs != len(other_type.args):
William Stein's avatar
William Stein committed
1365 1366 1367 1368 1369 1370 1371 1372
            return 0
        # When comparing C method signatures, the first argument
        # is exempt from compatibility checking (the proper check
        # is performed elsewhere).
        for i in range(as_cmethod, nargs):
            if not self.args[i].type.same_as(
                other_type.args[i].type):
                    return 0
Stefan Behnel's avatar
Stefan Behnel committed
1373
        if self.has_varargs != other_type.has_varargs:
William Stein's avatar
William Stein committed
1374
            return 0
Stefan Behnel's avatar
Stefan Behnel committed
1375
        if self.optional_arg_count != other_type.optional_arg_count:
1376
            return 0
William Stein's avatar
William Stein committed
1377 1378
        if not self.return_type.same_as(other_type.return_type):
            return 0
1379 1380
        if not self.same_calling_convention_as(other_type):
            return 0
William Stein's avatar
William Stein committed
1381
        return 1
1382

1383 1384 1385 1386 1387
    def compatible_signature_with(self, other_type, as_cmethod = 0):
        return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
    
    def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
        #print "CFuncType.same_c_signature_as_resolved_type:", \
Robert Bradshaw's avatar
Robert Bradshaw committed
1388
        #    self, other_type, "as_cmethod =", as_cmethod ###
1389 1390 1391 1392
        if other_type is error_type:
            return 1
        if not other_type.is_cfunction:
            return 0
1393
        if not self.is_overridable and other_type.is_overridable:
1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408
            return 0
        nargs = len(self.args)
        if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
            return 0
        if self.optional_arg_count < other_type.optional_arg_count:
            return 0
        # When comparing C method signatures, the first argument
        # is exempt from compatibility checking (the proper check
        # is performed elsewhere).
        for i in range(as_cmethod, len(other_type.args)):
            if not self.args[i].type.same_as(
                other_type.args[i].type):
                    return 0
        if self.has_varargs != other_type.has_varargs:
            return 0
1409
        if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1410 1411 1412
            return 0
        if not self.same_calling_convention_as(other_type):
            return 0
Robert Bradshaw's avatar
Robert Bradshaw committed
1413 1414
        if self.nogil != other_type.nogil:
            return 0
1415
        self.original_sig = other_type.original_sig or other_type
1416 1417 1418 1419 1420
        if as_cmethod:
            self.args[0] = other_type.args[0]
        return 1
        
        
1421 1422 1423 1424 1425 1426 1427 1428 1429
    def narrower_c_signature_than(self, other_type, as_cmethod = 0):
        return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
        
    def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
        if other_type is error_type:
            return 1
        if not other_type.is_cfunction:
            return 0
        nargs = len(self.args)
Stefan Behnel's avatar
Stefan Behnel committed
1430
        if nargs != len(other_type.args):
1431 1432 1433 1434 1435 1436 1437
            return 0
        for i in range(as_cmethod, nargs):
            if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
                return 0
            else:
                self.args[i].needs_type_test = other_type.args[i].needs_type_test \
                        or not self.args[i].type.same_as(other_type.args[i].type)
Stefan Behnel's avatar
Stefan Behnel committed
1438
        if self.has_varargs != other_type.has_varargs:
1439
            return 0
Stefan Behnel's avatar
Stefan Behnel committed
1440
        if self.optional_arg_count != other_type.optional_arg_count:
1441
            return 0
1442 1443 1444 1445
        if not self.return_type.subtype_of_resolved_type(other_type.return_type):
            return 0
        return 1

1446
    def same_calling_convention_as(self, other):
1447 1448 1449 1450 1451 1452 1453 1454 1455
        ## XXX Under discussion ...
        ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
        ## cs1 = self.calling_convention
        ## cs2 = other.calling_convention
        ## if (cs1 in callspec_words or
        ##     cs2 in callspec_words):
        ##     return cs1 == cs2
        ## else:
        ##     return True
1456 1457 1458
        sc1 = self.calling_convention == '__stdcall'
        sc2 = other.calling_convention == '__stdcall'
        return sc1 == sc2
William Stein's avatar
William Stein committed
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469
    
    def same_exception_signature_as(self, other_type):
        return self.same_exception_signature_as_resolved_type(
            other_type.resolve())

    def same_exception_signature_as_resolved_type(self, other_type):
        return self.exception_value == other_type.exception_value \
            and self.exception_check == other_type.exception_check
    
    def same_as_resolved_type(self, other_type, as_cmethod = 0):
        return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
1470 1471 1472 1473 1474 1475 1476
            and self.same_exception_signature_as_resolved_type(other_type) \
            and self.nogil == other_type.nogil
    
    def pointer_assignable_from_resolved_type(self, other_type):
        return self.same_c_signature_as_resolved_type(other_type) \
            and self.same_exception_signature_as_resolved_type(other_type) \
            and not (self.nogil and not other_type.nogil)
William Stein's avatar
William Stein committed
1477 1478
    
    def declaration_code(self, entity_code, 
1479 1480
                         for_display = 0, dll_linkage = None, pyrex = 0,
                         with_calling_convention = 1):
William Stein's avatar
William Stein committed
1481
        arg_decl_list = []
1482
        for arg in self.args[:len(self.args)-self.optional_arg_count]:
William Stein's avatar
William Stein committed
1483 1484
            arg_decl_list.append(
                arg.type.declaration_code("", for_display, pyrex = pyrex))
1485 1486
        if self.is_overridable:
            arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
1487
        if self.optional_arg_count:
1488
            arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
William Stein's avatar
William Stein committed
1489 1490
        if self.has_varargs:
            arg_decl_list.append("...")
1491
        arg_decl_code = ", ".join(arg_decl_list)
William Stein's avatar
William Stein committed
1492 1493
        if not arg_decl_code and not pyrex:
            arg_decl_code = "void"
1494
        trailer = ""
1495
        if (pyrex or for_display) and not self.return_type.is_pyobject:
William Stein's avatar
William Stein committed
1496
            if self.exception_value and self.exception_check:
1497
                trailer = " except? %s" % self.exception_value
William Stein's avatar
William Stein committed
1498
            elif self.exception_value:
1499
                trailer = " except %s" % self.exception_value
Felix Wu's avatar
Felix Wu committed
1500
            elif self.exception_check == '+':
1501
                trailer = " except +"
Felix Wu's avatar
Felix Wu committed
1502
            else:
1503 1504 1505
                " except *" # ignored
            if self.nogil:
                trailer += " nogil"
1506 1507 1508 1509 1510 1511 1512
        if not with_calling_convention:
            cc = ''
        else:
            cc = self.calling_convention_prefix()
            if (not entity_code and cc) or entity_code.startswith("*"):
                entity_code = "(%s%s)" % (cc, entity_code)
                cc = ""
William Stein's avatar
William Stein committed
1513
        return self.return_type.declaration_code(
1514
            "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
William Stein's avatar
William Stein committed
1515
            for_display, dll_linkage, pyrex)
Robert Bradshaw's avatar
Robert Bradshaw committed
1516
    
1517 1518 1519
    def function_header_code(self, func_name, arg_code):
        return "%s%s(%s)" % (self.calling_convention_prefix(),
            func_name, arg_code)
William Stein's avatar
William Stein committed
1520

1521 1522 1523 1524
    def signature_string(self):
        s = self.declaration_code("")
        return s

1525 1526 1527 1528
    def signature_cast_string(self):
        s = self.declaration_code("(*)", with_calling_convention=False)
        return '(%s)' % s

William Stein's avatar
William Stein committed
1529

1530
class CFuncTypeArg(object):
William Stein's avatar
William Stein committed
1531 1532 1533 1534 1535
    #  name       string
    #  cname      string
    #  type       PyrexType
    #  pos        source file position
    
1536
    def __init__(self, name, type, pos, cname=None):
William Stein's avatar
William Stein committed
1537
        self.name = name
1538 1539 1540 1541
        if cname is not None:
            self.cname = cname
        else:
            self.cname = Naming.var_prefix + name
William Stein's avatar
William Stein committed
1542 1543
        self.type = type
        self.pos = pos
1544 1545
        self.not_none = False
        self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
William Stein's avatar
William Stein committed
1546 1547 1548 1549 1550 1551 1552
    
    def __repr__(self):
        return "%s:%s" % (self.name, repr(self.type))
    
    def declaration_code(self, for_display = 0):
        return self.type.declaration_code(self.cname, for_display)

Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590
class StructUtilityCode(object):
    def __init__(self, type, forward_decl):
        self.type = type
        self.header = "static PyObject* %s(%s)" % (type.to_py_function, type.declaration_code('s'))
        self.forward_decl = forward_decl

    def __eq__(self, other):
        return isinstance(other, StructUtilityCode) and self.header == other.header
    def __hash__(self):
        return hash(self.header)
    
    def put_code(self, output):
        code = output['utility_code_def']
        proto = output['utility_code_proto']
        
        code.putln("%s {" % self.header)
        code.putln("PyObject* res;")
        code.putln("PyObject* member;")
        code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
        for member in self.type.scope.var_entries:
            nameconst_cname = code.get_py_string_const(member.name, identifier=True)
            code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
                member.type.to_py_function, member.cname))
            code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % nameconst_cname)
            code.putln("Py_DECREF(member);")
        code.putln("return res;")
        code.putln("bad:")
        code.putln("Py_XDECREF(member);")
        code.putln("Py_DECREF(res);")
        code.putln("return NULL;")
        code.putln("}")

        # This is a bit of a hack, we need a forward declaration
        # due to the way things are ordered in the module...
        if self.forward_decl:
            proto.putln(self.type.declaration_code('') + ';')
        proto.putln(self.header + ";")
        
William Stein's avatar
William Stein committed
1591 1592 1593 1594 1595 1596 1597

class CStructOrUnionType(CType):
    #  name          string
    #  cname         string
    #  kind          string              "struct" or "union"
    #  scope         StructOrUnionScope, or None if incomplete
    #  typedef_flag  boolean
1598
    #  packed        boolean
William Stein's avatar
William Stein committed
1599
    
1600 1601
    # entry          Entry
    
William Stein's avatar
William Stein committed
1602 1603 1604
    is_struct_or_union = 1
    has_attributes = 1
    
1605
    def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
William Stein's avatar
William Stein committed
1606 1607 1608 1609 1610
        self.name = name
        self.cname = cname
        self.kind = kind
        self.scope = scope
        self.typedef_flag = typedef_flag
Robert Bradshaw's avatar
Robert Bradshaw committed
1611
        self.is_struct = kind == 'struct'
Robert Bradshaw's avatar
Robert Bradshaw committed
1612 1613 1614 1615
        if self.is_struct:
            self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
        self.exception_check = True
        self._convert_code = None
1616
        self.packed = packed
Robert Bradshaw's avatar
Robert Bradshaw committed
1617
        
1618
    def create_to_py_utility_code(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
1619 1620
        if env.outer_scope is None:
            return False
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1621 1622 1623

        if self._convert_code is False: return # tri-state-ish

Robert Bradshaw's avatar
Robert Bradshaw committed
1624 1625
        if self._convert_code is None:
            for member in self.scope.var_entries:
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1626
                if not member.type.to_py_function or not member.type.create_to_py_utility_code(env):
Robert Bradshaw's avatar
Robert Bradshaw committed
1627
                    self.to_py_function = None
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1628
                    self._convert_code = False
Robert Bradshaw's avatar
Robert Bradshaw committed
1629
                    return False
1630
            forward_decl = (self.entry.visibility != 'extern')
Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
1631
            self._convert_code = StructUtilityCode(self, forward_decl)
Robert Bradshaw's avatar
Robert Bradshaw committed
1632 1633 1634
        
        env.use_utility_code(self._convert_code)
        return True
William Stein's avatar
William Stein committed
1635 1636
        
    def __repr__(self):
1637 1638
        return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
            ("", " typedef")[self.typedef_flag])
William Stein's avatar
William Stein committed
1639 1640 1641 1642

    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        if pyrex:
1643
            return self.base_declaration_code(self.name, entity_code)
William Stein's avatar
William Stein committed
1644 1645 1646 1647 1648 1649 1650
        else:
            if for_display:
                base = self.name
            elif self.typedef_flag:
                base = self.cname
            else:
                base = "%s %s" % (self.kind, self.cname)
1651
            return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
William Stein's avatar
William Stein committed
1652

1653
    def __eq__(self, other):
1654
        try:
Stefan Behnel's avatar
Stefan Behnel committed
1655 1656
            return (isinstance(other, CStructOrUnionType) and
                    self.name == other.name)
1657
        except AttributeError:
1658 1659 1660 1661 1662 1663 1664 1665 1666
            return False

    def __lt__(self, other):
        try:
            return self.name < other.name
        except AttributeError:
            # this is arbitrary, but it makes sure we always have
            # *some* kind of order
            return False
1667

Stefan Behnel's avatar
Stefan Behnel committed
1668
    def __hash__(self):
1669
        return hash(self.cname) ^ hash(self.kind)
Stefan Behnel's avatar
Stefan Behnel committed
1670

William Stein's avatar
William Stein committed
1671 1672 1673 1674 1675 1676
    def is_complete(self):
        return self.scope is not None
    
    def attributes_known(self):
        return self.is_complete()

1677
    def can_be_complex(self):
1678
        # Does the struct consist of exactly two identical floats?
1679
        fields = self.scope.var_entries
1680 1681 1682 1683 1684
        if len(fields) != 2: return False
        a, b = fields
        return (a.type.is_float and b.type.is_float and
                a.type.declaration_code("") ==
                b.type.declaration_code(""))
1685

1686 1687 1688 1689
    def struct_nesting_depth(self):
        child_depths = [x.type.struct_nesting_depth()
                        for x in self.scope.var_entries]
        return max(child_depths) + 1
William Stein's avatar
William Stein committed
1690

1691
class CEnumType(CType):
William Stein's avatar
William Stein committed
1692 1693 1694
    #  name           string
    #  cname          string or None
    #  typedef_flag   boolean
1695

William Stein's avatar
William Stein committed
1696
    is_enum = 1
1697 1698
    signed = 1
    rank = -1 # Ranks below any integer type
1699 1700
    to_py_function = "PyInt_FromLong"
    from_py_function = "PyInt_AsLong"
William Stein's avatar
William Stein committed
1701 1702 1703 1704 1705 1706 1707

    def __init__(self, name, cname, typedef_flag):
        self.name = name
        self.cname = cname
        self.values = []
        self.typedef_flag = typedef_flag
    
1708 1709 1710
    def __str__(self):
        return self.name
    
William Stein's avatar
William Stein committed
1711
    def __repr__(self):
1712 1713
        return "<CEnumType %s %s%s>" % (self.name, self.cname,
            ("", " typedef")[self.typedef_flag])
William Stein's avatar
William Stein committed
1714 1715 1716 1717
    
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        if pyrex:
1718
            return self.base_declaration_code(self.cname, entity_code)
William Stein's avatar
William Stein committed
1719 1720 1721 1722 1723
        else:
            if self.typedef_flag:
                base = self.cname
            else:
                base = "enum %s" % self.cname
1724
            return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
William Stein's avatar
William Stein committed
1725 1726


1727
class CStringType(object):
William Stein's avatar
William Stein committed
1728 1729 1730
    #  Mixin class for C string types.

    is_string = 1
1731
    is_unicode = 0
William Stein's avatar
William Stein committed
1732
    
1733 1734
    to_py_function = "__Pyx_PyBytes_FromString"
    from_py_function = "__Pyx_PyBytes_AsString"
1735
    exception_value = "NULL"
William Stein's avatar
William Stein committed
1736 1737

    def literal_code(self, value):
1738
        assert isinstance(value, str)
1739
        return '"%s"' % StringEncoding.escape_byte_string(value)
1740 1741


1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753
class CUTF8CharArrayType(CStringType, CArrayType):
    #  C 'char []' type.
    
    pymemberdef_typecode = "T_STRING_INPLACE"
    is_unicode = 1
    
    to_py_function = "PyUnicode_DecodeUTF8"
    exception_value = "NULL"
    
    def __init__(self, size):
        CArrayType.__init__(self, c_char_type, size)

William Stein's avatar
William Stein committed
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771
class CCharArrayType(CStringType, CArrayType):
    #  C 'char []' type.
    
    pymemberdef_typecode = "T_STRING_INPLACE"
    
    def __init__(self, size):
        CArrayType.__init__(self, c_char_type, size)
    

class CCharPtrType(CStringType, CPtrType):
    # C 'char *' type.
    
    pymemberdef_typecode = "T_STRING"
    
    def __init__(self):
        CPtrType.__init__(self, c_char_type)


1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783
class CUCharPtrType(CStringType, CPtrType):
    # C 'unsigned char *' type.
    
    pymemberdef_typecode = "T_STRING"
    
    to_py_function = "__Pyx_PyBytes_FromUString"
    from_py_function = "__Pyx_PyBytes_AsUString"

    def __init__(self):
        CPtrType.__init__(self, c_uchar_type)


Robert Bradshaw's avatar
Robert Bradshaw committed
1784 1785
class UnspecifiedType(PyrexType):
    # Used as a placeholder until the type can be determined.
Robert Bradshaw's avatar
Robert Bradshaw committed
1786 1787
    
    is_unspecified = 1
Robert Bradshaw's avatar
Robert Bradshaw committed
1788 1789 1790 1791 1792 1793 1794 1795 1796
        
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        return "<unspecified>"
    
    def same_as_resolved_type(self, other_type):
        return False
        

William Stein's avatar
William Stein committed
1797 1798 1799 1800 1801
class ErrorType(PyrexType):
    # Used to prevent propagation of error messages.
    
    is_error = 1
    exception_value = "0"
Robert Bradshaw's avatar
Robert Bradshaw committed
1802
    exception_check    = 0
William Stein's avatar
William Stein committed
1803 1804 1805
    to_py_function = "dummy"
    from_py_function = "dummy"
    
1806 1807 1808 1809
    def create_to_py_utility_code(self, env):
        return True
    
    def create_from_py_utility_code(self, env):
Robert Bradshaw's avatar
Robert Bradshaw committed
1810 1811
        return True
    
William Stein's avatar
William Stein committed
1812 1813 1814 1815 1816 1817
    def declaration_code(self, entity_code, 
            for_display = 0, dll_linkage = None, pyrex = 0):
        return "<error>"
    
    def same_as_resolved_type(self, other_type):
        return 1
1818 1819 1820
        
    def error_condition(self, result_code):
        return "dummy"
William Stein's avatar
William Stein committed
1821 1822


1823 1824 1825 1826 1827
rank_to_type_name = (
    "char",         # 0
    "short",        # 1
    "int",          # 2
    "long",         # 3
1828 1829 1830
    "Py_ssize_t",   # 4
    "size_t",       # 5
    "PY_LONG_LONG", # 6
1831 1832 1833
    "float",        # 7
    "double",       # 8
    "long double",  # 9
1834 1835
)

William Stein's avatar
William Stein committed
1836 1837 1838 1839 1840 1841
py_object_type = PyObjectType()

c_void_type =         CVoidType()
c_void_ptr_type =     CPtrType(c_void_type)
c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)

1842 1843 1844 1845
c_uchar_type =       CIntType(0, 0, "T_UBYTE")
c_ushort_type =      CIntType(1, 0, "T_USHORT")
c_uint_type =        CUIntType(2, 0, "T_UINT")
c_ulong_type =       CULongType(3, 0, "T_ULONG")
1846
c_ulonglong_type =   CULongLongType(6, 0, "T_ULONGLONG")
1847 1848 1849 1850

c_char_type =        CIntType(0, 1, "T_CHAR")
c_short_type =       CIntType(1, 1, "T_SHORT")
c_int_type =         CIntType(2, 1, "T_INT")
1851
c_long_type =        CLongType(3, 1, "T_LONG")
1852
c_longlong_type =    CLongLongType(6, 1, "T_LONGLONG")
1853
c_bint_type =        CBIntType(2, 1, "T_INT")
1854

1855 1856 1857
c_schar_type =       CIntType(0, 2, "T_CHAR")
c_sshort_type =      CIntType(1, 2, "T_SHORT")
c_sint_type =        CIntType(2, 2, "T_INT")
1858
c_slong_type =       CLongType(3, 2, "T_LONG")
1859
c_slonglong_type =   CLongLongType(6, 2, "T_LONGLONG")
1860

1861 1862
c_py_ssize_t_type =  CPySSizeTType(4, 2, "T_PYSSIZET")
c_size_t_type =      CSizeTType(5, 0, "T_SIZET")
1863

1864
c_float_type =       CFloatType(7, "T_FLOAT", math_h_modifier='f')
1865
c_double_type =      CFloatType(8, "T_DOUBLE")
1866
c_longdouble_type =  CFloatType(9, math_h_modifier='l')
William Stein's avatar
William Stein committed
1867

1868 1869
c_double_complex_type = CComplexType(c_double_type)

William Stein's avatar
William Stein committed
1870 1871 1872
c_null_ptr_type =     CNullPtrType(c_void_type)
c_char_array_type =   CCharArrayType(None)
c_char_ptr_type =     CCharPtrType()
1873
c_uchar_ptr_type =    CUCharPtrType()
1874
c_utf8_char_array_type = CUTF8CharArrayType(None)
William Stein's avatar
William Stein committed
1875 1876
c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
c_int_ptr_type =      CPtrType(c_int_type)
1877 1878
c_py_ssize_t_ptr_type =  CPtrType(c_py_ssize_t_type)
c_size_t_ptr_type =  CPtrType(c_size_t_type)
William Stein's avatar
William Stein committed
1879 1880 1881

c_returncode_type =   CIntType(2, 1, "T_INT", is_returncode = 1)

1882 1883
c_anon_enum_type =    CAnonEnumType(-1, 1)

1884
# the Py_buffer type is defined in Builtin.py
1885 1886
c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1887

William Stein's avatar
William Stein committed
1888
error_type =    ErrorType()
Robert Bradshaw's avatar
Robert Bradshaw committed
1889
unspecified_type = UnspecifiedType()
William Stein's avatar
William Stein committed
1890 1891 1892

sign_and_rank_to_type = {
    #(signed, rank)
1893 1894 1895
    (0, 0): c_uchar_type,
    (0, 1): c_ushort_type,
    (0, 2): c_uint_type,
1896
    (0, 3): c_ulong_type,
1897 1898
    (0, 6): c_ulonglong_type,

1899 1900 1901
    (1, 0): c_char_type,
    (1, 1): c_short_type,
    (1, 2): c_int_type,
William Stein's avatar
William Stein committed
1902
    (1, 3): c_long_type,
1903
    (1, 6): c_longlong_type,
1904

1905 1906 1907
    (2, 0): c_schar_type,
    (2, 1): c_sshort_type,
    (2, 2): c_sint_type,
1908
    (2, 3): c_slong_type,
1909
    (2, 6): c_slonglong_type,
1910

1911 1912 1913 1914 1915 1916
    (0, 4): c_py_ssize_t_type,
    (1, 4): c_py_ssize_t_type,
    (2, 4): c_py_ssize_t_type,
    (0, 5): c_size_t_type,
    (1, 5): c_size_t_type,
    (2, 5): c_size_t_type,
1917

1918
    (1, 7): c_float_type,
1919 1920
    (1, 8): c_double_type,
    (1, 9): c_longdouble_type,
1921
# In case we're mixing unsigned ints and floats...
1922
    (0, 7): c_float_type,
1923 1924
    (0, 8): c_double_type,
    (0, 9): c_longdouble_type,
William Stein's avatar
William Stein committed
1925 1926 1927 1928
}

modifiers_and_name_to_type = {
    #(signed, longness, name)
1929 1930 1931
    (0, 0, "char"): c_uchar_type,
    (0, -1, "int"): c_ushort_type,
    (0, 0, "int"): c_uint_type,
1932 1933
    (0, 1, "int"): c_ulong_type,
    (0, 2, "int"): c_ulonglong_type,
William Stein's avatar
William Stein committed
1934
    (1, 0, "void"): c_void_type,
1935 1936 1937
    (1, 0, "char"): c_char_type,
    (1, -1, "int"): c_short_type,
    (1, 0, "int"): c_int_type,
William Stein's avatar
William Stein committed
1938 1939
    (1, 1, "int"): c_long_type,
    (1, 2, "int"): c_longlong_type,
1940
    (1, 0, "float"): c_float_type,
William Stein's avatar
William Stein committed
1941 1942 1943
    (1, 0, "double"): c_double_type,
    (1, 1, "double"): c_longdouble_type,
    (1, 0, "object"): py_object_type,
1944 1945 1946 1947
    (1, 0, "bint"): c_bint_type,
    (2, 0, "char"): c_schar_type,
    (2, -1, "int"): c_sshort_type,
    (2, 0, "int"): c_sint_type,
1948 1949
    (2, 1, "int"): c_slong_type,
    (2, 2, "int"): c_slonglong_type,
1950

1951 1952
    (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
    (0, 0, "size_t") : c_size_t_type,
1953

1954
    (1, 0, "long"): c_long_type,
1955
    (1, 0, "short"): c_short_type,
1956
    (1, 0, "longlong"): c_longlong_type,
1957
    (1, 0, "bint"): c_bint_type,
William Stein's avatar
William Stein committed
1958 1959 1960 1961 1962
}

def widest_numeric_type(type1, type2):
    # Given two numeric types, return the narrowest type
    # encompassing both of them.
1963 1964 1965
    if type1 == type2:
        return type1
    if type1.is_complex:
1966 1967 1968 1969
        if type2.is_complex:
            return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
        else:
            return CComplexType(widest_numeric_type(type1.real_type, type2))
1970 1971
    elif type2.is_complex:
        return CComplexType(widest_numeric_type(type1, type2.real_type))
1972
    if type1.is_enum and type2.is_enum:
1973 1974 1975 1976 1977 1978 1979 1980
        return c_int_type
    elif type1 is type2:
        return type1
    elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
        if type2.rank > type1.rank:
            return type2
        else:
            return type1
1981
    else:
1982
        return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1983
    return widest_type
William Stein's avatar
William Stein committed
1984

Robert Bradshaw's avatar
Robert Bradshaw committed
1985 1986
def spanning_type(type1, type2):
    # Return a type assignable from both type1 and type2.
Robert Bradshaw's avatar
Robert Bradshaw committed
1987 1988 1989
    if type1 is py_object_type or type2 is py_object_type:
        return py_object_type
    elif type1 == type2:
Robert Bradshaw's avatar
Robert Bradshaw committed
1990 1991 1992
        return type1
    elif type1.is_numeric and type2.is_numeric:
        return widest_numeric_type(type1, type2)
Robert Bradshaw's avatar
Robert Bradshaw committed
1993 1994
    elif type1.is_pyobject ^ type2.is_pyobject:
        return py_object_type
Robert Bradshaw's avatar
Robert Bradshaw committed
1995 1996 1997 1998 1999 2000 2001
    elif type1.assignable_from(type2):
        return type1
    elif type2.assignable_from(type1):
        return type2
    else:
        return py_object_type
    
William Stein's avatar
William Stein committed
2002 2003 2004 2005
def simple_c_type(signed, longness, name):
    # Find type descriptor for simple type given name and modifiers.
    # Returns None if arguments don't make sense.
    return modifiers_and_name_to_type.get((signed, longness, name))
2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020
    
def parse_basic_type(name):
    base = None
    if name.startswith('p_'):
        base = parse_basic_type(name[2:])
    elif name.startswith('p'):
        base = parse_basic_type(name[1:])
    elif name.endswith('*'):
        base = parse_basic_type(name[:-1])
    if base:
        return CPtrType(base)
    elif name.startswith('u'):
        return simple_c_type(0, 0, name[1:])
    else:
        return simple_c_type(1, 0, name)
William Stein's avatar
William Stein committed
2021 2022 2023 2024 2025

def c_array_type(base_type, size):
    # Construct a C array type.
    if base_type is c_char_type:
        return CCharArrayType(size)
2026 2027
    elif base_type is error_type:
        return error_type
William Stein's avatar
William Stein committed
2028 2029 2030 2031 2032 2033 2034
    else:
        return CArrayType(base_type, size)

def c_ptr_type(base_type):
    # Construct a C pointer type.
    if base_type is c_char_type:
        return c_char_ptr_type
2035 2036
    elif base_type is c_uchar_type:
        return c_uchar_ptr_type
2037 2038
    elif base_type is error_type:
        return error_type
William Stein's avatar
William Stein committed
2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
    else:
        return CPtrType(base_type)

def same_type(type1, type2):
    return type1.same_as(type2)
    
def assignable_from(type1, type2):
    return type1.assignable_from(type2)

def typecast(to_type, from_type, expr_code):
    #  Return expr_code cast to a C type which can be
    #  assigned to to_type, assuming its existing C type
    #  is from_type.
    if to_type is from_type or \
        (not to_type.is_pyobject and assignable_from(to_type, from_type)):
            return expr_code
    else:
        #print "typecast: to", to_type, "from", from_type ###
        return to_type.cast_code(expr_code)
2058 2059 2060 2061 2062


type_conversion_predeclarations = """
/* Type Conversion Predeclarations */

Stefan Behnel's avatar
Stefan Behnel committed
2063
#if PY_MAJOR_VERSION < 3
Robert Bradshaw's avatar
Robert Bradshaw committed
2064 2065 2066
#define __Pyx_PyBytes_FromString          PyString_FromString
#define __Pyx_PyBytes_FromStringAndSize   PyString_FromStringAndSize
#define __Pyx_PyBytes_AsString            PyString_AsString
2067
#else
Robert Bradshaw's avatar
Robert Bradshaw committed
2068 2069 2070
#define __Pyx_PyBytes_FromString          PyBytes_FromString
#define __Pyx_PyBytes_FromStringAndSize   PyBytes_FromStringAndSize
#define __Pyx_PyBytes_AsString            PyBytes_AsString
2071 2072
#endif

2073 2074 2075
#define __Pyx_PyBytes_FromUString(s)      __Pyx_PyBytes_FromString((char*)s)
#define __Pyx_PyBytes_AsUString(s)        ((unsigned char*) __Pyx_PyBytes_AsString(s))

2076
#define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
2077 2078
static INLINE int __Pyx_PyObject_IsTrue(PyObject*);
static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
2079

2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094
#if !defined(T_PYSSIZET)
#if PY_VERSION_HEX < 0x02050000
#define T_PYSSIZET T_INT
#elif !defined(T_LONGLONG)
#define T_PYSSIZET \\
        ((sizeof(Py_ssize_t) == sizeof(int))  ? T_INT  : \\
        ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
#else
#define T_PYSSIZET \\
        ((sizeof(Py_ssize_t) == sizeof(int))          ? T_INT      : \\
        ((sizeof(Py_ssize_t) == sizeof(long))         ? T_LONG     : \\
        ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
#endif
#endif

Dag Sverre Seljebotn's avatar
Dag Sverre Seljebotn committed
2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128

#if !defined(T_ULONGLONG)
#define __Pyx_T_UNSIGNED_INT(x) \\
        ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
        ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
        ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
        ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : -1))))
#else
#define __Pyx_T_UNSIGNED_INT(x) \\
        ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
        ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
        ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
        ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : \\
        ((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
#endif
#if !defined(T_LONGLONG)
#define __Pyx_T_SIGNED_INT(x) \\
        ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
        ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
        ((sizeof(x) == sizeof(int))   ? T_INT : \\
        ((sizeof(x) == sizeof(long))  ? T_LONG : -1))))
#else
#define __Pyx_T_SIGNED_INT(x) \\
        ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
        ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
        ((sizeof(x) == sizeof(int))   ? T_INT : \\
        ((sizeof(x) == sizeof(long))  ? T_LONG : \\
        ((sizeof(x) == sizeof(PY_LONG_LONG))   ? T_LONGLONG : -1)))))
#endif

#define __Pyx_T_FLOATING(x) \\
        ((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
        ((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))

2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141
#if !defined(T_SIZET)
#if !defined(T_ULONGLONG)
#define T_SIZET \\
        ((sizeof(size_t) == sizeof(unsigned int))  ? T_UINT  : \\
        ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
#else
#define T_SIZET \\
        ((sizeof(size_t) == sizeof(unsigned int))          ? T_UINT      : \\
        ((sizeof(size_t) == sizeof(unsigned long))         ? T_ULONG     : \\
        ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
#endif
#endif

2142 2143 2144
static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
2145

2146
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
2147

2148 2149 2150 2151 2152
""" + type_conversion_predeclarations

type_conversion_functions = """
/* Type Conversion Functions */

2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170
static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
   if (x == Py_True) return 1;
   else if ((x == Py_False) | (x == Py_None)) return 0;
   else return PyObject_IsTrue(x);
}

static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
  PyNumberMethods *m;
  const char *name = NULL;
  PyObject *res = NULL;
#if PY_VERSION_HEX < 0x03000000
  if (PyInt_Check(x) || PyLong_Check(x))
#else
  if (PyLong_Check(x))
#endif
    return Py_INCREF(x), x;
  m = Py_TYPE(x)->tp_as_number;
#if PY_VERSION_HEX < 0x03000000
2171
  if (m && m->nb_int) {
2172 2173 2174
    name = "int";
    res = PyNumber_Int(x);
  }
2175 2176 2177 2178
  else if (m && m->nb_long) {
    name = "long";
    res = PyNumber_Long(x);
  }
2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205
#else
  if (m && m->nb_int) {
    name = "int";
    res = PyNumber_Long(x);
  }
#endif
  if (res) {
#if PY_VERSION_HEX < 0x03000000
    if (!PyInt_Check(res) && !PyLong_Check(res)) {
#else
    if (!PyLong_Check(res)) {
#endif
      PyErr_Format(PyExc_TypeError,
                   "__%s__ returned non-%s (type %.200s)",
                   name, name, Py_TYPE(res)->tp_name);
      Py_DECREF(res);
      return NULL;
    }
  }
  else if (!PyErr_Occurred()) {
    PyErr_SetString(PyExc_TypeError,
                    "an integer is required");
  }
  return res;
}

static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
2206 2207 2208 2209 2210 2211 2212 2213
  Py_ssize_t ival;
  PyObject* x = PyNumber_Index(b);
  if (!x) return -1;
  ival = PyInt_AsSsize_t(x);
  Py_DECREF(x);
  return ival;
}

2214
static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
2215
#if PY_VERSION_HEX < 0x02050000
2216
   if (ival <= LONG_MAX)
2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227
       return PyInt_FromLong((long)ival);
   else {
       unsigned char *bytes = (unsigned char *) &ival;
       int one = 1; int little = (int)*(unsigned char*)&one;
       return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
   }
#else
   return PyInt_FromSize_t(ival);
#endif
}

2228 2229
static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
   unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
2230 2231 2232
   if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
       return (size_t)-1;
   } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
2233 2234
       PyErr_SetString(PyExc_OverflowError,
                       "value too large to convert to size_t");
2235 2236
       return (size_t)-1;
   }
2237
   return (size_t)val;
2238 2239 2240
}

""" + type_conversion_functions
2241 2242