KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > polyglot > util > StdErrorQueue


1 package polyglot.util;
2
3 import java.io.*;
4 import java.util.StringTokenizer JavaDoc;
5
6 /**
7  * A <code>StdErrorQueue</code> handles outputing error messages.
8  */

9 public class StdErrorQueue extends AbstractErrorQueue
10 {
11     private PrintStream err;
12
13     public StdErrorQueue(PrintStream err, int limit, String JavaDoc name) {
14         super(limit, name);
15     this.err = err;
16     }
17
18     public void displayError(ErrorInfo e) {
19     String JavaDoc message = e.getErrorKind() != ErrorInfo.WARNING
20                ? e.getMessage()
21                : e.getErrorString() + " -- " + e.getMessage();
22
23     Position position = e.getPosition();
24
25     String JavaDoc prefix = position != null
26             ? position.nameAndLineString()
27             : name;
28
29         /*
30
31         // This doesn't work: it breaks the error message into one word
32         // per line.
33
34         CodeWriter w = new CodeWriter(err, 78);
35
36         w.begin(0);
37         w.write(prefix + ":");
38         w.write(" ");
39
40     StringTokenizer st = new StringTokenizer(message, " ");
41
42     while (st.hasMoreTokens()) {
43         String s = st.nextToken();
44             w.write(s);
45             if (st.hasMoreTokens()) {
46                 w.allowBreak(0, " ");
47             }
48         }
49
50         w.end();
51         w.newline(0);
52
53         try {
54             w.flush();
55         }
56         catch (IOException ex) {
57         }
58         */

59
60     // I (Nate) tried without success to get CodeWriter to do this.
61
// It would be nice if we could specify where breaks are allowed
62
// when generating the error. We don't want to break Jif labels,
63
// for instance.
64

65     int width = 0;
66     err.print(prefix + ":");
67     width += prefix.length() + 1;
68
69     int lmargin = 4;
70     int rmargin = 78;
71
72     StringTokenizer JavaDoc lines = new StringTokenizer JavaDoc(message, "\n", true);
73         boolean needNewline = false;
74
75     while (lines.hasMoreTokens()) {
76         String JavaDoc line = lines.nextToken();
77
78             if (line.indexOf("\n") < 0) {
79                 StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(line, " ");
80
81                 while (st.hasMoreTokens()) {
82                     String JavaDoc s = st.nextToken();
83
84                     if (width + s.length() + 1 > rmargin) {
85                         err.println();
86                         for (int i = 0; i < lmargin; i++) err.print(" ");
87                         width = lmargin;
88                     }
89                     else {
90                         err.print(" ");
91                         width++;
92                     }
93
94                     err.print(s);
95
96                     width += s.length();
97                 }
98
99                 needNewline = true;
100             }
101             else {
102                 err.println();
103                 needNewline = false;
104             }
105
106             width = lmargin;
107
108             if (lines.hasMoreTokens()) {
109                 for (int i = 0; i < lmargin; i++) err.print(" ");
110             }
111             else if (needNewline) {
112                 err.println();
113             }
114     }
115
116     if (position != null) {
117         showError(position);
118     }
119     }
120     
121     protected void tooManyErrors(ErrorInfo lastError) {
122         Position position = lastError.getPosition();
123         String JavaDoc prefix = position != null ? (position.file() + ": ") : "";
124         err.println(prefix + "Too many errors. Aborting compilation.");
125     }
126
127     protected Reader reader(Position pos) throws IOException {
128       if (pos.file() != null && pos.line() != Position.UNKNOWN) {
129       return new FileReader(pos.file());
130       }
131       return null;
132     }
133
134     private void showError(Position pos) {
135       try {
136         Reader r = reader(pos);
137
138         if (r == null) {
139           return;
140         }
141
142         LineNumberReader reader = new LineNumberReader(r);
143
144         String JavaDoc s = null;
145         while (reader.getLineNumber() < pos.line()) {
146           s = reader.readLine();
147         }
148
149         if (s != null) {
150           err.println(s);
151           showErrorIndicator(pos, reader.getLineNumber(), s);
152           
153           if (pos.endLine() != pos.line() &&
154               pos.endLine() != Position.UNKNOWN &&
155               pos.endLine() != Position.END_UNUSED) {
156
157               // if there is more than two lines,
158
// print some ellipsis.
159
if (pos.endLine() - pos.line() > 1) {
160                   // add some whitespace first
161
for (int j = 0; j < s.length() && Character.isWhitespace(s.charAt(j)); j++) {
162                       err.print(s.charAt(j));
163                   }
164                   err.println("...");
165               }
166               
167               while (reader.getLineNumber() < pos.endLine()) {
168                 s = reader.readLine();
169               }
170
171               // s is now the last line of the error.
172
if (s != null) {
173                 err.println(s);
174                 showErrorIndicator(pos, reader.getLineNumber(), s);
175               }
176             }
177         }
178         
179         reader.close();
180
181         err.println();
182       }
183       catch (IOException e) {
184       }
185     }
186     
187     protected void showErrorIndicator(Position pos, int lineNum, String JavaDoc s) {
188         if (pos.column() == Position.UNKNOWN) {
189             return;
190         }
191         
192         int i = 0;
193         while (i < s.length() && Character.isWhitespace(s.charAt(i))) {
194             err.print(s.charAt(i++));
195         }
196         
197         int startIndAt = i; // column position to start showing the indicator marks
198
int stopIndAt = s.length() - 1; // column position to stop showing the indicator marks
199
if (pos.line() == lineNum) {
200             startIndAt = pos.column();
201         }
202         if (pos.endLine() == lineNum) {
203             stopIndAt = pos.endColumn() - 1;
204         }
205         if (stopIndAt < startIndAt) {
206             stopIndAt = startIndAt;
207         }
208         if (pos.endColumn() == Position.UNKNOWN ||
209             pos.endColumn() == Position.END_UNUSED) {
210             stopIndAt = startIndAt;
211         }
212                 
213         for (;i <= stopIndAt; i++) {
214             char c = '-';
215             if (i < startIndAt) {
216               c = ' ';
217             }
218             if (i < s.length() && s.charAt(i) == '\t') {
219               c = '\t';
220             }
221             if (i == startIndAt && pos.line() == lineNum) {
222                 c = '^';
223             }
224             if (i == stopIndAt && pos.endLine() == lineNum) {
225                 c = '^';
226             }
227             
228             err.print(c);
229         }
230
231         err.println();
232     }
233     
234     public void flush() {
235     if (! flushed) {
236             if (errorCount() > 0) {
237                 err.println(errorCount() + " error" +
238                             (errorCount() > 1 ? "s." : "."));
239             }
240     }
241         super.flush();
242     }
243 }
244
Popular Tags