#!/usr/bin/python3 # file listerrors # This file is part of LyX, the document processor. # Licence details can be found in the file COPYING. # author Kayvan A. Sylvan # Full author contact details are available in file CREDITS. """reformat noweb and compiler errors for LyX. Expects to read from stdin and output to stdout. """ __author__ = "Kayvan A. Sylvan " __date__ = "$Date: 2003/10/13 09:50:10 $" __version__ = "$Revision: 1.4 $" __credits__ = """Edmar Wienskoski Jr. original Literate support for LyX. Bernard Michael Hurley modifications to original listerrors.""" __copyright__ = "Copyright 2002 - Kayvan A. Sylvan." from __future__ import print_function import sys, string def write_error(msg, tool = "noweb", line_number = 1): """Write out the given message in TeX error style. called like: write_error(msg, tool, line_number).""" print ("! Build Error: ==> %s ==>" % tool) print (" ...\n\nl.%d ..." % line_number) if type(msg) == type("str"): # simple string print (msg) else: # some kind of list (sequence or tuple) for m in msg: if m != "": print (m, end=" ") print () __lines = [] # lines pushed back def getline(file = sys.stdin): """read a line from internal stack or from file. optional file argument defaults to sys.stdin.""" global __lines lines = __lines if lines: line = lines.pop() else: line = file.readline() return line def pushline(line): "push a line onto the pushback stack." global __lines lines = __lines lines.append(line) def main(): """Entry point for listerrors. Takes no options. Reads stdin and writes to stdout. Filter errors""" while True: line = getline() if line == "": break try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ] for predicate in try_patterns_dispatch: if predicate(line): break def noweb_try(line): """see if line is a noweb error. Returns 1 on success, 0 otherwise. Outputs on stdout.""" retval = 0 if string.find(line, ": unescaped << in documentation chunk") != -1: line_parts = string.split(line, ':') num_str = line_parts[1] num_len = len(num_str) i = 0 while i < num_len and (num_str[i] in string.digits): i = i + 1 if i == num_len: write_error(":" + line_parts[2], "noweb", int(num_str)) retval = 1 if (not retval): left = string.find(line, "<<") if (left != -1) and ((left + 2) < len(line)) and \ (string.find(line[left+2:], ">>") != -1): write_error(line, "noweb"); retval = 1; if (not retval): msgs_to_try = ("couldn't open file", "couldn't open temporary file", "error writing temporary file", "ill-formed option", "unknown option", "Bad format sequence", "Can't open output file", "Can't open temporary file", "Capacity exceeded:", "Ignoring unknown option -", "This can't happen:", "non-numeric line number in") for msg in msgs_to_try: if string.find(line, msg) != -1: write_error(line, "noweb") retval = 1 break return retval def gcc_try(line): """See if line is a gcc error. Read ahead to handle all the lines. Returns 1 on success, 0 otherwise. Outputs on stdout.""" retval = 0 first_space = string.find(line, ' ') if first_space > 1: # The smallest would be "X: " if line[first_space - 1] == ':': header_to_see = line[:first_space - 1] next_line = getline() if next_line and next_line[:first_space - 1] == header_to_see: num_end = first_space while next_line[num_end] in string.digits: num_end = num_end + 1 if num_end > first_space: # good! num_str = next_line[first_space:num_end] msgs = [line[first_space:]] msgs.append(next_line[num_end + 1:]) header_to_see = next_line[:num_end] next_line = getline() while next_line and next_line[:num_end] == header_to_see: msgs.append(next_line[num_end + 1:]) next_line = getline() if next_line: pushline(next_line) write_error(msgs, "gcc", int(num_str)) retval = 1 else: # oops! Not a gcc error. pushline(next_line) elif next_line: pushline(next_line) # return this line to input stream return retval def xlc_try(line): """see if line is an xlc error. Returns 1 on success, 0 otherwise. Outputs on stdout.""" retval = 0 if line[0] == '"': # This is the first character of all xlc errors next_quote = string.find(line, '"', 1) first_space = string.find(line, ' ') if (next_quote != -1) and (first_space > next_quote): # no space inisde quotes if line[first_space - 1:first_space + 6] == ", line ": num_start = num_end = first_space + 6 while line[num_end] in string.digits: num_end = num_end + 1 if num_end > num_start: write_error(line, "xlc", int(line[num_start : num_end])) retval = 1 return retval if __name__ == "__main__": main()