# In time, hopefully the literals etc. will be
# supplied directly instead.
+ # parts {string:CCodeWriter}
+
# interned_strings
# consts
directives = {}
- def __init__(self, rootwriter, emit_linenums=False):
+ code_layout = [
+ 'h_code',
+ 'before_global_var',
+ 'global_var',
+ 'after_global_var',
+
+ 'utility_proto',
+ 'pystring_table',
+ 'init_cached_builtins',
+ 'init',
+ 'utility_def',
+ ]
+
+
+ def __init__(self, writer, emit_linenums=False):
self.filename_table = {}
self.filename_list = []
self.input_file_contents = {}
self.pystring_table_needed = False
self.in_utility_code_generation = False
self.emit_linenums = emit_linenums
+ self.parts = {}
+
+ assert writer.globalstate is None
+ writer.globalstate = self
+ for part in self.code_layout:
+ self.parts[part] = writer.insertion_point()#new_writer()
+ self.initwriters(writer)
+
def initwriters(self, rootwriter):
self.utilprotowriter = rootwriter.new_writer()
self.pystring_table.putln("static __Pyx_StringTabEntry %s[] = {" %
Naming.stringtab_cname)
+ def __getitem__(self, key):
+ return self.parts[key]
+
#
# Global constants, interned objects, etc.
#
- def insert_global_var_declarations_into(self, code):
- code.insert(self.decls_writer)
-
def close_global_decls(self):
# This is called when it is known that no more global declarations will
# declared (but can be called before or after insert_XXX).
code.insert(self.cleanupwriter)
def put_pyobject_decl(self, entry):
- self.decls_writer.putln("static PyObject *%s;" % entry.cname)
+ self['global_var'].putln("static PyObject *%s;" % entry.cname)
# The functions below are there in a transition phase only
# and will be deprecated. They are called from Nodes.BlockNode.
def add_const_definition(self, entry):
if self.should_declare(entry.cname, entry):
- self.decls_writer.put_var_declaration(entry, static = 1)
+ self['global_var'].put_var_declaration(entry, static = 1)
def add_interned_string_decl(self, entry):
if self.should_declare(entry.cname, entry):
- self.decls_writer.put_var_declaration(entry, static = 1)
+ self['global_var'].put_var_declaration(entry, static = 1)
self.add_py_string_decl(entry)
def add_py_string_decl(self, entry):
if self.should_declare(entry.pystring_cname, entry):
- self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname)
+ self['global_var'].putln("static PyObject *%s;" % entry.pystring_cname)
self.pystring_table_needed = True
self.pystring_table.putln("{&%s, %s, sizeof(%s), %d, %d, %d}," % (
entry.pystring_cname,
# globalstate GlobalState contains state global for a C file (input file info,
# utility code, declared constants etc.)
# emit_linenums boolean whether or not to write #line pragmas
+
+ globalstate = None
def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None):
if buffer is None: buffer = StringIOTree()
self.level = 0
self.call_level = 0
self.bol = 1
- if create_from is None:
- # Root CCodeWriter
- self.globalstate = GlobalState(self, emit_linenums=emit_linenums)
- self.globalstate.initwriters(self)
- # ^^^ need seperate step because this will reference self.globalstate
- else:
+
+ if create_from is not None:
# Use same global state
self.globalstate = create_from.globalstate
# Clone formatting state
self.level = create_from.level
self.bol = create_from.bol
self.call_level = create_from.call_level
- if emit_linenums is None:
+ if emit_linenums is None and self.globalstate:
self.emit_linenums = self.globalstate.emit_linenums
else:
self.emit_linenums = emit_linenums
def create_new(self, create_from, buffer, copy_formatting):
# polymorphic constructor -- very slightly more versatile
# than using __class__
- return CCodeWriter(create_from, buffer, copy_formatting)
+ result = CCodeWriter(create_from, buffer, copy_formatting)
+ return result
def copyto(self, f):
self.buffer.copyto(f)
if h_types or h_vars or h_funcs or h_extension_types:
result.h_file = replace_suffix(result.c_file, ".h")
h_code = Code.CCodeWriter()
+ Code.GlobalState(h_code)
if options.generate_pxi:
result.i_file = replace_suffix(result.c_file, ".pxi")
i_code = Code.PyrexCodeWriter(result.i_file)
if api_funcs or has_api_extension_types:
result.api_file = replace_suffix(result.c_file, "_api.h")
h_code = Code.CCodeWriter()
+ Code.GlobalState(h_code)
name = self.api_name(env)
guard = Naming.api_guard_prefix + name
h_code.put_h_guard(guard)
def generate_c_code(self, env, options, result):
modules = self.referenced_modules
+
if Options.annotate or options.annotate:
- code = Annotate.AnnotationCCodeWriter()
+ emit_linenums = False
+ rootwriter = Annotate.AnnotationCCodeWriter()
else:
- code = Code.CCodeWriter(emit_linenums=options.emit_linenums)
- h_code = code.insertion_point()
+ emit_linenums = options.emit_linenums
+ rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums)
+ globalstate = Code.GlobalState(rootwriter, emit_linenums)
+ h_code = globalstate['h_code']
+
self.generate_module_preamble(env, modules, h_code)
- code.globalstate.module_pos = self.pos
- code.globalstate.directives = self.directives
+ globalstate.module_pos = self.pos
+ globalstate.directives = self.directives
- code.globalstate.use_utility_code(refcount_utility_code)
+ globalstate.use_utility_code(refcount_utility_code)
+ code = globalstate['before_global_var']
code.putln('#define __Pyx_MODULE_NAME "%s"' % self.full_module_name)
code.putln("")
code.putln("/* Implementation of %s */" % env.qualified_name)
self.generate_interned_string_decls(env, code)
self.generate_py_string_decls(env, code)
- code.globalstate.insert_global_var_declarations_into(code)
-
+ code = globalstate['after_global_var']
+
self.generate_cached_builtins_decls(env, code)
self.body.generate_function_definitions(env, code)
code.mark_pos(None)
self.generate_declarations_for_modules(env, modules, h_code)
h_code.write('\n')
- code.globalstate.close_global_decls()
+ globalstate.close_global_decls()
f = open_new_file(result.c_file)
- code.copyto(f)
+ rootwriter.copyto(f)
f.close()
result.c_file_generated = 1
if Options.annotate or options.annotate:
- self.annotate(code)
- code.save_annotation(result.main_source_file, result.c_file)
+ self.annotate(rootwriter)
+ rootwriter.save_annotation(result.main_source_file, result.c_file)
def find_referenced_modules(self, env, module_list, modules_seen):
if env not in modules_seen: