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