1#!/usr/local/bin/python3.8 2 3# file listerrors 4# This file is part of LyX, the document processor. 5# Licence details can be found in the file COPYING. 6 7# author Kayvan A. Sylvan 8 9# Full author contact details are available in file CREDITS. 10 11"""reformat noweb and compiler errors for LyX. 12 13Expects to read from stdin and output to stdout. 14""" 15 16__author__ = "Kayvan A. Sylvan <kayvan@sylvan.com>" 17__date__ = "$Date: 2003/10/13 09:50:10 $" 18__version__ = "$Revision: 1.4 $" 19__credits__ = """Edmar Wienskoski Jr. <edmar-w-jr@technologist.com> 20 original Literate support for LyX. 21Bernard Michael Hurley <berhardh@westherts.ac.uk> 22 modifications to original listerrors.""" 23__copyright__ = "Copyright 2002 - Kayvan A. Sylvan." 24 25from __future__ import print_function 26import sys, string 27 28def write_error(msg, tool = "noweb", line_number = 1): 29 """Write out the given message in TeX error style. 30 31 called like: write_error(msg, tool, line_number).""" 32 print ("! Build Error: ==> %s ==>" % tool) 33 print (" ...\n\nl.%d ..." % line_number) 34 if type(msg) == type("str"): # simple string 35 print (msg) 36 else: # some kind of list (sequence or tuple) 37 for m in msg: 38 if m != "": print (m, end=" ") 39 print () 40 41__lines = [] # lines pushed back 42 43def getline(file = sys.stdin): 44 """read a line from internal stack or from file. 45 46 optional file argument defaults to sys.stdin.""" 47 global __lines 48 lines = __lines 49 if lines: 50 line = lines.pop() 51 else: 52 line = file.readline() 53 return line 54 55def pushline(line): 56 "push a line onto the pushback stack." 57 global __lines 58 lines = __lines 59 lines.append(line) 60 61def main(): 62 """Entry point for listerrors. Takes no options. 63 64 Reads stdin and writes to stdout. Filter errors""" 65 66 while True: 67 line = getline() 68 if line == "": break 69 try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ] 70 for predicate in try_patterns_dispatch: 71 if predicate(line): break 72 73def noweb_try(line): 74 """see if line is a noweb error. 75 76 Returns 1 on success, 0 otherwise. Outputs on stdout.""" 77 retval = 0 78 if string.find(line, ": unescaped << in documentation chunk") != -1: 79 line_parts = string.split(line, ':') 80 num_str = line_parts[1] 81 num_len = len(num_str) 82 i = 0 83 while i < num_len and (num_str[i] in string.digits): i = i + 1 84 if i == num_len: 85 write_error(":" + line_parts[2], "noweb", int(num_str)) 86 retval = 1 87 if (not retval): 88 left = string.find(line, "<<") 89 if (left != -1) and ((left + 2) < len(line)) and \ 90 (string.find(line[left+2:], ">>") != -1): 91 write_error(line, "noweb"); 92 retval = 1; 93 if (not retval): 94 msgs_to_try = ("couldn't open file", 95 "couldn't open temporary file", 96 "error writing temporary file", 97 "ill-formed option", 98 "unknown option", 99 "Bad format sequence", 100 "Can't open output file", 101 "Can't open temporary file", 102 "Capacity exceeded:", 103 "Ignoring unknown option -", 104 "This can't happen:", 105 "non-numeric line number in") 106 for msg in msgs_to_try: 107 if string.find(line, msg) != -1: 108 write_error(line, "noweb") 109 retval = 1 110 break 111 return retval 112 113def gcc_try(line): 114 """See if line is a gcc error. Read ahead to handle all the lines. 115 116 Returns 1 on success, 0 otherwise. Outputs on stdout.""" 117 retval = 0 118 first_space = string.find(line, ' ') 119 if first_space > 1: # The smallest would be "X: " 120 if line[first_space - 1] == ':': 121 header_to_see = line[:first_space - 1] 122 next_line = getline() 123 if next_line and next_line[:first_space - 1] == header_to_see: 124 num_end = first_space 125 while next_line[num_end] in string.digits: num_end = num_end + 1 126 if num_end > first_space: # good! 127 num_str = next_line[first_space:num_end] 128 msgs = [line[first_space:]] 129 msgs.append(next_line[num_end + 1:]) 130 header_to_see = next_line[:num_end] 131 next_line = getline() 132 while next_line and next_line[:num_end] == header_to_see: 133 msgs.append(next_line[num_end + 1:]) 134 next_line = getline() 135 if next_line: pushline(next_line) 136 write_error(msgs, "gcc", int(num_str)) 137 retval = 1 138 else: # oops! Not a gcc error. 139 pushline(next_line) 140 elif next_line: 141 pushline(next_line) # return this line to input stream 142 return retval 143 144def xlc_try(line): 145 """see if line is an xlc error. 146 147 Returns 1 on success, 0 otherwise. Outputs on stdout.""" 148 retval = 0 149 if line[0] == '"': # This is the first character of all xlc errors 150 next_quote = string.find(line, '"', 1) 151 first_space = string.find(line, ' ') 152 if (next_quote != -1) and (first_space > next_quote): # no space inisde quotes 153 if line[first_space - 1:first_space + 6] == ", line ": 154 num_start = num_end = first_space + 6 155 while line[num_end] in string.digits: num_end = num_end + 1 156 if num_end > num_start: 157 write_error(line, "xlc", int(line[num_start : num_end])) 158 retval = 1 159 return retval 160 161 162if __name__ == "__main__": 163 main() 164