Fix bug #252, mangle illegal optional c argument names.
[cython.git] / Cython / Compiler / PyrexTypes.py
1 #
2 #   Pyrex - Types
3 #
4
5 from Code import UtilityCode
6 import StringEncoding
7 import Naming
8 import copy
9
10 class BaseType(object):
11     #
12     #  Base class for all Pyrex types including pseudo-types.
13
14     def cast_code(self, expr_code):
15         return "((%s)%s)" % (self.declaration_code(""), expr_code)
16     
17     def specalization_name(self):
18         return self.declaration_code("").replace(" ", "__")
19     
20     def base_declaration_code(self, base_code, entity_code):
21         if entity_code:
22             return "%s %s" % (base_code, entity_code)
23         else:
24             return base_code
25
26 class PyrexType(BaseType):
27     #
28     #  Base class for all Pyrex types.
29     #
30     #  is_pyobject           boolean     Is a Python object type
31     #  is_extension_type     boolean     Is a Python extension type
32     #  is_numeric            boolean     Is a C numeric type
33     #  is_int                boolean     Is a C integer type
34     #  is_float              boolean     Is a C floating point type
35     #  is_complex            boolean     Is a C complex type
36     #  is_void               boolean     Is the C void type
37     #  is_array              boolean     Is a C array type
38     #  is_ptr                boolean     Is a C pointer type
39     #  is_null_ptr           boolean     Is the type of NULL
40     #  is_cfunction          boolean     Is a C function type
41     #  is_struct_or_union    boolean     Is a C struct or union type
42     #  is_struct             boolean     Is a C struct type
43     #  is_enum               boolean     Is a C enum type
44     #  is_typedef            boolean     Is a typedef type
45     #  is_string             boolean     Is a C char * type
46     #  is_unicode            boolean     Is a UTF-8 encoded C char * type
47     #  is_returncode         boolean     Is used only to signal exceptions
48     #  is_error              boolean     Is the dummy error type
49     #  is_buffer             boolean     Is buffer access type
50     #  has_attributes        boolean     Has C dot-selectable attributes
51     #  default_value         string      Initial value
52     #  pymemberdef_typecode  string      Type code for PyMemberDef struct
53     #
54     #  declaration_code(entity_code, 
55     #      for_display = 0, dll_linkage = None, pyrex = 0)
56     #    Returns a code fragment for the declaration of an entity
57     #    of this type, given a code fragment for the entity.
58     #    * If for_display, this is for reading by a human in an error
59     #      message; otherwise it must be valid C code.
60     #    * If dll_linkage is not None, it must be 'DL_EXPORT' or
61     #      'DL_IMPORT', and will be added to the base type part of
62     #      the declaration.
63     #    * If pyrex = 1, this is for use in a 'cdef extern'
64     #      statement of a Pyrex include file.
65     #
66     #  assignable_from(src_type)
67     #    Tests whether a variable of this type can be
68     #    assigned a value of type src_type.
69     #
70     #  same_as(other_type)
71     #    Tests whether this type represents the same type
72     #    as other_type.
73     #
74     #  as_argument_type():
75     #    Coerces array type into pointer type for use as
76     #    a formal argument type.
77     #
78         
79     is_pyobject = 0
80     is_unspecified = 0
81     is_extension_type = 0
82     is_builtin_type = 0
83     is_numeric = 0
84     is_int = 0
85     is_float = 0
86     is_complex = 0
87     is_void = 0
88     is_array = 0
89     is_ptr = 0
90     is_null_ptr = 0
91     is_cfunction = 0
92     is_struct_or_union = 0
93     is_struct = 0
94     is_enum = 0
95     is_typedef = 0
96     is_string = 0
97     is_unicode = 0
98     is_returncode = 0
99     is_error = 0
100     is_buffer = 0
101     has_attributes = 0
102     default_value = ""
103     pymemberdef_typecode = None
104     
105     def resolve(self):
106         # If a typedef, returns the base type.
107         return self
108     
109     def literal_code(self, value):
110         # Returns a C code fragment representing a literal
111         # value of this type.
112         return str(value)
113     
114     def __str__(self):
115         return self.declaration_code("", for_display = 1).strip()
116     
117     def same_as(self, other_type, **kwds):
118         return self.same_as_resolved_type(other_type.resolve(), **kwds)
119     
120     def same_as_resolved_type(self, other_type):
121         return self == other_type or other_type is error_type
122     
123     def subtype_of(self, other_type):
124         return self.subtype_of_resolved_type(other_type.resolve())
125     
126     def subtype_of_resolved_type(self, other_type):
127         return self.same_as(other_type)
128     
129     def assignable_from(self, src_type):
130         return self.assignable_from_resolved_type(src_type.resolve())
131     
132     def assignable_from_resolved_type(self, src_type):
133         return self.same_as(src_type)
134     
135     def as_argument_type(self):
136         return self
137     
138     def is_complete(self):
139         # A type is incomplete if it is an unsized array,
140         # a struct whose attributes are not defined, etc.
141         return 1
142
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                 self.is_extension_type or self.is_ptr)
146
147     def struct_nesting_depth(self):
148         # Returns the number levels of nested structs. This is
149         # used for constructing a stack for walking the run-time
150         # type information of the struct.
151         return 1
152
153
154 def create_typedef_type(cname, base_type, is_external=0):
155     if base_type.is_complex:
156         if is_external:
157             raise ValueError("Complex external typedefs not supported")
158         return base_type
159     else:
160         return CTypedefType(cname, base_type, is_external)
161
162 class CTypedefType(BaseType):
163     #
164     #  Pseudo-type defined with a ctypedef statement in a
165     #  'cdef extern from' block. Delegates most attribute
166     #  lookups to the base type. ANYTHING NOT DEFINED
167     #  HERE IS DELEGATED!
168     #
169     #  qualified_name      string
170     #  typedef_cname       string
171     #  typedef_base_type   PyrexType
172     #  typedef_is_external bool
173     
174     is_typedef = 1
175     typedef_is_external = 0
176
177     to_py_utility_code = None
178     from_py_utility_code = None
179     
180     
181     def __init__(self, cname, base_type, is_external=0):
182         assert not base_type.is_complex
183         self.typedef_cname = cname
184         self.typedef_base_type = base_type
185         self.typedef_is_external = is_external
186         # Make typecodes in external typedefs use typesize-neutral macros
187         if is_external:
188             typecode = None
189             if base_type.is_int:
190                 if base_type.signed == 0:
191                     typecode = "__Pyx_T_UNSIGNED_INT"
192                 else:
193                     typecode = "__Pyx_T_SIGNED_INT"
194             elif base_type.is_float and not rank_to_type_name[base_type.rank] == "long double":
195                 typecode = "__Pyx_T_FLOATING"
196             if typecode:
197                 self.pymemberdef_typecode = "%s(%s)" % (typecode, cname)
198     
199     def resolve(self):
200         return self.typedef_base_type.resolve()
201     
202     def declaration_code(self, entity_code, 
203             for_display = 0, dll_linkage = None, pyrex = 0):
204         name = self.declaration_name(for_display, pyrex)
205         return self.base_declaration_code(name, entity_code)
206     
207     def declaration_name(self, for_display = 0, pyrex = 0):
208         if pyrex or for_display:
209             return self.qualified_name
210         else:
211             return self.typedef_cname
212     
213     def as_argument_type(self):
214         return self
215
216     def cast_code(self, expr_code):
217         # If self is really an array (rather than pointer), we can't cast.
218         # For example, the gmp mpz_t. 
219         if self.typedef_base_type.is_ptr:
220             return self.typedef_base_type.cast_code(expr_code)
221         else:
222             return BaseType.cast_code(self, expr_code)
223
224     def __repr__(self):
225         return "<CTypedefType %s>" % self.typedef_cname
226     
227     def __str__(self):
228         return self.declaration_name(for_display = 1)
229
230     def _create_utility_code(self, template_utility_code,
231                              template_function_name):
232         type_name = self.typedef_cname.replace(" ","_")
233         utility_code = template_utility_code.specialize(
234             type     = self.typedef_cname,
235             TypeName = type_name)
236         function_name = template_function_name % type_name
237         return utility_code, function_name
238
239     def create_to_py_utility_code(self, env):
240         if self.typedef_is_external:
241             if not self.to_py_utility_code:
242                 base_type = self.typedef_base_type
243                 if base_type.is_int:
244                     self.to_py_utility_code, self.to_py_function = \
245                         self._create_utility_code(c_typedef_int_to_py_function,
246                                                   '__Pyx_PyInt_to_py_%s')
247                 elif base_type.is_float:
248                     pass # XXX implement!
249                 elif base_type.is_complex:
250                     pass # XXX implement!
251                     pass
252             if self.to_py_utility_code:
253                 env.use_utility_code(self.to_py_utility_code)
254                 return True
255         # delegation
256         return self.typedef_base_type.create_to_py_utility_code(env)
257
258     def create_from_py_utility_code(self, env):
259         if self.typedef_is_external:
260             if not self.from_py_utility_code:
261                 base_type = self.typedef_base_type
262                 if base_type.is_int:
263                     self.from_py_utility_code, self.from_py_function = \
264                         self._create_utility_code(c_typedef_int_from_py_function,
265                                                   '__Pyx_PyInt_from_py_%s')
266                 elif base_type.is_float:
267                     pass # XXX implement!
268                 elif base_type.is_complex:
269                     pass # XXX implement!
270             if self.from_py_utility_code:
271                 env.use_utility_code(self.from_py_utility_code)
272                 return True
273         # delegation
274         return self.typedef_base_type.create_from_py_utility_code(env)
275
276     def error_condition(self, result_code):
277         if self.typedef_is_external:
278             if self.exception_value:
279                 condition = "(%s == (%s)%s)" % (
280                     result_code, self.typedef_cname, self.exception_value)
281                 if self.exception_check:
282                     condition += " && PyErr_Occurred()"
283                 return condition
284         # delegation
285         return self.typedef_base_type.error_condition(result_code)
286
287     def __getattr__(self, name):
288         return getattr(self.typedef_base_type, name)
289
290 class BufferType(BaseType):
291     #
292     #  Delegates most attribute
293     #  lookups to the base type. ANYTHING NOT DEFINED
294     #  HERE IS DELEGATED!
295     
296     # dtype            PyrexType
297     # ndim             int
298     # mode             str
299     # negative_indices bool
300     # cast             bool
301     # is_buffer        bool
302     # writable         bool
303
304     is_buffer = 1
305     writable = True
306     def __init__(self, base, dtype, ndim, mode, negative_indices, cast):
307         self.base = base
308         self.dtype = dtype
309         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     def as_argument_type(self):
316         return self
317
318     def __getattr__(self, name):
319         return getattr(self.base, name)
320
321     def __repr__(self):
322         return "<BufferType %r>" % self.base
323
324 def public_decl(base, dll_linkage):
325     if dll_linkage:
326         return "%s(%s)" % (dll_linkage, base)
327     else:
328         return base
329     
330 class PyObjectType(PyrexType):
331     #
332     #  Base class for all Python object types (reference-counted).
333     #
334     #  buffer_defaults  dict or None     Default options for bu
335
336     name = "object"
337     is_pyobject = 1
338     default_value = "0"
339     pymemberdef_typecode = "T_OBJECT"
340     buffer_defaults = None
341     
342     def __str__(self):
343         return "Python object"
344     
345     def __repr__(self):
346         return "<PyObjectType>"
347     
348     def assignable_from(self, src_type):
349         # except for pointers, conversion will be attempted
350         return not src_type.is_ptr or src_type.is_string
351         
352     def declaration_code(self, entity_code, 
353             for_display = 0, dll_linkage = None, pyrex = 0):
354         if pyrex or for_display:
355             return self.base_declaration_code("object", entity_code)
356         else:
357             return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
358
359     def as_pyobject(self, cname):
360         if (not self.is_complete()) or self.is_extension_type:
361             return "(PyObject *)" + cname
362         else:
363             return cname
364
365 class BuiltinObjectType(PyObjectType):
366
367     is_builtin_type = 1
368     has_attributes = 1
369     base_type = None
370     module_name = '__builtin__'
371
372     alternative_name = None # used for str/bytes duality
373
374     def __init__(self, name, cname):
375         self.name = name
376         if name == 'str':
377             self.alternative_name = 'bytes'
378         elif name == 'bytes':
379             self.alternative_name = 'str'
380         self.cname = cname
381         self.typeptr_cname = "&" + cname
382                                  
383     def set_scope(self, scope):
384         self.scope = scope
385         if scope:
386             scope.parent_type = self
387         
388     def __str__(self):
389         return "%s object" % self.name
390     
391     def __repr__(self):
392         return "<%s>"% self.cname
393         
394     def assignable_from(self, src_type):
395         if isinstance(src_type, BuiltinObjectType):
396             return src_type.name == self.name or (
397                 src_type.name == self.alternative_name and
398                 src_type.name is not None)
399         else:
400             return not src_type.is_extension_type
401             
402     def typeobj_is_available(self):
403         return True
404         
405     def attributes_known(self):
406         return True
407         
408     def subtype_of(self, type):
409         return type.is_pyobject and self.assignable_from(type)
410         
411     def type_test_code(self, arg, notnone=False):
412         type_name = self.name
413         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             type_check = 'Py%s_CheckExact' % type_name.capitalize()
423
424         check = 'likely(%s(%s))' % (type_check, arg)
425         if not notnone:
426             check = check + ('||((%s) == Py_None)' % arg)
427         error = '(PyErr_Format(PyExc_TypeError, "Expected %s, got %%.200s", Py_TYPE(%s)->tp_name), 0)' % (self.name, arg)
428         return check + '||' + error
429
430     def declaration_code(self, entity_code, 
431             for_display = 0, dll_linkage = None, pyrex = 0):
432         if pyrex or for_display:
433             return self.base_declaration_code(self.name, entity_code)
434         else:
435             return "%s *%s" % (public_decl("PyObject", dll_linkage), entity_code)
436
437
438 class PyExtensionType(PyObjectType):
439     #
440     #  A Python extension type.
441     #
442     #  name             string
443     #  scope            CClassScope      Attribute namespace
444     #  visibility       string
445     #  typedef_flag     boolean
446     #  base_type        PyExtensionType or None
447     #  module_name      string or None   Qualified name of defining module
448     #  objstruct_cname  string           Name of PyObject struct
449     #  objtypedef_cname string           Name of PyObject struct typedef
450     #  typeobj_cname    string or None   C code fragment referring to type object
451     #  typeptr_cname    string or None   Name of pointer to external type object
452     #  vtabslot_cname   string           Name of C method table member
453     #  vtabstruct_cname string           Name of C method table struct
454     #  vtabptr_cname    string           Name of pointer to C method table
455     #  vtable_cname     string           Name of C method table definition
456     
457     is_extension_type = 1
458     has_attributes = 1
459     
460     objtypedef_cname = None
461     
462     def __init__(self, name, typedef_flag, base_type):
463         self.name = name
464         self.scope = None
465         self.typedef_flag = typedef_flag
466         self.base_type = base_type
467         self.module_name = None
468         self.objstruct_cname = None
469         self.typeobj_cname = None
470         self.typeptr_cname = None
471         self.vtabslot_cname = None
472         self.vtabstruct_cname = None
473         self.vtabptr_cname = None
474         self.vtable_cname = None
475     
476     def set_scope(self, scope):
477         self.scope = scope
478         if scope:
479             scope.parent_type = self
480     
481     def subtype_of_resolved_type(self, other_type):
482         if other_type.is_extension_type:
483             return self is other_type or (
484                 self.base_type and self.base_type.subtype_of(other_type))
485         else:
486             return other_type is py_object_type
487     
488     def typeobj_is_available(self):
489         # Do we have a pointer to the type object?
490         return self.typeptr_cname
491     
492     def typeobj_is_imported(self):
493         # If we don't know the C name of the type object but we do
494         # know which module it's defined in, it will be imported.
495         return self.typeobj_cname is None and self.module_name is not None
496     
497     def declaration_code(self, entity_code, 
498             for_display = 0, dll_linkage = None, pyrex = 0, deref = 0):
499         if pyrex or for_display:
500             return self.base_declaration_code(self.name, entity_code)
501         else:
502             if self.typedef_flag:
503                 base_format = "%s"
504             else:
505                 base_format = "struct %s"
506             base = public_decl(base_format % self.objstruct_cname, dll_linkage)
507             if deref:
508                 return "%s %s" % (base,  entity_code)
509             else:
510                 return "%s *%s" % (base,  entity_code)
511
512     def type_test_code(self, py_arg, notnone=False):
513
514         none_check = "((%s) == Py_None)" % py_arg
515         type_check = "likely(__Pyx_TypeTest(%s, %s))" % (
516             py_arg, self.typeptr_cname)
517         if notnone:
518             return type_check
519         else:
520             return "likely(%s || %s)" % (none_check, type_check)
521
522     def attributes_known(self):
523         return self.scope is not None
524     
525     def __str__(self):
526         return self.name
527     
528     def __repr__(self):
529         return "<PyExtensionType %s%s>" % (self.scope.class_name,
530             ("", " typedef")[self.typedef_flag])
531     
532
533 class CType(PyrexType):
534     #
535     #  Base class for all C types (non-reference-counted).
536     #
537     #  to_py_function     string     C function for converting to Python object
538     #  from_py_function   string     C function for constructing from Python object
539     #
540     
541     to_py_function = None
542     from_py_function = None
543     exception_value = None
544     exception_check = 1
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
551         
552     def error_condition(self, result_code):
553         conds = []
554         if self.is_string:
555             conds.append("(!%s)" % result_code)
556         elif self.exception_value is not None:
557             conds.append("(%s == (%s)%s)" % (result_code, self.sign_and_name(), self.exception_value))
558         if self.exception_check:
559             conds.append("PyErr_Occurred()")
560         if len(conds) > 0:
561             return " && ".join(conds)
562         else:
563             return 0
564
565
566 class CVoidType(CType):
567     is_void = 1
568     
569     def __repr__(self):
570         return "<CVoidType>"
571     
572     def declaration_code(self, entity_code, 
573             for_display = 0, dll_linkage = None, pyrex = 0):
574         base = public_decl("void", dll_linkage)
575         return self.base_declaration_code(base, entity_code)
576     
577     def is_complete(self):
578         return 0
579
580
581 class CNumericType(CType):
582     #
583     #   Base class for all C numeric types.
584     #
585     #   rank      integer     Relative size
586     #   signed    integer     0 = unsigned, 1 = unspecified, 2 = explicitly signed
587     #
588     
589     is_numeric = 1
590     default_value = "0"
591     
592     sign_words = ("unsigned ", "", "signed ")
593     
594     def __init__(self, rank, signed = 1, pymemberdef_typecode = None):
595         self.rank = rank
596         self.signed = signed
597         self.pymemberdef_typecode = pymemberdef_typecode
598     
599     def sign_and_name(self):
600         s = self.sign_words[self.signed]
601         n = rank_to_type_name[self.rank]
602         return s + n
603     
604     def __repr__(self):
605         return "<CNumericType %s>" % self.sign_and_name()
606     
607     def declaration_code(self, entity_code, 
608             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 type_conversion_functions = ""
617
618 c_int_from_py_function = UtilityCode(
619 proto="""
620 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
621 """,
622 impl="""
623 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
624     const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
625     const int is_unsigned = neg_one > const_zero;
626     if (sizeof(%(type)s) < sizeof(long)) {
627         long val = __Pyx_PyInt_AsLong(x);
628         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                     "can't convert negative value to %(type)s" :
633                     "value too large to convert to %(type)s");
634             }
635             return (%(type)s)-1;
636         }
637         return (%(type)s)val;
638     }
639     return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x);
640 }
641 """) #fool emacs: '
642
643 c_long_from_py_function = UtilityCode(
644 proto="""
645 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *);
646 """,
647 impl="""
648 static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) {
649     const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
650     const int is_unsigned = neg_one > const_zero;
651 #if PY_VERSION_HEX < 0x03000000
652     if (likely(PyInt_Check(x))) {
653         long val = PyInt_AS_LONG(x);
654         if (is_unsigned && unlikely(val < 0)) {
655             PyErr_SetString(PyExc_OverflowError,
656                             "can't convert negative value to %(type)s");
657             return (%(type)s)-1;
658         }
659         return (%(type)s)val;
660     } else
661 #endif
662     if (likely(PyLong_Check(x))) {
663         if (is_unsigned) {
664             if (unlikely(Py_SIZE(x) < 0)) {
665                 PyErr_SetString(PyExc_OverflowError,
666                                 "can't convert negative value to %(type)s");
667                 return (%(type)s)-1;
668             }
669             return PyLong_AsUnsigned%(TypeName)s(x);
670         } else {
671             return PyLong_As%(TypeName)s(x);
672         }
673     } else {
674         %(type)s val;
675         PyObject *tmp = __Pyx_PyNumber_Int(x);
676         if (!tmp) return (%(type)s)-1;
677         val = __Pyx_PyInt_As%(SignWord)s%(TypeName)s(tmp);
678         Py_DECREF(tmp);
679         return val;
680     }
681 }
682 """)
683
684 c_typedef_int_from_py_function = UtilityCode(
685 proto="""
686 static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *);
687 """,
688 impl="""
689 static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) {
690     const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
691     const int is_unsigned = neg_one > const_zero;
692     if (sizeof(%(type)s) == sizeof(char)) {
693         if (is_unsigned)
694             return (%(type)s)__Pyx_PyInt_AsUnsignedChar(x);
695         else
696             return (%(type)s)__Pyx_PyInt_AsSignedChar(x);
697     } else if (sizeof(%(type)s) == sizeof(short)) {
698         if (is_unsigned)
699             return (%(type)s)__Pyx_PyInt_AsUnsignedShort(x);
700         else
701             return (%(type)s)__Pyx_PyInt_AsSignedShort(x);
702     } else if (sizeof(%(type)s) == sizeof(int)) {
703         if (is_unsigned)
704             return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
705         else
706             return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
707     } else if (sizeof(%(type)s) == sizeof(long)) {
708         if (is_unsigned)
709             return (%(type)s)__Pyx_PyInt_AsUnsignedLong(x);
710         else
711             return (%(type)s)__Pyx_PyInt_AsSignedLong(x);
712     } else if (sizeof(%(type)s) == sizeof(PY_LONG_LONG)) {
713         if (is_unsigned)
714             return (%(type)s)__Pyx_PyInt_AsUnsignedLongLong(x);
715         else
716             return (%(type)s)__Pyx_PyInt_AsSignedLongLong(x);
717 #if 0
718     } else if (sizeof(%(type)s) > sizeof(short) &&
719                sizeof(%(type)s) < sizeof(int)) { /*  __int32 ILP64 ? */
720         if (is_unsigned)
721             return (%(type)s)__Pyx_PyInt_AsUnsignedInt(x);
722         else
723             return (%(type)s)__Pyx_PyInt_AsSignedInt(x);
724 #endif
725     }
726     PyErr_SetString(PyExc_TypeError, "%(TypeName)s");
727     return (%(type)s)-1;
728 }
729 """)
730
731 c_typedef_int_to_py_function = UtilityCode(
732 proto="""
733 static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s);
734 """,
735 impl="""
736 static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) {
737     const %(type)s neg_one = (%(type)s)-1, const_zero = 0;
738     const int is_unsigned = neg_one > const_zero;
739     if (sizeof(%(type)s) <  sizeof(long)) {
740         return PyInt_FromLong((long)val);
741     } else if (sizeof(%(type)s) == sizeof(long)) {
742         if (is_unsigned)
743             return PyLong_FromUnsignedLong((unsigned long)val);
744         else
745             return PyInt_FromLong((long)val);
746     } else { /* (sizeof(%(type)s) > sizeof(long)) */
747         if (is_unsigned)
748             return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val);
749         else
750             return PyLong_FromLongLong((PY_LONG_LONG)val);
751     }
752 }
753 """)
754
755 class CIntType(CNumericType):
756
757     is_int = 1
758     typedef_flag = 0
759     to_py_function = "PyInt_FromLong"
760     from_py_function = "__Pyx_PyInt_AsInt"
761     exception_value = -1
762
763     def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
764         CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
765         self.is_returncode = is_returncode
766         if self.from_py_function == "__Pyx_PyInt_AsInt":
767             self.from_py_function = self.get_type_conversion()
768
769     def get_type_conversion(self):
770         ctype = self.declaration_code('')
771         bits = ctype.split(" ", 1)
772         if len(bits) == 1:
773             sign_word, type_name = "", bits[0]
774         else:
775             sign_word, type_name = bits
776         type_name = type_name.replace("PY_LONG_LONG","long long")
777         SignWord  = sign_word.title()
778         TypeName  = type_name.title().replace(" ", "")
779         if "Long" in TypeName:
780             utility_code = c_long_from_py_function
781         else:
782             utility_code = c_int_from_py_function
783         utility_code.specialize(self,
784                                 SignWord=SignWord,
785                                 TypeName=TypeName)
786         func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName)
787         return func_name
788
789     def assignable_from_resolved_type(self, src_type):
790         return src_type.is_int or src_type.is_enum or src_type is error_type
791
792
793 class CBIntType(CIntType):
794
795     to_py_function = "__Pyx_PyBool_FromLong"
796     from_py_function = "__Pyx_PyObject_IsTrue"
797     exception_check = 0
798
799
800 class CAnonEnumType(CIntType):
801
802     is_enum = 1
803
804     def sign_and_name(self):
805         return 'int'
806
807
808 class CUIntType(CIntType):
809
810     to_py_function = "PyLong_FromUnsignedLong"
811     exception_value = -1
812
813
814 class CLongType(CIntType):
815
816     to_py_function = "PyInt_FromLong"
817
818
819 class CULongType(CUIntType):
820
821     to_py_function = "PyLong_FromUnsignedLong"
822
823
824 class CLongLongType(CIntType):
825
826     to_py_function = "PyLong_FromLongLong"
827
828
829 class CULongLongType(CUIntType):
830
831     to_py_function = "PyLong_FromUnsignedLongLong"
832
833
834 class CPySSizeTType(CIntType):
835
836     to_py_function = "PyInt_FromSsize_t"
837     from_py_function = "__Pyx_PyIndex_AsSsize_t"
838
839     def sign_and_name(self):
840         return rank_to_type_name[self.rank]
841
842
843 class CSizeTType(CUIntType):
844
845     to_py_function = "__Pyx_PyInt_FromSize_t"
846     from_py_function = "__Pyx_PyInt_AsSize_t"
847
848     def sign_and_name(self):
849         return rank_to_type_name[self.rank]
850
851
852 class CFloatType(CNumericType):
853
854     is_float = 1
855     to_py_function = "PyFloat_FromDouble"
856     from_py_function = "__pyx_PyFloat_AsDouble"
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
861     
862     def assignable_from_resolved_type(self, src_type):
863         return (src_type.is_numeric and not src_type.is_complex) or src_type is error_type
864
865
866 class CComplexType(CNumericType):
867     
868     is_complex = 1
869     to_py_function = "__pyx_PyComplex_FromComplex"
870     has_attributes = 1
871     scope = None
872     
873     def __init__(self, real_type):
874         while real_type.is_typedef and not real_type.typedef_is_external:
875             real_type = real_type.typedef_base_type
876         if real_type.is_typedef and real_type.typedef_is_external:
877             # The below is not actually used: Coercions are currently disabled
878             # so that complex types of external types can not be created
879             self.funcsuffix = "_%s" % real_type.specalization_name()
880         elif hasattr(real_type, 'math_h_modifier'):
881             self.funcsuffix = real_type.math_h_modifier
882         else:
883             self.funcsuffix = "_%s" % real_type.specalization_name()
884     
885         self.real_type = real_type
886         CNumericType.__init__(self, real_type.rank + 0.5, real_type.signed)
887         self.binops = {}
888         self.from_parts = "%s_from_parts" % self.specalization_name()
889         self.default_value = "%s(0, 0)" % self.from_parts
890
891     def __eq__(self, other):
892         if isinstance(self, CComplexType) and isinstance(other, CComplexType):
893             return self.real_type == other.real_type
894         else:
895             return False
896     
897     def __ne__(self, other):
898         if isinstance(self, CComplexType) and isinstance(other, CComplexType):
899             return self.real_type != other.real_type
900         else:
901             return True
902
903     def __lt__(self, other):
904         if isinstance(self, CComplexType) and isinstance(other, CComplexType):
905             return self.real_type < other.real_type
906         else:
907             # this is arbitrary, but it makes sure we always have
908             # *some* kind of order
909             return False
910
911     def __hash__(self):
912         return ~hash(self.real_type)
913
914     def declaration_code(self, entity_code, 
915             for_display = 0, dll_linkage = None, pyrex = 0):
916         if for_display:
917             base = public_decl(self.real_type.sign_and_name() + " complex", dll_linkage)
918         else:
919             base = public_decl(self.sign_and_name(), dll_linkage)
920         return self.base_declaration_code(base,  entity_code)
921
922     def sign_and_name(self):
923         real_type_name = self.real_type.specalization_name()
924         real_type_name = real_type_name.replace('long__double','long_double')
925         return Naming.type_prefix + real_type_name + "_complex"
926     
927     def assignable_from(self, src_type):
928         # Temporary hack/feature disabling, see #441
929         if (not src_type.is_complex and src_type.is_numeric and src_type.is_typedef
930             and src_type.typedef_is_external):
931              return False
932         else:
933             return super(CComplexType, self).assignable_from(src_type)
934         
935     def assignable_from_resolved_type(self, src_type):
936         return (src_type.is_complex and self.real_type.assignable_from_resolved_type(src_type.real_type)
937                     or src_type.is_numeric and self.real_type.assignable_from_resolved_type(src_type) 
938                     or src_type is error_type)
939                     
940     def attributes_known(self):
941         if self.scope is None:
942             import Symtab
943             self.scope = scope = Symtab.CClassScope(
944                     '',
945                     None,
946                     visibility="extern")
947             scope.parent_type = self
948             scope.declare_var("real", self.real_type, None, "real", is_cdef=True)
949             scope.declare_var("imag", self.real_type, None, "imag", is_cdef=True)
950             entry = scope.declare_cfunction(
951                     "conjugate",
952                     CFuncType(self, [CFuncTypeArg("self", self, None)]),
953                     pos=None,
954                     defining=1,
955                     cname="__Pyx_c_conj%s" % self.funcsuffix)
956
957         return True
958
959     def create_declaration_utility_code(self, env):
960         # This must always be run, because a single CComplexType instance can be shared
961         # across multiple compilations (the one created in the module scope)
962         env.use_utility_code(complex_header_utility_code)
963         env.use_utility_code(complex_real_imag_utility_code)
964         for utility_code in (complex_type_utility_code,
965                              complex_from_parts_utility_code,
966                              complex_arithmatic_utility_code):
967             env.use_utility_code(
968                 utility_code.specialize(
969                     self, 
970                     real_type = self.real_type.declaration_code(''),
971                     m = self.funcsuffix))
972         return True
973
974     def create_to_py_utility_code(self, env):
975         env.use_utility_code(complex_real_imag_utility_code)
976         env.use_utility_code(complex_to_py_utility_code)
977         return True
978
979     def create_from_py_utility_code(self, env):
980         self.real_type.create_from_py_utility_code(env)
981
982         for utility_code in (complex_from_parts_utility_code,
983                              complex_from_py_utility_code):
984             env.use_utility_code(
985                 utility_code.specialize(
986                     self, 
987                     real_type = self.real_type.declaration_code(''),
988                     m = self.funcsuffix))
989         self.from_py_function = "__Pyx_PyComplex_As_" + self.specalization_name()
990         return True
991     
992     def lookup_op(self, nargs, op):
993         try:
994             return self.binops[nargs, op]
995         except KeyError:
996             pass
997         try:
998             op_name = complex_ops[nargs, op]
999             self.binops[nargs, op] = func_name = "__Pyx_c_%s%s" % (op_name, self.funcsuffix)
1000             return func_name
1001         except KeyError:
1002             return None
1003
1004     def unary_op(self, op):
1005         return self.lookup_op(1, op)
1006         
1007     def binary_op(self, op):
1008         return self.lookup_op(2, op)
1009         
1010 complex_ops = {
1011     (1, '-'): 'neg',
1012     (1, 'zero'): 'is_zero',
1013     (2, '+'): 'sum',
1014     (2, '-'): 'diff',
1015     (2, '*'): 'prod',
1016     (2, '/'): 'quot',
1017     (2, '=='): 'eq',
1018 }
1019
1020 complex_header_utility_code = UtilityCode(
1021 proto_block='h_code',
1022 proto="""
1023 #if !defined(CYTHON_CCOMPLEX)
1024   #if defined(__cplusplus)
1025     #define CYTHON_CCOMPLEX 1
1026   #elif defined(_Complex_I)
1027     #define CYTHON_CCOMPLEX 1
1028   #else
1029     #define CYTHON_CCOMPLEX 0
1030   #endif
1031 #endif
1032
1033 #if CYTHON_CCOMPLEX
1034   #ifdef __cplusplus
1035     #include <complex>
1036   #else
1037     #include <complex.h>
1038   #endif
1039 #endif
1040 """)
1041
1042 complex_real_imag_utility_code = UtilityCode(
1043 proto="""
1044 #if CYTHON_CCOMPLEX
1045   #ifdef __cplusplus
1046     #define __Pyx_CREAL(z) ((z).real())
1047     #define __Pyx_CIMAG(z) ((z).imag())
1048   #else
1049     #define __Pyx_CREAL(z) (__real__(z))
1050     #define __Pyx_CIMAG(z) (__imag__(z))
1051   #endif
1052 #else
1053     #define __Pyx_CREAL(z) ((z).real)
1054     #define __Pyx_CIMAG(z) ((z).imag)
1055 #endif
1056 """)
1057
1058 complex_type_utility_code = UtilityCode(
1059 proto_block='complex_type_declarations',
1060 proto="""
1061 #if CYTHON_CCOMPLEX
1062   #ifdef __cplusplus
1063     typedef ::std::complex< %(real_type)s > %(type_name)s;
1064   #else
1065     typedef %(real_type)s _Complex %(type_name)s;
1066   #endif
1067 #else
1068     typedef struct { %(real_type)s real, imag; } %(type_name)s;
1069 #endif
1070 """)
1071
1072 complex_from_parts_utility_code = UtilityCode(
1073 proto_block='utility_code_proto',
1074 proto="""
1075 #if CYTHON_CCOMPLEX
1076   #ifdef __cplusplus
1077     static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
1078   #else
1079     static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
1080   #endif
1081 #else
1082     static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s, %(real_type)s);
1083 #endif
1084 """,
1085 impl="""
1086 #if CYTHON_CCOMPLEX
1087   #ifdef __cplusplus
1088     static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1089       return ::std::complex< %(real_type)s >(x, y);
1090     }
1091   #else
1092     static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1093       return x + y*(%(type)s)_Complex_I;
1094     }
1095   #endif
1096 #else
1097     static INLINE %(type)s %(type_name)s_from_parts(%(real_type)s x, %(real_type)s y) {
1098       %(type)s z;
1099        z.real = x;
1100        z.imag = y;
1101        return z;
1102     }
1103 #endif
1104 """)
1105
1106 complex_to_py_utility_code = UtilityCode(
1107 proto="""
1108 #define __pyx_PyComplex_FromComplex(z) \\
1109         PyComplex_FromDoubles((double)__Pyx_CREAL(z), \\
1110                               (double)__Pyx_CIMAG(z))
1111 """)
1112
1113 complex_from_py_utility_code = UtilityCode(
1114 proto="""
1115 static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject*);
1116 """,
1117 impl="""
1118 static %(type)s __Pyx_PyComplex_As_%(type_name)s(PyObject* o) {
1119     Py_complex cval;
1120     if (PyComplex_CheckExact(o))
1121         cval = ((PyComplexObject *)o)->cval;
1122     else
1123         cval = PyComplex_AsCComplex(o);
1124     return %(type_name)s_from_parts(
1125                (%(real_type)s)cval.real,
1126                (%(real_type)s)cval.imag);
1127 }
1128 """)
1129
1130 complex_arithmatic_utility_code = UtilityCode(
1131 proto="""
1132 #if CYTHON_CCOMPLEX
1133     #define __Pyx_c_eq%(m)s(a, b)   ((a)==(b))
1134     #define __Pyx_c_sum%(m)s(a, b)  ((a)+(b))
1135     #define __Pyx_c_diff%(m)s(a, b) ((a)-(b))
1136     #define __Pyx_c_prod%(m)s(a, b) ((a)*(b))
1137     #define __Pyx_c_quot%(m)s(a, b) ((a)/(b))
1138     #define __Pyx_c_neg%(m)s(a)     (-(a))
1139   #ifdef __cplusplus
1140     #define __Pyx_c_is_zero%(m)s(z) ((z)==(%(real_type)s)0)
1141     #define __Pyx_c_conj%(m)s(z)    (::std::conj(z))
1142     /*#define __Pyx_c_abs%(m)s(z)     (::std::abs(z))*/
1143   #else
1144     #define __Pyx_c_is_zero%(m)s(z) ((z)==0)
1145     #define __Pyx_c_conj%(m)s(z)    (conj%(m)s(z))
1146     /*#define __Pyx_c_abs%(m)s(z)     (cabs%(m)s(z))*/
1147  #endif
1148 #else
1149     static INLINE int __Pyx_c_eq%(m)s(%(type)s, %(type)s);
1150     static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s, %(type)s);
1151     static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s, %(type)s);
1152     static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s, %(type)s);
1153     static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s, %(type)s);
1154     static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s);
1155     static INLINE int __Pyx_c_is_zero%(m)s(%(type)s);
1156     static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s);
1157     /*static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s);*/
1158 #endif
1159 """,
1160 impl="""
1161 #if CYTHON_CCOMPLEX
1162 #else
1163     static INLINE int __Pyx_c_eq%(m)s(%(type)s a, %(type)s b) {
1164        return (a.real == b.real) && (a.imag == b.imag);
1165     }
1166     static INLINE %(type)s __Pyx_c_sum%(m)s(%(type)s a, %(type)s b) {
1167         %(type)s z;
1168         z.real = a.real + b.real;
1169         z.imag = a.imag + b.imag;
1170         return z;
1171     }
1172     static INLINE %(type)s __Pyx_c_diff%(m)s(%(type)s a, %(type)s b) {
1173         %(type)s z;
1174         z.real = a.real - b.real;
1175         z.imag = a.imag - b.imag;
1176         return z;
1177     }
1178     static INLINE %(type)s __Pyx_c_prod%(m)s(%(type)s a, %(type)s b) {
1179         %(type)s z;
1180         z.real = a.real * b.real - a.imag * b.imag;
1181         z.imag = a.real * b.imag + a.imag * b.real;
1182         return z;
1183     }
1184     static INLINE %(type)s __Pyx_c_quot%(m)s(%(type)s a, %(type)s b) {
1185         %(type)s z;
1186         %(real_type)s denom = b.real * b.real + b.imag * b.imag;
1187         z.real = (a.real * b.real + a.imag * b.imag) / denom;
1188         z.imag = (a.imag * b.real - a.real * b.imag) / denom;
1189         return z;
1190     }
1191     static INLINE %(type)s __Pyx_c_neg%(m)s(%(type)s a) {
1192         %(type)s z;
1193         z.real = -a.real;
1194         z.imag = -a.imag;
1195         return z;
1196     }
1197     static INLINE int __Pyx_c_is_zero%(m)s(%(type)s a) {
1198        return (a.real == 0) && (a.imag == 0);
1199     }
1200     static INLINE %(type)s __Pyx_c_conj%(m)s(%(type)s a) {
1201         %(type)s z;
1202         z.real =  a.real;
1203         z.imag = -a.imag;
1204         return z;
1205     }
1206 /*
1207     static INLINE %(real_type)s __Pyx_c_abs%(m)s(%(type)s z) {
1208 #if HAVE_HYPOT
1209         return hypot%(m)s(z.real, z.imag);
1210 #else
1211         return sqrt%(m)s(z.real*z.real + z.imag*z.imag);
1212 #endif
1213     }
1214 */
1215 #endif
1216 """)
1217
1218 class CArrayType(CType):
1219     #  base_type     CType              Element type
1220     #  size          integer or None    Number of elements
1221     
1222     is_array = 1
1223     
1224     def __init__(self, base_type, size):
1225         self.base_type = base_type
1226         self.size = size
1227         if base_type is c_char_type:
1228             self.is_string = 1
1229     
1230     def __repr__(self):
1231         return "<CArrayType %s %s>" % (self.size, repr(self.base_type))
1232     
1233     def same_as_resolved_type(self, other_type):
1234         return ((other_type.is_array and
1235             self.base_type.same_as(other_type.base_type))
1236                 or other_type is error_type)
1237     
1238     def assignable_from_resolved_type(self, src_type):
1239         # Can't assign to a variable of an array type
1240         return 0
1241     
1242     def element_ptr_type(self):
1243         return c_ptr_type(self.base_type)
1244
1245     def declaration_code(self, entity_code, 
1246             for_display = 0, dll_linkage = None, pyrex = 0):
1247         if self.size is not None:
1248             dimension_code = self.size
1249         else:
1250             dimension_code = ""
1251         if entity_code.startswith("*"):
1252             entity_code = "(%s)" % entity_code
1253         return self.base_type.declaration_code(
1254             "%s[%s]" % (entity_code, dimension_code),
1255             for_display, dll_linkage, pyrex)
1256     
1257     def as_argument_type(self):
1258         return c_ptr_type(self.base_type)
1259     
1260     def is_complete(self):
1261         return self.size is not None
1262
1263
1264 class CPtrType(CType):
1265     #  base_type     CType    Referenced type
1266     
1267     is_ptr = 1
1268     default_value = "0"
1269     
1270     def __init__(self, base_type):
1271         self.base_type = base_type
1272     
1273     def __repr__(self):
1274         return "<CPtrType %s>" % repr(self.base_type)
1275     
1276     def same_as_resolved_type(self, other_type):
1277         return ((other_type.is_ptr and
1278             self.base_type.same_as(other_type.base_type))
1279                 or other_type is error_type)
1280     
1281     def declaration_code(self, entity_code, 
1282             for_display = 0, dll_linkage = None, pyrex = 0):
1283         #print "CPtrType.declaration_code: pointer to", self.base_type ###
1284         return self.base_type.declaration_code(
1285             "*%s" % entity_code,
1286             for_display, dll_linkage, pyrex)
1287     
1288     def assignable_from_resolved_type(self, other_type):
1289         if other_type is error_type:
1290             return 1
1291         if other_type.is_null_ptr:
1292             return 1
1293         if self.base_type.is_cfunction:
1294             if other_type.is_ptr:
1295                 other_type = other_type.base_type.resolve()
1296             if other_type.is_cfunction:
1297                 return self.base_type.pointer_assignable_from_resolved_type(other_type)
1298             else:
1299                 return 0
1300         if other_type.is_array or other_type.is_ptr:
1301             return self.base_type.is_void or self.base_type.same_as(other_type.base_type)
1302         return 0
1303
1304
1305 class CNullPtrType(CPtrType):
1306
1307     is_null_ptr = 1
1308     
1309
1310 class CFuncType(CType):
1311     #  return_type      CType
1312     #  args             [CFuncTypeArg]
1313     #  has_varargs      boolean
1314     #  exception_value  string
1315     #  exception_check  boolean    True if PyErr_Occurred check needed
1316     #  calling_convention  string  Function calling convention
1317     #  nogil            boolean    Can be called without gil
1318     #  with_gil         boolean    Acquire gil around function body
1319     
1320     is_cfunction = 1
1321     original_sig = None
1322     
1323     def __init__(self, return_type, args, has_varargs = 0,
1324             exception_value = None, exception_check = 0, calling_convention = "",
1325             nogil = 0, with_gil = 0, is_overridable = 0, optional_arg_count = 0):
1326         self.return_type = return_type
1327         self.args = args
1328         self.has_varargs = has_varargs
1329         self.optional_arg_count = optional_arg_count
1330         self.exception_value = exception_value
1331         self.exception_check = exception_check
1332         self.calling_convention = calling_convention
1333         self.nogil = nogil
1334         self.with_gil = with_gil
1335         self.is_overridable = is_overridable
1336     
1337     def __repr__(self):
1338         arg_reprs = map(repr, self.args)
1339         if self.has_varargs:
1340             arg_reprs.append("...")
1341         if self.exception_value:
1342             except_clause = " %r" % self.exception_value
1343         else:
1344             except_clause = ""
1345         if self.exception_check:
1346             except_clause += "?"
1347         return "<CFuncType %s %s[%s]%s>" % (
1348             repr(self.return_type),
1349             self.calling_convention_prefix(),
1350             ",".join(arg_reprs),
1351             except_clause)
1352     
1353     def calling_convention_prefix(self):
1354         cc = self.calling_convention
1355         if cc:
1356             return cc + " "
1357         else:
1358             return ""
1359     
1360     def same_c_signature_as(self, other_type, as_cmethod = 0):
1361         return self.same_c_signature_as_resolved_type(
1362             other_type.resolve(), as_cmethod)
1363
1364     def same_c_signature_as_resolved_type(self, other_type, as_cmethod = 0):
1365         #print "CFuncType.same_c_signature_as_resolved_type:", \
1366         #    self, other_type, "as_cmethod =", as_cmethod ###
1367         if other_type is error_type:
1368             return 1
1369         if not other_type.is_cfunction:
1370             return 0
1371         if self.is_overridable != other_type.is_overridable:
1372             return 0
1373         nargs = len(self.args)
1374         if nargs != len(other_type.args):
1375             return 0
1376         # When comparing C method signatures, the first argument
1377         # is exempt from compatibility checking (the proper check
1378         # is performed elsewhere).
1379         for i in range(as_cmethod, nargs):
1380             if not self.args[i].type.same_as(
1381                 other_type.args[i].type):
1382                     return 0
1383         if self.has_varargs != other_type.has_varargs:
1384             return 0
1385         if self.optional_arg_count != other_type.optional_arg_count:
1386             return 0
1387         if not self.return_type.same_as(other_type.return_type):
1388             return 0
1389         if not self.same_calling_convention_as(other_type):
1390             return 0
1391         return 1
1392
1393     def compatible_signature_with(self, other_type, as_cmethod = 0):
1394         return self.compatible_signature_with_resolved_type(other_type.resolve(), as_cmethod)
1395     
1396     def compatible_signature_with_resolved_type(self, other_type, as_cmethod):
1397         #print "CFuncType.same_c_signature_as_resolved_type:", \
1398         #    self, other_type, "as_cmethod =", as_cmethod ###
1399         if other_type is error_type:
1400             return 1
1401         if not other_type.is_cfunction:
1402             return 0
1403         if not self.is_overridable and other_type.is_overridable:
1404             return 0
1405         nargs = len(self.args)
1406         if nargs - self.optional_arg_count != len(other_type.args) - other_type.optional_arg_count:
1407             return 0
1408         if self.optional_arg_count < other_type.optional_arg_count:
1409             return 0
1410         # When comparing C method signatures, the first argument
1411         # is exempt from compatibility checking (the proper check
1412         # is performed elsewhere).
1413         for i in range(as_cmethod, len(other_type.args)):
1414             if not self.args[i].type.same_as(
1415                 other_type.args[i].type):
1416                     return 0
1417         if self.has_varargs != other_type.has_varargs:
1418             return 0
1419         if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1420             return 0
1421         if not self.same_calling_convention_as(other_type):
1422             return 0
1423         if self.nogil != other_type.nogil:
1424             return 0
1425         self.original_sig = other_type.original_sig or other_type
1426         if as_cmethod:
1427             self.args[0] = other_type.args[0]
1428         return 1
1429         
1430         
1431     def narrower_c_signature_than(self, other_type, as_cmethod = 0):
1432         return self.narrower_c_signature_than_resolved_type(other_type.resolve(), as_cmethod)
1433         
1434     def narrower_c_signature_than_resolved_type(self, other_type, as_cmethod):
1435         if other_type is error_type:
1436             return 1
1437         if not other_type.is_cfunction:
1438             return 0
1439         nargs = len(self.args)
1440         if nargs != len(other_type.args):
1441             return 0
1442         for i in range(as_cmethod, nargs):
1443             if not self.args[i].type.subtype_of_resolved_type(other_type.args[i].type):
1444                 return 0
1445             else:
1446                 self.args[i].needs_type_test = other_type.args[i].needs_type_test \
1447                         or not self.args[i].type.same_as(other_type.args[i].type)
1448         if self.has_varargs != other_type.has_varargs:
1449             return 0
1450         if self.optional_arg_count != other_type.optional_arg_count:
1451             return 0
1452         if not self.return_type.subtype_of_resolved_type(other_type.return_type):
1453             return 0
1454         return 1
1455
1456     def same_calling_convention_as(self, other):
1457         ## XXX Under discussion ...
1458         ## callspec_words = ("__stdcall", "__cdecl", "__fastcall")
1459         ## cs1 = self.calling_convention
1460         ## cs2 = other.calling_convention
1461         ## if (cs1 in callspec_words or
1462         ##     cs2 in callspec_words):
1463         ##     return cs1 == cs2
1464         ## else:
1465         ##     return True
1466         sc1 = self.calling_convention == '__stdcall'
1467         sc2 = other.calling_convention == '__stdcall'
1468         return sc1 == sc2
1469     
1470     def same_exception_signature_as(self, other_type):
1471         return self.same_exception_signature_as_resolved_type(
1472             other_type.resolve())
1473
1474     def same_exception_signature_as_resolved_type(self, other_type):
1475         return self.exception_value == other_type.exception_value \
1476             and self.exception_check == other_type.exception_check
1477     
1478     def same_as_resolved_type(self, other_type, as_cmethod = 0):
1479         return self.same_c_signature_as_resolved_type(other_type, as_cmethod) \
1480             and self.same_exception_signature_as_resolved_type(other_type) \
1481             and self.nogil == other_type.nogil
1482     
1483     def pointer_assignable_from_resolved_type(self, other_type):
1484         return self.same_c_signature_as_resolved_type(other_type) \
1485             and self.same_exception_signature_as_resolved_type(other_type) \
1486             and not (self.nogil and not other_type.nogil)
1487     
1488     def declaration_code(self, entity_code, 
1489                          for_display = 0, dll_linkage = None, pyrex = 0,
1490                          with_calling_convention = 1):
1491         arg_decl_list = []
1492         for arg in self.args[:len(self.args)-self.optional_arg_count]:
1493             arg_decl_list.append(
1494                 arg.type.declaration_code("", for_display, pyrex = pyrex))
1495         if self.is_overridable:
1496             arg_decl_list.append("int %s" % Naming.skip_dispatch_cname)
1497         if self.optional_arg_count:
1498             arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname))
1499         if self.has_varargs:
1500             arg_decl_list.append("...")
1501         arg_decl_code = ", ".join(arg_decl_list)
1502         if not arg_decl_code and not pyrex:
1503             arg_decl_code = "void"
1504         trailer = ""
1505         if (pyrex or for_display) and not self.return_type.is_pyobject:
1506             if self.exception_value and self.exception_check:
1507                 trailer = " except? %s" % self.exception_value
1508             elif self.exception_value:
1509                 trailer = " except %s" % self.exception_value
1510             elif self.exception_check == '+':
1511                 trailer = " except +"
1512             else:
1513                 " except *" # ignored
1514             if self.nogil:
1515                 trailer += " nogil"
1516         if not with_calling_convention:
1517             cc = ''
1518         else:
1519             cc = self.calling_convention_prefix()
1520             if (not entity_code and cc) or entity_code.startswith("*"):
1521                 entity_code = "(%s%s)" % (cc, entity_code)
1522                 cc = ""
1523         return self.return_type.declaration_code(
1524             "%s%s(%s)%s" % (cc, entity_code, arg_decl_code, trailer),
1525             for_display, dll_linkage, pyrex)
1526     
1527     def function_header_code(self, func_name, arg_code):
1528         return "%s%s(%s)" % (self.calling_convention_prefix(),
1529             func_name, arg_code)
1530
1531     def signature_string(self):
1532         s = self.declaration_code("")
1533         return s
1534
1535     def signature_cast_string(self):
1536         s = self.declaration_code("(*)", with_calling_convention=False)
1537         return '(%s)' % s
1538     
1539     def opt_arg_cname(self, arg_name):
1540         return self.op_arg_struct.base_type.scope.lookup(arg_name).cname
1541
1542
1543 class CFuncTypeArg(object):
1544     #  name       string
1545     #  cname      string
1546     #  type       PyrexType
1547     #  pos        source file position
1548     
1549     def __init__(self, name, type, pos, cname=None):
1550         self.name = name
1551         if cname is not None:
1552             self.cname = cname
1553         else:
1554             self.cname = Naming.var_prefix + name
1555         self.type = type
1556         self.pos = pos
1557         self.not_none = False
1558         self.needs_type_test = False # TODO: should these defaults be set in analyse_types()?
1559     
1560     def __repr__(self):
1561         return "%s:%s" % (self.name, repr(self.type))
1562     
1563     def declaration_code(self, for_display = 0):
1564         return self.type.declaration_code(self.cname, for_display)
1565
1566 class StructUtilityCode(object):
1567     def __init__(self, type, forward_decl):
1568         self.type = type
1569         self.header = "static PyObject* %s(%s)" % (type.to_py_function, type.declaration_code('s'))
1570         self.forward_decl = forward_decl
1571
1572     def __eq__(self, other):
1573         return isinstance(other, StructUtilityCode) and self.header == other.header
1574     def __hash__(self):
1575         return hash(self.header)
1576     
1577     def put_code(self, output):
1578         code = output['utility_code_def']
1579         proto = output['utility_code_proto']
1580         
1581         code.putln("%s {" % self.header)
1582         code.putln("PyObject* res;")
1583         code.putln("PyObject* member;")
1584         code.putln("res = PyDict_New(); if (res == NULL) return NULL;")
1585         for member in self.type.scope.var_entries:
1586             nameconst_cname = code.get_py_string_const(member.name, identifier=True)
1587             code.putln("member = %s(s.%s); if (member == NULL) goto bad;" % (
1588                 member.type.to_py_function, member.cname))
1589             code.putln("if (PyDict_SetItem(res, %s, member) < 0) goto bad;" % nameconst_cname)
1590             code.putln("Py_DECREF(member);")
1591         code.putln("return res;")
1592         code.putln("bad:")
1593         code.putln("Py_XDECREF(member);")
1594         code.putln("Py_DECREF(res);")
1595         code.putln("return NULL;")
1596         code.putln("}")
1597
1598         # This is a bit of a hack, we need a forward declaration
1599         # due to the way things are ordered in the module...
1600         if self.forward_decl:
1601             proto.putln(self.type.declaration_code('') + ';')
1602         proto.putln(self.header + ";")
1603         
1604
1605 class CStructOrUnionType(CType):
1606     #  name          string
1607     #  cname         string
1608     #  kind          string              "struct" or "union"
1609     #  scope         StructOrUnionScope, or None if incomplete
1610     #  typedef_flag  boolean
1611     #  packed        boolean
1612     
1613     # entry          Entry
1614     
1615     is_struct_or_union = 1
1616     has_attributes = 1
1617     
1618     def __init__(self, name, kind, scope, typedef_flag, cname, packed=False):
1619         self.name = name
1620         self.cname = cname
1621         self.kind = kind
1622         self.scope = scope
1623         self.typedef_flag = typedef_flag
1624         self.is_struct = kind == 'struct'
1625         if self.is_struct:
1626             self.to_py_function = "%s_to_py_%s" % (Naming.convert_func_prefix, self.cname)
1627         self.exception_check = True
1628         self._convert_code = None
1629         self.packed = packed
1630         
1631     def create_to_py_utility_code(self, env):
1632         if env.outer_scope is None:
1633             return False
1634
1635         if self._convert_code is False: return # tri-state-ish
1636
1637         if self._convert_code is None:
1638             for member in self.scope.var_entries:
1639                 if not member.type.to_py_function or not member.type.create_to_py_utility_code(env):
1640                     self.to_py_function = None
1641                     self._convert_code = False
1642                     return False
1643             forward_decl = (self.entry.visibility != 'extern')
1644             self._convert_code = StructUtilityCode(self, forward_decl)
1645         
1646         env.use_utility_code(self._convert_code)
1647         return True
1648         
1649     def __repr__(self):
1650         return "<CStructOrUnionType %s %s%s>" % (self.name, self.cname,
1651             ("", " typedef")[self.typedef_flag])
1652
1653     def declaration_code(self, entity_code, 
1654             for_display = 0, dll_linkage = None, pyrex = 0):
1655         if pyrex:
1656             return self.base_declaration_code(self.name, entity_code)
1657         else:
1658             if for_display:
1659                 base = self.name
1660             elif self.typedef_flag:
1661                 base = self.cname
1662             else:
1663                 base = "%s %s" % (self.kind, self.cname)
1664             return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1665
1666     def __eq__(self, other):
1667         try:
1668             return (isinstance(other, CStructOrUnionType) and
1669                     self.name == other.name)
1670         except AttributeError:
1671             return False
1672
1673     def __lt__(self, other):
1674         try:
1675             return self.name < other.name
1676         except AttributeError:
1677             # this is arbitrary, but it makes sure we always have
1678             # *some* kind of order
1679             return False
1680
1681     def __hash__(self):
1682         return hash(self.cname) ^ hash(self.kind)
1683
1684     def is_complete(self):
1685         return self.scope is not None
1686     
1687     def attributes_known(self):
1688         return self.is_complete()
1689
1690     def can_be_complex(self):
1691         # Does the struct consist of exactly two identical floats?
1692         fields = self.scope.var_entries
1693         if len(fields) != 2: return False
1694         a, b = fields
1695         return (a.type.is_float and b.type.is_float and
1696                 a.type.declaration_code("") ==
1697                 b.type.declaration_code(""))
1698
1699     def struct_nesting_depth(self):
1700         child_depths = [x.type.struct_nesting_depth()
1701                         for x in self.scope.var_entries]
1702         return max(child_depths) + 1
1703
1704 class CEnumType(CType):
1705     #  name           string
1706     #  cname          string or None
1707     #  typedef_flag   boolean
1708
1709     is_enum = 1
1710     signed = 1
1711     rank = -1 # Ranks below any integer type
1712     to_py_function = "PyInt_FromLong"
1713     from_py_function = "PyInt_AsLong"
1714
1715     def __init__(self, name, cname, typedef_flag):
1716         self.name = name
1717         self.cname = cname
1718         self.values = []
1719         self.typedef_flag = typedef_flag
1720     
1721     def __str__(self):
1722         return self.name
1723     
1724     def __repr__(self):
1725         return "<CEnumType %s %s%s>" % (self.name, self.cname,
1726             ("", " typedef")[self.typedef_flag])
1727     
1728     def declaration_code(self, entity_code, 
1729             for_display = 0, dll_linkage = None, pyrex = 0):
1730         if pyrex:
1731             return self.base_declaration_code(self.cname, entity_code)
1732         else:
1733             if self.typedef_flag:
1734                 base = self.cname
1735             else:
1736                 base = "enum %s" % self.cname
1737             return self.base_declaration_code(public_decl(base, dll_linkage), entity_code)
1738
1739
1740 class CStringType(object):
1741     #  Mixin class for C string types.
1742
1743     is_string = 1
1744     is_unicode = 0
1745     
1746     to_py_function = "__Pyx_PyBytes_FromString"
1747     from_py_function = "__Pyx_PyBytes_AsString"
1748     exception_value = "NULL"
1749
1750     def literal_code(self, value):
1751         assert isinstance(value, str)
1752         return '"%s"' % StringEncoding.escape_byte_string(value)
1753
1754
1755 class CUTF8CharArrayType(CStringType, CArrayType):
1756     #  C 'char []' type.
1757     
1758     pymemberdef_typecode = "T_STRING_INPLACE"
1759     is_unicode = 1
1760     
1761     to_py_function = "PyUnicode_DecodeUTF8"
1762     exception_value = "NULL"
1763     
1764     def __init__(self, size):
1765         CArrayType.__init__(self, c_char_type, size)
1766
1767 class CCharArrayType(CStringType, CArrayType):
1768     #  C 'char []' type.
1769     
1770     pymemberdef_typecode = "T_STRING_INPLACE"
1771     
1772     def __init__(self, size):
1773         CArrayType.__init__(self, c_char_type, size)
1774     
1775
1776 class CCharPtrType(CStringType, CPtrType):
1777     # C 'char *' type.
1778     
1779     pymemberdef_typecode = "T_STRING"
1780     
1781     def __init__(self):
1782         CPtrType.__init__(self, c_char_type)
1783
1784
1785 class CUCharPtrType(CStringType, CPtrType):
1786     # C 'unsigned char *' type.
1787     
1788     pymemberdef_typecode = "T_STRING"
1789     
1790     to_py_function = "__Pyx_PyBytes_FromUString"
1791     from_py_function = "__Pyx_PyBytes_AsUString"
1792
1793     def __init__(self):
1794         CPtrType.__init__(self, c_uchar_type)
1795
1796
1797 class UnspecifiedType(PyrexType):
1798     # Used as a placeholder until the type can be determined.
1799     
1800     is_unspecified = 1
1801         
1802     def declaration_code(self, entity_code, 
1803             for_display = 0, dll_linkage = None, pyrex = 0):
1804         return "<unspecified>"
1805     
1806     def same_as_resolved_type(self, other_type):
1807         return False
1808         
1809
1810 class ErrorType(PyrexType):
1811     # Used to prevent propagation of error messages.
1812     
1813     is_error = 1
1814     exception_value = "0"
1815     exception_check    = 0
1816     to_py_function = "dummy"
1817     from_py_function = "dummy"
1818     
1819     def create_to_py_utility_code(self, env):
1820         return True
1821     
1822     def create_from_py_utility_code(self, env):
1823         return True
1824     
1825     def declaration_code(self, entity_code, 
1826             for_display = 0, dll_linkage = None, pyrex = 0):
1827         return "<error>"
1828     
1829     def same_as_resolved_type(self, other_type):
1830         return 1
1831         
1832     def error_condition(self, result_code):
1833         return "dummy"
1834
1835
1836 rank_to_type_name = (
1837     "char",         # 0
1838     "short",        # 1
1839     "int",          # 2
1840     "long",         # 3
1841     "Py_ssize_t",   # 4
1842     "size_t",       # 5
1843     "PY_LONG_LONG", # 6
1844     "float",        # 7
1845     "double",       # 8
1846     "long double",  # 9
1847 )
1848
1849 py_object_type = PyObjectType()
1850
1851 c_void_type =         CVoidType()
1852 c_void_ptr_type =     CPtrType(c_void_type)
1853 c_void_ptr_ptr_type = CPtrType(c_void_ptr_type)
1854
1855 c_uchar_type =       CIntType(0, 0, "T_UBYTE")
1856 c_ushort_type =      CIntType(1, 0, "T_USHORT")
1857 c_uint_type =        CUIntType(2, 0, "T_UINT")
1858 c_ulong_type =       CULongType(3, 0, "T_ULONG")
1859 c_ulonglong_type =   CULongLongType(6, 0, "T_ULONGLONG")
1860
1861 c_char_type =        CIntType(0, 1, "T_CHAR")
1862 c_short_type =       CIntType(1, 1, "T_SHORT")
1863 c_int_type =         CIntType(2, 1, "T_INT")
1864 c_long_type =        CLongType(3, 1, "T_LONG")
1865 c_longlong_type =    CLongLongType(6, 1, "T_LONGLONG")
1866 c_bint_type =        CBIntType(2, 1, "T_INT")
1867
1868 c_schar_type =       CIntType(0, 2, "T_CHAR")
1869 c_sshort_type =      CIntType(1, 2, "T_SHORT")
1870 c_sint_type =        CIntType(2, 2, "T_INT")
1871 c_slong_type =       CLongType(3, 2, "T_LONG")
1872 c_slonglong_type =   CLongLongType(6, 2, "T_LONGLONG")
1873
1874 c_py_ssize_t_type =  CPySSizeTType(4, 2, "T_PYSSIZET")
1875 c_size_t_type =      CSizeTType(5, 0, "T_SIZET")
1876
1877 c_float_type =       CFloatType(7, "T_FLOAT", math_h_modifier='f')
1878 c_double_type =      CFloatType(8, "T_DOUBLE")
1879 c_longdouble_type =  CFloatType(9, math_h_modifier='l')
1880
1881 c_double_complex_type = CComplexType(c_double_type)
1882
1883 c_null_ptr_type =     CNullPtrType(c_void_type)
1884 c_char_array_type =   CCharArrayType(None)
1885 c_char_ptr_type =     CCharPtrType()
1886 c_uchar_ptr_type =    CUCharPtrType()
1887 c_utf8_char_array_type = CUTF8CharArrayType(None)
1888 c_char_ptr_ptr_type = CPtrType(c_char_ptr_type)
1889 c_int_ptr_type =      CPtrType(c_int_type)
1890 c_py_ssize_t_ptr_type =  CPtrType(c_py_ssize_t_type)
1891 c_size_t_ptr_type =  CPtrType(c_size_t_type)
1892
1893 c_returncode_type =   CIntType(2, 1, "T_INT", is_returncode = 1)
1894
1895 c_anon_enum_type =    CAnonEnumType(-1, 1)
1896
1897 # the Py_buffer type is defined in Builtin.py
1898 c_py_buffer_type = CStructOrUnionType("Py_buffer", "struct", None, 1, "Py_buffer")
1899 c_py_buffer_ptr_type = CPtrType(c_py_buffer_type)
1900
1901 error_type =    ErrorType()
1902 unspecified_type = UnspecifiedType()
1903
1904 sign_and_rank_to_type = {
1905     #(signed, rank)
1906     (0, 0): c_uchar_type,
1907     (0, 1): c_ushort_type,
1908     (0, 2): c_uint_type,
1909     (0, 3): c_ulong_type,
1910     (0, 6): c_ulonglong_type,
1911
1912     (1, 0): c_char_type,
1913     (1, 1): c_short_type,
1914     (1, 2): c_int_type,
1915     (1, 3): c_long_type,
1916     (1, 6): c_longlong_type,
1917
1918     (2, 0): c_schar_type,
1919     (2, 1): c_sshort_type,
1920     (2, 2): c_sint_type,
1921     (2, 3): c_slong_type,
1922     (2, 6): c_slonglong_type,
1923
1924     (0, 4): c_py_ssize_t_type,
1925     (1, 4): c_py_ssize_t_type,
1926     (2, 4): c_py_ssize_t_type,
1927     (0, 5): c_size_t_type,
1928     (1, 5): c_size_t_type,
1929     (2, 5): c_size_t_type,
1930
1931     (1, 7): c_float_type,
1932     (1, 8): c_double_type,
1933     (1, 9): c_longdouble_type,
1934 # In case we're mixing unsigned ints and floats...
1935     (0, 7): c_float_type,
1936     (0, 8): c_double_type,
1937     (0, 9): c_longdouble_type,
1938 }
1939
1940 modifiers_and_name_to_type = {
1941     #(signed, longness, name)
1942     (0, 0, "char"): c_uchar_type,
1943     (0, -1, "int"): c_ushort_type,
1944     (0, 0, "int"): c_uint_type,
1945     (0, 1, "int"): c_ulong_type,
1946     (0, 2, "int"): c_ulonglong_type,
1947     (1, 0, "void"): c_void_type,
1948     (1, 0, "char"): c_char_type,
1949     (1, -1, "int"): c_short_type,
1950     (1, 0, "int"): c_int_type,
1951     (1, 1, "int"): c_long_type,
1952     (1, 2, "int"): c_longlong_type,
1953     (1, 0, "float"): c_float_type,
1954     (1, 0, "double"): c_double_type,
1955     (1, 1, "double"): c_longdouble_type,
1956     (1, 0, "object"): py_object_type,
1957     (1, 0, "bint"): c_bint_type,
1958     (2, 0, "char"): c_schar_type,
1959     (2, -1, "int"): c_sshort_type,
1960     (2, 0, "int"): c_sint_type,
1961     (2, 1, "int"): c_slong_type,
1962     (2, 2, "int"): c_slonglong_type,
1963
1964     (2, 0, "Py_ssize_t"): c_py_ssize_t_type,
1965     (0, 0, "size_t") : c_size_t_type,
1966
1967     (1, 0, "long"): c_long_type,
1968     (1, 0, "short"): c_short_type,
1969     (1, 0, "longlong"): c_longlong_type,
1970     (1, 0, "bint"): c_bint_type,
1971 }
1972
1973 def widest_numeric_type(type1, type2):
1974     # Given two numeric types, return the narrowest type
1975     # encompassing both of them.
1976     if type1 == type2:
1977         return type1
1978     if type1.is_complex:
1979         if type2.is_complex:
1980             return CComplexType(widest_numeric_type(type1.real_type, type2.real_type))
1981         else:
1982             return CComplexType(widest_numeric_type(type1.real_type, type2))
1983     elif type2.is_complex:
1984         return CComplexType(widest_numeric_type(type1, type2.real_type))
1985     if type1.is_enum and type2.is_enum:
1986         return c_int_type
1987     elif type1 is type2:
1988         return type1
1989     elif (type1.signed and type2.signed) or (not type1.signed and not type2.signed):
1990         if type2.rank > type1.rank:
1991             return type2
1992         else:
1993             return type1
1994     else:
1995         return sign_and_rank_to_type[min(type1.signed, type2.signed), max(type1.rank, type2.rank)]
1996     return widest_type
1997
1998 def spanning_type(type1, type2):
1999     # Return a type assignable from both type1 and type2.
2000     if type1 is py_object_type or type2 is py_object_type:
2001         return py_object_type
2002     elif type1 == type2:
2003         return type1
2004     elif type1.is_numeric and type2.is_numeric:
2005         return widest_numeric_type(type1, type2)
2006     elif type1.is_pyobject ^ type2.is_pyobject:
2007         return py_object_type
2008     elif type1.assignable_from(type2):
2009         return type1
2010     elif type2.assignable_from(type1):
2011         return type2
2012     else:
2013         return py_object_type
2014     
2015 def simple_c_type(signed, longness, name):
2016     # Find type descriptor for simple type given name and modifiers.
2017     # Returns None if arguments don't make sense.
2018     return modifiers_and_name_to_type.get((signed, longness, name))
2019     
2020 def parse_basic_type(name):
2021     base = None
2022     if name.startswith('p_'):
2023         base = parse_basic_type(name[2:])
2024     elif name.startswith('p'):
2025         base = parse_basic_type(name[1:])
2026     elif name.endswith('*'):
2027         base = parse_basic_type(name[:-1])
2028     if base:
2029         return CPtrType(base)
2030     elif name.startswith('u'):
2031         return simple_c_type(0, 0, name[1:])
2032     else:
2033         return simple_c_type(1, 0, name)
2034
2035 def c_array_type(base_type, size):
2036     # Construct a C array type.
2037     if base_type is c_char_type:
2038         return CCharArrayType(size)
2039     elif base_type is error_type:
2040         return error_type
2041     else:
2042         return CArrayType(base_type, size)
2043
2044 def c_ptr_type(base_type):
2045     # Construct a C pointer type.
2046     if base_type is c_char_type:
2047         return c_char_ptr_type
2048     elif base_type is c_uchar_type:
2049         return c_uchar_ptr_type
2050     elif base_type is error_type:
2051         return error_type
2052     else:
2053         return CPtrType(base_type)
2054
2055 def same_type(type1, type2):
2056     return type1.same_as(type2)
2057     
2058 def assignable_from(type1, type2):
2059     return type1.assignable_from(type2)
2060
2061 def typecast(to_type, from_type, expr_code):
2062     #  Return expr_code cast to a C type which can be
2063     #  assigned to to_type, assuming its existing C type
2064     #  is from_type.
2065     if to_type is from_type or \
2066         (not to_type.is_pyobject and assignable_from(to_type, from_type)):
2067             return expr_code
2068     else:
2069         #print "typecast: to", to_type, "from", from_type ###
2070         return to_type.cast_code(expr_code)
2071
2072
2073 type_conversion_predeclarations = """
2074 /* Type Conversion Predeclarations */
2075
2076 #if PY_MAJOR_VERSION < 3
2077 #define __Pyx_PyBytes_FromString          PyString_FromString
2078 #define __Pyx_PyBytes_FromStringAndSize   PyString_FromStringAndSize
2079 #define __Pyx_PyBytes_AsString            PyString_AsString
2080 #else
2081 #define __Pyx_PyBytes_FromString          PyBytes_FromString
2082 #define __Pyx_PyBytes_FromStringAndSize   PyBytes_FromStringAndSize
2083 #define __Pyx_PyBytes_AsString            PyBytes_AsString
2084 #endif
2085
2086 #define __Pyx_PyBytes_FromUString(s)      __Pyx_PyBytes_FromString((char*)s)
2087 #define __Pyx_PyBytes_AsUString(s)        ((unsigned char*) __Pyx_PyBytes_AsString(s))
2088
2089 #define __Pyx_PyBool_FromLong(b) ((b) ? (Py_INCREF(Py_True), Py_True) : (Py_INCREF(Py_False), Py_False))
2090 static INLINE int __Pyx_PyObject_IsTrue(PyObject*);
2091 static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x);
2092
2093 #if !defined(T_PYSSIZET)
2094 #if PY_VERSION_HEX < 0x02050000
2095 #define T_PYSSIZET T_INT
2096 #elif !defined(T_LONGLONG)
2097 #define T_PYSSIZET \\
2098         ((sizeof(Py_ssize_t) == sizeof(int))  ? T_INT  : \\
2099         ((sizeof(Py_ssize_t) == sizeof(long)) ? T_LONG : -1))
2100 #else
2101 #define T_PYSSIZET \\
2102         ((sizeof(Py_ssize_t) == sizeof(int))          ? T_INT      : \\
2103         ((sizeof(Py_ssize_t) == sizeof(long))         ? T_LONG     : \\
2104         ((sizeof(Py_ssize_t) == sizeof(PY_LONG_LONG)) ? T_LONGLONG : -1)))
2105 #endif
2106 #endif
2107
2108
2109 #if !defined(T_ULONGLONG)
2110 #define __Pyx_T_UNSIGNED_INT(x) \\
2111         ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
2112         ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
2113         ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
2114         ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : -1))))
2115 #else
2116 #define __Pyx_T_UNSIGNED_INT(x) \\
2117         ((sizeof(x) == sizeof(unsigned char))  ? T_UBYTE : \\
2118         ((sizeof(x) == sizeof(unsigned short)) ? T_USHORT : \\
2119         ((sizeof(x) == sizeof(unsigned int))   ? T_UINT : \\
2120         ((sizeof(x) == sizeof(unsigned long))  ? T_ULONG : \\
2121         ((sizeof(x) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))))
2122 #endif
2123 #if !defined(T_LONGLONG)
2124 #define __Pyx_T_SIGNED_INT(x) \\
2125         ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
2126         ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
2127         ((sizeof(x) == sizeof(int))   ? T_INT : \\
2128         ((sizeof(x) == sizeof(long))  ? T_LONG : -1))))
2129 #else
2130 #define __Pyx_T_SIGNED_INT(x) \\
2131         ((sizeof(x) == sizeof(char))  ? T_BYTE : \\
2132         ((sizeof(x) == sizeof(short)) ? T_SHORT : \\
2133         ((sizeof(x) == sizeof(int))   ? T_INT : \\
2134         ((sizeof(x) == sizeof(long))  ? T_LONG : \\
2135         ((sizeof(x) == sizeof(PY_LONG_LONG))   ? T_LONGLONG : -1)))))
2136 #endif
2137
2138 #define __Pyx_T_FLOATING(x) \\
2139         ((sizeof(x) == sizeof(float)) ? T_FLOAT : \\
2140         ((sizeof(x) == sizeof(double)) ? T_DOUBLE : -1))
2141
2142 #if !defined(T_SIZET)
2143 #if !defined(T_ULONGLONG)
2144 #define T_SIZET \\
2145         ((sizeof(size_t) == sizeof(unsigned int))  ? T_UINT  : \\
2146         ((sizeof(size_t) == sizeof(unsigned long)) ? T_ULONG : -1))
2147 #else
2148 #define T_SIZET \\
2149         ((sizeof(size_t) == sizeof(unsigned int))          ? T_UINT      : \\
2150         ((sizeof(size_t) == sizeof(unsigned long))         ? T_ULONG     : \\
2151         ((sizeof(size_t) == sizeof(unsigned PY_LONG_LONG)) ? T_ULONGLONG : -1)))
2152 #endif
2153 #endif
2154
2155 static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
2156 static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
2157 static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*);
2158
2159 #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
2160
2161 """ + type_conversion_predeclarations
2162
2163 type_conversion_functions = """
2164 /* Type Conversion Functions */
2165
2166 static INLINE int __Pyx_PyObject_IsTrue(PyObject* x) {
2167    if (x == Py_True) return 1;
2168    else if ((x == Py_False) | (x == Py_None)) return 0;
2169    else return PyObject_IsTrue(x);
2170 }
2171
2172 static INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) {
2173   PyNumberMethods *m;
2174   const char *name = NULL;
2175   PyObject *res = NULL;
2176 #if PY_VERSION_HEX < 0x03000000
2177   if (PyInt_Check(x) || PyLong_Check(x))
2178 #else
2179   if (PyLong_Check(x))
2180 #endif
2181     return Py_INCREF(x), x;
2182   m = Py_TYPE(x)->tp_as_number;
2183 #if PY_VERSION_HEX < 0x03000000
2184   if (m && m->nb_int) {
2185     name = "int";
2186     res = PyNumber_Int(x);
2187   }
2188   else if (m && m->nb_long) {
2189     name = "long";
2190     res = PyNumber_Long(x);
2191   }
2192 #else
2193   if (m && m->nb_int) {
2194     name = "int";
2195     res = PyNumber_Long(x);
2196   }
2197 #endif
2198   if (res) {
2199 #if PY_VERSION_HEX < 0x03000000
2200     if (!PyInt_Check(res) && !PyLong_Check(res)) {
2201 #else
2202     if (!PyLong_Check(res)) {
2203 #endif
2204       PyErr_Format(PyExc_TypeError,
2205                    "__%s__ returned non-%s (type %.200s)",
2206                    name, name, Py_TYPE(res)->tp_name);
2207       Py_DECREF(res);
2208       return NULL;
2209     }
2210   }
2211   else if (!PyErr_Occurred()) {
2212     PyErr_SetString(PyExc_TypeError,
2213                     "an integer is required");
2214   }
2215   return res;
2216 }
2217
2218 static INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
2219   Py_ssize_t ival;
2220   PyObject* x = PyNumber_Index(b);
2221   if (!x) return -1;
2222   ival = PyInt_AsSsize_t(x);
2223   Py_DECREF(x);
2224   return ival;
2225 }
2226
2227 static INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t ival) {
2228 #if PY_VERSION_HEX < 0x02050000
2229    if (ival <= LONG_MAX)
2230        return PyInt_FromLong((long)ival);
2231    else {
2232        unsigned char *bytes = (unsigned char *) &ival;
2233        int one = 1; int little = (int)*(unsigned char*)&one;
2234        return _PyLong_FromByteArray(bytes, sizeof(size_t), little, 0);
2235    }
2236 #else
2237    return PyInt_FromSize_t(ival);
2238 #endif
2239 }
2240
2241 static INLINE size_t __Pyx_PyInt_AsSize_t(PyObject* x) {
2242    unsigned PY_LONG_LONG val = __Pyx_PyInt_AsUnsignedLongLong(x);
2243    if (unlikely(val == (unsigned PY_LONG_LONG)-1 && PyErr_Occurred())) {
2244        return (size_t)-1;
2245    } else if (unlikely(val != (unsigned PY_LONG_LONG)(size_t)val)) {
2246        PyErr_SetString(PyExc_OverflowError,
2247                        "value too large to convert to size_t");
2248        return (size_t)-1;
2249    }
2250    return (size_t)val;
2251 }
2252
2253 """ + type_conversion_functions
2254
2255