]> git.lyx.org Git - lyx.git/blob - lib/scripts/listerrors
Add needauth option to gnuplot->PDF converter introduced in [066edd3c/lyxgit].
[lyx.git] / lib / scripts / listerrors
1 #!/usr/bin/env python
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
13 Expects 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.
21 Bernard Michael Hurley <berhardh@westherts.ac.uk>
22     modifications to original listerrors."""
23 __copyright__ = "Copyright 2002 - Kayvan A. Sylvan."
24
25 import sys, string
26
27 def write_error(msg, tool = "noweb", line_number = 1):
28   """Write out the given message in TeX error style.
29
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
39
40 __lines = [] # lines pushed back
41
42 def getline(file = sys.stdin):
43   """read a line from internal stack or from file.
44
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
53
54 def pushline(line):
55   "push a line onto the pushback stack."
56   global __lines
57   lines = __lines
58   lines.append(line)
59
60 def main():
61   """Entry point for listerrors. Takes no options.
62
63   Reads stdin and writes to stdout. Filter errors"""
64
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.
73
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
110
111 def gcc_try(line):
112   """See if line is a gcc error. Read ahead to handle all the lines.
113
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
141
142 def xlc_try(line):
143   """see if line is an xlc error.
144
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
158
159
160 if __name__ == "__main__":
161   main()