test/tools/javac/diags/RunExamples.java

Mon, 21 Jan 2013 20:13:56 +0000

author
mcimadamore
date
Mon, 21 Jan 2013 20:13:56 +0000
changeset 1510
7873d37f5b37
parent 1409
33abf479f202
child 1669
d3648557391b
permissions
-rw-r--r--

8005244: Implement overload resolution as per latest spec EDR
Summary: Add support for stuck expressions and provisional applicability
Reviewed-by: jjg

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

mercurial