0001: /*
0002: * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved.
0003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004: *
0005: * This code is free software; you can redistribute it and/or modify it
0006: * under the terms of the GNU General Public License version 2 only, as
0007: * published by the Free Software Foundation. Sun designates this
0008: * particular file as subject to the "Classpath" exception as provided
0009: * by Sun in the LICENSE file that accompanied this code.
0010: *
0011: * This code is distributed in the hope that it will be useful, but WITHOUT
0012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0014: * version 2 for more details (a copy is included in the LICENSE file that
0015: * accompanied this code).
0016: *
0017: * You should have received a copy of the GNU General Public License version
0018: * 2 along with this work; if not, write to the Free Software Foundation,
0019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020: *
0021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022: * CA 95054 USA or visit www.sun.com if you need additional information or
0023: * have any questions.
0024: */
0025:
0026: import java.util.*;
0027: import java.io.*;
0028: import java.nio.charset.*;
0029: import java.text.MessageFormat;
0030: import java.util.logging.*;
0031:
0032: public class WrapperGenerator {
0033: /* XLibParser converts Xlib.h to a Java Object that encapsulates the
0034: * X11 API and data structures */
0035: // Charset and decoder for ISO-8859-15
0036: private final static Logger log = Logger
0037: .getLogger("WrapperGenerator");
0038: boolean generateLog = true;
0039: boolean wide;
0040: private static Charset charset = Charset.forName("ISO-8859-15");
0041:
0042: String package_name = "sun.awt.X11";
0043: String package_path = "sun/awt/X11";
0044: String sizerFileName = "sizer.c";
0045: String defaultBaseClass = "XWrapperBase";
0046:
0047: String compile_options = "-lX11";
0048: static Hashtable symbolTable = new Hashtable();
0049: static Hashtable sizeTable32bit = new Hashtable();
0050: static Hashtable sizeTable64bit = new Hashtable();
0051: static Hashtable knownSizes32 = new Hashtable();
0052: static Hashtable knownSizes64 = new Hashtable();
0053: static {
0054: /*
0055: knownSizes64.put("", Integer.valueOf());
0056: knownSizes32.put("", Integer.valueOf());
0057: */
0058: knownSizes64.put("XComposeStatus", Integer.valueOf(16));
0059: knownSizes64.put("XTimeCoord", Integer.valueOf(16));
0060: knownSizes64.put("XExtData", Integer.valueOf(32));
0061: knownSizes64.put("XWindowChanges", Integer.valueOf(40));
0062: knownSizes64.put("XOMCharSetList", Integer.valueOf(16));
0063: knownSizes64.put("XModifierKeymap", Integer.valueOf(16));
0064: knownSizes32.put("XIMValuesList", Integer.valueOf(8));
0065: knownSizes32.put("XGCValues", Integer.valueOf(92));
0066: // knownSizes32.put("XIMStringConversionCallbackStruct", Integer.valueOf(16));
0067: }
0068:
0069: private static abstract class BaseType {
0070:
0071: String real_type;
0072: String name;
0073:
0074: public String getName() {
0075: return name;
0076: }
0077:
0078: public String getRealType() {
0079: return real_type;
0080: }
0081:
0082: public String toString() {
0083: return name;
0084: }
0085: }
0086:
0087: private static class AtomicType extends BaseType {
0088:
0089: private boolean alias;
0090: private String aliasName;
0091:
0092: static final int TYPE_INT = 0;
0093: static final int TYPE_CHAR = 1;
0094: static final int TYPE_LONG = 2;
0095: static final int TYPE_LONG_LONG = 3;
0096: static final int TYPE_DOUBLE = 4;
0097: static final int TYPE_FLOAT = 5;
0098: static final int TYPE_PTR = 6;
0099: static final int TYPE_SHORT = 7;
0100: static final int TYPE_BOOL = 8;
0101: static final int TYPE_STRUCT = 9;
0102: static final int TYPE_ARRAY = 10;
0103: static final int TYPE_BYTE = 11;
0104: static final int TYPE_ATOM = 12;
0105: static final int TYPE_ULONG = 13;
0106:
0107: static int getTypeForString(String str) {
0108: int type = -1;
0109: if (str.equals("int"))
0110: type = AtomicType.TYPE_INT;
0111: else if (str.equals("long"))
0112: type = AtomicType.TYPE_LONG;
0113: else if (str.equals("byte"))
0114: type = AtomicType.TYPE_BYTE;
0115: else if (str.equals("char"))
0116: type = AtomicType.TYPE_CHAR;
0117: else if (str.equals("long long"))
0118: type = AtomicType.TYPE_LONG_LONG;
0119: else if (str.equals("double"))
0120: type = AtomicType.TYPE_DOUBLE;
0121: else if (str.equals("float"))
0122: type = AtomicType.TYPE_FLOAT;
0123: else if (str.equals("pointer"))
0124: type = AtomicType.TYPE_PTR;
0125: else if (str.equals("short"))
0126: type = AtomicType.TYPE_SHORT;
0127: else if (str.equals("Bool"))
0128: type = AtomicType.TYPE_BOOL;
0129: else if (str.equals("struct"))
0130: type = AtomicType.TYPE_STRUCT;
0131: else if (str.equals("Atom"))
0132: type = AtomicType.TYPE_ATOM;
0133: else if (str.equals("array"))
0134: type = TYPE_ARRAY;
0135: else if (str.equals("ulong"))
0136: type = TYPE_ULONG;
0137: else
0138: throw new IllegalArgumentException(
0139: "Uknown type string: " + str);
0140:
0141: return type;
0142: }
0143:
0144: String getJavaType() {
0145: if (referencedType != null) {
0146: if (referencedType instanceof AtomicType) {
0147: return ((AtomicType) referencedType).getJavaType();
0148: } else {
0149: return referencedType.getName();
0150: }
0151: } else {
0152: return getJavaTypeForType(type);
0153: }
0154: }
0155:
0156: static String getJavaTypeForType(int type) {
0157: switch (type) {
0158: case TYPE_INT:
0159: return "int";
0160: case TYPE_CHAR:
0161: return "char";
0162: case TYPE_BYTE:
0163: return "byte";
0164: case TYPE_LONG:
0165: case TYPE_LONG_LONG:
0166: case TYPE_PTR:
0167: case TYPE_ULONG:
0168: return "long";
0169: case TYPE_DOUBLE:
0170: return "double";
0171: case TYPE_FLOAT:
0172: return "float";
0173: case TYPE_SHORT:
0174: return "short";
0175: case TYPE_BOOL:
0176: return "boolean";
0177: case TYPE_ATOM:
0178: return "long";
0179: default:
0180: throw new IllegalArgumentException("Unknown type: "
0181: + type);
0182: }
0183: }
0184:
0185: String getItemSize() {
0186: if (referencedType != null) {
0187: if (referencedType instanceof StructType) {
0188: return ((StructType) referencedType).getSize();
0189: } else {
0190: return ((AtomicType) referencedType).getItemSize();
0191: }
0192: } else {
0193: int i32 = getNativeSizeForAccess(getJavaAccess(false));
0194: int i64 = getNativeSizeForAccess(getJavaAccess(true));
0195: if (i32 != i64) {
0196: return "Native.get" + getNativeAccess() + "Size()";
0197: } else {
0198: return Integer.toString(i32);
0199: }
0200: }
0201: }
0202:
0203: String getJavaResult(String offset, String base) {
0204: String res = null;
0205: switch (type) {
0206: case TYPE_STRUCT:
0207: res = "pData + " + offset;
0208: break;
0209: case TYPE_PTR:
0210: if (referencedType == null
0211: || referencedType instanceof StructType) {
0212: res = base + "+" + offset;
0213: } else if (referencedType instanceof AtomicType) {
0214: res = MessageFormat
0215: .format(
0216: "Native.get{0}({1})",
0217: new Object[] {
0218: getNativeAccessForType(((AtomicType) referencedType).type),
0219: base + "+" + offset });
0220: }
0221: break;
0222: case TYPE_ARRAY:
0223: if (referencedType instanceof StructType) {
0224: res = "pData + " + offset;
0225: } else if (referencedType instanceof AtomicType) {
0226: res = MessageFormat
0227: .format(
0228: "Native.get{0}(pData + {1})",
0229: new Object[] {
0230: getNativeAccessForType(((AtomicType) referencedType).type),
0231: offset });
0232: }
0233: break;
0234: default:
0235: res = MessageFormat.format(
0236: "(Native.get{0}(pData+{1}))", new Object[] {
0237: getNativeAccess(), offset });
0238: }
0239: return getJavaResultConversion(res, base);
0240: }
0241:
0242: String getJavaResultConversion(String value, String base) {
0243: if (referencedType != null) {
0244: if (referencedType instanceof StructType) {
0245: if (type == TYPE_PTR) {
0246: return MessageFormat.format(
0247: "({2} != 0)?(new {0}({1})):(null)",
0248: new Object[] {
0249: referencedType.getName(),
0250: value, base });
0251: } else {
0252: return MessageFormat
0253: .format("new {0}({1})",
0254: new Object[] {
0255: referencedType
0256: .getName(),
0257: value });
0258: }
0259: } else {
0260: return value;
0261: }
0262: } else {
0263: return getJavaResultConversionForType(type, value);
0264: }
0265: }
0266:
0267: static String getJavaResultConversionForType(int type,
0268: String value) {
0269: return value;
0270: }
0271:
0272: String getNativeAccess() {
0273: return getNativeAccessForType(type);
0274: }
0275:
0276: String getJavaAccess(boolean wide) {
0277: return getJavaAccessForType(type, wide);
0278: }
0279:
0280: static String getJavaAccessForType(int type, boolean wide) {
0281: switch (type) {
0282: case TYPE_INT:
0283: return "Int";
0284: case TYPE_CHAR:
0285: return "Char";
0286: case TYPE_BYTE:
0287: return "Byte";
0288: case TYPE_LONG:
0289: case TYPE_PTR:
0290: case TYPE_ARRAY:
0291: case TYPE_STRUCT:
0292: case TYPE_ATOM:
0293: return (wide ? "Long" : "Int");
0294: case TYPE_LONG_LONG:
0295: return "Long";
0296: case TYPE_ULONG:
0297: return (wide ? "ULong" : "UInt");
0298: case TYPE_DOUBLE:
0299: return "Double";
0300: case TYPE_FLOAT:
0301: return "Float";
0302: case TYPE_SHORT:
0303: return "Short";
0304: case TYPE_BOOL:
0305: return "Int";
0306: default:
0307: throw new IllegalArgumentException("Unknown type: "
0308: + type);
0309: }
0310: }
0311:
0312: static String getNativeAccessForType(int type) {
0313: switch (type) {
0314: case TYPE_INT:
0315: return "Int";
0316: case TYPE_CHAR:
0317: return "Char";
0318: case TYPE_BYTE:
0319: return "Byte";
0320: case TYPE_LONG:
0321: case TYPE_PTR:
0322: case TYPE_ARRAY:
0323: case TYPE_STRUCT:
0324: return "Long";
0325: case TYPE_LONG_LONG:
0326: return "Long";
0327: case TYPE_ULONG:
0328: return "ULong";
0329: case TYPE_DOUBLE:
0330: return "Double";
0331: case TYPE_FLOAT:
0332: return "Float";
0333: case TYPE_SHORT:
0334: return "Short";
0335: case TYPE_BOOL:
0336: return "Bool";
0337: case TYPE_ATOM:
0338: return "Long";
0339: default:
0340: throw new IllegalArgumentException("Unknown type: "
0341: + type);
0342: }
0343: }
0344:
0345: static int getNativeSizeForAccess(String access) {
0346: if (access.equals("Int"))
0347: return 4;
0348: else if (access.equals("Byte"))
0349: return 1;
0350: else if (access.equals("Long"))
0351: return 8;
0352: else if (access.equals("Double"))
0353: return 8;
0354: else if (access.equals("Float"))
0355: return 4;
0356: else if (access.equals("Char"))
0357: return 2;
0358: else if (access.equals("Short"))
0359: return 2;
0360: else if (access.equals("ULong"))
0361: return 8;
0362: else if (access.equals("UInt"))
0363: return 4;
0364: else
0365: throw new IllegalArgumentException(
0366: "Unknow access type: " + access);
0367: }
0368:
0369: String getJavaConversion(String offset, String value) {
0370: if (referencedType != null) {
0371: if (referencedType instanceof StructType) {
0372: return getJavaConversionForType(TYPE_PTR, offset,
0373: value + ".pData");
0374: } else {
0375: if (type == TYPE_ARRAY) {
0376: return getJavaConversionForType(
0377: ((AtomicType) referencedType).type,
0378: offset, value);
0379: } else { // TYPE_PTR
0380: return getJavaConversionForType(TYPE_PTR,
0381: offset, value);
0382: }
0383: }
0384: } else {
0385: return getJavaConversionForType(type, offset, value);
0386: }
0387: }
0388:
0389: static String getJavaConversionForType(int type, String offset,
0390: String value) {
0391: return MessageFormat.format("Native.put{0}({2}, {1})",
0392: new Object[] { getNativeAccessForType(type), value,
0393: offset });
0394: }
0395:
0396: int type;
0397: int offset;
0398: int direction;
0399: BaseType referencedType;
0400: int arrayLength = -1;
0401: boolean autoFree = false;
0402:
0403: public AtomicType(int _type, String _name, String _real_type) {
0404: name = _name.replaceAll("[* \t]", "");
0405: if ((name.indexOf("[") != -1) || (name.indexOf("]") != -1)) {
0406: name = name.replaceAll("\\[.*\\]", "");
0407: }
0408: type = _type;
0409: real_type = _real_type;
0410: if (real_type == null) {
0411: System.out.println(" real type is null");
0412:
0413: }
0414: }
0415:
0416: public boolean isIn() {
0417: return direction == 0;
0418: }
0419:
0420: public boolean isOut() {
0421: return direction == 1;
0422: }
0423:
0424: public boolean isInOut() {
0425: return direction == 2;
0426: }
0427:
0428: public boolean isAutoFree() {
0429: return autoFree;
0430: }
0431:
0432: public void setAttributes(String[] attributes) {
0433: String mod = attributes[3];
0434: if ("in".equals(mod)) {
0435: direction = 0;
0436: } else if ("out".equals(mod)) {
0437: direction = 1;
0438: if (attributes.length > 4
0439: && "free".equals(attributes[4])) {
0440: autoFree = true;
0441: }
0442: } else if ("inout".equals(mod)) {
0443: direction = 2;
0444: } else if ("alias".equals(mod)) {
0445: alias = true;
0446: aliasName = attributes[4];
0447: } else if (type == TYPE_ARRAY || type == TYPE_PTR
0448: || type == TYPE_STRUCT) {
0449: referencedType = (BaseType) symbolTable.get(mod);
0450: if (referencedType == null) {
0451: log.warning("Can't find type for name " + mod);
0452: }
0453: if (attributes.length > 4) { // array length
0454: try {
0455: arrayLength = Integer.parseInt(attributes[4]);
0456: } catch (Exception e) {
0457: }
0458: }
0459: }
0460: }
0461:
0462: public BaseType getReferencedType() {
0463: return referencedType;
0464: }
0465:
0466: public int getArrayLength() {
0467: return arrayLength;
0468: }
0469:
0470: public void setOffset(int o) {
0471: offset = o;
0472: }
0473:
0474: public int getType() {
0475: return type;
0476: }
0477:
0478: public String getTypeUpperCase() {
0479: switch (type) {
0480: case TYPE_INT:
0481: return "Int";
0482: case TYPE_CHAR:
0483: return "Char";
0484: case TYPE_BYTE:
0485: return "Byte";
0486: case TYPE_LONG:
0487: case TYPE_LONG_LONG:
0488: case TYPE_PTR:
0489: return "Long";
0490: case TYPE_DOUBLE:
0491: return "Double";
0492: case TYPE_FLOAT:
0493: return "Float";
0494: case TYPE_SHORT:
0495: return "Short";
0496: case TYPE_BOOL:
0497: return "Int";
0498: case TYPE_ATOM:
0499: return "Long";
0500: case TYPE_ULONG:
0501: return "ULong";
0502: default:
0503: throw new IllegalArgumentException("Uknown type");
0504: }
0505: }
0506:
0507: public int getOffset() {
0508: return offset;
0509: }
0510:
0511: public boolean isAlias() {
0512: return alias;
0513: }
0514:
0515: public String getAliasName() {
0516: return aliasName;
0517: }
0518: }
0519:
0520: private static class StructType extends BaseType {
0521:
0522: Vector members;
0523: String description;
0524: boolean packed;
0525: int size;
0526: String baseClass, interfaces;
0527: boolean isInterface;
0528: String javaClassName;
0529:
0530: /**
0531: * Construct new structured type.
0532: * Description is used for name and type definition and has the following format:
0533: * structName [ '[' base classe ']' ] [ '{' interfaces '}' ] [ '|' javaClassName ]
0534: */
0535: public StructType(String _desc) {
0536: members = new Vector();
0537: parseDescription(_desc);
0538: }
0539:
0540: public int getNumFields() {
0541: return members.size();
0542: }
0543:
0544: public void setName(String _name) {
0545: _name = _name.replaceAll("[* \t]", "");
0546: parseDescription(_name);
0547: }
0548:
0549: public void setSize(int i) {
0550: size = i;
0551: }
0552:
0553: public String getDescription() {
0554: return description;
0555: }
0556:
0557: public Enumeration getMembers() {
0558: return members.elements();
0559: }
0560:
0561: public void addMember(BaseType tp) {
0562: members.add(tp);
0563: }
0564:
0565: public String getBaseClass() {
0566: return baseClass;
0567: }
0568:
0569: public String getInterfaces() {
0570: return interfaces;
0571: }
0572:
0573: public boolean getIsInterface() {
0574: return isInterface;
0575: }
0576:
0577: public String getJavaClassName() {
0578: return javaClassName;
0579: }
0580:
0581: void parseDescription(String _desc) {
0582: if (_desc.indexOf('[') != -1) { // Has base class
0583: baseClass = _desc.substring(_desc.indexOf('[') + 1,
0584: _desc.indexOf(']'));
0585: _desc = _desc.substring(0, _desc.indexOf('['))
0586: + _desc.substring(_desc.indexOf(']') + 1);
0587: }
0588: if (_desc.indexOf('{') != -1) { // Has base class
0589: interfaces = _desc.substring(_desc.indexOf('{') + 1,
0590: _desc.indexOf('}'));
0591: _desc = _desc.substring(0, _desc.indexOf('{'))
0592: + _desc.substring(_desc.indexOf('}') + 1);
0593: }
0594: if (_desc.startsWith("-")) { // Interface
0595: isInterface = true;
0596: _desc = _desc.substring(1, _desc.length());
0597: }
0598: if (_desc.indexOf("|") != -1) {
0599: javaClassName = _desc.substring(_desc.indexOf('|') + 1,
0600: _desc.length());
0601: _desc = _desc.substring(0, _desc.indexOf('|'));
0602: }
0603: name = _desc;
0604: if (javaClassName == null) {
0605: javaClassName = name;
0606: }
0607: description = _desc;
0608: // System.out.println("Struct " + name + " extends " + baseClass + " implements " + interfaces);
0609: }
0610:
0611: /**
0612: * Returns String containing Java code calculating size of the structure depending on the data model
0613: */
0614: public String getSize() {
0615: String s32 = (String) WrapperGenerator.sizeTable32bit
0616: .get(getName());
0617: String s64 = (String) WrapperGenerator.sizeTable64bit
0618: .get(getName());
0619: if (s32 == null || s64 == null) {
0620: return (s32 == null) ? (s64) : (s32);
0621: }
0622: if (s32.equals(s64)) {
0623: return s32;
0624: } else {
0625: return MessageFormat.format(
0626: "((XlibWrapper.dataModel == 32)?({0}):({1}))",
0627: new Object[] { s32, s64 });
0628: }
0629: }
0630:
0631: public String getOffset(AtomicType atp) {
0632: String key = getName()
0633: + "."
0634: + (atp.isAlias() ? atp.getAliasName() : atp
0635: .getName());
0636: String s64 = (String) WrapperGenerator.sizeTable64bit
0637: .get(key);
0638: String s32 = (String) WrapperGenerator.sizeTable32bit
0639: .get(key);
0640: if (s32 == null || s64 == null) {
0641: return (s32 == null) ? (s64) : (s32);
0642: }
0643: if (s32.equals(s64)) {
0644: return s32;
0645: } else {
0646: return MessageFormat.format(
0647: "((XlibWrapper.dataModel == 32)?({0}):({1}))",
0648: new Object[] { s32, s64 });
0649: }
0650: }
0651: }
0652:
0653: private static class FunctionType extends BaseType {
0654:
0655: Vector args;
0656: String description;
0657: boolean packed;
0658: String returnType;
0659:
0660: int alignment;
0661:
0662: public FunctionType(String _desc) {
0663: args = new Vector();
0664: description = _desc;
0665: setName(_desc);
0666: }
0667:
0668: boolean isVoid() {
0669: return (returnType == null);
0670: }
0671:
0672: String getReturnType() {
0673: if (returnType == null) {
0674: return "void";
0675: } else {
0676: return returnType;
0677: }
0678: }
0679:
0680: public int getNumArgs() {
0681: return args.size();
0682: }
0683:
0684: public void setName(String _name) {
0685: if (_name.startsWith("!")) {
0686: _name = _name.substring(1, _name.length());
0687: }
0688: if (_name.indexOf("|") != -1) {
0689: returnType = _name.substring(_name.indexOf("|") + 1,
0690: _name.length());
0691: _name = _name.substring(0, _name.indexOf("|"));
0692: }
0693: name = _name.replaceAll("[* \t]", "");
0694: }
0695:
0696: public String getDescription() {
0697: return description;
0698: }
0699:
0700: public Collection getArguments() {
0701: return args;
0702: }
0703:
0704: public void addArgument(BaseType tp) {
0705: args.add(tp);
0706: }
0707: }
0708:
0709: public String makeComment(String str) {
0710: StringTokenizer st = new StringTokenizer(str, "\r\n");
0711: String ret = "";
0712:
0713: while (st.hasMoreTokens()) {
0714: ret = ret + "//" + st.nextToken() + "\n";
0715: }
0716:
0717: return ret;
0718: }
0719:
0720: public String getJavaTypeForSize(int size) {
0721: switch (size) {
0722: case 1:
0723: return "byte";
0724: case 2:
0725: return "short";
0726: case 4:
0727: return "int";
0728: case 8:
0729: return "long";
0730: default:
0731: throw new RuntimeException("Unsupported size: " + size);
0732: }
0733: }
0734:
0735: public String getOffsets(StructType stp, AtomicType atp,
0736: boolean wide) {
0737: String key = stp.getName() + "." + atp.getName();
0738: return wide == true ? (String) sizeTable64bit.get(key)
0739: : (String) sizeTable32bit.get(key);
0740: }
0741:
0742: public String getStructSize(StructType stp, boolean wide) {
0743: return wide == true ? (String) sizeTable64bit
0744: .get(stp.getName()) : (String) sizeTable32bit.get(stp
0745: .getName());
0746: }
0747:
0748: public int getLongSize(boolean wide) {
0749: return Integer.parseInt(wide == true ? (String) sizeTable64bit
0750: .get("long") : (String) sizeTable32bit.get("long"));
0751: }
0752:
0753: public int getPtrSize(boolean wide) {
0754: return Integer.parseInt(wide == true ? (String) sizeTable64bit
0755: .get("ptr") : (String) sizeTable32bit.get("ptr"));
0756: }
0757:
0758: public int getBoolSize(boolean wide) {
0759: return getOrdinalSize("Bool", wide);
0760: }
0761:
0762: public int getOrdinalSize(String ordinal, boolean wide) {
0763: return Integer.parseInt(wide == true ? (String) sizeTable64bit
0764: .get(ordinal) : (String) sizeTable32bit.get(ordinal));
0765: }
0766:
0767: public void writeToString(StructType stp, PrintWriter pw) {
0768: int type;
0769: pw.println("\n\n\tString getName() {\n\t\treturn \""
0770: + stp.getName() + "\"; \n\t}");
0771: pw
0772: .println("\n\n\tString getFieldsAsString() {\n\t\tString ret=\"\";\n");
0773:
0774: for (Enumeration e = stp.getMembers(); e.hasMoreElements();) {
0775: AtomicType tp = (AtomicType) e.nextElement();
0776:
0777: type = tp.getType();
0778: String name = tp.getName().replace('.', '_');
0779: if ((name != null) && (name.length() > 0)) {
0780: if (type == AtomicType.TYPE_ATOM) {
0781: pw.println("\t\tret += \"\"+\"" + name
0782: + " = \" + XAtom.get(get_" + name
0783: + "()) +\", \";");
0784: } else if (name.equals("type")) {
0785: pw
0786: .println("\t\tret += \"\"+\"type = \" + XlibWrapper.eventToString[get_type()] +\", \";");
0787: } else if (name.equals("window")) {
0788: pw
0789: .println("\t\tret += \"\"+\"window = \" + getWindow(get_window()) + \", \";");
0790: } else if (type == AtomicType.TYPE_ARRAY) {
0791: pw.print("\t\tret += \"{\"");
0792: for (int i = 0; i < tp.getArrayLength(); i++) {
0793: pw.print(" + get_" + name + "(" + i
0794: + ") + \" \"");
0795: }
0796: pw.println(" + \"}\";");
0797: } else {
0798: pw.println("\t\tret += \"\"+\"" + name
0799: + " = \" + get_" + name + "() +\", \";");
0800: }
0801: }
0802:
0803: }
0804: pw.println("\t\treturn ret;\n\t}\n\n");
0805: }
0806:
0807: public void writeStubs(StructType stp, PrintWriter pw) {
0808: int type;
0809: String prefix = "";
0810: if (!stp.getIsInterface()) {
0811: prefix = "\t\tabstract ";
0812: } else {
0813: prefix = "\t";
0814: }
0815: for (Enumeration e = stp.getMembers(); e.hasMoreElements();) {
0816: AtomicType tp = (AtomicType) e.nextElement();
0817:
0818: type = tp.getType();
0819: String name = tp.getName().replace('.', '_');
0820: if ((name != null) && (name.length() > 0)) {
0821: if (type == AtomicType.TYPE_ARRAY) {
0822: // Returns pointer to the start of the array
0823: pw.println(prefix + "long get_" + name + "();");
0824:
0825: pw.println(prefix + tp.getJavaType() + " get_"
0826: + name + "(int index);");
0827: pw.println(prefix + "void set_" + name
0828: + "(int index, " + tp.getJavaType()
0829: + " v);");
0830: } else {
0831: pw.println(prefix + tp.getJavaType() + " get_"
0832: + name + "();");
0833: if (type != AtomicType.TYPE_STRUCT)
0834: pw.println(prefix + "void set_" + name + "("
0835: + tp.getJavaType() + " v);");
0836: }
0837: }
0838: }
0839: }
0840:
0841: private int padSize(int size, int wordLength) {
0842: int bytesPerWord = wordLength / 8;
0843: // Make size dividable by bytesPerWord
0844: return (size + bytesPerWord / 2) / bytesPerWord * bytesPerWord;
0845: }
0846:
0847: public void writeAccessorImpls(StructType stp, PrintWriter pw) {
0848: int type;
0849: int i = 0;
0850: String s_size_32 = getStructSize(stp, false);
0851: String s_size_64 = getStructSize(stp, true);
0852: int acc_size_32 = 0;
0853: int acc_size_64 = 0;
0854: String s_log = (generateLog ? "log.finest(\"\");" : "");
0855: for (Enumeration e = stp.getMembers(); e.hasMoreElements();) {
0856: AtomicType tp = (AtomicType) e.nextElement();
0857:
0858: type = tp.getType();
0859: String name = tp.getName().replace('.', '_');
0860: String pref = "\tpublic ";
0861: if ((name != null) && (name.length() > 0)) {
0862: String jt = tp.getJavaType();
0863: String ja_32 = tp.getJavaAccess(false);
0864: String ja_64 = tp.getJavaAccess(true);
0865: String ja = ja_32;
0866: int elemSize_32 = AtomicType
0867: .getNativeSizeForAccess(ja_32);
0868: int elemSize_64 = AtomicType
0869: .getNativeSizeForAccess(ja_64);
0870: String elemSize = tp.getItemSize();
0871: if (type == AtomicType.TYPE_ARRAY) {
0872: acc_size_32 += elemSize_32 * tp.getArrayLength();
0873: acc_size_64 += elemSize_64 * tp.getArrayLength();
0874: pw.println(pref
0875: + tp.getJavaType()
0876: + " get_"
0877: + name
0878: + "(int index) { "
0879: + s_log
0880: + "return "
0881: + tp.getJavaResult(stp.getOffset(tp)
0882: + "+index*" + elemSize, null)
0883: + "; }");
0884: if (tp.getReferencedType() instanceof AtomicType) { // Set for StructType is forbidden
0885: pw
0886: .println(MessageFormat
0887: .format(
0888: pref
0889: + "void set_{0}(int index, {1} v) '{' {3} {2}; '}'",
0890: new Object[] {
0891: name,
0892: jt,
0893: tp
0894: .getJavaConversion(
0895: "pData+"
0896: + stp
0897: .getOffset(tp)
0898: + " + index*"
0899: + elemSize,
0900: "v"),
0901: s_log }));
0902: }
0903: // Returns pointer to the start of the array
0904: pw.println(pref + "long get_" + name + "() { "
0905: + s_log + "return pData+"
0906: + stp.getOffset(tp) + "; }");
0907: } else if (type == AtomicType.TYPE_PTR) {
0908: pw
0909: .println(MessageFormat
0910: .format(
0911: pref
0912: + "{0} get_{1}(int index) '{' {3} return {2}; '}'",
0913: new Object[] {
0914: jt,
0915: name,
0916: tp
0917: .getJavaResult(
0918: "index*"
0919: + elemSize,
0920: "Native.getLong(pData+"
0921: + stp
0922: .getOffset(tp)
0923: + ")"),
0924: s_log }));
0925: pw.println(pref + "long get_" + name + "() { "
0926: + s_log + "return Native.getLong(pData+"
0927: + stp.getOffset(tp) + "); }");
0928: pw.println(MessageFormat.format(pref
0929: + "void set_{0}({1} v) '{' {3} {2}; '}'",
0930: new Object[] {
0931: name,
0932: "long",
0933: "Native.putLong(pData + "
0934: + stp.getOffset(tp)
0935: + ", v)", s_log }));
0936: acc_size_32 += elemSize_32;
0937: acc_size_64 += elemSize_64;
0938: } else {
0939: acc_size_32 += elemSize_32;
0940: acc_size_64 += elemSize_64;
0941: pw.println(pref + tp.getJavaType() + " get_" + name
0942: + "() { " + s_log + "return "
0943: + tp.getJavaResult(stp.getOffset(tp), null)
0944: + "; }");
0945: if (type != AtomicType.TYPE_STRUCT) {
0946: pw
0947: .println(MessageFormat
0948: .format(
0949: pref
0950: + "void set_{0}({1} v) '{' {3} {2}; '}'",
0951: new Object[] {
0952: name,
0953: jt,
0954: tp
0955: .getJavaConversion(
0956: "pData+"
0957: + stp
0958: .getOffset(tp),
0959: "v"),
0960: s_log }));
0961: }
0962: }
0963: i++;
0964: }
0965: }
0966: if (s_size_32 != null
0967: && !s_size_32.equals(Integer.toString(acc_size_32))) {
0968: log.fine("32 bits: The size of the structure "
0969: + stp.getName() + " " + s_size_32
0970: + " is not equal to the accumulated size "
0971: + acc_size_32 + " of the fields");
0972: } else if (s_size_64 != null
0973: && !s_size_64.equals(Integer.toString(acc_size_64))) {
0974: log.fine("64 bits: The size of the structure "
0975: + stp.getName() + " " + s_size_64
0976: + " is not equal to the accumulated size "
0977: + acc_size_64 + " of the fields");
0978: }
0979: }
0980:
0981: public void writeWrapperSubclass(StructType stp, PrintWriter pw,
0982: boolean wide) {
0983:
0984: pw.println("class " + stp.getJavaClassName() + "AccessorImpl"
0985: + " extends " + stp.getJavaClassName() + "Accessor {");
0986: pw
0987: .println("/*\nThis class serves as a Wrapper for the following X Struct \nsThe offsets here are calculated based on actual compiler.\n\n"
0988: + stp.getDescription() + "\n\n */");
0989:
0990: writeAccessorImpls(stp, pw);
0991:
0992: pw.println("\n\n } \n\n");
0993: }
0994:
0995: public void writeWrapper(String outputDir, StructType stp) {
0996: if (stp.getNumFields() > 0) {
0997:
0998: try {
0999: FileOutputStream fs = new FileOutputStream(outputDir
1000: + "/" + stp.getJavaClassName() + ".java");
1001: PrintWriter pw = new PrintWriter(fs);
1002: pw
1003: .println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n");
1004:
1005: pw.println("package " + package_name + ";\n");
1006: pw.println("import sun.misc.*;\n");
1007: pw.println("import java.util.logging.*;");
1008: String baseClass = stp.getBaseClass();
1009: if (baseClass == null) {
1010: baseClass = defaultBaseClass;
1011: }
1012: if (stp.getIsInterface()) {
1013: pw.print("public interface ");
1014: pw.print(stp.getJavaClassName());
1015: } else {
1016: pw.print("public class ");
1017: pw.print(stp.getJavaClassName() + " extends "
1018: + baseClass);
1019: }
1020: if (stp.getInterfaces() != null) {
1021: pw.print(" implements " + stp.getInterfaces());
1022: }
1023: pw.println(" { ");
1024: if (!stp.getIsInterface()) {
1025: pw
1026: .println("\tprivate Unsafe unsafe = XlibWrapper.unsafe; ");
1027: pw
1028: .println("\tprivate final boolean should_free_memory;");
1029: pw
1030: .println("\tpublic static int getSize() { return "
1031: + stp.getSize() + "; }");
1032: pw
1033: .println("\tpublic int getDataSize() { return getSize(); }");
1034: pw.println("\n\tlong pData;");
1035: pw
1036: .println("\n\tpublic long getPData() { return pData; }");
1037:
1038: pw.println("\n\n\t" + stp.getJavaClassName()
1039: + "(long addr) {");
1040: if (generateLog) {
1041: pw.println("\t\tlog.finest(\"Creating\");");
1042: }
1043: pw.println("\t\tpData=addr;");
1044: pw.println("\t\tshould_free_memory = false;");
1045: pw.println("\t}");
1046: pw.println("\n\n\t" + stp.getJavaClassName()
1047: + "() {");
1048: if (generateLog) {
1049: pw.println("\t\tlog.finest(\"Creating\");");
1050: }
1051: pw
1052: .println("\t\tpData = unsafe.allocateMemory(getSize());");
1053: pw.println("\t\tshould_free_memory = true;");
1054: pw.println("\t}");
1055:
1056: pw.println("\n\n\tpublic void dispose() {");
1057: if (generateLog) {
1058: pw.println("\t\tlog.finest(\"Disposing\");");
1059: }
1060: pw.println("\t\tif (should_free_memory) {");
1061: if (generateLog) {
1062: pw
1063: .println("\t\t\tlog.finest(\"freeing memory\");");
1064: }
1065: pw.println("\t\t\tunsafe.freeMemory(pData); \n\t}");
1066: pw.println("\t\t}");
1067: writeAccessorImpls(stp, pw);
1068: writeToString(stp, pw);
1069: } else {
1070: pw.println("\n\n\tvoid dispose();");
1071: pw.println("\n\tlong getPData();");
1072: writeStubs(stp, pw);
1073: }
1074:
1075: pw.println("}\n\n\n");
1076: pw.close();
1077: } catch (Exception e) {
1078: e.printStackTrace();
1079: }
1080: }
1081: }
1082:
1083: private boolean readSizeInfo(InputStream is, boolean wide) {
1084: String line;
1085: String splits[];
1086: BufferedReader in = new BufferedReader(
1087: new InputStreamReader(is));
1088: try {
1089: while ((line = in.readLine()) != null) {
1090: splits = line.split("\\p{Space}");
1091: if (splits.length == 2) {
1092: if (wide) {
1093: sizeTable64bit.put(splits[0], splits[1]);
1094: } else {
1095: sizeTable32bit.put(splits[0], splits[1]);
1096: }
1097: }
1098: }
1099: return true;
1100: } catch (Exception e) {
1101: e.printStackTrace();
1102: return false;
1103: }
1104: }
1105:
1106: public void writeFunctionCallWrapper(String outputDir,
1107: FunctionType ft) {
1108: try {
1109: FileOutputStream fs = new FileOutputStream(outputDir + "/"
1110: + ft.getName() + ".java");
1111: PrintWriter pw = new PrintWriter(fs);
1112: pw
1113: .println("// This file is an automatically generated file, please do not edit this file, modify the WrapperGenerator.java file instead !\n");
1114:
1115: pw.println("package " + package_name + ";\n");
1116: pw.println("import sun.misc.Unsafe;\n");
1117: pw.println("class " + ft.getName() + " {");
1118: pw
1119: .println("\tprivate static Unsafe unsafe = XlibWrapper.unsafe;");
1120: pw.println("\tprivate boolean __executed = false;");
1121: pw.println("\tprivate boolean __disposed = false;");
1122: Iterator iter = ft.getArguments().iterator();
1123: while (iter.hasNext()) {
1124: AtomicType at = (AtomicType) iter.next();
1125: if (at.isIn()) {
1126: pw.println("\t" + at.getJavaType() + " _"
1127: + at.getName() + ";");
1128: } else {
1129: pw.println("\tlong " + at.getName()
1130: + "_ptr = unsafe.allocateMemory(Native.get"
1131: + at.getTypeUpperCase() + "Size());");
1132: }
1133: }
1134: pw.println("\tpublic " + ft.getName() + "(");
1135: iter = ft.getArguments().iterator();
1136: boolean first = true;
1137: while (iter.hasNext()) {
1138: AtomicType at = (AtomicType) iter.next();
1139: if (at.isIn() || at.isInOut()) {
1140: if (!first) {
1141: pw.println(",");
1142: }
1143: first = false;
1144: pw.print("\t\t" + at.getJavaType() + " "
1145: + at.getName());
1146: }
1147: }
1148: pw.println("\t)");
1149: pw.println("\t{");
1150: iter = ft.getArguments().iterator();
1151: while (iter.hasNext()) {
1152: AtomicType at = (AtomicType) iter.next();
1153: if (at.isIn() || at.isInOut()) {
1154: pw.println("\t\tset_" + at.getName() + "("
1155: + at.getName() + ");");
1156: }
1157: }
1158: pw.println("\t}");
1159:
1160: pw.println("\tpublic " + ft.getReturnType()
1161: + " execute() {");
1162: if (ft.isVoid()) {
1163: pw.println("\t\texecute(null);");
1164: } else {
1165: pw.println("\t\treturn execute(null);");
1166: }
1167: pw.println("\t}");
1168:
1169: pw
1170: .println("\tpublic "
1171: + ft.getReturnType()
1172: + " execute(XToolkit.XErrorHandler errorHandler) {");
1173: pw.println("\t\tif (__disposed) {");
1174: pw
1175: .println("\t\t throw new IllegalStateException(\"Disposed\");");
1176: pw.println("\t\t}");
1177: pw.println("\t\tXToolkit.awtLock();");
1178: pw.println("\t\ttry {");
1179: pw.println("\t\t\tif (__executed) {");
1180: pw
1181: .println("\t\t\t throw new IllegalStateException(\"Already executed\");");
1182: pw.println("\t\t\t}");
1183: pw.println("\t\t\t__executed = true;");
1184: pw.println("\t\t\tif (errorHandler != null) {");
1185: pw
1186: .println("\t\t\t XToolkit.WITH_XERROR_HANDLER(errorHandler);");
1187: pw.println("\t\t\t}");
1188: iter = ft.getArguments().iterator();
1189: while (iter.hasNext()) {
1190: AtomicType at = (AtomicType) iter.next();
1191: if (!at.isIn() && at.isAutoFree()) {
1192: pw.println("\t\t\tNative.put"
1193: + at.getTypeUpperCase() + "("
1194: + at.getName() + "_ptr, 0);");
1195: }
1196: }
1197: if (!ft.isVoid()) {
1198: pw
1199: .println("\t\t\t" + ft.getReturnType()
1200: + " status = ");
1201: }
1202: pw.println("\t\t\tXlibWrapper." + ft.getName()
1203: + "(XToolkit.getDisplay(), ");
1204: iter = ft.getArguments().iterator();
1205: first = true;
1206: while (iter.hasNext()) {
1207: AtomicType at = (AtomicType) iter.next();
1208: if (!first) {
1209: pw.println(",");
1210: }
1211: first = false;
1212: if (at.isIn()) {
1213: pw.print("\t\t\t\tget_" + at.getName() + "()");
1214: } else {
1215: pw.print("\t\t\t\t" + at.getName() + "_ptr");
1216: }
1217: }
1218: pw.println("\t\t\t);");
1219: pw.println("\t\t\tif (errorHandler != null) {");
1220: pw.println("\t\t\t XToolkit.RESTORE_XERROR_HANDLER();");
1221: pw.println("\t\t\t}");
1222: if (!ft.isVoid()) {
1223: pw.println("\t\t\treturn status;");
1224: }
1225: pw.println("\t\t} finally {");
1226: pw.println("\t\t XToolkit.awtUnlock();");
1227: pw.println("\t\t}");
1228: pw.println("\t}");
1229:
1230: pw.println("\tpublic boolean isExecuted() {");
1231: pw.println("\t return __executed;");
1232: pw.println("\t}");
1233: pw.println("\t");
1234: pw.println("\tpublic boolean isDisposed() {");
1235: pw.println("\t return __disposed;");
1236: pw.println("\t}");
1237: pw.println("\tpublic void finalize() {");
1238: pw.println("\t dispose();");
1239: pw.println("\t}");
1240:
1241: pw.println("\tpublic void dispose() {");
1242: pw.println("\t\tXToolkit.awtLock();");
1243: pw.println("\t\ttry {");
1244: pw.println("\t\tif (__disposed || !__executed) {");
1245: pw.println("\t\t return;");
1246: pw.println("\t\t} finally {");
1247: pw.println("\t\t XToolkit.awtUnlock();");
1248: pw.println("\t\t}");
1249: pw.println("\t\t}");
1250:
1251: iter = ft.getArguments().iterator();
1252: while (iter.hasNext()) {
1253: AtomicType at = (AtomicType) iter.next();
1254: if (!at.isIn()) {
1255: if (at.isAutoFree()) {
1256: pw.println("\t\tif (__executed && get_"
1257: + at.getName() + "()!= 0) {");
1258: pw.println("\t\t\tXlibWrapper.XFree(get_"
1259: + at.getName() + "());");
1260: pw.println("\t\t}");
1261: }
1262: pw.println("\t\tunsafe.freeMemory(" + at.getName()
1263: + "_ptr);");
1264: }
1265: }
1266: pw.println("\t\t__disposed = true;");
1267: pw.println("\t\t}");
1268: pw.println("\t}");
1269:
1270: iter = ft.getArguments().iterator();
1271: while (iter.hasNext()) {
1272: AtomicType at = (AtomicType) iter.next();
1273: pw.println("\tpublic " + at.getJavaType() + " get_"
1274: + at.getName() + "() {");
1275:
1276: pw.println("\t\tif (__disposed) {");
1277: pw
1278: .println("\t\t throw new IllegalStateException(\"Disposed\");");
1279: pw.println("\t\t}");
1280: pw.println("\t\tif (!__executed) {");
1281: pw
1282: .println("\t\t throw new IllegalStateException(\"Not executed\");");
1283: pw.println("\t\t}");
1284:
1285: if (at.isIn()) {
1286: pw.println("\t\treturn _" + at.getName() + ";");
1287: } else {
1288: pw.println("\t\treturn Native.get"
1289: + at.getTypeUpperCase() + "("
1290: + at.getName() + "_ptr);");
1291: }
1292: pw.println("\t}");
1293:
1294: pw.println("\tpublic void set_" + at.getName() + "("
1295: + at.getJavaType() + " data) {");
1296: if (at.isIn()) {
1297: pw.println("\t\t_" + at.getName() + " = data;");
1298: } else {
1299: pw.println("\t\tNative.put" + at.getTypeUpperCase()
1300: + "(" + at.getName() + "_ptr, data);");
1301: }
1302: pw.println("\t}");
1303: }
1304: pw.println("}");
1305: pw.close();
1306: } catch (Exception e) {
1307: e.printStackTrace();
1308: }
1309: }
1310:
1311: public void writeJavaWrapperClass(String outputDir) {
1312: // (new File(outputDir, package_path)).mkdirs();
1313: try {
1314: for (Enumeration e = symbolTable.elements(); e
1315: .hasMoreElements();) {
1316: BaseType tp = (BaseType) e.nextElement();
1317: if (tp instanceof StructType) {
1318: StructType st = (StructType) tp;
1319: writeWrapper(outputDir, st);
1320: } else if (tp instanceof FunctionType) {
1321: writeFunctionCallWrapper(outputDir,
1322: (FunctionType) tp);
1323: }
1324: }
1325: } catch (Exception e) {
1326: e.printStackTrace();
1327: }
1328: }
1329:
1330: public void writeNativeSizer(String file) {
1331: int type;
1332: int i = 0;
1333: int j = 0;
1334: BaseType tp;
1335: StructType stp;
1336: Enumeration eo;
1337:
1338: try {
1339:
1340: FileOutputStream fs = new FileOutputStream(file);
1341: PrintWriter pw = new PrintWriter(fs);
1342:
1343: pw
1344: .println("/* This file is an automatically generated file, please do not edit this file, modify the XlibParser.java file instead !*/\n");
1345: pw
1346: .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");
1347: pw.println("#include <Xm/MwmUtil.h>");
1348: pw.println("#include <X11/extensions/Xdbe.h>");
1349: pw.println("#include \"awt_p.h\"");
1350: pw.println("#include \"color.h\"");
1351: pw.println("#include \"colordata.h\"");
1352:
1353: pw.println("\n\nint main(){");
1354: j = 0;
1355: for (eo = symbolTable.elements(); eo.hasMoreElements();) {
1356: tp = (BaseType) eo.nextElement();
1357: if (tp instanceof StructType) {
1358: stp = (StructType) tp;
1359: if (!stp.getIsInterface()) {
1360: pw
1361: .println(stp.getName() + " temp" + j
1362: + ";\n");
1363: j++;
1364: }
1365: }
1366: }
1367: j = 0;
1368:
1369: pw.println("printf(\"long\t%d\\n\",(int)sizeof(long));");
1370: pw.println("printf(\"int\t%d\\n\",(int)sizeof(int));");
1371: pw.println("printf(\"short\t%d\\n\",(int)sizeof(short));");
1372: pw.println("printf(\"ptr\t%d\\n\",(int)sizeof(void *));");
1373: pw.println("printf(\"Bool\t%d\\n\",(int)sizeof(Bool));");
1374: pw.println("printf(\"Atom\t%d\\n\",(int)sizeof(Atom));");
1375: pw
1376: .println("printf(\"Window\t%d\\n\",(int)sizeof(Window));");
1377:
1378: for (eo = symbolTable.elements(); eo.hasMoreElements();) {
1379:
1380: tp = (BaseType) eo.nextElement();
1381: if (tp instanceof StructType) {
1382: stp = (StructType) tp;
1383: if (stp.getIsInterface()) {
1384: continue;
1385: }
1386: for (Enumeration e = stp.getMembers(); e
1387: .hasMoreElements();) {
1388: AtomicType atp = (AtomicType) e.nextElement();
1389: if (atp.isAlias())
1390: continue;
1391: pw.println("printf(\"" + stp.getName() + "."
1392: + atp.getName() + "\t%d\\n\""
1393: + ",(int)((unsigned long ) &temp" + j
1394: + "." + atp.getName()
1395: + "- (unsigned long ) &temp" + j
1396: + ") );");
1397:
1398: i++;
1399:
1400: }
1401: pw.println("printf(\"" + stp.getName()
1402: + "\t%d\\n\"" + ",(int)sizeof(temp" + j
1403: + "));");
1404:
1405: j++;
1406: }
1407:
1408: }
1409: pw.println("return 0;");
1410: pw.println("}");
1411: pw.close();
1412:
1413: } catch (Exception e) {
1414: e.printStackTrace();
1415: }
1416: }
1417:
1418: private void initTypes() {
1419: symbolTable.put("int", new AtomicType(AtomicType.TYPE_INT, "",
1420: "int"));
1421: symbolTable.put("short", new AtomicType(AtomicType.TYPE_SHORT,
1422: "", "short"));
1423: symbolTable.put("long", new AtomicType(AtomicType.TYPE_LONG,
1424: "", "long"));
1425: symbolTable.put("float", new AtomicType(AtomicType.TYPE_FLOAT,
1426: "", "float"));
1427: symbolTable.put("double", new AtomicType(
1428: AtomicType.TYPE_DOUBLE, "", "double"));
1429: symbolTable.put("Bool", new AtomicType(AtomicType.TYPE_BOOL,
1430: "", "Bool"));
1431: symbolTable.put("char", new AtomicType(AtomicType.TYPE_CHAR,
1432: "", "char"));
1433: symbolTable.put("byte", new AtomicType(AtomicType.TYPE_BYTE,
1434: "", "byte"));
1435: symbolTable.put("pointer", new AtomicType(AtomicType.TYPE_PTR,
1436: "", "pointer"));
1437: symbolTable.put("longlong", new AtomicType(
1438: AtomicType.TYPE_LONG_LONG, "", "longlong"));
1439: symbolTable.put("Atom", new AtomicType(AtomicType.TYPE_ATOM,
1440: "", "Atom"));
1441: symbolTable.put("ulong", new AtomicType(AtomicType.TYPE_ULONG,
1442: "", "ulong"));
1443: }
1444:
1445: public WrapperGenerator(String outputDir, String xlibFilename) {
1446: initTypes();
1447: try {
1448: BufferedReader in = new BufferedReader(new FileReader(
1449: xlibFilename));
1450: String line;
1451: String splits[];
1452: BaseType curType = null;
1453: while ((line = in.readLine()) != null) {
1454: int commentStart = line.indexOf("//");
1455: if (commentStart >= 0) {
1456: // remove comment
1457: line = line.substring(0, commentStart);
1458: }
1459:
1460: if ("".equals(line)) {
1461: // skip empty line
1462: continue;
1463: }
1464:
1465: splits = line.split("\\p{Space}+");
1466: if (splits.length >= 2) {
1467: String struct_name = curType.getName();
1468: String field_name = splits[1];
1469: String s_type = splits[2];
1470: BaseType bt = curType;
1471: int type = AtomicType.getTypeForString(s_type);
1472: AtomicType atp = null;
1473: if (bt != null && type != -1) {
1474: atp = new AtomicType(type, field_name, s_type);
1475: if (splits.length > 3) {
1476: atp.setAttributes(splits);
1477: }
1478: if (bt instanceof StructType) {
1479: StructType stp = (StructType) bt;
1480: stp.addMember(atp);
1481: } else if (bt instanceof FunctionType) {
1482: ((FunctionType) bt).addArgument(atp);
1483: }
1484: } else if (bt == null) {
1485: System.out
1486: .println("Cannot find " + struct_name);
1487: }
1488:
1489: } else if (line != null) {
1490: BaseType bt = (BaseType) symbolTable.get(line);
1491: if (bt == null) {
1492: if (line.startsWith("!")) {
1493: FunctionType ft = new FunctionType(line);
1494: ft.setName(line);
1495: symbolTable.put(ft.getName(), ft);
1496: curType = ft;
1497: } else {
1498: StructType stp = new StructType(line);
1499: stp.setName(line);
1500: curType = stp;
1501: symbolTable.put(stp.getName(), stp);
1502: }
1503: }
1504: }
1505:
1506: }
1507: in.close();
1508: } catch (Exception e) {
1509: e.printStackTrace();
1510: }
1511:
1512: }
1513:
1514: private void makeSizer(String outputDir) {
1515: if (wide) {
1516: sizerFileName = "sizer.64.c";
1517: } else {
1518: sizerFileName = "sizer.32.c";
1519: }
1520: File fp = new File(outputDir, sizerFileName);
1521: writeNativeSizer(fp.getAbsolutePath());
1522: }
1523:
1524: private boolean readSizeInfo(String sizeInfo) {
1525: try {
1526: File f = new File(sizeInfo + ".32");
1527: boolean res = true;
1528: FileInputStream fis = null;
1529: if (f.exists()) {
1530: fis = new FileInputStream(f);
1531: res = readSizeInfo(fis, false);
1532: fis.close();
1533: }
1534: f = new File(sizeInfo + ".64");
1535: if (f.exists()) {
1536: fis = new FileInputStream(f);
1537: res &= readSizeInfo(fis, true);
1538: fis.close();
1539: }
1540: return res;
1541: } catch (Exception e) {
1542: e.printStackTrace();
1543: return false;
1544: }
1545: }
1546:
1547: private void startGeneration(String outputDir, String sizeInfo) {
1548: if (readSizeInfo(sizeInfo)) {
1549: writeJavaWrapperClass(outputDir);
1550: } else {
1551: System.out.println("Error calculating offsets");
1552: }
1553: }
1554:
1555: public static void main(String[] args) {
1556:
1557: if (args.length < 4) {
1558: System.out
1559: .println("Usage:\nWrapperGenerator <output_dir> <xlibtypes.txt> <action> [<platform> | <sizes info file>]");
1560: System.out.println("Where <action>: gen, sizer");
1561: System.out.println(" <platform>: 32, 64");
1562: System.exit(1);
1563: }
1564:
1565: WrapperGenerator xparser = new WrapperGenerator(args[0],
1566: args[1]);
1567: if (args[2].equals("sizer")) {
1568: xparser.wide = args[3].equals("64");
1569: xparser.makeSizer(args[0]);
1570: } else if (args[2].equals("gen")) {
1571: xparser.startGeneration(args[0], args[3]);
1572: }
1573: }
1574:
1575: }
|