tufte layout files:
[lyx.git] / lib / scripts / listerrors
blobe9b0da957ffe7aea1a691a5d21dadd0cd5ad6cb4
1 #!/usr/bin/python
3 # file listerrors
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.
14 """
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.
21 Bernard Michael Hurley <berhardh@westherts.ac.uk>
22 modifications to original listerrors."""
23 __copyright__ = "Copyright 2002 - Kayvan A. Sylvan."
25 import sys, string
27 def write_error(msg, tool = "noweb", line_number = 1):
28 """Write out the given message in TeX error style.
30 called like: write_error(msg, tool, line_number)."""
31 print "! Build Error: ==> %s ==>\n" % (tool),
32 print " ...\n\nl.%d ...\n" % (line_number),
33 if type(msg) == type("str"): # simple string
34 print msg
35 else: # some kind of list (sequence or tuple)
36 for m in msg:
37 if m != "": print m,
38 print
40 __lines = [] # lines pushed back
42 def getline(file = sys.stdin):
43 """read a line from internal stack or from file.
45 optional file argument defaults to sys.stdin."""
46 global __lines
47 lines = __lines
48 if lines:
49 line = lines.pop()
50 else:
51 line = file.readline()
52 return line
54 def pushline(line):
55 "push a line onto the pushback stack."
56 global __lines
57 lines = __lines
58 lines.append(line)
60 def main():
61 """Entry point for listerrors. Takes no options.
63 Reads stdin and writes to stdout. Filter errors"""
65 while 1:
66 line = getline()
67 if line == "": break
68 try_patterns_dispatch = [ noweb_try, gcc_try, xlc_try ]
69 for predicate in try_patterns_dispatch:
70 if predicate(line): break
71 def noweb_try(line):
72 """see if line is a noweb error.
74 Returns 1 on success, 0 otherwise. Outputs on stdout."""
75 retval = 0
76 if string.find(line, ": unescaped << in documentation chunk") != -1:
77 line_parts = string.split(line, ':')
78 num_str = line_parts[1]
79 num_len = len(num_str)
80 i = 0
81 while i < num_len and (num_str[i] in string.digits): i = i + 1
82 if i == num_len:
83 write_error(":" + line_parts[2], "noweb", int(num_str))
84 retval = 1
85 if (not retval):
86 left = string.find(line, "<<")
87 if (left != -1) and ((left + 2) < len(line)) and \
88 (string.find(line[left+2:], ">>") != -1):
89 write_error(line, "noweb");
90 retval = 1;
91 if (not retval):
92 msgs_to_try = ("couldn't open file",
93 "couldn't open temporary file",
94 "error writing temporary file",
95 "ill-formed option",
96 "unknown option",
97 "Bad format sequence",
98 "Can't open output file",
99 "Can't open temporary file",
100 "Capacity exceeded:",
101 "Ignoring unknown option -",
102 "This can't happen:",
103 "non-numeric line number in")
104 for msg in msgs_to_try:
105 if string.find(line, msg) != -1:
106 write_error(line, "noweb")
107 retval = 1
108 break
109 return retval
111 def gcc_try(line):
112 """See if line is a gcc error. Read ahead to handle all the lines.
114 Returns 1 on success, 0 otherwise. Outputs on stdout."""
115 retval = 0
116 first_space = string.find(line, ' ')
117 if first_space > 1: # The smallest would be "X: "
118 if line[first_space - 1] == ':':
119 header_to_see = line[:first_space - 1]
120 next_line = getline()
121 if next_line and next_line[:first_space - 1] == header_to_see:
122 num_end = first_space
123 while next_line[num_end] in string.digits: num_end = num_end + 1
124 if num_end > first_space: # good!
125 num_str = next_line[first_space:num_end]
126 msgs = [line[first_space:]]
127 msgs.append(next_line[num_end + 1:])
128 header_to_see = next_line[:num_end]
129 next_line = getline()
130 while next_line and next_line[:num_end] == header_to_see:
131 msgs.append(next_line[num_end + 1:])
132 next_line = getline()
133 if next_line: pushline(next_line)
134 write_error(msgs, "gcc", int(num_str))
135 retval = 1
136 else: # oops! Not a gcc error.
137 pushline(next_line)
138 elif next_line:
139 pushline(next_line) # return this line to input stream
140 return retval
142 def xlc_try(line):
143 """see if line is an xlc error.
145 Returns 1 on success, 0 otherwise. Outputs on stdout."""
146 retval = 0
147 if line[0] == '"': # This is the first character of all xlc errors
148 next_quote = string.find(line, '"', 1)
149 first_space = string.find(line, ' ')
150 if (next_quote != -1) and (first_space > next_quote): # no space inisde quotes
151 if line[first_space - 1:first_space + 6] == ", line ":
152 num_start = num_end = first_space + 6
153 while line[num_end] in string.digits: num_end = num_end + 1
154 if num_end > num_start:
155 write_error(line, "xlc", int(line[num_start : num_end]))
156 retval = 1
157 return retval
160 if __name__ == "__main__":
161 main()