1 11 package org.eclipse.swt.tools.internal; 12 import java.io.*; 13 import java.util.*; 14 15 16 public class MozillaGenerator { 17 FileReader r = null; 18 FileWriter w = null; 19 int maxLines = 1000; 20 int cntLines = 0; 21 int n = 0; 22 String [] b = null; 23 String body = null; 24 int nMethods = 0; 25 String uuidName; 26 String uuidValue; 27 String className; 28 String parentName; 29 String [] constantNames; 30 String [] constantValues; 31 String [] methodNames; 32 String [][] argTypes; 33 String [][] argNames; 34 String bodyOrder; 35 Hashtable vtbls; 36 37 static boolean DEBUG = false; 38 39 static String [] BEFORE_METHOD_NAME = { 45 " NS_IMETHOD ", 46 " NS_IMETHOD_(nsrefcnt) ", 47 " NS_IMETHOD_(void *) ", 48 " NS_IMETHOD_(void) " 49 }; 50 static String NO_SUPER_CLASS = "SWT_NO_SUPER_CLASS"; 51 52 static String [][] TYPES_C2JAVA = { 53 { "PRBool *", "boolean[]" }, 54 { "nsIID &", "nsID" }, 55 { "nsCID &", "nsID" }, 56 { "nsCID * *", "int /*long*/" }, { "* *", "int /*long*/[]" }, 58 { "**", "int /*long*/[]" }, 59 { "* &", "int /*long*/[]" }, 60 { "PRUint32 *", "int[]" }, 61 { "PRInt32 *", "int[]" }, 62 { "PRInt64 *", "long[]" }, 63 { "PRUnichar *", "char[]" }, 64 { "char *", "byte[]" }, 65 { "float *", "float[]" }, 66 { "PRUint16 *", "short[]" }, 67 { "nativeWindow *", "int /*long*/[]" }, 68 { "nsWriteSegmentFun", "int /*long*/" }, 69 { "nativeWindow", "int /*long*/" }, 70 71 { "*", "int /*long*/" }, { "&", "int /*long*/" }, 73 74 { "PRUint32", "int" }, 75 { "PRInt32", "int" }, 76 { "PRInt64", "long" }, 77 { "nsresult", "int" }, 78 { "PRBool", "boolean" }, 79 { "float", "float" }, 80 { "PRUint16", "short" }, 81 { "size_t", "int" }, 82 }; 83 84 static String GECKO = "/mozilla/mozilla/1.4/linux_gtk2/mozilla/dist/include/"; 85 static String TARGET_FOLDER = "/bluebird/teamswt/chrisx/amd64/workspace/org.eclipse.swt/Eclipse SWT Mozilla/common/org/eclipse/swt/internal/mozilla/"; 86 static String [] XPCOM_HEADERS = { 87 "profile/nsIProfile.h", 88 "widget/nsIAppShell.h", 89 "widget/nsIBaseWindow.h", 90 "xpcom/nsIComponentManager.h", 91 "xpcom/nsIComponentRegistrar.h", 92 "webbrwsr/nsIContextMenuListener.h", 93 "docshell/nsIDocShell.h", 94 "dom/nsIDOMEvent.h", 95 "dom/nsIDOMMouseEvent.h", 96 "dom/nsIDOMUIEvent.h", 97 "dom/nsIDOMWindow.h", 98 "uriloader/nsIDownload.h", 99 "webbrwsr/nsIEmbeddingSiteWindow.h", 100 "xpcom/nsIFactory.h", 101 "xpcom/nsIFile.h", 102 "helperAppDlg/nsIHelperAppLauncherDialog.h", 103 "exthandler/nsIExternalHelperAppService.h", "xpcom/nsIInputStream.h", 105 "xpcom/nsIInterfaceRequestor.h", 106 "necko/nsIIOService.h", 107 "xpcom/nsILocalFile.h", 108 "xpcom/nsIMemory.h", 109 "progressDlg/nsIProgressDialog.h", 110 "windowwatcher/nsIPromptService.h", 111 "xpcom/nsIServiceManager.h", 112 "xpcom/nsISupports.h", 113 "webbrwsr/nsITooltipListener.h", 114 "necko/nsIURI.h", 115 "uriloader/nsIURIContentListener.h", 116 "xpcom/nsIWeakReference.h", 117 "webbrwsr/nsIWebBrowser.h", 118 "webbrwsr/nsIWebBrowserChrome.h", 119 "webbrwsr/nsIWebBrowserChromeFocus.h", 120 "webbrwsr/nsIWebBrowserFocus.h", 121 "docshell/nsIWebNavigation.h", 122 "uriloader/nsIWebProgress.h", 123 "uriloader/nsIWebProgressListener.h", 124 "embed_base/nsIWindowCreator.h", 125 "windowwatcher/nsIWindowWatcher.h" }; 126 127 public static void main(String [] args) { 128 MozillaGenerator x = new MozillaGenerator(); 129 for (int i = 0; i < XPCOM_HEADERS.length; i++) 130 x.parse(GECKO + XPCOM_HEADERS[i], TARGET_FOLDER); 131 x.outputVtblCall(); 132 System.out.println("done"); 133 } 134 135 public MozillaGenerator() { 136 vtbls = new Hashtable(); 137 } 138 139 140 public void write(String data) { 141 if (DEBUG) { 142 System.out.print(data); 143 return; 144 } 145 try { 146 w.write(data); 147 } catch (IOException e) { 148 e.printStackTrace(); 149 } 150 } 151 152 public void writeLine() { 153 if (DEBUG) { 154 System.out.println(); 155 return; 156 } 157 write("\r\n"); 158 } 159 160 public void writeLine(String data) { 161 if (DEBUG) { 162 System.out.println(data); 163 return; 164 } 165 write(data + "\r\n"); 166 } 167 168 public void writeCopyrights() { 169 writeLine(COPYRIGHTS); 170 } 171 172 public void writePackageDeclaration() { 173 writeLine(PACKAGE_DECLARATION); 174 } 175 176 public void writeClassDeclaration(String className, String parentName) { 177 String line = "public class " + className; 178 if (!parentName.equals(NO_SUPER_CLASS)) line += " extends " + parentName; 179 line += " {"; 180 writeLine(line); 181 } 182 183 public void writeLastMethodId(String parentName, int nMethods) { 184 String line = "\tstatic final int LAST_METHOD_ID = "; 185 if (!parentName.equals(NO_SUPER_CLASS)) line += parentName + ".LAST_METHOD_ID + " + nMethods + ";"; 186 else line += "" + (nMethods - 1)+ ";"; writeLine(line); 188 } 189 190 public void writeIID(String uuidName, String uuidValue) { 191 writeLine("\tpublic static final String " + uuidName + " ="); 192 writeLine("\t\t\"" + uuidValue + "\";"); 193 writeLine(); 194 String iid = uuidName.substring(0, uuidName.indexOf("_STR")); 195 writeLine("\tpublic static final nsID " + iid + " ="); 196 writeLine("\t\tnew nsID(" + uuidName + ");"); 197 } 198 199 public void writeAddressField() { 200 writeLine("\tint /*long*/ address;"); 201 } 202 public void writeConstructor(String className, String parentName) { 203 writeLine("\tpublic " + className + "(int /*long*/ address) {"); 204 if (!parentName.equals(NO_SUPER_CLASS)) { 205 writeLine("\t\tsuper(address);"); 206 } else { 207 writeLine("\t\tthis.address = address;"); 208 } 209 writeLine("\t}"); 210 } 211 212 public void writeAddressGetter() { 213 writeLine("\tpublic int /*long*/ getAddress() {"); 214 writeLine("\t\treturn this.address;"); 215 writeLine("\t}"); 216 } 217 218 public void writeConstant(String name, String value) { 219 writeLine("\tpublic static final int " + name + " = " + value + ";"); 220 } 221 222 public void writeMethod(String name, String parentName, int methodIndex, String [] argTypes, String [] argNames) { 223 write("\tpublic int " + name + "("); 224 for (int i = 0; i < argTypes.length; i++) { 225 write(argTypes[i] + " " + argNames[i]); 226 if (i < argTypes.length - 1) 227 write(", "); 228 } 229 write(") {"); 230 writeLine(); 231 String line = "\t\treturn XPCOM.VtblCall("; 232 if (!parentName.equals(NO_SUPER_CLASS)) line += parentName + ".LAST_METHOD_ID + " + (methodIndex + 1) + ", getAddress()"; 233 else line += methodIndex + ", getAddress()"; write(line); 235 if (argTypes.length > 0) 236 write(", "); 237 for (int i = 0; i < argTypes.length; i++) { 238 write(argNames[i]); 239 if (i < argTypes.length - 1) 240 write(", "); 241 } 242 writeLine(");"); 243 writeLine("\t}"); 244 } 245 246 public void writeClassEnd() { 247 write("}"); 248 } 249 250 public void logVtblCall(String [] argTypes) { 251 String vtbl = "static final native int VtblCall(int fnNumber, int /*long*/ ppVtbl"; 252 if (argTypes.length > 0) 253 vtbl += ", "; 254 for (int i = 0; i < argTypes.length; i++) { 255 vtbl += argTypes[i] + " arg" + i; 256 if (i < argTypes.length - 1) 257 vtbl += ", "; 258 } 259 vtbl += ");"; 260 Integer key = new Integer (argTypes.length); 261 Vector list = (Vector) vtbls.get(key); 262 if (list == null) { 263 list = new Vector(); 264 vtbls.put(key, list); 265 } 266 boolean duplicate = false; 267 Enumeration e = list.elements(); 268 while (e.hasMoreElements()) { 269 String s = (String ) e.nextElement(); 270 if (vtbl.equals(s)) { 271 duplicate = true; 272 break; 273 } 274 } 275 if (!duplicate) 276 list.add(vtbl); 277 } 278 279 public void outputVtblCall() { 280 Enumeration e = vtbls.keys(); 281 int n = 0; 282 while (e.hasMoreElements()) { 283 e.nextElement(); 284 n++; 285 } 286 Integer [] keys = new Integer [n]; 287 e = vtbls.keys(); 288 n = 0; 289 while (e.hasMoreElements()) { 290 keys[n] = (Integer ) e.nextElement(); 291 n++; 292 } 293 Arrays.sort(keys); 294 for (int i = 0; i < keys.length; i++) { 295 Vector list = (Vector) vtbls.get(keys[i]); 296 Object [] elts = (Object []) list.toArray(); 297 Arrays.sort(elts); 298 for (int j = 0; j < elts.length; j++) { 299 System.out.println(elts[j]); 300 } 301 } 302 303 } 304 305 306 307 311 public void parse(String src, String destPath) { 312 if (DEBUG) writeLine("*** PARSING <"+src+"> to folder "+destPath); 313 b = new String [maxLines]; 314 cntLines = 0; 315 try { 316 r = new FileReader(src); 317 BufferedReader br = new BufferedReader(r); 318 while ((b[cntLines] = br.readLine()) != null) { 319 cntLines++; 320 } 321 br.close(); 322 } catch (IOException e) { 323 e.printStackTrace(); 324 return; 325 } 326 n = 0; 327 boolean lookForClasses = true; 328 while (lookForClasses) { 329 330 lookForClasses = parse(); 331 332 String destFile = destPath + className + ".java"; 333 try { 334 w = new FileWriter(destFile); 335 if (DEBUG) writeLine("** CREATED JAVA FILE <"+destFile+">"); 336 } catch (IOException e) { 337 e.printStackTrace(); 338 return; 339 } 340 341 342 writeCopyrights(); 343 writePackageDeclaration(); 344 writeLine(); 345 writeClassDeclaration(className, parentName); 346 writeLine(); 347 writeLastMethodId(parentName, nMethods); 348 writeLine(); 349 writeIID(uuidName, uuidValue); 350 writeLine(); 351 if (parentName.equals(NO_SUPER_CLASS)) { 352 writeAddressField(); 353 writeLine(); 354 } 355 writeConstructor(className, parentName); 356 writeLine(); 357 358 if (parentName.equals(NO_SUPER_CLASS)) { 359 writeAddressGetter(); 360 writeLine(); 361 } 362 363 int constantIndex = 0, methodIndex = 0; 364 for (int i = 0; i < bodyOrder.length(); i++) { 365 if (bodyOrder.charAt(i) == 'C') { 366 writeConstant(constantNames[constantIndex], 367 constantValues[constantIndex]); 368 if (i < bodyOrder.length() - 1) writeLine(); 369 constantIndex++; 370 } else if (bodyOrder.charAt(i) == 'M') { 371 writeMethod(methodNames[methodIndex], parentName, methodIndex, 372 argTypes[methodIndex], argNames[methodIndex]); 373 if (i < bodyOrder.length() - 1) writeLine(); 374 methodIndex++; 375 } 376 } 377 378 writeClassEnd(); 379 380 try { 381 w.close(); 382 } catch (IOException e) { 383 e.printStackTrace(); 384 } 385 } 386 } 387 388 public String getPackages() { 389 return "package org.eclipse.swt.internal.mozilla;"; 390 } 391 392 public boolean parse() { 393 if (!jumpToUuidDeclaration()) return false; 394 uuidName = getUuidName(b[n]); 395 if (DEBUG) 396 System.out.println("UUID name: <" + uuidName + ">"); 397 uuidValue = getUuidValue(b[n]); 398 if (DEBUG) 399 System.out.println("UUID value: <" + uuidValue + ">"); 400 jumpToInterfaceDeclaration(); 401 className = getClassName(b[n]); 402 if (DEBUG) 403 System.out.println("Interface name: <" + className + ">"); 404 parentName = getParentName(b[n]); 405 if (DEBUG) 406 System.out.println("parentName: <" + parentName + ">"); 407 parseBody(); 408 return true; 409 } 410 411 boolean jumpToUuidDeclaration() { 412 while (!(b[n].startsWith("#define ") && b[n].indexOf("_IID_STR \"") != -1)) { 414 n++; 415 if (n >= cntLines) return false; 416 } 417 return true; 418 } 419 420 String getUuidName(String declaration) { 423 return declaration.substring(declaration.indexOf("#define ") 424 + "#define ".length(), declaration.indexOf(" \"")); 425 } 426 427 String getUuidValue(String declaration) { 430 return declaration.substring(declaration.indexOf("_IID_STR \"") 431 + "_IID_STR \"".length(), declaration.lastIndexOf('"')); 432 } 433 434 void jumpToInterfaceDeclaration() { 435 while (!(b[n].startsWith("class NS_NO_VTABLE "))) { 437 n++; 438 } 439 } 440 441 String getClassName(String declaration) { 445 int endIndex = declaration.indexOf(" :"); 446 if (endIndex == -1) endIndex = declaration.indexOf(" {"); 448 return declaration.substring(declaration.indexOf("class NS_NO_VTABLE ") 449 + "class NS_NO_VTABLE ".length(), endIndex); 450 } 451 452 String getParentName(String declaration) { 456 if (declaration.indexOf(" :") == -1) return NO_SUPER_CLASS; 457 return declaration.substring(declaration.indexOf(": public ") 458 + ": public ".length(), declaration.indexOf(" {")); 459 } 460 461 void parseBody() { 467 body = ""; 468 bodyOrder = ""; 469 int nConstants = 0; 470 nMethods = 0; 471 472 int tmp_n = n; 473 while (true) { 474 int type = jumpToNextConstantOrMethod(); 475 if (type == CONSTANT) 476 nConstants++; 477 if (type == METHOD) 478 nMethods++; 479 if (type == END_BODY) 480 break; 481 n++; 482 } 483 n = tmp_n; 484 constantNames = new String [nConstants]; 485 constantValues = new String [nConstants]; 486 methodNames = new String [nMethods]; 487 argTypes = new String [nMethods][]; 488 argNames = new String [nMethods][]; 489 int constantIndex = 0, methodIndex = 0; 490 while (true) { 491 int type = jumpToNextConstantOrMethod(); 492 if (type == CONSTANT) { 493 parseConstant(b[n], constantIndex); 494 bodyOrder += "C"; 495 constantIndex++; 496 } 497 if (type == METHOD) { 498 parseMethod(b[n], methodIndex); 499 logVtblCall(argTypes[methodIndex]); 500 bodyOrder += "M"; 501 methodIndex++; 502 } 503 if (type == END_BODY) 504 return; 505 n++; 506 } 507 } 508 509 static int CONSTANT = 0; 510 511 static int METHOD = 1; 512 513 static int END_BODY = 2; 514 515 boolean isEndOfInterfaceBody() { 516 return b[n].startsWith("};"); 517 } 518 519 int jumpToNextConstantOrMethod() { 520 while (!isEndOfInterfaceBody()) { 521 if (b[n].startsWith(" enum { ")) { 522 return CONSTANT; 523 } 524 if (methodNameStartIndexOf(b[n]) != -1) { 525 return METHOD; 526 } 527 n++; 528 } 529 return END_BODY; 530 } 531 532 void parseConstant(String constant, int constantIndex) { 533 String constantName = constant.substring(constant.indexOf(" enum { ") 534 + " enum { ".length(), constant.indexOf(" =")); 535 if (DEBUG) 536 writeLine("constantName <" + constantName + ">"); 537 constantNames[constantIndex] = constantName; 538 539 int endIndex = constant.indexOf("U };"); 542 if (endIndex == -1) endIndex = constant.indexOf(" };"); 545 String constantValue = constant.substring(constant.indexOf(" = ") 546 + " = ".length(), endIndex); 547 if (DEBUG) 548 writeLine("constantValue <" + constantValue + ">"); 549 constantValues[constantIndex] = constantValue; 550 } 551 552 void parseMethod(String line, int methodIndex) { 561 int start = methodNameStartIndexOf(line); 562 int end = methodNameEndIndexOf(line); 563 String methodName = line.substring(start, end); 564 if (DEBUG) 565 writeLine("method name: <" + methodName + ">"); 566 methodNames[methodIndex] = methodName; 567 int argStart = end+"(".length(); 568 int argEnd = line.indexOf(")", argStart); 569 parseArgs(line.substring(argStart, argEnd), methodIndex); 570 } 571 572 int methodNameStartIndexOf(String line) { 575 for (int i = 0; i < BEFORE_METHOD_NAME.length; i++) { 576 int index = line.indexOf(BEFORE_METHOD_NAME[i]); 577 if (index != -1) return index + BEFORE_METHOD_NAME[i].length(); 578 } 579 return -1; 580 } 581 int methodNameEndIndexOf(String line) { 582 int startIndex = methodNameStartIndexOf(line); 583 return line.indexOf("(", startIndex); 584 } 585 void parseArgs(String args, int methodIndex) { 586 int nArgs = -1; 587 String [] noArgs = new String [] { "", "void" }; 589 for (int i = 0; i < noArgs.length; i++) { 590 if (args.equals(noArgs[i])) { 591 nArgs = 0; 592 break; 593 } 594 } 595 if (nArgs == -1) 596 nArgs = count(args, ", ") + 1; 597 String [] argTypes = new String [nArgs]; 598 this.argTypes[methodIndex] = argTypes; 599 String [] argNames = new String [nArgs]; 600 this.argNames[methodIndex] = argNames; 601 int typeStart = 0; 602 603 String [] typeNameSep = new String [] { " * *", " **", " * & ", " * ", " *", 605 " & ", " " }; 606 for (int i = 0; i < nArgs; i++) { 607 608 int nextTypeStart = i < nArgs - 1 ? args.indexOf(", ", typeStart) 609 + ", ".length() : args.length(); 610 int typeNameSepIndex = 0; 611 int separatorIndex = 0; 612 for (; typeNameSepIndex < typeNameSep.length; typeNameSepIndex++) { 613 separatorIndex = args.indexOf(typeNameSep[typeNameSepIndex], 614 typeStart); 615 if (separatorIndex != -1 && separatorIndex < nextTypeStart) 616 break; 617 } 618 String separator = typeNameSep[typeNameSepIndex]; 619 argTypes[i] = getC2JavaType(args.substring(typeStart, 620 separatorIndex + separator.length())); 621 if (DEBUG) 622 writeLine("arg type" + i + ": <" + argTypes[i] + ">"); 623 624 int nameStart = separatorIndex + separator.length(); 625 int nameEnd = i < nArgs - 1 ? args.indexOf(", ", nameStart) : args 626 .length(); 627 argNames[i] = args.substring(nameStart, nameEnd); 628 if (DEBUG) 629 writeLine("arg name" + i + ": <" + argNames[i] + ">"); 630 631 typeStart = nextTypeStart; 632 } 633 } 634 635 String getC2JavaType(String cType) { 636 for (int i = 0; i < TYPES_C2JAVA.length; i++) { 637 if (cType.indexOf(TYPES_C2JAVA[i][0]) != -1) 638 return TYPES_C2JAVA[i][1]; 639 } 640 return "!ERROR UNKNOWN C TYPE <" + cType + ">!"; 641 } 642 643 static int count(String s, String part) { 645 int index = -1, cnt = 0; 646 while ((index = s.indexOf(part, index + 1)) != -1) 647 cnt++; 648 return cnt; 649 } 650 651 static String COPYRIGHTS = 652 "/* ***** BEGIN LICENSE BLOCK *****\r\n" 653 + " * Version: MPL 1.1\r\n" 654 + " *\r\n" 655 + " * The contents of this file are subject to the Mozilla Public License Version\r\n" 656 + " * 1.1 (the \"License\"); you may not use this file except in compliance with\r\n" 657 + " * the License. You may obtain a copy of the License at\r\n" 658 + " * http://www.mozilla.org/MPL/\r\n" 659 + " *\r\n" 660 + " * Software distributed under the License is distributed on an \"AS IS\" basis,\r\n" 661 + " * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r\n" 662 + " * for the specific language governing rights and limitations under the\r\n" 663 + " * License.\r\n" 664 + " *\r\n" 665 + " * The Original Code is Mozilla Communicator client code, released March 31, 1998.\r\n" 666 + " *\r\n" 667 + " * The Initial Developer of the Original Code is\r\n" 668 + " * Netscape Communications Corporation.\r\n" 669 + " * Portions created by Netscape are Copyright (C) 1998-1999\r\n" 670 + " * Netscape Communications Corporation. All Rights Reserved.\r\n" 671 + " *\r\n" 672 + " * Contributor(s):\r\n" 673 + " *\r\n" 674 + " * IBM\r\n" 675 + " * - Binding to permit interfacing between Mozilla and SWT\r\n" 676 + " * - Copyright (C) 2003 IBM Corp. All Rights Reserved.\r\n" 677 + " *\r\n" + " * ***** END LICENSE BLOCK ***** */"; 678 679 static String PACKAGE_DECLARATION = "package org.eclipse.swt.internal.mozilla;"; 680 681 } 682 | Popular Tags |