From f40643123d00088af743285b9fd41dd7b5a16da4 Mon Sep 17 00:00:00 2001 From: Robert Bradshaw <robertwb@math.washington.edu> Date: Sat, 13 Sep 2008 12:48:45 -0700 Subject: [PATCH] Option to emit #line directives, ticket #53 --- Cython/Compiler/CmdLine.py | 4 +++- Cython/Compiler/Code.py | 22 +++++++++++++++++----- Cython/Compiler/Main.py | 3 ++- Cython/Compiler/ModuleNode.py | 3 +-- 4 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Cython/Compiler/CmdLine.py b/Cython/Compiler/CmdLine.py index 34e891e6a..a423d2acd 100644 --- a/Cython/Compiler/CmdLine.py +++ b/Cython/Compiler/CmdLine.py @@ -36,7 +36,7 @@ Options: -D, --no-docstrings Remove docstrings. -a, --annotate Produce a colorized HTML version of the source. - --convert-range Convert for loops using range() function to for...from loops. + --line-directives Produce #line directives pointing to the .pyx source --cplus Output a c++ rather than c file. -X, --directive <name>=<value>[,<name=value,...] Overrides a compiler directive """ @@ -114,6 +114,8 @@ def parse_command_line(args): Options.annotate = True elif option == "--convert-range": Options.convert_range = True + elif option == "--line-directives": + options.emit_linenums = True elif option in ("-X", "--directive"): try: options.pragma_overrides = Options.parse_option_list(pop_arg()) diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index 9010f4fbf..e0897b4d4 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -161,13 +161,14 @@ class GlobalState(object): # interned_nums # cached_builtins - def __init__(self, rootwriter): + def __init__(self, rootwriter, emit_linenums=False): self.filename_table = {} self.filename_list = [] self.input_file_contents = {} self.used_utility_code = set() self.declared_cnames = {} self.pystring_table_needed = False + self.emit_linenums = emit_linenums def initwriters(self, rootwriter): self.utilprotowriter = rootwriter.new_writer() @@ -378,6 +379,8 @@ class GlobalState(object): writer.insert(self.utilprotowriter) def put_utility_code_defs(self, writer): + if self.emit_linenums: + writer.write('\n#line 1 "cython_utility"\n') writer.insert(self.utildefwriter) @@ -403,7 +406,7 @@ class CCodeWriter(object): - marker: Not copied to insertion point - filename_table, filename_list, input_file_contents: All codewriters coming from the same root share the same instances simultaneously. - """ + """ # f file output file # buffer StringIOTree @@ -415,19 +418,21 @@ class CCodeWriter(object): # generation (labels and temps state etc.) # 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 - def __init__(self, create_from=None, buffer=None, copy_formatting=False): + def __init__(self, create_from=None, buffer=None, copy_formatting=False, emit_linenums=None): if buffer is None: buffer = StringIOTree() self.buffer = buffer self.marker = None self.last_marker_line = 0 + self.source_desc = "" self.funcstate = None self.level = 0 self.bol = 1 if create_from is None: # Root CCodeWriter - self.globalstate = GlobalState(self) + self.globalstate = GlobalState(self, emit_linenums=emit_linenums) self.globalstate.initwriters(self) # ^^^ need seperate step because this will reference self.globalstate else: @@ -437,6 +442,10 @@ class CCodeWriter(object): if copy_formatting: self.level = create_from.level self.bol = create_from.bol + if emit_linenums is None: + 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 @@ -504,6 +513,8 @@ class CCodeWriter(object): def putln(self, code = ""): if self.marker and self.bol: self.emit_marker() + if self.emit_linenums and self.last_marker_line != 0: + self.write('\n#line %s "%s"\n' % (self.last_marker_line, self.source_desc)) if code: self.put(code) self.write("\n"); @@ -580,7 +591,8 @@ class CCodeWriter(object): marker = u'"%s":%d\n%s\n' % ( source_desc.get_escaped_description(), line, u'\n'.join(lines)) self.marker = (line, marker) - + if self.emit_linenums: + self.source_desc = source_desc.get_escaped_description() def put_label(self, lbl): if lbl in self.funcstate.labels_used: diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py index 8a9139d02..53af007d7 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@ -727,7 +727,8 @@ default_options = dict( timestamps = None, verbose = 0, quiet = 0, - pragma_overrides = {} + pragma_overrides = {}, + emit_linenums = False, ) if sys.platform == "mac": from Cython.Mac.MacSystem import c_compile, c_link, CCompilerError diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index 23cb11455..88db1af7c 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -3,7 +3,6 @@ # import os, time -from cStringIO import StringIO from PyrexTypes import CPtrType import Future @@ -240,7 +239,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): if Options.annotate or options.annotate: code = Annotate.AnnotationCCodeWriter() else: - code = Code.CCodeWriter() + code = Code.CCodeWriter(emit_linenums=options.emit_linenums) h_code = code.insertion_point() self.generate_module_preamble(env, modules, h_code) -- 2.30.9