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