]> git.lyx.org Git - lyx.git/blob - lib/scripts/listerrors
Update scripts to support simultaneously python 2 and 3
[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 from __future__ import print_function
26 import sys, string
27
28 def 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
43 def 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
55 def pushline(line):
56   "push a line onto the pushback stack."
57   global __lines
58   lines = __lines
59   lines.append(line)
60
61 def 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
73 def 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
113 def 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
144 def 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
162 if __name__ == "__main__":
163   main()