Commit 5aab5520 authored by Robert Bradshaw's avatar Robert Bradshaw

Pyrex Official version 0.9.5.1a

parent 54ab11e7
...@@ -22,8 +22,9 @@ class CCodeWriter: ...@@ -22,8 +22,9 @@ class CCodeWriter:
in_try_finally = 0 in_try_finally = 0
def __init__(self, outfile_name): def __init__(self, f):
self.f = open_new_file(outfile_name) #self.f = open_new_file(outfile_name)
self.f = f
self.level = 0 self.level = 0
self.bol = 1 self.bol = 1
self.marker = None self.marker = None
...@@ -80,6 +81,7 @@ class CCodeWriter: ...@@ -80,6 +81,7 @@ class CCodeWriter:
def init_labels(self): def init_labels(self):
self.label_counter = 0 self.label_counter = 0
self.labels_used = {}
self.return_label = self.new_label() self.return_label = self.new_label()
self.new_error_label() self.new_error_label()
self.continue_label = None self.continue_label = None
...@@ -134,9 +136,17 @@ class CCodeWriter: ...@@ -134,9 +136,17 @@ class CCodeWriter:
new_labels.append(old_label) new_labels.append(old_label)
self.set_all_labels(new_labels) self.set_all_labels(new_labels)
return old_labels return old_labels
def use_label(self, lbl):
self.labels_used[lbl] = 1
def put_label(self, lbl): 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, def put_var_declarations(self, entries, static = 0, dll_linkage = None,
definition = True): definition = True):
...@@ -146,28 +156,23 @@ class CCodeWriter: ...@@ -146,28 +156,23 @@ class CCodeWriter:
def put_var_declaration(self, entry, static = 0, dll_linkage = None, def put_var_declaration(self, entry, static = 0, dll_linkage = None,
definition = True): definition = True):
#print "Code.put_var_declaration:", entry.name, "definition =", definition #print "Code.put_var_declaration:", entry.name, "definition =", definition ###
visibility = entry.visibility visibility = entry.visibility
if visibility == 'private' and not definition: if visibility == 'private' and not definition:
return return
if not entry.used and visibility == "private":
return
storage_class = ""
if visibility == 'extern': if visibility == 'extern':
storage_class = Naming.extern_c_macro storage_class = Naming.extern_c_macro
elif visibility == 'public': elif visibility == 'public':
if definition: if not definition:
storage_class = ""
else:
storage_class = Naming.extern_c_macro storage_class = Naming.extern_c_macro
elif visibility == 'private': elif visibility == 'private':
if static: if static:
storage_class = "static" storage_class = "static"
else:
storage_class = ""
if storage_class: if storage_class:
self.put("%s " % 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': if visibility <> 'public':
dll_linkage = None dll_linkage = None
self.put(entry.type.declaration_code(entry.cname, self.put(entry.type.declaration_code(entry.cname,
...@@ -186,10 +191,6 @@ class CCodeWriter: ...@@ -186,10 +191,6 @@ class CCodeWriter:
def as_pyobject(self, cname, type): def as_pyobject(self, cname, type):
return typecast(py_object_type, type, cname) 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): def put_incref(self, cname, type):
self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type)) self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
...@@ -231,12 +232,13 @@ class CCodeWriter: ...@@ -231,12 +232,13 @@ class CCodeWriter:
self.putln("Py_XDECREF(%s); %s = 0;" % ( self.putln("Py_XDECREF(%s); %s = 0;" % (
self.entry_as_pyobject(entry), entry.cname)) 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: for entry in entries:
if entry.xdecref_cleanup: if not used_only or entry.used:
self.put_var_xdecref(entry) if entry.xdecref_cleanup:
else: self.put_var_xdecref(entry)
self.put_var_decref(entry) else:
self.put_var_decref(entry)
def put_var_xdecrefs(self, entries): def put_var_xdecrefs(self, entries):
for entry in entries: for entry in entries:
...@@ -269,13 +271,15 @@ class CCodeWriter: ...@@ -269,13 +271,15 @@ class CCodeWriter:
term)) term))
def error_goto(self, pos): def error_goto(self, pos):
lbl = self.error_label
self.use_label(lbl)
return "{%s = %s[%s]; %s = %s; goto %s;}" % ( return "{%s = %s[%s]; %s = %s; goto %s;}" % (
Naming.filename_cname, Naming.filename_cname,
Naming.filetable_cname, Naming.filetable_cname,
self.lookup_filename(pos[0]), self.lookup_filename(pos[0]),
Naming.lineno_cname, Naming.lineno_cname,
pos[1], pos[1],
self.error_label) lbl)
def lookup_filename(self, filename): def lookup_filename(self, filename):
try: try:
......
...@@ -8,7 +8,7 @@ from Errors import error, InternalError ...@@ -8,7 +8,7 @@ from Errors import error, InternalError
import Naming import Naming
from Nodes import Node from Nodes import Node
import PyrexTypes import PyrexTypes
from PyrexTypes import py_object_type, typecast from PyrexTypes import py_object_type, c_long_type, typecast
import Symtab import Symtab
import Options import Options
...@@ -89,13 +89,23 @@ class ExprNode(Node): ...@@ -89,13 +89,23 @@ class ExprNode(Node):
# - If a temporary was allocated, call release_temp on # - If a temporary was allocated, call release_temp on
# all sub-expressions. # all sub-expressions.
# #
# A default implementation of allocate_temps is # allocate_target_temps
# provided which uses the following abstract method: # - 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 # calculate_result_code
# - Return a C code fragment evaluating to # - Return a C code fragment evaluating to
# the result. This is only called when the # the result. This is only called when the
# result is not a temporary. # 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_const
# - Check that this node and its subnodes form a # - Check that this node and its subnodes form a
...@@ -145,16 +155,6 @@ class ExprNode(Node): ...@@ -145,16 +155,6 @@ class ExprNode(Node):
# - Generate code to perform the deletion. # - Generate code to perform the deletion.
# - Call generate_disposal_code on all sub-expressions. # - 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 is_sequence_constructor = 0
...@@ -231,12 +231,12 @@ class ExprNode(Node): ...@@ -231,12 +231,12 @@ class ExprNode(Node):
self.analyse_types(env) self.analyse_types(env)
self.allocate_temps(env) self.allocate_temps(env)
def analyse_target_expression(self, env): def analyse_target_expression(self, env, rhs):
# Convenience routine performing both the Type # Convenience routine performing both the Type
# Analysis and Temp Allocation phases for the LHS of # Analysis and Temp Allocation phases for the LHS of
# an assignment. # an assignment.
self.analyse_target_types(env) self.analyse_target_types(env)
self.allocate_target_temps(env) self.allocate_target_temps(env, rhs)
def analyse_boolean_expression(self, env): def analyse_boolean_expression(self, env):
# Analyse expression and coerce to a boolean. # Analyse expression and coerce to a boolean.
...@@ -298,12 +298,15 @@ class ExprNode(Node): ...@@ -298,12 +298,15 @@ class ExprNode(Node):
# a subnode. # a subnode.
return self.is_temp return self.is_temp
def allocate_target_temps(self, env): def allocate_target_temps(self, env, rhs):
# Perform allocate_temps for the LHS of an assignment. # Perform temp allocation for the LHS of an assignment.
if debug_temp_alloc: if debug_temp_alloc:
print self, "Allocating target temps" print self, "Allocating target temps"
self.allocate_subexpr_temps(env) self.allocate_subexpr_temps(env)
self.result_code = self.target_code() self.result_code = self.target_code()
if rhs:
rhs.release_temp(env)
self.release_subexpr_temps(env)
def allocate_temps(self, env, result = None): def allocate_temps(self, env, result = None):
# Allocate temporary variables for this node and # Allocate temporary variables for this node and
...@@ -362,9 +365,9 @@ class ExprNode(Node): ...@@ -362,9 +365,9 @@ class ExprNode(Node):
def calculate_result_code(self): def calculate_result_code(self):
self.not_implemented("calculate_result_code") self.not_implemented("calculate_result_code")
def release_target_temp(self, env): # def release_target_temp(self, env):
# Release temporaries used by LHS of an assignment. # # Release temporaries used by LHS of an assignment.
self.release_subexpr_temps(env) # self.release_subexpr_temps(env)
def release_temp(self, env): def release_temp(self, env):
# If this node owns a temporary result, release it, # If this node owns a temporary result, release it,
...@@ -463,7 +466,8 @@ class ExprNode(Node): ...@@ -463,7 +466,8 @@ class ExprNode(Node):
if not src.type.is_pyobject: if not src.type.is_pyobject:
src = CoerceToPyTypeNode(src, env) src = CoerceToPyTypeNode(src, env)
if not src.type.subtype_of(dst_type): 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: elif src.type.is_pyobject:
src = CoerceFromPyTypeNode(dst_type, src, env) src = CoerceFromPyTypeNode(dst_type, src, env)
else: # neither src nor dst are py types else: # neither src nor dst are py types
...@@ -576,7 +580,7 @@ class ConstNode(AtomicExprNode): ...@@ -576,7 +580,7 @@ class ConstNode(AtomicExprNode):
class NullNode(ConstNode): class NullNode(ConstNode):
type = PyrexTypes.c_null_ptr_type type = PyrexTypes.c_null_ptr_type
value = "0" value = "NULL"
class CharNode(ConstNode): class CharNode(ConstNode):
...@@ -703,13 +707,14 @@ class NameNode(AtomicExprNode): ...@@ -703,13 +707,14 @@ class NameNode(AtomicExprNode):
def analyse_entry(self, env): def analyse_entry(self, env):
self.check_identifier_kind() self.check_identifier_kind()
self.type = self.entry.type entry = self.entry
if self.entry.is_declared_generic: self.type = entry.type
if entry.is_declared_generic:
self.result_ctype = py_object_type self.result_ctype = py_object_type
# Reference to C array turns into pointer to first element. ## Reference to C array turns into pointer to first element.
while self.type.is_array: #while self.type.is_array:
self.type = self.type.element_ptr_type() # self.type = self.type.element_ptr_type()
if self.entry.is_pyglobal or self.entry.is_builtin: if entry.is_pyglobal or entry.is_builtin:
assert self.type.is_pyobject, "Python global or builtin not a Python object" assert self.type.is_pyobject, "Python global or builtin not a Python object"
self.is_temp = 1 self.is_temp = 1
if Options.intern_names: if Options.intern_names:
...@@ -727,7 +732,9 @@ class NameNode(AtomicExprNode): ...@@ -727,7 +732,9 @@ class NameNode(AtomicExprNode):
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
def check_identifier_kind(self): def check_identifier_kind(self):
#print "NameNode.check_identifier_kind:", self.entry.name ###
entry = self.entry entry = self.entry
entry.used = 1
if not (entry.is_const or entry.is_variable if not (entry.is_const or entry.is_variable
or entry.is_builtin or entry.is_cfunction): or entry.is_builtin or entry.is_cfunction):
if self.entry.as_variable: if self.entry.as_variable:
...@@ -1071,11 +1078,11 @@ class IndexNode(ExprNode): ...@@ -1071,11 +1078,11 @@ class IndexNode(ExprNode):
self.index.py_result(), self.index.py_result(),
rhs.py_result(), rhs.py_result(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
self.generate_subexpr_disposal_code(code)
else: else:
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
self.result_code, rhs.result_code)) self.result_code, rhs.result_code))
self.generate_subexpr_disposal_code(code)
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
...@@ -1220,9 +1227,12 @@ class SimpleCallNode(ExprNode): ...@@ -1220,9 +1227,12 @@ class SimpleCallNode(ExprNode):
function.obj = CloneNode(self.self) function.obj = CloneNode(self.self)
func_type = self.function_type() func_type = self.function_type()
if func_type.is_pyobject: 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.args = None
self.arg_tuple.analyse_types(env)
self.type = py_object_type self.type = py_object_type
self.is_temp = 1 self.is_temp = 1
else: else:
...@@ -1309,11 +1319,15 @@ class SimpleCallNode(ExprNode): ...@@ -1309,11 +1319,15 @@ class SimpleCallNode(ExprNode):
def generate_result_code(self, code): def generate_result_code(self, code):
func_type = self.function_type() func_type = self.function_type()
if func_type.is_pyobject: if func_type.is_pyobject:
if self.arg_tuple:
arg_code = self.arg_tuple.py_result()
else:
arg_code = "0"
code.putln( code.putln(
"%s = PyObject_CallObject(%s, %s); if (!%s) %s" % ( "%s = PyObject_CallObject(%s, %s); if (!%s) %s" % (
self.result_code, self.result_code,
self.function.py_result(), self.function.py_result(),
self.arg_tuple.py_result(), arg_code,
self.result_code, self.result_code,
code.error_goto(self.pos))) code.error_goto(self.pos)))
elif func_type.is_cfunction: elif func_type.is_cfunction:
...@@ -1535,9 +1549,9 @@ class AttributeNode(ExprNode): ...@@ -1535,9 +1549,9 @@ class AttributeNode(ExprNode):
self.analyse_attribute(env) self.analyse_attribute(env)
if self.entry and self.entry.is_cmethod and not self.is_called: if self.entry and self.entry.is_cmethod and not self.is_called:
error(self.pos, "C method can only be called") error(self.pos, "C method can only be called")
# Reference to C array turns into pointer to first element. ## Reference to C array turns into pointer to first element.
while self.type.is_array: #while self.type.is_array:
self.type = self.type.element_ptr_type() # self.type = self.type.element_ptr_type()
if self.is_py_attr: if self.is_py_attr:
if not target: if not target:
self.is_temp = 1 self.is_temp = 1
...@@ -1568,6 +1582,8 @@ class AttributeNode(ExprNode): ...@@ -1568,6 +1582,8 @@ class AttributeNode(ExprNode):
obj_type = PyrexTypes.error_type obj_type = PyrexTypes.error_type
self.entry = entry self.entry = entry
if 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: if entry.is_variable or entry.is_cmethod:
self.type = entry.type self.type = entry.type
self.member = entry.cname self.member = entry.cname
...@@ -1662,7 +1678,6 @@ class AttributeNode(ExprNode): ...@@ -1662,7 +1678,6 @@ class AttributeNode(ExprNode):
code.error_goto(self.pos))) code.error_goto(self.pos)))
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
else: else:
#select_code = self.select_code()
select_code = self.result_code select_code = self.result_code
if self.type.is_pyobject: if self.type.is_pyobject:
rhs.make_owned_reference(code) rhs.make_owned_reference(code)
...@@ -1670,7 +1685,8 @@ class AttributeNode(ExprNode): ...@@ -1670,7 +1685,8 @@ class AttributeNode(ExprNode):
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
select_code, select_code,
rhs.result_code)) rhs.result_as(self.ctype())))
#rhs.result_code))
rhs.generate_post_assignment_code(code) rhs.generate_post_assignment_code(code)
self.obj.generate_disposal_code(code) self.obj.generate_disposal_code(code)
...@@ -1704,6 +1720,7 @@ class SequenceNode(ExprNode): ...@@ -1704,6 +1720,7 @@ class SequenceNode(ExprNode):
# Contains common code for performing sequence unpacking. # Contains common code for performing sequence unpacking.
# #
# args [ExprNode] # args [ExprNode]
# iterator ExprNode
# unpacked_items [ExprNode] or None # unpacked_items [ExprNode] or None
# coerced_unpacked_items [ExprNode] or None # coerced_unpacked_items [ExprNode] or None
...@@ -1725,11 +1742,11 @@ class SequenceNode(ExprNode): ...@@ -1725,11 +1742,11 @@ class SequenceNode(ExprNode):
self.is_temp = 1 self.is_temp = 1
def analyse_target_types(self, env): 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 = [] self.coerced_unpacked_items = []
for arg in self.args: for arg in self.args:
arg.analyse_target_types(env) arg.analyse_target_types(env)
#node = CloneNode(self.unpacked_item)
unpacked_item = PyTempNode(self.pos, env) unpacked_item = PyTempNode(self.pos, env)
coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env) coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
self.unpacked_items.append(unpacked_item) self.unpacked_items.append(unpacked_item)
...@@ -1737,27 +1754,39 @@ class SequenceNode(ExprNode): ...@@ -1737,27 +1754,39 @@ class SequenceNode(ExprNode):
self.type = py_object_type self.type = py_object_type
env.use_utility_code(unpacking_utility_code) env.use_utility_code(unpacking_utility_code)
def allocate_target_temps(self, env): def allocate_target_temps(self, env, rhs):
for arg in self.args: self.iterator.allocate_temps(env)
arg.allocate_target_temps(env) if rhs:
for node in self.coerced_unpacked_items: rhs.release_temp(env)
for arg, node in zip(self.args, self.coerced_unpacked_items):
node.allocate_temps(env) node.allocate_temps(env)
arg.allocate_target_temps(env, node)
def release_target_temp(self, env): #arg.release_target_temp(env)
for arg in self.args: #node.release_temp(env)
arg.release_target_temp(env) self.iterator.release_temp(env)
for node in self.coerced_unpacked_items:
node.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): def generate_result_code(self, code):
self.generate_operation_code(code) self.generate_operation_code(code)
def generate_assignment_code(self, rhs, 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)): for i in range(len(self.args)):
item = self.unpacked_items[i] item = self.unpacked_items[i]
unpack_code = "__Pyx_UnpackItem(%s, %s)" % ( unpack_code = "__Pyx_UnpackItem(%s)" % (
rhs.py_result(), self.iterator.py_result())
i)
code.putln( code.putln(
"%s = %s; if (!%s) %s" % ( "%s = %s; if (!%s) %s" % (
item.result_code, item.result_code,
...@@ -1768,14 +1797,13 @@ class SequenceNode(ExprNode): ...@@ -1768,14 +1797,13 @@ class SequenceNode(ExprNode):
value_node.generate_evaluation_code(code) value_node.generate_evaluation_code(code)
self.args[i].generate_assignment_code(value_node, code) self.args[i].generate_assignment_code(value_node, code)
code.putln( code.putln(
"if (__Pyx_EndUnpack(%s, %s) < 0) %s" % ( "if (__Pyx_EndUnpack(%s) < 0) %s" % (
rhs.py_result(), self.iterator.py_result(),
len(self.args),
code.error_goto(self.pos))) code.error_goto(self.pos)))
if debug_disposal_code: if debug_disposal_code:
print "UnpackNode.generate_assignment_code:" print "UnpackNode.generate_assignment_code:"
print "...generating disposal code for", rhs print "...generating disposal code for", rhs
rhs.generate_disposal_code(code) self.iterator.generate_disposal_code(code)
class TupleNode(SequenceNode): class TupleNode(SequenceNode):
...@@ -2560,10 +2588,13 @@ class CmpNode: ...@@ -2560,10 +2588,13 @@ class CmpNode:
return 1 return 1
if type1.is_pyobject: # type2 will be, too if type1.is_pyobject: # type2 will be, too
return 1 return 1
elif type1.is_ptr: elif type1.is_ptr or type1.is_array:
return type1.is_null_ptr or type2.is_null_ptr \ return type1.is_null_ptr or type2.is_null_ptr \
or type1.same_as(type2) or ((type2.is_ptr or type2.is_array)
elif (type1.is_numeric and type2.is_numeric 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')): and op not in ('is', 'is_not')):
return 1 return 1
else: else:
...@@ -2819,9 +2850,6 @@ class CastNode(CoercionNode): ...@@ -2819,9 +2850,6 @@ class CastNode(CoercionNode):
self.type = new_type self.type = new_type
def calculate_result_code(self): def calculate_result_code(self):
#return "((%s)%s)" % (
# self.type.declaration_code(""),
# self.arg.result)
return self.arg.result_as(self.type) return self.arg.result_as(self.type)
def generate_result_code(self, code): def generate_result_code(self, code):
...@@ -2904,12 +2932,14 @@ class CoerceFromPyTypeNode(CoercionNode): ...@@ -2904,12 +2932,14 @@ class CoerceFromPyTypeNode(CoercionNode):
"Obtaining char * from temporary Python value") "Obtaining char * from temporary Python value")
def generate_result_code(self, code): def generate_result_code(self, code):
#opnd = self.arg.py_result()
function = self.type.from_py_function 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, self.result_code,
function, rhs,
self.arg.py_result(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
...@@ -2995,8 +3025,10 @@ class CloneNode(CoercionNode): ...@@ -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) { static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
PyObject *result; PyObject *result;
result = PyObject_GetAttrString(dict, name); result = PyObject_GetAttrString(dict, name);
...@@ -3004,10 +3036,12 @@ static PyObject *__Pyx_GetName(PyObject *dict, char *name) { ...@@ -3004,10 +3036,12 @@ static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
PyErr_SetString(PyExc_NameError, name); PyErr_SetString(PyExc_NameError, name);
return result; 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) { static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyObject *result; PyObject *result;
result = PyObject_GetAttr(dict, name); result = PyObject_GetAttr(dict, name);
...@@ -3015,12 +3049,14 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) { ...@@ -3015,12 +3049,14 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyErr_SetObject(PyExc_NameError, name); PyErr_SetObject(PyExc_NameError, name);
return result; 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) { static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
PyObject *__import__ = 0; PyObject *__import__ = 0;
PyObject *empty_list = 0; PyObject *empty_list = 0;
...@@ -3056,12 +3092,14 @@ bad: ...@@ -3056,12 +3092,14 @@ bad:
""" % { """ % {
"BUILTINS": Naming.builtins_cname, "BUILTINS": Naming.builtins_cname,
"GLOBALS": Naming.module_cname, "GLOBALS": Naming.module_cname,
} }]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
get_exception_utility_code = \ get_exception_utility_code = [
""" """
static PyObject *__Pyx_GetExcValue(void); /*proto*/
""","""
static PyObject *__Pyx_GetExcValue(void) { static PyObject *__Pyx_GetExcValue(void) {
PyObject *type = 0, *value = 0, *tb = 0; PyObject *type = 0, *value = 0, *tb = 0;
PyObject *result = 0; PyObject *result = 0;
...@@ -3091,41 +3129,48 @@ bad: ...@@ -3091,41 +3129,48 @@ bad:
Py_XDECREF(tb); Py_XDECREF(tb);
return result; 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) { static void __Pyx_UnpackError(void) {
PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size"); PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size");
} }
static PyObject *__Pyx_UnpackItem(PyObject *seq, int i) { static PyObject *__Pyx_UnpackItem(PyObject *iter) {
PyObject *item; PyObject *item;
if (!(item = PySequence_GetItem(seq, i))) { if (!(item = PyIter_Next(iter))) {
if (PyErr_ExceptionMatches(PyExc_IndexError)) if (!PyErr_Occurred())
__Pyx_UnpackError(); __Pyx_UnpackError();
} }
return item; return item;
} }
static int __Pyx_EndUnpack(PyObject *seq, int i) { static int __Pyx_EndUnpack(PyObject *iter) {
PyObject *item; PyObject *item;
if (item = PySequence_GetItem(seq, i)) { if ((item = PyIter_Next(iter))) {
Py_DECREF(item); Py_DECREF(item);
__Pyx_UnpackError(); __Pyx_UnpackError();
return -1; return -1;
} }
PyErr_Clear(); else if (!PyErr_Occurred())
return 0; 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) { static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
if (!type) { if (!type) {
PyErr_Format(PyExc_SystemError, "Missing type object"); PyErr_Format(PyExc_SystemError, "Missing type object");
...@@ -3137,12 +3182,14 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) { ...@@ -3137,12 +3182,14 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
obj->ob_type->tp_name, type->tp_name); obj->ob_type->tp_name, type->tp_name);
return 0; 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( static PyObject *__Pyx_CreateClass(
PyObject *bases, PyObject *dict, PyObject *name, char *modname) PyObject *bases, PyObject *dict, PyObject *name, char *modname)
{ {
...@@ -3159,6 +3206,6 @@ bad: ...@@ -3159,6 +3206,6 @@ bad:
Py_XDECREF(py_modname); Py_XDECREF(py_modname);
return result; return result;
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
#
# 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])
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Pyrex - Parse tree nodes # Pyrex - Parse tree nodes
# #
import os, string, sys, time import string, sys
import Code import Code
from Errors import error, InternalError from Errors import error, InternalError
...@@ -11,8 +11,6 @@ import PyrexTypes ...@@ -11,8 +11,6 @@ import PyrexTypes
from PyrexTypes import py_object_type, error_type, CTypedefType from PyrexTypes import py_object_type, error_type, CTypedefType
from Symtab import ModuleScope, LocalScope, \ from Symtab import ModuleScope, LocalScope, \
StructOrUnionScope, PyClassScope, CClassScope StructOrUnionScope, PyClassScope, CClassScope
import TypeSlots
import Version
from Pyrex.Utils import open_new_file, replace_suffix from Pyrex.Utils import open_new_file, replace_suffix
import Options import Options
...@@ -95,1214 +93,6 @@ class BlockNode: ...@@ -95,1214 +93,6 @@ class BlockNode:
for entry in entries: for entry in entries:
code.putln( code.putln(
"static PyObject *%s;" % entry.pystring_cname) "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): class StatListNode(Node):
...@@ -1697,8 +487,6 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1697,8 +487,6 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Top-level constants used by this function # ----- Top-level constants used by this function
self.generate_interned_name_decls(lenv, code) self.generate_interned_name_decls(lenv, code)
self.generate_py_string_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) self.generate_const_definitions(lenv, code)
# ----- Function header # ----- Function header
code.putln("") code.putln("")
...@@ -1721,13 +509,12 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1721,13 +509,12 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Fetch arguments # ----- Fetch arguments
self.generate_argument_parsing_code(code) self.generate_argument_parsing_code(code)
self.generate_argument_increfs(lenv, code) self.generate_argument_increfs(lenv, code)
#self.generate_stararg_getting_code(code)
self.generate_argument_conversion_code(code)
# ----- Initialise local variables # ----- Initialise local variables
for entry in lenv.var_entries: 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) 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) self.generate_argument_type_tests(code)
# ----- Function body # ----- Function body
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
...@@ -1743,29 +530,31 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1743,29 +530,31 @@ class FuncDefNode(StatNode, BlockNode):
val = self.return_type.default_value val = self.return_type.default_value
if val: if val:
code.putln("%s = %s;" % (Naming.retval_cname, 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 # ----- Error cleanup
code.put_label(code.error_label) if code.error_label in code.labels_used:
code.put_var_xdecrefs(lenv.temp_entries) code.put_goto(code.return_label)
err_val = self.error_value() code.put_label(code.error_label)
exc_check = self.caller_will_check_exceptions() code.put_var_xdecrefs(lenv.temp_entries)
if err_val is not None or exc_check: err_val = self.error_value()
code.putln( exc_check = self.caller_will_check_exceptions()
'__Pyx_AddTraceback("%s");' % if err_val is not None or exc_check:
self.entry.qualified_name)
if err_val is not None:
code.putln( code.putln(
"%s = %s;" % ( '__Pyx_AddTraceback("%s");' %
Naming.retval_cname, self.entry.qualified_name)
err_val)) if err_val is not None:
else: code.putln(
code.putln( "%s = %s;" % (
'__Pyx_WriteUnraisable("%s");' % Naming.retval_cname,
self.entry.qualified_name) err_val))
env.use_utility_code(unraisable_exception_utility_code) else:
code.putln(
'__Pyx_WriteUnraisable("%s");' %
self.entry.qualified_name)
env.use_utility_code(unraisable_exception_utility_code)
# ----- Return cleanup # ----- Return cleanup
code.put_label(code.return_label) 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) code.put_var_decrefs(lenv.arg_entries)
self.put_stararg_decrefs(code) self.put_stararg_decrefs(code)
if not self.return_type.is_void: if not self.return_type.is_void:
...@@ -1872,9 +661,6 @@ class CFuncDefNode(FuncDefNode): ...@@ -1872,9 +661,6 @@ class CFuncDefNode(FuncDefNode):
def generate_argument_parsing_code(self, code): def generate_argument_parsing_code(self, code):
pass pass
# def generate_stararg_getting_code(self, code):
# pass
def generate_argument_conversion_code(self, code): def generate_argument_conversion_code(self, code):
pass pass
...@@ -2015,6 +801,7 @@ class DefNode(FuncDefNode): ...@@ -2015,6 +801,7 @@ class DefNode(FuncDefNode):
arg.entry.init_to_none = 0 arg.entry.init_to_none = 0
else: else:
arg.entry = self.declare_argument(env, arg) arg.entry = self.declare_argument(env, arg)
arg.entry.used = 1
arg.entry.is_self_arg = arg.is_self_arg arg.entry.is_self_arg = arg.is_self_arg
if arg.hdr_type: if arg.hdr_type:
if arg.is_self_arg or \ if arg.is_self_arg or \
...@@ -2025,11 +812,13 @@ class DefNode(FuncDefNode): ...@@ -2025,11 +812,13 @@ class DefNode(FuncDefNode):
def declare_python_arg(self, env, arg): def declare_python_arg(self, env, arg):
if arg: if arg:
arg.entry = env.declare_var(arg.name, entry = env.declare_var(arg.name,
PyrexTypes.py_object_type, arg.pos) PyrexTypes.py_object_type, arg.pos)
arg.entry.init = "0" entry.used = 1
arg.entry.init_to_none = 0 entry.init = "0"
arg.entry.xdecref_cleanup = 1 entry.init_to_none = 0
entry.xdecref_cleanup = 1
arg.entry = entry
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.analyse_default_values(env) self.analyse_default_values(env)
...@@ -2044,6 +833,7 @@ class DefNode(FuncDefNode): ...@@ -2044,6 +833,7 @@ class DefNode(FuncDefNode):
arg.default = arg.default.coerce_to(arg.type, env) arg.default = arg.default.coerce_to(arg.type, env)
arg.default.allocate_temps(env) arg.default.allocate_temps(env)
arg.default_entry = env.add_default_value(arg.type) arg.default_entry = env.add_default_value(arg.type)
arg.default_entry.used = 1
else: else:
error(arg.pos, error(arg.pos,
"This argument cannot have a default value") "This argument cannot have a default value")
...@@ -2339,11 +1129,10 @@ class PyClassDefNode(StatNode, BlockNode): ...@@ -2339,11 +1129,10 @@ class PyClassDefNode(StatNode, BlockNode):
self.scope = cenv self.scope = cenv
self.body.analyse_declarations(cenv) self.body.analyse_declarations(cenv)
self.body.analyse_expressions(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.dict.release_temp(env)
self.classobj.release_temp(env) #self.classobj.release_temp(env)
self.target.release_target_temp(env) #self.target.release_target_temp(env)
#env.recycle_pending_temps()
def generate_function_definitions(self, env, code): def generate_function_definitions(self, env, code):
self.generate_py_string_decls(self.scope, code) self.generate_py_string_decls(self.scope, code)
...@@ -2488,7 +1277,6 @@ class ExprStatNode(StatNode): ...@@ -2488,7 +1277,6 @@ class ExprStatNode(StatNode):
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.expr.analyse_expressions(env) self.expr.analyse_expressions(env)
self.expr.release_temp(env) self.expr.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code): def generate_execution_code(self, code):
self.expr.generate_evaluation_code(code) self.expr.generate_evaluation_code(code)
...@@ -2507,8 +1295,13 @@ class AssignmentNode(StatNode): ...@@ -2507,8 +1295,13 @@ class AssignmentNode(StatNode):
# to any of the left hand sides. # to any of the left hand sides.
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.analyse_expressions_1(env) self.analyse_types(env)
self.analyse_expressions_2(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): def generate_execution_code(self, code):
self.generate_rhs_evaluation_code(code) self.generate_rhs_evaluation_code(code)
...@@ -2526,18 +1319,33 @@ class SingleAssignmentNode(AssignmentNode): ...@@ -2526,18 +1319,33 @@ class SingleAssignmentNode(AssignmentNode):
def analyse_declarations(self, env): def analyse_declarations(self, env):
self.lhs.analyse_target_declaration(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.rhs.analyse_types(env)
self.lhs.analyse_target_types(env) self.lhs.analyse_target_types(env)
self.rhs = self.rhs.coerce_to(self.lhs.type, env) self.rhs = self.rhs.coerce_to(self.lhs.type, env)
if use_temp: if use_temp:
self.rhs = self.rhs.coerce_to_temp(env) self.rhs = self.rhs.coerce_to_temp(env)
def allocate_rhs_temps(self, env):
self.rhs.allocate_temps(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): # def analyse_expressions_1(self, env, use_temp = 0):
self.lhs.allocate_target_temps(env) # self.rhs.analyse_types(env)
self.lhs.release_target_temp(env) # self.lhs.analyse_target_types(env)
self.rhs.release_temp(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): def generate_rhs_evaluation_code(self, code):
self.rhs.generate_evaluation_code(code) self.rhs.generate_evaluation_code(code)
...@@ -2562,31 +1370,12 @@ class CascadedAssignmentNode(AssignmentNode): ...@@ -2562,31 +1370,12 @@ class CascadedAssignmentNode(AssignmentNode):
for lhs in self.lhs_list: for lhs in self.lhs_list:
lhs.analyse_target_declaration(env) lhs.analyse_target_declaration(env)
# def analyse_expressions(self, env): def analyse_types(self, env, use_temp = 0):
# 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):
self.rhs.analyse_types(env) self.rhs.analyse_types(env)
if use_temp: if use_temp:
self.rhs = self.rhs.coerce_to_temp(env) self.rhs = self.rhs.coerce_to_temp(env)
else: else:
self.rhs = self.rhs.coerce_to_simple(env) self.rhs = self.rhs.coerce_to_simple(env)
self.rhs.allocate_temps(env)
def analyse_expressions_2(self, env):
from ExprNodes import CloneNode from ExprNodes import CloneNode
self.coerced_rhs_list = [] self.coerced_rhs_list = []
for lhs in self.lhs_list: for lhs in self.lhs_list:
...@@ -2594,21 +1383,39 @@ class CascadedAssignmentNode(AssignmentNode): ...@@ -2594,21 +1383,39 @@ class CascadedAssignmentNode(AssignmentNode):
rhs = CloneNode(self.rhs) rhs = CloneNode(self.rhs)
rhs = rhs.coerce_to(lhs.type, env) rhs = rhs.coerce_to(lhs.type, env)
self.coerced_rhs_list.append(rhs) 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) rhs.allocate_temps(env)
lhs.allocate_target_temps(env) lhs.allocate_target_temps(env, rhs)
lhs.release_target_temp(env) #lhs.release_target_temp(env)
rhs.release_temp(env) #rhs.release_temp(env)
self.rhs.release_temp(env) self.rhs.release_temp(env)
# def generate_execution_code(self, code): # def analyse_expressions_1(self, env, use_temp = 0):
# self.rhs.generate_evaluation_code(code) # self.rhs.analyse_types(env)
# for i in range(len(self.lhs_list)): # if use_temp:
# lhs = self.lhs_list[i] # self.rhs = self.rhs.coerce_to_temp(env)
# rhs = self.coerced_rhs_list[i] # else:
# rhs.generate_evaluation_code(code) # self.rhs = self.rhs.coerce_to_simple(env)
# lhs.generate_assignment_code(rhs, code) # self.rhs.allocate_temps(env)
# # Assignment has already disposed of the cloned RHS #
# self.rhs.generate_disposal_code(code) # 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): def generate_rhs_evaluation_code(self, code):
self.rhs.generate_evaluation_code(code) self.rhs.generate_evaluation_code(code)
...@@ -2642,9 +1449,16 @@ class ParallelAssignmentNode(AssignmentNode): ...@@ -2642,9 +1449,16 @@ class ParallelAssignmentNode(AssignmentNode):
def analyse_expressions(self, env): def analyse_expressions(self, env):
for stat in self.stats: 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: 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): def generate_execution_code(self, code):
for stat in self.stats: for stat in self.stats:
...@@ -2695,10 +1509,10 @@ class DelStatNode(StatNode): ...@@ -2695,10 +1509,10 @@ class DelStatNode(StatNode):
def analyse_expressions(self, env): def analyse_expressions(self, env):
for arg in self.args: for arg in self.args:
arg.analyse_target_expression(env) arg.analyse_target_expression(env, None)
if not arg.type.is_pyobject: if not arg.type.is_pyobject:
error(arg.pos, "Deletion of non-Python object") error(arg.pos, "Deletion of non-Python object")
#env.recycle_pending_temps() # TEMPORARY #arg.release_target_temp(env)
def generate_execution_code(self, code): def generate_execution_code(self, code):
for arg in self.args: for arg in self.args:
...@@ -2726,9 +1540,10 @@ class BreakStatNode(StatNode): ...@@ -2726,9 +1540,10 @@ class BreakStatNode(StatNode):
if not code.break_label: if not code.break_label:
error(self.pos, "break statement not inside loop") error(self.pos, "break statement not inside loop")
else: else:
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
code.break_label) # code.break_label)
code.put_goto(code.break_label)
class ContinueStatNode(StatNode): class ContinueStatNode(StatNode):
...@@ -2742,9 +1557,10 @@ class ContinueStatNode(StatNode): ...@@ -2742,9 +1557,10 @@ class ContinueStatNode(StatNode):
elif not code.continue_label: elif not code.continue_label:
error(self.pos, "continue statement not inside loop") error(self.pos, "continue statement not inside loop")
else: else:
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
code.continue_label) # code.continue_label)
code.put_goto(code.continue_label)
class ReturnStatNode(StatNode): class ReturnStatNode(StatNode):
...@@ -2780,8 +1596,6 @@ class ReturnStatNode(StatNode): ...@@ -2780,8 +1596,6 @@ class ReturnStatNode(StatNode):
if not self.return_type: if not self.return_type:
# error reported earlier # error reported earlier
return return
for entry in self.temps_in_use:
code.put_var_decref_clear(entry)
if self.value: if self.value:
self.value.generate_evaluation_code(code) self.value.generate_evaluation_code(code)
self.value.make_owned_reference(code) self.value.make_owned_reference(code)
...@@ -2798,9 +1612,12 @@ class ReturnStatNode(StatNode): ...@@ -2798,9 +1612,12 @@ class ReturnStatNode(StatNode):
"%s = %s;" % ( "%s = %s;" % (
Naming.retval_cname, Naming.retval_cname,
self.return_type.default_value)) self.return_type.default_value))
code.putln( for entry in self.temps_in_use:
"goto %s;" % code.put_var_decref_clear(entry)
code.return_label) #code.putln(
# "goto %s;" %
# code.return_label)
code.put_goto(code.return_label)
class RaiseStatNode(StatNode): class RaiseStatNode(StatNode):
...@@ -2962,9 +1779,10 @@ class IfClauseNode(Node): ...@@ -2962,9 +1779,10 @@ class IfClauseNode(Node):
"if (%s) {" % "if (%s) {" %
self.condition.result_code) self.condition.result_code)
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
end_label) # end_label)
code.put_goto(end_label)
code.putln("}") code.putln("}")
...@@ -2993,12 +1811,12 @@ class WhileStatNode(StatNode): ...@@ -2993,12 +1811,12 @@ class WhileStatNode(StatNode):
old_loop_labels = code.new_loop_labels() old_loop_labels = code.new_loop_labels()
code.putln( code.putln(
"while (1) {") "while (1) {")
code.put_label(code.continue_label)
self.condition.generate_evaluation_code(code) self.condition.generate_evaluation_code(code)
code.putln( code.putln(
"if (!%s) break;" % "if (!%s) break;" %
self.condition.result_code) self.condition.result_code)
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.put_label(code.continue_label)
code.putln("}") code.putln("}")
break_label = code.break_label break_label = code.break_label
code.set_loop_labels(old_loop_labels) code.set_loop_labels(old_loop_labels)
...@@ -3031,12 +1849,10 @@ class ForInStatNode(StatNode): ...@@ -3031,12 +1849,10 @@ class ForInStatNode(StatNode):
self.item = ExprNodes.NextNode(self.iterator, env) self.item = ExprNodes.NextNode(self.iterator, env)
self.item = self.item.coerce_to(self.target.type, env) self.item = self.item.coerce_to(self.target.type, env)
self.item.allocate_temps(env) self.item.allocate_temps(env)
self.target.allocate_target_temps(env) self.target.allocate_target_temps(env, self.item)
self.item.release_temp(env) #self.item.release_temp(env)
self.target.release_target_temp(env) #self.target.release_target_temp(env)
#env.recycle_pending_temps() # TEMPORARY
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
#env.recycle_pending_temps() # TEMPORARY
if self.else_clause: if self.else_clause:
self.else_clause.analyse_expressions(env) self.else_clause.analyse_expressions(env)
self.iterator.release_temp(env) self.iterator.release_temp(env)
...@@ -3046,10 +1862,10 @@ class ForInStatNode(StatNode): ...@@ -3046,10 +1862,10 @@ class ForInStatNode(StatNode):
self.iterator.generate_evaluation_code(code) self.iterator.generate_evaluation_code(code)
code.putln( code.putln(
"for (;;) {") "for (;;) {")
code.put_label(code.continue_label)
self.item.generate_evaluation_code(code) self.item.generate_evaluation_code(code)
self.target.generate_assignment_code(self.item, code) self.target.generate_assignment_code(self.item, code)
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.put_label(code.continue_label)
code.putln( code.putln(
"}") "}")
break_label = code.break_label break_label = code.break_label
...@@ -3075,6 +1891,7 @@ class ForFromStatNode(StatNode): ...@@ -3075,6 +1891,7 @@ class ForFromStatNode(StatNode):
# #
# Used internally: # Used internally:
# #
# is_py_target bool
# loopvar_name string # loopvar_name string
# py_loopvar_node PyTempNode or None # py_loopvar_node PyTempNode or None
...@@ -3094,14 +1911,19 @@ class ForFromStatNode(StatNode): ...@@ -3094,14 +1911,19 @@ class ForFromStatNode(StatNode):
if not (self.bound2.is_name or self.bound2.is_literal): if not (self.bound2.is_name or self.bound2.is_literal):
self.bound2 = self.bound2.coerce_to_temp(env) self.bound2 = self.bound2.coerce_to_temp(env)
target_type = self.target.type target_type = self.target.type
if not (target_type.is_pyobject if not (target_type.is_pyobject or target_type.is_int):
or target_type.assignable_from(PyrexTypes.c_int_type)): error(self.target.pos,
error(self.target.pos, "Integer for-loop variable must be of type int or Python object")
"Cannot assign integer to variable of type '%s'" % 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 target_type.is_int: if target_type.is_int:
self.is_py_target = 0
self.loopvar_name = self.target.entry.cname self.loopvar_name = self.target.entry.cname
self.py_loopvar_node = None self.py_loopvar_node = None
else: else:
self.is_py_target = 1
c_loopvar_node = ExprNodes.TempNode(self.pos, c_loopvar_node = ExprNodes.TempNode(self.pos,
PyrexTypes.c_long_type, env) PyrexTypes.c_long_type, env)
c_loopvar_node.allocate_temps(env) c_loopvar_node.allocate_temps(env)
...@@ -3110,20 +1932,18 @@ class ForFromStatNode(StatNode): ...@@ -3110,20 +1932,18 @@ class ForFromStatNode(StatNode):
ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env) ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
self.bound1.allocate_temps(env) self.bound1.allocate_temps(env)
self.bound2.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.py_loopvar_node.allocate_temps(env)
self.target.allocate_target_temps(env) self.target.allocate_target_temps(env, self.py_loopvar_node)
self.target.release_target_temp(env) #self.target.release_target_temp(env)
if self.py_loopvar_node: #self.py_loopvar_node.release_temp(env)
self.py_loopvar_node.release_temp(env)
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
if self.py_loopvar_node: if self.is_py_target:
c_loopvar_node.release_temp(env) c_loopvar_node.release_temp(env)
if self.else_clause: if self.else_clause:
self.else_clause.analyse_expressions(env) self.else_clause.analyse_expressions(env)
self.bound1.release_temp(env) self.bound1.release_temp(env)
self.bound2.release_temp(env) self.bound2.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code): def generate_execution_code(self, code):
old_loop_labels = code.new_loop_labels() old_loop_labels = code.new_loop_labels()
...@@ -3200,9 +2020,10 @@ class TryExceptStatNode(StatNode): ...@@ -3200,9 +2020,10 @@ class TryExceptStatNode(StatNode):
self.else_clause.generate_execution_code(code) self.else_clause.generate_execution_code(code)
code.putln( code.putln(
"}") "}")
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
end_label) # end_label)
code.put_goto(end_label)
code.put_label(our_error_label) code.put_label(our_error_label)
code.put_var_xdecrefs_clear(self.cleanup_list) code.put_var_xdecrefs_clear(self.cleanup_list)
default_clause_seen = 0 default_clause_seen = 0
...@@ -3214,9 +2035,10 @@ class TryExceptStatNode(StatNode): ...@@ -3214,9 +2035,10 @@ class TryExceptStatNode(StatNode):
error(except_clause.pos, "Default except clause not last") error(except_clause.pos, "Default except clause not last")
except_clause.generate_handling_code(code, end_label) except_clause.generate_handling_code(code, end_label)
if not default_clause_seen: if not default_clause_seen:
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
code.error_label) # code.error_label)
code.put_goto(code.error_label)
code.put_label(end_label) code.put_label(end_label)
...@@ -3248,11 +2070,11 @@ class ExceptClauseNode(Node): ...@@ -3248,11 +2070,11 @@ class ExceptClauseNode(Node):
self.exc_value = ExprNodes.ExcValueNode(self.pos, env) self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
self.exc_value.allocate_temps(env) self.exc_value.allocate_temps(env)
if self.target: if self.target:
self.target.analyse_target_expression(env) self.target.analyse_target_expression(env, self.exc_value)
self.exc_value.release_temp(env) else:
if self.target: self.exc_value.release_temp(env)
self.target.release_target_temp(env) #if self.target:
#env.recycle_pending_temps() # TEMPORARY # self.target.release_target_temp(env)
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
def generate_handling_code(self, code, end_label): def generate_handling_code(self, code, end_label):
...@@ -3281,9 +2103,10 @@ class ExceptClauseNode(Node): ...@@ -3281,9 +2103,10 @@ class ExceptClauseNode(Node):
else: else:
self.exc_value.generate_disposal_code(code) self.exc_value.generate_disposal_code(code)
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.putln( #code.putln(
"goto %s;" # "goto %s;"
% end_label) # % end_label)
code.put_goto(end_label)
code.putln( code.putln(
"}") "}")
...@@ -3353,20 +2176,23 @@ class TryFinallyStatNode(StatNode): ...@@ -3353,20 +2176,23 @@ class TryFinallyStatNode(StatNode):
#code.putln( #code.putln(
# "int %s;" % # "int %s;" %
# self.lineno_var) # self.lineno_var)
code.use_label(catch_label)
code.putln( code.putln(
"__pyx_why = 0; goto %s;" % "__pyx_why = 0; goto %s;" %
catch_label) catch_label)
for i in range(len(new_labels)): for i in range(len(new_labels)):
if new_labels[i] and new_labels[i] <> "<try>": new_label = new_labels[i]
if new_labels[i] == new_error_label: if new_label and new_label <> "<try>":
self.put_error_catcher(code, if new_label in code.labels_used:
new_error_label, i+1, catch_label) if new_label == new_error_label:
else: self.put_error_catcher(code,
code.putln( new_error_label, i+1, catch_label)
"%s: __pyx_why = %s; goto %s;" % ( else:
new_labels[i], code.putln(
i+1, "%s: __pyx_why = %s; goto %s;" % (
catch_label)) new_label,
i+1,
catch_label))
code.put_label(catch_label) code.put_label(catch_label)
code.set_all_labels(old_labels) code.set_all_labels(old_labels)
self.finally_clause.generate_execution_code(code) self.finally_clause.generate_execution_code(code)
...@@ -3377,6 +2203,7 @@ class TryFinallyStatNode(StatNode): ...@@ -3377,6 +2203,7 @@ class TryFinallyStatNode(StatNode):
if old_labels[i] == old_error_label: if old_labels[i] == old_error_label:
self.put_error_uncatcher(code, i+1, old_error_label) self.put_error_uncatcher(code, i+1, old_error_label)
else: else:
code.use_label(old_labels[i])
code.putln( code.putln(
"case %s: goto %s;" % ( "case %s: goto %s;" % (
i+1, i+1,
...@@ -3400,9 +2227,10 @@ class TryFinallyStatNode(StatNode): ...@@ -3400,9 +2227,10 @@ class TryFinallyStatNode(StatNode):
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
self.lineno_var, Naming.lineno_cname)) self.lineno_var, Naming.lineno_cname))
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
catch_label) # catch_label)
code.put_goto(catch_label)
code.putln( code.putln(
"}") "}")
...@@ -3420,9 +2248,10 @@ class TryFinallyStatNode(StatNode): ...@@ -3420,9 +2248,10 @@ class TryFinallyStatNode(StatNode):
code.putln( code.putln(
"%s = 0;" % "%s = 0;" %
var) var)
code.putln( #code.putln(
"goto %s;" % # "goto %s;" %
error_label) # error_label)
code.put_goto(error_label)
code.putln( code.putln(
"}") "}")
...@@ -3502,11 +2331,10 @@ class FromImportStatNode(StatNode): ...@@ -3502,11 +2331,10 @@ class FromImportStatNode(StatNode):
for name, target in self.items: for name, target in self.items:
if Options.intern_names: if Options.intern_names:
self.interned_items.append((env.intern(name), target)) self.interned_items.append((env.intern(name), target))
target.analyse_target_expression(env) target.analyse_target_expression(env, None)
target.release_temp(env) #target.release_target_temp(env) # was release_temp ?!?
self.module.release_temp(env) self.module.release_temp(env)
self.item.release_temp(env) self.item.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code): def generate_execution_code(self, code):
self.module.generate_evaluation_code(code) self.module.generate_evaluation_code(code)
...@@ -3542,38 +2370,21 @@ utility_function_predeclarations = \ ...@@ -3542,38 +2370,21 @@ utility_function_predeclarations = \
""" """
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/ typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*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 = \ #get_name_predeclaration = \
"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/" #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
get_name_interned_predeclaration = \ #get_name_interned_predeclaration = \
"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/" #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
printing_utility_code = \ printing_utility_code = [
r""" """
static int __Pyx_PrintItem(PyObject *); /*proto*/
static int __Pyx_PrintNewline(void); /*proto*/
""",r"""
static PyObject *__Pyx_GetStdout(void) { static PyObject *__Pyx_GetStdout(void) {
PyObject *f = PySys_GetObject("stdout"); PyObject *f = PySys_GetObject("stdout");
if (!f) { if (!f) {
...@@ -3614,14 +2425,16 @@ static int __Pyx_PrintNewline(void) { ...@@ -3614,14 +2425,16 @@ static int __Pyx_PrintNewline(void) {
PyFile_SoftSpace(f, 0); PyFile_SoftSpace(f, 0);
return 0; return 0;
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
# The following function is based on do_raise() from ceval.c. # 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) { static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
Py_XINCREF(type); Py_XINCREF(type);
Py_XINCREF(value); Py_XINCREF(value);
...@@ -3648,32 +2461,28 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { ...@@ -3648,32 +2461,28 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
Py_INCREF(type); Py_INCREF(type);
Py_DECREF(tmp); Py_DECREF(tmp);
} }
if (PyString_Check(type)) if (PyString_Check(type)) {
; if (PyErr_Warn(PyExc_DeprecationWarning,
else if (PyClass_Check(type)) "raising a string exception is deprecated"))
goto raise_error;
}
else if (PyType_Check(type) || PyClass_Check(type))
; /*PyErr_NormalizeException(&type, &value, &tb);*/ ; /*PyErr_NormalizeException(&type, &value, &tb);*/
else if (PyInstance_Check(type)) { else {
/* Raising an instance. The value should be a dummy. */ /* Raising an instance. The value should be a dummy. */
if (value != Py_None) { if (value != Py_None) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"instance exception may not have a separate value"); "instance exception may not have a separate value");
goto raise_error; goto raise_error;
} }
else { /* Normalize to raise <class>, <instance> */
/* Normalize to raise <class>, <instance> */ Py_DECREF(value);
Py_DECREF(value); value = type;
value = type; if (PyInstance_Check(type))
type = (PyObject*) ((PyInstanceObject*)type)->in_class; type = (PyObject*) ((PyInstanceObject*)type)->in_class;
Py_INCREF(type); else
} type = (PyObject*) type->ob_type;
} 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;
} }
PyErr_Restore(type, value, tb); PyErr_Restore(type, value, tb);
return; return;
...@@ -3683,12 +2492,14 @@ raise_error: ...@@ -3683,12 +2492,14 @@ raise_error:
Py_XDECREF(tb); Py_XDECREF(tb);
return; return;
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
reraise_utility_code = \ reraise_utility_code = [
""" """
static void __Pyx_ReRaise(void); /*proto*/
""","""
static void __Pyx_ReRaise(void) { static void __Pyx_ReRaise(void) {
PyThreadState *tstate = PyThreadState_Get(); PyThreadState *tstate = PyThreadState_Get();
PyObject *type = tstate->exc_type; PyObject *type = tstate->exc_type;
...@@ -3699,12 +2510,14 @@ static void __Pyx_ReRaise(void) { ...@@ -3699,12 +2510,14 @@ static void __Pyx_ReRaise(void) {
Py_XINCREF(tb); Py_XINCREF(tb);
PyErr_Restore(type, value, 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) { static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
if (!type) { if (!type) {
PyErr_Format(PyExc_SystemError, "Missing type object"); PyErr_Format(PyExc_SystemError, "Missing type object");
...@@ -3717,7 +2530,7 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed ...@@ -3717,7 +2530,7 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
name, type->tp_name, obj->ob_type->tp_name); name, type->tp_name, obj->ob_type->tp_name);
return 0; return 0;
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
# #
...@@ -3733,8 +2546,11 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed ...@@ -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. # 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( static int __Pyx_GetStarArgs(
PyObject **args, PyObject **args,
PyObject **kwds, PyObject **kwds,
...@@ -3799,18 +2615,22 @@ static int __Pyx_GetStarArgs( ...@@ -3799,18 +2615,22 @@ static int __Pyx_GetStarArgs(
bad: bad:
Py_XDECREF(args1); Py_XDECREF(args1);
Py_XDECREF(kwds1); Py_XDECREF(kwds1);
if (*args2) if (*args2) {
Py_XDECREF(*args2); Py_XDECREF(*args2);
if (*kwds2) }
if (*kwds2) {
Py_XDECREF(*kwds2); Py_XDECREF(*kwds2);
}
return -1; return -1;
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
unraisable_exception_utility_code = \ unraisable_exception_utility_code = [
""" """
static void __Pyx_WriteUnraisable(char *name); /*proto*/
""","""
static void __Pyx_WriteUnraisable(char *name) { static void __Pyx_WriteUnraisable(char *name) {
PyObject *old_exc, *old_val, *old_tb; PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx; PyObject *ctx;
...@@ -3821,12 +2641,14 @@ static void __Pyx_WriteUnraisable(char *name) { ...@@ -3821,12 +2641,14 @@ static void __Pyx_WriteUnraisable(char *name) {
ctx = Py_None; ctx = Py_None;
PyErr_WriteUnraisable(ctx); PyErr_WriteUnraisable(ctx);
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
traceback_utility_code = \ traceback_utility_code = [
""" """
static void __Pyx_AddTraceback(char *funcname); /*proto*/
""","""
#include "compile.h" #include "compile.h"
#include "frameobject.h" #include "frameobject.h"
#include "traceback.h" #include "traceback.h"
...@@ -3888,12 +2710,14 @@ bad: ...@@ -3888,12 +2710,14 @@ bad:
'FILENAME': Naming.filename_cname, 'FILENAME': Naming.filename_cname,
'LINENO': Naming.lineno_cname, 'LINENO': Naming.lineno_cname,
'GLOBALS': Naming.module_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, static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
long size) long size)
{ {
...@@ -3943,12 +2767,14 @@ done: ...@@ -3943,12 +2767,14 @@ done:
Py_XDECREF(py_name_list); Py_XDECREF(py_name_list);
return (PyTypeObject *)result; 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) { static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
PyObject *pycobj = 0; PyObject *pycobj = 0;
int result; int result;
...@@ -3967,12 +2793,14 @@ done: ...@@ -3967,12 +2793,14 @@ done:
Py_XDECREF(pycobj); Py_XDECREF(pycobj);
return result; return result;
} }
""" """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
get_vtable_utility_code = \ get_vtable_utility_code = [
r""" """
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
""",r"""
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) { static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
int result; int result;
PyObject *pycobj; PyObject *pycobj;
...@@ -3992,12 +2820,14 @@ done: ...@@ -3992,12 +2820,14 @@ done:
Py_XDECREF(pycobj); Py_XDECREF(pycobj);
return result; 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) { static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
while (t->p) { while (t->p) {
*t->p = PyString_InternFromString(t->s); *t->p = PyString_InternFromString(t->s);
...@@ -4007,12 +2837,14 @@ static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) { ...@@ -4007,12 +2837,14 @@ static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
} }
return 0; 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) { static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
while (t->p) { while (t->p) {
*t->p = PyString_FromStringAndSize(t->s, t->n - 1); *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
...@@ -4022,6 +2854,6 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) { ...@@ -4022,6 +2854,6 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
} }
return 0; return 0;
} }
"""; """]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
...@@ -8,6 +8,7 @@ from types import ListType, TupleType ...@@ -8,6 +8,7 @@ from types import ListType, TupleType
from Scanning import PyrexScanner from Scanning import PyrexScanner
import Nodes import Nodes
import ExprNodes import ExprNodes
from ModuleNode import ModuleNode
from Errors import error, InternalError from Errors import error, InternalError
def p_ident(s, message = "Expected an identifier"): def p_ident(s, message = "Expected an identifier"):
...@@ -413,13 +414,7 @@ def p_atom(s): ...@@ -413,13 +414,7 @@ def p_atom(s):
elif sy == '`': elif sy == '`':
return p_backquote_expr(s) return p_backquote_expr(s)
elif sy == 'INT': elif sy == 'INT':
digits = s.systring value = s.systring
if digits[:2] == "0x":
value = long(digits[2:], 16)
elif digits[:1] == "0":
value = int(digits, 8)
else:
value = int(s.systring)
s.next() s.next()
return ExprNodes.IntNode(pos, value = value) return ExprNodes.IntNode(pos, value = value)
elif sy == 'LONG': elif sy == 'LONG':
...@@ -517,7 +512,7 @@ def p_string_literal(s): ...@@ -517,7 +512,7 @@ def p_string_literal(s):
elif c == '\n': elif c == '\n':
pass pass
else: else:
chars.append(systr[1:]) chars.append(r'\\' + systr[1:])
elif sy == 'NEWLINE': elif sy == 'NEWLINE':
chars.append(r'\n') chars.append(r'\n')
elif sy == 'END_STRING': elif sy == 'END_STRING':
...@@ -668,7 +663,6 @@ def p_expression_or_assignment(s): ...@@ -668,7 +663,6 @@ def p_expression_or_assignment(s):
if len(nodes) == 1: if len(nodes) == 1:
return nodes[0] return nodes[0]
else: else:
#return Nodes.StatListNode(nodes[0].pos, stats = nodes)
return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes) return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes)
def flatten_parallel_assignments(input, output): def flatten_parallel_assignments(input, output):
...@@ -1375,19 +1369,19 @@ def p_exception_value_clause(s): ...@@ -1375,19 +1369,19 @@ def p_exception_value_clause(s):
if s.sy == '?': if s.sy == '?':
exc_check = 1 exc_check = 1
s.next() s.next()
exc_val = p_exception_value(s) exc_val = p_simple_expr(s) #p_exception_value(s)
return exc_val, exc_check return exc_val, exc_check
def p_exception_value(s): #def p_exception_value(s):
sign = "" # sign = ""
if s.sy == "-": # if s.sy == "-":
sign = "-" # sign = "-"
s.next() # s.next()
if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'): # if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'):
s.systring = sign + s.systring # s.systring = sign + s.systring
return p_atom(s) # return p_atom(s)
else: # else:
s.error("Exception value must be an int or float literal or NULL") # s.error("Exception value must be an int or float literal or NULL")
c_arg_list_terminators = ('*', '**', '.', ')') c_arg_list_terminators = ('*', '**', '.', ')')
c_arg_list_trailers = ('.', '*', '**') c_arg_list_trailers = ('.', '*', '**')
...@@ -1780,7 +1774,7 @@ def p_module(s, pxd): ...@@ -1780,7 +1774,7 @@ def p_module(s, pxd):
if s.sy <> 'EOF': if s.sy <> 'EOF':
s.error("Syntax error in statement [%s,%s]" % ( s.error("Syntax error in statement [%s,%s]" % (
repr(s.sy), repr(s.systring))) repr(s.sy), repr(s.systring)))
return Nodes.ModuleNode(pos, doc = doc, body = body) return ModuleNode(pos, doc = doc, body = body)
#---------------------------------------------- #----------------------------------------------
# #
......
...@@ -259,14 +259,14 @@ class CType(PyrexType): ...@@ -259,14 +259,14 @@ class CType(PyrexType):
from_py_function = None from_py_function = None
class CSimpleType(CType): #class CSimpleType(CType):
# # #
# Base class for all unstructured C types. # # Base class for all unstructured C types.
# # #
pass # pass
class CVoidType(CSimpleType): class CVoidType(CType):
is_void = 1 is_void = 1
def __repr__(self): def __repr__(self):
...@@ -313,9 +313,6 @@ class CNumericType(CType): ...@@ -313,9 +313,6 @@ class CNumericType(CType):
u = "unsigned " u = "unsigned "
return "<CNumericType %s%s>" % (u, rank_to_type_name[self.rank]) 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, def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0): for_display = 0, dll_linkage = None, pyrex = 0):
if self.signed: if self.signed:
...@@ -324,8 +321,6 @@ class CNumericType(CType): ...@@ -324,8 +321,6 @@ class CNumericType(CType):
u = "unsigned " u = "unsigned "
base = public_decl(u + rank_to_type_name[self.rank], dll_linkage) base = public_decl(u + rank_to_type_name[self.rank], dll_linkage)
return "%s %s" % (base, entity_code) return "%s %s" % (base, entity_code)
# return "%s%s %s" % (u, rank_to_type_name[self.rank], entity_code)
class CIntType(CNumericType): class CIntType(CNumericType):
...@@ -338,6 +333,9 @@ class CIntType(CNumericType): ...@@ -338,6 +333,9 @@ class CIntType(CNumericType):
def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0): def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
CNumericType.__init__(self, rank, signed, pymemberdef_typecode) CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
self.is_returncode = is_returncode 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): class CUIntType(CIntType):
...@@ -373,6 +371,9 @@ class CFloatType(CNumericType): ...@@ -373,6 +371,9 @@ class CFloatType(CNumericType):
def __init__(self, rank, pymemberdef_typecode = None): def __init__(self, rank, pymemberdef_typecode = None):
CNumericType.__init__(self, rank, 1, pymemberdef_typecode) 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): class CArrayType(CType):
# base_type CType Element type # base_type CType Element type
...@@ -447,6 +448,8 @@ class CPtrType(CType): ...@@ -447,6 +448,8 @@ class CPtrType(CType):
return 1 return 1
elif self.base_type.is_cfunction and other_type.is_cfunction: elif self.base_type.is_cfunction and other_type.is_cfunction:
return self.base_type.same_as(other_type) 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: elif not other_type.is_ptr:
return 0 return 0
elif self.base_type.is_void: elif self.base_type.is_void:
...@@ -608,14 +611,16 @@ class CStructOrUnionType(CType): ...@@ -608,14 +611,16 @@ class CStructOrUnionType(CType):
return self.is_complete() return self.is_complete()
class CEnumType(CIntType): class CEnumType(CType):
# name string # name string
# cname string or None # cname string or None
# typedef_flag boolean # typedef_flag boolean
is_enum = 1 is_enum = 1
signed = 1 #signed = 1
rank = 2 #rank = 2
to_py_function = "PyInt_FromLong"
from_py_function = "PyInt_AsLong"
def __init__(self, name, cname, typedef_flag): def __init__(self, name, cname, typedef_flag):
self.name = name self.name = name
......
...@@ -61,6 +61,7 @@ class Entry: ...@@ -61,6 +61,7 @@ class Entry:
# interned_cname string C name of interned name string # interned_cname string C name of interned name string
# pystring_cname string C name of Python version of string literal # pystring_cname string C name of Python version of string literal
# is_interned boolean For string const entries, value is interned # is_interned boolean For string const entries, value is interned
# used boolean
borrowed = 0 borrowed = 0
init = "" init = ""
...@@ -91,6 +92,7 @@ class Entry: ...@@ -91,6 +92,7 @@ class Entry:
interned_cname = None interned_cname = None
pystring_cname = None pystring_cname = None
is_interned = 0 is_interned = 0
used = 0
def __init__(self, name, cname, type, pos = None, init = None): def __init__(self, name, cname, type, pos = None, init = None):
self.name = name self.name = name
...@@ -351,6 +353,7 @@ class Scope: ...@@ -351,6 +353,7 @@ class Scope:
# Add an entry for a string constant. # Add an entry for a string constant.
cname = self.new_const_cname() cname = self.new_const_cname()
entry = Entry("", cname, c_char_array_type, init = value) entry = Entry("", cname, c_char_array_type, init = value)
entry.used = 1
self.const_entries.append(entry) self.const_entries.append(entry)
return entry return entry
...@@ -395,6 +398,7 @@ class Scope: ...@@ -395,6 +398,7 @@ class Scope:
self.temp_counter = n + 1 self.temp_counter = n + 1
cname = "%s%d" % (Naming.pyrex_prefix, n) cname = "%s%d" % (Naming.pyrex_prefix, n)
entry = Entry("", cname, type) entry = Entry("", cname, type)
entry.used = 1
if type.is_pyobject: if type.is_pyobject:
entry.init = "0" entry.init = "0"
self.cname_to_entry[entry.cname] = entry self.cname_to_entry[entry.cname] = entry
...@@ -476,6 +480,7 @@ class ModuleScope(Scope): ...@@ -476,6 +480,7 @@ class ModuleScope(Scope):
# intern_map {string : string} Mapping from Python names to interned strs # intern_map {string : string} Mapping from Python names to interned strs
# interned_names [string] Interned names pending generation of declarations # interned_names [string] Interned names pending generation of declarations
# all_pystring_entries [Entry] Python string consts from all scopes # 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): def __init__(self, name, parent_module, context):
self.parent_module = parent_module self.parent_module = parent_module
...@@ -500,6 +505,7 @@ class ModuleScope(Scope): ...@@ -500,6 +505,7 @@ class ModuleScope(Scope):
self.intern_map = {} self.intern_map = {}
self.interned_names = [] self.interned_names = []
self.all_pystring_entries = [] self.all_pystring_entries = []
self.types_imported = {}
def qualifying_scope(self): def qualifying_scope(self):
return self.parent_module return self.parent_module
...@@ -565,6 +571,8 @@ class ModuleScope(Scope): ...@@ -565,6 +571,8 @@ class ModuleScope(Scope):
# None if previously declared as something else. # None if previously declared as something else.
entry = self.lookup_here(name) entry = self.lookup_here(name)
if entry: 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): if not (entry.is_pyglobal and not entry.as_module):
error(pos, "'%s' redeclared" % name) error(pos, "'%s' redeclared" % name)
return None return None
...@@ -956,6 +964,8 @@ class CClassScope(ClassScope): ...@@ -956,6 +964,8 @@ class CClassScope(ClassScope):
if visibility in ('public', 'readonly'): if visibility in ('public', 'readonly'):
if type.pymemberdef_typecode: if type.pymemberdef_typecode:
self.public_attr_entries.append(entry) self.public_attr_entries.append(entry)
if name == "__weakref__":
error(pos, "Special attribute __weakref__ cannot be exposed to Python")
else: else:
error(pos, error(pos,
"C attribute of type '%s' cannot be accessed from Python" % type) "C attribute of type '%s' cannot be accessed from Python" % type)
......
version = '0.9.4.1' version = '0.9.5.1a'
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
verbose = 0 verbose = 0
gcc_pendantic = True gcc_pendantic = True
gcc_warnings_are_errors = False gcc_warnings_are_errors = True
gcc_all_warnings = True
import os import os
from Pyrex.Utils import replace_suffix from Pyrex.Utils import replace_suffix
...@@ -23,6 +24,9 @@ if gcc_pendantic: ...@@ -23,6 +24,9 @@ if gcc_pendantic:
compiler_options.extend(["-pedantic", "-Wno-long-long"]) compiler_options.extend(["-pedantic", "-Wno-long-long"])
if gcc_warnings_are_errors: if gcc_warnings_are_errors:
compiler_options.append("-Werror") compiler_options.append("-Werror")
if gcc_all_warnings:
compiler_options.append("-Wall")
compiler_options.append("-Wno-unused-function")
linkers = ["gcc", "g++"] linkers = ["gcc", "g++"]
linker_options = \ linker_options = \
...@@ -45,6 +49,7 @@ def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"): ...@@ -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] args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
if verbose_flag or verbose: if verbose_flag or verbose:
print " ".join(args) print " ".join(args)
#print compiler, args ###
status = os.spawnvp(os.P_WAIT, compiler, args) status = os.spawnvp(os.P_WAIT, compiler, args)
if status <> 0: if status <> 0:
raise CCompilerError("C compiler returned status %s" % status) raise CCompilerError("C compiler returned status %s" % status)
......
"""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 = {
}
"""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 = {
}
# 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 $@
"Apple Event suite for pyserver."
import aetools
import MacOS
_code = 'misc'
class PS_Misc_Suite:
def DoScript(self, _object, _attributes={}, **_arguments):
"""DoScript: Execute a 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 = {
}
#
# 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"
...@@ -108,6 +108,15 @@ PyMac_BuildHFSUniStr255(HFSUniStr255 *itself) ...@@ -108,6 +108,15 @@ PyMac_BuildHFSUniStr255(HFSUniStr255 *itself)
static PyObject *File_Error; 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 -------------------- */ /* ------------------- Object type FSCatalogInfo -------------------- */
static PyTypeObject FSCatalogInfo_Type; static PyTypeObject FSCatalogInfo_Type;
...@@ -338,16 +347,16 @@ static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject ...@@ -338,16 +347,16 @@ static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject
static PyObject *FSCatalogInfo_get_finderInfo(FSCatalogInfoObject *self, void *closure) 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) static int FSCatalogInfo_set_finderInfo(FSCatalogInfoObject *self, PyObject *v, void *closure)
{ {
if (!FInfo_Check(v)) { if (!FInfo_Check(v)) {
PyErr_SetString(PyTypeError, "Expected an FInfo object"); PyErr_SetString(PyExc_TypeError, "Expected an FInfo object");
return -1; return -1;
} }
*(FInfo *)self->finderInfo = ((FInfoObject *)self)->ob_itself; *(FInfo *)self->ob_itself.finderInfo = ((FInfoObject *)v)->ob_itself;
return 0; return 0;
} }
...@@ -485,15 +494,6 @@ static PyTypeObject FSCatalogInfo_Type = { ...@@ -485,15 +494,6 @@ static PyTypeObject FSCatalogInfo_Type = {
/* ----------------------- Object type FInfo ------------------------ */ /* ----------------------- 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) static PyObject *FInfo_New(FInfo *itself)
{ {
FInfoObject *it; FInfoObject *it;
...@@ -3247,8 +3247,8 @@ PyMac_GetFSRef(PyObject *v, FSRef *fsr) ...@@ -3247,8 +3247,8 @@ PyMac_GetFSRef(PyObject *v, FSRef *fsr)
if ( PyString_Check(v) || PyUnicode_Check(v)) { if ( PyString_Check(v) || PyUnicode_Check(v)) {
char *path = NULL; char *path = NULL;
if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path)) if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
return NULL; return 0;
if ( (err=FSPathMakeRef(path, fsr, NULL)) ) { if ( (err=FSPathMakeRef((unsigned char *)path, fsr, NULL)) ) {
PyMac_Error(err); PyMac_Error(err);
return 0; return 0;
} }
......
#
# 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment