Commit 3c84aafe authored by Stefan Behnel's avatar Stefan Behnel

simplify option passing in CCodeWriter by moving them into a common CCodeConfig object

parent be7033c5
...@@ -985,14 +985,14 @@ class GlobalState(object): ...@@ -985,14 +985,14 @@ class GlobalState(object):
] ]
def __init__(self, writer, module_node, emit_linenums=False, common_utility_include_dir=None): def __init__(self, writer, module_node, code_config, common_utility_include_dir=None):
self.filename_table = {} self.filename_table = {}
self.filename_list = [] self.filename_list = []
self.input_file_contents = {} self.input_file_contents = {}
self.utility_codes = set() self.utility_codes = set()
self.declared_cnames = {} self.declared_cnames = {}
self.in_utility_code_generation = False self.in_utility_code_generation = False
self.emit_linenums = emit_linenums self.code_config = code_config
self.common_utility_include_dir = common_utility_include_dir self.common_utility_include_dir = common_utility_include_dir
self.parts = {} self.parts = {}
self.module_node = module_node # because some utility code generation needs it self.module_node = module_node # because some utility code generation needs it
...@@ -1005,8 +1005,7 @@ class GlobalState(object): ...@@ -1005,8 +1005,7 @@ class GlobalState(object):
self.py_constants = [] self.py_constants = []
self.cached_cmethods = {} self.cached_cmethods = {}
assert writer.globalstate is None writer.set_global_state(self)
writer.globalstate = self
self.rootwriter = writer self.rootwriter = writer
def initialize_main_c_code(self): def initialize_main_c_code(self):
...@@ -1046,7 +1045,7 @@ class GlobalState(object): ...@@ -1046,7 +1045,7 @@ class GlobalState(object):
code.putln("/* --- Runtime support code (head) --- */") code.putln("/* --- Runtime support code (head) --- */")
code = self.parts['utility_code_def'] code = self.parts['utility_code_def']
if self.emit_linenums: if self.code_config.emit_linenums:
code.write('\n#line 1 "cython_utility"\n') code.write('\n#line 1 "cython_utility"\n')
code.putln("") code.putln("")
code.putln("/* --- Runtime support code --- */") code.putln("/* --- Runtime support code --- */")
...@@ -1480,6 +1479,17 @@ def funccontext_property(name): ...@@ -1480,6 +1479,17 @@ def funccontext_property(name):
return property(get, set) return property(get, set)
class CCodeConfig(object):
# emit_linenums boolean write #line pragmas?
# emit_code_comments boolean copy the original code into C comments?
# c_line_in_traceback boolean append the c file and line number to the traceback for exceptions?
def __init__(self, emit_linenums=True, emit_code_comments=True, c_line_in_traceback=True):
self.emit_code_comments = emit_code_comments
self.emit_linenums = emit_linenums
self.c_line_in_traceback = c_line_in_traceback
class CCodeWriter(object): class CCodeWriter(object):
""" """
Utility class to output C code. Utility class to output C code.
...@@ -1507,16 +1517,13 @@ class CCodeWriter(object): ...@@ -1507,16 +1517,13 @@ class CCodeWriter(object):
# generation (labels and temps state etc.) # generation (labels and temps state etc.)
# globalstate GlobalState contains state global for a C file (input file info, # globalstate GlobalState contains state global for a C file (input file info,
# utility code, declared constants etc.) # utility code, declared constants etc.)
# emit_linenums boolean whether or not to write #line pragmas
#
# c_line_in_traceback boolean append the c file and line number to the traceback for exceptions
#
# pyclass_stack list used during recursive code generation to pass information # pyclass_stack list used during recursive code generation to pass information
# about the current class one is in # about the current class one is in
# code_config CCodeConfig configuration options for the C code writer
globalstate = None globalstate = code_config = None
def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None, c_line_in_traceback=True): def __init__(self, create_from=None, buffer=None, copy_formatting=False):
if buffer is None: buffer = StringIOTree() if buffer is None: buffer = StringIOTree()
self.buffer = buffer self.buffer = buffer
self.last_pos = None self.last_pos = None
...@@ -1530,7 +1537,7 @@ class CCodeWriter(object): ...@@ -1530,7 +1537,7 @@ class CCodeWriter(object):
if create_from is not None: if create_from is not None:
# Use same global state # Use same global state
self.globalstate = create_from.globalstate self.set_global_state(create_from.globalstate)
self.funcstate = create_from.funcstate self.funcstate = create_from.funcstate
# Clone formatting state # Clone formatting state
if copy_formatting: if copy_formatting:
...@@ -1540,19 +1547,17 @@ class CCodeWriter(object): ...@@ -1540,19 +1547,17 @@ class CCodeWriter(object):
self.last_pos = create_from.last_pos self.last_pos = create_from.last_pos
self.last_marked_pos = create_from.last_marked_pos self.last_marked_pos = create_from.last_marked_pos
if emit_linenums is None and self.globalstate:
self.emit_linenums = self.globalstate.emit_linenums
else:
self.emit_linenums = emit_linenums
self.c_line_in_traceback = c_line_in_traceback
def create_new(self, create_from, buffer, copy_formatting): def create_new(self, create_from, buffer, copy_formatting):
# polymorphic constructor -- very slightly more versatile # polymorphic constructor -- very slightly more versatile
# than using __class__ # than using __class__
result = CCodeWriter(create_from, buffer, copy_formatting, result = CCodeWriter(create_from, buffer, copy_formatting)
c_line_in_traceback=self.c_line_in_traceback)
return result return result
def set_global_state(self, global_state):
assert self.globalstate is None # prevent overwriting once it's set
self.globalstate = global_state
self.code_config = global_state.code_config
def copyto(self, f): def copyto(self, f):
self.buffer.copyto(f) self.buffer.copyto(f)
...@@ -1575,7 +1580,7 @@ class CCodeWriter(object): ...@@ -1575,7 +1580,7 @@ class CCodeWriter(object):
Creates a new CCodeWriter connected to the same global state, which Creates a new CCodeWriter connected to the same global state, which
can later be inserted using insert. can later be inserted using insert.
""" """
return CCodeWriter(create_from=self, c_line_in_traceback=self.c_line_in_traceback) return CCodeWriter(create_from=self)
def insert(self, writer): def insert(self, writer):
""" """
...@@ -1656,7 +1661,7 @@ class CCodeWriter(object): ...@@ -1656,7 +1661,7 @@ class CCodeWriter(object):
def putln(self, code="", safe=False): def putln(self, code="", safe=False):
if self.last_pos and self.bol: if self.last_pos and self.bol:
self.emit_marker() self.emit_marker()
if self.emit_linenums and self.last_marked_pos: if self.code_config.emit_linenums and self.last_marked_pos:
source_desc, line, _ = self.last_marked_pos source_desc, line, _ = self.last_marked_pos
self.write('\n#line %s "%s"\n' % (line, source_desc.get_escaped_description())) self.write('\n#line %s "%s"\n' % (line, source_desc.get_escaped_description()))
if code: if code:
...@@ -1679,7 +1684,7 @@ class CCodeWriter(object): ...@@ -1679,7 +1684,7 @@ class CCodeWriter(object):
self.last_marked_pos = pos self.last_marked_pos = pos
self.last_pos = None self.last_pos = None
self.write("\n") self.write("\n")
if Options.emit_code_comments: if self.code_config.emit_code_comments:
self.indent() self.indent()
self.write("/* %s */\n" % self._build_marker(pos)) self.write("/* %s */\n" % self._build_marker(pos))
if trace and self.funcstate and self.funcstate.can_trace and self.globalstate.directives['linetrace']: if trace and self.funcstate and self.funcstate.can_trace and self.globalstate.directives['linetrace']:
...@@ -2120,7 +2125,7 @@ class CCodeWriter(object): ...@@ -2120,7 +2125,7 @@ class CCodeWriter(object):
self.funcstate.should_declare_error_indicator = True self.funcstate.should_declare_error_indicator = True
if used: if used:
self.funcstate.uses_error_indicator = True self.funcstate.uses_error_indicator = True
if self.c_line_in_traceback: if self.code_config.c_line_in_traceback:
cinfo = " %s = %s;" % (Naming.clineno_cname, Naming.line_c_macro) cinfo = " %s = %s;" % (Naming.clineno_cname, Naming.line_c_macro)
else: else:
cinfo = "" cinfo = ""
......
...@@ -139,7 +139,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -139,7 +139,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if (h_types or h_vars or h_funcs or h_extension_types): if (h_types or h_vars or h_funcs or h_extension_types):
result.h_file = replace_suffix(result.c_file, ".h") result.h_file = replace_suffix(result.c_file, ".h")
h_code = Code.CCodeWriter() h_code = Code.CCodeWriter()
Code.GlobalState(h_code, self) Code.GlobalState(h_code, self, Code.CCodeConfig()) # FIXME: config?
if options.generate_pxi: if options.generate_pxi:
result.i_file = replace_suffix(result.c_file, ".pxi") result.i_file = replace_suffix(result.c_file, ".pxi")
i_code = Code.PyrexCodeWriter(result.i_file) i_code = Code.PyrexCodeWriter(result.i_file)
...@@ -213,7 +213,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -213,7 +213,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if api_vars or api_funcs or api_extension_types: if api_vars or api_funcs or api_extension_types:
result.api_file = replace_suffix(result.c_file, "_api.h") result.api_file = replace_suffix(result.c_file, "_api.h")
h_code = Code.CCodeWriter() h_code = Code.CCodeWriter()
Code.GlobalState(h_code, self) Code.GlobalState(h_code, self, Code.CCodeConfig()) # FIXME: config?
h_code.put_generated_by() h_code.put_generated_by()
api_guard = Naming.api_guard_prefix + self.api_name(env) api_guard = Naming.api_guard_prefix + self.api_name(env)
h_code.put_h_guard(api_guard) h_code.put_h_guard(api_guard)
...@@ -312,8 +312,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -312,8 +312,18 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
rootwriter = Annotate.AnnotationCCodeWriter() rootwriter = Annotate.AnnotationCCodeWriter()
else: else:
emit_linenums = options.emit_linenums emit_linenums = options.emit_linenums
rootwriter = Code.CCodeWriter(emit_linenums=emit_linenums, c_line_in_traceback=options.c_line_in_traceback) rootwriter = Code.CCodeWriter()
globalstate = Code.GlobalState(rootwriter, self, emit_linenums, options.common_utility_include_dir)
c_code_config = Code.CCodeConfig(
emit_linenums=emit_linenums,
emit_code_comments=env.directives['emit_code_comments'],
c_line_in_traceback=options.c_line_in_traceback,
)
globalstate = Code.GlobalState(
rootwriter, self,
code_config=c_code_config,
common_utility_include_dir=options.common_utility_include_dir,
)
globalstate.initialize_main_c_code() globalstate.initialize_main_c_code()
h_code = globalstate['h_code'] h_code = globalstate['h_code']
......
...@@ -117,6 +117,7 @@ directive_defaults = { ...@@ -117,6 +117,7 @@ directive_defaults = {
'profile': False, 'profile': False,
'no_gc_clear': False, 'no_gc_clear': False,
'linetrace': False, 'linetrace': False,
'emit_code_comments': True, # copy original source code into C code comments
'annotation_typing': False, # read type declarations from Python function annotations 'annotation_typing': False, # read type declarations from Python function annotations
'infer_types': None, 'infer_types': None,
'infer_types.verbose': False, 'infer_types.verbose': False,
...@@ -253,6 +254,7 @@ directive_scopes = { # defaults to available everywhere ...@@ -253,6 +254,7 @@ directive_scopes = { # defaults to available everywhere
'test_assert_path_exists' : ('function', 'class', 'cclass'), 'test_assert_path_exists' : ('function', 'class', 'cclass'),
'test_fail_if_path_exists' : ('function', 'class', 'cclass'), 'test_fail_if_path_exists' : ('function', 'class', 'cclass'),
'freelist': ('cclass',), 'freelist': ('cclass',),
'emit_code_comments': ('module',),
'annotation_typing': ('module',), # FIXME: analysis currently lacks more specific function scope 'annotation_typing': ('module',), # FIXME: analysis currently lacks more specific function scope
# Avoid scope-specific to/from_py_functions for c_string. # Avoid scope-specific to/from_py_functions for c_string.
'c_string_type': ('module',), 'c_string_type': ('module',),
......
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