1 /* 2 * Copyright (c) 1999, 2013, 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 import java.io.File; 26 import java.io.IOException; 27 import java.io.PrintWriter; 28 import java.util.Enumeration; 29 import java.util.Hashtable; 30 import java.util.Iterator; 31 import java.util.List; 32 import java.util.Stack; 33 import java.util.TreeSet; 34 import java.util.Vector; 35 36 abstract class HsArgHandler extends ArgHandler { 37 static final int STRING = 1; 38 static final int VECTOR = 2; 39 static final int HASH = 3; 40 41 boolean nextNotKey(ArgIterator it) { 42 if (it.next()) { 43 String s = it.get(); 44 return (s.length() == 0) || (s.charAt(0) != '-'); 45 } else { 46 return false; 47 } 48 } 49 50 void empty(String key, String message) { 51 if (key != null) { 52 System.err.println("** Error: empty " + key); 53 } 54 if (message != null) { 55 System.err.println(message); 56 } 57 WinGammaPlatform.usage(); 58 } 59 60 static String getCfg(String val) { 61 int under = val.indexOf('_'); 62 int len = val.length(); 63 if (under != -1 && under < len - 1) { 64 return val.substring(under+1, len); 65 } else { 66 return null; 67 } 68 } 69 } 70 71 class ArgRuleSpecific extends ArgRule { 72 ArgRuleSpecific(String arg, ArgHandler handler) { 73 super(arg, handler); 74 } 75 76 boolean match(String rulePattern, String arg) { 77 return rulePattern.startsWith(arg); 78 } 79 } 80 81 82 class SpecificHsArgHandler extends HsArgHandler { 83 84 String message, argKey, valKey; 85 int type; 86 87 public void handle(ArgIterator it) { 88 String cfg = getCfg(it.get()); 89 if (nextNotKey(it)) { 90 String val = it.get(); 91 switch (type) { 92 case VECTOR: 93 BuildConfig.addFieldVector(cfg, valKey, val); 94 break; 95 case HASH: 96 BuildConfig.putFieldHash(cfg, valKey, val, "1"); 97 break; 98 case STRING: 99 BuildConfig.putField(cfg, valKey, val); 100 break; 101 default: 102 empty(valKey, "Unknown type: "+type); 103 } 104 it.next(); 105 106 } else { 107 empty(argKey, message); 108 } 109 } 110 111 SpecificHsArgHandler(String argKey, String valKey, String message, int type) { 112 this.argKey = argKey; 113 this.valKey = valKey; 114 this.message = message; 115 this.type = type; 116 } 117 } 118 119 120 class HsArgRule extends ArgRuleSpecific { 121 122 HsArgRule(String argKey, String valKey, String message, int type) { 123 super(argKey, new SpecificHsArgHandler(argKey, valKey, message, type)); 124 } 125 126 } 127 128 public abstract class WinGammaPlatform { 129 130 public boolean fileNameStringEquality(String s1, String s2) { 131 return s1.equalsIgnoreCase(s2); 132 } 133 134 static void usage() throws IllegalArgumentException { 135 System.err.println("WinGammaPlatform platform-specific options:"); 136 System.err.println(" -sourceBase <path to directory (workspace) " + 137 "containing source files; no trailing slash>"); 138 System.err.println(" -projectFileName <full pathname to which project file " + 139 "will be written; all parent directories must " + 140 "already exist>"); 141 System.err.println(" If any of the above are specified, "+ 142 "they must all be."); 143 System.err.println(" Note: if '-altRelativeInclude' option below " + 144 "is used, then the '-relativeAltSrcInclude' " + 145 "option must be used to specify the alternate " + 146 "source dir, e.g., 'src\\closed'"); 147 System.err.println(" Additional, optional arguments, which can be " + 148 "specified multiple times:"); 149 System.err.println(" -absoluteInclude <string containing absolute " + 150 "path to include directory>"); 151 System.err.println(" -altRelativeInclude <string containing " + 152 "alternate include directory relative to " + 153 "-sourceBase>"); 154 System.err.println(" -relativeInclude <string containing include " + 155 "directory relative to -sourceBase>"); 156 System.err.println(" -define <preprocessor flag to be #defined " + 157 "(note: doesn't yet support " + 158 "#define (flag) (value))>"); 159 System.err.println(" -startAt <subdir of sourceBase>"); 160 System.err.println(" -additionalFile <file not in database but " + 161 "which should show up in project file>"); 162 System.err.println(" -additionalGeneratedFile <absolute path to " + 163 "directory containing file; no trailing slash> " + 164 "<name of file generated later in the build process>"); 165 throw new IllegalArgumentException(); 166 } 167 168 169 public void addPerFileLine(Hashtable table, 170 String fileName, 171 String line) { 172 Vector v = (Vector) table.get(fileName); 173 if (v != null) { 174 v.add(line); 175 } else { 176 v = new Vector(); 177 v.add(line); 178 table.put(fileName, v); 179 } 180 } 181 182 protected static class PerFileCondData { 183 public String releaseString; 184 public String debugString; 185 } 186 187 protected void addConditionalPerFileLine(Hashtable table, 188 String fileName, 189 String releaseLine, 190 String debugLine) { 191 PerFileCondData data = new PerFileCondData(); 192 data.releaseString = releaseLine; 193 data.debugString = debugLine; 194 Vector v = (Vector) table.get(fileName); 195 if (v != null) { 196 v.add(data); 197 } else { 198 v = new Vector(); 199 v.add(data); 200 table.put(fileName, v); 201 } 202 } 203 204 protected static class PrelinkCommandData { 205 String description; 206 String commands; 207 } 208 209 protected void addPrelinkCommand(Hashtable table, 210 String build, 211 String description, 212 String commands) { 213 PrelinkCommandData data = new PrelinkCommandData(); 214 data.description = description; 215 data.commands = commands; 216 table.put(build, data); 217 } 218 219 public boolean findString(Vector v, String s) { 220 for (Iterator iter = v.iterator(); iter.hasNext(); ) { 221 if (((String) iter.next()).equals(s)) { 222 return true; 223 } 224 } 225 226 return false; 227 } 228 229 String getProjectName(String fullPath, String extension) 230 throws IllegalArgumentException, IOException { 231 File file = new File(fullPath).getCanonicalFile(); 232 fullPath = file.getCanonicalPath(); 233 String parent = file.getParent(); 234 235 if (!fullPath.endsWith(extension)) { 236 throw new IllegalArgumentException("project file name \"" + 237 fullPath + 238 "\" does not end in "+extension); 239 } 240 241 if ((parent != null) && 242 (!fullPath.startsWith(parent))) { 243 throw new RuntimeException( 244 "Internal error: parent of file name \"" + parent + 245 "\" does not match file name \"" + fullPath + "\"" 246 ); 247 } 248 249 int len = parent.length(); 250 if (!parent.endsWith(Util.sep)) { 251 len += Util.sep.length(); 252 } 253 254 int end = fullPath.length() - extension.length(); 255 256 if (len == end) { 257 throw new RuntimeException( 258 "Internal error: file name was empty" 259 ); 260 } 261 262 return fullPath.substring(len, end); 263 } 264 265 protected abstract String getProjectExt(); 266 267 public void createVcproj(String[] args) 268 throws IllegalArgumentException, IOException { 269 270 parseArguments(args); 271 272 String projectFileName = BuildConfig.getFieldString(null, "ProjectFileName"); 273 String ext = getProjectExt(); 274 275 String projectName = getProjectName(projectFileName, ext); 276 277 writeProjectFile(projectFileName, projectName, createAllConfigs(BuildConfig.getFieldString(null, "PlatformName"))); 278 } 279 280 protected void writePrologue(String[] args) { 281 System.err.println("WinGammaPlatform platform-specific arguments:"); 282 for (int i = 0; i < args.length; i++) { 283 System.err.print(args[i] + " "); 284 } 285 System.err.println(); 286 } 287 288 289 void parseArguments(String[] args) { 290 new ArgsParser(args, 291 new ArgRule[] 292 { 293 new ArgRule("-sourceBase", 294 new HsArgHandler() { 295 public void handle(ArgIterator it) { 296 String cfg = getCfg(it.get()); 297 if (nextNotKey(it)) { 298 String sb = (String) it.get(); 299 if (sb.endsWith(Util.sep)) { 300 sb = sb.substring(0, sb.length() - 1); 301 } 302 BuildConfig.putField(cfg, "SourceBase", sb); 303 it.next(); 304 } else { 305 empty("-sourceBase", null); 306 } 307 } 308 } 309 ), 310 311 new HsArgRule("-buildBase", 312 "BuildBase", 313 " (Did you set the HotSpotBuildSpace environment variable?)", 314 HsArgHandler.STRING 315 ), 316 317 new HsArgRule("-buildSpace", 318 "BuildSpace", 319 null, 320 HsArgHandler.STRING 321 ), 322 323 new HsArgRule("-platformName", 324 "PlatformName", 325 null, 326 HsArgHandler.STRING 327 ), 328 329 new HsArgRule("-projectFileName", 330 "ProjectFileName", 331 null, 332 HsArgHandler.STRING 333 ), 334 335 new HsArgRule("-jdkTargetRoot", 336 "JdkTargetRoot", 337 " (Did you set the HotSpotJDKDist environment variable?)", 338 HsArgHandler.STRING 339 ), 340 341 new HsArgRule("-compiler", 342 "CompilerVersion", 343 " (Did you set the VcVersion correctly?)", 344 HsArgHandler.STRING 345 ), 346 347 new HsArgRule("-absoluteInclude", 348 "AbsoluteInclude", 349 null, 350 HsArgHandler.VECTOR 351 ), 352 353 new HsArgRule("-altRelativeInclude", 354 "AltRelativeInclude", 355 null, 356 HsArgHandler.VECTOR 357 ), 358 359 new HsArgRule("-relativeInclude", 360 "RelativeInclude", 361 null, 362 HsArgHandler.VECTOR 363 ), 364 365 new HsArgRule("-absoluteSrcInclude", 366 "AbsoluteSrcInclude", 367 null, 368 HsArgHandler.VECTOR 369 ), 370 371 new HsArgRule("-relativeAltSrcInclude", 372 "RelativeAltSrcInclude", 373 null, 374 HsArgHandler.STRING 375 ), 376 377 new HsArgRule("-relativeSrcInclude", 378 "RelativeSrcInclude", 379 null, 380 HsArgHandler.VECTOR 381 ), 382 383 new HsArgRule("-define", 384 "Define", 385 null, 386 HsArgHandler.VECTOR 387 ), 388 389 new HsArgRule("-useToGeneratePch", 390 "UseToGeneratePch", 391 null, 392 HsArgHandler.STRING 393 ), 394 395 new ArgRuleSpecific("-perFileLine", 396 new HsArgHandler() { 397 public void handle(ArgIterator it) { 398 String cfg = getCfg(it.get()); 399 if (nextNotKey(it)) { 400 String fileName = it.get(); 401 if (nextNotKey(it)) { 402 String line = it.get(); 403 BuildConfig.putFieldHash(cfg, "PerFileLine", fileName, line); 404 it.next(); 405 return; 406 } 407 } 408 empty(null, "** Error: wrong number of args to -perFileLine"); 409 } 410 } 411 ), 412 413 new ArgRuleSpecific("-conditionalPerFileLine", 414 new HsArgHandler() { 415 public void handle(ArgIterator it) { 416 String cfg = getCfg(it.get()); 417 if (nextNotKey(it)) { 418 String fileName = it.get(); 419 if (nextNotKey(it)) { 420 String productLine = it.get(); 421 if (nextNotKey(it)) { 422 String debugLine = it.get(); 423 BuildConfig.putFieldHash(cfg+"_debug", "CondPerFileLine", 424 fileName, debugLine); 425 BuildConfig.putFieldHash(cfg+"_product", "CondPerFileLine", 426 fileName, productLine); 427 it.next(); 428 return; 429 } 430 } 431 } 432 433 empty(null, "** Error: wrong number of args to -conditionalPerFileLine"); 434 } 435 } 436 ), 437 438 new HsArgRule("-disablePch", 439 "DisablePch", 440 null, 441 HsArgHandler.HASH 442 ), 443 444 new ArgRule("-startAt", 445 new HsArgHandler() { 446 public void handle(ArgIterator it) { 447 if (BuildConfig.getField(null, "StartAt") != null) { 448 empty(null, "** Error: multiple -startAt"); 449 } 450 if (nextNotKey(it)) { 451 BuildConfig.putField(null, "StartAt", it.get()); 452 it.next(); 453 } else { 454 empty("-startAt", null); 455 } 456 } 457 } 458 ), 459 460 new HsArgRule("-ignoreFile", 461 "IgnoreFile", 462 null, 463 HsArgHandler.HASH 464 ), 465 466 new HsArgRule("-ignorePath", 467 "IgnorePath", 468 null, 469 HsArgHandler.VECTOR 470 ), 471 472 new HsArgRule("-hidePath", 473 "HidePath", 474 null, 475 HsArgHandler.VECTOR 476 ), 477 478 new HsArgRule("-additionalFile", 479 "AdditionalFile", 480 null, 481 HsArgHandler.VECTOR 482 ), 483 484 new ArgRuleSpecific("-additionalGeneratedFile", 485 new HsArgHandler() { 486 public void handle(ArgIterator it) { 487 String cfg = getCfg(it.get()); 488 if (nextNotKey(it)) { 489 String dir = it.get(); 490 if (nextNotKey(it)) { 491 String fileName = it.get(); 492 BuildConfig.putFieldHash(cfg, "AdditionalGeneratedFile", 493 Util.normalize(dir + Util.sep + fileName), 494 fileName); 495 it.next(); 496 return; 497 } 498 } 499 empty(null, "** Error: wrong number of args to -additionalGeneratedFile"); 500 } 501 } 502 ), 503 504 new ArgRule("-prelink", 505 new HsArgHandler() { 506 public void handle(ArgIterator it) { 507 if (nextNotKey(it)) { 508 if (nextNotKey(it)) { 509 String description = it.get(); 510 if (nextNotKey(it)) { 511 String command = it.get(); 512 BuildConfig.putField(null, "PrelinkDescription", description); 513 BuildConfig.putField(null, "PrelinkCommand", command); 514 it.next(); 515 return; 516 } 517 } 518 } 519 520 empty(null, "** Error: wrong number of args to -prelink"); 521 } 522 } 523 ), 524 525 new ArgRule("-postbuild", 526 new HsArgHandler() { 527 public void handle(ArgIterator it) { 528 if (nextNotKey(it)) { 529 if (nextNotKey(it)) { 530 String description = it.get(); 531 if (nextNotKey(it)) { 532 String command = it.get(); 533 BuildConfig.putField(null, "PostbuildDescription", description); 534 BuildConfig.putField(null, "PostbuildCommand", command); 535 it.next(); 536 return; 537 } 538 } 539 } 540 541 empty(null, "** Error: wrong number of args to -postbuild"); 542 } 543 } 544 ), 545 }, 546 new ArgHandler() { 547 public void handle(ArgIterator it) { 548 549 throw new RuntimeException("Arg Parser: unrecognized option "+it.get()); 550 } 551 } 552 ); 553 if (BuildConfig.getField(null, "SourceBase") == null || 554 BuildConfig.getField(null, "BuildBase") == null || 555 BuildConfig.getField(null, "ProjectFileName") == null || 556 BuildConfig.getField(null, "CompilerVersion") == null) { 557 usage(); 558 } 559 560 if (BuildConfig.getField(null, "UseToGeneratePch") == null) { 561 throw new RuntimeException("ERROR: need to specify one file to compute PCH, with -useToGeneratePch flag"); 562 } 563 564 BuildConfig.putField(null, "PlatformObject", this); 565 } 566 567 Vector createAllConfigs(String platform) { 568 Vector allConfigs = new Vector(); 569 570 allConfigs.add(new C1DebugConfig()); 571 allConfigs.add(new C1FastDebugConfig()); 572 allConfigs.add(new C1ProductConfig()); 573 574 allConfigs.add(new C2DebugConfig()); 575 allConfigs.add(new C2FastDebugConfig()); 576 allConfigs.add(new C2ProductConfig()); 577 578 allConfigs.add(new TieredDebugConfig()); 579 allConfigs.add(new TieredFastDebugConfig()); 580 allConfigs.add(new TieredProductConfig()); 581 582 return allConfigs; 583 } 584 585 PrintWriter printWriter; 586 587 public void writeProjectFile(String projectFileName, String projectName, 588 Vector<BuildConfig> allConfigs) throws IOException { 589 throw new RuntimeException("use compiler version specific version"); 590 } 591 592 int indent; 593 private Stack<String> tagStack = new Stack<String>(); 594 595 private void startTagPrim(String name, String[] attrs, boolean close) { 596 startTagPrim(name, attrs, close, true); 597 } 598 599 private void startTagPrim(String name, String[] attrs, boolean close, 600 boolean newline) { 601 doIndent(); 602 printWriter.print("<" + name); 603 indent++; 604 605 if (attrs != null && attrs.length > 0) { 606 for (int i = 0; i < attrs.length; i += 2) { 607 printWriter.print(" " + attrs[i] + "=\"" + attrs[i + 1] + "\""); 608 if (i < attrs.length - 2) { 609 } 610 } 611 } 612 613 if (close) { 614 indent--; 615 printWriter.print(" />"); 616 } else { 617 // TODO push tag name, and change endTag to pop and print. 618 tagStack.push(name); 619 printWriter.print(">"); 620 } 621 if (newline) { 622 printWriter.println(); 623 } 624 } 625 626 void startTag(String name, String... attrs) { 627 startTagPrim(name, attrs, false); 628 } 629 630 void startTagV(String name, Vector attrs) { 631 String s[] = new String[attrs.size()]; 632 for (int i = 0; i < attrs.size(); i++) { 633 s[i] = (String) attrs.elementAt(i); 634 } 635 startTagPrim(name, s, false); 636 } 637 638 void endTag() { 639 String name = tagStack.pop(); 640 indent--; 641 doIndent(); 642 printWriter.println("</" + name + ">"); 643 } 644 645 private void endTagNoIndent() { 646 String name = tagStack.pop(); 647 indent--; 648 printWriter.println("</" + name + ">"); 649 } 650 651 void tag(String name, String... attrs) { 652 startTagPrim(name, attrs, true); 653 } 654 655 void tagData(String name, String data) { 656 startTagPrim(name, null, false, false); 657 printWriter.print(data); 658 endTagNoIndent(); 659 } 660 661 void tagData(String name, String data, String... attrs) { 662 startTagPrim(name, attrs, false, false); 663 printWriter.print(data); 664 endTagNoIndent(); 665 } 666 667 void tagV(String name, Vector attrs) { 668 String s[] = new String[attrs.size()]; 669 for (int i = 0; i < attrs.size(); i++) { 670 s[i] = (String) attrs.elementAt(i); 671 } 672 startTagPrim(name, s, true); 673 } 674 675 void doIndent() { 676 for (int i = 0; i < indent; i++) { 677 printWriter.print(" "); 678 } 679 } 680 681 682 }