1 /*
   2  * Copyright (c) 2003, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package build.tools.x11wrappergen;
  27 
  28 import java.util.*;
  29 import java.io.*;
  30 import java.nio.charset.*;
  31 import java.text.MessageFormat;
  32 import java.util.logging.Level;
  33 import java.util.logging.Logger;
  34 
  35 public class WrapperGenerator {
  36     /* XLibParser converts Xlib.h to a Java Object that encapsulates the
  37      * X11 API and data structures */
  38     // Charset and decoder for ISO-8859-15
  39     private final static Logger log = Logger.getLogger("WrapperGenerator");
  40     boolean generateLog = true;
  41     boolean wide;
  42     private static Charset charset = Charset.forName("ISO-8859-15");
  43 
  44     String package_name = "sun.awt.X11";
  45     String package_path = "sun/awt/X11";
  46     String sizerFileName = "sizer.c";
  47     String defaultBaseClass = "XWrapperBase";
  48 
  49     String compile_options = "-lX11";
  50     static Hashtable symbolTable = new Hashtable();
  51     static Hashtable sizeTable32bit = new Hashtable();
  52     static Hashtable sizeTable64bit = new Hashtable();
  53     static Hashtable knownSizes32 = new Hashtable();
  54     static Hashtable knownSizes64 = new Hashtable();
  55     static {
  56 /*
  57         knownSizes64.put("", Integer.valueOf());
  58         knownSizes32.put("", Integer.valueOf());
  59 */
  60         knownSizes64.put("XComposeStatus", Integer.valueOf(16));
  61         knownSizes64.put("XTimeCoord", Integer.valueOf(16));
  62         knownSizes64.put("XExtData", Integer.valueOf(32));
  63         knownSizes64.put("XWindowChanges", Integer.valueOf(40));
  64         knownSizes64.put("XOMCharSetList", Integer.valueOf(16));
  65         knownSizes64.put("XModifierKeymap", Integer.valueOf(16));
  66         knownSizes32.put("XIMValuesList", Integer.valueOf(8));
  67         knownSizes32.put("XGCValues", Integer.valueOf(92));
  68 //          knownSizes32.put("XIMStringConversionCallbackStruct", Integer.valueOf(16));
  69     }
  70 
  71     private static abstract class BaseType {
  72 
  73         String real_type;
  74         String name;
  75 
  76 
  77         public String getName() {
  78             return name;
  79         }
  80         public String getRealType() {
  81             return real_type;
  82         }
  83 
  84         public String toString() {
  85             return name;
  86         }
  87     }
  88 
  89     private static class AtomicType extends BaseType {
  90 
  91         private boolean alias;
  92         private String aliasName;
  93 
  94         static final int TYPE_INT=0;
  95         static final int TYPE_CHAR=1;
  96         static final int TYPE_LONG=2;
  97         static final int TYPE_LONG_LONG=3;
  98         static final int TYPE_DOUBLE=4;
  99         static final int TYPE_FLOAT=5;
 100         static final int TYPE_PTR=6;
 101         static final int TYPE_SHORT=7;
 102         static final int TYPE_BOOL = 8;
 103         static final int TYPE_STRUCT = 9;
 104         static final int TYPE_ARRAY = 10;
 105         static final int TYPE_BYTE=11;
 106         static final int TYPE_ATOM = 12;
 107         static final int TYPE_ULONG = 13;
 108         static int getTypeForString(String str) {
 109             int type=-1;
 110             if (str.equals("int"))
 111                 type = AtomicType.TYPE_INT;
 112             else if (str.equals("long"))
 113                 type = AtomicType.TYPE_LONG;
 114             else if (str.equals("byte"))
 115                 type = AtomicType.TYPE_BYTE;
 116             else if (str.equals("char"))
 117                 type = AtomicType.TYPE_CHAR;
 118             else if (str.equals("long long"))
 119                 type = AtomicType.TYPE_LONG_LONG;
 120             else if (str.equals("double"))
 121                 type = AtomicType.TYPE_DOUBLE;
 122             else if (str.equals("float"))
 123                 type = AtomicType.TYPE_FLOAT;
 124             else if (str.equals("pointer"))
 125                 type = AtomicType.TYPE_PTR;
 126             else if (str.equals("short"))
 127                 type = AtomicType.TYPE_SHORT;
 128             else if (str.equals("Bool"))
 129                 type = AtomicType.TYPE_BOOL;
 130             else if (str.equals("struct"))
 131                 type = AtomicType.TYPE_STRUCT;
 132             else if (str.equals("Atom"))
 133                 type = AtomicType.TYPE_ATOM;
 134             else if (str.equals("array"))
 135                 type = TYPE_ARRAY;
 136             else if (str.equals("ulong"))
 137                 type = TYPE_ULONG;
 138             else throw new IllegalArgumentException("Uknown type string: " + str);
 139 
 140             return type;
 141         }
 142         String getJavaType() {
 143             if (referencedType != null) {
 144                 if (referencedType instanceof AtomicType) {
 145                     return ((AtomicType)referencedType).getJavaType();
 146                 } else {
 147                     return referencedType.getName();
 148                 }
 149             } else {
 150                 return getJavaTypeForType(type);
 151             }
 152         }
 153         static String getJavaTypeForType(int type) {
 154             switch (type) {
 155               case TYPE_INT:
 156                   return "int";
 157               case TYPE_CHAR:
 158                   return "char";
 159               case TYPE_BYTE:
 160                   return "byte";
 161               case TYPE_LONG:
 162               case TYPE_LONG_LONG:
 163               case TYPE_PTR:
 164               case TYPE_ULONG:
 165                   return "long";
 166               case TYPE_DOUBLE:
 167                   return "double";
 168               case TYPE_FLOAT:
 169                   return "float";
 170               case TYPE_SHORT:
 171                   return "short";
 172               case TYPE_BOOL:
 173                   return "boolean";
 174               case TYPE_ATOM:
 175                   return "long";
 176               default:
 177                   throw new IllegalArgumentException("Unknown type: " + type);
 178             }
 179         }
 180         String getItemSize() {
 181             if (referencedType != null) {
 182                   if (referencedType instanceof StructType) {
 183                       return ((StructType)referencedType).getSize();
 184                   } else {
 185                       return ((AtomicType)referencedType).getItemSize();
 186                   }
 187             } else {
 188                 int i32 = getNativeSizeForAccess(getJavaAccess(false));
 189                 int i64 = getNativeSizeForAccess(getJavaAccess(true));
 190                 if (i32 != i64) {
 191                     return "Native.get" + getNativeAccess() + "Size()";
 192                 } else {
 193                     return Integer.toString(i32);
 194                 }
 195             }
 196         }
 197 
 198         String getJavaResult(String offset, String base) {
 199             String res = null;
 200             switch (type) {
 201               case TYPE_STRUCT:
 202                   res = "pData + " + offset;
 203                   break;
 204               case TYPE_PTR:
 205                   if (referencedType == null || referencedType instanceof StructType) {
 206                       res = base + "+" + offset;
 207                   } else if (referencedType instanceof AtomicType) {
 208                       res = MessageFormat.format("Native.get{0}({1})",
 209                                                  new Object[] {getNativeAccessForType(((AtomicType)referencedType).type),
 210                                                                base + "+" + offset});
 211                   }
 212                   break;
 213               case TYPE_ARRAY:
 214                   if (referencedType instanceof StructType) {
 215                       res = "pData + " + offset;
 216                   }  else if (referencedType instanceof AtomicType) {
 217                       res = MessageFormat.format("Native.get{0}(pData + {1})",
 218                                                  new Object[] {getNativeAccessForType(((AtomicType)referencedType).type),
 219                                                                offset});
 220                   }
 221                   break;
 222               default:
 223                 res = MessageFormat.format("(Native.get{0}(pData+{1}))",
 224                                            new Object[] {getNativeAccess(), offset});
 225             }
 226             return getJavaResultConversion(res, base);
 227         }
 228         String getJavaResultConversion(String value, String base) {
 229             if (referencedType != null) {
 230                 if (referencedType instanceof StructType) {
 231                     if (type == TYPE_PTR) {
 232                         return MessageFormat.format("({2} != 0)?(new {0}({1})):(null)", new Object[] {referencedType.getName(),value, base});
 233                     } else {
 234                         return MessageFormat.format("new {0}({1})", new Object[] {referencedType.getName(),value});
 235                     }
 236                 } else {
 237                     return value;
 238                 }
 239             } else {
 240                 return getJavaResultConversionForType(type, value);
 241             }
 242         }
 243         static String getJavaResultConversionForType(int type, String value) {
 244             return value;
 245         }
 246         String getNativeAccess() {
 247             return getNativeAccessForType(type);
 248         }
 249         String getJavaAccess(boolean wide) {
 250             return getJavaAccessForType(type, wide);
 251         }
 252         static String getJavaAccessForType(int type, boolean wide) {
 253             switch (type) {
 254               case TYPE_INT:
 255                   return "Int";
 256               case TYPE_CHAR:
 257                   return "Char";
 258               case TYPE_BYTE:
 259                   return "Byte";
 260               case TYPE_LONG:
 261               case TYPE_PTR:
 262               case TYPE_ARRAY:
 263               case TYPE_STRUCT:
 264               case TYPE_ATOM:
 265                   return (wide?"Long":"Int");
 266               case TYPE_LONG_LONG:
 267                   return "Long";
 268               case TYPE_ULONG:
 269                   return (wide?"ULong":"UInt");
 270               case TYPE_DOUBLE:
 271                   return "Double";
 272               case TYPE_FLOAT:
 273                   return "Float";
 274               case TYPE_SHORT:
 275                   return "Short";
 276               case TYPE_BOOL:
 277                   return "Int";
 278               default:
 279                   throw new IllegalArgumentException("Unknown type: " + type);
 280             }
 281         }
 282         static String getNativeAccessForType(int type) {
 283             switch (type) {
 284               case TYPE_INT:
 285                   return "Int";
 286               case TYPE_CHAR:
 287                   return "Char";
 288               case TYPE_BYTE:
 289                   return "Byte";
 290               case TYPE_LONG:
 291               case TYPE_PTR:
 292               case TYPE_ARRAY:
 293               case TYPE_STRUCT:
 294                   return "Long";
 295               case TYPE_LONG_LONG:
 296                   return "Long";
 297               case TYPE_ULONG:
 298                   return "ULong";
 299               case TYPE_DOUBLE:
 300                   return "Double";
 301               case TYPE_FLOAT:
 302                   return "Float";
 303               case TYPE_SHORT:
 304                   return "Short";
 305               case TYPE_BOOL:
 306                   return "Bool";
 307               case TYPE_ATOM:
 308                   return "Long";
 309               default:
 310                   throw new IllegalArgumentException("Unknown type: " + type);
 311             }
 312         }
 313 
 314         static int getNativeSizeForAccess(String access) {
 315             if (access.equals("Int")) return 4;
 316             else if (access.equals("Byte")) return 1;
 317             else if (access.equals("Long")) return 8;
 318             else if (access.equals("Double")) return 8;
 319             else if (access.equals("Float")) return 4;
 320             else if (access.equals("Char")) return 2;
 321             else if (access.equals("Short")) return 2;
 322             else if (access.equals("ULong")) return 8;
 323             else if (access.equals("UInt")) return 4;
 324             else throw new IllegalArgumentException("Unknow access type: " + access);
 325         }
 326 
 327         String getJavaConversion(String offset, String value) {
 328             if (referencedType != null) {
 329                 if (referencedType instanceof StructType) {
 330                     return getJavaConversionForType(TYPE_PTR, offset, value + ".pData");
 331                 } else {
 332                     if (type == TYPE_ARRAY) {
 333                         return getJavaConversionForType(((AtomicType)referencedType).type, offset, value);
 334                     } else { // TYPE_PTR
 335                         return getJavaConversionForType(TYPE_PTR, offset, value);
 336                     }
 337                 }
 338             } else {
 339                 return getJavaConversionForType(type, offset, value);
 340             }
 341         }
 342         static String getJavaConversionForType(int type, String offset, String value) {
 343             return MessageFormat.format("Native.put{0}({2}, {1})", new Object[] {getNativeAccessForType(type), value, offset});
 344         }
 345 
 346 
 347         int type;
 348         int offset;
 349         int direction;
 350         BaseType referencedType;
 351         int arrayLength = -1;
 352         boolean autoFree = false;
 353         public AtomicType(int _type,String _name, String _real_type) {
 354             name = _name.replaceAll("[* \t]","");
 355             if ((name.indexOf("[") != -1) || (name.indexOf("]") != -1))
 356             {
 357                 name = name.replaceAll("\\[.*\\]","");
 358             }
 359             type = _type;
 360             real_type = _real_type;
 361             if (real_type == null)
 362             {
 363                 System.out.println(" real type is null");
 364 
 365             }
 366         }
 367         public boolean isIn() {
 368             return direction == 0;
 369         }
 370         public boolean isOut() {
 371             return direction == 1;
 372         }
 373         public boolean isInOut() {
 374             return direction == 2;
 375         }
 376         public boolean isAutoFree() {
 377             return autoFree;
 378         }
 379         public void setAttributes(String[] attributes) {
 380             String mod = attributes[3];
 381             if ("in".equals(mod)) {
 382                 direction = 0;
 383             } else if ("out".equals(mod)) {
 384                 direction = 1;
 385                 if (attributes.length > 4 && "free".equals(attributes[4])) {
 386                     autoFree = true;
 387                 }
 388             } else if ("inout".equals(mod)) {
 389                 direction = 2;
 390             } else if ("alias".equals(mod)) {
 391                 alias = true;
 392                 aliasName = attributes[4];
 393             } else if (type == TYPE_ARRAY || type == TYPE_PTR || type == TYPE_STRUCT) {
 394                 referencedType = (BaseType)symbolTable.get(mod);
 395                 if (referencedType == null) {
 396                     log.warning("Can't find type for name " + mod);
 397                 }
 398                 if (attributes.length > 4) { // array length
 399                     try {
 400                         arrayLength = Integer.parseInt(attributes[4]);
 401                     } catch (Exception e) {
 402                     }
 403                 }
 404             }
 405         }
 406         public BaseType getReferencedType() {
 407             return referencedType;
 408         }
 409         public int getArrayLength() {
 410             return arrayLength;
 411         }
 412         public void setOffset(int o)
 413         {
 414             offset = o;
 415         }
 416         public int getType() {
 417             return type;
 418         }
 419         public String getTypeUpperCase() {
 420             switch (type) {
 421               case TYPE_INT:
 422                   return "Int";
 423               case TYPE_CHAR:
 424                   return "Char";
 425               case TYPE_BYTE:
 426                   return "Byte";
 427               case TYPE_LONG:
 428               case TYPE_LONG_LONG:
 429               case TYPE_PTR:
 430                   return "Long";
 431               case TYPE_DOUBLE:
 432                   return "Double";
 433               case TYPE_FLOAT:
 434                   return "Float";
 435               case TYPE_SHORT:
 436                   return "Short";
 437               case TYPE_BOOL:
 438                   return "Int";
 439               case TYPE_ATOM:
 440                   return "Long";
 441               case TYPE_ULONG:
 442                   return "ULong";
 443               default: throw new IllegalArgumentException("Uknown type");
 444             }
 445         }
 446         public int getOffset()
 447         {
 448             return offset;
 449         }
 450         public boolean isAlias() {
 451             return alias;
 452         }
 453         public String getAliasName() {
 454             return aliasName;
 455         }
 456     }
 457 
 458     private static class StructType extends BaseType {
 459 
 460         Vector members;
 461         String description;
 462         boolean packed;
 463         int size;
 464         String baseClass, interfaces;
 465         boolean isInterface;
 466         String javaClassName;
 467 
 468         /**
 469          * Construct new structured type.
 470          * Description is used for name and type definition and has the following format:
 471          * structName [ '[' base classe ']' ] [ '{' interfaces '}' ] [ '|' javaClassName ]
 472          */
 473         public StructType(String _desc)
 474         {
 475             members = new Vector();
 476             parseDescription(_desc);
 477         }
 478         public int getNumFields()
 479         {
 480             return members.size();
 481         }
 482         public void setName(String _name)
 483         {
 484             _name = _name.replaceAll("[* \t]","");
 485             parseDescription(_name);
 486         }
 487 
 488         public void setSize(int i)
 489         {
 490             size = i;
 491         }
 492 
 493         public String getDescription()
 494         {
 495             return description;
 496         }
 497 
 498         public Enumeration getMembers()
 499         {
 500             return members.elements();
 501         }
 502 
 503         public void addMember(BaseType tp)
 504         {
 505             members.add(tp);
 506         }
 507         public String getBaseClass() {
 508             return baseClass;
 509         }
 510         public String getInterfaces() {
 511             return interfaces;
 512         }
 513         public boolean getIsInterface() {
 514             return isInterface;
 515         }
 516         public String getJavaClassName() {
 517             return javaClassName;
 518         }
 519         void parseDescription(String _desc) {
 520             if (_desc.indexOf('[') != -1) { // Has base class
 521                 baseClass = _desc.substring(_desc.indexOf('[')+1, _desc.indexOf(']'));
 522                 _desc = _desc.substring(0, _desc.indexOf('[')) + _desc.substring(_desc.indexOf(']')+1);
 523             }
 524             if (_desc.indexOf('{') != -1) { // Has base class
 525                 interfaces = _desc.substring(_desc.indexOf('{')+1, _desc.indexOf('}'));
 526                 _desc = _desc.substring(0, _desc.indexOf('{')) + _desc.substring(_desc.indexOf('}')+1);
 527             }
 528             if (_desc.startsWith("-")) { // Interface
 529                 isInterface = true;
 530                 _desc = _desc.substring(1, _desc.length());
 531             }
 532             if (_desc.indexOf("|") != -1) {
 533                 javaClassName = _desc.substring(_desc.indexOf('|')+1, _desc.length());
 534                 _desc = _desc.substring(0, _desc.indexOf('|'));
 535             }
 536             name = _desc;
 537             if (javaClassName == null) {
 538                 javaClassName = name;
 539             }
 540             description = _desc;
 541 //              System.out.println("Struct " + name + " extends " + baseClass + " implements " + interfaces);
 542         }
 543 
 544         /**
 545          * Returns String containing Java code calculating size of the structure depending on the data model
 546          */
 547         public String getSize() {
 548             String s32 = (String) WrapperGenerator.sizeTable32bit.get(getName());
 549             String s64 = (String) WrapperGenerator.sizeTable64bit.get(getName());
 550             if (s32 == null || s64 == null) {
 551                 return (s32 == null)?(s64):(s32);
 552             }
 553             if (s32.equals(s64)) {
 554                 return s32;
 555             } else {
 556                 return MessageFormat.format("((XlibWrapper.dataModel == 32)?({0}):({1}))", new Object[] {s32, s64});
 557             }
 558         }
 559         public String getOffset(AtomicType atp) {
 560             String key = getName()+"."+(atp.isAlias() ? atp.getAliasName() : atp.getName());
 561             String s64 = (String) WrapperGenerator.sizeTable64bit.get(key);
 562             String s32 = (String) WrapperGenerator.sizeTable32bit.get(key);
 563             if (s32 == null || s64 == null) {
 564                 return (s32 == null)?(s64):(s32);
 565             }
 566             if (s32.equals(s64)) {
 567                 return s32;
 568             } else {
 569                 return MessageFormat.format("((XlibWrapper.dataModel == 32)?({0}):({1}))", new Object[]{s32, s64});
 570             }
 571         }
 572     }
 573 
 574     private static class FunctionType extends BaseType {
 575 
 576         Vector args;
 577         String description;
 578         boolean packed;
 579         String returnType;
 580 
 581         int alignment;
 582 
 583         public FunctionType(String _desc)
 584         {
 585             args = new Vector();
 586             description = _desc;
 587             setName(_desc);
 588         }
 589         boolean isVoid() {
 590             return (returnType == null);
 591         }
 592         String getReturnType() {
 593             if (returnType == null) {
 594                 return "void";
 595             } else {
 596                 return returnType;
 597             }
 598         }
 599 
 600         public int getNumArgs()
 601         {
 602             return args.size();
 603         }
 604         public void setName(String _name)
 605         {
 606             if (_name.startsWith("!")) {
 607                 _name = _name.substring(1, _name.length());
 608             }
 609             if (_name.indexOf("|") != -1) {
 610                 returnType = _name.substring(_name.indexOf("|")+1, _name.length());
 611                 _name = _name.substring(0, _name.indexOf("|"));
 612             }
 613             name = _name.replaceAll("[* \t]","");
 614         }
 615 
 616         public String getDescription()
 617         {
 618             return description;
 619         }
 620 
 621         public Collection getArguments()
 622         {
 623             return args;
 624         }
 625         public void addArgument(BaseType tp)
 626         {
 627             args.add(tp);
 628         }
 629     }
 630 
 631     public String makeComment(String str)
 632     {
 633         StringTokenizer st = new StringTokenizer(str,"\r\n");
 634         String ret="";
 635 
 636         while (st.hasMoreTokens())
 637         {
 638             ret = ret + "//" + st.nextToken() + "\n";
 639         }
 640 
 641         return ret;
 642     }
 643 
 644     public String getJavaTypeForSize(int size) {
 645         switch(size) {
 646           case 1: return "byte";
 647           case 2: return "short";
 648           case 4: return "int";
 649           case 8: return "long";
 650           default: throw new RuntimeException("Unsupported size: " + size);
 651         }
 652     }
 653     public String getOffsets(StructType stp,AtomicType atp, boolean wide)
 654     {
 655         String key = stp.getName()+"."+atp.getName();
 656         return wide == true ? (String) sizeTable64bit.get(key) : (String) sizeTable32bit.get(key);
 657     }
 658 
 659     public String getStructSize(StructType stp, boolean wide)
 660     {
 661         return wide == true ? (String) sizeTable64bit.get(stp.getName()) : (String) sizeTable32bit.get(stp.getName());
 662     }
 663 
 664     public int getLongSize(boolean wide)
 665     {
 666         return Integer.parseInt(wide == true ? (String)sizeTable64bit.get("long") : (String)sizeTable32bit.get("long"));
 667     }
 668 
 669     public int getPtrSize(boolean wide)
 670     {
 671         return Integer.parseInt(wide == true ? (String)sizeTable64bit.get("ptr") : (String)sizeTable32bit.get("ptr"));
 672     }
 673     public int getBoolSize(boolean wide) {
 674         return getOrdinalSize("Bool", wide);
 675     }
 676     public int getOrdinalSize(String ordinal, boolean wide) {
 677         return Integer.parseInt(wide == true ? (String)sizeTable64bit.get(ordinal) : (String)sizeTable32bit.get(ordinal));
 678     }
 679 
 680     public void writeToString(StructType stp, PrintWriter pw) {
 681         int type;
 682         pw.println("\n\n\tString getName() {\n\t\treturn \"" + stp.getName()+ "\"; \n\t}");
 683         pw.println("\n\n\tString getFieldsAsString() {\n\t\tStringBuilder ret = new StringBuilder(" + stp.getNumFields() * 40 + ");\n");
 684 
 685         for (Enumeration e = stp.getMembers() ; e.hasMoreElements() ;) {
 686             AtomicType tp = (AtomicType) e.nextElement();
 687 
 688             type = tp.getType();
 689             String name = tp.getName().replace('.', '_');
 690             if ((name != null) && (name.length() > 0))
 691             {
 692                 if (type == AtomicType.TYPE_ATOM) {
 693                     pw.println("\t\tret.append(\"" + name + " = \" ).append( XAtom.get(get_" + name + "()) ).append(\", \");");
 694                 } else if (name.equals("type")) {
 695                     pw.println("\t\tret.append(\"type = \").append( XlibWrapper.eventToString[get_type()] ).append(\", \");");
 696                 } else if (name.equals("window")){
 697                     pw.println("\t\tret.append(\"window = \" ).append( getWindow(get_window()) ).append(\", \");");
 698                 } else if (type == AtomicType.TYPE_ARRAY) {
 699                     pw.print("\t\tret.append(\"{\")");
 700                     for (int i = 0; i < tp.getArrayLength(); i++) {
 701                         pw.print("\n\t\t.append( get_" + name + "(" + i + ") ).append(\" \")");
 702                     }
 703                     pw.println(".append( \"}\");");
 704                 } else {
 705                     pw.println("\t\tret.append(\"" + name +" = \").append( get_"+ name+"() ).append(\", \");");
 706                 }
 707             }
 708 
 709         }
 710         pw.println("\t\treturn ret.toString();\n\t}\n\n");
 711     }
 712 
 713     public void writeStubs(StructType stp, PrintWriter pw) {
 714         int type;
 715         String prefix = "";
 716         if (!stp.getIsInterface()) {
 717             prefix = "\t\tabstract ";
 718         } else {
 719             prefix = "\t";
 720         }
 721         for (Enumeration e = stp.getMembers() ; e.hasMoreElements() ;) {
 722             AtomicType tp = (AtomicType) e.nextElement();
 723 
 724             type = tp.getType();
 725             String name = tp.getName().replace('.','_');
 726             if ((name != null) && (name.length() > 0))
 727             {
 728                 if (type == AtomicType.TYPE_ARRAY) {
 729                     // Returns pointer to the start of the array
 730                     pw.println(prefix + "long get_" +name +"();");
 731 
 732                     pw.println(prefix + tp.getJavaType() + " get_" +name +"(int index);");
 733                     pw.println(prefix + "void set_" +name +"(int index, " + tp.getJavaType() + " v);");
 734                 } else {
 735                     pw.println(prefix + tp.getJavaType() + " get_" +name +"();");
 736                     if (type != AtomicType.TYPE_STRUCT) pw.println(prefix + "void set_" +name +"(" + tp.getJavaType() + " v);");
 737                 }
 738             }
 739         }
 740     }
 741 
 742     private int padSize(int size, int wordLength) {
 743         int bytesPerWord = wordLength / 8;
 744         // Make size dividable by bytesPerWord
 745         return (size + bytesPerWord / 2) / bytesPerWord * bytesPerWord;
 746     }
 747 
 748     public void writeAccessorImpls(StructType stp, PrintWriter pw) {
 749         int type;
 750         int i=0;
 751         String s_size_32 = getStructSize(stp, false);
 752         String s_size_64 = getStructSize(stp, true);
 753         int acc_size_32 = 0;
 754         int acc_size_64 = 0;
 755         String s_log = (generateLog?"log.finest(\"\");":"");
 756         for (Enumeration e = stp.getMembers() ; e.hasMoreElements() ;) {
 757             AtomicType tp = (AtomicType) e.nextElement();
 758 
 759             type = tp.getType();
 760             String name = tp.getName().replace('.','_');
 761             String pref = "\tpublic " ;
 762             if ((name != null) && (name.length() > 0))
 763             {
 764                 String jt = tp.getJavaType();
 765                 String ja_32 = tp.getJavaAccess(false);
 766                 String ja_64 = tp.getJavaAccess(true);
 767                 String ja = ja_32;
 768                 int elemSize_32 = AtomicType.getNativeSizeForAccess(ja_32);
 769                 int elemSize_64 = AtomicType.getNativeSizeForAccess(ja_64);
 770                 String elemSize = tp.getItemSize();
 771                 if (type == AtomicType.TYPE_ARRAY) {
 772                     acc_size_32 += elemSize_32 * tp.getArrayLength();
 773                     acc_size_64 += elemSize_64 * tp.getArrayLength();
 774                     pw.println(pref + tp.getJavaType() + " get_" +name + "(int index) { " +s_log+"return " +
 775                                tp.getJavaResult(stp.getOffset(tp) + "+index*" + elemSize, null) + "; }");
 776                     if (tp.getReferencedType() instanceof AtomicType) { // Set for StructType is forbidden
 777                         pw.println(MessageFormat.format(pref + "void set_{0}(int index, {1} v) '{' {3} {2}; '}'",
 778                                                         new Object[] {
 779                                                             name, jt,
 780                                                             tp.getJavaConversion("pData+"+stp.getOffset(tp)+" + index*" + elemSize, "v"),
 781                                                             s_log}));
 782                     }
 783                     // Returns pointer to the start of the array
 784                     pw.println(pref + "long get_" +name+ "() { "+s_log+"return pData+"+stp.getOffset(tp)+"; }");
 785                 } else if (type == AtomicType.TYPE_PTR) {
 786                     pw.println(MessageFormat.format(pref + "{0} get_{1}(int index) '{' {3} return {2}; '}'",
 787                                          new Object[] {
 788                                              jt, name,
 789                                              tp.getJavaResult("index*" + elemSize, "Native.getLong(pData+"+stp.getOffset(tp)+")"),
 790                                              s_log
 791                                              }));
 792                     pw.println(pref + "long get_" +name+ "() { "+s_log+"return Native.getLong(pData+"+stp.getOffset(tp)+"); }");
 793                     pw.println(MessageFormat.format(pref + "void set_{0}({1} v) '{' {3} {2}; '}'",
 794                                                     new Object[] {name, "long", "Native.putLong(pData + " + stp.getOffset(tp) + ", v)", s_log}));
 795                     acc_size_32 += elemSize_32;
 796                     acc_size_64 += elemSize_64;
 797                 } else {
 798                     acc_size_32 += elemSize_32;
 799                     acc_size_64 += elemSize_64;
 800                     pw.println(pref + tp.getJavaType() + " get_" +name +
 801                                "() { "+s_log+"return " + tp.getJavaResult(stp.getOffset(tp), null) + "; }");
 802                     if (type != AtomicType.TYPE_STRUCT) {
 803                         pw.println(MessageFormat.format(pref + "void set_{0}({1} v) '{' {3} {2}; '}'",
 804                                                         new Object[] {name, jt, tp.getJavaConversion("pData+"+stp.getOffset(tp), "v"), s_log}));
 805                     }
 806                 }
 807                 i++;
 808             }
 809         }
 810         if (s_size_32 != null && !s_size_32.equals(Integer.toString(acc_size_32))) {
 811             if (log.isLoggable(Level.FINE)) {
 812                 log.fine("32 bits: The size of the structure " + stp.getName() + " " + s_size_32 +
 813                         " is not equal to the accumulated size " +acc_size_32 + " of the fields");
 814             }
 815         } else if (s_size_64 != null && !s_size_64.equals(Integer.toString(acc_size_64))) {
 816             if (log.isLoggable(Level.FINE)) {
 817                 log.fine("64 bits: The size of the structure " + stp.getName() + " " +s_size_64+
 818                         " is not equal to the accumulated size " +acc_size_64+" of the fields");
 819             }
 820         }
 821     }
 822 
 823     public void writeWrapperSubclass(StructType stp, PrintWriter pw, boolean wide) {
 824 
 825 
 826         pw.println("class " + stp.getJavaClassName() + "AccessorImpl"  + " extends " + stp.getJavaClassName() + "Accessor  {");
 827         pw.println("/*\nThis class serves as a Wrapper for the following X Struct \nsThe offsets here are calculated based on actual compiler.\n\n" +stp.getDescription() + "\n\n */");
 828 
 829         writeAccessorImpls(stp, pw);
 830 
 831         pw.println("\n\n } \n\n");
 832     }
 833 
 834     public void writeWrapper(String outputDir, StructType stp)
 835     {
 836         if (stp.getNumFields() > 0) {
 837 
 838             try {
 839                 FileOutputStream fs =  new FileOutputStream(outputDir + "/"+stp.getJavaClassName()+".java");
 840                 PrintWriter pw = new PrintWriter(fs);
 841                 pw.println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n" );
 842 
 843                 pw.println("package "+package_name+";\n");
 844                 pw.println("import sun.misc.*;\n");
 845                 pw.println("import sun.util.logging.PlatformLogger;");
 846                 String baseClass = stp.getBaseClass();
 847                 if (baseClass == null) {
 848                     baseClass = defaultBaseClass;
 849                 }
 850                 if (stp.getIsInterface()) {
 851                     pw.print("public interface ");
 852                     pw.print(stp.getJavaClassName());
 853                 } else {
 854                     pw.print("public class ");
 855                     pw.print(stp.getJavaClassName() + " extends " + baseClass);
 856                 }
 857                 if (stp.getInterfaces() != null) {
 858                     pw.print(" implements " + stp.getInterfaces());
 859                 }
 860                 pw.println(" { ");
 861                 if (!stp.getIsInterface()) {
 862                     pw.println("\tprivate Unsafe unsafe = XlibWrapper.unsafe; ");
 863                     pw.println("\tprivate final boolean should_free_memory;");
 864                     pw.println("\tpublic static int getSize() { return " + stp.getSize() + "; }");
 865                     pw.println("\tpublic int getDataSize() { return getSize(); }");
 866                     pw.println("\n\tlong pData;");
 867                     pw.println("\n\tpublic long getPData() { return pData; }");
 868 
 869                     pw.println("\n\n\tpublic " + stp.getJavaClassName() + "(long addr) {");
 870                     if (generateLog) {
 871                         pw.println("\t\tlog.finest(\"Creating\");");
 872                     }
 873                     pw.println("\t\tpData=addr;");
 874                     pw.println("\t\tshould_free_memory = false;");
 875                     pw.println("\t}");
 876                     pw.println("\n\n\tpublic " + stp.getJavaClassName() + "() {");
 877                     if (generateLog) {
 878                         pw.println("\t\tlog.finest(\"Creating\");");
 879                     }
 880                     pw.println("\t\tpData = unsafe.allocateMemory(getSize());");
 881                     pw.println("\t\tshould_free_memory = true;");
 882                     pw.println("\t}");
 883 
 884                     pw.println("\n\n\tpublic void dispose() {");
 885                     if (generateLog) {
 886                         pw.println("\t\tlog.finest(\"Disposing\");");
 887                     }
 888                     pw.println("\t\tif (should_free_memory) {");
 889                     if (generateLog) {
 890                         pw.println("\t\t\tlog.finest(\"freeing memory\");");
 891                     }
 892                     pw.println("\t\t\tunsafe.freeMemory(pData); \n\t}");
 893                     pw.println("\t\t}");
 894                     writeAccessorImpls(stp, pw);
 895                     writeToString(stp,pw);
 896                 } else {
 897                     pw.println("\n\n\tvoid dispose();");
 898                     pw.println("\n\tlong getPData();");
 899                     writeStubs(stp,pw);
 900                 }
 901 
 902 
 903                 pw.println("}\n\n\n");
 904                 pw.close();
 905             }
 906             catch (Exception e)
 907             {
 908                 e.printStackTrace();
 909             }
 910         }
 911     }
 912 
 913     private boolean readSizeInfo(InputStream is, boolean wide) {
 914         String line;
 915         String splits[];
 916         BufferedReader in  = new BufferedReader(new InputStreamReader(is));
 917         try {
 918             while ((line = in.readLine()) != null)
 919             {
 920                 splits = line.split("\\p{Space}");
 921                 if (splits.length == 2)
 922                 {
 923                     if (wide) {
 924                         sizeTable64bit.put(splits[0],splits[1]);
 925                     } else {
 926                         sizeTable32bit.put(splits[0],splits[1]);
 927                     }
 928                 }
 929             }
 930             return true;
 931         } catch (Exception e) {
 932             e.printStackTrace();
 933             return false;
 934         }
 935     }
 936 
 937     public void writeFunctionCallWrapper(String outputDir, FunctionType ft) {
 938         try {
 939             FileOutputStream fs =  new FileOutputStream(outputDir + "/" + ft.getName()+".java");
 940             PrintWriter pw = new PrintWriter(fs);
 941             pw.println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n" );
 942 
 943             pw.println("package "+package_name+";\n");
 944             pw.println("import sun.misc.Unsafe;\n");
 945             pw.println("class " + ft.getName() + " {");
 946             pw.println("\tprivate static Unsafe unsafe = XlibWrapper.unsafe;");
 947             pw.println("\tprivate boolean __executed = false;");
 948             pw.println("\tprivate boolean __disposed = false;");
 949             Iterator iter = ft.getArguments().iterator();
 950             while (iter.hasNext()) {
 951                 AtomicType at = (AtomicType)iter.next();
 952                 if (at.isIn()) {
 953                     pw.println("\t" + at.getJavaType() + " _" + at.getName() + ";");
 954                 } else {
 955                     pw.println("\tlong " + at.getName() + "_ptr = unsafe.allocateMemory(Native.get" + at.getTypeUpperCase() + "Size());");
 956                 }
 957             }
 958             pw.println("\tpublic " + ft.getName() + "(");
 959             iter = ft.getArguments().iterator();
 960             boolean first = true;
 961             while (iter.hasNext()) {
 962                 AtomicType at = (AtomicType)iter.next();
 963                 if (at.isIn() || at.isInOut()) {
 964                     if (!first) {
 965                         pw.println(",");
 966                     }
 967                     first = false;
 968                     pw.print("\t\t" + at.getJavaType() + " " + at.getName());
 969                 }
 970             }
 971             pw.println("\t)");
 972             pw.println("\t{");
 973             iter = ft.getArguments().iterator();
 974             while (iter.hasNext()) {
 975                 AtomicType at = (AtomicType)iter.next();
 976                 if (at.isIn() || at.isInOut()) {
 977                     pw.println("\t\tset_" + at.getName() + "(" + at.getName() + ");");
 978                 }
 979             }
 980             pw.println("\t}");
 981 
 982             pw.println("\tpublic " + ft.getReturnType() + " execute() {");
 983             if (ft.isVoid()) {
 984                 pw.println("\t\texecute(null);");
 985             } else {
 986                 pw.println("\t\treturn execute(null);");
 987             }
 988             pw.println("\t}");
 989 
 990             pw.println("\tpublic " + ft.getReturnType() + " execute(XToolkit.XErrorHandler errorHandler) {");
 991             pw.println("\t\tif (__disposed) {");
 992             pw.println("\t\t    throw new IllegalStateException(\"Disposed\");");
 993             pw.println("\t\t}");
 994             pw.println("\t\tXToolkit.awtLock();");
 995             pw.println("\t\ttry {");
 996             pw.println("\t\t\tif (__executed) {");
 997             pw.println("\t\t\t    throw new IllegalStateException(\"Already executed\");");
 998             pw.println("\t\t\t}");
 999             pw.println("\t\t\t__executed = true;");
1000             pw.println("\t\t\tif (errorHandler != null) {");
1001             pw.println("\t\t\t    XErrorHandlerUtil.WITH_XERROR_HANDLER(errorHandler);");
1002             pw.println("\t\t\t}");
1003             iter = ft.getArguments().iterator();
1004             while (iter.hasNext()) {
1005                 AtomicType at = (AtomicType)iter.next();
1006                 if (!at.isIn() && at.isAutoFree()) {
1007                     pw.println("\t\t\tNative.put" + at.getTypeUpperCase() + "(" +at.getName() + "_ptr, 0);");
1008                 }
1009             }
1010             if (!ft.isVoid()) {
1011                 pw.println("\t\t\t" + ft.getReturnType() + " status = ");
1012             }
1013             pw.println("\t\t\tXlibWrapper." + ft.getName() + "(XToolkit.getDisplay(), ");
1014             iter = ft.getArguments().iterator();
1015             first = true;
1016             while (iter.hasNext()) {
1017                 AtomicType at = (AtomicType)iter.next();
1018                 if (!first) {
1019                     pw.println(",");
1020                 }
1021                 first = false;
1022                 if (at.isIn()) {
1023                     pw.print("\t\t\t\tget_" + at.getName() + "()");
1024                 } else {
1025                     pw.print("\t\t\t\t" + at.getName() + "_ptr");
1026                 }
1027             }
1028             pw.println("\t\t\t);");
1029             pw.println("\t\t\tif (errorHandler != null) {");
1030             pw.println("\t\t\t    XErrorHandlerUtil.RESTORE_XERROR_HANDLER();");
1031             pw.println("\t\t\t}");
1032             if (!ft.isVoid()) {
1033                 pw.println("\t\t\treturn status;");
1034             }
1035             pw.println("\t\t} finally {");
1036             pw.println("\t\t    XToolkit.awtUnlock();");
1037             pw.println("\t\t}");
1038             pw.println("\t}");
1039 
1040             pw.println("\tpublic boolean isExecuted() {");
1041             pw.println("\t    return __executed;");
1042             pw.println("\t}");
1043             pw.println("\t");
1044             pw.println("\tpublic boolean isDisposed() {");
1045             pw.println("\t    return __disposed;");
1046             pw.println("\t}");
1047             pw.println("\tpublic void finalize() {");
1048             pw.println("\t    dispose();");
1049             pw.println("\t}");
1050 
1051             pw.println("\tpublic void dispose() {");
1052             pw.println("\t\tXToolkit.awtLock();");
1053             pw.println("\t\ttry {");
1054             pw.println("\t\tif (__disposed || !__executed) {");
1055             pw.println("\t\t    return;");
1056             pw.println("\t\t} finally {");
1057             pw.println("\t\t    XToolkit.awtUnlock();");
1058             pw.println("\t\t}");
1059             pw.println("\t\t}");
1060 
1061             iter = ft.getArguments().iterator();
1062             while (iter.hasNext()) {
1063                 AtomicType at = (AtomicType)iter.next();
1064                 if (!at.isIn()) {
1065                     if (at.isAutoFree()) {
1066                         pw.println("\t\tif (__executed && get_" + at.getName() + "()!= 0) {");
1067                         pw.println("\t\t\tXlibWrapper.XFree(get_" + at.getName() + "());");
1068                         pw.println("\t\t}");
1069                     }
1070                     pw.println("\t\tunsafe.freeMemory(" + at.getName() + "_ptr);");
1071                 }
1072             }
1073             pw.println("\t\t__disposed = true;");
1074             pw.println("\t\t}");
1075             pw.println("\t}");
1076 
1077             iter = ft.getArguments().iterator();
1078             while (iter.hasNext()) {
1079                 AtomicType at = (AtomicType)iter.next();
1080                 pw.println("\tpublic " + at.getJavaType() + " get_" + at.getName() + "() {");
1081 
1082                 pw.println("\t\tif (__disposed) {");
1083                 pw.println("\t\t    throw new IllegalStateException(\"Disposed\");");
1084                 pw.println("\t\t}");
1085                 pw.println("\t\tif (!__executed) {");
1086                 pw.println("\t\t    throw new IllegalStateException(\"Not executed\");");
1087                 pw.println("\t\t}");
1088 
1089                 if (at.isIn()) {
1090                     pw.println("\t\treturn _" + at.getName() + ";");
1091                 } else {
1092                     pw.println("\t\treturn Native.get" + at.getTypeUpperCase() + "(" + at.getName() + "_ptr);");
1093                 }
1094                 pw.println("\t}");
1095 
1096                 pw.println("\tpublic void set_" + at.getName() + "(" + at.getJavaType() + " data) {");
1097                 if (at.isIn()) {
1098                     pw.println("\t\t_" + at.getName() + " = data;");
1099                 } else {
1100                     pw.println("\t\tNative.put" + at.getTypeUpperCase() + "(" + at.getName() + "_ptr, data);");
1101                 }
1102                 pw.println("\t}");
1103             }
1104             pw.println("}");
1105             pw.close();
1106         } catch (Exception e) {
1107             e.printStackTrace();
1108         }
1109     }
1110 
1111     public void writeJavaWrapperClass(String outputDir) {
1112 //          (new File(outputDir, package_path)).mkdirs();
1113         try {
1114             for (Enumeration e = symbolTable.elements() ; e.hasMoreElements() ;) {
1115                 BaseType tp = (BaseType) e.nextElement();
1116                 if (tp instanceof StructType) {
1117                     StructType st = (StructType) tp;
1118                     writeWrapper(outputDir, st);
1119                 } else if (tp instanceof FunctionType) {
1120                     writeFunctionCallWrapper(outputDir, (FunctionType)tp);
1121                 }
1122             }
1123         }
1124         catch (Exception e) {
1125             e.printStackTrace();
1126         }
1127     }
1128 
1129 
1130     public void writeNativeSizer(String file)
1131     {
1132         int type;
1133         int i=0;
1134         int j=0;
1135         BaseType tp;
1136         StructType stp;
1137         Enumeration eo;
1138 
1139 
1140         try {
1141 
1142             FileOutputStream fs =  new FileOutputStream(file);
1143             PrintWriter pw = new PrintWriter(fs);
1144 
1145             pw.println("/* This file is an automatically generated file, please do not edit this file, modify the XlibParser.java file instead !*/\n" );
1146             pw.println("#include <X11/Xlib.h>\n#include <X11/Xutil.h>\n#include <X11/Xos.h>\n#include <X11/Xatom.h>\n#include <stdio.h>\n");
1147             pw.println("#include <X11/extensions/Xdbe.h>");
1148             pw.println("#include <X11/XKBlib.h>");
1149             pw.println("#include \"awt_p.h\"");
1150             pw.println("#include \"color.h\"");
1151             pw.println("#include \"colordata.h\"");
1152             pw.println("\ntypedef struct\n");
1153             pw.println("{\n");
1154             pw.println("    unsigned long flags;\n");
1155             pw.println("    unsigned long functions;\n");
1156             pw.println("    unsigned long decorations;\n");
1157             pw.println("    long inputMode;\n");
1158             pw.println("    unsigned long status;\n");
1159             pw.println("} PropMwmHints;\n");
1160 
1161 
1162             pw.println("\n\nint main(){");
1163             j=0;
1164             for ( eo = symbolTable.elements() ; eo.hasMoreElements() ;) {
1165                 tp = (BaseType) eo.nextElement();
1166                 if (tp instanceof StructType)
1167                 {
1168                     stp = (StructType) tp;
1169                     if (!stp.getIsInterface()) {
1170                         pw.println(stp.getName()+"  temp"+ j + ";\n");
1171                         j++;
1172                     }
1173                 }
1174             }
1175             j=0;
1176 
1177             pw.println("printf(\"long\t%d\\n\",(int)sizeof(long));");
1178             pw.println("printf(\"int\t%d\\n\",(int)sizeof(int));");
1179             pw.println("printf(\"short\t%d\\n\",(int)sizeof(short));");
1180             pw.println("printf(\"ptr\t%d\\n\",(int)sizeof(void *));");
1181             pw.println("printf(\"Bool\t%d\\n\",(int)sizeof(Bool));");
1182             pw.println("printf(\"Atom\t%d\\n\",(int)sizeof(Atom));");
1183             pw.println("printf(\"Window\t%d\\n\",(int)sizeof(Window));");
1184 
1185 
1186             for (eo = symbolTable.elements() ; eo.hasMoreElements() ;) {
1187 
1188 
1189                 tp = (BaseType) eo.nextElement();
1190                 if (tp instanceof StructType)
1191                 {
1192                     stp = (StructType) tp;
1193                     if (stp.getIsInterface()) {
1194                         continue;
1195                     }
1196                     for (Enumeration e = stp.getMembers() ; e.hasMoreElements() ;) {
1197                         AtomicType atp = (AtomicType) e.nextElement();
1198                         if (atp.isAlias()) continue;
1199                         pw.println("printf(\""+ stp.getName() + "." + atp.getName() + "\t%d\\n\""+
1200                                    ",(int)((unsigned long ) &temp"+j+"."+atp.getName()+"- (unsigned long ) &temp" + j + ")  );");
1201 
1202                         i++;
1203 
1204 
1205                     }
1206                     pw.println("printf(\""+ stp.getName() + "\t%d\\n\"" + ",(int)sizeof(temp"+j+"));");
1207 
1208                     j++;
1209                 }
1210 
1211             }
1212             pw.println("return 0;");
1213             pw.println("}");
1214             pw.close();
1215 
1216         }
1217         catch (Exception e)
1218         {
1219             e.printStackTrace();
1220         }
1221     }
1222 
1223     private void initTypes() {
1224         symbolTable.put("int", new AtomicType(AtomicType.TYPE_INT, "", "int"));
1225         symbolTable.put("short", new AtomicType(AtomicType.TYPE_SHORT, "", "short"));
1226         symbolTable.put("long", new AtomicType(AtomicType.TYPE_LONG, "", "long"));
1227         symbolTable.put("float", new AtomicType(AtomicType.TYPE_FLOAT, "", "float"));
1228         symbolTable.put("double", new AtomicType(AtomicType.TYPE_DOUBLE, "", "double"));
1229         symbolTable.put("Bool", new AtomicType(AtomicType.TYPE_BOOL, "", "Bool"));
1230         symbolTable.put("char", new AtomicType(AtomicType.TYPE_CHAR, "", "char"));
1231         symbolTable.put("byte", new AtomicType(AtomicType.TYPE_BYTE, "", "byte"));
1232         symbolTable.put("pointer", new AtomicType(AtomicType.TYPE_PTR, "", "pointer"));
1233         symbolTable.put("longlong", new AtomicType(AtomicType.TYPE_LONG_LONG, "", "longlong"));
1234         symbolTable.put("Atom", new AtomicType(AtomicType.TYPE_ATOM, "", "Atom"));
1235         symbolTable.put("ulong", new AtomicType(AtomicType.TYPE_ULONG, "", "ulong"));
1236     }
1237     public WrapperGenerator(String outputDir, String xlibFilename) {
1238         initTypes();
1239         try {
1240             BufferedReader in  = new BufferedReader(new FileReader(xlibFilename));
1241             String line;
1242             String splits[];
1243             BaseType curType = null;
1244             while ((line = in.readLine()) != null)
1245             {
1246                 int commentStart = line.indexOf("//");
1247                 if (commentStart >= 0) {
1248                     // remove comment
1249                     line = line.substring(0, commentStart);
1250                 }
1251 
1252                 if ("".equals(line)) {
1253                     // skip empty line
1254                     continue;
1255                 }
1256 
1257                 splits = line.split("\\p{Space}+");
1258                 if (splits.length >= 2)
1259                 {
1260                     String struct_name = curType.getName();
1261                     String field_name = splits[1];
1262                     String s_type = splits[2];
1263                     BaseType bt = curType;
1264                     int type = AtomicType.getTypeForString(s_type);
1265                     AtomicType atp = null;
1266                     if (bt != null && type != -1) {
1267                         atp = new AtomicType(type,field_name,s_type);
1268                         if (splits.length > 3) {
1269                             atp.setAttributes(splits);
1270                         }
1271                         if (bt instanceof StructType) {
1272                             StructType  stp = (StructType) bt;
1273                             stp.addMember(atp);
1274                         } else if (bt instanceof FunctionType) {
1275                             ((FunctionType)bt).addArgument(atp);
1276                         }
1277                     }
1278                     else if (bt == null) {
1279                         System.out.println("Cannot find " + struct_name);
1280                     }
1281 
1282                 }
1283                 else  if (line != null) {
1284                     BaseType bt = (BaseType) symbolTable.get(line);
1285                     if (bt == null) {
1286                         if (line.startsWith("!")) {
1287                             FunctionType ft = new FunctionType(line);
1288                             ft.setName(line);
1289                             symbolTable.put(ft.getName(),ft);
1290                             curType = ft;
1291                         } else {
1292                             StructType stp = new StructType(line);
1293                             stp.setName(line);
1294                             curType = stp;
1295                             symbolTable.put(stp.getName(),stp);
1296                         }
1297                     }
1298                 }
1299 
1300             }
1301             in.close();
1302         }
1303         catch (Exception e) {
1304             e.printStackTrace();
1305         }
1306 
1307     }
1308     private void makeSizer(String outputDir) {
1309         if (wide) {
1310             sizerFileName = "sizer.64.c";
1311         } else {
1312             sizerFileName = "sizer.32.c";
1313         }
1314         File fp = new File(outputDir, sizerFileName);
1315         writeNativeSizer(fp.getAbsolutePath());
1316     }
1317     private boolean readSizeInfo(String sizeInfo) {
1318         try {
1319             File f = new File(sizeInfo+".32");
1320             boolean res = true;
1321             FileInputStream fis = null;
1322             if (f.exists()) {
1323                 fis = new FileInputStream(f);
1324                 res = readSizeInfo(fis, false);
1325                 fis.close();
1326             }
1327             f = new File(sizeInfo+".64");
1328             if (f.exists()) {
1329                 fis = new FileInputStream(f);
1330                 res &= readSizeInfo(fis, true);
1331                 fis.close();
1332             }
1333             return res;
1334         } catch (Exception e) {
1335             e.printStackTrace();
1336             return false;
1337         }
1338     }
1339 
1340     private void startGeneration(String outputDir, String sizeInfo) {
1341         if (readSizeInfo(sizeInfo))
1342         {
1343             writeJavaWrapperClass(outputDir);
1344         }
1345         else {
1346             System.out.println("Error calculating offsets");
1347         }
1348     }
1349 
1350     public static void main(String[] args) {
1351 
1352         if (args.length < 4) {
1353             System.out.println("Usage:\nWrapperGenerator <output_dir> <xlibtypes.txt> <action> [<platform> | <sizes info file>]");
1354             System.out.println("Where <action>: gen, sizer");
1355             System.out.println("      <platform>: 32, 64");
1356             System.exit(1);
1357         }
1358 
1359         WrapperGenerator xparser = new WrapperGenerator(args[0], args[1]);
1360         if (args[2].equals("sizer")) {
1361             xparser.wide = args[3].equals("64");
1362             xparser.makeSizer(args[0]);
1363         } else if (args[2].equals("gen")) {
1364             xparser.startGeneration(args[0], args[3]);
1365         }
1366     }
1367 
1368 }