test/tools/javac/diags/RunExamples.java

changeset 610
3640b60bd0f6
child 795
7b99f98b3035
equal deleted inserted replaced
609:13354e1abba7 610:3640b60bd0f6
1 /*
2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /**
25 * @test
26 * @bug 6968063
27 * @summary provide examples of code that generate diagnostics
28 * @build Example HTMLWriter RunExamples
29 * @run main RunExamples
30 */
31
32 import java.io.*;
33 import java.text.SimpleDateFormat;
34 import java.util.*;
35 import java.util.regex.Matcher;
36 import java.util.regex.Pattern;
37
38 /**
39 * Utility to run selected or all examples, writing results to
40 * stdout, a plain text file or an HTML file. This program can be
41 * run standalone, or as a jtreg test.
42 *
43 * Options:
44 * -examples dir directory of examples. Defaults to ${test.src}/examples
45 * -raw run examples with -XDrawDiagnostics
46 * -showFiles include text of source files in the output
47 * -verbose verbose output
48 * -o file write output to file: format will be HTML if
49 * file has .html extension; otherwise it will be plain text.
50 * default is to stdout
51 * -title string specify a title, only applies to HTML output
52 */
53 public class RunExamples {
54 public static void main(String... args) throws Exception {
55 boolean jtreg = (System.getProperty("test.src") != null);
56 File tmpDir;
57 if (jtreg) {
58 // use standard jtreg scratch directory: the current directory
59 tmpDir = new File(System.getProperty("user.dir"));
60 } else {
61 tmpDir = new File(System.getProperty("java.io.tmpdir"),
62 RunExamples.class.getName()
63 + (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()));
64 }
65 Example.setTempDir(tmpDir);
66
67 RunExamples r = new RunExamples();
68
69 try {
70 if (r.run(args))
71 return;
72 } finally {
73 /* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
74 * jtreg scratch directory, which is the current directory.
75 * In case someone is faking jtreg mode, make sure to only
76 * clean tmpDir when it is reasonable to do so.
77 */
78 if (tmpDir.isDirectory() &&
79 tmpDir.getName().startsWith(RunExamples.class.getName())) {
80 if (clean(tmpDir))
81 tmpDir.delete();
82 }
83 }
84
85 if (jtreg)
86 throw new Exception(r.errors + " errors occurred");
87 else
88 System.exit(1);
89 }
90
91 boolean run(String... args) {
92 Set<String> selectedKeys = new TreeSet<String>();
93 Set<Example> selectedExamples = new TreeSet<Example>();
94 File testSrc = new File(System.getProperty("test.src", "."));
95 File examplesDir = new File(testSrc, "examples");
96 File outFile = null;
97 boolean raw = false;
98 boolean showFiles = false;
99 boolean verbose = false;
100 String title = null;
101
102 for (int i = 0; i < args.length; i++) {
103 String arg = args[i];
104 if (arg.equals("-k") && (i + 1) < args.length)
105 selectedKeys.add(args[++i]);
106 else if (arg.equals("-examples") && (i + 1) < args.length)
107 examplesDir = new File(args[++i]);
108 else if (arg.equals("-raw"))
109 raw = true;
110 else if (arg.equals("-showFiles"))
111 showFiles = true;
112 else if (arg.equals("-verbose"))
113 verbose = true;
114 else if (arg.equals("-o") && (i + 1) < args.length)
115 outFile = new File(args[++i]);
116 else if (arg.equals("-title") && (i + 1) < args.length)
117 title = args[++i];
118 else if (arg.startsWith("-")) {
119 error("unknown option: " + arg);
120 return false;
121 } else {
122 while (i < args.length) {
123 File f = new File(examplesDir, args[i]);
124 selectedExamples.add(new Example(f));
125 i++;
126 }
127 }
128 }
129
130 if (selectedKeys.size() > 0) {
131 Set<Example> examples = getExamples(examplesDir);
132 nextKey:
133 for (String k: selectedKeys) {
134 for (Example e: examples) {
135 if (e.getDeclaredKeys().contains(k))
136 continue nextKey;
137 }
138 error("Key " + k + ": no examples found");
139 }
140 } else {
141 if (selectedExamples.size() == 0)
142 selectedExamples = getExamples(examplesDir);
143 }
144
145 try {
146 Runner r;
147 if (outFile == null) {
148 PrintWriter out = new PrintWriter(System.out);
149 r = new TextRunner(out, showFiles, raw, verbose);
150 } else if (outFile.getName().endsWith(".html"))
151 r = new HTMLRunner(outFile, showFiles, raw, verbose, title);
152 else
153 r = new TextRunner(outFile, showFiles, raw, verbose);
154 r.run(selectedExamples);
155 r.close();
156 } catch (IOException e) {
157 error("Error writing output: " + e);
158 }
159
160 return (errors == 0);
161 }
162
163 /**
164 * Get the complete set of examples to be checked.
165 */
166 Set<Example> getExamples(File examplesDir) {
167 Set<Example> results = new TreeSet<Example>();
168 for (File f: examplesDir.listFiles()) {
169 if (f.isDirectory() || f.isFile() && f.getName().endsWith(".java"))
170 results.add(new Example(f));
171 }
172 return results;
173 }
174
175 /**
176 * Report an error.
177 */
178 void error(String msg) {
179 System.err.println("Error: " + msg);
180 errors++;
181 }
182
183 int errors;
184
185 /**
186 * Clean the contents of a directory.
187 */
188 static boolean clean(File dir) {
189 boolean ok = true;
190 for (File f: dir.listFiles()) {
191 if (f.isDirectory())
192 ok &= clean(f);
193 ok &= f.delete();
194 }
195 return ok;
196 }
197
198 static abstract class Runner {
199 Runner(boolean showFiles, boolean raw, boolean verbose) {
200 this.showFiles = showFiles;
201 this.raw = raw;
202 this.verbose = verbose;
203 }
204
205 void close() throws IOException { }
206
207 void run(Collection<Example> examples) throws IOException {
208 for (Example e: examples) {
209 startExample(e);
210 if (showFiles) {
211 showFile(e, e.infoFile);
212 Set<File> srcFiles = new TreeSet<File>(e.srcFiles);
213 srcFiles.remove(e.infoFile);
214 showFiles(e, srcFiles);
215 showFiles(e, e.srcPathFiles);
216 showFiles(e, e.procFiles);
217 showFiles(e, e.supportFiles);
218 }
219 run(e);
220 }
221 }
222
223 void showFiles(Example e, Collection<File> files) throws IOException {
224 for (File f: files)
225 showFile(e, f);
226 }
227
228 abstract void startExample(Example e) throws IOException;
229
230 abstract void showFile(Example e, File f) throws IOException;
231
232 abstract void run(Example e) throws IOException;
233
234 protected String read(File f) throws IOException {
235 byte[] bytes = new byte[(int) f.length()];
236 DataInputStream in = new DataInputStream(new FileInputStream(f));
237 try {
238 in.readFully(bytes);
239 } finally {
240 in.close();
241 }
242 return new String(bytes);
243 }
244
245 protected Pattern copyrightHeaderPat =
246 Pattern.compile("(?s)(/\\*.*?Copyright.*?\\*/\n)\\s*(.*)");
247 protected Pattern infoHeaderPat =
248 Pattern.compile("(?s)((?://\\s*[a-z]+:[^\n]*\n)+)\\s*(.*)");
249
250 protected boolean showFiles;
251 protected boolean raw;
252 protected boolean verbose;
253 }
254
255 static class TextRunner extends Runner {
256 TextRunner(File file, boolean showFiles, boolean raw, boolean verbose)
257 throws IOException {
258 super(showFiles, raw, verbose);
259 this.file = file;
260 out = new PrintWriter(new FileWriter(file));
261 }
262
263 TextRunner(PrintWriter out, boolean showFiles, boolean raw, boolean verbose)
264 throws IOException {
265 super(showFiles, raw, verbose);
266 this.out = out;
267 }
268
269 @Override
270 void close() {
271 if (file != null)
272 out.close();
273 }
274
275 @Override
276 void startExample(Example e) {
277 out.println("----- " + e.getName() + " --------------------");
278 out.println();
279 }
280
281 @Override
282 void showFile(Example e, File f) {
283 out.println("--- " + f);
284 String text;
285 try {
286 text = read(f);
287 } catch (IOException ex) {
288 text = "Error reading " + f + "; " + ex;
289 }
290 Matcher m = copyrightHeaderPat.matcher(text);
291 if (m.matches()) {
292 out.println("(Copyright)");
293 writeLines(m.group(2));
294 } else {
295 writeLines(text);
296 }
297 out.println();
298 }
299
300 @Override
301 void run(Example e) {
302 // only show Output: header if also showing files
303 if (showFiles)
304 out.println("--- Output:");
305 e.run(out, raw, verbose);
306 out.println();
307 }
308
309 void writeLines(String text) {
310 for (String line: text.split("\n"))
311 out.println(line);
312 }
313
314 File file;
315 PrintWriter out;
316 }
317
318 static class HTMLRunner extends Runner {
319 HTMLRunner(File file, boolean showFiles, boolean raw, boolean verbose, String title)
320 throws IOException {
321 super(showFiles, raw, verbose);
322 this.file = file;
323 PrintWriter out = new PrintWriter(new FileWriter(file));
324 html = new HTMLWriter(out);
325 html.startTag(HTMLWriter.HEAD);
326 if (title != null) {
327 html.startTag(HTMLWriter.TITLE);
328 html.write(title);
329 html.endTag(HTMLWriter.TITLE);
330 }
331 html.startTag(HTMLWriter.STYLE);
332 html.newLine();
333 html.writeLine("div.file { background-color:#e0ffe0; margin-left:30px; margin-right:30px;\n"
334 + " padding: 3px; border: thin solid silver; }");
335 html.writeLine("p.file { white-space: pre-wrap; font-family:monospace; margin: 0; }");
336 html.writeLine("div.output { background-color:#e0e0ff; margin-left:30px; margin-right:30px;\n"
337 + " padding: 3px; border: thin solid silver; }");
338 html.writeLine("p.output { white-space: pre-wrap; font-family:monospace; margin: 0; }");
339 html.writeLine("table.index { border: thin solid silver; }");
340 html.writeLine(".copyright { font-size: x-small }");
341 html.writeLine(".hidden { display:none }");
342 html.writeLine(".unhidden { display:block }");
343 html.writeLine(".odd { background-color: #e0e0e0 }");
344 html.writeLine(".even { background-color: white }");
345 html.endTag(HTMLWriter.STYLE);
346 html.startTag(HTMLWriter.SCRIPT);
347 html.writeAttr(HTMLWriter.TYPE, HTMLWriter.TEXT_JAVASCRIPT);
348 html.writeLine("\nfunction unhide(id) {\n"
349 + " var item = document.getElementById(id);\n"
350 + " if (item) {\n"
351 + " item.className=(item.className=='hidden')?'unhidden':'hidden';\n"
352 + " }\n"
353 + "}");
354 html.endTag(HTMLWriter.SCRIPT);
355 html.endTag(HTMLWriter.HEAD);
356 html.startTag(HTMLWriter.BODY);
357 if (title != null) {
358 html.startTag(TITLE_HEADER);
359 html.write(title);
360 html.endTag(TITLE_HEADER);
361 }
362 }
363
364 @Override
365 void close() throws IOException {
366 html.endTag(HTMLWriter.BODY);
367 html.newLine();
368 html.flush();
369 }
370
371 @Override
372 void run(Collection<Example> examples) throws IOException {
373 if (examples.size() > 1)
374 writeIndex(examples);
375 super.run(examples);
376 }
377
378 void writeIndex(Collection<Example> examples) throws IOException {
379 Map<String, Set<Example>> index = new TreeMap<String, Set<Example>>();
380 Set<String> initials = new HashSet<String>();
381 for (Example e: examples) {
382 for (String k: e.getDeclaredKeys()) {
383 Set<Example> s = index.get(k);
384 if (s == null)
385 index.put(k, s = new TreeSet<Example>());
386 s.add(e);
387 }
388 initials.add(e.getName().substring(0, 1).toUpperCase());
389 }
390
391
392 if (INDEX_HEADER != null) {
393 html.startTag(INDEX_HEADER);
394 html.write("Index");
395 html.endTag(INDEX_HEADER);
396 }
397
398 html.startTag(HTMLWriter.P);
399 html.writeLine("Examples: ");
400 for (char initial = 'A'; initial <= 'Z'; initial++) {
401 String s = String.valueOf(initial);
402 if (initials.contains(s)) {
403 html.writeLink("#" + s, s);
404 } else {
405 html.write(s);
406 }
407 html.newLine();
408 }
409 html.endTag(HTMLWriter.P);
410
411 html.startTag(HTMLWriter.TABLE);
412 html.writeAttr(HTMLWriter.CLASS, "index");
413 html.newLine();
414 int row = 0;
415 for (Map.Entry<String, Set<Example>> entry: index.entrySet()) {
416 html.startTag(HTMLWriter.TR);
417 html.writeAttr(HTMLWriter.CLASS,
418 (row++ % 2 == 0 ? "even" : "odd"));
419 html.startTag(HTMLWriter.TD);
420 html.writeAttr("valign", "top");
421 html.write(entry.getKey());
422 html.endTag(HTMLWriter.TD);
423 html.newLine();
424 html.startTag(HTMLWriter.TD);
425 html.writeAttr(HTMLWriter.ALIGN, "top");
426 String sep = "";
427 for (Example e: entry.getValue()) {
428 html.write(sep);
429 html.writeLink('#' + e.getName(), e.getName());
430 sep = ", ";
431 }
432 html.endTag(HTMLWriter.TD);
433 html.endTag(HTMLWriter.TR);
434 html.newLine();
435 }
436 html.endTag(HTMLWriter.TABLE);
437 }
438
439 @Override
440 void startExample(Example e) throws IOException {
441 String name = e.getName();
442 String initial = name.substring(0, 1).toUpperCase();
443 if (!initial.equals(currInitial)) {
444 html.writeLinkDestination(initial, "");
445 currInitial = initial;
446 }
447 html.writeLinkDestination(name, "");
448 html.startTag(EXAMPLE_HEADER);
449 html.write(e.getName());
450 html.endTag(EXAMPLE_HEADER);
451 }
452
453 @Override
454 void showFile(Example e, File f) throws IOException {
455 String text;
456 try {
457 text = read(f);
458 } catch (IOException ex) {
459 text = "Error reading " + f + ": " + ex;
460 }
461 if (!f.equals(e.file)) {
462 html.startTag(FILE_HEADER);
463 html.write(e.file.toURI().relativize(f.toURI()).toString());
464 html.endTag(FILE_HEADER);
465 }
466 html.startTag(HTMLWriter.DIV);
467 html.writeAttr(CLASS, FILE);
468
469 String legalHeader;
470 Matcher m1 = copyrightHeaderPat.matcher(text);
471 if (m1.matches()) {
472 legalHeader = m1.group(1);
473 text = m1.group(2);
474 } else
475 legalHeader = null;
476
477 String infoHeader;
478 Matcher m2 = infoHeaderPat.matcher(text);
479 if (m2.matches()) {
480 infoHeader = m2.group(1);
481 text = m2.group(2);
482 } else
483 infoHeader = null;
484
485 String legalId = null, infoId = null;
486 if (legalHeader != null || infoHeader != null) {
487 String sep = "";
488 html.startTag(HTMLWriter.SPAN);
489 html.writeStyleAttr("float: right");
490 if (legalHeader != null) {
491 legalId = nextId();
492 html.startTag(HTMLWriter.A);
493 html.writeAttr(HTMLWriter.HREF, "javascript:unhide('" + legalId + "');");
494 //html.writeEntity("&copy;");
495 html.write("Copyright");
496 html.endTag(HTMLWriter.A);
497 sep = ", ";
498 }
499 if (infoHeader != null) {
500 html.write(sep);
501 infoId = nextId();
502 html.startTag(HTMLWriter.A);
503 html.writeAttr(HTMLWriter.HREF, "javascript:unhide('" + infoId + "');");
504 html.write("Info");
505 html.endTag(HTMLWriter.A);
506 sep = ", ";
507 }
508 html.endTag(HTMLWriter.SPAN);
509 }
510
511 html.startTag(HTMLWriter.P);
512 html.writeAttr(CLASS, FILE);
513 if (legalHeader != null) {
514 html.startTag(HTMLWriter.SPAN);
515 html.writeAttr(HTMLWriter.CLASS, "hidden");
516 html.writeAttr(HTMLWriter.ID, legalId);
517 html.write(legalHeader);
518 html.newLine();
519 html.endTag(HTMLWriter.SPAN);
520 }
521 if (infoHeader != null) {
522 html.startTag(HTMLWriter.SPAN);
523 html.writeAttr(HTMLWriter.CLASS, "hidden");
524 html.writeAttr(HTMLWriter.ID, infoId);
525 html.write(infoHeader);
526 html.newLine();
527 html.endTag(HTMLWriter.SPAN);
528 }
529 html.write(text);
530 html.endTag(HTMLWriter.P);
531
532 html.endTag(HTMLWriter.DIV);
533 }
534
535 @Override
536 void run(Example e) throws IOException {
537 StringWriter sw = new StringWriter();
538 PrintWriter pw = new PrintWriter(sw);
539 e.run(pw, raw, verbose);
540 pw.flush();
541
542 // only show Output: header if also showing files
543 if (showFiles) {
544 html.startTag(OUTPUT_HEADER);
545 html.write("Output:");
546 html.endTag(OUTPUT_HEADER);
547 }
548
549 html.startTag(HTMLWriter.DIV);
550 html.writeAttr(CLASS, OUTPUT);
551 html.startTag(HTMLWriter.P);
552 html.writeAttr(CLASS, OUTPUT);
553 String[] lines = sw.toString().split("\n");
554 for (String line: lines) {
555 html.write(line);
556 html.newLine();
557 }
558 html.endTag(HTMLWriter.P);
559 html.endTag(HTMLWriter.DIV);
560 }
561
562 String nextId() {
563 return "id" + (nextId++);
564 }
565
566 File file;
567 HTMLWriter html;
568 int nextId;
569 String currInitial = "";
570
571 static final String TITLE_HEADER = HTMLWriter.H3;
572 static final String INDEX_HEADER = HTMLWriter.H4;
573 static final String EXAMPLE_HEADER = HTMLWriter.H4;
574 static final String FILE_HEADER = HTMLWriter.H5;
575 static final String OUTPUT_HEADER = HTMLWriter.H5;
576 static final String CLASS = "class";
577 static final String FILE = "file";
578 static final String OUTPUT = "output";
579 }
580 }
581
582

mercurial