Pyrex Official version 0.9.5.1a
authorRobert Bradshaw <robertwb@math.washington.edu>
Thu, 7 Jun 2007 02:22:57 +0000 (19:22 -0700)
committerRobert Bradshaw <robertwb@math.washington.edu>
Thu, 7 Jun 2007 02:22:57 +0000 (19:22 -0700)
16 files changed:
Cython/Compiler/Code.py
Cython/Compiler/ExprNodes.py
Cython/Compiler/ModuleNode.py [new file with mode: 0644]
Cython/Compiler/Nodes.py
Cython/Compiler/Parsing.py
Cython/Compiler/PyrexTypes.py
Cython/Compiler/Symtab.py
Cython/Compiler/Version.py
Cython/Mac/DarwinSystem.py
Cython/Mac/Finder_Std_Suite.py [deleted file]
Cython/Mac/MPW_Misc_Suite.py [deleted file]
Cython/Mac/Makefile [new file with mode: 0644]
Cython/Mac/PS_Misc_Suite.py [deleted file]
Cython/Mac/PyServerMain.py [deleted file]
Cython/Mac/_Filemodule_patched.c
Cython/Unix/LinuxSystem.py [new file with mode: 0644]

index a9a7982906cbd04e5d885b03a3b62fe999e2efd3..5158e3bc11b281781267bcf03f1e7d04af3eda1d 100644 (file)
@@ -22,8 +22,9 @@ class CCodeWriter:
     
     in_try_finally = 0
     
-    def __init__(self, outfile_name):
-        self.f = open_new_file(outfile_name)
+    def __init__(self, f):
+        #self.f = open_new_file(outfile_name)
+        self.f = f
         self.level = 0
         self.bol = 1
         self.marker = None
@@ -80,6 +81,7 @@ class CCodeWriter:
 
     def init_labels(self):
         self.label_counter = 0
+        self.labels_used = {}
         self.return_label = self.new_label()
         self.new_error_label()
         self.continue_label = None
@@ -134,9 +136,17 @@ class CCodeWriter:
                 new_labels.append(old_label)
         self.set_all_labels(new_labels)
         return old_labels
+    
+    def use_label(self, lbl):
+        self.labels_used[lbl] = 1
 
     def put_label(self, lbl):
-        self.putln("%s:;" % lbl)
+        if lbl in self.labels_used:
+            self.putln("%s:;" % lbl)
+    
+    def put_goto(self, lbl):
+        self.use_label(lbl)
+        self.putln("goto %s;" % lbl)
     
     def put_var_declarations(self, entries, static = 0, dll_linkage = None,
             definition = True):
@@ -146,28 +156,23 @@ class CCodeWriter:
     
     def put_var_declaration(self, entry, static = 0, dll_linkage = None,
             definition = True):
-        #print "Code.put_var_declaration:", entry.name, "definition =", definition
+        #print "Code.put_var_declaration:", entry.name, "definition =", definition ###
         visibility = entry.visibility
         if visibility == 'private' and not definition:
             return
+        if not entry.used and visibility == "private":
+            return
+        storage_class = ""
         if visibility == 'extern':
             storage_class = Naming.extern_c_macro
         elif visibility == 'public':
-            if definition:
-                storage_class = ""
-            else:
+            if not definition:
                 storage_class = Naming.extern_c_macro
         elif visibility == 'private':
             if static:
                 storage_class = "static"
-            else:
-                storage_class = ""
         if storage_class:
             self.put("%s " % storage_class)
-        #if visibility == 'extern' or visibility == 'public' and not definition:
-        #      self.put("%s " % Naming.extern_c_macro)
-        #elif static and visibility <> 'public':
-        #      self.put("static ")
         if visibility <> 'public':
             dll_linkage = None
         self.put(entry.type.declaration_code(entry.cname,
@@ -186,10 +191,6 @@ class CCodeWriter:
     
     def as_pyobject(self, cname, type):
         return typecast(py_object_type, type, cname)
-        #if type.is_extension_type and type.base_type:
-        #      return "(PyObject *)" + cname
-        #else:
-        #      return cname
     
     def put_incref(self, cname, type):
         self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
@@ -231,12 +232,13 @@ class CCodeWriter:
             self.putln("Py_XDECREF(%s); %s = 0;" % (
                 self.entry_as_pyobject(entry), entry.cname))
     
-    def put_var_decrefs(self, entries):
+    def put_var_decrefs(self, entries, used_only = 0):
         for entry in entries:
-            if entry.xdecref_cleanup:
-                self.put_var_xdecref(entry)
-            else:
-                self.put_var_decref(entry)
+            if not used_only or entry.used:
+                if entry.xdecref_cleanup:
+                    self.put_var_xdecref(entry)
+                else:
+                    self.put_var_decref(entry)
     
     def put_var_xdecrefs(self, entries):
         for entry in entries:
@@ -269,13 +271,15 @@ class CCodeWriter:
                 term))
     
     def error_goto(self, pos):
+        lbl = self.error_label
+        self.use_label(lbl)
         return "{%s = %s[%s]; %s = %s; goto %s;}" % (
             Naming.filename_cname,
             Naming.filetable_cname,
             self.lookup_filename(pos[0]),
             Naming.lineno_cname,
             pos[1],
-            self.error_label)
+            lbl)
     
     def lookup_filename(self, filename):
         try:
index d194335cf103d62372932c33860698fff2ae469d..0456342bbc16a98e1b784983202ef0e6de1481ef 100644 (file)
@@ -8,7 +8,7 @@ from Errors import error, InternalError
 import Naming
 from Nodes import Node
 import PyrexTypes
-from PyrexTypes import py_object_type, typecast
+from PyrexTypes import py_object_type, c_long_type, typecast
 import Symtab
 import Options
 
@@ -89,13 +89,23 @@ class ExprNode(Node):
     #        - If a temporary was allocated, call release_temp on 
     #          all sub-expressions.
     #
-    #        A default implementation of allocate_temps is 
-    #        provided which uses the following abstract method:
+    #      allocate_target_temps
+    #        - Call allocate_temps on sub-nodes and allocate any other
+    #          temps used during assignment.
+    #        - Fill in result_code with a C lvalue if needed.
+    #        - If a rhs node is supplied, call release_temp on it.
+    #        - Call release_temp on sub-nodes and release any other
+    #          temps used during assignment.
     #
-    #          calculate_result_code
-    #            - Return a C code fragment evaluating to
-    #              the result. This is only called when the
-    #              result is not a temporary.
+    #      calculate_result_code
+    #        - Return a C code fragment evaluating to
+    #          the result. This is only called when the
+    #          result is not a temporary.
+    #
+    #      target_code
+    #        Called by the default implementation of allocate_target_temps.
+    #        Should return a C lvalue for assigning to the node. The default
+    #        implementation calls calculate_result_code.
     #
     #      check_const
     #        - Check that this node and its subnodes form a
@@ -145,16 +155,6 @@ class ExprNode(Node):
     #        - Generate code to perform the deletion.
     #        - Call generate_disposal_code on all sub-expressions.
     #
-    #       #result_as_extension_type ### OBSOLETE ###
-    #       #  Normally, the results of all nodes whose type
-    #       #  is a Python object, either generic or an extension
-    #       #  type, are returned as a generic Python object, so
-    #       #  that they can be passed directly to Python/C API
-    #       #  routines. This method is called to obtain the
-    #       #  result as the actual type of the node. It is only
-    #       #  called when the type is known to actually be an
-    #       #  extension type, and nodes whose result can never
-    #       #  be an extension type need not implement it.
     #
     
     is_sequence_constructor = 0
@@ -231,12 +231,12 @@ class ExprNode(Node):
         self.analyse_types(env)
         self.allocate_temps(env)
     
-    def analyse_target_expression(self, env):
+    def analyse_target_expression(self, env, rhs):
         #  Convenience routine performing both the Type
         #  Analysis and Temp Allocation phases for the LHS of
         #  an assignment.
         self.analyse_target_types(env)
-        self.allocate_target_temps(env)
+        self.allocate_target_temps(env, rhs)
     
     def analyse_boolean_expression(self, env):
         #  Analyse expression and coerce to a boolean.
@@ -298,12 +298,15 @@ class ExprNode(Node):
         #  a subnode.
         return self.is_temp
             
-    def allocate_target_temps(self, env):
-        #  Perform allocate_temps for the LHS of an assignment.
+    def allocate_target_temps(self, env, rhs):
+        #  Perform temp allocation for the LHS of an assignment.
         if debug_temp_alloc:
             print self, "Allocating target temps"
         self.allocate_subexpr_temps(env)
         self.result_code = self.target_code()
+        if rhs:
+            rhs.release_temp(env)
+        self.release_subexpr_temps(env)
     
     def allocate_temps(self, env, result = None):
         #  Allocate temporary variables for this node and
@@ -362,9 +365,9 @@ class ExprNode(Node):
     def calculate_result_code(self):
         self.not_implemented("calculate_result_code")
     
-    def release_target_temp(self, env):
-        #  Release temporaries used by LHS of an assignment.
-        self.release_subexpr_temps(env)
+#      def release_target_temp(self, env):
+#              #  Release temporaries used by LHS of an assignment.
+#              self.release_subexpr_temps(env)
 
     def release_temp(self, env):
         #  If this node owns a temporary result, release it,
@@ -463,7 +466,8 @@ class ExprNode(Node):
             if not src.type.is_pyobject:
                 src = CoerceToPyTypeNode(src, env)
             if not src.type.subtype_of(dst_type):
-                src = PyTypeTestNode(src, dst_type, env)
+                if not isinstance(src, NoneNode):
+                    src = PyTypeTestNode(src, dst_type, env)
         elif src.type.is_pyobject:
             src = CoerceFromPyTypeNode(dst_type, src, env)
         else: # neither src nor dst are py types
@@ -576,7 +580,7 @@ class ConstNode(AtomicExprNode):
 
 class NullNode(ConstNode):
     type = PyrexTypes.c_null_ptr_type
-    value = "0"
+    value = "NULL"
 
 
 class CharNode(ConstNode):
@@ -703,13 +707,14 @@ class NameNode(AtomicExprNode):
         
     def analyse_entry(self, env):
         self.check_identifier_kind()
-        self.type = self.entry.type
-        if self.entry.is_declared_generic:
+        entry = self.entry
+        self.type = entry.type
+        if entry.is_declared_generic:
             self.result_ctype = py_object_type
-        # Reference to C array turns into pointer to first element.
-        while self.type.is_array:
-            self.type = self.type.element_ptr_type()
-        if self.entry.is_pyglobal or self.entry.is_builtin:
+        ## Reference to C array turns into pointer to first element.
+        #while self.type.is_array:
+        #      self.type = self.type.element_ptr_type()
+        if entry.is_pyglobal or entry.is_builtin:
             assert self.type.is_pyobject, "Python global or builtin not a Python object"
             self.is_temp = 1
             if Options.intern_names:
@@ -727,7 +732,9 @@ class NameNode(AtomicExprNode):
             self.type = PyrexTypes.error_type
     
     def check_identifier_kind(self):
+        #print "NameNode.check_identifier_kind:", self.entry.name ###
         entry = self.entry
+        entry.used = 1
         if not (entry.is_const or entry.is_variable 
             or entry.is_builtin or entry.is_cfunction):
                 if self.entry.as_variable:
@@ -1071,11 +1078,11 @@ class IndexNode(ExprNode):
                     self.index.py_result(),
                     rhs.py_result(),
                     code.error_goto(self.pos)))
-            self.generate_subexpr_disposal_code(code)
         else:
             code.putln(
                 "%s = %s;" % (
                     self.result_code, rhs.result_code))
+        self.generate_subexpr_disposal_code(code)
         rhs.generate_disposal_code(code)
     
     def generate_deletion_code(self, code):
@@ -1220,9 +1227,12 @@ class SimpleCallNode(ExprNode):
             function.obj = CloneNode(self.self)
         func_type = self.function_type()
         if func_type.is_pyobject:
-            self.arg_tuple = TupleNode(self.pos, args = self.args)
+            if self.args:
+                self.arg_tuple = TupleNode(self.pos, args = self.args)
+                self.arg_tuple.analyse_types(env)
+            else:
+                self.arg_tuple = None
             self.args = None
-            self.arg_tuple.analyse_types(env)
             self.type = py_object_type
             self.is_temp = 1
         else:
@@ -1309,11 +1319,15 @@ class SimpleCallNode(ExprNode):
     def generate_result_code(self, code):
         func_type = self.function_type()
         if func_type.is_pyobject:
+            if self.arg_tuple:
+                arg_code = self.arg_tuple.py_result()
+            else:
+                arg_code = "0"
             code.putln(
                 "%s = PyObject_CallObject(%s, %s); if (!%s) %s" % (
                     self.result_code,
                     self.function.py_result(),
-                    self.arg_tuple.py_result(),
+                    arg_code,
                     self.result_code,
                     code.error_goto(self.pos)))
         elif func_type.is_cfunction:
@@ -1535,9 +1549,9 @@ class AttributeNode(ExprNode):
         self.analyse_attribute(env)
         if self.entry and self.entry.is_cmethod and not self.is_called:
             error(self.pos, "C method can only be called")
-        # Reference to C array turns into pointer to first element.
-        while self.type.is_array:
-            self.type = self.type.element_ptr_type()
+        ## Reference to C array turns into pointer to first element.
+        #while self.type.is_array:
+        #      self.type = self.type.element_ptr_type()
         if self.is_py_attr:
             if not target:
                 self.is_temp = 1
@@ -1568,6 +1582,8 @@ class AttributeNode(ExprNode):
                 obj_type = PyrexTypes.error_type
             self.entry = entry
             if entry:
+                if obj_type.is_extension_type and entry.name == "__weakref__":
+                    error(self.pos, "Illegal use of special attribute __weakref__")
                 if entry.is_variable or entry.is_cmethod:
                     self.type = entry.type
                     self.member = entry.cname
@@ -1662,7 +1678,6 @@ class AttributeNode(ExprNode):
                         code.error_goto(self.pos)))
             rhs.generate_disposal_code(code)
         else:
-            #select_code = self.select_code()
             select_code = self.result_code
             if self.type.is_pyobject:
                 rhs.make_owned_reference(code)
@@ -1670,7 +1685,8 @@ class AttributeNode(ExprNode):
             code.putln(
                 "%s = %s;" % (
                     select_code,
-                    rhs.result_code))
+                    rhs.result_as(self.ctype())))
+                    #rhs.result_code))
             rhs.generate_post_assignment_code(code)
         self.obj.generate_disposal_code(code)
     
@@ -1704,6 +1720,7 @@ class SequenceNode(ExprNode):
     #  Contains common code for performing sequence unpacking.
     #
     #  args                    [ExprNode]
+    #  iterator                ExprNode
     #  unpacked_items          [ExprNode] or None
     #  coerced_unpacked_items  [ExprNode] or None
     
@@ -1725,11 +1742,11 @@ class SequenceNode(ExprNode):
         self.is_temp = 1
     
     def analyse_target_types(self, env):
-        self.unpacked_items = [] # PyTempNode(self.pos, env)
+        self.iterator = PyTempNode(self.pos, env)
+        self.unpacked_items = []
         self.coerced_unpacked_items = []
         for arg in self.args:
             arg.analyse_target_types(env)
-            #node = CloneNode(self.unpacked_item)
             unpacked_item = PyTempNode(self.pos, env)
             coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
             self.unpacked_items.append(unpacked_item)
@@ -1737,27 +1754,39 @@ class SequenceNode(ExprNode):
         self.type = py_object_type
         env.use_utility_code(unpacking_utility_code)
     
-    def allocate_target_temps(self, env):
-        for arg in self.args:
-            arg.allocate_target_temps(env)
-        for node in self.coerced_unpacked_items:
+    def allocate_target_temps(self, env, rhs):
+        self.iterator.allocate_temps(env)
+        if rhs:
+            rhs.release_temp(env)
+        for arg, node in zip(self.args, self.coerced_unpacked_items):
             node.allocate_temps(env)
-    
-    def release_target_temp(self, env):
-        for arg in self.args:
-            arg.release_target_temp(env)
-        for node in self.coerced_unpacked_items:
-            node.release_temp(env)
+            arg.allocate_target_temps(env, node)
+            #arg.release_target_temp(env)
+            #node.release_temp(env)
+        self.iterator.release_temp(env)
+    
+#      def release_target_temp(self, env):
+#              #for arg in self.args:
+#              #       arg.release_target_temp(env)
+#              #for node in self.coerced_unpacked_items:
+#              #       node.release_temp(env)
+#              self.iterator.release_temp(env)
     
     def generate_result_code(self, code):
         self.generate_operation_code(code)
     
     def generate_assignment_code(self, rhs, code):
+        code.putln(
+            "%s = PyObject_GetIter(%s); if (!%s) %s" % (
+                self.iterator.result_code,
+                rhs.py_result(),
+                self.iterator.result_code,
+                code.error_goto(self.pos)))
+        rhs.generate_disposal_code(code)
         for i in range(len(self.args)):
             item = self.unpacked_items[i]
-            unpack_code = "__Pyx_UnpackItem(%s, %s)" % (
-                rhs.py_result(),
-                i)
+            unpack_code = "__Pyx_UnpackItem(%s)" % (
+                self.iterator.py_result())
             code.putln(
                 "%s = %s; if (!%s) %s" % (
                     item.result_code,
@@ -1768,14 +1797,13 @@ class SequenceNode(ExprNode):
             value_node.generate_evaluation_code(code)
             self.args[i].generate_assignment_code(value_node, code)
         code.putln(
-            "if (__Pyx_EndUnpack(%s, %s) < 0) %s" % (
-                rhs.py_result(),
-                len(self.args),
+            "if (__Pyx_EndUnpack(%s) < 0) %s" % (
+                self.iterator.py_result(),
                 code.error_goto(self.pos)))
         if debug_disposal_code:
             print "UnpackNode.generate_assignment_code:"
             print "...generating disposal code for", rhs
-        rhs.generate_disposal_code(code)
+        self.iterator.generate_disposal_code(code)
 
 
 class TupleNode(SequenceNode):
@@ -2560,10 +2588,13 @@ class CmpNode:
             return 1
         if type1.is_pyobject: # type2 will be, too
             return 1
-        elif type1.is_ptr:
+        elif type1.is_ptr or type1.is_array:
             return type1.is_null_ptr or type2.is_null_ptr \
-                or type1.same_as(type2)
-        elif (type1.is_numeric and type2.is_numeric
+                or ((type2.is_ptr or type2.is_array)
+                    and type1.base_type.same_as(type2.base_type))
+        elif ((type1.is_numeric and type2.is_numeric
+                    or type1.is_enum and (type1 is type2 or type2.is_int)
+                    or type1.is_int and type2.is_enum)
                 and op not in ('is', 'is_not')):
             return 1
         else:
@@ -2819,9 +2850,6 @@ class CastNode(CoercionNode):
         self.type = new_type
     
     def calculate_result_code(self):
-        #return "((%s)%s)" % (
-        #      self.type.declaration_code(""),
-        #      self.arg.result)
         return self.arg.result_as(self.type)
 
     def generate_result_code(self, code):
@@ -2904,12 +2932,14 @@ class CoerceFromPyTypeNode(CoercionNode):
                 "Obtaining char * from temporary Python value")
     
     def generate_result_code(self, code):
-        #opnd = self.arg.py_result()
         function = self.type.from_py_function
-        code.putln('%s = %s(%s); if (PyErr_Occurred()) %s' % (
+        operand = self.arg.py_result()
+        rhs = "%s(%s)" % (function, operand)
+        if self.type.is_enum:
+            rhs = typecast(self.type, c_long_type, rhs)
+        code.putln('%s = %s; if (PyErr_Occurred()) %s' % (
             self.result_code, 
-            function, 
-            self.arg.py_result(), 
+            rhs, 
             code.error_goto(self.pos)))
 
 
@@ -2995,8 +3025,10 @@ class CloneNode(CoercionNode):
 #
 #------------------------------------------------------------------------------------
 
-get_name_utility_code = \
+get_name_utility_code = [
 """
+static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/
+""","""
 static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
     PyObject *result;
     result = PyObject_GetAttrString(dict, name);
@@ -3004,10 +3036,12 @@ static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
         PyErr_SetString(PyExc_NameError, name);
     return result;
 }
-"""
+"""]
 
-get_name_interned_utility_code = \
+get_name_interned_utility_code = [
 """
+static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
+""","""
 static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
     PyObject *result;
     result = PyObject_GetAttr(dict, name);
@@ -3015,12 +3049,14 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
         PyErr_SetObject(PyExc_NameError, name);
     return result;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-import_utility_code = \
+import_utility_code = [
 """
+static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
+""","""
 static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
     PyObject *__import__ = 0;
     PyObject *empty_list = 0;
@@ -3056,12 +3092,14 @@ bad:
 """ % {
     "BUILTINS": Naming.builtins_cname,
     "GLOBALS":  Naming.module_cname,
-}
+}]
 
 #------------------------------------------------------------------------------------
 
-get_exception_utility_code = \
+get_exception_utility_code = [
 """
+static PyObject *__Pyx_GetExcValue(void); /*proto*/
+""","""
 static PyObject *__Pyx_GetExcValue(void) {
     PyObject *type = 0, *value = 0, *tb = 0;
     PyObject *result = 0;
@@ -3091,41 +3129,48 @@ bad:
     Py_XDECREF(tb);
     return result;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-unpacking_utility_code = \
+unpacking_utility_code = [
 """
+static PyObject *__Pyx_UnpackItem(PyObject *); /*proto*/
+static int __Pyx_EndUnpack(PyObject *); /*proto*/
+""","""
 static void __Pyx_UnpackError(void) {
     PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size");
 }
 
-static PyObject *__Pyx_UnpackItem(PyObject *seq, int i) {
-  PyObject *item;
-  if (!(item = PySequence_GetItem(seq, i))) {
-    if (PyErr_ExceptionMatches(PyExc_IndexError))
-       __Pyx_UnpackError();
-  }
-  return item;
+static PyObject *__Pyx_UnpackItem(PyObject *iter) {
+    PyObject *item;
+    if (!(item = PyIter_Next(iter))) {
+        if (!PyErr_Occurred())
+            __Pyx_UnpackError();
+    }
+    return item;
 }
 
-static int __Pyx_EndUnpack(PyObject *seq, int i) {
-  PyObject *item;
-  if (item = PySequence_GetItem(seq, i)) {
-    Py_DECREF(item);
-    __Pyx_UnpackError();
-    return -1;
-  }
-  PyErr_Clear();
-    return 0;
+static int __Pyx_EndUnpack(PyObject *iter) {
+    PyObject *item;
+    if ((item = PyIter_Next(iter))) {
+        Py_DECREF(item);
+        __Pyx_UnpackError();
+        return -1;
+    }
+    else if (!PyErr_Occurred())
+        return 0;
+    else
+        return -1;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-type_test_utility_code = \
+type_test_utility_code = [
 """
+static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
+""","""
 static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
     if (!type) {
         PyErr_Format(PyExc_SystemError, "Missing type object");
@@ -3137,12 +3182,14 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
         obj->ob_type->tp_name, type->tp_name);
     return 0;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-create_class_utility_code = \
+create_class_utility_code = [
 """
+static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
+""","""
 static PyObject *__Pyx_CreateClass(
     PyObject *bases, PyObject *dict, PyObject *name, char *modname)
 {
@@ -3159,6 +3206,6 @@ bad:
     Py_XDECREF(py_modname);
     return result;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
new file mode 100644 (file)
index 0000000..3760e5c
--- /dev/null
@@ -0,0 +1,1270 @@
+#
+#   Pyrex - Module parse tree node
+#
+
+import os, time
+from cStringIO import StringIO
+
+import Code
+import Naming
+import Nodes
+import Options
+import PyrexTypes
+import TypeSlots
+import Version
+
+from Errors import error
+from PyrexTypes import py_object_type
+from Pyrex.Utils import open_new_file, replace_suffix
+
+class ModuleNode(Nodes.Node, Nodes.BlockNode):
+    #  doc       string or None
+    #  body      StatListNode
+    
+    def analyse_declarations(self, env):
+        env.doc = self.doc
+        self.body.analyse_declarations(env)
+    
+    def process_implementation(self, env, result):
+        self.analyse_declarations(env)
+        env.check_c_classes()
+        self.body.analyse_expressions(env)
+        env.return_type = PyrexTypes.c_void_type
+        self.generate_c_code(env, result)
+        self.generate_h_code(env, result)
+    
+    def generate_h_code(self, env, result):
+        public_vars_and_funcs = []
+        public_extension_types = []
+        for entry in env.var_entries:
+            if entry.visibility == 'public':
+                public_vars_and_funcs.append(entry)
+        for entry in env.cfunc_entries:
+            if entry.visibility == 'public':
+                public_vars_and_funcs.append(entry)
+        for entry in env.c_class_entries:
+            if entry.visibility == 'public':
+                public_extension_types.append(entry)
+        if public_vars_and_funcs or public_extension_types:
+            result.h_file = replace_suffix(result.c_file, ".h")
+            result.i_file = replace_suffix(result.c_file, ".pxi")
+            h_code = Code.CCodeWriter(open_new_file(result.h_file))
+            i_code = Code.PyrexCodeWriter(result.i_file)
+            self.generate_extern_c_macro_definition(h_code)
+            for entry in public_vars_and_funcs:
+                h_code.putln("%s %s;" % (
+                    Naming.extern_c_macro,
+                    entry.type.declaration_code(
+                        entry.cname, dll_linkage = "DL_IMPORT")))
+                i_code.putln("cdef extern %s" % 
+                    entry.type.declaration_code(entry.cname, pyrex = 1))
+            for entry in public_extension_types:
+                self.generate_cclass_header_code(entry.type, h_code)
+                self.generate_cclass_include_code(entry.type, i_code)
+            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
+    
+    def generate_cclass_header_code(self, type, h_code):
+        #h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
+        h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
+            Naming.extern_c_macro,
+            type.typeobj_cname))
+        self.generate_obj_struct_definition(type, h_code)
+    
+    def generate_cclass_include_code(self, type, i_code):
+        i_code.putln("cdef extern class %s.%s:" % (
+            type.module_name, type.name))
+        i_code.indent()
+        var_entries = type.scope.var_entries
+        if var_entries:
+            for entry in var_entries:
+                i_code.putln("cdef %s" % 
+                    entry.type.declaration_code(entry.cname, pyrex = 1))
+        else:
+            i_code.putln("pass")
+        i_code.dedent()
+    
+    def generate_c_code(self, env, result):
+        modules = []
+        self.find_referenced_modules(env, modules, {})
+        #code = Code.CCodeWriter(result.c_file)
+        code = Code.CCodeWriter(StringIO())
+        code.h = Code.CCodeWriter(StringIO())
+        code.init_labels()
+        self.generate_module_preamble(env, modules, code.h)
+
+        code.putln("")
+        code.putln("/* Implementation of %s */" % env.qualified_name)
+        self.generate_const_definitions(env, code)
+        self.generate_interned_name_decls(env, code)
+        self.generate_py_string_decls(env, code)
+        self.body.generate_function_definitions(env, code)
+        self.generate_interned_name_table(env, code)
+        self.generate_py_string_table(env, code)
+        self.generate_typeobj_definitions(env, code)
+        self.generate_method_table(env, code)
+        self.generate_filename_init_prototype(code)
+        self.generate_module_init_func(modules[:-1], env, code)
+        self.generate_filename_table(code)
+        self.generate_utility_functions(env, code)
+
+        for module in modules:
+            self.generate_declarations_for_module(module, code.h,
+                definition = module is env)
+
+        f = open_new_file(result.c_file)
+        f.write(code.h.f.getvalue())
+        f.write("\n")
+        f.write(code.f.getvalue())
+        f.close()
+        result.c_file_generated = 1
+    
+    def find_referenced_modules(self, env, module_list, modules_seen):
+        if env not in modules_seen:
+            modules_seen[env] = 1
+            for imported_module in env.cimported_modules:
+                self.find_referenced_modules(imported_module, module_list, modules_seen)
+            module_list.append(env)
+        
+    def generate_module_preamble(self, env, cimported_modules, code):
+        code.putln('/* Generated by Pyrex %s on %s */' % (
+            Version.version, time.asctime()))
+        code.putln('')
+        for filename in env.python_include_files:
+            code.putln('#include "%s"' % filename)
+        code.putln("#ifndef PY_LONG_LONG")
+        code.putln("  #define PY_LONG_LONG LONG_LONG")
+        code.putln("#endif")
+        self.generate_extern_c_macro_definition(code)
+        code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
+        self.generate_includes(env, cimported_modules, code)
+        #for filename in env.include_files:
+        #      code.putln('#include "%s"' % filename)
+        code.putln('')
+        code.put(Nodes.utility_function_predeclarations)
+        #if Options.intern_names:
+        #      code.putln(Nodes.get_name_interned_predeclaration)
+        #else:
+        #      code.putln(get_name_predeclaration)
+        code.putln('')
+        code.putln('static PyObject *%s;' % env.module_cname)
+        code.putln('static PyObject *%s;' % Naming.builtins_cname)
+        code.putln('static int %s;' % Naming.lineno_cname)
+        code.putln('static char *%s;' % Naming.filename_cname)
+        code.putln('static char **%s;' % Naming.filetable_cname)
+        if env.doc:
+            code.putln('')
+            code.putln('static char %s[] = "%s";' % (env.doc_cname, env.doc))
+    
+    def generate_extern_c_macro_definition(self, code):
+        name = Naming.extern_c_macro
+        code.putln("#ifdef __cplusplus")
+        code.putln('#define %s extern "C"' % name)
+        code.putln("#else")
+        code.putln("#define %s extern" % name)
+        code.putln("#endif")
+
+    def generate_includes(self, env, cimported_modules, code):
+        includes = env.include_files[:]
+        for module in cimported_modules:
+            for filename in module.include_files:
+                if filename not in includes:
+                    includes.append(filename)
+        for filename in includes:
+            code.putln('#include "%s"' % filename)
+    
+    def generate_filename_table(self, code):
+        code.putln("")
+        code.putln("static char *%s[] = {" % Naming.filenames_cname)
+        if code.filename_list:
+            for filename in code.filename_list:
+                filename = os.path.basename(filename)
+                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
+                code.putln('"%s",' % 
+                    escaped_filename)
+        else:
+            # Some C compilers don't like an empty array
+            code.putln("0")
+        code.putln("};")
+    
+    def generate_declarations_for_module(self, env, code, definition):
+        code.putln("")
+        code.putln("/* Declarations from %s */" % env.qualified_name)
+        self.generate_type_predeclarations(env, code)
+        self.generate_type_definitions(env, code)
+        self.generate_global_declarations(env, code, definition)
+        self.generate_cfunction_predeclarations(env, code)
+
+    def generate_type_predeclarations(self, env, code):
+        pass
+    
+    def generate_type_definitions(self, env, code):
+        # Generate definitions of structs/unions/enums.
+        for entry in env.sue_entries:
+            if not entry.in_cinclude:
+                type = entry.type
+                if type.is_struct_or_union:
+                    self.generate_struct_union_definition(entry, code)
+                else:
+                    self.generate_enum_definition(entry, code)
+        # Generate extension type object struct definitions.
+        for entry in env.c_class_entries:
+            if not entry.in_cinclude:
+                self.generate_typeobject_predeclaration(entry, code)
+                self.generate_obj_struct_definition(entry.type, code)
+                self.generate_exttype_vtable_struct(entry, code)
+                self.generate_exttype_vtabptr_declaration(entry, code)
+    
+    def sue_header_footer(self, type, kind, name):
+        if type.typedef_flag:
+            header = "typedef %s {" % kind
+            footer = "} %s;" % name
+        else:
+            header = "%s %s {" % (kind, name)
+            footer = "};"
+        return header, footer
+    
+    def generate_struct_union_definition(self, entry, code):
+        type = entry.type
+        scope = type.scope
+        if scope:
+            header, footer = \
+                self.sue_header_footer(type, type.kind, type.cname)
+            code.putln("")
+            code.putln(header)
+            var_entries = scope.var_entries
+            if not var_entries:
+                error(entry.pos,
+                    "Empty struct or union definition not allowed outside a"
+                    " 'cdef extern from' block")
+            for attr in var_entries:
+                code.putln(
+                    "%s;" %
+                        attr.type.declaration_code(attr.cname))
+            code.putln(footer)
+
+    def generate_enum_definition(self, entry, code):
+        type = entry.type
+        name = entry.cname or entry.name or ""
+        header, footer = \
+            self.sue_header_footer(type, "enum", name)
+        code.putln("")
+        code.putln(header)
+        enum_values = entry.enum_values
+        if not enum_values:
+            error(entry.pos,
+                "Empty enum definition not allowed outside a"
+                " 'cdef extern from' block")
+        else:
+            last_entry = enum_values[-1]
+            for value_entry in enum_values:
+                if value_entry.value == value_entry.name:
+                    value_code = value_entry.cname
+                else:
+                    value_code = ("%s = %s" % (
+                        value_entry.cname,
+                        value_entry.value))
+                if value_entry is not last_entry:
+                    value_code += ","
+                code.putln(value_code)
+        code.putln(footer)
+    
+    def generate_typeobject_predeclaration(self, entry, code):
+        code.putln("")
+        name = entry.type.typeobj_cname
+        if name:
+            if entry.visibility == 'extern' and not entry.in_cinclude:
+                code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
+                    Naming.extern_c_macro,
+                    name))
+            elif entry.visibility == 'public':
+                #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
+                code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
+                    Naming.extern_c_macro,
+                    name))
+            # ??? Do we really need the rest of this? ???
+            #else:
+            #  code.putln("staticforward PyTypeObject %s;" % name)
+    
+    def generate_exttype_vtable_struct(self, entry, code):
+        # Generate struct declaration for an extension type's vtable.
+        type = entry.type
+        scope = type.scope
+        if type.vtabstruct_cname:
+            code.putln("")
+            code.putln(
+                "struct %s {" %
+                    type.vtabstruct_cname)
+            if type.base_type and type.base_type.vtabstruct_cname:
+                code.putln("struct %s %s;" % (
+                    type.base_type.vtabstruct_cname,
+                    Naming.obj_base_cname))
+            for method_entry in scope.cfunc_entries:
+                if not method_entry.is_inherited:
+                    code.putln(
+                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
+            code.putln(
+                "};")
+    
+    def generate_exttype_vtabptr_declaration(self, entry, code):
+        # Generate declaration of pointer to an extension type's vtable.
+        type = entry.type
+        if type.vtabptr_cname:
+            code.putln("static struct %s *%s;" % (
+                type.vtabstruct_cname,
+                type.vtabptr_cname))
+    
+    def generate_obj_struct_definition(self, type, code):
+        # Generate object struct definition for an
+        # extension type.
+        if not type.scope:
+            return # Forward declared but never defined
+        header, footer = \
+            self.sue_header_footer(type, "struct", type.objstruct_cname)
+        code.putln("")
+        code.putln(header)
+        base_type = type.base_type
+        if base_type:
+            code.putln(
+                "%s%s %s;" % (
+                    ("struct ", "")[base_type.typedef_flag],
+                    base_type.objstruct_cname,
+                    Naming.obj_base_cname))
+        else:
+            code.putln(
+                "PyObject_HEAD")
+        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
+            code.putln(
+                "struct %s *%s;" % (
+                    type.vtabstruct_cname,
+                    type.vtabslot_cname))
+        for attr in type.scope.var_entries:
+            code.putln(
+                "%s;" %
+                    attr.type.declaration_code(attr.cname))
+        code.putln(footer)
+
+    def generate_global_declarations(self, env, code, definition):
+        code.putln("")
+        for entry in env.c_class_entries:
+            code.putln("static PyTypeObject *%s = 0;" % 
+                entry.type.typeptr_cname)
+        code.put_var_declarations(env.var_entries, static = 1, 
+            dll_linkage = "DL_EXPORT", definition = definition)
+        code.put_var_declarations(env.default_entries, static = 1)
+    
+    def generate_cfunction_predeclarations(self, env, code):
+        for entry in env.cfunc_entries:
+            if not entry.in_cinclude:
+                if entry.visibility == 'public':
+                    dll_linkage = "DL_EXPORT"
+                else:
+                    dll_linkage = None
+                header = entry.type.declaration_code(entry.cname, 
+                    dll_linkage = dll_linkage)
+                if entry.visibility <> 'private':
+                    storage_class = "%s " % Naming.extern_c_macro
+                else:
+                    storage_class = "static "
+                code.putln("%s%s; /*proto*/" % (
+                    storage_class,
+                    header))
+    
+    def generate_typeobj_definitions(self, env, code):
+        full_module_name = env.qualified_name
+        for entry in env.c_class_entries:
+            #print "generate_typeobj_definitions:", entry.name
+            #print "...visibility =", entry.visibility
+            if entry.visibility <> 'extern':
+                type = entry.type
+                scope = type.scope
+                if scope: # could be None if there was an error
+                    self.generate_exttype_vtable(scope, code)
+                    self.generate_new_function(scope, code)
+                    self.generate_dealloc_function(scope, code)
+                    self.generate_traverse_function(scope, code)
+                    self.generate_clear_function(scope, code)
+                    if scope.defines_any(["__getitem__"]):
+                        self.generate_getitem_int_function(scope, code)
+                    if scope.defines_any(["__setitem__", "__delitem__"]):
+                        self.generate_ass_subscript_function(scope, code)
+                    if scope.defines_any(["__setslice__", "__delslice__"]):
+                        self.generate_ass_slice_function(scope, code)
+                    if scope.defines_any(["__getattr__"]):
+                        self.generate_getattro_function(scope, code)
+                    if scope.defines_any(["__setattr__", "__delattr__"]):
+                        self.generate_setattro_function(scope, code)
+                    if scope.defines_any(["__get__"]):
+                        self.generate_descr_get_function(scope, code)
+                    if scope.defines_any(["__set__", "__delete__"]):
+                        self.generate_descr_set_function(scope, code)
+                    self.generate_property_accessors(scope, code)
+                    self.generate_method_table(scope, code)
+                    self.generate_member_table(scope, code)
+                    self.generate_getset_table(scope, code)
+                    self.generate_typeobj_definition(full_module_name, entry, code)
+    
+    def generate_exttype_vtable(self, scope, code):
+        # Generate the definition of an extension type's vtable.
+        type = scope.parent_type
+        if type.vtable_cname:
+            code.putln("static struct %s %s;" % (
+                type.vtabstruct_cname,
+                type.vtable_cname))
+        
+    def generate_self_cast(self, scope, code):
+        type = scope.parent_type
+        code.putln(
+            "%s = (%s)o;" % (
+                type.declaration_code("p"),
+                type.declaration_code("")))
+    
+    def generate_new_function(self, scope, code):
+        base_type = scope.parent_type.base_type
+        code.putln("")
+        code.putln(
+            "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
+                % scope.mangle_internal("tp_new"))
+        if base_type:
+            code.putln(
+                "PyObject *o = %s->tp_new(t, a, k);" %
+                    base_type.typeptr_cname)
+        else:
+            code.putln(
+                "PyObject *o = (*t->tp_alloc)(t, 0);")
+        type = scope.parent_type
+        py_attrs = []
+        for entry in scope.var_entries:
+            if entry.type.is_pyobject:
+                py_attrs.append(entry)
+        if type.vtabslot_cname or py_attrs:
+            self.generate_self_cast(scope, code)
+        if type.vtabslot_cname:
+            code.putln("*(struct %s **)&p->%s = %s;" % (
+                type.vtabstruct_cname,
+                type.vtabslot_cname,
+                type.vtabptr_cname))
+        for entry in py_attrs:
+            if entry.name == "__weakref__":
+                code.putln("p->%s = 0;" % entry.cname)
+            else:
+                code.put_init_var_to_py_none(entry, "p->%s")
+        entry = scope.lookup_here("__new__")
+        if entry:
+            code.putln(
+                "if (%s(o, a, k) < 0) {" % 
+                    entry.func_cname)
+            code.put_decref_clear("o", py_object_type);
+            code.putln(
+                "}")
+        code.putln(
+            "return o;")
+        code.putln(
+            "}")
+    
+    def generate_dealloc_function(self, scope, code):
+        base_type = scope.parent_type.base_type
+        code.putln("")
+        code.putln(
+            "static void %s(PyObject *o) {"
+                % scope.mangle_internal("tp_dealloc"))
+        py_attrs = []
+        for entry in scope.var_entries:
+            if entry.type.is_pyobject and entry.name <> "__weakref__":
+                py_attrs.append(entry)
+        if py_attrs:
+            self.generate_self_cast(scope, code)
+        self.generate_usr_dealloc_call(scope, code)
+        if scope.lookup_here("__weakref__"):
+            code.putln("PyObject_ClearWeakRefs(o);")
+        for entry in py_attrs:
+            code.put_xdecref("p->%s" % entry.cname, entry.type)
+        if base_type:
+            code.putln(
+                "%s->tp_dealloc(o);" %
+                    base_type.typeptr_cname)
+        else:
+            code.putln(
+                "(*o->ob_type->tp_free)(o);")
+        code.putln(
+            "}")
+    
+    def generate_usr_dealloc_call(self, scope, code):
+        entry = scope.lookup_here("__dealloc__")
+        if entry:
+            code.putln(
+                "{")
+            code.putln(
+                    "PyObject *etype, *eval, *etb;")
+            code.putln(
+                    "PyErr_Fetch(&etype, &eval, &etb);")
+            code.putln(
+                    "++o->ob_refcnt;")
+            code.putln(
+                    "%s(o);" % 
+                        entry.func_cname)
+            code.putln(
+                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
+            code.putln(
+                    "--o->ob_refcnt;")
+            code.putln(
+                    "PyErr_Restore(etype, eval, etb);")
+            code.putln(
+                "}")
+    
+    def generate_traverse_function(self, scope, code):
+        base_type = scope.parent_type.base_type
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o, visitproc v, void *a) {"
+                % scope.mangle_internal("tp_traverse"))
+        py_attrs = []
+        for entry in scope.var_entries:
+            if entry.type.is_pyobject:
+                py_attrs.append(entry)
+        if base_type or py_attrs:
+            code.putln(
+                    "int e;")
+        if py_attrs:
+            self.generate_self_cast(scope, code)
+        if base_type:
+            code.putln(
+                    "e = %s->tp_traverse(o, v, a); if (e) return e;" %
+                        base_type.typeptr_cname)
+        for entry in py_attrs:
+            var_code = "p->%s" % entry.cname
+            code.putln(
+                    "if (%s) {"
+                        % var_code)
+            if entry.type.is_extension_type:
+                var_code = "((PyObject*)%s)" % var_code
+            code.putln(
+                        "e = (*v)(%s, a); if (e) return e;" 
+                            % var_code)
+            code.putln(
+                    "}")
+        code.putln(
+                "return 0;")
+        code.putln(
+            "}")
+    
+    def generate_clear_function(self, scope, code):
+        base_type = scope.parent_type.base_type
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o) {"
+                % scope.mangle_internal("tp_clear"))
+        py_attrs = []
+        for entry in scope.var_entries:
+            if entry.type.is_pyobject:
+                py_attrs.append(entry)
+        if py_attrs:
+            self.generate_self_cast(scope, code)
+        if base_type:
+            code.putln(
+                "%s->tp_clear(o);" %
+                    base_type.typeptr_cname)
+        for entry in py_attrs:
+            name = "p->%s" % entry.cname
+            code.put_xdecref(name, entry.type)
+            code.put_init_var_to_py_none(entry, "p->%s")
+        code.putln(
+            "return 0;")
+        code.putln(
+            "}")
+        
+    def generate_getitem_int_function(self, scope, code):
+        # This function is put into the sq_item slot when
+        # a __getitem__ method is present. It converts its
+        # argument to a Python integer and calls mp_subscript.
+        code.putln(
+            "static PyObject *%s(PyObject *o, int i) {" %
+                scope.mangle_internal("sq_item"))
+        code.putln(
+                "PyObject *r;")
+        code.putln(
+                "PyObject *x = PyInt_FromLong(i); if(!x) return 0;")
+        code.putln(
+                "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
+        code.putln(
+                "Py_DECREF(x);")
+        code.putln(
+                "return r;")
+        code.putln(
+            "}")
+
+    def generate_ass_subscript_function(self, scope, code):
+        # Setting and deleting an item are both done through
+        # the ass_subscript method, so we dispatch to user's __setitem__
+        # or __delitem__, or raise an exception.
+        base_type = scope.parent_type.base_type
+        set_entry = scope.lookup_here("__setitem__")
+        del_entry = scope.lookup_here("__delitem__")
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
+                scope.mangle_internal("mp_ass_subscript"))
+        code.putln(
+                "if (v) {")
+        if set_entry:
+            code.putln(
+                    "return %s(o, i, v);" %
+                        set_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
+            code.putln(
+                    "PyErr_Format(PyExc_NotImplementedError,")
+            code.putln(
+                    '  "Subscript assignment not supported by %s", o->ob_type->tp_name);')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+                "else {")
+        if del_entry:
+            code.putln(
+                    "return %s(o, i);" %
+                        del_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
+            code.putln(
+                    "PyErr_Format(PyExc_NotImplementedError,")
+            code.putln(
+                    '  "Subscript deletion not supported by %s", o->ob_type->tp_name);')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+            "}")
+    
+    def generate_guarded_basetype_call(
+            self, base_type, substructure, slot, args, code):
+        if base_type:
+            base_tpname = base_type.typeptr_cname
+            if substructure:
+                code.putln(
+                    "if (%s->%s && %s->%s->%s)" % (
+                        base_tpname, substructure, base_tpname, substructure, slot))
+                code.putln(
+                    "  return %s->%s->%s(%s);" % (
+                        base_tpname, substructure, slot, args))
+            else:
+                code.putln(
+                    "if (%s->%s)" % (
+                        base_tpname, slot))
+                code.putln(
+                    "  return %s->%s(%s);" % (
+                        base_tpname, slot, args))
+
+    def generate_ass_slice_function(self, scope, code):
+        # Setting and deleting a slice are both done through
+        # the ass_slice method, so we dispatch to user's __setslice__
+        # or __delslice__, or raise an exception.
+        base_type = scope.parent_type.base_type
+        set_entry = scope.lookup_here("__setslice__")
+        del_entry = scope.lookup_here("__delslice__")
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o, int i, int j, PyObject *v) {" %
+                scope.mangle_internal("sq_ass_slice"))
+        code.putln(
+                "if (v) {")
+        if set_entry:
+            code.putln(
+                    "return %s(o, i, j, v);" %
+                        set_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
+            code.putln(
+                    "PyErr_Format(PyExc_NotImplementedError,")
+            code.putln(
+                    '  "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+                "else {")
+        if del_entry:
+            code.putln(
+                    "return %s(o, i, j);" %
+                        del_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
+            code.putln(
+                    "PyErr_Format(PyExc_NotImplementedError,")
+            code.putln(
+                    '  "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+            "}")
+
+    def generate_getattro_function(self, scope, code):
+        # First try to get the attribute using PyObject_GenericGetAttr.
+        # If that raises an AttributeError, call the user's __getattr__
+        # method.
+        entry = scope.lookup_here("__getattr__")
+        code.putln("")
+        code.putln(
+            "static PyObject *%s(PyObject *o, PyObject *n) {"
+                % scope.mangle_internal("tp_getattro"))
+        code.putln(
+                "PyObject *v = PyObject_GenericGetAttr(o, n);")
+        code.putln(
+                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
+        code.putln(
+                    "PyErr_Clear();")
+        code.putln(
+                    "v = %s(o, n);" %
+                        entry.func_cname)
+        code.putln(
+                "}")
+        code.putln(
+                "return v;")
+        code.putln(
+            "}")
+    
+    def generate_setattro_function(self, scope, code):
+        # Setting and deleting an attribute are both done through
+        # the setattro method, so we dispatch to user's __setattr__
+        # or __delattr__ or fall back on PyObject_GenericSetAttr.
+        base_type = scope.parent_type.base_type
+        set_entry = scope.lookup_here("__setattr__")
+        del_entry = scope.lookup_here("__delattr__")
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
+                scope.mangle_internal("tp_setattro"))
+        code.putln(
+                "if (v) {")
+        if set_entry:
+            code.putln(
+                    "return %s(o, n, v);" %
+                        set_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, None, "tp_setattro", "o, n, v", code)
+            code.putln(
+                    "return PyObject_GenericSetAttr(o, n, v);")
+        code.putln(
+                "}")
+        code.putln(
+                "else {")
+        if del_entry:
+            code.putln(
+                    "return %s(o, n);" %
+                        del_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, None, "tp_setattro", "o, n, v", code)
+            code.putln(
+                    "return PyObject_GenericSetAttr(o, n, 0);")
+        code.putln(
+                "}")
+        code.putln(
+            "}")
+    
+    def generate_descr_get_function(self, scope, code):
+        # The __get__ function of a descriptor object can be
+        # called with NULL for the second or third arguments
+        # under some circumstances, so we replace them with
+        # None in that case.
+        user_get_entry = scope.lookup_here("__get__")
+        code.putln("")
+        code.putln(
+            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
+                scope.mangle_internal("tp_descr_get"))
+        code.putln(
+            "PyObject *r = 0;")
+        code.putln(
+            "if (!i) i = Py_None;")
+        code.putln(
+            "if (!c) c = Py_None;")
+        #code.put_incref("i", py_object_type)
+        #code.put_incref("c", py_object_type)
+        code.putln(
+            "r = %s(o, i, c);" %
+                user_get_entry.func_cname)
+        #code.put_decref("i", py_object_type)
+        #code.put_decref("c", py_object_type)
+        code.putln(
+            "return r;")
+        code.putln(
+            "}")
+    
+    def generate_descr_set_function(self, scope, code):
+        # Setting and deleting are both done through the __set__
+        # method of a descriptor, so we dispatch to user's __set__
+        # or __delete__ or raise an exception.
+        base_type = scope.parent_type.base_type
+        user_set_entry = scope.lookup_here("__set__")
+        user_del_entry = scope.lookup_here("__delete__")
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
+                scope.mangle_internal("tp_descr_set"))
+        code.putln(
+                "if (v) {")
+        if user_set_entry:
+            code.putln(
+                    "return %s(o, i, v);" %
+                        user_set_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, None, "tp_descr_set", "o, i, v", code)
+            code.putln(
+                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+                "else {")
+        if user_del_entry:
+            code.putln(
+                    "return %s(o, i);" %
+                        user_del_entry.func_cname)
+        else:
+            self.generate_guarded_basetype_call(
+                base_type, None, "tp_descr_set", "o, i, v", code)
+            code.putln(
+                    'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")           
+        code.putln(
+            "}")
+    
+    def generate_property_accessors(self, cclass_scope, code):
+        for entry in cclass_scope.property_entries:
+            property_scope = entry.scope
+            if property_scope.defines_any(["__get__"]):
+                self.generate_property_get_function(entry, code)
+            if property_scope.defines_any(["__set__", "__del__"]):
+                self.generate_property_set_function(entry, code)
+    
+    def generate_property_get_function(self, property_entry, code):
+        property_scope = property_entry.scope
+        property_entry.getter_cname = property_scope.parent_scope.mangle(
+            Naming.prop_get_prefix, property_entry.name)
+        get_entry = property_scope.lookup_here("__get__")
+        code.putln("")
+        code.putln(
+            "static PyObject *%s(PyObject *o, void *x) {" %
+                property_entry.getter_cname)
+        code.putln(
+                "return %s(o);" %
+                    get_entry.func_cname)
+        code.putln(
+            "}")
+    
+    def generate_property_set_function(self, property_entry, code):
+        property_scope = property_entry.scope
+        property_entry.setter_cname = property_scope.parent_scope.mangle(
+            Naming.prop_set_prefix, property_entry.name)
+        set_entry = property_scope.lookup_here("__set__")
+        del_entry = property_scope.lookup_here("__del__")
+        code.putln("")
+        code.putln(
+            "static int %s(PyObject *o, PyObject *v, void *x) {" %
+                property_entry.setter_cname)
+        code.putln(
+                "if (v) {")
+        if set_entry:
+            code.putln(
+                    "return %s(o, v);" %
+                        set_entry.func_cname)
+        else:
+            code.putln(
+                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+                "else {")
+        if del_entry:
+            code.putln(
+                    "return %s(o);" %
+                        del_entry.func_cname)
+        else:
+            code.putln(
+                    'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
+            code.putln(
+                    "return -1;")
+        code.putln(
+                "}")
+        code.putln(
+            "}")
+
+    def generate_typeobj_definition(self, modname, entry, code):
+        type = entry.type
+        scope = type.scope
+        for suite in TypeSlots.substructures:
+            suite.generate_substructure(scope, code)
+        code.putln("")
+        if entry.visibility == 'public':
+            header = "DL_EXPORT(PyTypeObject) %s = {"
+        else:
+            #header = "statichere PyTypeObject %s = {"
+            header = "PyTypeObject %s = {"
+        #code.putln(header % scope.parent_type.typeobj_cname)
+        code.putln(header % type.typeobj_cname)
+        code.putln(
+            "PyObject_HEAD_INIT(0)")
+        code.putln(
+            "0, /*ob_size*/")
+        code.putln(
+            '"%s.%s", /*tp_name*/' % (
+                modname, scope.class_name))
+        if type.typedef_flag:
+            objstruct = type.objstruct_cname
+        else:
+            #objstruct = "struct %s" % scope.parent_type.objstruct_cname
+            objstruct = "struct %s" % type.objstruct_cname
+        code.putln(
+            "sizeof(%s), /*tp_basicsize*/" %
+                objstruct)
+        code.putln(
+            "0, /*tp_itemsize*/")
+        for slot in TypeSlots.slot_table:
+            slot.generate(scope, code)
+        code.putln(
+            "};")
+    
+    def generate_method_table(self, env, code):
+        code.putln("")
+        code.putln(
+            "static struct PyMethodDef %s[] = {" % 
+                env.method_table_cname)
+        for entry in env.pyfunc_entries:
+                code.put_pymethoddef(entry, ",")
+        code.putln(
+                "{0, 0, 0, 0}")
+        code.putln(
+            "};")
+    
+    def generate_member_table(self, env, code):
+        #print "ModuleNode.generate_member_table: scope =", env ###
+        if env.public_attr_entries:
+            code.putln("")
+            code.putln(
+                "static struct PyMemberDef %s[] = {" %
+                    env.member_table_cname)
+            type = env.parent_type
+            if type.typedef_flag:
+                objstruct = type.objstruct_cname
+            else:
+                objstruct = "struct %s" % type.objstruct_cname
+            for entry in env.public_attr_entries:
+                type_code = entry.type.pymemberdef_typecode
+                if entry.visibility == 'readonly':
+                    flags = "READONLY"
+                else:
+                    flags = "0"
+                code.putln('{"%s", %s, %s, %s, 0},' % (
+                    entry.name,
+                    type_code,
+                    "offsetof(%s, %s)" % (objstruct, entry.name),
+                    flags))
+            code.putln(
+                    "{0, 0, 0, 0, 0}")
+            code.putln(
+                "};")
+    
+    def generate_getset_table(self, env, code):
+        if env.property_entries:
+            code.putln("")
+            code.putln(
+                "static struct PyGetSetDef %s[] = {" %
+                    env.getset_table_cname)
+            for entry in env.property_entries:
+                code.putln(
+                    '{"%s", %s, %s, %s, 0},' % (
+                        entry.name,
+                        entry.getter_cname or "0",
+                        entry.setter_cname or "0",
+                        entry.doc_cname or "0"))
+            code.putln(
+                    "{0, 0, 0, 0, 0}")
+            code.putln(
+                "};")
+    
+    def generate_interned_name_table(self, env, code):
+        items = env.intern_map.items()
+        if items:
+            items.sort()
+            code.putln("")
+            code.putln(
+                "static __Pyx_InternTabEntry %s[] = {" %
+                    Naming.intern_tab_cname)
+            for (name, cname) in items:
+                code.putln(
+                    '{&%s, "%s"},' % (
+                        cname,
+                        name))
+            code.putln(
+                "{0, 0}")
+            code.putln(
+                "};")
+    
+    def generate_py_string_table(self, env, code):
+        entries = env.all_pystring_entries
+        if entries:
+            code.putln("")
+            code.putln(
+                "static __Pyx_StringTabEntry %s[] = {" %
+                    Naming.stringtab_cname)
+            for entry in entries:
+                code.putln(
+                    "{&%s, %s, sizeof(%s)}," % (
+                        entry.pystring_cname,
+                        entry.cname,
+                        entry.cname))
+            code.putln(
+                "{0, 0, 0}")
+            code.putln(
+                "};")
+    
+    def generate_filename_init_prototype(self, code):
+        code.putln("");
+        code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
+
+    def generate_module_init_func(self, imported_modules, env, code):
+        code.putln("")
+        header = "PyMODINIT_FUNC init%s(void)" % env.module_name
+        code.putln("%s; /*proto*/" % header)
+        code.putln("%s {" % header)
+        code.put_var_declarations(env.temp_entries)
+        #code.putln("/*--- Libary function declarations ---*/")
+        env.generate_library_function_declarations(code)
+        self.generate_filename_init_call(code)
+        #code.putln("/*--- Module creation code ---*/")
+        self.generate_module_creation_code(env, code)
+        #code.putln("/*--- Intern code ---*/")
+        self.generate_intern_code(env, code)
+        #code.putln("/*--- String init code ---*/")
+        self.generate_string_init_code(env, code)
+        #code.putln("/*--- Global init code ---*/")
+        self.generate_global_init_code(env, code)
+
+        #code.putln("/*--- Type init code ---*/")
+        self.generate_type_init_code(env, code)
+
+        #code.putln("/*--- Type import code ---*/")
+        for module in imported_modules:
+            self.generate_type_import_code_for_module(module, env, code)
+
+        #code.putln("/*--- Execution code ---*/")
+        self.body.generate_execution_code(code)
+        code.putln("return;")
+        code.put_label(code.error_label)
+        code.put_var_xdecrefs(env.temp_entries)
+        code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
+        env.use_utility_code(Nodes.traceback_utility_code)
+        code.putln('}')
+    
+    def generate_filename_init_call(self, code):
+        code.putln("%s();" % Naming.fileinit_cname)
+    
+    def generate_module_creation_code(self, env, code):
+        # Generate code to create the module object and
+        # install the builtins.
+        if env.doc:
+            doc = env.doc_cname
+        else:
+            doc = "0"
+        code.putln(
+            '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
+                env.module_cname, 
+                env.module_name, 
+                env.method_table_cname, 
+                doc))
+        code.putln(
+            "if (!%s) %s;" % (
+                env.module_cname,
+                code.error_goto(self.pos)));
+        code.putln(
+            '%s = PyImport_AddModule("__builtin__");' %
+                Naming.builtins_cname)
+        code.putln(
+            "if (!%s) %s;" % (
+                Naming.builtins_cname,
+                code.error_goto(self.pos)));
+        code.putln(
+            'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
+                env.module_cname,
+                Naming.builtins_cname,
+                code.error_goto(self.pos)))
+    
+    def generate_intern_code(self, env, code):
+        if env.intern_map:
+            env.use_utility_code(Nodes.init_intern_tab_utility_code);
+            code.putln(
+                "if (__Pyx_InternStrings(%s) < 0) %s;" % (
+                    Naming.intern_tab_cname,
+                    code.error_goto(self.pos)))
+    
+    def generate_string_init_code(self, env, code):
+        if env.all_pystring_entries:
+            env.use_utility_code(Nodes.init_string_tab_utility_code)
+            code.putln(
+                "if (__Pyx_InitStrings(%s) < 0) %s;" % (
+                    Naming.stringtab_cname,
+                    code.error_goto(self.pos)))
+    
+    def generate_global_init_code(self, env, code):
+        # Generate code to initialise global PyObject *
+        # variables to None.
+        for entry in env.var_entries:
+            if entry.visibility <> 'extern':
+                if entry.type.is_pyobject:
+                    code.put_init_var_to_py_none(entry)
+    
+    def generate_type_import_code_for_module(self, module, env, code):
+        # Generate type import code for all extension types in
+        # an imported module.
+        if module.c_class_entries:
+            for entry in module.c_class_entries:
+                self.generate_type_import_code(env, entry.type, entry.pos, code)
+    
+    def generate_type_init_code(self, env, code):
+        # Generate type import code for extern extension types
+        # and type ready code for non-extern ones.
+        for entry in env.c_class_entries:
+            if entry.visibility == 'extern':
+                self.generate_type_import_code(env, entry.type, entry.pos, code)
+            else:
+                self.generate_base_type_import_code(env, entry, code)
+                self.generate_exttype_vtable_init_code(entry, code)
+                self.generate_type_ready_code(env, entry, code)
+                self.generate_typeptr_assignment_code(entry, code)
+    
+    def generate_base_type_import_code(self, env, entry, code):
+        base_type = entry.type.base_type
+        if base_type and base_type.module_name <> env.qualified_name:
+            self.generate_type_import_code(env, base_type, self.pos, code)
+    
+    def use_type_import_utility_code(self, env):
+        import ExprNodes
+        env.use_utility_code(Nodes.type_import_utility_code)
+        env.use_utility_code(ExprNodes.import_utility_code)
+    
+    def generate_type_import_code(self, env, type, pos, code):
+        # If not already done, generate code to import the typeobject of an
+        # extension type defined in another module, and extract its C method
+        # table pointer if any.
+        if type in env.types_imported:
+            return
+        if type.typedef_flag:
+            objstruct = type.objstruct_cname
+        else:
+            objstruct = "struct %s" % type.objstruct_cname
+        code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
+            type.typeptr_cname,
+            type.module_name, 
+            type.name,
+            objstruct,
+            type.typeptr_cname,
+            code.error_goto(pos)))
+        self.use_type_import_utility_code(env)
+        if type.vtabptr_cname:
+            code.putln(
+                "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
+                    type.typeptr_cname,
+                    type.vtabptr_cname,
+                    code.error_goto(pos)))
+            env.use_utility_code(Nodes.get_vtable_utility_code)
+        env.types_imported[type] = 1
+    
+    def generate_type_ready_code(self, env, entry, code):
+        # Generate a call to PyType_Ready for an extension
+        # type defined in this module.
+        type = entry.type
+        typeobj_cname = type.typeobj_cname
+        scope = type.scope
+        if scope: # could be None if there was an error
+            if entry.visibility <> 'extern':
+                for slot in TypeSlots.slot_table:
+                    slot.generate_dynamic_init_code(scope, code)
+                code.putln(
+                    "if (PyType_Ready(&%s) < 0) %s" % (
+                        typeobj_cname,
+                        code.error_goto(entry.pos)))
+                if type.vtable_cname:
+                    code.putln(
+                        "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
+                            typeobj_cname,
+                            type.vtabptr_cname,
+                            code.error_goto(entry.pos)))
+                    env.use_utility_code(Nodes.set_vtable_utility_code)
+                code.putln(
+                    'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
+                        Naming.module_cname,
+                        scope.class_name,
+                        typeobj_cname,
+                        code.error_goto(entry.pos)))
+                weakref_entry = scope.lookup_here("__weakref__")
+                if weakref_entry:
+                    if weakref_entry.type is py_object_type:
+                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
+                        code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
+                            tp_weaklistoffset,
+                            tp_weaklistoffset,
+                            type.objstruct_cname,
+                            weakref_entry.cname))
+                    else:
+                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
+    
+    def generate_exttype_vtable_init_code(self, entry, code):
+        # Generate code to initialise the C method table of an
+        # extension type.
+        type = entry.type
+        if type.vtable_cname:
+            code.putln(
+                "%s = &%s;" % (
+                    type.vtabptr_cname,
+                    type.vtable_cname))
+            if type.base_type and type.base_type.vtabptr_cname:
+                code.putln(
+                    "%s.%s = *%s;" % (
+                        type.vtable_cname,
+                        Naming.obj_base_cname,
+                        type.base_type.vtabptr_cname))
+            for meth_entry in type.scope.cfunc_entries:
+                if meth_entry.func_cname:
+                    code.putln(
+                        "*(void(**)())&%s.%s = (void(*)())%s;" % (
+                            type.vtable_cname,
+                            meth_entry.cname,
+                            meth_entry.func_cname))
+    
+    def generate_typeptr_assignment_code(self, entry, code):
+        # Generate code to initialise the typeptr of an extension
+        # type defined in this module to point to its type object.
+        type = entry.type
+        if type.typeobj_cname:
+            code.putln(
+                "%s = &%s;" % (
+                    type.typeptr_cname, type.typeobj_cname))
+    
+    def generate_utility_functions(self, env, code):
+        code.putln("")
+        code.putln("/* Runtime support code */")
+        code.putln("")
+        code.putln("static void %s(void) {" % Naming.fileinit_cname)
+        code.putln("%s = %s;" % 
+            (Naming.filetable_cname, Naming.filenames_cname))
+        code.putln("}")
+        for utility_code in env.utility_code_used:
+            code.h.put(utility_code[0])
+            code.put(utility_code[1])
index a70f7f7252bb5e438fe636361b3dd61b1dcf8f63..1c816d4bb6dab413a860adb5423e5ae3d8f0899b 100644 (file)
@@ -2,7 +2,7 @@
 #   Pyrex - Parse tree nodes
 #
 
-import os, string, sys, time
+import string, sys
 
 import Code
 from Errors import error, InternalError
@@ -11,8 +11,6 @@ import PyrexTypes
 from PyrexTypes import py_object_type, error_type, CTypedefType
 from Symtab import ModuleScope, LocalScope, \
     StructOrUnionScope, PyClassScope, CClassScope
-import TypeSlots
-import Version
 from Pyrex.Utils import open_new_file, replace_suffix
 import Options
 
@@ -95,1214 +93,6 @@ class BlockNode:
             for entry in entries:
                 code.putln(
                     "static PyObject *%s;" % entry.pystring_cname)
-        
-
-class ModuleNode(Node, BlockNode):
-    #  doc       string or None
-    #  body      StatListNode
-    
-    def analyse_declarations(self, env):
-        env.doc = self.doc
-        self.body.analyse_declarations(env)
-    
-    def process_implementation(self, env, result):
-        self.analyse_declarations(env)
-        env.check_c_classes()
-        self.body.analyse_expressions(env)
-        env.return_type = PyrexTypes.c_void_type
-        self.generate_c_code(env, result)
-        self.generate_h_code(env, result)
-    
-    def generate_h_code(self, env, result):
-        public_vars_and_funcs = []
-        public_extension_types = []
-        for entry in env.var_entries:
-            if entry.visibility == 'public':
-                public_vars_and_funcs.append(entry)
-        for entry in env.cfunc_entries:
-            if entry.visibility == 'public':
-                public_vars_and_funcs.append(entry)
-        for entry in env.c_class_entries:
-            if entry.visibility == 'public':
-                public_extension_types.append(entry)
-        if public_vars_and_funcs or public_extension_types:
-            result.h_file = replace_suffix(result.c_file, ".h")
-            result.i_file = replace_suffix(result.c_file, ".pxi")
-            h_code = Code.CCodeWriter(result.h_file)
-            i_code = Code.PyrexCodeWriter(result.i_file)
-            self.generate_extern_c_macro_definition(h_code)
-            for entry in public_vars_and_funcs:
-                h_code.putln("%s %s;" % (
-                    Naming.extern_c_macro,
-                    entry.type.declaration_code(
-                        entry.cname, dll_linkage = "DL_IMPORT")))
-                i_code.putln("cdef extern %s" % 
-                    entry.type.declaration_code(entry.cname, pyrex = 1))
-            for entry in public_extension_types:
-                self.generate_cclass_header_code(entry.type, h_code)
-                self.generate_cclass_include_code(entry.type, i_code)
-            h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
-    
-    def generate_cclass_header_code(self, type, h_code):
-        #h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
-        h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
-            Naming.extern_c_macro,
-            type.typeobj_cname))
-        self.generate_obj_struct_definition(type, h_code)
-    
-    def generate_cclass_include_code(self, type, i_code):
-        i_code.putln("cdef extern class %s.%s:" % (
-            type.module_name, type.name))
-        i_code.indent()
-        var_entries = type.scope.var_entries
-        if var_entries:
-            for entry in var_entries:
-                i_code.putln("cdef %s" % 
-                    entry.type.declaration_code(entry.cname, pyrex = 1))
-        else:
-            i_code.putln("pass")
-        i_code.dedent()
-    
-    def generate_c_code(self, env, result):
-        modules = []
-        self.find_referenced_modules(env, modules, {})
-        code = Code.CCodeWriter(result.c_file)
-        code.init_labels()
-        self.generate_module_preamble(env, modules, code)
-        for module in modules:
-            self.generate_declarations_for_module(module, code,
-                definition = module is env)
-        code.putln("")
-        code.putln("/* Implementation of %s */" % env.qualified_name)
-        self.generate_const_definitions(env, code)
-        self.generate_interned_name_decls(env, code)
-        self.generate_py_string_decls(env, code)
-        self.body.generate_function_definitions(env, code)
-        self.generate_interned_name_table(env, code)
-        self.generate_py_string_table(env, code)
-        self.generate_typeobj_definitions(env, code)
-        self.generate_method_table(env, code)
-        self.generate_filename_init_prototype(code)
-        self.generate_module_init_func(modules[:-1], env, code)
-        self.generate_filename_table(code)
-        self.generate_utility_functions(env, code)
-        result.c_file_generated = 1
-    
-    def find_referenced_modules(self, env, module_list, modules_seen):
-        if env not in modules_seen:
-            modules_seen[env] = 1
-            for imported_module in env.cimported_modules:
-                self.find_referenced_modules(imported_module, module_list, modules_seen)
-            module_list.append(env)
-        
-    def generate_module_preamble(self, env, cimported_modules, code):
-        code.putln('/* Generated by Pyrex %s on %s */' % (
-            Version.version, time.asctime()))
-        code.putln('')
-        for filename in env.python_include_files:
-            code.putln('#include "%s"' % filename)
-        code.putln("#ifndef PY_LONG_LONG")
-        code.putln("  #define PY_LONG_LONG LONG_LONG")
-        code.putln("#endif")
-        self.generate_extern_c_macro_definition(code)
-        code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
-        self.generate_includes(env, cimported_modules, code)
-        #for filename in env.include_files:
-        #      code.putln('#include "%s"' % filename)
-        code.putln('')
-        code.put(utility_function_predeclarations)
-        if Options.intern_names:
-            code.putln(get_name_interned_predeclaration)
-        else:
-            code.putln(get_name_predeclaration)
-        code.putln('')
-        code.putln('static PyObject *%s;' % env.module_cname)
-        code.putln('static PyObject *%s;' % Naming.builtins_cname)
-        code.putln('static int %s;' % Naming.lineno_cname)
-        code.putln('static char *%s;' % Naming.filename_cname)
-        code.putln('static char **%s;' % Naming.filetable_cname)
-        if env.doc:
-            code.putln('')
-            code.putln('static char %s[] = "%s";' % (env.doc_cname, env.doc))
-    
-    def generate_extern_c_macro_definition(self, code):
-        name = Naming.extern_c_macro
-        code.putln("#ifdef __cplusplus")
-        code.putln('#define %s extern "C"' % name)
-        code.putln("#else")
-        code.putln("#define %s extern" % name)
-        code.putln("#endif")
-
-    def generate_includes(self, env, cimported_modules, code):
-        includes = env.include_files[:]
-        for module in cimported_modules:
-            for filename in module.include_files:
-                if filename not in includes:
-                    includes.append(filename)
-        for filename in includes:
-            code.putln('#include "%s"' % filename)
-    
-    def generate_filename_table(self, code):
-        code.putln("")
-        code.putln("static char *%s[] = {" % Naming.filenames_cname)
-        if code.filename_list:
-            for filename in code.filename_list:
-                filename = os.path.basename(filename)
-                escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
-                code.putln('"%s",' % 
-                    escaped_filename)
-        else:
-            # Some C compilers don't like an empty array
-            code.putln("0")
-        code.putln("};")
-    
-    def generate_declarations_for_module(self, env, code, definition):
-        code.putln("")
-        code.putln("/* Declarations from %s */" % env.qualified_name)
-        self.generate_type_predeclarations(env, code)
-        self.generate_type_definitions(env, code)
-        self.generate_global_declarations(env, code, definition)
-        self.generate_cfunction_predeclarations(env, code)
-
-    def generate_type_predeclarations(self, env, code):
-        pass
-    
-    def generate_type_definitions(self, env, code):
-        # Generate definitions of structs/unions/enums.
-        for entry in env.sue_entries:
-            if not entry.in_cinclude:
-                type = entry.type
-                if type.is_struct_or_union:
-                    self.generate_struct_union_definition(entry, code)
-                else:
-                    self.generate_enum_definition(entry, code)
-        # Generate extension type object struct definitions.
-        for entry in env.c_class_entries:
-            if not entry.in_cinclude:
-                self.generate_typeobject_predeclaration(entry, code)
-                self.generate_obj_struct_definition(entry.type, code)
-                self.generate_exttype_vtable_struct(entry, code)
-                self.generate_exttype_vtabptr_declaration(entry, code)
-    
-    def sue_header_footer(self, type, kind, name):
-        if type.typedef_flag:
-            header = "typedef %s {" % kind
-            footer = "} %s;" % name
-        else:
-            header = "%s %s {" % (kind, name)
-            footer = "};"
-        return header, footer
-    
-    def generate_struct_union_definition(self, entry, code):
-        type = entry.type
-        scope = type.scope
-        if scope:
-            header, footer = \
-                self.sue_header_footer(type, type.kind, type.cname)
-            code.putln("")
-            code.putln(header)
-            var_entries = scope.var_entries
-            if not var_entries:
-                error(entry.pos,
-                    "Empty struct or union definition not allowed outside a"
-                    " 'cdef extern from' block")
-            for attr in var_entries:
-                code.putln(
-                    "%s;" %
-                        attr.type.declaration_code(attr.cname))
-            code.putln(footer)
-
-    def generate_enum_definition(self, entry, code):
-        type = entry.type
-        name = entry.cname or entry.name or ""
-        header, footer = \
-            self.sue_header_footer(type, "enum", name)
-        code.putln("")
-        code.putln(header)
-        enum_values = entry.enum_values
-        if not enum_values:
-            error(entry.pos,
-                "Empty enum definition not allowed outside a"
-                " 'cdef extern from' block")
-        for value_entry in enum_values:
-            if value_entry.value == value_entry.name:
-                code.putln(
-                    "%s," % 
-                        value_entry.cname)
-            else:
-                code.putln(
-                    "%s = %s," % (
-                        value_entry.cname,
-                        value_entry.value))
-        code.putln(footer)
-    
-    def generate_typeobject_predeclaration(self, entry, code):
-        code.putln("")
-        name = entry.type.typeobj_cname
-        if name:
-            if entry.visibility == 'extern' and not entry.in_cinclude:
-                code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
-                    Naming.extern_c_macro,
-                    name))
-            elif entry.visibility == 'public':
-                #code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
-                code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
-                    Naming.extern_c_macro,
-                    name))
-            # ??? Do we really need the rest of this? ???
-            #else:
-            #  code.putln("staticforward PyTypeObject %s;" % name)
-    
-    def generate_exttype_vtable_struct(self, entry, code):
-        # Generate struct declaration for an extension type's vtable.
-        type = entry.type
-        scope = type.scope
-        if type.vtabstruct_cname:
-            code.putln("")
-            code.putln(
-                "struct %s {" %
-                    type.vtabstruct_cname)
-            if type.base_type and type.base_type.vtabstruct_cname:
-                code.putln("struct %s %s;" % (
-                    type.base_type.vtabstruct_cname,
-                    Naming.obj_base_cname))
-            for method_entry in scope.cfunc_entries:
-                if not method_entry.is_inherited:
-                    code.putln(
-                        "%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
-            code.putln(
-                "};")
-    
-    def generate_exttype_vtabptr_declaration(self, entry, code):
-        # Generate declaration of pointer to an extension type's vtable.
-        type = entry.type
-        if type.vtabptr_cname:
-            code.putln("static struct %s *%s;" % (
-                type.vtabstruct_cname,
-                type.vtabptr_cname))
-    
-    def generate_obj_struct_definition(self, type, code):
-        # Generate object struct definition for an
-        # extension type.
-        if not type.scope:
-            return # Forward declared but never defined
-        header, footer = \
-            self.sue_header_footer(type, "struct", type.objstruct_cname)
-        code.putln("")
-        code.putln(header)
-        base_type = type.base_type
-        if base_type:
-            code.putln(
-                "%s%s %s;" % (
-                    ("struct ", "")[base_type.typedef_flag],
-                    base_type.objstruct_cname,
-                    Naming.obj_base_cname))
-        else:
-            code.putln(
-                "PyObject_HEAD")
-        if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
-            code.putln(
-                "struct %s *%s;" % (
-                    type.vtabstruct_cname,
-                    type.vtabslot_cname))
-        for attr in type.scope.var_entries:
-            code.putln(
-                "%s;" %
-                    attr.type.declaration_code(attr.cname))
-        code.putln(footer)
-
-    def generate_global_declarations(self, env, code, definition):
-        code.putln("")
-        for entry in env.c_class_entries:
-            code.putln("static PyTypeObject *%s = 0;" % 
-                entry.type.typeptr_cname)
-        code.put_var_declarations(env.var_entries, static = 1, 
-            dll_linkage = "DL_EXPORT", definition = definition)
-        code.put_var_declarations(env.default_entries, static = 1)
-    
-    def generate_cfunction_predeclarations(self, env, code):
-        for entry in env.cfunc_entries:
-            if not entry.in_cinclude:
-                if entry.visibility == 'public':
-                    dll_linkage = "DL_EXPORT"
-                else:
-                    dll_linkage = None
-                header = entry.type.declaration_code(entry.cname, 
-                    dll_linkage = dll_linkage)
-                if entry.visibility <> 'private':
-                    storage_class = "%s " % Naming.extern_c_macro
-                else:
-                    storage_class = "static "
-                code.putln("%s%s; /*proto*/" % (
-                    storage_class,
-                    header))
-    
-    def generate_typeobj_definitions(self, env, code):
-        full_module_name = env.qualified_name
-        for entry in env.c_class_entries:
-            #print "generate_typeobj_definitions:", entry.name
-            #print "...visibility =", entry.visibility
-            if entry.visibility <> 'extern':
-                type = entry.type
-                scope = type.scope
-                if scope: # could be None if there was an error
-                    self.generate_exttype_vtable(scope, code)
-                    self.generate_new_function(scope, code)
-                    self.generate_dealloc_function(scope, code)
-                    self.generate_traverse_function(scope, code)
-                    self.generate_clear_function(scope, code)
-                    if scope.defines_any(["__getitem__"]):
-                        self.generate_getitem_int_function(scope, code)
-                    if scope.defines_any(["__setitem__", "__delitem__"]):
-                        self.generate_ass_subscript_function(scope, code)
-                    if scope.defines_any(["__setslice__", "__delslice__"]):
-                        self.generate_ass_slice_function(scope, code)
-                    if scope.defines_any(["__getattr__"]):
-                        self.generate_getattro_function(scope, code)
-                    if scope.defines_any(["__setattr__", "__delattr__"]):
-                        self.generate_setattro_function(scope, code)
-                    if scope.defines_any(["__get__"]):
-                        self.generate_descr_get_function(scope, code)
-                    if scope.defines_any(["__set__", "__delete__"]):
-                        self.generate_descr_set_function(scope, code)
-                    self.generate_property_accessors(scope, code)
-                    self.generate_method_table(scope, code)
-                    self.generate_member_table(scope, code)
-                    self.generate_getset_table(scope, code)
-                    self.generate_typeobj_definition(full_module_name, entry, code)
-    
-    def generate_exttype_vtable(self, scope, code):
-        # Generate the definition of an extension type's vtable.
-        type = scope.parent_type
-        if type.vtable_cname:
-            code.putln("static struct %s %s;" % (
-                type.vtabstruct_cname,
-                type.vtable_cname))
-        
-    def generate_self_cast(self, scope, code):
-        type = scope.parent_type
-        code.putln(
-            "%s = (%s)o;" % (
-                type.declaration_code("p"),
-                type.declaration_code("")))
-    
-    def generate_new_function(self, scope, code):
-        base_type = scope.parent_type.base_type
-        code.putln("")
-        code.putln(
-            "static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
-                % scope.mangle_internal("tp_new"))
-        if base_type:
-            code.putln(
-                "PyObject *o = %s->tp_new(t, a, k);" %
-                    base_type.typeptr_cname)
-        else:
-            code.putln(
-                "PyObject *o = (*t->tp_alloc)(t, 0);")
-        self.generate_self_cast(scope, code)
-        type = scope.parent_type
-        if type.vtabslot_cname:
-            code.putln("*(struct %s **)&p->%s = %s;" % (
-                type.vtabstruct_cname,
-                type.vtabslot_cname,
-                type.vtabptr_cname))
-        for entry in scope.var_entries:
-            if entry.type.is_pyobject:
-                code.put_init_var_to_py_none(entry, "p->%s")
-        entry = scope.lookup_here("__new__")
-        if entry:
-            code.putln(
-                "if (%s(o, a, k) < 0) {" % 
-                    entry.func_cname)
-            code.put_decref_clear("o", py_object_type);
-            code.putln(
-                "}")
-        code.putln(
-            "return o;")
-        code.putln(
-            "}")
-    
-    def generate_dealloc_function(self, scope, code):
-        base_type = scope.parent_type.base_type
-        code.putln("")
-        code.putln(
-            "static void %s(PyObject *o) {"
-                % scope.mangle_internal("tp_dealloc"))
-        self.generate_self_cast(scope, code)
-        self.generate_usr_dealloc_call(scope, code)
-        for entry in scope.var_entries:
-            if entry.type.is_pyobject:
-                code.put_xdecref("p->%s" % entry.cname, entry.type)
-        if base_type:
-            code.putln(
-                "%s->tp_dealloc(o);" %
-                    base_type.typeptr_cname)
-        else:
-            code.putln(
-                "(*o->ob_type->tp_free)(o);")
-        code.putln(
-            "}")
-    
-    def generate_usr_dealloc_call(self, scope, code):
-        entry = scope.lookup_here("__dealloc__")
-        if entry:
-            code.putln(
-                "{")
-            code.putln(
-                    "PyObject *etype, *eval, *etb;")
-            code.putln(
-                    "PyErr_Fetch(&etype, &eval, &etb);")
-            code.putln(
-                    "++o->ob_refcnt;")
-            code.putln(
-                    "%s(o);" % 
-                        entry.func_cname)
-            code.putln(
-                    "if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
-            code.putln(
-                    "--o->ob_refcnt;")
-            code.putln(
-                    "PyErr_Restore(etype, eval, etb);")
-            code.putln(
-                "}")
-    
-    def generate_traverse_function(self, scope, code):
-        base_type = scope.parent_type.base_type
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o, visitproc v, void *a) {"
-                % scope.mangle_internal("tp_traverse"))
-        code.putln(
-                "int e;")
-        self.generate_self_cast(scope, code)
-        if base_type:
-            code.putln(
-                    "e = %s->tp_traverse(o, v, a); if (e) return e;" %
-                        base_type.typeptr_cname)
-        for entry in scope.var_entries:
-            if entry.type.is_pyobject:
-                var_code = "p->%s" % entry.cname
-                code.putln(
-                        "if (%s) {"
-                            % var_code)
-                if entry.type.is_extension_type:
-                    var_code = "((PyObject*)%s)" % var_code
-                code.putln(
-                            "e = (*v)(%s, a); if (e) return e;" 
-                                % var_code)
-                code.putln(
-                        "}")
-        code.putln(
-                "return 0;")
-        code.putln(
-            "}")
-    
-    def generate_clear_function(self, scope, code):
-        base_type = scope.parent_type.base_type
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o) {"
-                % scope.mangle_internal("tp_clear"))
-        self.generate_self_cast(scope, code)
-        if base_type:
-            code.putln(
-                "%s->tp_clear(o);" %
-                    base_type.typeptr_cname)
-        for entry in scope.var_entries:
-            if entry.type.is_pyobject:
-                name = "p->%s" % entry.cname
-                code.put_xdecref(name, entry.type)
-                #code.put_init_to_py_none(name)
-                code.put_init_var_to_py_none(entry, "p->%s")
-        code.putln(
-            "return 0;")
-        code.putln(
-            "}")
-        
-    def generate_getitem_int_function(self, scope, code):
-        # This function is put into the sq_item slot when
-        # a __getitem__ method is present. It converts its
-        # argument to a Python integer and calls mp_subscript.
-        code.putln(
-            "static PyObject *%s(PyObject *o, int i) {" %
-                scope.mangle_internal("sq_item"))
-        code.putln(
-                "PyObject *r;")
-        code.putln(
-                "PyObject *x = PyInt_FromLong(i); if(!x) return 0;")
-        code.putln(
-                "r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
-        code.putln(
-                "Py_DECREF(x);")
-        code.putln(
-                "return r;")
-        code.putln(
-            "}")
-
-    def generate_ass_subscript_function(self, scope, code):
-        # Setting and deleting an item are both done through
-        # the ass_subscript method, so we dispatch to user's __setitem__
-        # or __delitem__, or raise an exception.
-        base_type = scope.parent_type.base_type
-        set_entry = scope.lookup_here("__setitem__")
-        del_entry = scope.lookup_here("__delitem__")
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
-                scope.mangle_internal("mp_ass_subscript"))
-        code.putln(
-                "if (v) {")
-        if set_entry:
-            code.putln(
-                    "return %s(o, i, v);" %
-                        set_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
-            code.putln(
-                    "PyErr_Format(PyExc_NotImplementedError,")
-            code.putln(
-                    '  "Subscript assignment not supported by %s", o->ob_type->tp_name);')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-                "else {")
-        if del_entry:
-            code.putln(
-                    "return %s(o, i);" %
-                        del_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
-            code.putln(
-                    "PyErr_Format(PyExc_NotImplementedError,")
-            code.putln(
-                    '  "Subscript deletion not supported by %s", o->ob_type->tp_name);')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-            "}")
-    
-    def generate_guarded_basetype_call(
-            self, base_type, substructure, slot, args, code):
-        if base_type:
-            base_tpname = base_type.typeptr_cname
-            if substructure:
-                code.putln(
-                    "if (%s->%s && %s->%s->%s)" % (
-                        base_tpname, substructure, base_tpname, substructure, slot))
-                code.putln(
-                    "  return %s->%s->%s(%s);" % (
-                        base_tpname, substructure, slot, args))
-            else:
-                code.putln(
-                    "if (%s->%s)" % (
-                        base_tpname, slot))
-                code.putln(
-                    "  return %s->%s(%s);" % (
-                        base_tpname, slot, args))
-
-    def generate_ass_slice_function(self, scope, code):
-        # Setting and deleting a slice are both done through
-        # the ass_slice method, so we dispatch to user's __setslice__
-        # or __delslice__, or raise an exception.
-        base_type = scope.parent_type.base_type
-        set_entry = scope.lookup_here("__setslice__")
-        del_entry = scope.lookup_here("__delslice__")
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o, int i, int j, PyObject *v) {" %
-                scope.mangle_internal("sq_ass_slice"))
-        code.putln(
-                "if (v) {")
-        if set_entry:
-            code.putln(
-                    "return %s(o, i, j, v);" %
-                        set_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
-            code.putln(
-                    "PyErr_Format(PyExc_NotImplementedError,")
-            code.putln(
-                    '  "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-                "else {")
-        if del_entry:
-            code.putln(
-                    "return %s(o, i, j);" %
-                        del_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
-            code.putln(
-                    "PyErr_Format(PyExc_NotImplementedError,")
-            code.putln(
-                    '  "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-            "}")
-
-    def generate_getattro_function(self, scope, code):
-        # First try to get the attribute using PyObject_GenericGetAttr.
-        # If that raises an AttributeError, call the user's __getattr__
-        # method.
-        entry = scope.lookup_here("__getattr__")
-        code.putln("")
-        code.putln(
-            "static PyObject *%s(PyObject *o, PyObject *n) {"
-                % scope.mangle_internal("tp_getattro"))
-        code.putln(
-                "PyObject *v = PyObject_GenericGetAttr(o, n);")
-        code.putln(
-                "if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
-        code.putln(
-                    "PyErr_Clear();")
-        code.putln(
-                    "v = %s(o, n);" %
-                        entry.func_cname)
-        code.putln(
-                "}")
-        code.putln(
-                "return v;")
-        code.putln(
-            "}")
-    
-    def generate_setattro_function(self, scope, code):
-        # Setting and deleting an attribute are both done through
-        # the setattro method, so we dispatch to user's __setattr__
-        # or __delattr__ or fall back on PyObject_GenericSetAttr.
-        base_type = scope.parent_type.base_type
-        set_entry = scope.lookup_here("__setattr__")
-        del_entry = scope.lookup_here("__delattr__")
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
-                scope.mangle_internal("tp_setattro"))
-        code.putln(
-                "if (v) {")
-        if set_entry:
-            code.putln(
-                    "return %s(o, n, v);" %
-                        set_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, None, "tp_setattro", "o, n, v", code)
-            code.putln(
-                    "return PyObject_GenericSetAttr(o, n, v);")
-        code.putln(
-                "}")
-        code.putln(
-                "else {")
-        if del_entry:
-            code.putln(
-                    "return %s(o, n);" %
-                        del_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, None, "tp_setattro", "o, n, v", code)
-            code.putln(
-                    "return PyObject_GenericSetAttr(o, n, 0);")
-        code.putln(
-                "}")
-        code.putln(
-            "}")
-    
-    def generate_descr_get_function(self, scope, code):
-        # The __get__ function of a descriptor object can be
-        # called with NULL for the second or third arguments
-        # under some circumstances, so we replace them with
-        # None in that case.
-        user_get_entry = scope.lookup_here("__get__")
-        code.putln("")
-        code.putln(
-            "static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
-                scope.mangle_internal("tp_descr_get"))
-        code.putln(
-            "PyObject *r = 0;")
-        code.putln(
-            "if (!i) i = Py_None;")
-        code.putln(
-            "if (!c) c = Py_None;")
-        #code.put_incref("i", py_object_type)
-        #code.put_incref("c", py_object_type)
-        code.putln(
-            "r = %s(o, i, c);" %
-                user_get_entry.func_cname)
-        #code.put_decref("i", py_object_type)
-        #code.put_decref("c", py_object_type)
-        code.putln(
-            "return r;")
-        code.putln(
-            "}")
-    
-    def generate_descr_set_function(self, scope, code):
-        # Setting and deleting are both done through the __set__
-        # method of a descriptor, so we dispatch to user's __set__
-        # or __delete__ or raise an exception.
-        base_type = scope.parent_type.base_type
-        user_set_entry = scope.lookup_here("__set__")
-        user_del_entry = scope.lookup_here("__delete__")
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
-                scope.mangle_internal("tp_descr_set"))
-        code.putln(
-                "if (v) {")
-        if user_set_entry:
-            code.putln(
-                    "return %s(o, i, v);" %
-                        user_set_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, None, "tp_descr_set", "o, i, v", code)
-            code.putln(
-                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-                "else {")
-        if user_del_entry:
-            code.putln(
-                    "return %s(o, i);" %
-                        user_del_entry.func_cname)
-        else:
-            self.generate_guarded_basetype_call(
-                base_type, None, "tp_descr_set", "o, i, v", code)
-            code.putln(
-                    'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")           
-        code.putln(
-            "}")
-    
-    def generate_property_accessors(self, cclass_scope, code):
-        for entry in cclass_scope.property_entries:
-            property_scope = entry.scope
-            if property_scope.defines_any(["__get__"]):
-                self.generate_property_get_function(entry, code)
-            if property_scope.defines_any(["__set__", "__del__"]):
-                self.generate_property_set_function(entry, code)
-    
-    def generate_property_get_function(self, property_entry, code):
-        property_scope = property_entry.scope
-        property_entry.getter_cname = property_scope.parent_scope.mangle(
-            Naming.prop_get_prefix, property_entry.name)
-        get_entry = property_scope.lookup_here("__get__")
-        code.putln("")
-        code.putln(
-            "static PyObject *%s(PyObject *o, void *x) {" %
-                property_entry.getter_cname)
-        code.putln(
-                "return %s(o);" %
-                    get_entry.func_cname)
-        code.putln(
-            "}")
-    
-    def generate_property_set_function(self, property_entry, code):
-        property_scope = property_entry.scope
-        property_entry.setter_cname = property_scope.parent_scope.mangle(
-            Naming.prop_set_prefix, property_entry.name)
-        set_entry = property_scope.lookup_here("__set__")
-        del_entry = property_scope.lookup_here("__del__")
-        code.putln("")
-        code.putln(
-            "static int %s(PyObject *o, PyObject *v, void *x) {" %
-                property_entry.setter_cname)
-        code.putln(
-                "if (v) {")
-        if set_entry:
-            code.putln(
-                    "return %s(o, v);" %
-                        set_entry.func_cname)
-        else:
-            code.putln(
-                    'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-                "else {")
-        if del_entry:
-            code.putln(
-                    "return %s(o);" %
-                        del_entry.func_cname)
-        else:
-            code.putln(
-                    'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
-            code.putln(
-                    "return -1;")
-        code.putln(
-                "}")
-        code.putln(
-            "}")
-
-    def generate_typeobj_definition(self, modname, entry, code):
-        type = entry.type
-        scope = type.scope
-        for suite in TypeSlots.substructures:
-            suite.generate_substructure(scope, code)
-        code.putln("")
-        if entry.visibility == 'public':
-            header = "DL_EXPORT(PyTypeObject) %s = {"
-        else:
-            #header = "statichere PyTypeObject %s = {"
-            header = "PyTypeObject %s = {"
-        #code.putln(header % scope.parent_type.typeobj_cname)
-        code.putln(header % type.typeobj_cname)
-        code.putln(
-            "PyObject_HEAD_INIT(0)")
-        code.putln(
-            "0, /*ob_size*/")
-        code.putln(
-            '"%s.%s", /*tp_name*/' % (
-                modname, scope.class_name))
-        if type.typedef_flag:
-            objstruct = type.objstruct_cname
-        else:
-            #objstruct = "struct %s" % scope.parent_type.objstruct_cname
-            objstruct = "struct %s" % type.objstruct_cname
-        code.putln(
-            "sizeof(%s), /*tp_basicsize*/" %
-                objstruct)
-        code.putln(
-            "0, /*tp_itemsize*/")
-        for slot in TypeSlots.slot_table:
-            slot.generate(scope, code)
-        code.putln(
-            "};")
-    
-    def generate_method_table(self, env, code):
-        code.putln("")
-        code.putln(
-            "static struct PyMethodDef %s[] = {" % 
-                env.method_table_cname)
-        for entry in env.pyfunc_entries:
-                code.put_pymethoddef(entry, ",")
-        code.putln(
-                "{0, 0, 0, 0}")
-        code.putln(
-            "};")
-    
-    def generate_member_table(self, env, code):
-        #print "ModuleNode.generate_member_table: scope =", env ###
-        if env.public_attr_entries:
-            code.putln("")
-            code.putln(
-                "static struct PyMemberDef %s[] = {" %
-                    env.member_table_cname)
-            type = env.parent_type
-            if type.typedef_flag:
-                objstruct = type.objstruct_cname
-            else:
-                objstruct = "struct %s" % type.objstruct_cname
-            for entry in env.public_attr_entries:
-                type_code = entry.type.pymemberdef_typecode
-                if entry.visibility == 'readonly':
-                    flags = "READONLY"
-                else:
-                    flags = "0"
-                code.putln('{"%s", %s, %s, %s, 0},' % (
-                    entry.name,
-                    type_code,
-                    "offsetof(%s, %s)" % (objstruct, entry.name),
-                    flags))
-            code.putln(
-                    "{0, 0, 0, 0, 0}")
-            code.putln(
-                "};")
-    
-    def generate_getset_table(self, env, code):
-        if env.property_entries:
-            code.putln("")
-            code.putln(
-                "static struct PyGetSetDef %s[] = {" %
-                    env.getset_table_cname)
-            for entry in env.property_entries:
-                code.putln(
-                    '{"%s", %s, %s, %s, 0},' % (
-                        entry.name,
-                        entry.getter_cname or "0",
-                        entry.setter_cname or "0",
-                        entry.doc_cname or "0"))
-            code.putln(
-                    "{0, 0, 0, 0, 0}")
-            code.putln(
-                "};")
-    
-    def generate_interned_name_table(self, env, code):
-        items = env.intern_map.items()
-        if items:
-            items.sort()
-            code.putln("")
-            code.putln(
-                "static __Pyx_InternTabEntry %s[] = {" %
-                    Naming.intern_tab_cname)
-            for (name, cname) in items:
-                code.putln(
-                    '{&%s, "%s"},' % (
-                        cname,
-                        name))
-            code.putln(
-                "{0, 0}")
-            code.putln(
-                "};")
-    
-    def generate_py_string_table(self, env, code):
-        entries = env.all_pystring_entries
-        if entries:
-            code.putln("")
-            code.putln(
-                "static __Pyx_StringTabEntry %s[] = {" %
-                    Naming.stringtab_cname)
-            for entry in entries:
-                code.putln(
-                    "{&%s, %s, sizeof(%s)}," % (
-                        entry.pystring_cname,
-                        entry.cname,
-                        entry.cname))
-            code.putln(
-                "{0, 0, 0}")
-            code.putln(
-                "};")
-    
-    def generate_filename_init_prototype(self, code):
-        code.putln("");
-        code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
-
-    def generate_module_init_func(self, imported_modules, env, code):
-        code.putln("")
-        header = "PyMODINIT_FUNC init%s(void)" % env.module_name
-        code.putln("%s; /*proto*/" % header)
-        code.putln("%s {" % header)
-        code.put_var_declarations(env.temp_entries)
-        #code.putln("/*--- Libary function declarations ---*/")
-        env.generate_library_function_declarations(code)
-        self.generate_filename_init_call(code)
-        #code.putln("/*--- Module creation code ---*/")
-        self.generate_module_creation_code(env, code)
-        #code.putln("/*--- Intern code ---*/")
-        self.generate_intern_code(env, code)
-        #code.putln("/*--- String init code ---*/")
-        self.generate_string_init_code(env, code)
-        #code.putln("/*--- Global init code ---*/")
-        self.generate_global_init_code(env, code)
-        #code.putln("/*--- Type import code ---*/")
-        for module in imported_modules:
-            self.generate_type_import_code_for_module(module, env, code)
-        #code.putln("/*--- Type init code ---*/")
-        self.generate_type_init_code(env, code)
-        #code.putln("/*--- Execution code ---*/")
-        self.body.generate_execution_code(code)
-        code.putln("return;")
-        code.put_label(code.error_label)
-        code.put_var_xdecrefs(env.temp_entries)
-        code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
-        env.use_utility_code(traceback_utility_code)
-        code.putln('}')
-    
-    def generate_filename_init_call(self, code):
-        code.putln("%s();" % Naming.fileinit_cname)
-    
-    def generate_module_creation_code(self, env, code):
-        # Generate code to create the module object and
-        # install the builtins.
-        if env.doc:
-            doc = env.doc_cname
-        else:
-            doc = "0"
-        code.putln(
-            '%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
-                env.module_cname, 
-                env.module_name, 
-                env.method_table_cname, 
-                doc))
-        code.putln(
-            "if (!%s) %s;" % (
-                env.module_cname,
-                code.error_goto(self.pos)));
-        code.putln(
-            '%s = PyImport_AddModule("__builtin__");' %
-                Naming.builtins_cname)
-        code.putln(
-            "if (!%s) %s;" % (
-                Naming.builtins_cname,
-                code.error_goto(self.pos)));
-        code.putln(
-            'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
-                env.module_cname,
-                Naming.builtins_cname,
-                code.error_goto(self.pos)))
-    
-    def generate_intern_code(self, env, code):
-        if env.intern_map:
-            env.use_utility_code(init_intern_tab_utility_code);
-            code.putln(
-                "if (__Pyx_InternStrings(%s) < 0) %s;" % (
-                    Naming.intern_tab_cname,
-                    code.error_goto(self.pos)))
-    
-    def generate_string_init_code(self, env, code):
-        if env.all_pystring_entries:
-            env.use_utility_code(init_string_tab_utility_code)
-            code.putln(
-                "if (__Pyx_InitStrings(%s) < 0) %s;" % (
-                    Naming.stringtab_cname,
-                    code.error_goto(self.pos)))
-    
-    def generate_global_init_code(self, env, code):
-        # Generate code to initialise global PyObject *
-        # variables to None.
-        for entry in env.var_entries:
-            if entry.visibility <> 'extern':
-                if entry.type.is_pyobject:
-                    code.put_init_var_to_py_none(entry)
-    
-    def generate_type_import_code_for_module(self, module, env, code):
-        # Generate type import code for all extension types in
-        # an imported module.
-        if module.c_class_entries:
-            for entry in module.c_class_entries:
-                self.generate_type_import_code(env, entry, code)
-    
-    def generate_type_init_code(self, env, code):
-        # Generate type import code for extern extension types
-        # and type ready code for non-extern ones.
-        for entry in env.c_class_entries:
-            if entry.visibility == 'extern':
-                self.generate_type_import_code(env, entry, code)
-            else:
-                self.generate_exttype_vtable_init_code(entry, code)
-                self.generate_type_ready_code(env, entry, code)
-                self.generate_typeptr_assignment_code(entry, code)
-    
-    def use_type_import_utility_code(self, env):
-        import ExprNodes
-        env.use_utility_code(type_import_utility_code)
-        env.use_utility_code(ExprNodes.import_utility_code)
-    
-    def generate_type_import_code(self, env, entry, code):
-        # Generate code to import the typeobject of an
-        # extension type defined in another module, and
-        # extract its C method table pointer if any.
-        type = entry.type
-        if type.typedef_flag:
-            objstruct = type.objstruct_cname
-        else:
-            objstruct = "struct %s" % type.objstruct_cname
-        code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
-            type.typeptr_cname,
-            type.module_name, 
-            type.name,
-            objstruct,
-            type.typeptr_cname,
-            code.error_goto(entry.pos)))
-        self.use_type_import_utility_code(env)
-        if type.vtabptr_cname:
-            code.putln(
-                "if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
-                    type.typeptr_cname,
-                    type.vtabptr_cname,
-                    code.error_goto(entry.pos)))
-            env.use_utility_code(get_vtable_utility_code)
-    
-    def generate_type_ready_code(self, env, entry, code):
-        # Generate a call to PyType_Ready for an extension
-        # type defined in this module.
-        type = entry.type
-        typeobj_cname = type.typeobj_cname
-        scope = type.scope
-        if scope: # could be None if there was an error
-            if entry.visibility <> 'extern':
-                for slot in TypeSlots.slot_table:
-                    slot.generate_dynamic_init_code(scope, code)
-                code.putln(
-                    "if (PyType_Ready(&%s) < 0) %s" % (
-                        typeobj_cname,
-                        code.error_goto(entry.pos)))
-                if type.vtable_cname:
-                    code.putln(
-                        "if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
-                            typeobj_cname,
-                            type.vtabptr_cname,
-                            code.error_goto(entry.pos)))
-                    env.use_utility_code(set_vtable_utility_code)
-                code.putln(
-                    'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
-                        Naming.module_cname,
-                        scope.class_name,
-                        typeobj_cname,
-                        code.error_goto(entry.pos)))
-                weakref_entry = scope.lookup_here("__weakref__")
-                if weakref_entry:
-                    if weakref_entry.type is py_object_type:
-                        tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
-                        code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
-                            tp_weaklistoffset,
-                            tp_weaklistoffset,
-                            type.objstruct_cname,
-                            weakref_entry.cname))
-                    else:
-                        error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
-    
-    def generate_exttype_vtable_init_code(self, entry, code):
-        # Generate code to initialise the C method table of an
-        # extension type.
-        type = entry.type
-        if type.vtable_cname:
-            code.putln(
-                "%s = &%s;" % (
-                    type.vtabptr_cname,
-                    type.vtable_cname))
-            if type.base_type and type.base_type.vtabptr_cname:
-                code.putln(
-                    "%s.%s = *%s;" % (
-                        type.vtable_cname,
-                        Naming.obj_base_cname,
-                        type.base_type.vtabptr_cname))
-            for meth_entry in type.scope.cfunc_entries:
-                if meth_entry.func_cname:
-                    code.putln(
-                        "*(void **)&%s.%s = (void *)%s;" % (
-                            type.vtable_cname,
-                            meth_entry.cname,
-                            meth_entry.func_cname))
-    
-    def generate_typeptr_assignment_code(self, entry, code):
-        # Generate code to initialise the typeptr of an extension
-        # type defined in this module to point to its type object.
-        type = entry.type
-        if type.typeobj_cname:
-            code.putln(
-                "%s = &%s;" % (
-                    type.typeptr_cname, type.typeobj_cname))
-    
-    def generate_utility_functions(self, env, code):
-        code.putln("")
-        code.putln("/* Runtime support code */")
-        code.putln("")
-        code.putln("static void %s(void) {" % Naming.fileinit_cname)
-        code.putln("%s = %s;" % 
-            (Naming.filetable_cname, Naming.filenames_cname))
-        code.putln("}")
-        for utility_code in env.utility_code_used:
-            code.put(utility_code)
 
 
 class StatListNode(Node):
@@ -1697,8 +487,6 @@ class FuncDefNode(StatNode, BlockNode):
         # ----- Top-level constants used by this function
         self.generate_interned_name_decls(lenv, code)
         self.generate_py_string_decls(lenv, code)
-        #code.putln("")
-        #code.put_var_declarations(lenv.const_entries, static = 1)
         self.generate_const_definitions(lenv, code)
         # ----- Function header
         code.putln("")
@@ -1721,13 +509,12 @@ class FuncDefNode(StatNode, BlockNode):
         # ----- Fetch arguments
         self.generate_argument_parsing_code(code)
         self.generate_argument_increfs(lenv, code)
-        #self.generate_stararg_getting_code(code)
-        self.generate_argument_conversion_code(code)
         # ----- Initialise local variables
         for entry in lenv.var_entries:
-            if entry.type.is_pyobject and entry.init_to_none:
+            if entry.type.is_pyobject and entry.init_to_none and entry.used:
                 code.put_init_var_to_py_none(entry)
-        # ----- Check types of arguments
+        # ----- Check and convert arguments
+        self.generate_argument_conversion_code(code)
         self.generate_argument_type_tests(code)
         # ----- Function body
         self.body.generate_execution_code(code)
@@ -1743,29 +530,31 @@ class FuncDefNode(StatNode, BlockNode):
             val = self.return_type.default_value
             if val:
                 code.putln("%s = %s;" % (Naming.retval_cname, val))
-        code.putln("goto %s;" % code.return_label)
+        #code.putln("goto %s;" % code.return_label)
         # ----- Error cleanup
-        code.put_label(code.error_label)
-        code.put_var_xdecrefs(lenv.temp_entries)
-        err_val = self.error_value()
-        exc_check = self.caller_will_check_exceptions()
-        if err_val is not None or exc_check:
-            code.putln(
-                '__Pyx_AddTraceback("%s");' % 
-                    self.entry.qualified_name)
-            if err_val is not None:
+        if code.error_label in code.labels_used:
+            code.put_goto(code.return_label)
+            code.put_label(code.error_label)
+            code.put_var_xdecrefs(lenv.temp_entries)
+            err_val = self.error_value()
+            exc_check = self.caller_will_check_exceptions()
+            if err_val is not None or exc_check:
                 code.putln(
-                    "%s = %s;" % (
-                        Naming.retval_cname, 
-                        err_val))
-        else:
-            code.putln(
-                '__Pyx_WriteUnraisable("%s");' % 
-                    self.entry.qualified_name)
-            env.use_utility_code(unraisable_exception_utility_code)
+                    '__Pyx_AddTraceback("%s");' % 
+                        self.entry.qualified_name)
+                if err_val is not None:
+                    code.putln(
+                        "%s = %s;" % (
+                            Naming.retval_cname, 
+                            err_val))
+            else:
+                code.putln(
+                    '__Pyx_WriteUnraisable("%s");' % 
+                        self.entry.qualified_name)
+                env.use_utility_code(unraisable_exception_utility_code)
         # ----- Return cleanup
         code.put_label(code.return_label)
-        code.put_var_decrefs(lenv.var_entries)
+        code.put_var_decrefs(lenv.var_entries, used_only = 1)
         code.put_var_decrefs(lenv.arg_entries)
         self.put_stararg_decrefs(code)
         if not self.return_type.is_void:
@@ -1872,9 +661,6 @@ class CFuncDefNode(FuncDefNode):
     def generate_argument_parsing_code(self, code):
         pass
     
-#      def generate_stararg_getting_code(self, code):
-#              pass
-    
     def generate_argument_conversion_code(self, code):
         pass
     
@@ -2015,6 +801,7 @@ class DefNode(FuncDefNode):
                 arg.entry.init_to_none = 0
             else:
                 arg.entry = self.declare_argument(env, arg)
+            arg.entry.used = 1
             arg.entry.is_self_arg = arg.is_self_arg
             if arg.hdr_type:
                 if arg.is_self_arg or \
@@ -2025,11 +812,13 @@ class DefNode(FuncDefNode):
 
     def declare_python_arg(self, env, arg):
         if arg:
-            arg.entry = env.declare_var(arg.name, 
+            entry = env.declare_var(arg.name, 
                 PyrexTypes.py_object_type, arg.pos)
-            arg.entry.init = "0"
-            arg.entry.init_to_none = 0
-            arg.entry.xdecref_cleanup = 1
+            entry.used = 1
+            entry.init = "0"
+            entry.init_to_none = 0
+            entry.xdecref_cleanup = 1
+            arg.entry = entry
             
     def analyse_expressions(self, env):
         self.analyse_default_values(env)
@@ -2044,6 +833,7 @@ class DefNode(FuncDefNode):
                     arg.default = arg.default.coerce_to(arg.type, env)
                     arg.default.allocate_temps(env)
                     arg.default_entry = env.add_default_value(arg.type)
+                    arg.default_entry.used = 1
                 else:
                     error(arg.pos,
                         "This argument cannot have a default value")
@@ -2339,11 +1129,10 @@ class PyClassDefNode(StatNode, BlockNode):
         self.scope = cenv
         self.body.analyse_declarations(cenv)
         self.body.analyse_expressions(cenv)
-        self.target.analyse_target_expression(env)
+        self.target.analyse_target_expression(env, self.classobj)
         self.dict.release_temp(env)
-        self.classobj.release_temp(env)
-        self.target.release_target_temp(env)
-        #env.recycle_pending_temps()
+        #self.classobj.release_temp(env)
+        #self.target.release_target_temp(env)
     
     def generate_function_definitions(self, env, code):
         self.generate_py_string_decls(self.scope, code)
@@ -2488,7 +1277,6 @@ class ExprStatNode(StatNode):
     def analyse_expressions(self, env):
         self.expr.analyse_expressions(env)
         self.expr.release_temp(env)
-        #env.recycle_pending_temps() # TEMPORARY
     
     def generate_execution_code(self, code):
         self.expr.generate_evaluation_code(code)
@@ -2507,8 +1295,13 @@ class AssignmentNode(StatNode):
     #  to any of the left hand sides.
 
     def analyse_expressions(self, env):
-        self.analyse_expressions_1(env)
-        self.analyse_expressions_2(env)
+        self.analyse_types(env)
+        self.allocate_rhs_temps(env)
+        self.allocate_lhs_temps(env)
+
+#      def analyse_expressions(self, env):
+#              self.analyse_expressions_1(env)
+#              self.analyse_expressions_2(env)
 
     def generate_execution_code(self, code):
         self.generate_rhs_evaluation_code(code)
@@ -2526,18 +1319,33 @@ class SingleAssignmentNode(AssignmentNode):
     def analyse_declarations(self, env):
         self.lhs.analyse_target_declaration(env)
     
-    def analyse_expressions_1(self, env, use_temp = 0):
+    def analyse_types(self, env, use_temp = 0):
         self.rhs.analyse_types(env)
         self.lhs.analyse_target_types(env)
         self.rhs = self.rhs.coerce_to(self.lhs.type, env)
         if use_temp:
             self.rhs = self.rhs.coerce_to_temp(env)
+    
+    def allocate_rhs_temps(self, env):
         self.rhs.allocate_temps(env)
+
+    def allocate_lhs_temps(self, env):
+        self.lhs.allocate_target_temps(env, self.rhs)
+        #self.lhs.release_target_temp(env)
+        #self.rhs.release_temp(env)            
     
-    def analyse_expressions_2(self, env):
-        self.lhs.allocate_target_temps(env)
-        self.lhs.release_target_temp(env)
-        self.rhs.release_temp(env)             
+#      def analyse_expressions_1(self, env, use_temp = 0):
+#              self.rhs.analyse_types(env)
+#              self.lhs.analyse_target_types(env)
+#              self.rhs = self.rhs.coerce_to(self.lhs.type, env)
+#              if use_temp:
+#                      self.rhs = self.rhs.coerce_to_temp(env)
+#              self.rhs.allocate_temps(env)
+#      
+#      def analyse_expressions_2(self, env):
+#              self.lhs.allocate_target_temps(env)
+#              self.lhs.release_target_temp(env)
+#              self.rhs.release_temp(env)              
 
     def generate_rhs_evaluation_code(self, code):
         self.rhs.generate_evaluation_code(code)
@@ -2562,31 +1370,12 @@ class CascadedAssignmentNode(AssignmentNode):
         for lhs in self.lhs_list:
             lhs.analyse_target_declaration(env)
     
-#      def analyse_expressions(self, env):
-#              import ExprNodes
-#              self.rhs.analyse_types(env)
-#              self.rhs = self.rhs.coerce_to_temp(env)
-#              self.rhs.allocate_temps(env)
-#              self.coerced_rhs_list = []
-#              for lhs in self.lhs_list:
-#                      lhs.analyse_target_types(env)
-#                      coerced_rhs = ExprNodes.CloneNode(self.rhs).coerce_to(lhs.type, env)
-#                      self.coerced_rhs_list.append(coerced_rhs)
-#                      coerced_rhs.allocate_temps(env)
-#                      lhs.allocate_target_temps(env)
-#                      coerced_rhs.release_temp(env)
-#                      lhs.release_target_temp(env)
-#              self.rhs.release_temp(env)
-
-    def analyse_expressions_1(self, env, use_temp = 0):
+    def analyse_types(self, env, use_temp = 0):
         self.rhs.analyse_types(env)
         if use_temp:
             self.rhs = self.rhs.coerce_to_temp(env)
         else:
             self.rhs = self.rhs.coerce_to_simple(env)
-        self.rhs.allocate_temps(env)
-    
-    def analyse_expressions_2(self, env):
         from ExprNodes import CloneNode
         self.coerced_rhs_list = []
         for lhs in self.lhs_list:
@@ -2594,21 +1383,39 @@ class CascadedAssignmentNode(AssignmentNode):
             rhs = CloneNode(self.rhs)
             rhs = rhs.coerce_to(lhs.type, env)
             self.coerced_rhs_list.append(rhs)
+
+    def allocate_rhs_temps(self, env):
+        self.rhs.allocate_temps(env)
+    
+    def allocate_lhs_temps(self, env):
+        for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
             rhs.allocate_temps(env)
-            lhs.allocate_target_temps(env)
-            lhs.release_target_temp(env)
-            rhs.release_temp(env)
+            lhs.allocate_target_temps(env, rhs)
+            #lhs.release_target_temp(env)
+            #rhs.release_temp(env)
         self.rhs.release_temp(env)
-            
-#      def generate_execution_code(self, code):
-#              self.rhs.generate_evaluation_code(code)
-#              for i in range(len(self.lhs_list)):
-#                      lhs = self.lhs_list[i]
-#                      rhs = self.coerced_rhs_list[i]
-#                      rhs.generate_evaluation_code(code)
-#                      lhs.generate_assignment_code(rhs, code)
-#                      # Assignment has already disposed of the cloned RHS
-#              self.rhs.generate_disposal_code(code)
+    
+#      def analyse_expressions_1(self, env, use_temp = 0):
+#              self.rhs.analyse_types(env)
+#              if use_temp:
+#                      self.rhs = self.rhs.coerce_to_temp(env)
+#              else:
+#                      self.rhs = self.rhs.coerce_to_simple(env)
+#              self.rhs.allocate_temps(env)
+#      
+#      def analyse_expressions_2(self, env):
+#              from ExprNodes import CloneNode
+#              self.coerced_rhs_list = []
+#              for lhs in self.lhs_list:
+#                      lhs.analyse_target_types(env)
+#                      rhs = CloneNode(self.rhs)
+#                      rhs = rhs.coerce_to(lhs.type, env)
+#                      self.coerced_rhs_list.append(rhs)
+#                      rhs.allocate_temps(env)
+#                      lhs.allocate_target_temps(env)
+#                      lhs.release_target_temp(env)
+#                      rhs.release_temp(env)
+#              self.rhs.release_temp(env)
     
     def generate_rhs_evaluation_code(self, code):
         self.rhs.generate_evaluation_code(code)
@@ -2642,9 +1449,16 @@ class ParallelAssignmentNode(AssignmentNode):
     
     def analyse_expressions(self, env):
         for stat in self.stats:
-            stat.analyse_expressions_1(env, use_temp = 1)
+            stat.analyse_types(env, use_temp = 1)
+            stat.allocate_rhs_temps(env)
         for stat in self.stats:
-            stat.analyse_expressions_2(env)
+            stat.allocate_lhs_temps(env)
+
+#      def analyse_expressions(self, env):
+#              for stat in self.stats:
+#                      stat.analyse_expressions_1(env, use_temp = 1)
+#              for stat in self.stats:
+#                      stat.analyse_expressions_2(env)
     
     def generate_execution_code(self, code):
         for stat in self.stats:
@@ -2695,10 +1509,10 @@ class DelStatNode(StatNode):
     
     def analyse_expressions(self, env):
         for arg in self.args:
-            arg.analyse_target_expression(env)
+            arg.analyse_target_expression(env, None)
             if not arg.type.is_pyobject:
                 error(arg.pos, "Deletion of non-Python object")
-            #env.recycle_pending_temps() # TEMPORARY
+            #arg.release_target_temp(env)
     
     def generate_execution_code(self, code):
         for arg in self.args:
@@ -2726,9 +1540,10 @@ class BreakStatNode(StatNode):
         if not code.break_label:
             error(self.pos, "break statement not inside loop")
         else:
-            code.putln(
-                "goto %s;" %
-                    code.break_label)
+            #code.putln(
+            #  "goto %s;" %
+            #          code.break_label)
+            code.put_goto(code.break_label)
 
 
 class ContinueStatNode(StatNode):
@@ -2742,9 +1557,10 @@ class ContinueStatNode(StatNode):
         elif not code.continue_label:
             error(self.pos, "continue statement not inside loop")
         else:
-            code.putln(
-                "goto %s;" %
-                    code.continue_label)
+            #code.putln(
+            #  "goto %s;" %
+            #          code.continue_label)
+            code.put_goto(code.continue_label)
 
 
 class ReturnStatNode(StatNode):
@@ -2780,8 +1596,6 @@ class ReturnStatNode(StatNode):
         if not self.return_type:
             # error reported earlier
             return
-        for entry in self.temps_in_use:
-            code.put_var_decref_clear(entry)
         if self.value:
             self.value.generate_evaluation_code(code)
             self.value.make_owned_reference(code)
@@ -2798,9 +1612,12 @@ class ReturnStatNode(StatNode):
                     "%s = %s;" % (
                         Naming.retval_cname,
                         self.return_type.default_value))
-        code.putln(
-            "goto %s;" %
-                code.return_label)
+        for entry in self.temps_in_use:
+            code.put_var_decref_clear(entry)
+        #code.putln(
+        #      "goto %s;" %
+        #              code.return_label)
+        code.put_goto(code.return_label)
 
 
 class RaiseStatNode(StatNode):
@@ -2962,9 +1779,10 @@ class IfClauseNode(Node):
             "if (%s) {" %
                 self.condition.result_code)
         self.body.generate_execution_code(code)
-        code.putln(
-            "goto %s;" %
-                end_label)
+        #code.putln(
+        #      "goto %s;" %
+        #              end_label)
+        code.put_goto(end_label)
         code.putln("}")
         
     
@@ -2993,12 +1811,12 @@ class WhileStatNode(StatNode):
         old_loop_labels = code.new_loop_labels()
         code.putln(
             "while (1) {")
-        code.put_label(code.continue_label)
         self.condition.generate_evaluation_code(code)
         code.putln(
             "if (!%s) break;" %
                 self.condition.result_code)
         self.body.generate_execution_code(code)
+        code.put_label(code.continue_label)
         code.putln("}")
         break_label = code.break_label
         code.set_loop_labels(old_loop_labels)
@@ -3031,12 +1849,10 @@ class ForInStatNode(StatNode):
         self.item = ExprNodes.NextNode(self.iterator, env)
         self.item = self.item.coerce_to(self.target.type, env)
         self.item.allocate_temps(env)
-        self.target.allocate_target_temps(env)
-        self.item.release_temp(env)
-        self.target.release_target_temp(env)
-        #env.recycle_pending_temps() # TEMPORARY
+        self.target.allocate_target_temps(env, self.item)
+        #self.item.release_temp(env)
+        #self.target.release_target_temp(env)
         self.body.analyse_expressions(env)
-        #env.recycle_pending_temps() # TEMPORARY
         if self.else_clause:
             self.else_clause.analyse_expressions(env)
         self.iterator.release_temp(env)
@@ -3046,10 +1862,10 @@ class ForInStatNode(StatNode):
         self.iterator.generate_evaluation_code(code)
         code.putln(
             "for (;;) {")
-        code.put_label(code.continue_label)
         self.item.generate_evaluation_code(code)
         self.target.generate_assignment_code(self.item, code)
         self.body.generate_execution_code(code)
+        code.put_label(code.continue_label)
         code.putln(
             "}")
         break_label = code.break_label
@@ -3075,6 +1891,7 @@ class ForFromStatNode(StatNode):
     #
     #  Used internally:
     #
+    #  is_py_target       bool
     #  loopvar_name       string
     #  py_loopvar_node    PyTempNode or None
     
@@ -3094,14 +1911,19 @@ class ForFromStatNode(StatNode):
         if not (self.bound2.is_name or self.bound2.is_literal):
             self.bound2 = self.bound2.coerce_to_temp(env)
         target_type = self.target.type
-        if not (target_type.is_pyobject
-            or target_type.assignable_from(PyrexTypes.c_int_type)):
-                error(self.target.pos,
-                    "Cannot assign integer to variable of type '%s'" % target_type)
+        if not (target_type.is_pyobject or target_type.is_int):
+            error(self.target.pos,
+                "Integer for-loop variable must be of type int or Python object")
+        #if not (target_type.is_pyobject
+        #      or target_type.assignable_from(PyrexTypes.c_int_type)):
+        #              error(self.target.pos,
+        #                      "Cannot assign integer to variable of type '%s'" % target_type)
         if target_type.is_int:
+            self.is_py_target = 0
             self.loopvar_name = self.target.entry.cname
             self.py_loopvar_node = None
         else:
+            self.is_py_target = 1
             c_loopvar_node = ExprNodes.TempNode(self.pos, 
                 PyrexTypes.c_long_type, env)
             c_loopvar_node.allocate_temps(env)
@@ -3110,20 +1932,18 @@ class ForFromStatNode(StatNode):
                 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
         self.bound1.allocate_temps(env)
         self.bound2.allocate_temps(env)
-        if self.py_loopvar_node:
+        if self.is_py_target:
             self.py_loopvar_node.allocate_temps(env)
-        self.target.allocate_target_temps(env)
-        self.target.release_target_temp(env)
-        if self.py_loopvar_node:
-            self.py_loopvar_node.release_temp(env)
+            self.target.allocate_target_temps(env, self.py_loopvar_node)
+            #self.target.release_target_temp(env)
+            #self.py_loopvar_node.release_temp(env)
         self.body.analyse_expressions(env)
-        if self.py_loopvar_node:
+        if self.is_py_target:
             c_loopvar_node.release_temp(env)
         if self.else_clause:
             self.else_clause.analyse_expressions(env)
         self.bound1.release_temp(env)
         self.bound2.release_temp(env)
-        #env.recycle_pending_temps() # TEMPORARY
             
     def generate_execution_code(self, code):
         old_loop_labels = code.new_loop_labels()
@@ -3200,9 +2020,10 @@ class TryExceptStatNode(StatNode):
             self.else_clause.generate_execution_code(code)
             code.putln(
                 "}")
-        code.putln(
-            "goto %s;" %
-                end_label)
+        #code.putln(
+        #      "goto %s;" %
+        #              end_label)
+        code.put_goto(end_label)
         code.put_label(our_error_label)
         code.put_var_xdecrefs_clear(self.cleanup_list)
         default_clause_seen = 0
@@ -3214,9 +2035,10 @@ class TryExceptStatNode(StatNode):
                     error(except_clause.pos, "Default except clause not last")
             except_clause.generate_handling_code(code, end_label)
         if not default_clause_seen:
-            code.putln(
-                "goto %s;" %
-                    code.error_label)
+            #code.putln(
+            #  "goto %s;" %
+            #          code.error_label)
+            code.put_goto(code.error_label)
         code.put_label(end_label)
 
 
@@ -3248,11 +2070,11 @@ class ExceptClauseNode(Node):
         self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
         self.exc_value.allocate_temps(env)
         if self.target:
-            self.target.analyse_target_expression(env)
-        self.exc_value.release_temp(env)
-        if self.target:
-            self.target.release_target_temp(env)
-        #env.recycle_pending_temps() # TEMPORARY
+            self.target.analyse_target_expression(env, self.exc_value)
+        else:
+            self.exc_value.release_temp(env)
+        #if self.target:
+        #      self.target.release_target_temp(env)
         self.body.analyse_expressions(env)
     
     def generate_handling_code(self, code, end_label):
@@ -3281,9 +2103,10 @@ class ExceptClauseNode(Node):
         else:
             self.exc_value.generate_disposal_code(code)
         self.body.generate_execution_code(code)
-        code.putln(
-            "goto %s;"
-                % end_label)
+        #code.putln(
+        #      "goto %s;"
+        #              % end_label)
+        code.put_goto(end_label)
         code.putln(
             "}")
 
@@ -3353,20 +2176,23 @@ class TryFinallyStatNode(StatNode):
         #code.putln(
         #              "int %s;" %
         #                      self.lineno_var)
+        code.use_label(catch_label)
         code.putln(
                 "__pyx_why = 0; goto %s;" %
                     catch_label)
         for i in range(len(new_labels)):
-            if new_labels[i] and new_labels[i] <> "<try>":
-                if new_labels[i] == new_error_label:
-                    self.put_error_catcher(code, 
-                        new_error_label, i+1, catch_label)
-                else:
-                    code.putln(
-                        "%s: __pyx_why = %s; goto %s;" % (
-                            new_labels[i],
-                            i+1,
-                            catch_label))
+            new_label = new_labels[i]
+            if new_label and new_label <> "<try>":
+                if new_label in code.labels_used:
+                    if new_label == new_error_label:
+                        self.put_error_catcher(code, 
+                            new_error_label, i+1, catch_label)
+                    else:
+                            code.putln(
+                                "%s: __pyx_why = %s; goto %s;" % (
+                                    new_label,
+                                    i+1,
+                                    catch_label))
         code.put_label(catch_label)
         code.set_all_labels(old_labels)
         self.finally_clause.generate_execution_code(code)
@@ -3377,6 +2203,7 @@ class TryFinallyStatNode(StatNode):
                 if old_labels[i] == old_error_label:
                     self.put_error_uncatcher(code, i+1, old_error_label)
                 else:
+                    code.use_label(old_labels[i])
                     code.putln(
                         "case %s: goto %s;" % (
                             i+1,
@@ -3400,9 +2227,10 @@ class TryFinallyStatNode(StatNode):
         code.putln(
                 "%s = %s;" % (
                     self.lineno_var, Naming.lineno_cname))
-        code.putln(
-                "goto %s;" %
-                    catch_label)
+        #code.putln(
+        #              "goto %s;" %
+        #                      catch_label)
+        code.put_goto(catch_label)
         code.putln(
             "}")
             
@@ -3420,9 +2248,10 @@ class TryFinallyStatNode(StatNode):
             code.putln(
                 "%s = 0;" %
                     var)
-        code.putln(
-                "goto %s;" %
-                    error_label)
+        #code.putln(
+        #              "goto %s;" %
+        #                      error_label)
+        code.put_goto(error_label)
         code.putln(
             "}")
 
@@ -3502,11 +2331,10 @@ class FromImportStatNode(StatNode):
         for name, target in self.items:
             if Options.intern_names:
                 self.interned_items.append((env.intern(name), target))
-            target.analyse_target_expression(env)
-            target.release_temp(env)
+            target.analyse_target_expression(env, None)
+            #target.release_target_temp(env) # was release_temp ?!?
         self.module.release_temp(env)
         self.item.release_temp(env)
-        #env.recycle_pending_temps() # TEMPORARY
     
     def generate_execution_code(self, code):
         self.module.generate_evaluation_code(code)
@@ -3542,38 +2370,21 @@ utility_function_predeclarations = \
 """
 typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
 typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
-static PyObject *__Pyx_UnpackItem(PyObject *, int); /*proto*/
-static int __Pyx_EndUnpack(PyObject *, int); /*proto*/
-static int __Pyx_PrintItem(PyObject *); /*proto*/
-static int __Pyx_PrintNewline(void); /*proto*/
-static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
-static void __Pyx_ReRaise(void); /*proto*/
-static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
-static PyObject *__Pyx_GetExcValue(void); /*proto*/
-static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
-static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
-static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,\
- char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
-static void __Pyx_WriteUnraisable(char *name); /*proto*/
-static void __Pyx_AddTraceback(char *funcname); /*proto*/
-static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
-static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
-static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
-static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
-static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
-static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
 """
 
-get_name_predeclaration = \
-"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
+#get_name_predeclaration = \
+#"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
 
-get_name_interned_predeclaration = \
-"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
+#get_name_interned_predeclaration = \
+#"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
 
 #------------------------------------------------------------------------------------
 
-printing_utility_code = \
-r"""
+printing_utility_code = [
+"""
+static int __Pyx_PrintItem(PyObject *); /*proto*/
+static int __Pyx_PrintNewline(void); /*proto*/
+""",r"""
 static PyObject *__Pyx_GetStdout(void) {
     PyObject *f = PySys_GetObject("stdout");
     if (!f) {
@@ -3614,14 +2425,16 @@ static int __Pyx_PrintNewline(void) {
     PyFile_SoftSpace(f, 0);
     return 0;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
 # The following function is based on do_raise() from ceval.c.
 
-raise_utility_code = \
+raise_utility_code = [
 """
+static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
+""","""
 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
     Py_XINCREF(type);
     Py_XINCREF(value);
@@ -3648,32 +2461,28 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
         Py_INCREF(type);
         Py_DECREF(tmp);
     }
-    if (PyString_Check(type))
-        ;
-    else if (PyClass_Check(type))
+    if (PyString_Check(type)) {
+        if (PyErr_Warn(PyExc_DeprecationWarning,
+                "raising a string exception is deprecated"))
+            goto raise_error;
+    }
+    else if (PyType_Check(type) || PyClass_Check(type))
         ; /*PyErr_NormalizeException(&type, &value, &tb);*/
-    else if (PyInstance_Check(type)) {
+    else {
         /* Raising an instance.  The value should be a dummy. */
         if (value != Py_None) {
             PyErr_SetString(PyExc_TypeError,
-              "instance exception may not have a separate value");
+                "instance exception may not have a separate value");
             goto raise_error;
         }
-        else {
-            /* Normalize to raise <class>, <instance> */
-            Py_DECREF(value);
-            value = type;
+        /* Normalize to raise <class>, <instance> */
+        Py_DECREF(value);
+        value = type;
+        if (PyInstance_Check(type))
             type = (PyObject*) ((PyInstanceObject*)type)->in_class;
-            Py_INCREF(type);
-        }
-    }
-    else {
-        /* Not something you can raise.  You get an exception
-           anyway, just not what you specified :-) */
-        PyErr_Format(PyExc_TypeError,
-                 "exceptions must be strings, classes, or "
-                 "instances, not %s", type->ob_type->tp_name);
-        goto raise_error;
+        else
+            type = (PyObject*) type->ob_type;
+        Py_INCREF(type);
     }
     PyErr_Restore(type, value, tb);
     return;
@@ -3683,12 +2492,14 @@ raise_error:
     Py_XDECREF(tb);
     return;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-reraise_utility_code = \
+reraise_utility_code = [
 """
+static void __Pyx_ReRaise(void); /*proto*/
+""","""
 static void __Pyx_ReRaise(void) {
     PyThreadState *tstate = PyThreadState_Get();
     PyObject *type = tstate->exc_type;
@@ -3699,12 +2510,14 @@ static void __Pyx_ReRaise(void) {
     Py_XINCREF(tb);
     PyErr_Restore(type, value, tb);
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-arg_type_test_utility_code = \
+arg_type_test_utility_code = [
 """
+static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
+""","""
 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
     if (!type) {
         PyErr_Format(PyExc_SystemError, "Missing type object");
@@ -3717,7 +2530,7 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
         name, type->tp_name, obj->ob_type->tp_name);
     return 0;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 #
@@ -3733,8 +2546,11 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
 #  reference to the same dictionary is passed back in *kwds.
 #
 
-get_starargs_utility_code = \
+get_starargs_utility_code = [
 """
+static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,\
+ char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
+""","""
 static int __Pyx_GetStarArgs(
     PyObject **args, 
     PyObject **kwds,
@@ -3799,18 +2615,22 @@ static int __Pyx_GetStarArgs(
 bad:
     Py_XDECREF(args1);
     Py_XDECREF(kwds1);
-    if (*args2)
+    if (*args2) {
         Py_XDECREF(*args2);
-    if (*kwds2)
+    }
+    if (*kwds2) {
         Py_XDECREF(*kwds2);
+    }
     return -1;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-unraisable_exception_utility_code = \
+unraisable_exception_utility_code = [
 """
+static void __Pyx_WriteUnraisable(char *name); /*proto*/
+""","""
 static void __Pyx_WriteUnraisable(char *name) {
     PyObject *old_exc, *old_val, *old_tb;
     PyObject *ctx;
@@ -3821,12 +2641,14 @@ static void __Pyx_WriteUnraisable(char *name) {
         ctx = Py_None;
     PyErr_WriteUnraisable(ctx);
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-traceback_utility_code = \
+traceback_utility_code = [
 """
+static void __Pyx_AddTraceback(char *funcname); /*proto*/
+""","""
 #include "compile.h"
 #include "frameobject.h"
 #include "traceback.h"
@@ -3888,12 +2710,14 @@ bad:
     'FILENAME': Naming.filename_cname,
     'LINENO':  Naming.lineno_cname,
     'GLOBALS': Naming.module_cname
-}
+}]
 
 #------------------------------------------------------------------------------------
 
-type_import_utility_code = \
+type_import_utility_code = [
 """
+static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size);  /*proto*/
+""","""
 static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, 
     long size) 
 {
@@ -3943,12 +2767,14 @@ done:
     Py_XDECREF(py_name_list);
     return (PyTypeObject *)result;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-set_vtable_utility_code = \
+set_vtable_utility_code = [
 """
+static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
+""","""
 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
     PyObject *pycobj = 0;
     int result;
@@ -3967,12 +2793,14 @@ done:
     Py_XDECREF(pycobj);
     return result;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-get_vtable_utility_code = \
-r"""
+get_vtable_utility_code = [
+"""
+static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
+""",r"""
 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
     int result;
     PyObject *pycobj;
@@ -3992,12 +2820,14 @@ done:
     Py_XDECREF(pycobj);
     return result;
 }
-"""
+"""]
 
 #------------------------------------------------------------------------------------
 
-init_intern_tab_utility_code = \
+init_intern_tab_utility_code = [
 """
+static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
+""","""
 static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
     while (t->p) {
         *t->p = PyString_InternFromString(t->s);
@@ -4007,12 +2837,14 @@ static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
     }
     return 0;
 }
-""";
+"""]
 
 #------------------------------------------------------------------------------------
 
-init_string_tab_utility_code = \
+init_string_tab_utility_code = [
 """
+static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
+""","""
 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     while (t->p) {
         *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
@@ -4022,6 +2854,6 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     }
     return 0;
 }
-""";
+"""]
 
 #------------------------------------------------------------------------------------
index 827c2559b0012654c47eab6638f70960c4a2927f..22bb490e10ea04ab7eff8dd4374fa01167e501d8 100644 (file)
@@ -8,6 +8,7 @@ from types import ListType, TupleType
 from Scanning import PyrexScanner
 import Nodes
 import ExprNodes
+from ModuleNode import ModuleNode
 from Errors import error, InternalError
 
 def p_ident(s, message = "Expected an identifier"):
@@ -413,13 +414,7 @@ def p_atom(s):
     elif sy == '`':
         return p_backquote_expr(s)
     elif sy == 'INT':
-        digits = s.systring
-        if digits[:2] == "0x":
-            value = long(digits[2:], 16)
-        elif digits[:1] == "0":
-            value = int(digits, 8)
-        else:
-            value = int(s.systring)
+        value = s.systring
         s.next()
         return ExprNodes.IntNode(pos, value = value)
     elif sy == 'LONG':
@@ -517,7 +512,7 @@ def p_string_literal(s):
                 elif c == '\n':
                     pass
                 else:
-                    chars.append(systr[1:])
+                    chars.append(r'\\' + systr[1:])
         elif sy == 'NEWLINE':
             chars.append(r'\n')
         elif sy == 'END_STRING':
@@ -668,7 +663,6 @@ def p_expression_or_assignment(s):
         if len(nodes) == 1:
             return nodes[0]
         else:
-            #return Nodes.StatListNode(nodes[0].pos, stats = nodes)
             return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes)
 
 def flatten_parallel_assignments(input, output):
@@ -1375,19 +1369,19 @@ def p_exception_value_clause(s):
             if s.sy == '?':
                 exc_check = 1
                 s.next()
-            exc_val = p_exception_value(s)
+            exc_val = p_simple_expr(s) #p_exception_value(s)
     return exc_val, exc_check
 
-def p_exception_value(s):
-    sign = ""
-    if s.sy == "-":
-        sign = "-"
-        s.next()
-    if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'):
-        s.systring = sign + s.systring
-        return p_atom(s)
-    else:
-        s.error("Exception value must be an int or float literal or NULL")
+#def p_exception_value(s):
+#      sign = ""
+#      if s.sy == "-":
+#              sign = "-"
+#              s.next()
+#      if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'):
+#              s.systring = sign + s.systring
+#              return p_atom(s)
+#      else:
+#              s.error("Exception value must be an int or float literal or NULL")
 
 c_arg_list_terminators = ('*', '**', '.', ')')
 c_arg_list_trailers = ('.', '*', '**')
@@ -1780,7 +1774,7 @@ def p_module(s, pxd):
     if s.sy <> 'EOF':
         s.error("Syntax error in statement [%s,%s]" % (
             repr(s.sy), repr(s.systring)))
-    return Nodes.ModuleNode(pos, doc = doc, body = body)
+    return ModuleNode(pos, doc = doc, body = body)
 
 #----------------------------------------------
 #
index 885766428e81cd5b005bf370c1f02fc28f633bc6..e0e359470001331ec7e8cc77bf0f019a4b544990 100644 (file)
@@ -259,14 +259,14 @@ class CType(PyrexType):
     from_py_function = None
 
 
-class CSimpleType(CType):
-    #
-    #  Base class for all unstructured C types.
-    #
-    pass
+#class CSimpleType(CType):
+#      #
+#      #  Base class for all unstructured C types.
+#      #
+#      pass
 
 
-class CVoidType(CSimpleType):
+class CVoidType(CType):
     is_void = 1
     
     def __repr__(self):
@@ -313,9 +313,6 @@ class CNumericType(CType):
             u = "unsigned "
         return "<CNumericType %s%s>" % (u, rank_to_type_name[self.rank])
     
-    def assignable_from_resolved_type(self, src_type):
-        return src_type.is_numeric or src_type is error_type
-    
     def declaration_code(self, entity_code, 
             for_display = 0, dll_linkage = None, pyrex = 0):
         if self.signed:
@@ -324,8 +321,6 @@ class CNumericType(CType):
             u = "unsigned "
         base = public_decl(u + rank_to_type_name[self.rank], dll_linkage)
         return "%s %s" % (base,  entity_code)
-
-#              return "%s%s %s" % (u, rank_to_type_name[self.rank], entity_code)
     
 
 class CIntType(CNumericType):
@@ -338,6 +333,9 @@ class CIntType(CNumericType):
     def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
         CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
         self.is_returncode = is_returncode
+    
+    def assignable_from_resolved_type(self, src_type):
+        return src_type.is_int or src_type.is_enum or src_type is error_type
 
 
 class CUIntType(CIntType):
@@ -373,6 +371,9 @@ class CFloatType(CNumericType):
     def __init__(self, rank, pymemberdef_typecode = None):
         CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
     
+    def assignable_from_resolved_type(self, src_type):
+        return src_type.is_numeric or src_type is error_type
+
 
 class CArrayType(CType):
     #  base_type     CType              Element type
@@ -447,6 +448,8 @@ class CPtrType(CType):
             return 1
         elif self.base_type.is_cfunction and other_type.is_cfunction:
             return self.base_type.same_as(other_type)
+        elif other_type.is_array:
+            return self.base_type.same_as(other_type.base_type)
         elif not other_type.is_ptr:
             return 0
         elif self.base_type.is_void:
@@ -608,14 +611,16 @@ class CStructOrUnionType(CType):
         return self.is_complete()
 
 
-class CEnumType(CIntType):
+class CEnumType(CType):
     #  name           string
     #  cname          string or None
     #  typedef_flag   boolean
     
     is_enum = 1
-    signed = 1
-    rank = 2
+    #signed = 1
+    #rank = 2
+    to_py_function = "PyInt_FromLong"
+    from_py_function = "PyInt_AsLong"
 
     def __init__(self, name, cname, typedef_flag):
         self.name = name
index 6ae4e3bf22e7f300ed2ec58fa12033f12c654517..3ac9218c9a7f8e5894d9b37a5dcd61db3e9ac58e 100644 (file)
@@ -61,6 +61,7 @@ class Entry:
     # interned_cname   string     C name of interned name string
     # pystring_cname   string     C name of Python version of string literal
     # is_interned      boolean    For string const entries, value is interned
+    # used             boolean
 
     borrowed = 0
     init = ""
@@ -91,6 +92,7 @@ class Entry:
     interned_cname = None
     pystring_cname = None
     is_interned = 0
+    used = 0
     
     def __init__(self, name, cname, type, pos = None, init = None):
         self.name = name
@@ -351,6 +353,7 @@ class Scope:
         # Add an entry for a string constant.
         cname = self.new_const_cname()
         entry = Entry("", cname, c_char_array_type, init = value)
+        entry.used = 1
         self.const_entries.append(entry)
         return entry
     
@@ -395,6 +398,7 @@ class Scope:
         self.temp_counter = n + 1
         cname = "%s%d" % (Naming.pyrex_prefix, n)
         entry = Entry("", cname, type)
+        entry.used = 1
         if type.is_pyobject:
             entry.init = "0"
         self.cname_to_entry[entry.cname] = entry
@@ -476,6 +480,7 @@ class ModuleScope(Scope):
     # intern_map           {string : string}  Mapping from Python names to interned strs
     # interned_names       [string]           Interned names pending generation of declarations
     # all_pystring_entries [Entry]            Python string consts from all scopes
+    # types_imported       {PyrexType : 1}    Set of types for which import code generated
 
     def __init__(self, name, parent_module, context):
         self.parent_module = parent_module
@@ -500,6 +505,7 @@ class ModuleScope(Scope):
         self.intern_map = {}
         self.interned_names = []
         self.all_pystring_entries = []
+        self.types_imported = {}
     
     def qualifying_scope(self):
         return self.parent_module
@@ -565,6 +571,8 @@ class ModuleScope(Scope):
         # None if previously declared as something else.
         entry = self.lookup_here(name)
         if entry:
+            if entry.is_pyglobal and entry.as_module is scope:
+                return entry # Already declared as the same module
             if not (entry.is_pyglobal and not entry.as_module):
                 error(pos, "'%s' redeclared" % name)
                 return None
@@ -956,6 +964,8 @@ class CClassScope(ClassScope):
         if visibility in ('public', 'readonly'):
             if type.pymemberdef_typecode:
                 self.public_attr_entries.append(entry)
+                if name == "__weakref__":
+                    error(pos, "Special attribute __weakref__ cannot be exposed to Python")
             else:
                 error(pos,
                     "C attribute of type '%s' cannot be accessed from Python" % type)
index da96658989af972255a6eb642a3cbe62e176bc65..be15e839073b9159e84a4a04bb8eee672b060f47 100644 (file)
@@ -1 +1 @@
-version = '0.9.4.1'
+version = '0.9.5.1a'
index aa34b0d2dc9c9ad8c40b9ea8adcb952bd60ef778..030dea0ed67a80c88be8ba5dabee8a931540763c 100644 (file)
@@ -4,7 +4,8 @@
 
 verbose = 0
 gcc_pendantic = True
-gcc_warnings_are_errors = False
+gcc_warnings_are_errors = True
+gcc_all_warnings = True
 
 import os
 from Pyrex.Utils import replace_suffix
@@ -23,6 +24,9 @@ if gcc_pendantic:
     compiler_options.extend(["-pedantic", "-Wno-long-long"])
 if gcc_warnings_are_errors:
     compiler_options.append("-Werror")
+if gcc_all_warnings:
+    compiler_options.append("-Wall")
+    compiler_options.append("-Wno-unused-function")
 
 linkers = ["gcc", "g++"]
 linker_options = \
@@ -45,6 +49,7 @@ def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
     args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
     if verbose_flag or verbose:
         print " ".join(args)
+    #print compiler, args ###
     status = os.spawnvp(os.P_WAIT, compiler, args)
     if status <> 0:
         raise CCompilerError("C compiler returned status %s" % status)
diff --git a/Cython/Mac/Finder_Std_Suite.py b/Cython/Mac/Finder_Std_Suite.py
deleted file mode 100644 (file)
index 1cec7d8..0000000
+++ /dev/null
@@ -1,768 +0,0 @@
-"""Suite Standard Suite: Common terms for most applications
-Level 1, version 1
-
-Generated from Macintosh HD:System 8.0:Finder
-AETE/AEUT resource version 0/144, language 0, script 0
-"""
-
-import aetools
-import MacOS
-
-_code = 'core'
-
-class Finder_Std_Suite:
-
-    _argmap_class_info = {
-        '_in' : 'wrcd',
-    }
-
-    def class_info(self, _object=None, _attributes={}, **_arguments):
-        """class info: Get information about an object class
-        Required argument: the object class about which information is requested
-        Keyword argument _in: the human language and script system in which to return information
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: a record containing the object's properties and elements
-        """
-        _code = 'core'
-        _subcode = 'qobj'
-
-        aetools.keysubst(_arguments, self._argmap_class_info)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_close = {
-        'saving' : 'savo',
-        'saving_in' : 'kfil',
-    }
-
-    def close(self, _object, _attributes={}, **_arguments):
-        """close: Close an object
-        Required argument: the object to close
-        Keyword argument saving: specifies whether changes should be saved before closing
-        Keyword argument saving_in: the file in which to save the object
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'core'
-        _subcode = 'clos'
-
-        aetools.keysubst(_arguments, self._argmap_close)
-        _arguments['----'] = _object
-
-        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_count = {
-        'each' : 'kocl',
-    }
-
-    def count(self, _object, _attributes={}, **_arguments):
-        """count: Return the number of elements of a particular class within an object
-        Required argument: the object whose elements are to be counted
-        Keyword argument each: the class of the elements to be counted
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: the number of elements
-        """
-        _code = 'core'
-        _subcode = 'cnte'
-
-        aetools.keysubst(_arguments, self._argmap_count)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_data_size = {
-        'as' : 'rtyp',
-    }
-
-    def data_size(self, _object, _attributes={}, **_arguments):
-        """data size: Return the size in bytes of an object
-        Required argument: the object whose data size is to be returned
-        Keyword argument as: the data type for which the size is calculated
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: the size of the object in bytes
-        """
-        _code = 'core'
-        _subcode = 'dsiz'
-
-        aetools.keysubst(_arguments, self._argmap_data_size)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    def delete(self, _object, _attributes={}, **_arguments):
-        """delete: Delete an element from an object
-        Required argument: the element to delete
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'core'
-        _subcode = 'delo'
-
-        if _arguments: raise TypeError, 'No optional args expected'
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_duplicate = {
-        'to' : 'insh',
-        'replacing' : 'alrp',
-        'routing_suppressed' : 'rout',
-    }
-
-    def duplicate(self, _object, _attributes={}, **_arguments):
-        """duplicate: Duplicate object(s)
-        Required argument: the object(s) to duplicate
-        Keyword argument to: the new location for the object(s)
-        Keyword argument replacing: Specifies whether or not to replace items in the destination that have the same name as items being duplicated
-        Keyword argument routing_suppressed: Specifies whether or not to autoroute items (default is false). Only applies when copying to the system folder.
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: to the duplicated object(s)
-        """
-        _code = 'core'
-        _subcode = 'clon'
-
-        aetools.keysubst(_arguments, self._argmap_duplicate)
-        _arguments['----'] = _object
-
-        aetools.enumsubst(_arguments, 'alrp', _Enum_bool)
-        aetools.enumsubst(_arguments, 'rout', _Enum_bool)
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_event_info = {
-        '_in' : 'wrcd',
-    }
-
-    def event_info(self, _object, _attributes={}, **_arguments):
-        """event info: Get information about the Apple events in a suite
-        Required argument: the event class of the Apple events for which to return information
-        Keyword argument _in: the human language and script system in which to return information
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: a record containing the events and their parameters
-        """
-        _code = 'core'
-        _subcode = 'gtei'
-
-        aetools.keysubst(_arguments, self._argmap_event_info)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    def exists(self, _object, _attributes={}, **_arguments):
-        """exists: Verify if an object exists
-        Required argument: the object in question
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: true if it exists, false if not
-        """
-        _code = 'core'
-        _subcode = 'doex'
-
-        if _arguments: raise TypeError, 'No optional args expected'
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_get = {
-        'as' : 'rtyp',
-    }
-
-    def get(self, _object, _attributes={}, **_arguments):
-        """get: Get the data for an object
-        Required argument: the object whose data is to be returned
-        Keyword argument as: the desired types for the data, in order of preference
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: the data from the object
-        """
-        _code = 'core'
-        _subcode = 'getd'
-
-        aetools.keysubst(_arguments, self._argmap_get)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_make = {
-        'new' : 'kocl',
-        'at' : 'insh',
-        'to' : 'to  ',
-        'with_data' : 'data',
-        'with_properties' : 'prdt',
-    }
-
-    def make(self, _no_object=None, _attributes={}, **_arguments):
-        """make: Make a new element
-        Keyword argument new: the class of the new element
-        Keyword argument at: the location at which to insert the element
-        Keyword argument to: when creating an alias file, the original item to create an alias to
-        Keyword argument with_data: the initial data for the element
-        Keyword argument with_properties: the initial values for the properties of the element
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: to the new object(s)
-        """
-        _code = 'core'
-        _subcode = 'crel'
-
-        aetools.keysubst(_arguments, self._argmap_make)
-        if _no_object != None: raise TypeError, 'No direct arg expected'
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_move = {
-        'to' : 'insh',
-        'replacing' : 'alrp',
-        'positioned_at' : 'mvpl',
-        'routing_suppressed' : 'rout',
-    }
-
-    def move(self, _object, _attributes={}, **_arguments):
-        """move: Move object(s) to a new location
-        Required argument: the object(s) to move
-        Keyword argument to: the new location for the object(s)
-        Keyword argument replacing: Specifies whether or not to replace items in the destination that have the same name as items being moved
-        Keyword argument positioned_at: Gives a list (in local window coordinates) of positions for the destination items
-        Keyword argument routing_suppressed: Specifies whether or not to autoroute items (default is false). Only applies when moving to the system folder.
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: to the object(s) after they have been moved
-        """
-        _code = 'core'
-        _subcode = 'move'
-
-        aetools.keysubst(_arguments, self._argmap_move)
-        _arguments['----'] = _object
-
-        aetools.enumsubst(_arguments, 'alrp', _Enum_bool)
-        aetools.enumsubst(_arguments, 'mvpl', _Enum_list)
-        aetools.enumsubst(_arguments, 'rout', _Enum_bool)
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_open = {
-        'using' : 'usin',
-        'with_properties' : 'prdt',
-    }
-
-    def open(self, _object, _attributes={}, **_arguments):
-        """open: Open the specified object(s)
-        Required argument: list of objects to open
-        Keyword argument using: the application file to open the object with
-        Keyword argument with_properties: the initial values for the properties, to be sent along with the open event sent to the application that opens the direct object
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'aevt'
-        _subcode = 'odoc'
-
-        aetools.keysubst(_arguments, self._argmap_open)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    def _print(self, _object, _attributes={}, **_arguments):
-        """print: Print the specified object(s)
-        Required argument: list of objects to print
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'aevt'
-        _subcode = 'pdoc'
-
-        if _arguments: raise TypeError, 'No optional args expected'
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_quit = {
-        'saving' : 'savo',
-    }
-
-    def quit(self, _no_object=None, _attributes={}, **_arguments):
-        """quit: Quit the Finder (direct parameter ignored)
-        Keyword argument saving: specifies whether to save currently open documents (not supported by Finder)
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'aevt'
-        _subcode = 'quit'
-
-        aetools.keysubst(_arguments, self._argmap_quit)
-        if _no_object != None: raise TypeError, 'No direct arg expected'
-
-        aetools.enumsubst(_arguments, 'savo', _Enum_savo)
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_save = {
-        '_in' : 'kfil',
-        'as' : 'fltp',
-    }
-
-    def save(self, _object, _attributes={}, **_arguments):
-        """save: Save an object (Not supported by Finder)
-        Required argument: the object to save
-        Keyword argument _in: the file in which to save the object (not supported by Finder)
-        Keyword argument as: the file type of the document in which to save the data (not supported by Finder)
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'core'
-        _subcode = 'save'
-
-        aetools.keysubst(_arguments, self._argmap_save)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_set = {
-        'to' : 'data',
-    }
-
-    def set(self, _object, _attributes={}, **_arguments):
-        """set: Set an object's data
-        Required argument: the object to change
-        Keyword argument to: the new value
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'core'
-        _subcode = 'setd'
-
-        aetools.keysubst(_arguments, self._argmap_set)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-    _argmap_suite_info = {
-        '_in' : 'wrcd',
-    }
-
-    def suite_info(self, _object, _attributes={}, **_arguments):
-        """suite info: Get information about event suite(s)
-        Required argument: the suite for which to return information
-        Keyword argument _in: the human language and script system in which to return information
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        Returns: a record containing the suites and their versions
-        """
-        _code = 'core'
-        _subcode = 'gtsi'
-
-        aetools.keysubst(_arguments, self._argmap_suite_info)
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-
-class application(aetools.ComponentItem):
-    """application - An application program"""
-    want = 'capp'
-class about_this_computer(aetools.NProperty):
-    """about this computer - the "About this Computer" dialog and the list of running processes displayed in it"""
-    which = 'abbx'
-    want = 'obj '
-class apple_menu_items_folder(aetools.NProperty):
-    """apple menu items folder - the special folder named "Apple Menu Items," the contents of which appear in the Apple menu"""
-    which = 'amnu'
-    want = 'obj '
-class clipboard(aetools.NProperty):
-    """clipboard - the Finder's clipboard window"""
-    which = 'pcli'
-    want = 'obj '
-class control_panels_folder(aetools.NProperty):
-    """control panels folder - the special folder named 'Control Panels'"""
-    which = 'ctrl'
-    want = 'obj '
-class desktop(aetools.NProperty):
-    """desktop - the desktop"""
-    which = 'desk'
-    want = 'obj '
-class extensions_folder(aetools.NProperty):
-    """extensions folder - the special folder named 'Extensions'"""
-    which = 'extn'
-    want = 'obj '
-class file_sharing(aetools.NProperty):
-    """file sharing - Is file sharing on?"""
-    which = 'fshr'
-    want = 'bool'
-class Finder_preferences(aetools.NProperty):
-    """Finder preferences - Various preferences that apply to the Finder as a whole"""
-    which = 'pfrp'
-    want = 'obj '
-class fonts_folder(aetools.NProperty):
-    """fonts folder - the special folder named 'Fonts'"""
-    which = 'ffnt'
-    want = 'obj '
-class frontmost(aetools.NProperty):
-    """frontmost - Is the Finder the frontmost process?"""
-    which = 'pisf'
-    want = 'bool'
-class insertion_location(aetools.NProperty):
-    """insertion location - the container in which a new folder would appear if "New Folder" was selected"""
-    which = 'pins'
-    want = 'obj '
-class largest_free_block(aetools.NProperty):
-    """largest free block - the largest free block of process memory available to launch an application"""
-    which = 'mfre'
-    want = 'long'
-class preferences_folder(aetools.NProperty):
-    """preferences folder - the special folder named 'Preferences'"""
-    which = 'pref'
-    want = 'obj '
-class product_version(aetools.NProperty):
-    """product version - the version of the System software running on this computer"""
-    which = 'ver2'
-    want = 'itxt'
-class selection(aetools.NProperty):
-    """selection - the selection visible to the user"""
-    which = 'sele'
-    want = 'obj '
-class sharing_starting_up(aetools.NProperty):
-    """sharing starting up - Is file sharing in the process of starting up?"""
-    which = 'fsup'
-    want = 'bool'
-class shutdown_items_folder(aetools.NProperty):
-    """shutdown items folder - the special folder named 'Shutdown Items'"""
-    which = 'shdf'
-    want = 'obj '
-class startup_items_folder(aetools.NProperty):
-    """startup items folder - the special folder named 'Startup Items'"""
-    which = 'strt'
-    want = 'obj '
-class system_folder(aetools.NProperty):
-    """system folder - the System folder"""
-    which = 'macs'
-    want = 'obj '
-class temporary_items_folder(aetools.NProperty):
-    """temporary items folder - the special folder named "Temporary Items" (invisible)"""
-    which = 'temp'
-    want = 'obj '
-class version(aetools.NProperty):
-    """version - the version of the Finder"""
-    which = 'vers'
-    want = 'itxt'
-class view_preferences(aetools.NProperty):
-    """view preferences - backwards compatibility with Finder Scripting Extension. DEPRECATED -- not supported after Finder 8.0"""
-    which = 'pvwp'
-    want = 'obj '
-class visible(aetools.NProperty):
-    """visible - Is the Finder's layer visible?"""
-    which = 'pvis'
-    want = 'bool'
-#        element 'dsut' as ['indx', 'name']
-#        element 'alia' as ['indx', 'name']
-#        element 'appf' as ['indx', 'name', 'ID  ']
-#        element 'clpf' as ['indx', 'name']
-#        element 'lwnd' as ['indx', 'name']
-#        element 'ctnr' as ['indx', 'name']
-#        element 'cwnd' as ['indx', 'name']
-#        element 'dwnd' as ['indx', 'name']
-#        element 'ccdv' as ['indx', 'name']
-#        element 'dafi' as ['indx', 'name']
-#        element 'cdsk' as ['indx', 'name']
-#        element 'cdis' as ['indx', 'name', 'ID  ']
-#        element 'docf' as ['indx', 'name']
-#        element 'file' as ['indx', 'name']
-#        element 'cfol' as ['indx', 'name', 'ID  ']
-#        element 'fntf' as ['indx', 'name']
-#        element 'fsut' as ['indx', 'name']
-#        element 'iwnd' as ['indx', 'name']
-#        element 'cobj' as ['indx', 'name']
-#        element 'sctr' as ['indx', 'name']
-#        element 'swnd' as ['indx', 'name']
-#        element 'sndf' as ['indx', 'name']
-#        element 'qwnd' as ['indx', 'name']
-#        element 'stcs' as ['indx', 'name']
-#        element 'ctrs' as ['indx', 'name']
-#        element 'cwin' as ['indx', 'name']
-
-class file(aetools.ComponentItem):
-    """file - A file"""
-    want = 'file'
-class creator_type(aetools.NProperty):
-    """creator type - the OSType identifying the application that created the item"""
-    which = 'fcrt'
-    want = 'type'
-class file_type_obsolete(aetools.NProperty):
-    """file type obsolete - the OSType identifying the type of data contained in the item (DEPRECATED - for use with scripts compiled before Finder 8.0. Will be removed in the next release)"""
-    which = 'fitp'
-    want = 'type'
-class file_type(aetools.NProperty):
-    """file type - the OSType identifying the type of data contained in the item"""
-    which = 'asty'
-    want = 'type'
-class locked_obsolete(aetools.NProperty):
-    """locked obsolete - Is the file locked? (DEPRECATED - for use with scripts compiled before Finder 8.0. Will be removed in the next release)"""
-    which = 'islk'
-    want = 'bool'
-class locked(aetools.NProperty):
-    """locked - Is the file locked?"""
-    which = 'aslk'
-    want = 'bool'
-# repeated property product_version the version of the product (visible at the top of the "Get Info" window)
-class stationery(aetools.NProperty):
-    """stationery - Is the file a stationery pad?"""
-    which = 'pspd'
-    want = 'bool'
-# repeated property version the version of the file (visible at the bottom of the "Get Info" window)
-
-files = file
-
-class window(aetools.ComponentItem):
-    """window - A window"""
-    want = 'cwin'
-class collapsed(aetools.NProperty):
-    """collapsed - Is the window collapsed (only applies to non-pop-up windows)?"""
-    which = 'wshd'
-    want = 'bool'
-class popup(aetools.NProperty):
-    """popup - Is the window is a pop-up window?"""
-    which = 'drwr'
-    want = 'bool'
-class pulled_open(aetools.NProperty):
-    """pulled open - Is the window pulled open (only applies to pop-up windows)?"""
-    which = 'pull'
-    want = 'bool'
-# repeated property visible Is the window visible (always true for Finder windows)?
-class zoomed_full_size(aetools.NProperty):
-    """zoomed full size - Is the window zoomed to the full size of the screen? (can only be set, not read)"""
-    which = 'zumf'
-    want = 'bool'
-
-windows = window
-# XXXX application element 'dsut' not found!!
-# XXXX application element 'alia' not found!!
-# XXXX application element 'appf' not found!!
-# XXXX application element 'clpf' not found!!
-# XXXX application element 'lwnd' not found!!
-# XXXX application element 'ctnr' not found!!
-# XXXX application element 'cwnd' not found!!
-# XXXX application element 'dwnd' not found!!
-# XXXX application element 'ccdv' not found!!
-# XXXX application element 'dafi' not found!!
-# XXXX application element 'cdsk' not found!!
-# XXXX application element 'cdis' not found!!
-# XXXX application element 'docf' not found!!
-# XXXX application element 'cfol' not found!!
-# XXXX application element 'fntf' not found!!
-# XXXX application element 'fsut' not found!!
-# XXXX application element 'iwnd' not found!!
-# XXXX application element 'cobj' not found!!
-# XXXX application element 'sctr' not found!!
-# XXXX application element 'swnd' not found!!
-# XXXX application element 'sndf' not found!!
-# XXXX application element 'qwnd' not found!!
-# XXXX application element 'stcs' not found!!
-# XXXX application element 'ctrs' not found!!
-application._propdict = {
-    'about_this_computer' : about_this_computer,
-    'apple_menu_items_folder' : apple_menu_items_folder,
-    'clipboard' : clipboard,
-    'control_panels_folder' : control_panels_folder,
-    'desktop' : desktop,
-    'extensions_folder' : extensions_folder,
-    'file_sharing' : file_sharing,
-    'Finder_preferences' : Finder_preferences,
-    'fonts_folder' : fonts_folder,
-    'frontmost' : frontmost,
-    'insertion_location' : insertion_location,
-    'largest_free_block' : largest_free_block,
-    'preferences_folder' : preferences_folder,
-    'product_version' : product_version,
-    'selection' : selection,
-    'sharing_starting_up' : sharing_starting_up,
-    'shutdown_items_folder' : shutdown_items_folder,
-    'startup_items_folder' : startup_items_folder,
-    'system_folder' : system_folder,
-    'temporary_items_folder' : temporary_items_folder,
-    'version' : version,
-    'view_preferences' : view_preferences,
-    'visible' : visible,
-}
-application._elemdict = {
-    'file' : file,
-    'window' : window,
-}
-file._propdict = {
-    'creator_type' : creator_type,
-    'file_type_obsolete' : file_type_obsolete,
-    'file_type' : file_type,
-    'locked_obsolete' : locked_obsolete,
-    'locked' : locked,
-    'product_version' : product_version,
-    'stationery' : stationery,
-    'version' : version,
-}
-file._elemdict = {
-}
-window._propdict = {
-    'collapsed' : collapsed,
-    'popup' : popup,
-    'pulled_open' : pulled_open,
-    'visible' : visible,
-    'zoomed_full_size' : zoomed_full_size,
-}
-window._elemdict = {
-}
-# XXXX enum list not found!!
-# XXXX enum bool not found!!
-# XXXX enum savo not found!!
-
-#
-# Indices of types declared in this module
-#
-_classdeclarations = {
-    'cwin' : window,
-    'file' : file,
-    'capp' : application,
-}
-
-_propdeclarations = {
-    'amnu' : apple_menu_items_folder,
-    'pvwp' : view_preferences,
-    'extn' : extensions_folder,
-    'pins' : insertion_location,
-    'fshr' : file_sharing,
-    'aslk' : locked,
-    'drwr' : popup,
-    'fcrt' : creator_type,
-    'pcli' : clipboard,
-    'asty' : file_type,
-    'strt' : startup_items_folder,
-    'islk' : locked_obsolete,
-    'pvis' : visible,
-    'pref' : preferences_folder,
-    'pisf' : frontmost,
-    'sele' : selection,
-    'temp' : temporary_items_folder,
-    'pull' : pulled_open,
-    'abbx' : about_this_computer,
-    'wshd' : collapsed,
-    'pspd' : stationery,
-    'fitp' : file_type_obsolete,
-    'pfrp' : Finder_preferences,
-    'desk' : desktop,
-    'fsup' : sharing_starting_up,
-    'mfre' : largest_free_block,
-    'ctrl' : control_panels_folder,
-    'zumf' : zoomed_full_size,
-    'shdf' : shutdown_items_folder,
-    'ffnt' : fonts_folder,
-    'macs' : system_folder,
-    'ver2' : product_version,
-    'vers' : version,
-}
-
-_compdeclarations = {
-}
-
-_enumdeclarations = {
-}
diff --git a/Cython/Mac/MPW_Misc_Suite.py b/Cython/Mac/MPW_Misc_Suite.py
deleted file mode 100644 (file)
index a11f59d..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-"""Suite Misc Suite: Suite that adds additional features to the Application.
-Level 1, version 1
-
-Generated from MPW:MPW Shell
-AETE/AEUT resource version 1/0, language 0, script 0
-"""
-
-import aetools
-import MacOS
-
-_code = 'misc'
-
-class MPW_Misc_Suite:
-
-    def DoScript(self, _object, _attributes={}, **_arguments):
-        """DoScript: Execute an MPW command, any command that could be executed from the command line can be sent as a script.
-        Required argument: The script to execute
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'misc'
-        _subcode = 'dosc'
-
-        if _arguments: raise TypeError, 'No optional args expected'
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-
-#
-# Indices of types declared in this module
-#
-_classdeclarations = {
-}
-
-_propdeclarations = {
-}
-
-_compdeclarations = {
-}
-
-_enumdeclarations = {
-}
diff --git a/Cython/Mac/Makefile b/Cython/Mac/Makefile
new file mode 100644 (file)
index 0000000..a7ca34b
--- /dev/null
@@ -0,0 +1,19 @@
+# Makefile for Darwin
+
+# Change this to your Python source location
+PYTHON := /Local/Build/Pythonic/python/2.3
+
+INCLUDE := -I$(PYTHON) -I$(PYTHON)/Include -I$(PYTHON)/Mac/Include
+
+CCOPTS := -fno-strict-aliasing -Wno-long-double -no-cpp-precomp \
+       -mno-fused-madd -fno-common -dynamic
+
+LDOPTS := -Wl,-F.,-w -bundle -framework Python -framework Carbon
+
+all:   _File.so
+
+_File.o:       _Filemodule_patched.c
+       gcc -c $(INCLUDE) $(OPTS) $< -o $@
+
+_File.so:      _File.o
+       gcc $(LDOPTS) $< -o $@
diff --git a/Cython/Mac/PS_Misc_Suite.py b/Cython/Mac/PS_Misc_Suite.py
deleted file mode 100644 (file)
index d664ffe..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-"Apple Event suite for pyserver."
-
-import aetools
-import MacOS
-
-_code = 'misc'
-
-class PS_Misc_Suite:
-
-    def DoScript(self, _object, _attributes={}, **_arguments):
-        """DoScript: Execute a\ 5 Python file, optionally with command line args.
-        Required argument: filename.py or [filename.py, arg, ...]
-        Keyword argument _attributes: AppleEvent attribute dictionary
-        """
-        _code = 'misc'
-        _subcode = 'dosc'
-
-        if _arguments: raise TypeError, 'No optional args expected'
-        _arguments['----'] = _object
-
-
-        _reply, _arguments, _attributes = self.send(_code, _subcode,
-                _arguments, _attributes)
-        if _arguments.has_key('errn'):
-            raise aetools.Error, aetools.decodeerror(_arguments)
-        # XXXX Optionally decode result
-        if _arguments.has_key('----'):
-            return _arguments['----']
-
-
-#
-# Indices of types declared in this module
-#
-_classdeclarations = {
-}
-
-_propdeclarations = {
-}
-
-_compdeclarations = {
-}
-
-_enumdeclarations = {
-}
diff --git a/Cython/Mac/PyServerMain.py b/Cython/Mac/PyServerMain.py
deleted file mode 100644 (file)
index 9769d11..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-#
-#   Simple Apple-event driven Python interpreter
-#
-
-import os, sys, traceback
-from cStringIO import StringIO
-from MiniAEFrame import AEServer, MiniApplication
-
-class PythonServer(AEServer, MiniApplication):
-    
-    def __init__(self):
-        MiniApplication.__init__(self)
-        AEServer.__init__(self)
-        self.installaehandler('aevt', 'oapp', ignore)
-        self.installaehandler('aevt', 'quit', quit)
-        self.installaehandler('misc', 'dosc', doscript)
-
-
-def ignore(**kwds):
-    pass
-
-def quit(**kwds):
-    server._quit()
-
-def doscript(args, **kwds):
-    print "doscript:", repr(args) ###
-    stat = 0
-    output = ""
-    errput = ""
-    #print "Normalising args" ###
-    if type(args) == type(""):
-        args = [args]
-    #print "Setting sys.argv" ###
-    sys.argv = args
-    #print "Finding script directory and module file" ###
-    dir = os.path.dirname(args[0])
-    dir = os.path.join(start_dir, dir)
-    pyfile = os.path.basename(args[0])
-    mod = os.path.splitext(pyfile)[0]
-    #print "dir:", repr(dir) ###
-    #print "mod:", repr(mod) ###
-    os.chdir(dir)
-    sys.path = start_path[:]
-    sys.path[0] = dir
-    #print "path:", sys.path ###
-    try:
-        sys.stdout = StringIO()
-        sys.stderr = StringIO()
-        try:
-            #sys.__stdout__.write("Path: %s\n" % sys.path) ###
-            #sys.__stdout__.write("Importing: %s\n" % mod) ###
-            try:
-                __import__(mod)
-            except KeyboardInterrupt:
-                raise
-            except SystemExit, exc:
-                #sys.__stdout__.write("Caught a SystemExit\n") ###
-                try:
-                    stat = int(str(exc))
-                except ValueError:
-                    stat = 1
-                #sys.__stdout__.write("stat = %s\n" % stat) ###
-            except:
-                traceback.print_exc()
-                stat = 1
-            #sys.__stdout__.write("Done the import\n") ###
-        finally:
-            output = sys.stdout.getvalue()
-            #sys.__stdout__.write("Output:\n%s" % output) ###
-            errput = sys.stderr.getvalue()
-    finally:
-        sys.stdout = sys.__stdout__
-        sys.stderr = sys.__stdout__
-        pass
-    return [stat, output, errput]
-
-start_dir = os.getcwd()
-start_path = sys.path[:]
-server = PythonServer()
-#print "Open for business"
-try:
-    server.mainloop()
-except:
-    traceback.print_exc()
-    #sys.exit(1)
-#print "Closing shop"
index 8e909367cc93674841073424ecb17eb850cd274c..d5aaf2b4083e9d51a9d07b7de8627c760cfbc1bf 100644 (file)
@@ -108,6 +108,15 @@ PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
 
 static PyObject *File_Error;
 
+static PyTypeObject FInfo_Type;
+
+#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
+
+typedef struct FInfoObject {
+       PyObject_HEAD
+       FInfo ob_itself;
+} FInfoObject;
+
 /* ------------------- Object type FSCatalogInfo -------------------- */
 
 static PyTypeObject FSCatalogInfo_Type;
@@ -338,16 +347,16 @@ static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject
 
 static PyObject *FSCatalogInfo_get_finderInfo(FSCatalogInfoObject *self, void *closure)
 {
-       return FInfo_New((FInfo *)self->finderInfo);
+       return FInfo_New((FInfo *)self->ob_itself.finderInfo);
 }
 
 static int FSCatalogInfo_set_finderInfo(FSCatalogInfoObject *self, PyObject *v, void *closure)
 {
        if (!FInfo_Check(v)) {
-               PyErr_SetString(PyTypeError, "Expected an FInfo object");
+               PyErr_SetString(PyExc_TypeError, "Expected an FInfo object");
                return -1;
        }
-       *(FInfo *)self->finderInfo = ((FInfoObject *)self)->ob_itself;
+       *(FInfo *)self->ob_itself.finderInfo = ((FInfoObject *)v)->ob_itself;
        return 0;
 }
 
@@ -485,15 +494,6 @@ static PyTypeObject FSCatalogInfo_Type = {
 
 /* ----------------------- Object type FInfo ------------------------ */
 
-static PyTypeObject FInfo_Type;
-
-#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
-
-typedef struct FInfoObject {
-       PyObject_HEAD
-       FInfo ob_itself;
-} FInfoObject;
-
 static PyObject *FInfo_New(FInfo *itself)
 {
        FInfoObject *it;
@@ -3247,8 +3247,8 @@ PyMac_GetFSRef(PyObject *v, FSRef *fsr)
        if ( PyString_Check(v) || PyUnicode_Check(v)) {
                char *path = NULL;
                if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
-                       return NULL;
-               if ( (err=FSPathMakeRef(path, fsr, NULL)) ) {
+                       return 0;
+               if ( (err=FSPathMakeRef((unsigned char *)path, fsr, NULL)) ) {
                        PyMac_Error(err);
                        return 0;
                }
diff --git a/Cython/Unix/LinuxSystem.py b/Cython/Unix/LinuxSystem.py
new file mode 100644 (file)
index 0000000..e9722ff
--- /dev/null
@@ -0,0 +1,74 @@
+#
+#   Pyrex - Linux system interface
+#
+
+verbose = 0
+gcc_pendantic = True
+gcc_warnings_are_errors = True
+gcc_all_warnings = True
+
+import os
+from Pyrex.Utils import replace_suffix
+from Pyrex.Compiler.Errors import PyrexError
+
+version = "%s.%s" % sys.version[:2]
+py_include_dirs = [
+    "%s/include/python%s" % (sys.prefix, version)
+]
+
+compilers = ["gcc", "g++"]
+compiler_options = \
+    "-g -c -fno-strict-aliasing -Wno-long-double -no-cpp-precomp " \
+    "-mno-fused-madd -fno-common -dynamic " \
+    .split()
+if gcc_pendantic:
+    compiler_options.extend(["-pedantic", "-Wno-long-long"])
+if gcc_warnings_are_errors:
+    compiler_options.append("-Werror")
+if gcc_all_warnings:
+    compiler_options.append("-Wall")
+    compiler_options.append("-Wno-unused-function")
+
+linkers = ["gcc", "g++"]
+linker_options = \
+    "-shared" \
+    .split()
+
+class CCompilerError(PyrexError):
+    pass
+
+def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
+    #  Compile the given C source file to produce
+    #  an object file. Returns the pathname of the
+    #  resulting file.
+    c_file = os.path.join(os.getcwd(), c_file)
+    o_file = replace_suffix(c_file, obj_suffix)
+    include_options = []
+    for dir in py_include_dirs:
+        include_options.append("-I%s" % dir)
+    compiler = compilers[bool(cplus)]
+    args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
+    if verbose_flag or verbose:
+        print " ".join(args)
+    #print compiler, args ###
+    status = os.spawnvp(os.P_WAIT, compiler, args)
+    if status <> 0:
+        raise CCompilerError("C compiler returned status %s" % status)
+    return o_file
+
+def c_link(obj_file, verbose_flag = 0, extra_objects = [], cplus = 0):
+    return c_link_list([obj_file] + extra_objects, verbose_flag, cplus)
+
+def c_link_list(obj_files, verbose_flag = 0, cplus = 0):
+    #  Link the given object files into a dynamically
+    #  loadable extension file. Returns the pathname
+    #  of the resulting file.
+    out_file = replace_suffix(obj_files[0], ".so")
+    linker = linkers[bool(cplus)]
+    args = [linker] + linker_options + obj_files + ["-o", out_file]
+    if verbose_flag or verbose:
+        print " ".join(args)
+    status = os.spawnvp(os.P_WAIT, linker, args)
+    if status <> 0:
+        raise CCompilerError("Linker returned status %s" % status)
+    return out_file