Tue, 10 Apr 2012 08:15:25 -0700
7074397: Build infrastructure changes (makefile re-write)
Summary: New makefiles transition, old and new living side by side for now.
Reviewed-by: ohair, jjg, dholmes, ohrstrom, erikj, ihse, tgranat, ykantser
Contributed-by: ohrstrom <fredrik.ohrstrom@oracle.com>, erikj <erik.joelsson@oracle.com>, ihse <magnus.ihse.bursie@oracle.com>, tgranat <torbjorn.granat@oracle.com>, ykantser <yekaterina.kantserova@oracle.com>
1 /*
2 * Copyright (c) 2010, 2011, 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 */
24 /**
25 * @test
26 * @bug 6968063 7127924
27 * @summary provide examples of code that generate diagnostics
28 * @build ArgTypeCompilerFactory Example HTMLWriter RunExamples
29 * @run main/othervm RunExamples
30 */
31 /*
32 * See CR 7127924 for info on why othervm is used.
33 */
35 import java.io.*;
36 import java.text.SimpleDateFormat;
37 import java.util.*;
38 import java.util.regex.Matcher;
39 import java.util.regex.Pattern;
41 /**
42 * Utility to run selected or all examples, writing results to
43 * stdout, a plain text file or an HTML file. This program can be
44 * run standalone, or as a jtreg test.
45 *
46 * Options:
47 * -examples dir directory of examples. Defaults to ${test.src}/examples
48 * -raw run examples with -XDrawDiagnostics
49 * -showFiles include text of source files in the output
50 * -verbose verbose output
51 * -o file write output to file: format will be HTML if
52 * file has .html extension; otherwise it will be plain text.
53 * default is to stdout
54 * -title string specify a title, only applies to HTML output
55 */
56 public class RunExamples {
57 public static void main(String... args) throws Exception {
58 jtreg = (System.getProperty("test.src") != null);
59 File tmpDir;
60 if (jtreg) {
61 // use standard jtreg scratch directory: the current directory
62 tmpDir = new File(System.getProperty("user.dir"));
63 } else {
64 tmpDir = new File(System.getProperty("java.io.tmpdir"),
65 RunExamples.class.getName()
66 + (new SimpleDateFormat("yyMMddHHmmss")).format(new Date()));
67 }
68 Example.setTempDir(tmpDir);
70 RunExamples r = new RunExamples();
72 try {
73 if (r.run(args))
74 return;
75 } finally {
76 /* VERY IMPORTANT NOTE. In jtreg mode, tmpDir is set to the
77 * jtreg scratch directory, which is the current directory.
78 * In case someone is faking jtreg mode, make sure to only
79 * clean tmpDir when it is reasonable to do so.
80 */
81 if (tmpDir.isDirectory() &&
82 tmpDir.getName().startsWith(RunExamples.class.getName())) {
83 if (clean(tmpDir))
84 tmpDir.delete();
85 }
86 }
88 if (jtreg)
89 throw new Exception(r.errors + " errors occurred");
90 else
91 System.exit(1);
92 }
94 boolean run(String... args) {
95 Set<String> selectedKeys = new TreeSet<String>();
96 Set<Example> selectedExamples = new TreeSet<Example>();
97 File testSrc = new File(System.getProperty("test.src", "."));
98 File examplesDir = new File(testSrc, "examples");
99 File outFile = null;
100 boolean raw = false;
101 boolean showFiles = false;
102 boolean verbose = false;
103 boolean argTypes = false;
104 String title = null;
106 for (int i = 0; i < args.length; i++) {
107 String arg = args[i];
108 if (arg.equals("-k") && (i + 1) < args.length)
109 selectedKeys.add(args[++i]);
110 else if (arg.equals("-examples") && (i + 1) < args.length)
111 examplesDir = new File(args[++i]);
112 else if (arg.equals("-raw"))
113 raw = true;
114 else if (arg.equals("-showFiles"))
115 showFiles = true;
116 else if (arg.equals("-verbose"))
117 verbose = true;
118 else if (arg.equals("-o") && (i + 1) < args.length)
119 outFile = new File(args[++i]);
120 else if (arg.equals("-title") && (i + 1) < args.length)
121 title = args[++i];
122 else if (arg.equals("-argtypes"))
123 argTypes = true;
124 else if (arg.startsWith("-")) {
125 error("unknown option: " + arg);
126 return false;
127 } else {
128 while (i < args.length) {
129 File f = new File(examplesDir, args[i]);
130 selectedExamples.add(new Example(f));
131 i++;
132 }
133 }
134 }
136 // special mode to show message keys and the types of the args that
137 // are used.
138 if (argTypes)
139 Example.Compiler.factory = new ArgTypeCompilerFactory();
141 if (selectedKeys.size() > 0) {
142 Set<Example> examples = getExamples(examplesDir);
143 nextKey:
144 for (String k: selectedKeys) {
145 for (Example e: examples) {
146 if (e.getDeclaredKeys().contains(k))
147 continue nextKey;
148 }
149 error("Key " + k + ": no examples found");
150 }
151 } else {
152 if (selectedExamples.isEmpty())
153 selectedExamples = getExamples(examplesDir);
154 }
156 try {
157 Runner r;
158 if (outFile == null) {
159 PrintWriter out = new PrintWriter(System.out);
160 r = new TextRunner(out, showFiles, raw, verbose);
161 } else if (outFile.getName().endsWith(".html"))
162 r = new HTMLRunner(outFile, showFiles, raw, verbose, title);
163 else
164 r = new TextRunner(outFile, showFiles, raw, verbose);
165 r.run(selectedExamples);
166 r.close();
167 } catch (IOException e) {
168 error("Error writing output: " + e);
169 }
171 return (errors == 0);
172 }
174 /**
175 * Get the complete set of examples to be checked.
176 */
177 Set<Example> getExamples(File examplesDir) {
178 Set<Example> results = new TreeSet<Example>();
179 for (File f: examplesDir.listFiles()) {
180 if (isValidExample(f))
181 results.add(new Example(f));
182 }
183 return results;
184 }
186 boolean isValidExample(File f) {
187 return (f.isDirectory() && (!jtreg || f.list().length > 0)) ||
188 (f.isFile() && f.getName().endsWith(".java"));
189 }
191 /**
192 * Report an error.
193 */
194 void error(String msg) {
195 System.err.println("Error: " + msg);
196 errors++;
197 }
199 static boolean jtreg;
201 int errors;
203 /**
204 * Clean the contents of a directory.
205 */
206 static boolean clean(File dir) {
207 boolean ok = true;
208 for (File f: dir.listFiles()) {
209 if (f.isDirectory())
210 ok &= clean(f);
211 ok &= f.delete();
212 }
213 return ok;
214 }
216 static abstract class Runner {
217 Runner(boolean showFiles, boolean raw, boolean verbose) {
218 this.showFiles = showFiles;
219 this.raw = raw;
220 this.verbose = verbose;
221 }
223 void close() throws IOException { }
225 void run(Collection<Example> examples) throws IOException {
226 for (Example e: examples) {
227 startExample(e);
228 if (showFiles) {
229 showFile(e, e.infoFile);
230 Set<File> srcFiles = new TreeSet<File>(e.srcFiles);
231 srcFiles.remove(e.infoFile);
232 showFiles(e, srcFiles);
233 showFiles(e, e.srcPathFiles);
234 showFiles(e, e.procFiles);
235 showFiles(e, e.supportFiles);
236 }
237 run(e);
238 }
239 }
241 void showFiles(Example e, Collection<File> files) throws IOException {
242 for (File f: files)
243 showFile(e, f);
244 }
246 abstract void startExample(Example e) throws IOException;
248 abstract void showFile(Example e, File f) throws IOException;
250 abstract void run(Example e) throws IOException;
252 protected String read(File f) throws IOException {
253 byte[] bytes = new byte[(int) f.length()];
254 DataInputStream in = new DataInputStream(new FileInputStream(f));
255 try {
256 in.readFully(bytes);
257 } finally {
258 in.close();
259 }
260 return new String(bytes);
261 }
263 protected Pattern copyrightHeaderPat =
264 Pattern.compile("(?s)(/\\*.*?Copyright.*?\\*/\n)\\s*(.*)");
265 protected Pattern infoHeaderPat =
266 Pattern.compile("(?s)((?://\\s*[a-z]+:[^\n]*\n)+)\\s*(.*)");
268 protected boolean showFiles;
269 protected boolean raw;
270 protected boolean verbose;
271 }
273 static class TextRunner extends Runner {
274 TextRunner(File file, boolean showFiles, boolean raw, boolean verbose)
275 throws IOException {
276 super(showFiles, raw, verbose);
277 this.file = file;
278 out = new PrintWriter(new FileWriter(file));
279 }
281 TextRunner(PrintWriter out, boolean showFiles, boolean raw, boolean verbose)
282 throws IOException {
283 super(showFiles, raw, verbose);
284 this.out = out;
285 }
287 @Override
288 void close() {
289 if (file != null)
290 out.close();
291 }
293 @Override
294 void startExample(Example e) {
295 out.println("----- " + e.getName() + " --------------------");
296 out.println();
297 }
299 @Override
300 void showFile(Example e, File f) {
301 out.println("--- " + f);
302 String text;
303 try {
304 text = read(f);
305 } catch (IOException ex) {
306 text = "Error reading " + f + "; " + ex;
307 }
308 Matcher m = copyrightHeaderPat.matcher(text);
309 if (m.matches()) {
310 out.println("(Copyright)");
311 writeLines(m.group(2));
312 } else {
313 writeLines(text);
314 }
315 out.println();
316 }
318 @Override
319 void run(Example e) {
320 // only show Output: header if also showing files
321 if (showFiles)
322 out.println("--- Output:");
323 e.run(out, raw, verbose);
324 out.println();
325 }
327 void writeLines(String text) {
328 for (String line: text.split("\n"))
329 out.println(line);
330 }
332 File file;
333 PrintWriter out;
334 }
336 static class HTMLRunner extends Runner {
337 HTMLRunner(File file, boolean showFiles, boolean raw, boolean verbose, String title)
338 throws IOException {
339 super(showFiles, raw, verbose);
340 this.file = file;
341 PrintWriter out = new PrintWriter(new FileWriter(file));
342 html = new HTMLWriter(out);
343 html.startTag(HTMLWriter.HEAD);
344 if (title != null) {
345 html.startTag(HTMLWriter.TITLE);
346 html.write(title);
347 html.endTag(HTMLWriter.TITLE);
348 }
349 html.startTag(HTMLWriter.STYLE);
350 html.newLine();
351 html.writeLine("div.file { background-color:#e0ffe0; margin-left:30px; margin-right:30px;\n"
352 + " padding: 3px; border: thin solid silver; }");
353 html.writeLine("p.file { white-space: pre-wrap; font-family:monospace; margin: 0; }");
354 html.writeLine("div.output { background-color:#e0e0ff; margin-left:30px; margin-right:30px;\n"
355 + " padding: 3px; border: thin solid silver; }");
356 html.writeLine("p.output { white-space: pre-wrap; font-family:monospace; margin: 0; }");
357 html.writeLine("table.index { border: thin solid silver; }");
358 html.writeLine(".copyright { font-size: x-small }");
359 html.writeLine(".hidden { display:none }");
360 html.writeLine(".unhidden { display:block }");
361 html.writeLine(".odd { background-color: #e0e0e0 }");
362 html.writeLine(".even { background-color: white }");
363 html.endTag(HTMLWriter.STYLE);
364 html.startTag(HTMLWriter.SCRIPT);
365 html.writeAttr(HTMLWriter.TYPE, HTMLWriter.TEXT_JAVASCRIPT);
366 html.writeLine("\nfunction unhide(id) {\n"
367 + " var item = document.getElementById(id);\n"
368 + " if (item) {\n"
369 + " item.className=(item.className=='hidden')?'unhidden':'hidden';\n"
370 + " }\n"
371 + "}");
372 html.endTag(HTMLWriter.SCRIPT);
373 html.endTag(HTMLWriter.HEAD);
374 html.startTag(HTMLWriter.BODY);
375 if (title != null) {
376 html.startTag(TITLE_HEADER);
377 html.write(title);
378 html.endTag(TITLE_HEADER);
379 }
380 }
382 @Override
383 void close() throws IOException {
384 html.endTag(HTMLWriter.BODY);
385 html.newLine();
386 html.flush();
387 }
389 @Override
390 void run(Collection<Example> examples) throws IOException {
391 if (examples.size() > 1)
392 writeIndex(examples);
393 super.run(examples);
394 }
396 void writeIndex(Collection<Example> examples) throws IOException {
397 Map<String, Set<Example>> index = new TreeMap<String, Set<Example>>();
398 Set<String> initials = new HashSet<String>();
399 for (Example e: examples) {
400 for (String k: e.getDeclaredKeys()) {
401 Set<Example> s = index.get(k);
402 if (s == null)
403 index.put(k, s = new TreeSet<Example>());
404 s.add(e);
405 }
406 initials.add(e.getName().substring(0, 1).toUpperCase());
407 }
410 if (INDEX_HEADER != null) {
411 html.startTag(INDEX_HEADER);
412 html.write("Index");
413 html.endTag(INDEX_HEADER);
414 }
416 html.startTag(HTMLWriter.P);
417 html.writeLine("Examples: ");
418 for (char initial = 'A'; initial <= 'Z'; initial++) {
419 String s = String.valueOf(initial);
420 if (initials.contains(s)) {
421 html.writeLink("#" + s, s);
422 } else {
423 html.write(s);
424 }
425 html.newLine();
426 }
427 html.endTag(HTMLWriter.P);
429 html.startTag(HTMLWriter.TABLE);
430 html.writeAttr(HTMLWriter.CLASS, "index");
431 html.newLine();
432 int row = 0;
433 for (Map.Entry<String, Set<Example>> entry: index.entrySet()) {
434 html.startTag(HTMLWriter.TR);
435 html.writeAttr(HTMLWriter.CLASS,
436 (row++ % 2 == 0 ? "even" : "odd"));
437 html.startTag(HTMLWriter.TD);
438 html.writeAttr("valign", "top");
439 html.write(entry.getKey());
440 html.endTag(HTMLWriter.TD);
441 html.newLine();
442 html.startTag(HTMLWriter.TD);
443 html.writeAttr(HTMLWriter.ALIGN, "top");
444 String sep = "";
445 for (Example e: entry.getValue()) {
446 html.write(sep);
447 html.writeLink('#' + e.getName(), e.getName());
448 sep = ", ";
449 }
450 html.endTag(HTMLWriter.TD);
451 html.endTag(HTMLWriter.TR);
452 html.newLine();
453 }
454 html.endTag(HTMLWriter.TABLE);
455 }
457 @Override
458 void startExample(Example e) throws IOException {
459 String name = e.getName();
460 String initial = name.substring(0, 1).toUpperCase();
461 if (!initial.equals(currInitial)) {
462 html.writeLinkDestination(initial, "");
463 currInitial = initial;
464 }
465 html.writeLinkDestination(name, "");
466 html.startTag(EXAMPLE_HEADER);
467 html.write(e.getName());
468 html.endTag(EXAMPLE_HEADER);
469 }
471 @Override
472 void showFile(Example e, File f) throws IOException {
473 String text;
474 try {
475 text = read(f);
476 } catch (IOException ex) {
477 text = "Error reading " + f + ": " + ex;
478 }
479 if (!f.equals(e.file)) {
480 html.startTag(FILE_HEADER);
481 html.write(e.file.toURI().relativize(f.toURI()).toString());
482 html.endTag(FILE_HEADER);
483 }
484 html.startTag(HTMLWriter.DIV);
485 html.writeAttr(CLASS, FILE);
487 String legalHeader;
488 Matcher m1 = copyrightHeaderPat.matcher(text);
489 if (m1.matches()) {
490 legalHeader = m1.group(1);
491 text = m1.group(2);
492 } else
493 legalHeader = null;
495 String infoHeader;
496 Matcher m2 = infoHeaderPat.matcher(text);
497 if (m2.matches()) {
498 infoHeader = m2.group(1);
499 text = m2.group(2);
500 } else
501 infoHeader = null;
503 String legalId = null, infoId = null;
504 if (legalHeader != null || infoHeader != null) {
505 String sep = "";
506 html.startTag(HTMLWriter.SPAN);
507 html.writeStyleAttr("float: right");
508 if (legalHeader != null) {
509 legalId = nextId();
510 html.startTag(HTMLWriter.A);
511 html.writeAttr(HTMLWriter.HREF, "javascript:unhide('" + legalId + "');");
512 //html.writeEntity("©");
513 html.write("Copyright");
514 html.endTag(HTMLWriter.A);
515 sep = ", ";
516 }
517 if (infoHeader != null) {
518 html.write(sep);
519 infoId = nextId();
520 html.startTag(HTMLWriter.A);
521 html.writeAttr(HTMLWriter.HREF, "javascript:unhide('" + infoId + "');");
522 html.write("Info");
523 html.endTag(HTMLWriter.A);
524 sep = ", ";
525 }
526 html.endTag(HTMLWriter.SPAN);
527 }
529 html.startTag(HTMLWriter.P);
530 html.writeAttr(CLASS, FILE);
531 if (legalHeader != null) {
532 html.startTag(HTMLWriter.SPAN);
533 html.writeAttr(HTMLWriter.CLASS, "hidden");
534 html.writeAttr(HTMLWriter.ID, legalId);
535 html.write(legalHeader);
536 html.newLine();
537 html.endTag(HTMLWriter.SPAN);
538 }
539 if (infoHeader != null) {
540 html.startTag(HTMLWriter.SPAN);
541 html.writeAttr(HTMLWriter.CLASS, "hidden");
542 html.writeAttr(HTMLWriter.ID, infoId);
543 html.write(infoHeader);
544 html.newLine();
545 html.endTag(HTMLWriter.SPAN);
546 }
547 html.write(text);
548 html.endTag(HTMLWriter.P);
550 html.endTag(HTMLWriter.DIV);
551 }
553 @Override
554 void run(Example e) throws IOException {
555 StringWriter sw = new StringWriter();
556 PrintWriter pw = new PrintWriter(sw);
557 e.run(pw, raw, verbose);
558 pw.flush();
560 // only show Output: header if also showing files
561 if (showFiles) {
562 html.startTag(OUTPUT_HEADER);
563 html.write("Output:");
564 html.endTag(OUTPUT_HEADER);
565 }
567 html.startTag(HTMLWriter.DIV);
568 html.writeAttr(CLASS, OUTPUT);
569 html.startTag(HTMLWriter.P);
570 html.writeAttr(CLASS, OUTPUT);
571 String[] lines = sw.toString().split("\n");
572 for (String line: lines) {
573 html.write(line);
574 html.newLine();
575 }
576 html.endTag(HTMLWriter.P);
577 html.endTag(HTMLWriter.DIV);
578 }
580 String nextId() {
581 return "id" + (nextId++);
582 }
584 File file;
585 HTMLWriter html;
586 int nextId;
587 String currInitial = "";
589 static final String TITLE_HEADER = HTMLWriter.H3;
590 static final String INDEX_HEADER = HTMLWriter.H4;
591 static final String EXAMPLE_HEADER = HTMLWriter.H4;
592 static final String FILE_HEADER = HTMLWriter.H5;
593 static final String OUTPUT_HEADER = HTMLWriter.H5;
594 static final String CLASS = "class";
595 static final String FILE = "file";
596 static final String OUTPUT = "output";
597 }
598 }