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:
in_try_finally = 0
def __init__(self, outfile_name):
self.f = open_new_file(outfile_name)
def __init__(self, f):
#self.f = open_new_file(outfile_name)
self.f = f
self.level = 0
self.bol = 1
self.marker = None
......@@ -80,6 +81,7 @@ class CCodeWriter:
def init_labels(self):
self.label_counter = 0
self.labels_used = {}
self.return_label = self.new_label()
self.new_error_label()
self.continue_label = None
......@@ -134,9 +136,17 @@ class CCodeWriter:
new_labels.append(old_label)
self.set_all_labels(new_labels)
return old_labels
def use_label(self, lbl):
self.labels_used[lbl] = 1
def put_label(self, lbl):
self.putln("%s:;" % lbl)
if lbl in self.labels_used:
self.putln("%s:;" % lbl)
def put_goto(self, lbl):
self.use_label(lbl)
self.putln("goto %s;" % lbl)
def put_var_declarations(self, entries, static = 0, dll_linkage = None,
definition = True):
......@@ -146,28 +156,23 @@ class CCodeWriter:
def put_var_declaration(self, entry, static = 0, dll_linkage = None,
definition = True):
#print "Code.put_var_declaration:", entry.name, "definition =", definition
#print "Code.put_var_declaration:", entry.name, "definition =", definition ###
visibility = entry.visibility
if visibility == 'private' and not definition:
return
if not entry.used and visibility == "private":
return
storage_class = ""
if visibility == 'extern':
storage_class = Naming.extern_c_macro
elif visibility == 'public':
if definition:
storage_class = ""
else:
if not definition:
storage_class = Naming.extern_c_macro
elif visibility == 'private':
if static:
storage_class = "static"
else:
storage_class = ""
if storage_class:
self.put("%s " % storage_class)
#if visibility == 'extern' or visibility == 'public' and not definition:
# self.put("%s " % Naming.extern_c_macro)
#elif static and visibility <> 'public':
# self.put("static ")
if visibility <> 'public':
dll_linkage = None
self.put(entry.type.declaration_code(entry.cname,
......@@ -186,10 +191,6 @@ class CCodeWriter:
def as_pyobject(self, cname, type):
return typecast(py_object_type, type, cname)
#if type.is_extension_type and type.base_type:
# return "(PyObject *)" + cname
#else:
# return cname
def put_incref(self, cname, type):
self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
......@@ -231,12 +232,13 @@ class CCodeWriter:
self.putln("Py_XDECREF(%s); %s = 0;" % (
self.entry_as_pyobject(entry), entry.cname))
def put_var_decrefs(self, entries):
def put_var_decrefs(self, entries, used_only = 0):
for entry in entries:
if entry.xdecref_cleanup:
self.put_var_xdecref(entry)
else:
self.put_var_decref(entry)
if not used_only or entry.used:
if entry.xdecref_cleanup:
self.put_var_xdecref(entry)
else:
self.put_var_decref(entry)
def put_var_xdecrefs(self, entries):
for entry in entries:
......@@ -269,13 +271,15 @@ class CCodeWriter:
term))
def error_goto(self, pos):
lbl = self.error_label
self.use_label(lbl)
return "{%s = %s[%s]; %s = %s; goto %s;}" % (
Naming.filename_cname,
Naming.filetable_cname,
self.lookup_filename(pos[0]),
Naming.lineno_cname,
pos[1],
self.error_label)
lbl)
def lookup_filename(self, filename):
try:
......
......@@ -8,7 +8,7 @@ from Errors import error, InternalError
import Naming
from Nodes import Node
import PyrexTypes
from PyrexTypes import py_object_type, typecast
from PyrexTypes import py_object_type, c_long_type, typecast
import Symtab
import Options
......@@ -89,13 +89,23 @@ class ExprNode(Node):
# - If a temporary was allocated, call release_temp on
# all sub-expressions.
#
# A default implementation of allocate_temps is
# provided which uses the following abstract method:
# allocate_target_temps
# - Call allocate_temps on sub-nodes and allocate any other
# temps used during assignment.
# - Fill in result_code with a C lvalue if needed.
# - If a rhs node is supplied, call release_temp on it.
# - Call release_temp on sub-nodes and release any other
# temps used during assignment.
#
# calculate_result_code
# - Return a C code fragment evaluating to
# the result. This is only called when the
# result is not a temporary.
# calculate_result_code
# - Return a C code fragment evaluating to
# the result. This is only called when the
# result is not a temporary.
#
# target_code
# Called by the default implementation of allocate_target_temps.
# Should return a C lvalue for assigning to the node. The default
# implementation calls calculate_result_code.
#
# check_const
# - Check that this node and its subnodes form a
......@@ -145,16 +155,6 @@ class ExprNode(Node):
# - Generate code to perform the deletion.
# - Call generate_disposal_code on all sub-expressions.
#
# #result_as_extension_type ### OBSOLETE ###
# # Normally, the results of all nodes whose type
# # is a Python object, either generic or an extension
# # type, are returned as a generic Python object, so
# # that they can be passed directly to Python/C API
# # routines. This method is called to obtain the
# # result as the actual type of the node. It is only
# # called when the type is known to actually be an
# # extension type, and nodes whose result can never
# # be an extension type need not implement it.
#
is_sequence_constructor = 0
......@@ -231,12 +231,12 @@ class ExprNode(Node):
self.analyse_types(env)
self.allocate_temps(env)
def analyse_target_expression(self, env):
def analyse_target_expression(self, env, rhs):
# Convenience routine performing both the Type
# Analysis and Temp Allocation phases for the LHS of
# an assignment.
self.analyse_target_types(env)
self.allocate_target_temps(env)
self.allocate_target_temps(env, rhs)
def analyse_boolean_expression(self, env):
# Analyse expression and coerce to a boolean.
......@@ -298,12 +298,15 @@ class ExprNode(Node):
# a subnode.
return self.is_temp
def allocate_target_temps(self, env):
# Perform allocate_temps for the LHS of an assignment.
def allocate_target_temps(self, env, rhs):
# Perform temp allocation for the LHS of an assignment.
if debug_temp_alloc:
print self, "Allocating target temps"
self.allocate_subexpr_temps(env)
self.result_code = self.target_code()
if rhs:
rhs.release_temp(env)
self.release_subexpr_temps(env)
def allocate_temps(self, env, result = None):
# Allocate temporary variables for this node and
......@@ -362,9 +365,9 @@ class ExprNode(Node):
def calculate_result_code(self):
self.not_implemented("calculate_result_code")
def release_target_temp(self, env):
# Release temporaries used by LHS of an assignment.
self.release_subexpr_temps(env)
# def release_target_temp(self, env):
# # Release temporaries used by LHS of an assignment.
# self.release_subexpr_temps(env)
def release_temp(self, env):
# If this node owns a temporary result, release it,
......@@ -463,7 +466,8 @@ class ExprNode(Node):
if not src.type.is_pyobject:
src = CoerceToPyTypeNode(src, env)
if not src.type.subtype_of(dst_type):
src = PyTypeTestNode(src, dst_type, env)
if not isinstance(src, NoneNode):
src = PyTypeTestNode(src, dst_type, env)
elif src.type.is_pyobject:
src = CoerceFromPyTypeNode(dst_type, src, env)
else: # neither src nor dst are py types
......@@ -576,7 +580,7 @@ class ConstNode(AtomicExprNode):
class NullNode(ConstNode):
type = PyrexTypes.c_null_ptr_type
value = "0"
value = "NULL"
class CharNode(ConstNode):
......@@ -703,13 +707,14 @@ class NameNode(AtomicExprNode):
def analyse_entry(self, env):
self.check_identifier_kind()
self.type = self.entry.type
if self.entry.is_declared_generic:
entry = self.entry
self.type = entry.type
if entry.is_declared_generic:
self.result_ctype = py_object_type
# Reference to C array turns into pointer to first element.
while self.type.is_array:
self.type = self.type.element_ptr_type()
if self.entry.is_pyglobal or self.entry.is_builtin:
## Reference to C array turns into pointer to first element.
#while self.type.is_array:
# self.type = self.type.element_ptr_type()
if entry.is_pyglobal or entry.is_builtin:
assert self.type.is_pyobject, "Python global or builtin not a Python object"
self.is_temp = 1
if Options.intern_names:
......@@ -727,7 +732,9 @@ class NameNode(AtomicExprNode):
self.type = PyrexTypes.error_type
def check_identifier_kind(self):
#print "NameNode.check_identifier_kind:", self.entry.name ###
entry = self.entry
entry.used = 1
if not (entry.is_const or entry.is_variable
or entry.is_builtin or entry.is_cfunction):
if self.entry.as_variable:
......@@ -1071,11 +1078,11 @@ class IndexNode(ExprNode):
self.index.py_result(),
rhs.py_result(),
code.error_goto(self.pos)))
self.generate_subexpr_disposal_code(code)
else:
code.putln(
"%s = %s;" % (
self.result_code, rhs.result_code))
self.generate_subexpr_disposal_code(code)
rhs.generate_disposal_code(code)
def generate_deletion_code(self, code):
......@@ -1220,9 +1227,12 @@ class SimpleCallNode(ExprNode):
function.obj = CloneNode(self.self)
func_type = self.function_type()
if func_type.is_pyobject:
self.arg_tuple = TupleNode(self.pos, args = self.args)
if self.args:
self.arg_tuple = TupleNode(self.pos, args = self.args)
self.arg_tuple.analyse_types(env)
else:
self.arg_tuple = None
self.args = None
self.arg_tuple.analyse_types(env)
self.type = py_object_type
self.is_temp = 1
else:
......@@ -1309,11 +1319,15 @@ class SimpleCallNode(ExprNode):
def generate_result_code(self, code):
func_type = self.function_type()
if func_type.is_pyobject:
if self.arg_tuple:
arg_code = self.arg_tuple.py_result()
else:
arg_code = "0"
code.putln(
"%s = PyObject_CallObject(%s, %s); if (!%s) %s" % (
self.result_code,
self.function.py_result(),
self.arg_tuple.py_result(),
arg_code,
self.result_code,
code.error_goto(self.pos)))
elif func_type.is_cfunction:
......@@ -1535,9 +1549,9 @@ class AttributeNode(ExprNode):
self.analyse_attribute(env)
if self.entry and self.entry.is_cmethod and not self.is_called:
error(self.pos, "C method can only be called")
# Reference to C array turns into pointer to first element.
while self.type.is_array:
self.type = self.type.element_ptr_type()
## Reference to C array turns into pointer to first element.
#while self.type.is_array:
# self.type = self.type.element_ptr_type()
if self.is_py_attr:
if not target:
self.is_temp = 1
......@@ -1568,6 +1582,8 @@ class AttributeNode(ExprNode):
obj_type = PyrexTypes.error_type
self.entry = entry
if entry:
if obj_type.is_extension_type and entry.name == "__weakref__":
error(self.pos, "Illegal use of special attribute __weakref__")
if entry.is_variable or entry.is_cmethod:
self.type = entry.type
self.member = entry.cname
......@@ -1662,7 +1678,6 @@ class AttributeNode(ExprNode):
code.error_goto(self.pos)))
rhs.generate_disposal_code(code)
else:
#select_code = self.select_code()
select_code = self.result_code
if self.type.is_pyobject:
rhs.make_owned_reference(code)
......@@ -1670,7 +1685,8 @@ class AttributeNode(ExprNode):
code.putln(
"%s = %s;" % (
select_code,
rhs.result_code))
rhs.result_as(self.ctype())))
#rhs.result_code))
rhs.generate_post_assignment_code(code)
self.obj.generate_disposal_code(code)
......@@ -1704,6 +1720,7 @@ class SequenceNode(ExprNode):
# Contains common code for performing sequence unpacking.
#
# args [ExprNode]
# iterator ExprNode
# unpacked_items [ExprNode] or None
# coerced_unpacked_items [ExprNode] or None
......@@ -1725,11 +1742,11 @@ class SequenceNode(ExprNode):
self.is_temp = 1
def analyse_target_types(self, env):
self.unpacked_items = [] # PyTempNode(self.pos, env)
self.iterator = PyTempNode(self.pos, env)
self.unpacked_items = []
self.coerced_unpacked_items = []
for arg in self.args:
arg.analyse_target_types(env)
#node = CloneNode(self.unpacked_item)
unpacked_item = PyTempNode(self.pos, env)
coerced_unpacked_item = unpacked_item.coerce_to(arg.type, env)
self.unpacked_items.append(unpacked_item)
......@@ -1737,27 +1754,39 @@ class SequenceNode(ExprNode):
self.type = py_object_type
env.use_utility_code(unpacking_utility_code)
def allocate_target_temps(self, env):
for arg in self.args:
arg.allocate_target_temps(env)
for node in self.coerced_unpacked_items:
def allocate_target_temps(self, env, rhs):
self.iterator.allocate_temps(env)
if rhs:
rhs.release_temp(env)
for arg, node in zip(self.args, self.coerced_unpacked_items):
node.allocate_temps(env)
def release_target_temp(self, env):
for arg in self.args:
arg.release_target_temp(env)
for node in self.coerced_unpacked_items:
node.release_temp(env)
arg.allocate_target_temps(env, node)
#arg.release_target_temp(env)
#node.release_temp(env)
self.iterator.release_temp(env)
# def release_target_temp(self, env):
# #for arg in self.args:
# # arg.release_target_temp(env)
# #for node in self.coerced_unpacked_items:
# # node.release_temp(env)
# self.iterator.release_temp(env)
def generate_result_code(self, code):
self.generate_operation_code(code)
def generate_assignment_code(self, rhs, code):
code.putln(
"%s = PyObject_GetIter(%s); if (!%s) %s" % (
self.iterator.result_code,
rhs.py_result(),
self.iterator.result_code,
code.error_goto(self.pos)))
rhs.generate_disposal_code(code)
for i in range(len(self.args)):
item = self.unpacked_items[i]
unpack_code = "__Pyx_UnpackItem(%s, %s)" % (
rhs.py_result(),
i)
unpack_code = "__Pyx_UnpackItem(%s)" % (
self.iterator.py_result())
code.putln(
"%s = %s; if (!%s) %s" % (
item.result_code,
......@@ -1768,14 +1797,13 @@ class SequenceNode(ExprNode):
value_node.generate_evaluation_code(code)
self.args[i].generate_assignment_code(value_node, code)
code.putln(
"if (__Pyx_EndUnpack(%s, %s) < 0) %s" % (
rhs.py_result(),
len(self.args),
"if (__Pyx_EndUnpack(%s) < 0) %s" % (
self.iterator.py_result(),
code.error_goto(self.pos)))
if debug_disposal_code:
print "UnpackNode.generate_assignment_code:"
print "...generating disposal code for", rhs
rhs.generate_disposal_code(code)
self.iterator.generate_disposal_code(code)
class TupleNode(SequenceNode):
......@@ -2560,10 +2588,13 @@ class CmpNode:
return 1
if type1.is_pyobject: # type2 will be, too
return 1
elif type1.is_ptr:
elif type1.is_ptr or type1.is_array:
return type1.is_null_ptr or type2.is_null_ptr \
or type1.same_as(type2)
elif (type1.is_numeric and type2.is_numeric
or ((type2.is_ptr or type2.is_array)
and type1.base_type.same_as(type2.base_type))
elif ((type1.is_numeric and type2.is_numeric
or type1.is_enum and (type1 is type2 or type2.is_int)
or type1.is_int and type2.is_enum)
and op not in ('is', 'is_not')):
return 1
else:
......@@ -2819,9 +2850,6 @@ class CastNode(CoercionNode):
self.type = new_type
def calculate_result_code(self):
#return "((%s)%s)" % (
# self.type.declaration_code(""),
# self.arg.result)
return self.arg.result_as(self.type)
def generate_result_code(self, code):
......@@ -2904,12 +2932,14 @@ class CoerceFromPyTypeNode(CoercionNode):
"Obtaining char * from temporary Python value")
def generate_result_code(self, code):
#opnd = self.arg.py_result()
function = self.type.from_py_function
code.putln('%s = %s(%s); if (PyErr_Occurred()) %s' % (
operand = self.arg.py_result()
rhs = "%s(%s)" % (function, operand)
if self.type.is_enum:
rhs = typecast(self.type, c_long_type, rhs)
code.putln('%s = %s; if (PyErr_Occurred()) %s' % (
self.result_code,
function,
self.arg.py_result(),
rhs,
code.error_goto(self.pos)))
......@@ -2995,8 +3025,10 @@ class CloneNode(CoercionNode):
#
#------------------------------------------------------------------------------------
get_name_utility_code = \
get_name_utility_code = [
"""
static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/
""","""
static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
PyObject *result;
result = PyObject_GetAttrString(dict, name);
......@@ -3004,10 +3036,12 @@ static PyObject *__Pyx_GetName(PyObject *dict, char *name) {
PyErr_SetString(PyExc_NameError, name);
return result;
}
"""
"""]
get_name_interned_utility_code = \
get_name_interned_utility_code = [
"""
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/
""","""
static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyObject *result;
result = PyObject_GetAttr(dict, name);
......@@ -3015,12 +3049,14 @@ static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name) {
PyErr_SetObject(PyExc_NameError, name);
return result;
}
"""
"""]
#------------------------------------------------------------------------------------
import_utility_code = \
import_utility_code = [
"""
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
""","""
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list) {
PyObject *__import__ = 0;
PyObject *empty_list = 0;
......@@ -3056,12 +3092,14 @@ bad:
""" % {
"BUILTINS": Naming.builtins_cname,
"GLOBALS": Naming.module_cname,
}
}]
#------------------------------------------------------------------------------------
get_exception_utility_code = \
get_exception_utility_code = [
"""
static PyObject *__Pyx_GetExcValue(void); /*proto*/
""","""
static PyObject *__Pyx_GetExcValue(void) {
PyObject *type = 0, *value = 0, *tb = 0;
PyObject *result = 0;
......@@ -3091,41 +3129,48 @@ bad:
Py_XDECREF(tb);
return result;
}
"""
"""]
#------------------------------------------------------------------------------------
unpacking_utility_code = \
unpacking_utility_code = [
"""
static PyObject *__Pyx_UnpackItem(PyObject *); /*proto*/
static int __Pyx_EndUnpack(PyObject *); /*proto*/
""","""
static void __Pyx_UnpackError(void) {
PyErr_SetString(PyExc_ValueError, "unpack sequence of wrong size");
}
static PyObject *__Pyx_UnpackItem(PyObject *seq, int i) {
PyObject *item;
if (!(item = PySequence_GetItem(seq, i))) {
if (PyErr_ExceptionMatches(PyExc_IndexError))
__Pyx_UnpackError();
}
return item;
static PyObject *__Pyx_UnpackItem(PyObject *iter) {
PyObject *item;
if (!(item = PyIter_Next(iter))) {
if (!PyErr_Occurred())
__Pyx_UnpackError();
}
return item;
}
static int __Pyx_EndUnpack(PyObject *seq, int i) {
PyObject *item;
if (item = PySequence_GetItem(seq, i)) {
Py_DECREF(item);
__Pyx_UnpackError();
return -1;
}
PyErr_Clear();
return 0;
static int __Pyx_EndUnpack(PyObject *iter) {
PyObject *item;
if ((item = PyIter_Next(iter))) {
Py_DECREF(item);
__Pyx_UnpackError();
return -1;
}
else if (!PyErr_Occurred())
return 0;
else
return -1;
}
"""
"""]
#------------------------------------------------------------------------------------
type_test_utility_code = \
type_test_utility_code = [
"""
static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
""","""
static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
if (!type) {
PyErr_Format(PyExc_SystemError, "Missing type object");
......@@ -3137,12 +3182,14 @@ static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type) {
obj->ob_type->tp_name, type->tp_name);
return 0;
}
"""
"""]
#------------------------------------------------------------------------------------
create_class_utility_code = \
create_class_utility_code = [
"""
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
""","""
static PyObject *__Pyx_CreateClass(
PyObject *bases, PyObject *dict, PyObject *name, char *modname)
{
......@@ -3159,6 +3206,6 @@ bad:
Py_XDECREF(py_modname);
return result;
}
"""
"""]
#------------------------------------------------------------------------------------
#
# 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 @@
# Pyrex - Parse tree nodes
#
import os, string, sys, time
import string, sys
import Code
from Errors import error, InternalError
......@@ -11,8 +11,6 @@ import PyrexTypes
from PyrexTypes import py_object_type, error_type, CTypedefType
from Symtab import ModuleScope, LocalScope, \
StructOrUnionScope, PyClassScope, CClassScope
import TypeSlots
import Version
from Pyrex.Utils import open_new_file, replace_suffix
import Options
......@@ -95,1214 +93,6 @@ class BlockNode:
for entry in entries:
code.putln(
"static PyObject *%s;" % entry.pystring_cname)
class ModuleNode(Node, BlockNode):
# doc string or None
# body StatListNode
def analyse_declarations(self, env):
env.doc = self.doc
self.body.analyse_declarations(env)
def process_implementation(self, env, result):
self.analyse_declarations(env)
env.check_c_classes()
self.body.analyse_expressions(env)
env.return_type = PyrexTypes.c_void_type
self.generate_c_code(env, result)
self.generate_h_code(env, result)
def generate_h_code(self, env, result):
public_vars_and_funcs = []
public_extension_types = []
for entry in env.var_entries:
if entry.visibility == 'public':
public_vars_and_funcs.append(entry)
for entry in env.cfunc_entries:
if entry.visibility == 'public':
public_vars_and_funcs.append(entry)
for entry in env.c_class_entries:
if entry.visibility == 'public':
public_extension_types.append(entry)
if public_vars_and_funcs or public_extension_types:
result.h_file = replace_suffix(result.c_file, ".h")
result.i_file = replace_suffix(result.c_file, ".pxi")
h_code = Code.CCodeWriter(result.h_file)
i_code = Code.PyrexCodeWriter(result.i_file)
self.generate_extern_c_macro_definition(h_code)
for entry in public_vars_and_funcs:
h_code.putln("%s %s;" % (
Naming.extern_c_macro,
entry.type.declaration_code(
entry.cname, dll_linkage = "DL_IMPORT")))
i_code.putln("cdef extern %s" %
entry.type.declaration_code(entry.cname, pyrex = 1))
for entry in public_extension_types:
self.generate_cclass_header_code(entry.type, h_code)
self.generate_cclass_include_code(entry.type, i_code)
h_code.putln("PyMODINIT_FUNC init%s(void);" % env.module_name)
def generate_cclass_header_code(self, type, h_code):
#h_code.putln("extern DL_IMPORT(PyTypeObject) %s;" % type.typeobj_cname)
h_code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
Naming.extern_c_macro,
type.typeobj_cname))
self.generate_obj_struct_definition(type, h_code)
def generate_cclass_include_code(self, type, i_code):
i_code.putln("cdef extern class %s.%s:" % (
type.module_name, type.name))
i_code.indent()
var_entries = type.scope.var_entries
if var_entries:
for entry in var_entries:
i_code.putln("cdef %s" %
entry.type.declaration_code(entry.cname, pyrex = 1))
else:
i_code.putln("pass")
i_code.dedent()
def generate_c_code(self, env, result):
modules = []
self.find_referenced_modules(env, modules, {})
code = Code.CCodeWriter(result.c_file)
code.init_labels()
self.generate_module_preamble(env, modules, code)
for module in modules:
self.generate_declarations_for_module(module, code,
definition = module is env)
code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name)
self.generate_const_definitions(env, code)
self.generate_interned_name_decls(env, code)
self.generate_py_string_decls(env, code)
self.body.generate_function_definitions(env, code)
self.generate_interned_name_table(env, code)
self.generate_py_string_table(env, code)
self.generate_typeobj_definitions(env, code)
self.generate_method_table(env, code)
self.generate_filename_init_prototype(code)
self.generate_module_init_func(modules[:-1], env, code)
self.generate_filename_table(code)
self.generate_utility_functions(env, code)
result.c_file_generated = 1
def find_referenced_modules(self, env, module_list, modules_seen):
if env not in modules_seen:
modules_seen[env] = 1
for imported_module in env.cimported_modules:
self.find_referenced_modules(imported_module, module_list, modules_seen)
module_list.append(env)
def generate_module_preamble(self, env, cimported_modules, code):
code.putln('/* Generated by Pyrex %s on %s */' % (
Version.version, time.asctime()))
code.putln('')
for filename in env.python_include_files:
code.putln('#include "%s"' % filename)
code.putln("#ifndef PY_LONG_LONG")
code.putln(" #define PY_LONG_LONG LONG_LONG")
code.putln("#endif")
self.generate_extern_c_macro_definition(code)
code.putln("%s double pow(double, double);" % Naming.extern_c_macro)
self.generate_includes(env, cimported_modules, code)
#for filename in env.include_files:
# code.putln('#include "%s"' % filename)
code.putln('')
code.put(utility_function_predeclarations)
if Options.intern_names:
code.putln(get_name_interned_predeclaration)
else:
code.putln(get_name_predeclaration)
code.putln('')
code.putln('static PyObject *%s;' % env.module_cname)
code.putln('static PyObject *%s;' % Naming.builtins_cname)
code.putln('static int %s;' % Naming.lineno_cname)
code.putln('static char *%s;' % Naming.filename_cname)
code.putln('static char **%s;' % Naming.filetable_cname)
if env.doc:
code.putln('')
code.putln('static char %s[] = "%s";' % (env.doc_cname, env.doc))
def generate_extern_c_macro_definition(self, code):
name = Naming.extern_c_macro
code.putln("#ifdef __cplusplus")
code.putln('#define %s extern "C"' % name)
code.putln("#else")
code.putln("#define %s extern" % name)
code.putln("#endif")
def generate_includes(self, env, cimported_modules, code):
includes = env.include_files[:]
for module in cimported_modules:
for filename in module.include_files:
if filename not in includes:
includes.append(filename)
for filename in includes:
code.putln('#include "%s"' % filename)
def generate_filename_table(self, code):
code.putln("")
code.putln("static char *%s[] = {" % Naming.filenames_cname)
if code.filename_list:
for filename in code.filename_list:
filename = os.path.basename(filename)
escaped_filename = filename.replace("\\", "\\\\").replace('"', r'\"')
code.putln('"%s",' %
escaped_filename)
else:
# Some C compilers don't like an empty array
code.putln("0")
code.putln("};")
def generate_declarations_for_module(self, env, code, definition):
code.putln("")
code.putln("/* Declarations from %s */" % env.qualified_name)
self.generate_type_predeclarations(env, code)
self.generate_type_definitions(env, code)
self.generate_global_declarations(env, code, definition)
self.generate_cfunction_predeclarations(env, code)
def generate_type_predeclarations(self, env, code):
pass
def generate_type_definitions(self, env, code):
# Generate definitions of structs/unions/enums.
for entry in env.sue_entries:
if not entry.in_cinclude:
type = entry.type
if type.is_struct_or_union:
self.generate_struct_union_definition(entry, code)
else:
self.generate_enum_definition(entry, code)
# Generate extension type object struct definitions.
for entry in env.c_class_entries:
if not entry.in_cinclude:
self.generate_typeobject_predeclaration(entry, code)
self.generate_obj_struct_definition(entry.type, code)
self.generate_exttype_vtable_struct(entry, code)
self.generate_exttype_vtabptr_declaration(entry, code)
def sue_header_footer(self, type, kind, name):
if type.typedef_flag:
header = "typedef %s {" % kind
footer = "} %s;" % name
else:
header = "%s %s {" % (kind, name)
footer = "};"
return header, footer
def generate_struct_union_definition(self, entry, code):
type = entry.type
scope = type.scope
if scope:
header, footer = \
self.sue_header_footer(type, type.kind, type.cname)
code.putln("")
code.putln(header)
var_entries = scope.var_entries
if not var_entries:
error(entry.pos,
"Empty struct or union definition not allowed outside a"
" 'cdef extern from' block")
for attr in var_entries:
code.putln(
"%s;" %
attr.type.declaration_code(attr.cname))
code.putln(footer)
def generate_enum_definition(self, entry, code):
type = entry.type
name = entry.cname or entry.name or ""
header, footer = \
self.sue_header_footer(type, "enum", name)
code.putln("")
code.putln(header)
enum_values = entry.enum_values
if not enum_values:
error(entry.pos,
"Empty enum definition not allowed outside a"
" 'cdef extern from' block")
for value_entry in enum_values:
if value_entry.value == value_entry.name:
code.putln(
"%s," %
value_entry.cname)
else:
code.putln(
"%s = %s," % (
value_entry.cname,
value_entry.value))
code.putln(footer)
def generate_typeobject_predeclaration(self, entry, code):
code.putln("")
name = entry.type.typeobj_cname
if name:
if entry.visibility == 'extern' and not entry.in_cinclude:
code.putln("%s DL_IMPORT(PyTypeObject) %s;" % (
Naming.extern_c_macro,
name))
elif entry.visibility == 'public':
#code.putln("DL_EXPORT(PyTypeObject) %s;" % name)
code.putln("%s DL_EXPORT(PyTypeObject) %s;" % (
Naming.extern_c_macro,
name))
# ??? Do we really need the rest of this? ???
#else:
# code.putln("staticforward PyTypeObject %s;" % name)
def generate_exttype_vtable_struct(self, entry, code):
# Generate struct declaration for an extension type's vtable.
type = entry.type
scope = type.scope
if type.vtabstruct_cname:
code.putln("")
code.putln(
"struct %s {" %
type.vtabstruct_cname)
if type.base_type and type.base_type.vtabstruct_cname:
code.putln("struct %s %s;" % (
type.base_type.vtabstruct_cname,
Naming.obj_base_cname))
for method_entry in scope.cfunc_entries:
if not method_entry.is_inherited:
code.putln(
"%s;" % method_entry.type.declaration_code("(*%s)" % method_entry.name))
code.putln(
"};")
def generate_exttype_vtabptr_declaration(self, entry, code):
# Generate declaration of pointer to an extension type's vtable.
type = entry.type
if type.vtabptr_cname:
code.putln("static struct %s *%s;" % (
type.vtabstruct_cname,
type.vtabptr_cname))
def generate_obj_struct_definition(self, type, code):
# Generate object struct definition for an
# extension type.
if not type.scope:
return # Forward declared but never defined
header, footer = \
self.sue_header_footer(type, "struct", type.objstruct_cname)
code.putln("")
code.putln(header)
base_type = type.base_type
if base_type:
code.putln(
"%s%s %s;" % (
("struct ", "")[base_type.typedef_flag],
base_type.objstruct_cname,
Naming.obj_base_cname))
else:
code.putln(
"PyObject_HEAD")
if type.vtabslot_cname and not (type.base_type and type.base_type.vtabslot_cname):
code.putln(
"struct %s *%s;" % (
type.vtabstruct_cname,
type.vtabslot_cname))
for attr in type.scope.var_entries:
code.putln(
"%s;" %
attr.type.declaration_code(attr.cname))
code.putln(footer)
def generate_global_declarations(self, env, code, definition):
code.putln("")
for entry in env.c_class_entries:
code.putln("static PyTypeObject *%s = 0;" %
entry.type.typeptr_cname)
code.put_var_declarations(env.var_entries, static = 1,
dll_linkage = "DL_EXPORT", definition = definition)
code.put_var_declarations(env.default_entries, static = 1)
def generate_cfunction_predeclarations(self, env, code):
for entry in env.cfunc_entries:
if not entry.in_cinclude:
if entry.visibility == 'public':
dll_linkage = "DL_EXPORT"
else:
dll_linkage = None
header = entry.type.declaration_code(entry.cname,
dll_linkage = dll_linkage)
if entry.visibility <> 'private':
storage_class = "%s " % Naming.extern_c_macro
else:
storage_class = "static "
code.putln("%s%s; /*proto*/" % (
storage_class,
header))
def generate_typeobj_definitions(self, env, code):
full_module_name = env.qualified_name
for entry in env.c_class_entries:
#print "generate_typeobj_definitions:", entry.name
#print "...visibility =", entry.visibility
if entry.visibility <> 'extern':
type = entry.type
scope = type.scope
if scope: # could be None if there was an error
self.generate_exttype_vtable(scope, code)
self.generate_new_function(scope, code)
self.generate_dealloc_function(scope, code)
self.generate_traverse_function(scope, code)
self.generate_clear_function(scope, code)
if scope.defines_any(["__getitem__"]):
self.generate_getitem_int_function(scope, code)
if scope.defines_any(["__setitem__", "__delitem__"]):
self.generate_ass_subscript_function(scope, code)
if scope.defines_any(["__setslice__", "__delslice__"]):
self.generate_ass_slice_function(scope, code)
if scope.defines_any(["__getattr__"]):
self.generate_getattro_function(scope, code)
if scope.defines_any(["__setattr__", "__delattr__"]):
self.generate_setattro_function(scope, code)
if scope.defines_any(["__get__"]):
self.generate_descr_get_function(scope, code)
if scope.defines_any(["__set__", "__delete__"]):
self.generate_descr_set_function(scope, code)
self.generate_property_accessors(scope, code)
self.generate_method_table(scope, code)
self.generate_member_table(scope, code)
self.generate_getset_table(scope, code)
self.generate_typeobj_definition(full_module_name, entry, code)
def generate_exttype_vtable(self, scope, code):
# Generate the definition of an extension type's vtable.
type = scope.parent_type
if type.vtable_cname:
code.putln("static struct %s %s;" % (
type.vtabstruct_cname,
type.vtable_cname))
def generate_self_cast(self, scope, code):
type = scope.parent_type
code.putln(
"%s = (%s)o;" % (
type.declaration_code("p"),
type.declaration_code("")))
def generate_new_function(self, scope, code):
base_type = scope.parent_type.base_type
code.putln("")
code.putln(
"static PyObject *%s(PyTypeObject *t, PyObject *a, PyObject *k) {"
% scope.mangle_internal("tp_new"))
if base_type:
code.putln(
"PyObject *o = %s->tp_new(t, a, k);" %
base_type.typeptr_cname)
else:
code.putln(
"PyObject *o = (*t->tp_alloc)(t, 0);")
self.generate_self_cast(scope, code)
type = scope.parent_type
if type.vtabslot_cname:
code.putln("*(struct %s **)&p->%s = %s;" % (
type.vtabstruct_cname,
type.vtabslot_cname,
type.vtabptr_cname))
for entry in scope.var_entries:
if entry.type.is_pyobject:
code.put_init_var_to_py_none(entry, "p->%s")
entry = scope.lookup_here("__new__")
if entry:
code.putln(
"if (%s(o, a, k) < 0) {" %
entry.func_cname)
code.put_decref_clear("o", py_object_type);
code.putln(
"}")
code.putln(
"return o;")
code.putln(
"}")
def generate_dealloc_function(self, scope, code):
base_type = scope.parent_type.base_type
code.putln("")
code.putln(
"static void %s(PyObject *o) {"
% scope.mangle_internal("tp_dealloc"))
self.generate_self_cast(scope, code)
self.generate_usr_dealloc_call(scope, code)
for entry in scope.var_entries:
if entry.type.is_pyobject:
code.put_xdecref("p->%s" % entry.cname, entry.type)
if base_type:
code.putln(
"%s->tp_dealloc(o);" %
base_type.typeptr_cname)
else:
code.putln(
"(*o->ob_type->tp_free)(o);")
code.putln(
"}")
def generate_usr_dealloc_call(self, scope, code):
entry = scope.lookup_here("__dealloc__")
if entry:
code.putln(
"{")
code.putln(
"PyObject *etype, *eval, *etb;")
code.putln(
"PyErr_Fetch(&etype, &eval, &etb);")
code.putln(
"++o->ob_refcnt;")
code.putln(
"%s(o);" %
entry.func_cname)
code.putln(
"if (PyErr_Occurred()) PyErr_WriteUnraisable(o);")
code.putln(
"--o->ob_refcnt;")
code.putln(
"PyErr_Restore(etype, eval, etb);")
code.putln(
"}")
def generate_traverse_function(self, scope, code):
base_type = scope.parent_type.base_type
code.putln("")
code.putln(
"static int %s(PyObject *o, visitproc v, void *a) {"
% scope.mangle_internal("tp_traverse"))
code.putln(
"int e;")
self.generate_self_cast(scope, code)
if base_type:
code.putln(
"e = %s->tp_traverse(o, v, a); if (e) return e;" %
base_type.typeptr_cname)
for entry in scope.var_entries:
if entry.type.is_pyobject:
var_code = "p->%s" % entry.cname
code.putln(
"if (%s) {"
% var_code)
if entry.type.is_extension_type:
var_code = "((PyObject*)%s)" % var_code
code.putln(
"e = (*v)(%s, a); if (e) return e;"
% var_code)
code.putln(
"}")
code.putln(
"return 0;")
code.putln(
"}")
def generate_clear_function(self, scope, code):
base_type = scope.parent_type.base_type
code.putln("")
code.putln(
"static int %s(PyObject *o) {"
% scope.mangle_internal("tp_clear"))
self.generate_self_cast(scope, code)
if base_type:
code.putln(
"%s->tp_clear(o);" %
base_type.typeptr_cname)
for entry in scope.var_entries:
if entry.type.is_pyobject:
name = "p->%s" % entry.cname
code.put_xdecref(name, entry.type)
#code.put_init_to_py_none(name)
code.put_init_var_to_py_none(entry, "p->%s")
code.putln(
"return 0;")
code.putln(
"}")
def generate_getitem_int_function(self, scope, code):
# This function is put into the sq_item slot when
# a __getitem__ method is present. It converts its
# argument to a Python integer and calls mp_subscript.
code.putln(
"static PyObject *%s(PyObject *o, int i) {" %
scope.mangle_internal("sq_item"))
code.putln(
"PyObject *r;")
code.putln(
"PyObject *x = PyInt_FromLong(i); if(!x) return 0;")
code.putln(
"r = o->ob_type->tp_as_mapping->mp_subscript(o, x);")
code.putln(
"Py_DECREF(x);")
code.putln(
"return r;")
code.putln(
"}")
def generate_ass_subscript_function(self, scope, code):
# Setting and deleting an item are both done through
# the ass_subscript method, so we dispatch to user's __setitem__
# or __delitem__, or raise an exception.
base_type = scope.parent_type.base_type
set_entry = scope.lookup_here("__setitem__")
del_entry = scope.lookup_here("__delitem__")
code.putln("")
code.putln(
"static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
scope.mangle_internal("mp_ass_subscript"))
code.putln(
"if (v) {")
if set_entry:
code.putln(
"return %s(o, i, v);" %
set_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "Subscript assignment not supported by %s", o->ob_type->tp_name);')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"else {")
if del_entry:
code.putln(
"return %s(o, i);" %
del_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, "tp_as_mapping", "mp_ass_subscript", "o, i, v", code)
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "Subscript deletion not supported by %s", o->ob_type->tp_name);')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"}")
def generate_guarded_basetype_call(
self, base_type, substructure, slot, args, code):
if base_type:
base_tpname = base_type.typeptr_cname
if substructure:
code.putln(
"if (%s->%s && %s->%s->%s)" % (
base_tpname, substructure, base_tpname, substructure, slot))
code.putln(
" return %s->%s->%s(%s);" % (
base_tpname, substructure, slot, args))
else:
code.putln(
"if (%s->%s)" % (
base_tpname, slot))
code.putln(
" return %s->%s(%s);" % (
base_tpname, slot, args))
def generate_ass_slice_function(self, scope, code):
# Setting and deleting a slice are both done through
# the ass_slice method, so we dispatch to user's __setslice__
# or __delslice__, or raise an exception.
base_type = scope.parent_type.base_type
set_entry = scope.lookup_here("__setslice__")
del_entry = scope.lookup_here("__delslice__")
code.putln("")
code.putln(
"static int %s(PyObject *o, int i, int j, PyObject *v) {" %
scope.mangle_internal("sq_ass_slice"))
code.putln(
"if (v) {")
if set_entry:
code.putln(
"return %s(o, i, j, v);" %
set_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "2-element slice assignment not supported by %s", o->ob_type->tp_name);')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"else {")
if del_entry:
code.putln(
"return %s(o, i, j);" %
del_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, "tp_as_sequence", "sq_ass_slice", "o, i, j, v", code)
code.putln(
"PyErr_Format(PyExc_NotImplementedError,")
code.putln(
' "2-element slice deletion not supported by %s", o->ob_type->tp_name);')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"}")
def generate_getattro_function(self, scope, code):
# First try to get the attribute using PyObject_GenericGetAttr.
# If that raises an AttributeError, call the user's __getattr__
# method.
entry = scope.lookup_here("__getattr__")
code.putln("")
code.putln(
"static PyObject *%s(PyObject *o, PyObject *n) {"
% scope.mangle_internal("tp_getattro"))
code.putln(
"PyObject *v = PyObject_GenericGetAttr(o, n);")
code.putln(
"if (!v && PyErr_ExceptionMatches(PyExc_AttributeError)) {")
code.putln(
"PyErr_Clear();")
code.putln(
"v = %s(o, n);" %
entry.func_cname)
code.putln(
"}")
code.putln(
"return v;")
code.putln(
"}")
def generate_setattro_function(self, scope, code):
# Setting and deleting an attribute are both done through
# the setattro method, so we dispatch to user's __setattr__
# or __delattr__ or fall back on PyObject_GenericSetAttr.
base_type = scope.parent_type.base_type
set_entry = scope.lookup_here("__setattr__")
del_entry = scope.lookup_here("__delattr__")
code.putln("")
code.putln(
"static int %s(PyObject *o, PyObject *n, PyObject *v) {" %
scope.mangle_internal("tp_setattro"))
code.putln(
"if (v) {")
if set_entry:
code.putln(
"return %s(o, n, v);" %
set_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, None, "tp_setattro", "o, n, v", code)
code.putln(
"return PyObject_GenericSetAttr(o, n, v);")
code.putln(
"}")
code.putln(
"else {")
if del_entry:
code.putln(
"return %s(o, n);" %
del_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, None, "tp_setattro", "o, n, v", code)
code.putln(
"return PyObject_GenericSetAttr(o, n, 0);")
code.putln(
"}")
code.putln(
"}")
def generate_descr_get_function(self, scope, code):
# The __get__ function of a descriptor object can be
# called with NULL for the second or third arguments
# under some circumstances, so we replace them with
# None in that case.
user_get_entry = scope.lookup_here("__get__")
code.putln("")
code.putln(
"static PyObject *%s(PyObject *o, PyObject *i, PyObject *c) {" %
scope.mangle_internal("tp_descr_get"))
code.putln(
"PyObject *r = 0;")
code.putln(
"if (!i) i = Py_None;")
code.putln(
"if (!c) c = Py_None;")
#code.put_incref("i", py_object_type)
#code.put_incref("c", py_object_type)
code.putln(
"r = %s(o, i, c);" %
user_get_entry.func_cname)
#code.put_decref("i", py_object_type)
#code.put_decref("c", py_object_type)
code.putln(
"return r;")
code.putln(
"}")
def generate_descr_set_function(self, scope, code):
# Setting and deleting are both done through the __set__
# method of a descriptor, so we dispatch to user's __set__
# or __delete__ or raise an exception.
base_type = scope.parent_type.base_type
user_set_entry = scope.lookup_here("__set__")
user_del_entry = scope.lookup_here("__delete__")
code.putln("")
code.putln(
"static int %s(PyObject *o, PyObject *i, PyObject *v) {" %
scope.mangle_internal("tp_descr_set"))
code.putln(
"if (v) {")
if user_set_entry:
code.putln(
"return %s(o, i, v);" %
user_set_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, None, "tp_descr_set", "o, i, v", code)
code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"else {")
if user_del_entry:
code.putln(
"return %s(o, i);" %
user_del_entry.func_cname)
else:
self.generate_guarded_basetype_call(
base_type, None, "tp_descr_set", "o, i, v", code)
code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__delete__");')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"}")
def generate_property_accessors(self, cclass_scope, code):
for entry in cclass_scope.property_entries:
property_scope = entry.scope
if property_scope.defines_any(["__get__"]):
self.generate_property_get_function(entry, code)
if property_scope.defines_any(["__set__", "__del__"]):
self.generate_property_set_function(entry, code)
def generate_property_get_function(self, property_entry, code):
property_scope = property_entry.scope
property_entry.getter_cname = property_scope.parent_scope.mangle(
Naming.prop_get_prefix, property_entry.name)
get_entry = property_scope.lookup_here("__get__")
code.putln("")
code.putln(
"static PyObject *%s(PyObject *o, void *x) {" %
property_entry.getter_cname)
code.putln(
"return %s(o);" %
get_entry.func_cname)
code.putln(
"}")
def generate_property_set_function(self, property_entry, code):
property_scope = property_entry.scope
property_entry.setter_cname = property_scope.parent_scope.mangle(
Naming.prop_set_prefix, property_entry.name)
set_entry = property_scope.lookup_here("__set__")
del_entry = property_scope.lookup_here("__del__")
code.putln("")
code.putln(
"static int %s(PyObject *o, PyObject *v, void *x) {" %
property_entry.setter_cname)
code.putln(
"if (v) {")
if set_entry:
code.putln(
"return %s(o, v);" %
set_entry.func_cname)
else:
code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__set__");')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"else {")
if del_entry:
code.putln(
"return %s(o);" %
del_entry.func_cname)
else:
code.putln(
'PyErr_SetString(PyExc_NotImplementedError, "__del__");')
code.putln(
"return -1;")
code.putln(
"}")
code.putln(
"}")
def generate_typeobj_definition(self, modname, entry, code):
type = entry.type
scope = type.scope
for suite in TypeSlots.substructures:
suite.generate_substructure(scope, code)
code.putln("")
if entry.visibility == 'public':
header = "DL_EXPORT(PyTypeObject) %s = {"
else:
#header = "statichere PyTypeObject %s = {"
header = "PyTypeObject %s = {"
#code.putln(header % scope.parent_type.typeobj_cname)
code.putln(header % type.typeobj_cname)
code.putln(
"PyObject_HEAD_INIT(0)")
code.putln(
"0, /*ob_size*/")
code.putln(
'"%s.%s", /*tp_name*/' % (
modname, scope.class_name))
if type.typedef_flag:
objstruct = type.objstruct_cname
else:
#objstruct = "struct %s" % scope.parent_type.objstruct_cname
objstruct = "struct %s" % type.objstruct_cname
code.putln(
"sizeof(%s), /*tp_basicsize*/" %
objstruct)
code.putln(
"0, /*tp_itemsize*/")
for slot in TypeSlots.slot_table:
slot.generate(scope, code)
code.putln(
"};")
def generate_method_table(self, env, code):
code.putln("")
code.putln(
"static struct PyMethodDef %s[] = {" %
env.method_table_cname)
for entry in env.pyfunc_entries:
code.put_pymethoddef(entry, ",")
code.putln(
"{0, 0, 0, 0}")
code.putln(
"};")
def generate_member_table(self, env, code):
#print "ModuleNode.generate_member_table: scope =", env ###
if env.public_attr_entries:
code.putln("")
code.putln(
"static struct PyMemberDef %s[] = {" %
env.member_table_cname)
type = env.parent_type
if type.typedef_flag:
objstruct = type.objstruct_cname
else:
objstruct = "struct %s" % type.objstruct_cname
for entry in env.public_attr_entries:
type_code = entry.type.pymemberdef_typecode
if entry.visibility == 'readonly':
flags = "READONLY"
else:
flags = "0"
code.putln('{"%s", %s, %s, %s, 0},' % (
entry.name,
type_code,
"offsetof(%s, %s)" % (objstruct, entry.name),
flags))
code.putln(
"{0, 0, 0, 0, 0}")
code.putln(
"};")
def generate_getset_table(self, env, code):
if env.property_entries:
code.putln("")
code.putln(
"static struct PyGetSetDef %s[] = {" %
env.getset_table_cname)
for entry in env.property_entries:
code.putln(
'{"%s", %s, %s, %s, 0},' % (
entry.name,
entry.getter_cname or "0",
entry.setter_cname or "0",
entry.doc_cname or "0"))
code.putln(
"{0, 0, 0, 0, 0}")
code.putln(
"};")
def generate_interned_name_table(self, env, code):
items = env.intern_map.items()
if items:
items.sort()
code.putln("")
code.putln(
"static __Pyx_InternTabEntry %s[] = {" %
Naming.intern_tab_cname)
for (name, cname) in items:
code.putln(
'{&%s, "%s"},' % (
cname,
name))
code.putln(
"{0, 0}")
code.putln(
"};")
def generate_py_string_table(self, env, code):
entries = env.all_pystring_entries
if entries:
code.putln("")
code.putln(
"static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname)
for entry in entries:
code.putln(
"{&%s, %s, sizeof(%s)}," % (
entry.pystring_cname,
entry.cname,
entry.cname))
code.putln(
"{0, 0, 0}")
code.putln(
"};")
def generate_filename_init_prototype(self, code):
code.putln("");
code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
def generate_module_init_func(self, imported_modules, env, code):
code.putln("")
header = "PyMODINIT_FUNC init%s(void)" % env.module_name
code.putln("%s; /*proto*/" % header)
code.putln("%s {" % header)
code.put_var_declarations(env.temp_entries)
#code.putln("/*--- Libary function declarations ---*/")
env.generate_library_function_declarations(code)
self.generate_filename_init_call(code)
#code.putln("/*--- Module creation code ---*/")
self.generate_module_creation_code(env, code)
#code.putln("/*--- Intern code ---*/")
self.generate_intern_code(env, code)
#code.putln("/*--- String init code ---*/")
self.generate_string_init_code(env, code)
#code.putln("/*--- Global init code ---*/")
self.generate_global_init_code(env, code)
#code.putln("/*--- Type import code ---*/")
for module in imported_modules:
self.generate_type_import_code_for_module(module, env, code)
#code.putln("/*--- Type init code ---*/")
self.generate_type_init_code(env, code)
#code.putln("/*--- Execution code ---*/")
self.body.generate_execution_code(code)
code.putln("return;")
code.put_label(code.error_label)
code.put_var_xdecrefs(env.temp_entries)
code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
env.use_utility_code(traceback_utility_code)
code.putln('}')
def generate_filename_init_call(self, code):
code.putln("%s();" % Naming.fileinit_cname)
def generate_module_creation_code(self, env, code):
# Generate code to create the module object and
# install the builtins.
if env.doc:
doc = env.doc_cname
else:
doc = "0"
code.putln(
'%s = Py_InitModule4("%s", %s, %s, 0, PYTHON_API_VERSION);' % (
env.module_cname,
env.module_name,
env.method_table_cname,
doc))
code.putln(
"if (!%s) %s;" % (
env.module_cname,
code.error_goto(self.pos)));
code.putln(
'%s = PyImport_AddModule("__builtin__");' %
Naming.builtins_cname)
code.putln(
"if (!%s) %s;" % (
Naming.builtins_cname,
code.error_goto(self.pos)));
code.putln(
'if (PyObject_SetAttrString(%s, "__builtins__", %s) < 0) %s;' % (
env.module_cname,
Naming.builtins_cname,
code.error_goto(self.pos)))
def generate_intern_code(self, env, code):
if env.intern_map:
env.use_utility_code(init_intern_tab_utility_code);
code.putln(
"if (__Pyx_InternStrings(%s) < 0) %s;" % (
Naming.intern_tab_cname,
code.error_goto(self.pos)))
def generate_string_init_code(self, env, code):
if env.all_pystring_entries:
env.use_utility_code(init_string_tab_utility_code)
code.putln(
"if (__Pyx_InitStrings(%s) < 0) %s;" % (
Naming.stringtab_cname,
code.error_goto(self.pos)))
def generate_global_init_code(self, env, code):
# Generate code to initialise global PyObject *
# variables to None.
for entry in env.var_entries:
if entry.visibility <> 'extern':
if entry.type.is_pyobject:
code.put_init_var_to_py_none(entry)
def generate_type_import_code_for_module(self, module, env, code):
# Generate type import code for all extension types in
# an imported module.
if module.c_class_entries:
for entry in module.c_class_entries:
self.generate_type_import_code(env, entry, code)
def generate_type_init_code(self, env, code):
# Generate type import code for extern extension types
# and type ready code for non-extern ones.
for entry in env.c_class_entries:
if entry.visibility == 'extern':
self.generate_type_import_code(env, entry, code)
else:
self.generate_exttype_vtable_init_code(entry, code)
self.generate_type_ready_code(env, entry, code)
self.generate_typeptr_assignment_code(entry, code)
def use_type_import_utility_code(self, env):
import ExprNodes
env.use_utility_code(type_import_utility_code)
env.use_utility_code(ExprNodes.import_utility_code)
def generate_type_import_code(self, env, entry, code):
# Generate code to import the typeobject of an
# extension type defined in another module, and
# extract its C method table pointer if any.
type = entry.type
if type.typedef_flag:
objstruct = type.objstruct_cname
else:
objstruct = "struct %s" % type.objstruct_cname
code.putln('%s = __Pyx_ImportType("%s", "%s", sizeof(%s)); if (!%s) %s' % (
type.typeptr_cname,
type.module_name,
type.name,
objstruct,
type.typeptr_cname,
code.error_goto(entry.pos)))
self.use_type_import_utility_code(env)
if type.vtabptr_cname:
code.putln(
"if (__Pyx_GetVtable(%s->tp_dict, &%s) < 0) %s" % (
type.typeptr_cname,
type.vtabptr_cname,
code.error_goto(entry.pos)))
env.use_utility_code(get_vtable_utility_code)
def generate_type_ready_code(self, env, entry, code):
# Generate a call to PyType_Ready for an extension
# type defined in this module.
type = entry.type
typeobj_cname = type.typeobj_cname
scope = type.scope
if scope: # could be None if there was an error
if entry.visibility <> 'extern':
for slot in TypeSlots.slot_table:
slot.generate_dynamic_init_code(scope, code)
code.putln(
"if (PyType_Ready(&%s) < 0) %s" % (
typeobj_cname,
code.error_goto(entry.pos)))
if type.vtable_cname:
code.putln(
"if (__Pyx_SetVtable(%s.tp_dict, %s) < 0) %s" % (
typeobj_cname,
type.vtabptr_cname,
code.error_goto(entry.pos)))
env.use_utility_code(set_vtable_utility_code)
code.putln(
'if (PyObject_SetAttrString(%s, "%s", (PyObject *)&%s) < 0) %s' % (
Naming.module_cname,
scope.class_name,
typeobj_cname,
code.error_goto(entry.pos)))
weakref_entry = scope.lookup_here("__weakref__")
if weakref_entry:
if weakref_entry.type is py_object_type:
tp_weaklistoffset = "%s.tp_weaklistoffset" % typeobj_cname
code.putln("if (%s == 0) %s = offsetof(struct %s, %s);" % (
tp_weaklistoffset,
tp_weaklistoffset,
type.objstruct_cname,
weakref_entry.cname))
else:
error(weakref_entry.pos, "__weakref__ slot must be of type 'object'")
def generate_exttype_vtable_init_code(self, entry, code):
# Generate code to initialise the C method table of an
# extension type.
type = entry.type
if type.vtable_cname:
code.putln(
"%s = &%s;" % (
type.vtabptr_cname,
type.vtable_cname))
if type.base_type and type.base_type.vtabptr_cname:
code.putln(
"%s.%s = *%s;" % (
type.vtable_cname,
Naming.obj_base_cname,
type.base_type.vtabptr_cname))
for meth_entry in type.scope.cfunc_entries:
if meth_entry.func_cname:
code.putln(
"*(void **)&%s.%s = (void *)%s;" % (
type.vtable_cname,
meth_entry.cname,
meth_entry.func_cname))
def generate_typeptr_assignment_code(self, entry, code):
# Generate code to initialise the typeptr of an extension
# type defined in this module to point to its type object.
type = entry.type
if type.typeobj_cname:
code.putln(
"%s = &%s;" % (
type.typeptr_cname, type.typeobj_cname))
def generate_utility_functions(self, env, code):
code.putln("")
code.putln("/* Runtime support code */")
code.putln("")
code.putln("static void %s(void) {" % Naming.fileinit_cname)
code.putln("%s = %s;" %
(Naming.filetable_cname, Naming.filenames_cname))
code.putln("}")
for utility_code in env.utility_code_used:
code.put(utility_code)
class StatListNode(Node):
......@@ -1697,8 +487,6 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Top-level constants used by this function
self.generate_interned_name_decls(lenv, code)
self.generate_py_string_decls(lenv, code)
#code.putln("")
#code.put_var_declarations(lenv.const_entries, static = 1)
self.generate_const_definitions(lenv, code)
# ----- Function header
code.putln("")
......@@ -1721,13 +509,12 @@ class FuncDefNode(StatNode, BlockNode):
# ----- Fetch arguments
self.generate_argument_parsing_code(code)
self.generate_argument_increfs(lenv, code)
#self.generate_stararg_getting_code(code)
self.generate_argument_conversion_code(code)
# ----- Initialise local variables
for entry in lenv.var_entries:
if entry.type.is_pyobject and entry.init_to_none:
if entry.type.is_pyobject and entry.init_to_none and entry.used:
code.put_init_var_to_py_none(entry)
# ----- Check types of arguments
# ----- Check and convert arguments
self.generate_argument_conversion_code(code)
self.generate_argument_type_tests(code)
# ----- Function body
self.body.generate_execution_code(code)
......@@ -1743,29 +530,31 @@ class FuncDefNode(StatNode, BlockNode):
val = self.return_type.default_value
if val:
code.putln("%s = %s;" % (Naming.retval_cname, val))
code.putln("goto %s;" % code.return_label)
#code.putln("goto %s;" % code.return_label)
# ----- Error cleanup
code.put_label(code.error_label)
code.put_var_xdecrefs(lenv.temp_entries)
err_val = self.error_value()
exc_check = self.caller_will_check_exceptions()
if err_val is not None or exc_check:
code.putln(
'__Pyx_AddTraceback("%s");' %
self.entry.qualified_name)
if err_val is not None:
if code.error_label in code.labels_used:
code.put_goto(code.return_label)
code.put_label(code.error_label)
code.put_var_xdecrefs(lenv.temp_entries)
err_val = self.error_value()
exc_check = self.caller_will_check_exceptions()
if err_val is not None or exc_check:
code.putln(
"%s = %s;" % (
Naming.retval_cname,
err_val))
else:
code.putln(
'__Pyx_WriteUnraisable("%s");' %
self.entry.qualified_name)
env.use_utility_code(unraisable_exception_utility_code)
'__Pyx_AddTraceback("%s");' %
self.entry.qualified_name)
if err_val is not None:
code.putln(
"%s = %s;" % (
Naming.retval_cname,
err_val))
else:
code.putln(
'__Pyx_WriteUnraisable("%s");' %
self.entry.qualified_name)
env.use_utility_code(unraisable_exception_utility_code)
# ----- Return cleanup
code.put_label(code.return_label)
code.put_var_decrefs(lenv.var_entries)
code.put_var_decrefs(lenv.var_entries, used_only = 1)
code.put_var_decrefs(lenv.arg_entries)
self.put_stararg_decrefs(code)
if not self.return_type.is_void:
......@@ -1872,9 +661,6 @@ class CFuncDefNode(FuncDefNode):
def generate_argument_parsing_code(self, code):
pass
# def generate_stararg_getting_code(self, code):
# pass
def generate_argument_conversion_code(self, code):
pass
......@@ -2015,6 +801,7 @@ class DefNode(FuncDefNode):
arg.entry.init_to_none = 0
else:
arg.entry = self.declare_argument(env, arg)
arg.entry.used = 1
arg.entry.is_self_arg = arg.is_self_arg
if arg.hdr_type:
if arg.is_self_arg or \
......@@ -2025,11 +812,13 @@ class DefNode(FuncDefNode):
def declare_python_arg(self, env, arg):
if arg:
arg.entry = env.declare_var(arg.name,
entry = env.declare_var(arg.name,
PyrexTypes.py_object_type, arg.pos)
arg.entry.init = "0"
arg.entry.init_to_none = 0
arg.entry.xdecref_cleanup = 1
entry.used = 1
entry.init = "0"
entry.init_to_none = 0
entry.xdecref_cleanup = 1
arg.entry = entry
def analyse_expressions(self, env):
self.analyse_default_values(env)
......@@ -2044,6 +833,7 @@ class DefNode(FuncDefNode):
arg.default = arg.default.coerce_to(arg.type, env)
arg.default.allocate_temps(env)
arg.default_entry = env.add_default_value(arg.type)
arg.default_entry.used = 1
else:
error(arg.pos,
"This argument cannot have a default value")
......@@ -2339,11 +1129,10 @@ class PyClassDefNode(StatNode, BlockNode):
self.scope = cenv
self.body.analyse_declarations(cenv)
self.body.analyse_expressions(cenv)
self.target.analyse_target_expression(env)
self.target.analyse_target_expression(env, self.classobj)
self.dict.release_temp(env)
self.classobj.release_temp(env)
self.target.release_target_temp(env)
#env.recycle_pending_temps()
#self.classobj.release_temp(env)
#self.target.release_target_temp(env)
def generate_function_definitions(self, env, code):
self.generate_py_string_decls(self.scope, code)
......@@ -2488,7 +1277,6 @@ class ExprStatNode(StatNode):
def analyse_expressions(self, env):
self.expr.analyse_expressions(env)
self.expr.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code):
self.expr.generate_evaluation_code(code)
......@@ -2507,8 +1295,13 @@ class AssignmentNode(StatNode):
# to any of the left hand sides.
def analyse_expressions(self, env):
self.analyse_expressions_1(env)
self.analyse_expressions_2(env)
self.analyse_types(env)
self.allocate_rhs_temps(env)
self.allocate_lhs_temps(env)
# def analyse_expressions(self, env):
# self.analyse_expressions_1(env)
# self.analyse_expressions_2(env)
def generate_execution_code(self, code):
self.generate_rhs_evaluation_code(code)
......@@ -2526,18 +1319,33 @@ class SingleAssignmentNode(AssignmentNode):
def analyse_declarations(self, env):
self.lhs.analyse_target_declaration(env)
def analyse_expressions_1(self, env, use_temp = 0):
def analyse_types(self, env, use_temp = 0):
self.rhs.analyse_types(env)
self.lhs.analyse_target_types(env)
self.rhs = self.rhs.coerce_to(self.lhs.type, env)
if use_temp:
self.rhs = self.rhs.coerce_to_temp(env)
def allocate_rhs_temps(self, env):
self.rhs.allocate_temps(env)
def allocate_lhs_temps(self, env):
self.lhs.allocate_target_temps(env, self.rhs)
#self.lhs.release_target_temp(env)
#self.rhs.release_temp(env)
def analyse_expressions_2(self, env):
self.lhs.allocate_target_temps(env)
self.lhs.release_target_temp(env)
self.rhs.release_temp(env)
# def analyse_expressions_1(self, env, use_temp = 0):
# self.rhs.analyse_types(env)
# self.lhs.analyse_target_types(env)
# self.rhs = self.rhs.coerce_to(self.lhs.type, env)
# if use_temp:
# self.rhs = self.rhs.coerce_to_temp(env)
# self.rhs.allocate_temps(env)
#
# def analyse_expressions_2(self, env):
# self.lhs.allocate_target_temps(env)
# self.lhs.release_target_temp(env)
# self.rhs.release_temp(env)
def generate_rhs_evaluation_code(self, code):
self.rhs.generate_evaluation_code(code)
......@@ -2562,31 +1370,12 @@ class CascadedAssignmentNode(AssignmentNode):
for lhs in self.lhs_list:
lhs.analyse_target_declaration(env)
# def analyse_expressions(self, env):
# import ExprNodes
# self.rhs.analyse_types(env)
# self.rhs = self.rhs.coerce_to_temp(env)
# self.rhs.allocate_temps(env)
# self.coerced_rhs_list = []
# for lhs in self.lhs_list:
# lhs.analyse_target_types(env)
# coerced_rhs = ExprNodes.CloneNode(self.rhs).coerce_to(lhs.type, env)
# self.coerced_rhs_list.append(coerced_rhs)
# coerced_rhs.allocate_temps(env)
# lhs.allocate_target_temps(env)
# coerced_rhs.release_temp(env)
# lhs.release_target_temp(env)
# self.rhs.release_temp(env)
def analyse_expressions_1(self, env, use_temp = 0):
def analyse_types(self, env, use_temp = 0):
self.rhs.analyse_types(env)
if use_temp:
self.rhs = self.rhs.coerce_to_temp(env)
else:
self.rhs = self.rhs.coerce_to_simple(env)
self.rhs.allocate_temps(env)
def analyse_expressions_2(self, env):
from ExprNodes import CloneNode
self.coerced_rhs_list = []
for lhs in self.lhs_list:
......@@ -2594,21 +1383,39 @@ class CascadedAssignmentNode(AssignmentNode):
rhs = CloneNode(self.rhs)
rhs = rhs.coerce_to(lhs.type, env)
self.coerced_rhs_list.append(rhs)
def allocate_rhs_temps(self, env):
self.rhs.allocate_temps(env)
def allocate_lhs_temps(self, env):
for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
rhs.allocate_temps(env)
lhs.allocate_target_temps(env)
lhs.release_target_temp(env)
rhs.release_temp(env)
lhs.allocate_target_temps(env, rhs)
#lhs.release_target_temp(env)
#rhs.release_temp(env)
self.rhs.release_temp(env)
# def generate_execution_code(self, code):
# self.rhs.generate_evaluation_code(code)
# for i in range(len(self.lhs_list)):
# lhs = self.lhs_list[i]
# rhs = self.coerced_rhs_list[i]
# rhs.generate_evaluation_code(code)
# lhs.generate_assignment_code(rhs, code)
# # Assignment has already disposed of the cloned RHS
# self.rhs.generate_disposal_code(code)
# def analyse_expressions_1(self, env, use_temp = 0):
# self.rhs.analyse_types(env)
# if use_temp:
# self.rhs = self.rhs.coerce_to_temp(env)
# else:
# self.rhs = self.rhs.coerce_to_simple(env)
# self.rhs.allocate_temps(env)
#
# def analyse_expressions_2(self, env):
# from ExprNodes import CloneNode
# self.coerced_rhs_list = []
# for lhs in self.lhs_list:
# lhs.analyse_target_types(env)
# rhs = CloneNode(self.rhs)
# rhs = rhs.coerce_to(lhs.type, env)
# self.coerced_rhs_list.append(rhs)
# rhs.allocate_temps(env)
# lhs.allocate_target_temps(env)
# lhs.release_target_temp(env)
# rhs.release_temp(env)
# self.rhs.release_temp(env)
def generate_rhs_evaluation_code(self, code):
self.rhs.generate_evaluation_code(code)
......@@ -2642,9 +1449,16 @@ class ParallelAssignmentNode(AssignmentNode):
def analyse_expressions(self, env):
for stat in self.stats:
stat.analyse_expressions_1(env, use_temp = 1)
stat.analyse_types(env, use_temp = 1)
stat.allocate_rhs_temps(env)
for stat in self.stats:
stat.analyse_expressions_2(env)
stat.allocate_lhs_temps(env)
# def analyse_expressions(self, env):
# for stat in self.stats:
# stat.analyse_expressions_1(env, use_temp = 1)
# for stat in self.stats:
# stat.analyse_expressions_2(env)
def generate_execution_code(self, code):
for stat in self.stats:
......@@ -2695,10 +1509,10 @@ class DelStatNode(StatNode):
def analyse_expressions(self, env):
for arg in self.args:
arg.analyse_target_expression(env)
arg.analyse_target_expression(env, None)
if not arg.type.is_pyobject:
error(arg.pos, "Deletion of non-Python object")
#env.recycle_pending_temps() # TEMPORARY
#arg.release_target_temp(env)
def generate_execution_code(self, code):
for arg in self.args:
......@@ -2726,9 +1540,10 @@ class BreakStatNode(StatNode):
if not code.break_label:
error(self.pos, "break statement not inside loop")
else:
code.putln(
"goto %s;" %
code.break_label)
#code.putln(
# "goto %s;" %
# code.break_label)
code.put_goto(code.break_label)
class ContinueStatNode(StatNode):
......@@ -2742,9 +1557,10 @@ class ContinueStatNode(StatNode):
elif not code.continue_label:
error(self.pos, "continue statement not inside loop")
else:
code.putln(
"goto %s;" %
code.continue_label)
#code.putln(
# "goto %s;" %
# code.continue_label)
code.put_goto(code.continue_label)
class ReturnStatNode(StatNode):
......@@ -2780,8 +1596,6 @@ class ReturnStatNode(StatNode):
if not self.return_type:
# error reported earlier
return
for entry in self.temps_in_use:
code.put_var_decref_clear(entry)
if self.value:
self.value.generate_evaluation_code(code)
self.value.make_owned_reference(code)
......@@ -2798,9 +1612,12 @@ class ReturnStatNode(StatNode):
"%s = %s;" % (
Naming.retval_cname,
self.return_type.default_value))
code.putln(
"goto %s;" %
code.return_label)
for entry in self.temps_in_use:
code.put_var_decref_clear(entry)
#code.putln(
# "goto %s;" %
# code.return_label)
code.put_goto(code.return_label)
class RaiseStatNode(StatNode):
......@@ -2962,9 +1779,10 @@ class IfClauseNode(Node):
"if (%s) {" %
self.condition.result_code)
self.body.generate_execution_code(code)
code.putln(
"goto %s;" %
end_label)
#code.putln(
# "goto %s;" %
# end_label)
code.put_goto(end_label)
code.putln("}")
......@@ -2993,12 +1811,12 @@ class WhileStatNode(StatNode):
old_loop_labels = code.new_loop_labels()
code.putln(
"while (1) {")
code.put_label(code.continue_label)
self.condition.generate_evaluation_code(code)
code.putln(
"if (!%s) break;" %
self.condition.result_code)
self.body.generate_execution_code(code)
code.put_label(code.continue_label)
code.putln("}")
break_label = code.break_label
code.set_loop_labels(old_loop_labels)
......@@ -3031,12 +1849,10 @@ class ForInStatNode(StatNode):
self.item = ExprNodes.NextNode(self.iterator, env)
self.item = self.item.coerce_to(self.target.type, env)
self.item.allocate_temps(env)
self.target.allocate_target_temps(env)
self.item.release_temp(env)
self.target.release_target_temp(env)
#env.recycle_pending_temps() # TEMPORARY
self.target.allocate_target_temps(env, self.item)
#self.item.release_temp(env)
#self.target.release_target_temp(env)
self.body.analyse_expressions(env)
#env.recycle_pending_temps() # TEMPORARY
if self.else_clause:
self.else_clause.analyse_expressions(env)
self.iterator.release_temp(env)
......@@ -3046,10 +1862,10 @@ class ForInStatNode(StatNode):
self.iterator.generate_evaluation_code(code)
code.putln(
"for (;;) {")
code.put_label(code.continue_label)
self.item.generate_evaluation_code(code)
self.target.generate_assignment_code(self.item, code)
self.body.generate_execution_code(code)
code.put_label(code.continue_label)
code.putln(
"}")
break_label = code.break_label
......@@ -3075,6 +1891,7 @@ class ForFromStatNode(StatNode):
#
# Used internally:
#
# is_py_target bool
# loopvar_name string
# py_loopvar_node PyTempNode or None
......@@ -3094,14 +1911,19 @@ class ForFromStatNode(StatNode):
if not (self.bound2.is_name or self.bound2.is_literal):
self.bound2 = self.bound2.coerce_to_temp(env)
target_type = self.target.type
if not (target_type.is_pyobject
or target_type.assignable_from(PyrexTypes.c_int_type)):
error(self.target.pos,
"Cannot assign integer to variable of type '%s'" % target_type)
if not (target_type.is_pyobject or target_type.is_int):
error(self.target.pos,
"Integer for-loop variable must be of type int or Python object")
#if not (target_type.is_pyobject
# or target_type.assignable_from(PyrexTypes.c_int_type)):
# error(self.target.pos,
# "Cannot assign integer to variable of type '%s'" % target_type)
if target_type.is_int:
self.is_py_target = 0
self.loopvar_name = self.target.entry.cname
self.py_loopvar_node = None
else:
self.is_py_target = 1
c_loopvar_node = ExprNodes.TempNode(self.pos,
PyrexTypes.c_long_type, env)
c_loopvar_node.allocate_temps(env)
......@@ -3110,20 +1932,18 @@ class ForFromStatNode(StatNode):
ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
self.bound1.allocate_temps(env)
self.bound2.allocate_temps(env)
if self.py_loopvar_node:
if self.is_py_target:
self.py_loopvar_node.allocate_temps(env)
self.target.allocate_target_temps(env)
self.target.release_target_temp(env)
if self.py_loopvar_node:
self.py_loopvar_node.release_temp(env)
self.target.allocate_target_temps(env, self.py_loopvar_node)
#self.target.release_target_temp(env)
#self.py_loopvar_node.release_temp(env)
self.body.analyse_expressions(env)
if self.py_loopvar_node:
if self.is_py_target:
c_loopvar_node.release_temp(env)
if self.else_clause:
self.else_clause.analyse_expressions(env)
self.bound1.release_temp(env)
self.bound2.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code):
old_loop_labels = code.new_loop_labels()
......@@ -3200,9 +2020,10 @@ class TryExceptStatNode(StatNode):
self.else_clause.generate_execution_code(code)
code.putln(
"}")
code.putln(
"goto %s;" %
end_label)
#code.putln(
# "goto %s;" %
# end_label)
code.put_goto(end_label)
code.put_label(our_error_label)
code.put_var_xdecrefs_clear(self.cleanup_list)
default_clause_seen = 0
......@@ -3214,9 +2035,10 @@ class TryExceptStatNode(StatNode):
error(except_clause.pos, "Default except clause not last")
except_clause.generate_handling_code(code, end_label)
if not default_clause_seen:
code.putln(
"goto %s;" %
code.error_label)
#code.putln(
# "goto %s;" %
# code.error_label)
code.put_goto(code.error_label)
code.put_label(end_label)
......@@ -3248,11 +2070,11 @@ class ExceptClauseNode(Node):
self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
self.exc_value.allocate_temps(env)
if self.target:
self.target.analyse_target_expression(env)
self.exc_value.release_temp(env)
if self.target:
self.target.release_target_temp(env)
#env.recycle_pending_temps() # TEMPORARY
self.target.analyse_target_expression(env, self.exc_value)
else:
self.exc_value.release_temp(env)
#if self.target:
# self.target.release_target_temp(env)
self.body.analyse_expressions(env)
def generate_handling_code(self, code, end_label):
......@@ -3281,9 +2103,10 @@ class ExceptClauseNode(Node):
else:
self.exc_value.generate_disposal_code(code)
self.body.generate_execution_code(code)
code.putln(
"goto %s;"
% end_label)
#code.putln(
# "goto %s;"
# % end_label)
code.put_goto(end_label)
code.putln(
"}")
......@@ -3353,20 +2176,23 @@ class TryFinallyStatNode(StatNode):
#code.putln(
# "int %s;" %
# self.lineno_var)
code.use_label(catch_label)
code.putln(
"__pyx_why = 0; goto %s;" %
catch_label)
for i in range(len(new_labels)):
if new_labels[i] and new_labels[i] <> "<try>":
if new_labels[i] == new_error_label:
self.put_error_catcher(code,
new_error_label, i+1, catch_label)
else:
code.putln(
"%s: __pyx_why = %s; goto %s;" % (
new_labels[i],
i+1,
catch_label))
new_label = new_labels[i]
if new_label and new_label <> "<try>":
if new_label in code.labels_used:
if new_label == new_error_label:
self.put_error_catcher(code,
new_error_label, i+1, catch_label)
else:
code.putln(
"%s: __pyx_why = %s; goto %s;" % (
new_label,
i+1,
catch_label))
code.put_label(catch_label)
code.set_all_labels(old_labels)
self.finally_clause.generate_execution_code(code)
......@@ -3377,6 +2203,7 @@ class TryFinallyStatNode(StatNode):
if old_labels[i] == old_error_label:
self.put_error_uncatcher(code, i+1, old_error_label)
else:
code.use_label(old_labels[i])
code.putln(
"case %s: goto %s;" % (
i+1,
......@@ -3400,9 +2227,10 @@ class TryFinallyStatNode(StatNode):
code.putln(
"%s = %s;" % (
self.lineno_var, Naming.lineno_cname))
code.putln(
"goto %s;" %
catch_label)
#code.putln(
# "goto %s;" %
# catch_label)
code.put_goto(catch_label)
code.putln(
"}")
......@@ -3420,9 +2248,10 @@ class TryFinallyStatNode(StatNode):
code.putln(
"%s = 0;" %
var)
code.putln(
"goto %s;" %
error_label)
#code.putln(
# "goto %s;" %
# error_label)
code.put_goto(error_label)
code.putln(
"}")
......@@ -3502,11 +2331,10 @@ class FromImportStatNode(StatNode):
for name, target in self.items:
if Options.intern_names:
self.interned_items.append((env.intern(name), target))
target.analyse_target_expression(env)
target.release_temp(env)
target.analyse_target_expression(env, None)
#target.release_target_temp(env) # was release_temp ?!?
self.module.release_temp(env)
self.item.release_temp(env)
#env.recycle_pending_temps() # TEMPORARY
def generate_execution_code(self, code):
self.module.generate_evaluation_code(code)
......@@ -3542,38 +2370,21 @@ utility_function_predeclarations = \
"""
typedef struct {PyObject **p; char *s;} __Pyx_InternTabEntry; /*proto*/
typedef struct {PyObject **p; char *s; long n;} __Pyx_StringTabEntry; /*proto*/
static PyObject *__Pyx_UnpackItem(PyObject *, int); /*proto*/
static int __Pyx_EndUnpack(PyObject *, int); /*proto*/
static int __Pyx_PrintItem(PyObject *); /*proto*/
static int __Pyx_PrintNewline(void); /*proto*/
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
static void __Pyx_ReRaise(void); /*proto*/
static PyObject *__Pyx_Import(PyObject *name, PyObject *from_list); /*proto*/
static PyObject *__Pyx_GetExcValue(void); /*proto*/
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
static int __Pyx_TypeTest(PyObject *obj, PyTypeObject *type); /*proto*/
static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,\
char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
static void __Pyx_WriteUnraisable(char *name); /*proto*/
static void __Pyx_AddTraceback(char *funcname); /*proto*/
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
static PyObject *__Pyx_CreateClass(PyObject *bases, PyObject *dict, PyObject *name, char *modname); /*proto*/
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
"""
get_name_predeclaration = \
"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
#get_name_predeclaration = \
#"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
get_name_interned_predeclaration = \
"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
#get_name_interned_predeclaration = \
#"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
#------------------------------------------------------------------------------------
printing_utility_code = \
r"""
printing_utility_code = [
"""
static int __Pyx_PrintItem(PyObject *); /*proto*/
static int __Pyx_PrintNewline(void); /*proto*/
""",r"""
static PyObject *__Pyx_GetStdout(void) {
PyObject *f = PySys_GetObject("stdout");
if (!f) {
......@@ -3614,14 +2425,16 @@ static int __Pyx_PrintNewline(void) {
PyFile_SoftSpace(f, 0);
return 0;
}
"""
"""]
#------------------------------------------------------------------------------------
# The following function is based on do_raise() from ceval.c.
raise_utility_code = \
raise_utility_code = [
"""
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
""","""
static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
Py_XINCREF(type);
Py_XINCREF(value);
......@@ -3648,32 +2461,28 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
Py_INCREF(type);
Py_DECREF(tmp);
}
if (PyString_Check(type))
;
else if (PyClass_Check(type))
if (PyString_Check(type)) {
if (PyErr_Warn(PyExc_DeprecationWarning,
"raising a string exception is deprecated"))
goto raise_error;
}
else if (PyType_Check(type) || PyClass_Check(type))
; /*PyErr_NormalizeException(&type, &value, &tb);*/
else if (PyInstance_Check(type)) {
else {
/* Raising an instance. The value should be a dummy. */
if (value != Py_None) {
PyErr_SetString(PyExc_TypeError,
"instance exception may not have a separate value");
"instance exception may not have a separate value");
goto raise_error;
}
else {
/* Normalize to raise <class>, <instance> */
Py_DECREF(value);
value = type;
/* Normalize to raise <class>, <instance> */
Py_DECREF(value);
value = type;
if (PyInstance_Check(type))
type = (PyObject*) ((PyInstanceObject*)type)->in_class;
Py_INCREF(type);
}
}
else {
/* Not something you can raise. You get an exception
anyway, just not what you specified :-) */
PyErr_Format(PyExc_TypeError,
"exceptions must be strings, classes, or "
"instances, not %s", type->ob_type->tp_name);
goto raise_error;
else
type = (PyObject*) type->ob_type;
Py_INCREF(type);
}
PyErr_Restore(type, value, tb);
return;
......@@ -3683,12 +2492,14 @@ raise_error:
Py_XDECREF(tb);
return;
}
"""
"""]
#------------------------------------------------------------------------------------
reraise_utility_code = \
reraise_utility_code = [
"""
static void __Pyx_ReRaise(void); /*proto*/
""","""
static void __Pyx_ReRaise(void) {
PyThreadState *tstate = PyThreadState_Get();
PyObject *type = tstate->exc_type;
......@@ -3699,12 +2510,14 @@ static void __Pyx_ReRaise(void) {
Py_XINCREF(tb);
PyErr_Restore(type, value, tb);
}
"""
"""]
#------------------------------------------------------------------------------------
arg_type_test_utility_code = \
arg_type_test_utility_code = [
"""
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name); /*proto*/
""","""
static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name) {
if (!type) {
PyErr_Format(PyExc_SystemError, "Missing type object");
......@@ -3717,7 +2530,7 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
name, type->tp_name, obj->ob_type->tp_name);
return 0;
}
"""
"""]
#------------------------------------------------------------------------------------
#
......@@ -3733,8 +2546,11 @@ static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed
# reference to the same dictionary is passed back in *kwds.
#
get_starargs_utility_code = \
get_starargs_utility_code = [
"""
static int __Pyx_GetStarArgs(PyObject **args, PyObject **kwds,\
char *kwd_list[], int nargs, PyObject **args2, PyObject **kwds2); /*proto*/
""","""
static int __Pyx_GetStarArgs(
PyObject **args,
PyObject **kwds,
......@@ -3799,18 +2615,22 @@ static int __Pyx_GetStarArgs(
bad:
Py_XDECREF(args1);
Py_XDECREF(kwds1);
if (*args2)
if (*args2) {
Py_XDECREF(*args2);
if (*kwds2)
}
if (*kwds2) {
Py_XDECREF(*kwds2);
}
return -1;
}
"""
"""]
#------------------------------------------------------------------------------------
unraisable_exception_utility_code = \
unraisable_exception_utility_code = [
"""
static void __Pyx_WriteUnraisable(char *name); /*proto*/
""","""
static void __Pyx_WriteUnraisable(char *name) {
PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx;
......@@ -3821,12 +2641,14 @@ static void __Pyx_WriteUnraisable(char *name) {
ctx = Py_None;
PyErr_WriteUnraisable(ctx);
}
"""
"""]
#------------------------------------------------------------------------------------
traceback_utility_code = \
traceback_utility_code = [
"""
static void __Pyx_AddTraceback(char *funcname); /*proto*/
""","""
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
......@@ -3888,12 +2710,14 @@ bad:
'FILENAME': Naming.filename_cname,
'LINENO': Naming.lineno_cname,
'GLOBALS': Naming.module_cname
}
}]
#------------------------------------------------------------------------------------
type_import_utility_code = \
type_import_utility_code = [
"""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name, long size); /*proto*/
""","""
static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
long size)
{
......@@ -3943,12 +2767,14 @@ done:
Py_XDECREF(py_name_list);
return (PyTypeObject *)result;
}
"""
"""]
#------------------------------------------------------------------------------------
set_vtable_utility_code = \
set_vtable_utility_code = [
"""
static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
""","""
static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
PyObject *pycobj = 0;
int result;
......@@ -3967,12 +2793,14 @@ done:
Py_XDECREF(pycobj);
return result;
}
"""
"""]
#------------------------------------------------------------------------------------
get_vtable_utility_code = \
r"""
get_vtable_utility_code = [
"""
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
""",r"""
static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
int result;
PyObject *pycobj;
......@@ -3992,12 +2820,14 @@ done:
Py_XDECREF(pycobj);
return result;
}
"""
"""]
#------------------------------------------------------------------------------------
init_intern_tab_utility_code = \
init_intern_tab_utility_code = [
"""
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t); /*proto*/
""","""
static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
while (t->p) {
*t->p = PyString_InternFromString(t->s);
......@@ -4007,12 +2837,14 @@ static int __Pyx_InternStrings(__Pyx_InternTabEntry *t) {
}
return 0;
}
""";
"""]
#------------------------------------------------------------------------------------
init_string_tab_utility_code = \
init_string_tab_utility_code = [
"""
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
""","""
static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
while (t->p) {
*t->p = PyString_FromStringAndSize(t->s, t->n - 1);
......@@ -4022,6 +2854,6 @@ static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
}
return 0;
}
""";
"""]
#------------------------------------------------------------------------------------
......@@ -8,6 +8,7 @@ from types import ListType, TupleType
from Scanning import PyrexScanner
import Nodes
import ExprNodes
from ModuleNode import ModuleNode
from Errors import error, InternalError
def p_ident(s, message = "Expected an identifier"):
......@@ -413,13 +414,7 @@ def p_atom(s):
elif sy == '`':
return p_backquote_expr(s)
elif sy == 'INT':
digits = s.systring
if digits[:2] == "0x":
value = long(digits[2:], 16)
elif digits[:1] == "0":
value = int(digits, 8)
else:
value = int(s.systring)
value = s.systring
s.next()
return ExprNodes.IntNode(pos, value = value)
elif sy == 'LONG':
......@@ -517,7 +512,7 @@ def p_string_literal(s):
elif c == '\n':
pass
else:
chars.append(systr[1:])
chars.append(r'\\' + systr[1:])
elif sy == 'NEWLINE':
chars.append(r'\n')
elif sy == 'END_STRING':
......@@ -668,7 +663,6 @@ def p_expression_or_assignment(s):
if len(nodes) == 1:
return nodes[0]
else:
#return Nodes.StatListNode(nodes[0].pos, stats = nodes)
return Nodes.ParallelAssignmentNode(nodes[0].pos, stats = nodes)
def flatten_parallel_assignments(input, output):
......@@ -1375,19 +1369,19 @@ def p_exception_value_clause(s):
if s.sy == '?':
exc_check = 1
s.next()
exc_val = p_exception_value(s)
exc_val = p_simple_expr(s) #p_exception_value(s)
return exc_val, exc_check
def p_exception_value(s):
sign = ""
if s.sy == "-":
sign = "-"
s.next()
if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'):
s.systring = sign + s.systring
return p_atom(s)
else:
s.error("Exception value must be an int or float literal or NULL")
#def p_exception_value(s):
# sign = ""
# if s.sy == "-":
# sign = "-"
# s.next()
# if s.sy in ('INT', 'LONG', 'FLOAT', 'NULL'):
# s.systring = sign + s.systring
# return p_atom(s)
# else:
# s.error("Exception value must be an int or float literal or NULL")
c_arg_list_terminators = ('*', '**', '.', ')')
c_arg_list_trailers = ('.', '*', '**')
......@@ -1780,7 +1774,7 @@ def p_module(s, pxd):
if s.sy <> 'EOF':
s.error("Syntax error in statement [%s,%s]" % (
repr(s.sy), repr(s.systring)))
return Nodes.ModuleNode(pos, doc = doc, body = body)
return ModuleNode(pos, doc = doc, body = body)
#----------------------------------------------
#
......
......@@ -259,14 +259,14 @@ class CType(PyrexType):
from_py_function = None
class CSimpleType(CType):
#
# Base class for all unstructured C types.
#
pass
#class CSimpleType(CType):
# #
# # Base class for all unstructured C types.
# #
# pass
class CVoidType(CSimpleType):
class CVoidType(CType):
is_void = 1
def __repr__(self):
......@@ -313,9 +313,6 @@ class CNumericType(CType):
u = "unsigned "
return "<CNumericType %s%s>" % (u, rank_to_type_name[self.rank])
def assignable_from_resolved_type(self, src_type):
return src_type.is_numeric or src_type is error_type
def declaration_code(self, entity_code,
for_display = 0, dll_linkage = None, pyrex = 0):
if self.signed:
......@@ -324,8 +321,6 @@ class CNumericType(CType):
u = "unsigned "
base = public_decl(u + rank_to_type_name[self.rank], dll_linkage)
return "%s %s" % (base, entity_code)
# return "%s%s %s" % (u, rank_to_type_name[self.rank], entity_code)
class CIntType(CNumericType):
......@@ -338,6 +333,9 @@ class CIntType(CNumericType):
def __init__(self, rank, signed, pymemberdef_typecode = None, is_returncode = 0):
CNumericType.__init__(self, rank, signed, pymemberdef_typecode)
self.is_returncode = is_returncode
def assignable_from_resolved_type(self, src_type):
return src_type.is_int or src_type.is_enum or src_type is error_type
class CUIntType(CIntType):
......@@ -373,6 +371,9 @@ class CFloatType(CNumericType):
def __init__(self, rank, pymemberdef_typecode = None):
CNumericType.__init__(self, rank, 1, pymemberdef_typecode)
def assignable_from_resolved_type(self, src_type):
return src_type.is_numeric or src_type is error_type
class CArrayType(CType):
# base_type CType Element type
......@@ -447,6 +448,8 @@ class CPtrType(CType):
return 1
elif self.base_type.is_cfunction and other_type.is_cfunction:
return self.base_type.same_as(other_type)
elif other_type.is_array:
return self.base_type.same_as(other_type.base_type)
elif not other_type.is_ptr:
return 0
elif self.base_type.is_void:
......@@ -608,14 +611,16 @@ class CStructOrUnionType(CType):
return self.is_complete()
class CEnumType(CIntType):
class CEnumType(CType):
# name string
# cname string or None
# typedef_flag boolean
is_enum = 1
signed = 1
rank = 2
#signed = 1
#rank = 2
to_py_function = "PyInt_FromLong"
from_py_function = "PyInt_AsLong"
def __init__(self, name, cname, typedef_flag):
self.name = name
......
......@@ -61,6 +61,7 @@ class Entry:
# interned_cname string C name of interned name string
# pystring_cname string C name of Python version of string literal
# is_interned boolean For string const entries, value is interned
# used boolean
borrowed = 0
init = ""
......@@ -91,6 +92,7 @@ class Entry:
interned_cname = None
pystring_cname = None
is_interned = 0
used = 0
def __init__(self, name, cname, type, pos = None, init = None):
self.name = name
......@@ -351,6 +353,7 @@ class Scope:
# Add an entry for a string constant.
cname = self.new_const_cname()
entry = Entry("", cname, c_char_array_type, init = value)
entry.used = 1
self.const_entries.append(entry)
return entry
......@@ -395,6 +398,7 @@ class Scope:
self.temp_counter = n + 1
cname = "%s%d" % (Naming.pyrex_prefix, n)
entry = Entry("", cname, type)
entry.used = 1
if type.is_pyobject:
entry.init = "0"
self.cname_to_entry[entry.cname] = entry
......@@ -476,6 +480,7 @@ class ModuleScope(Scope):
# intern_map {string : string} Mapping from Python names to interned strs
# interned_names [string] Interned names pending generation of declarations
# all_pystring_entries [Entry] Python string consts from all scopes
# types_imported {PyrexType : 1} Set of types for which import code generated
def __init__(self, name, parent_module, context):
self.parent_module = parent_module
......@@ -500,6 +505,7 @@ class ModuleScope(Scope):
self.intern_map = {}
self.interned_names = []
self.all_pystring_entries = []
self.types_imported = {}
def qualifying_scope(self):
return self.parent_module
......@@ -565,6 +571,8 @@ class ModuleScope(Scope):
# None if previously declared as something else.
entry = self.lookup_here(name)
if entry:
if entry.is_pyglobal and entry.as_module is scope:
return entry # Already declared as the same module
if not (entry.is_pyglobal and not entry.as_module):
error(pos, "'%s' redeclared" % name)
return None
......@@ -956,6 +964,8 @@ class CClassScope(ClassScope):
if visibility in ('public', 'readonly'):
if type.pymemberdef_typecode:
self.public_attr_entries.append(entry)
if name == "__weakref__":
error(pos, "Special attribute __weakref__ cannot be exposed to Python")
else:
error(pos,
"C attribute of type '%s' cannot be accessed from Python" % type)
......
version = '0.9.4.1'
version = '0.9.5.1a'
......@@ -4,7 +4,8 @@
verbose = 0
gcc_pendantic = True
gcc_warnings_are_errors = False
gcc_warnings_are_errors = True
gcc_all_warnings = True
import os
from Pyrex.Utils import replace_suffix
......@@ -23,6 +24,9 @@ if gcc_pendantic:
compiler_options.extend(["-pedantic", "-Wno-long-long"])
if gcc_warnings_are_errors:
compiler_options.append("-Werror")
if gcc_all_warnings:
compiler_options.append("-Wall")
compiler_options.append("-Wno-unused-function")
linkers = ["gcc", "g++"]
linker_options = \
......@@ -45,6 +49,7 @@ def c_compile(c_file, verbose_flag = 0, cplus = 0, obj_suffix = ".o"):
args = [compiler] + compiler_options + include_options + [c_file, "-o", o_file]
if verbose_flag or verbose:
print " ".join(args)
#print compiler, args ###
status = os.spawnvp(os.P_WAIT, compiler, args)
if status <> 0:
raise CCompilerError("C compiler returned status %s" % status)
......
"""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)
static PyObject *File_Error;
static PyTypeObject FInfo_Type;
#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
typedef struct FInfoObject {
PyObject_HEAD
FInfo ob_itself;
} FInfoObject;
/* ------------------- Object type FSCatalogInfo -------------------- */
static PyTypeObject FSCatalogInfo_Type;
......@@ -338,16 +347,16 @@ static int FSCatalogInfo_set_userPrivileges(FSCatalogInfoObject *self, PyObject
static PyObject *FSCatalogInfo_get_finderInfo(FSCatalogInfoObject *self, void *closure)
{
return FInfo_New((FInfo *)self->finderInfo);
return FInfo_New((FInfo *)self->ob_itself.finderInfo);
}
static int FSCatalogInfo_set_finderInfo(FSCatalogInfoObject *self, PyObject *v, void *closure)
{
if (!FInfo_Check(v)) {
PyErr_SetString(PyTypeError, "Expected an FInfo object");
PyErr_SetString(PyExc_TypeError, "Expected an FInfo object");
return -1;
}
*(FInfo *)self->finderInfo = ((FInfoObject *)self)->ob_itself;
*(FInfo *)self->ob_itself.finderInfo = ((FInfoObject *)v)->ob_itself;
return 0;
}
......@@ -485,15 +494,6 @@ static PyTypeObject FSCatalogInfo_Type = {
/* ----------------------- Object type FInfo ------------------------ */
static PyTypeObject FInfo_Type;
#define FInfo_Check(x) ((x)->ob_type == &FInfo_Type || PyObject_TypeCheck((x), &FInfo_Type))
typedef struct FInfoObject {
PyObject_HEAD
FInfo ob_itself;
} FInfoObject;
static PyObject *FInfo_New(FInfo *itself)
{
FInfoObject *it;
......@@ -3247,8 +3247,8 @@ PyMac_GetFSRef(PyObject *v, FSRef *fsr)
if ( PyString_Check(v) || PyUnicode_Check(v)) {
char *path = NULL;
if (!PyArg_Parse(v, "et", Py_FileSystemDefaultEncoding, &path))
return NULL;
if ( (err=FSPathMakeRef(path, fsr, NULL)) ) {
return 0;
if ( (err=FSPathMakeRef((unsigned char *)path, fsr, NULL)) ) {
PyMac_Error(err);
return 0;
}
......
#
# 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