4 # This file is part of LyX, the document processor.
5 # Licence details can be found in the file COPYING.
7 # author Kayvan A. Sylvan
9 # Full author contact details are available in file CREDITS.
11 """reformat noweb and compiler errors for LyX.
13 Expects to read from stdin and output to stdout.
15 from __future__ import print_function
17 __author__ = "Kayvan A. Sylvan <kayvan@sylvan.com>"
18 __date__ = "$Date: 2003/10/13 09:50:10 $"
19 __version__ = "$Revision: 1.4 $"
20 __credits__ = """Edmar Wienskoski Jr. <edmar-w-jr@technologist.com>
21 original Literate support for LyX.
22 Bernard Michael Hurley <berhardh@westherts.ac.uk>
23 modifications to original listerrors."""
24 __copyright__ = "Copyright 2002 - Kayvan A. Sylvan."
28 def write_error(msg, tool = "noweb", line_number = 1):
29 """Write out the given message in TeX error style.
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
36 else: # some kind of list (sequence or tuple)
38 if m != "": print (m, end=" ")
41 __lines = [] # lines pushed back
43 def getline(file = sys.stdin):
44 """read a line from internal stack or from file.
46 optional file argument defaults to sys.stdin."""
52 line = file.readline()
56 "push a line onto the pushback stack."
62 """Entry point for listerrors. Takes no options.
64 Reads stdin and writes to stdout. Filter errors"""
69 try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
70 for predicate in try_patterns_dispatch:
71 if predicate(line): break
74 """see if line is a noweb error.
76 Returns 1 on success, 0 otherwise. Outputs on stdout."""
78 if line.find(": unescaped << in documentation chunk") != -1:
79 line_parts = line.split(':')
80 num_str = line_parts[1]
81 num_len = len(num_str)
83 while i < num_len and (num_str[i] in string.digits): i = i + 1
85 write_error(":" + line_parts[2], "noweb", int(num_str))
88 left = line.find("<<")
89 if (left != -1) and ((left + 2) < len(line)) and \
90 (line[left+2:].find(">>") != -1):
91 write_error(line, "noweb");
94 msgs_to_try = ("couldn't open file",
95 "couldn't open temporary file",
96 "error writing temporary file",
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 line.find(msg) != -1:
108 write_error(line, "noweb")
114 """See if line is a gcc error. Read ahead to handle all the lines.
116 Returns 1 on success, 0 otherwise. Outputs on stdout."""
118 first_space = line.find(' ')
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))
138 else: # oops! Not a gcc error.
141 pushline(next_line) # return this line to input stream
145 """see if line is an xlc error.
147 Returns 1 on success, 0 otherwise. Outputs on stdout."""
149 if line[0] == '"': # This is the first character of all xlc errors
150 next_quote = line.find('"', 1)
151 first_space = line.find(' ')
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]))
162 if __name__ == "__main__":