0001: /*
0002: * Copyright 1999-2004 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: * COMPONENT_NAME: idl.toJava
0027: *
0028: * ORIGINS: 27
0029: *
0030: * Licensed Materials - Property of IBM
0031: * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
0032: * RMI-IIOP v1.0
0033: *
0034: * @(#)Util.java 1.25 07/05/05
0035: */
0036:
0037: package com.sun.tools.corba.se.idl.toJavaPortable;
0038:
0039: // Notes:
0040: // -F46838.4<klr> Ported -td option from toJava.
0041: // -10/17/98 KLR Ported fix for d48911 from toJava
0042: // -10/18/98 KLR Ported fix from toJava for "unsigned long" constants
0043: // -F46082.51<daz> Removed code to collect makefile list generation inforamtion
0044: // from getStream(); see f46830.
0045: // -F46082.51<daz> Removed -stateful feature: methods javaStatefulName(String)
0046: // and javaStatefulName(SymtabEntry) are obsolete, supplanted by javaName().
0047: // -D54640<daz> Represent unsigned long long expressions with their computed
0048: // value rather than their actual representation (see notes in method
0049: // parseTerminal(), parseBinary(), and parseUnary().)
0050: // -D58319<daz> Add getVersion() method.
0051: // -D48034<daz> Import Helper classes for typedef struct members when generating
0052: // helper. See method addImportLines().
0053: // -D59851<daz> Modify to enable QuickTest build. (pending)
0054: // -D42256<daz> Determine import lines for template types, which may specify any
0055: // positive int., constant expression for a boundary. Such expression containing
0056: // non-literal contansts previously caused problems when appearing in constructs
0057: // structs, unions, exceptions, typedefs, operation types and parameters,
0058: // attributes; and of course, sequences, strings.
0059: // -D59063<daz> Add helper for global exception to stub import list.
0060: // -D58951<daz> Publicise members for QuickTest.
0061: // -D59421<klr> Change ValueBaseHolder to SerializableHolder
0062: // -D59596<klr> Prevent accesses to elements of empty Vectors.
0063: // -D59771<daz> Add import stmt for Helper of global type in stubs.
0064: // -D59355<daz> Remove target dir. from filename when writing to prolog.
0065: // -D59437<daz> Fill typename information for value boxes.
0066: // -D62023<klr> Don't import ValueBase*
0067: // -D62023<klr> Add corbaLevel
0068:
0069: import java.io.File;
0070: import java.io.PrintWriter;
0071: import java.math.BigInteger;
0072: import java.text.DateFormat;
0073: import java.util.Date;
0074: import java.util.Enumeration;
0075: import java.util.Hashtable;
0076: import java.util.Locale;
0077: import java.util.Vector;
0078:
0079: import com.sun.tools.corba.se.idl.ConstEntry;
0080: import com.sun.tools.corba.se.idl.EnumEntry;
0081: import com.sun.tools.corba.se.idl.ExceptionEntry;
0082: import com.sun.tools.corba.se.idl.GenFileStream;
0083: import com.sun.tools.corba.se.idl.InterfaceEntry;
0084: import com.sun.tools.corba.se.idl.MethodEntry;
0085: import com.sun.tools.corba.se.idl.NativeEntry;
0086: import com.sun.tools.corba.se.idl.ParameterEntry;
0087: import com.sun.tools.corba.se.idl.PrimitiveEntry;
0088: import com.sun.tools.corba.se.idl.SequenceEntry;
0089: import com.sun.tools.corba.se.idl.StringEntry;
0090: import com.sun.tools.corba.se.idl.StructEntry;
0091: import com.sun.tools.corba.se.idl.SymtabEntry;
0092: import com.sun.tools.corba.se.idl.TypedefEntry;
0093: import com.sun.tools.corba.se.idl.UnionBranch;
0094: import com.sun.tools.corba.se.idl.UnionEntry;
0095: import com.sun.tools.corba.se.idl.ValueEntry;
0096: import com.sun.tools.corba.se.idl.ValueBoxEntry;
0097: import com.sun.tools.corba.se.idl.InterfaceState;
0098:
0099: import com.sun.tools.corba.se.idl.constExpr.*;
0100:
0101: /**
0102: * Class Util is a repository of static members available for general
0103: * use by the IDL parser framework and any generator extensions.
0104: **/
0105: public class Util extends com.sun.tools.corba.se.idl.Util {
0106: // <d58319>
0107: /**
0108: * Fetch the version number of this build of the IDL-to-Java (portable)
0109: * compiler from the appropriate properties file.
0110: * @return the version number of this compiler build.
0111: **/
0112: public static String getVersion() {
0113: return com.sun.tools.corba.se.idl.Util
0114: .getVersion("com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp");
0115: } // getVersion
0116:
0117: /**
0118: * This method is called by Setup.preEmit, so
0119: * symbolTable is available for all Util methods.
0120: **/
0121: static void setSymbolTable(Hashtable symtab) {
0122: symbolTable = symtab;
0123: } // setSymbolTable
0124:
0125: public static void setPackageTranslation(Hashtable pkgtrans) {
0126: packageTranslation = pkgtrans;
0127: }
0128:
0129: public static boolean isInterface(String name) {
0130: return isInterface(name, symbolTable);
0131: } // isInterface
0132:
0133: static String arrayInfo(Vector arrayInfo) {
0134: int arrays = arrayInfo.size();
0135: String info = "";
0136: Enumeration e = arrayInfo.elements();
0137: while (e.hasMoreElements())
0138: info = info + '['
0139: + parseExpression((Expression) e.nextElement())
0140: + ']';
0141: return info;
0142: } // arrayInfo
0143:
0144: // <d58951> static String sansArrayInfo (Vector arrayInfo)
0145: public static String sansArrayInfo(Vector arrayInfo) {
0146: int arrays = arrayInfo.size();
0147: String brackets = "";
0148: for (int i = 0; i < arrays; ++i)
0149: brackets = brackets + "[]";
0150: return brackets;
0151: } // sansArrayInfo
0152:
0153: // <d58951> static String sansArrayInfo (String name)
0154: static public String sansArrayInfo(String name) {
0155: int index = name.indexOf('[');
0156: if (index >= 0) {
0157: String array = name.substring(index);
0158: name = name.substring(0, index);
0159: while (!array.equals("")) {
0160: name = name + "[]";
0161: array = array.substring(array.indexOf(']') + 1);
0162: }
0163: }
0164: return name;
0165: } // sansArrayInfo
0166:
0167: /**
0168: * Given a symbol table entry, return the name of
0169: * the file which should be created.
0170: **/
0171: public static String fileName(SymtabEntry entry, String extension) {
0172: NameModifier nm = new NameModifierImpl();
0173: return fileName(entry, nm, extension);
0174: } // fileName
0175:
0176: public static String fileName(SymtabEntry entry,
0177: NameModifier modifier, String extension) {
0178: // This may not be the most appropriate place for
0179: // the mkdir calls, but it's common to everything:
0180: String pkg = containerFullName(entry.container());
0181: if (pkg != null && !pkg.equals(""))
0182: mkdir(pkg);
0183:
0184: String name = entry.name();
0185: name = modifier.makeName(name) + extension;
0186: if (pkg != null && !pkg.equals(""))
0187: name = pkg + '/' + name;
0188:
0189: return name.replace('/', File.separatorChar);
0190: } // fileName
0191:
0192: public static GenFileStream stream(SymtabEntry entry,
0193: String extension) {
0194: NameModifier nm = new NameModifierImpl();
0195: return stream(entry, nm, extension);
0196: } // stream
0197:
0198: public static GenFileStream stream(SymtabEntry entry,
0199: NameModifier modifier, String extension) {
0200: return getStream(fileName(entry, modifier, extension), entry);
0201: }
0202:
0203: public static GenFileStream getStream(String name, SymtabEntry entry) {
0204: // <f46838.4>
0205: String absPathName = ((Arguments) Compile.compiler.arguments).targetDir
0206: + name;
0207: if (Compile.compiler.arguments.keepOldFiles
0208: && new File(absPathName).exists())
0209: return null;
0210: else
0211: // Write the data to the file stream
0212: return new GenFileStream(absPathName);
0213: } // getStream
0214:
0215: public static String containerFullName(SymtabEntry container) {
0216: String name = doContainerFullName(container);
0217: if (packageTranslation.size() > 0)
0218: name = translate(name);
0219: return name;
0220: }
0221:
0222: public static String translate(String name) {
0223: String head = name;
0224: String tail = "";
0225: int index;
0226: String trname;
0227:
0228: // Check for package name translations, starting with the
0229: // most specific match.
0230: do {
0231: trname = (String) (packageTranslation.get(head));
0232: if (trname != null)
0233: return trname + tail;
0234:
0235: index = head.lastIndexOf('/');
0236: if (index >= 0) {
0237: tail = head.substring(index) + tail;
0238: head = head.substring(0, index);
0239: }
0240: } while (index >= 0);
0241:
0242: return name;
0243: }
0244:
0245: private static String doContainerFullName(SymtabEntry container) {
0246: String name = "";
0247:
0248: if (container == null)
0249: name = "";
0250: else {
0251: if (container instanceof InterfaceEntry
0252: || container instanceof StructEntry
0253: || container instanceof UnionEntry)
0254: name = container.name() + "Package";
0255: else
0256: name = container.name();
0257:
0258: if (container.container() != null
0259: && !container.container().name().equals(""))
0260: name = doContainerFullName(container.container()) + '/'
0261: + name;
0262: }
0263:
0264: return name;
0265: } // doContainerFullName
0266:
0267: /**
0268: * Given a SymtabEntry, return the string which should be used
0269: * for this entry. Enums are converted to ints, typedefs and
0270: * sequences are converted to their info types. javaQualifiedName
0271: * does not do any of these conversions.
0272: **/
0273: public static String javaName(SymtabEntry entry) {
0274: // First get the real name of this type
0275: String name = "";
0276: if (entry instanceof TypedefEntry
0277: || entry instanceof SequenceEntry)
0278: try {
0279: name = sansArrayInfo((String) entry
0280: .dynamicVariable(Compile.typedefInfo));
0281: } catch (NoSuchFieldException e) {
0282: name = entry.name();
0283: }
0284: else if (entry instanceof PrimitiveEntry)
0285: name = javaPrimName(entry.name());
0286: else if (entry instanceof StringEntry)
0287: name = "String";
0288: else if (entry instanceof NativeEntry)
0289: name = javaNativeName(entry.name());
0290: else if (entry instanceof ValueEntry
0291: && entry.name().equals("ValueBase"))
0292: name = "java.io.Serializable";
0293: else if (entry instanceof ValueBoxEntry) {
0294: ValueBoxEntry v = (ValueBoxEntry) entry;
0295: TypedefEntry member = ((InterfaceState) v.state()
0296: .elementAt(0)).entry;
0297: SymtabEntry mType = member.type();
0298: if (mType instanceof PrimitiveEntry) {
0299: name = containerFullName(entry.container());
0300: if (!name.equals(""))
0301: name = name + '.';
0302: name = name + entry.name();
0303: } else
0304: name = javaName(mType);
0305: } else {
0306: name = containerFullName(entry.container());
0307: if (name.equals(""))
0308: name = entry.name();
0309: else
0310: name = name + '.' + entry.name();
0311: }
0312:
0313: // Make it a fully package-qualified name
0314: return name.replace('/', '.');
0315: } // javaName
0316:
0317: public static String javaPrimName(String name) {
0318: if (name.equals("long") || name.equals("unsigned long"))
0319: name = "int";
0320: else if (name.equals("octet"))
0321: name = "byte";
0322: // "unisigned long long" exceeds Java long.
0323: else if (name.equals("long long")
0324: || name.equals("unsigned long long"))
0325: name = "long";
0326: else if (name.equals("wchar"))
0327: name = "char";
0328: else if (name.equals("unsigned short"))
0329: name = "short";
0330: else if (name.equals("any"))
0331: name = "org.omg.CORBA.Any";
0332: else if (name.equals("TypeCode"))
0333: name = "org.omg.CORBA.TypeCode";
0334: else if (name.equals("Principal")) // <d61961>
0335: name = "org.omg.CORBA.Principal";
0336: return name;
0337: } // javaPrimName
0338:
0339: public static String javaNativeName(String name) {
0340:
0341: // translations for Native declarations according to CORBA 2.3 spec
0342:
0343: if (name.equals("AbstractBase") || name.equals("Cookie"))
0344: name = "java.lang.Object";
0345: else if (name.equals("Servant"))
0346: name = "org.omg.PortableServer.Servant";
0347: else if (name.equals("ValueFactory"))
0348: name = "org.omg.CORBA.portable.ValueFactory";
0349: return name;
0350: }
0351:
0352: /**
0353: * Given a symtabEntry, return the name of this entry. This
0354: * method does not do any conversions like javaName does.
0355: **/
0356: public static String javaQualifiedName(SymtabEntry entry) {
0357: String name = "";
0358: if (entry instanceof PrimitiveEntry)
0359: name = javaPrimName(entry.name());
0360: else if (entry instanceof StringEntry)
0361: name = "String";
0362: else if (entry instanceof ValueEntry
0363: && entry.name().equals("ValueBase"))
0364: name = "java.io.Serializable";
0365: else {
0366: SymtabEntry container = entry.container();
0367: if (container != null)
0368: name = container.name();
0369: if (name.equals(""))
0370: name = entry.name();
0371: else
0372: name = containerFullName(entry.container()) + '.'
0373: + entry.name();
0374: }
0375: return name.replace('/', '.');
0376: } // javaQualifiedName
0377:
0378: // <f46082.03> Publicize for extensions.
0379: //static String collapseName (String name)
0380:
0381: /**
0382: * Collapse primitive type names.
0383: **/
0384: public static String collapseName(String name) {
0385: if (name.equals("unsigned short"))
0386: name = "ushort";
0387: else if (name.equals("unsigned long"))
0388: name = "ulong";
0389: else if (name.equals("unsigned long long"))
0390: name = "ulonglong";
0391: else if (name.equals("long long"))
0392: name = "longlong";
0393: return name;
0394: } // collapseName
0395:
0396: /**
0397: *
0398: **/
0399: public static SymtabEntry typeOf(SymtabEntry entry) {
0400: while (entry instanceof TypedefEntry
0401: && ((TypedefEntry) entry).arrayInfo().isEmpty()
0402: && !(entry.type() instanceof SequenceEntry))
0403: entry = entry.type();
0404: return entry;
0405: } // typeOf
0406:
0407: /**
0408: * Fill the info field with the full name (with array info) of the type.
0409: **/
0410: static void fillInfo(SymtabEntry infoEntry) {
0411: String arrayInfo = "";
0412: SymtabEntry entry = infoEntry;
0413: boolean alreadyHave = false;
0414:
0415: do {
0416: try {
0417: alreadyHave = entry
0418: .dynamicVariable(Compile.typedefInfo) != null;
0419: } catch (NoSuchFieldException e) {
0420: }
0421: // If this entry's info has already been processed
0422: // don't bother processing it again, just take it.
0423: if (!alreadyHave) {
0424: if (entry instanceof TypedefEntry)
0425: arrayInfo = arrayInfo
0426: + arrayInfo(((TypedefEntry) entry)
0427: .arrayInfo());
0428: else if (entry instanceof SequenceEntry) {
0429: Expression maxSize = ((SequenceEntry) entry)
0430: .maxSize();
0431: if (maxSize == null)
0432: arrayInfo = arrayInfo + "[]";
0433: else
0434: arrayInfo = arrayInfo + '['
0435: + parseExpression(maxSize) + ']';
0436: }
0437: if (entry.type() == null) {
0438: // <d59437> Suppress this message. It tells the developer nothing, and
0439: // this path does not cause the algorithm to fail. Value boxes may
0440: // contain anonymous types, like a struct or enum.
0441: //System.err.println (getMessage ("PreEmit.indeterminateTypeInfo", entry.typeName ()));
0442: } else
0443: entry = entry.type();
0444: }
0445: } while (!alreadyHave
0446: && entry != null
0447: && (entry instanceof TypedefEntry || entry instanceof SequenceEntry));
0448: // <d59437> Value boxes may contain types lacking typename info., which
0449: // causes the 2nd case, below, to fail with exception when retrieving the
0450: // javaName().
0451: if (entry instanceof ValueBoxEntry)
0452: fillValueBoxInfo((ValueBoxEntry) entry);
0453: try {
0454: if (alreadyHave)
0455: infoEntry.dynamicVariable(Compile.typedefInfo,
0456: (String) entry
0457: .dynamicVariable(Compile.typedefInfo)
0458: + arrayInfo);
0459: else
0460: infoEntry.dynamicVariable(Compile.typedefInfo,
0461: javaName(entry) + arrayInfo);
0462: } catch (NoSuchFieldException e) {
0463: }
0464: } // fillInfo
0465:
0466: // <d59437>
0467: /**
0468: *
0469: **/
0470: static void fillValueBoxInfo(ValueBoxEntry vb) {
0471: SymtabEntry stateMember = (((InterfaceState) vb.state()
0472: .elementAt(0)).entry);
0473: if (stateMember.type() != null)
0474: Util.fillInfo(stateMember.type());
0475: Util.fillInfo(stateMember);
0476: } // fillValueBoxInfo
0477:
0478: /**
0479: *
0480: **/
0481: public static String holderName(SymtabEntry entry) {
0482: String name;
0483: if (entry instanceof PrimitiveEntry)
0484: if (entry.name().equals("any"))
0485: name = "org.omg.CORBA.AnyHolder";
0486: else if (entry.name().equals("TypeCode"))
0487: name = "org.omg.CORBA.TypeCodeHolder";
0488: else if (entry.name().equals("Principal")) // <d61961>
0489: name = "org.omg.CORBA.PrincipalHolder";
0490: else
0491: name = "org.omg.CORBA."
0492: + capitalize(javaQualifiedName(entry))
0493: + "Holder";
0494: else if (entry instanceof TypedefEntry) {
0495: TypedefEntry td = (TypedefEntry) entry;
0496: if (!td.arrayInfo().isEmpty()
0497: || td.type() instanceof SequenceEntry)
0498: name = javaQualifiedName(entry) + "Holder";
0499: else
0500: name = holderName(entry.type());
0501: } else if (entry instanceof StringEntry)
0502: name = "org.omg.CORBA.StringHolder";
0503: else if (entry instanceof ValueEntry) {
0504: if (entry.name().equals("ValueBase"))
0505: name = "org.omg.CORBA.ValueBaseHolder"; // <d59421>, <d60929>
0506: else
0507: name = javaName(entry) + "Holder";
0508: } else if (entry instanceof NativeEntry) {
0509: // do not attach holder to the translation for Native Entries, e.g.
0510: // for Cookie it should be CookieHolder instead of java.lang.ObjectHolder
0511: // returns the complete name for the package, etc.
0512: name = javaQualifiedName(entry) + "Holder";
0513: } else
0514: name = javaName(entry) + "Holder";
0515: return name;
0516: } // holderName
0517:
0518: /**
0519: * <d61056>
0520: **/
0521: public static String helperName(SymtabEntry entry,
0522: boolean qualifiedName) {
0523: if (entry instanceof ValueEntry)
0524: if (entry.name().equals("ValueBase"))
0525: return "org.omg.CORBA.ValueBaseHelper";
0526:
0527: if (qualifiedName)
0528: return javaQualifiedName(entry) + "Helper";
0529: else
0530: return javaName(entry) + "Helper";
0531: } // helperName
0532:
0533: public static final short TypeFile = 0, StubFile = 1,
0534: HelperFile = 2, HolderFile = 3, StateFile = 4;
0535:
0536: /**
0537: *
0538: **/
0539: public static void writePackage(PrintWriter stream,
0540: SymtabEntry entry) {
0541: writePackage(stream, entry, TypeFile);
0542: } // writePackage
0543:
0544: /**
0545: *
0546: **/
0547: public static void writePackage(PrintWriter stream,
0548: SymtabEntry entry, String name, short type) {
0549: if (name != null && !name.equals("")) {
0550: stream.println("package " + name.replace('/', '.') + ';');
0551:
0552: // This type is in a module. Just in case it refers to types
0553: // in the unnamed module, add an import statement for each of
0554: // those types.
0555: if (!Compile.compiler.importTypes.isEmpty()) {
0556: stream.println();
0557: Vector v = addImportLines(entry,
0558: Compile.compiler.importTypes, type);
0559: printImports(v, stream);
0560: }
0561: }
0562: } // writePackage
0563:
0564: /**
0565: *
0566: **/
0567: public static void writePackage(PrintWriter stream,
0568: SymtabEntry entry, short type) {
0569: String fullName = containerFullName(entry.container());
0570: if (fullName != null && !fullName.equals("")) {
0571: stream.println("package " + fullName.replace('/', '.')
0572: + ';');
0573: // This type is in a module. Just in case it refers to types
0574: // in the unnamed module, add an import statement for each of
0575: // those types.
0576: if ((type != HolderFile || entry instanceof TypedefEntry)
0577: && !Compile.compiler.importTypes.isEmpty()) {
0578: stream.println();
0579: Vector v = addImportLines(entry,
0580: Compile.compiler.importTypes, type);
0581: printImports(v, stream);
0582: }
0583: /*
0584: Enumeration e = Compile.compiler.importTypes.elements ();
0585: while (e.hasMoreElements ())
0586: {
0587: SymtabEntry i = (SymtabEntry)e.nextElement ();
0588: // Write import for type
0589: if (!(i instanceof TypedefEntry))
0590: stream.println ("import " + i.name () + ';');
0591:
0592: // Write import for Helper
0593: if (!(i instanceof ConstEntry))
0594: stream.println ("import " + i.name () + "Helper;");
0595:
0596: // Write import for Holder
0597: if (!(i instanceof ConstEntry))
0598: if (!(i instanceof TypedefEntry) || (i.type () instanceof SequenceEntry || !((TypedefEntry)i).arrayInfo ().isEmpty ()))
0599: stream.println ("import " + i.name () + "Holder;");
0600: }
0601: */
0602: }
0603: } // writePackage
0604:
0605: /**
0606: *
0607: **/
0608: static private void printImports(Vector importList,
0609: PrintWriter stream) {
0610: Enumeration e = importList.elements();
0611: while (e.hasMoreElements())
0612: stream.println("import " + (String) e.nextElement() + ';');
0613: } // printImport
0614:
0615: /**
0616: *
0617: **/
0618: static private void addTo(Vector importList, String name) {
0619: // REVISIT - <d62023-klr> was also importing ValueBaseHolder and Helper
0620: if (name.startsWith("ValueBase")) // don't import ValueBase*
0621: if ((name.compareTo("ValueBase") == 0)
0622: || (name.compareTo("ValueBaseHolder") == 0)
0623: || (name.compareTo("ValueBaseHelper") == 0))
0624: return;
0625: if (!importList.contains(name))
0626: importList.addElement(name);
0627: } // addTo
0628:
0629: /**
0630: *
0631: **/
0632: static private Vector addImportLines(SymtabEntry entry,
0633: Vector importTypes, short type) {
0634: Vector importList = new Vector();
0635: if (entry instanceof ConstEntry) {
0636: ConstEntry c = (ConstEntry) entry;
0637: Object cvalue = c.value().value();
0638: if (cvalue instanceof ConstEntry
0639: && importTypes.contains(cvalue))
0640: addTo(importList, ((ConstEntry) cvalue).name());
0641: } else if (entry instanceof ValueEntry && type == HelperFile) // <d59512>
0642: {
0643: // This code inspired by ValueGen.getConcreteBaseTypeCode(). Helper method
0644: // type() could be invoked against a global valuetype.
0645: if (((ValueEntry) entry).derivedFrom().size() > 0) // <59596> KLR HACK
0646: {
0647: ValueEntry base = (ValueEntry) ((ValueEntry) entry)
0648: .derivedFrom().elementAt(0);
0649: String baseName = base.name();
0650: if (!"ValueBase".equals(baseName))
0651: if (importTypes.contains(base))
0652: addTo(importList, baseName + "Helper");
0653: }
0654: } else if (entry instanceof InterfaceEntry
0655: && (type == TypeFile || type == StubFile)) {
0656: InterfaceEntry i = (InterfaceEntry) entry;
0657:
0658: if (i instanceof ValueEntry) // <d59512>
0659: {
0660: // Examine interface parents in supports vector.
0661: Enumeration e = ((ValueEntry) i).supports().elements();
0662: while (e.hasMoreElements()) {
0663: SymtabEntry parent = (SymtabEntry) e.nextElement();
0664: if (importTypes.contains(parent)) {
0665: addTo(importList, parent.name() + "Operations");
0666: }
0667: // If this is a stub, then recurse to the parents
0668: if (type == StubFile) {
0669: if (importTypes.contains(parent))
0670: addTo(importList, parent.name());
0671: Vector subImportList = addImportLines(parent,
0672: importTypes, StubFile);
0673: Enumeration en = subImportList.elements();
0674: while (en.hasMoreElements()) {
0675: addTo(importList, (String) en.nextElement());
0676: }
0677: }
0678: }
0679: }
0680: // Interface or valuetype -- Examine interface and valuetype parents,
0681: // Look through derivedFrom vector
0682: Enumeration e = i.derivedFrom().elements();
0683: while (e.hasMoreElements()) {
0684: SymtabEntry parent = (SymtabEntry) e.nextElement();
0685: if (importTypes.contains(parent)) {
0686: addTo(importList, parent.name());
0687: // <d59512> Always add both imports, even though superfluous. Cannot
0688: // tell when writing Operations or Signature interface!
0689: if (!(parent instanceof ValueEntry)) // && parent.name ().equals ("ValueBase")))
0690: addTo(importList, parent.name() + "Operations");
0691: }
0692: // If this is a stub, then recurse to the parents
0693: if (type == StubFile) {
0694: Vector subImportList = addImportLines(parent,
0695: importTypes, StubFile);
0696: Enumeration en = subImportList.elements();
0697: while (en.hasMoreElements()) {
0698: addTo(importList, (String) en.nextElement());
0699: }
0700: }
0701: }
0702: // Look through methods vector
0703: e = i.methods().elements();
0704: while (e.hasMoreElements()) {
0705: MethodEntry m = (MethodEntry) e.nextElement();
0706:
0707: // Look at method type
0708: SymtabEntry mtype = typeOf(m.type());
0709: if (mtype != null && importTypes.contains(mtype))
0710: if (type == TypeFile || type == StubFile) {
0711: addTo(importList, mtype.name());
0712: addTo(importList, mtype.name() + "Holder");
0713: if (type == StubFile)
0714: addTo(importList, mtype.name() + "Helper");
0715: }
0716: checkForArrays(mtype, importTypes, importList);
0717: // <d42256> Print import lines for globals constants and constants
0718: // within global interfaces.
0719: if (type == StubFile)
0720: checkForBounds(mtype, importTypes, importList);
0721:
0722: // Look through exceptions
0723: Enumeration exEnum = m.exceptions().elements();
0724: while (exEnum.hasMoreElements()) {
0725: ExceptionEntry ex = (ExceptionEntry) exEnum
0726: .nextElement();
0727: if (importTypes.contains(ex)) {
0728: addTo(importList, ex.name());
0729: addTo(importList, ex.name() + "Helper"); // <d59063>
0730: }
0731: }
0732:
0733: // Look through parameters
0734: Enumeration parms = m.parameters().elements();
0735: while (parms.hasMoreElements()) {
0736: ParameterEntry parm = (ParameterEntry) parms
0737: .nextElement();
0738: SymtabEntry parmType = typeOf(parm.type());
0739: if (importTypes.contains(parmType)) {
0740: // <d59771> Helper needed in stubs.
0741: if (type == StubFile)
0742: addTo(importList, parmType.name()
0743: + "Helper");
0744: if (parm.passType() == ParameterEntry.In)
0745: addTo(importList, parmType.name());
0746: else
0747: addTo(importList, parmType.name()
0748: + "Holder");
0749: }
0750: checkForArrays(parmType, importTypes, importList);
0751: // <d42256>
0752: if (type == StubFile)
0753: checkForBounds(parmType, importTypes,
0754: importList);
0755: }
0756: }
0757: } else if (entry instanceof StructEntry) {
0758: StructEntry s = (StructEntry) entry;
0759:
0760: // Look through the members
0761: Enumeration members = s.members().elements();
0762: while (members.hasMoreElements()) {
0763: SymtabEntry member = (TypedefEntry) members
0764: .nextElement();
0765: // <d48034> Need to add helper name for typedef members. This name
0766: // is referenced at typecode generation in Helper class.
0767: SymtabEntry memberType = member.type();
0768: member = typeOf(member);
0769: if (importTypes.contains(member)) {
0770: // If this IS a typedef, then there are only Helper/Holder classes.
0771: //if (!(member instanceof TypedefEntry))
0772: // <d59437> Valueboxes
0773: if (!(member instanceof TypedefEntry)
0774: && !(member instanceof ValueBoxEntry))
0775: addTo(importList, member.name());
0776: // <d48034> Add helper name of alias, too, if member is a typedef.
0777: //if (type == HelperFile)
0778: // addTo (importList, member.name () + "Helper");
0779: if (type == HelperFile) {
0780: addTo(importList, member.name() + "Helper");
0781: if (memberType instanceof TypedefEntry)
0782: addTo(importList, memberType.name()
0783: + "Helper");
0784: }
0785: }
0786: checkForArrays(member, importTypes, importList);
0787: checkForBounds(member, importTypes, importList);
0788: }
0789: } else if (entry instanceof TypedefEntry) {
0790: TypedefEntry t = (TypedefEntry) entry;
0791: String arrays = checkForArrayBase(t, importTypes,
0792: importList);
0793: if (type == HelperFile) {
0794: checkForArrayDimensions(arrays, importTypes, importList);
0795: try {
0796: String name = (String) t
0797: .dynamicVariable(Compile.typedefInfo);
0798: int index = name.indexOf('[');
0799: if (index >= 0)
0800: name = name.substring(0, index);
0801: // See if the base type should be added to the list.
0802: SymtabEntry typeEntry = (SymtabEntry) symbolTable
0803: .get(name);
0804: if (typeEntry != null
0805: && importTypes.contains(typeEntry))
0806: addTo(importList, typeEntry.name() + "Helper");
0807: } catch (NoSuchFieldException e) {
0808: }
0809:
0810: // <d42256> Typedefs for global bounded strings need import
0811: // statement when bound expression contains non-literal constants.
0812: checkForBounds(typeOf(t), importTypes, importList);
0813: }
0814: Vector subImportList = addImportLines(t.type(),
0815: importTypes, type);
0816: Enumeration e = subImportList.elements();
0817: while (e.hasMoreElements())
0818: addTo(importList, (String) e.nextElement());
0819: } else if (entry instanceof UnionEntry) {
0820: UnionEntry u = (UnionEntry) entry;
0821:
0822: // Look at the discriminant type
0823: SymtabEntry utype = typeOf(u.type());
0824: if (utype instanceof EnumEntry
0825: && importTypes.contains(utype))
0826: addTo(importList, utype.name());
0827:
0828: // Look through the branches
0829: Enumeration branches = u.branches().elements();
0830: while (branches.hasMoreElements()) {
0831: UnionBranch branch = (UnionBranch) branches
0832: .nextElement();
0833: SymtabEntry branchEntry = typeOf(branch.typedef);
0834: if (importTypes.contains(branchEntry)) {
0835: addTo(importList, branchEntry.name());
0836: if (type == HelperFile)
0837: addTo(importList, branchEntry.name() + "Helper");
0838: }
0839: checkForArrays(branchEntry, importTypes, importList);
0840: // <d42256>
0841: checkForBounds(branchEntry, importTypes, importList);
0842: }
0843: }
0844:
0845: // If a typedef is not a sequence or an array, only holders and
0846: // helpers are generated for it. Remove references to such
0847: // class names.
0848: Enumeration en = importList.elements();
0849: while (en.hasMoreElements()) {
0850: String name = (String) en.nextElement();
0851: SymtabEntry e = (SymtabEntry) symbolTable.get(name);
0852: if (e != null && e instanceof TypedefEntry) {
0853: TypedefEntry t = (TypedefEntry) e;
0854: if (t.arrayInfo().size() == 0
0855: || !(t.type() instanceof SequenceEntry))
0856: importList.removeElement(name);
0857: }
0858: }
0859: return importList;
0860: } // addImportLines
0861:
0862: /**
0863: *
0864: **/
0865: static private void checkForArrays(SymtabEntry entry,
0866: Vector importTypes, Vector importList) {
0867: if (entry instanceof TypedefEntry) {
0868: TypedefEntry t = (TypedefEntry) entry;
0869: String arrays = checkForArrayBase(t, importTypes,
0870: importList);
0871: checkForArrayDimensions(arrays, importTypes, importList);
0872: }
0873: } // checkForArrays
0874:
0875: /**
0876: *
0877: **/
0878: static private String checkForArrayBase(TypedefEntry t,
0879: Vector importTypes, Vector importList) {
0880: String arrays = "";
0881: try {
0882: String name = (String) t
0883: .dynamicVariable(Compile.typedefInfo);
0884: int index = name.indexOf('[');
0885: if (index >= 0) {
0886: arrays = name.substring(index);
0887: name = name.substring(0, index);
0888: }
0889:
0890: // See if the base type should be added to the list.
0891: SymtabEntry typeEntry = (SymtabEntry) symbolTable.get(name);
0892: if (typeEntry != null && importTypes.contains(typeEntry))
0893: addTo(importList, typeEntry.name());
0894: } catch (NoSuchFieldException e) {
0895: }
0896: return arrays;
0897: } // checkForArrayBase
0898:
0899: /**
0900: *
0901: **/
0902: static private void checkForArrayDimensions(String arrays,
0903: Vector importTypes, Vector importList) {
0904: // See if any of the arrays contain a constentry.
0905: // If so, see if it should be added to the list.
0906: while (!arrays.equals("")) {
0907: int index = arrays.indexOf(']');
0908: String dim = arrays.substring(1, index);
0909: arrays = arrays.substring(index + 1);
0910: SymtabEntry constant = (SymtabEntry) symbolTable.get(dim);
0911: if (constant == null) {
0912: // A constant expr could be of the form <const> OR
0913: // <interface>.<const>. This if branch checks for that case.
0914: int i = dim.lastIndexOf('.');
0915: if (i >= 0)
0916: constant = (SymtabEntry) symbolTable.get(dim
0917: .substring(0, i));
0918: }
0919: if (constant != null && importTypes.contains(constant))
0920: addTo(importList, constant.name());
0921: }
0922: } // checkForArrayDimensions
0923:
0924: // <d42256> Call the following method when its necessary to determine the
0925: // the import types for IDL constructs containing arbitrary positive int.
0926: // expressions, which may specify non-literal constants.
0927:
0928: /**
0929: * Determine the import lines for template types.
0930: **/
0931: static private void checkForBounds(SymtabEntry entry,
0932: Vector importTypes, Vector importList) {
0933: // Obtain actual type, just to be complete.
0934: SymtabEntry entryType = entry;
0935: while (entryType instanceof TypedefEntry)
0936: entryType = entryType.type();
0937:
0938: if (entryType instanceof StringEntry
0939: && ((StringEntry) entryType).maxSize() != null)
0940: checkForGlobalConstants(((StringEntry) entryType).maxSize()
0941: .rep(), importTypes, importList);
0942: else if (entryType instanceof SequenceEntry
0943: && ((SequenceEntry) entryType).maxSize() != null)
0944: checkForGlobalConstants(((SequenceEntry) entryType)
0945: .maxSize().rep(), importTypes, importList);
0946: } // checkForBounds
0947:
0948: /**
0949: * Extract the global constants from the supplied integer expression
0950: * representation (string) and add them to the supplied import list.
0951: **/
0952: static private void checkForGlobalConstants(String exprRep,
0953: Vector importTypes, Vector importList) {
0954: // NOTE: Do not use '/' as a delimiter. Symbol table names use '/' as a
0955: // delimiter and would not be otherwise properly collected. Blanks and
0956: // arithmetic symbols do not appear in tokens, except for '/'.
0957: java.util.StringTokenizer st = new java.util.StringTokenizer(
0958: exprRep, " +-*()~&|^%<>");
0959: while (st.hasMoreTokens()) {
0960: String token = st.nextToken();
0961: // When token contains '/', it represents the division symbol or
0962: // a nested type (e.g., I/x). Ignore the division symbol, and don't
0963: // forget constants declared within global interfaces!
0964: if (!token.equals("/")) {
0965: SymtabEntry typeEntry = (SymtabEntry) symbolTable
0966: .get(token);
0967: if (typeEntry instanceof ConstEntry) {
0968: int slashIdx = token.indexOf('/');
0969: if (slashIdx < 0) // Possible global constant
0970: {
0971: if (importTypes.contains(typeEntry))
0972: addTo(importList, typeEntry.name());
0973: } else // Possible constant in global interface
0974: {
0975: SymtabEntry constContainer = (SymtabEntry) symbolTable
0976: .get(token.substring(0, slashIdx));
0977: if (constContainer instanceof InterfaceEntry
0978: && importTypes.contains(constContainer))
0979: addTo(importList, constContainer.name());
0980: }
0981: }
0982: }
0983: }
0984: } // checkForGlobalConstants
0985:
0986: /**
0987: *
0988: **/
0989: public static void writeInitializer(String indent, String name,
0990: String arrayDcl, SymtabEntry entry, PrintWriter stream) {
0991: if (entry instanceof TypedefEntry) {
0992: TypedefEntry td = (TypedefEntry) entry;
0993: writeInitializer(indent, name, arrayDcl
0994: + sansArrayInfo(td.arrayInfo()), td.type(), stream);
0995: } else if (entry instanceof SequenceEntry)
0996: writeInitializer(indent, name, arrayDcl + "[]", entry
0997: .type(), stream);
0998: else if (entry instanceof EnumEntry)
0999: if (arrayDcl.length() > 0)
1000: stream.println(indent + javaName(entry) + ' ' + name
1001: + arrayDcl + " = null;");
1002: else
1003: stream.println(indent + javaName(entry) + ' ' + name
1004: + " = null;");
1005: else if (entry instanceof PrimitiveEntry) {
1006: boolean array = arrayDcl.length() > 0;
1007: String tname = javaPrimName(entry.name());
1008: if (tname.equals("boolean"))
1009: stream.println(indent + "boolean " + name + arrayDcl
1010: + " = " + (array ? "null;" : "false;"));
1011: else if (tname.equals("org.omg.CORBA.TypeCode"))
1012: stream.println(indent + "org.omg.CORBA.TypeCode "
1013: + name + arrayDcl + " = null;");
1014: else if (tname.equals("org.omg.CORBA.Any"))
1015: stream.println(indent + "org.omg.CORBA.Any " + name
1016: + arrayDcl + " = null;");
1017: else if (tname.equals("org.omg.CORBA.Principal")) // <d61961>
1018: stream.println(indent + "org.omg.CORBA.Principal "
1019: + name + arrayDcl + " = null;");
1020: else
1021: stream.println(indent + tname + ' ' + name + arrayDcl
1022: + " = "
1023: + (array ? "null;" : '(' + tname + ")0;"));
1024: }
1025: // <f46082.51> Remove -stateful feature. This case is identical to next one
1026: // because javaName() supplants javaStatefulName().
1027: //else if (entry instanceof InterfaceEntry && ((InterfaceEntry)entry).state () != null)
1028: // stream.println (indent + javaStatefulName ((InterfaceEntry)entry) + ' ' + name + arrayDcl + " = null;");
1029: else
1030: stream.println(indent + javaName(entry) + ' ' + name
1031: + arrayDcl + " = null;");
1032: } // writeInitializer
1033:
1034: /**
1035: *
1036: **/
1037: public static void writeInitializer(String indent, String name,
1038: String arrayDcl, SymtabEntry entry, String initializer,
1039: PrintWriter stream) {
1040: if (entry instanceof TypedefEntry) {
1041: TypedefEntry td = (TypedefEntry) entry;
1042: writeInitializer(indent, name, arrayDcl
1043: + sansArrayInfo(td.arrayInfo()), td.type(),
1044: initializer, stream);
1045: } else if (entry instanceof SequenceEntry)
1046: writeInitializer(indent, name, arrayDcl + "[]", entry
1047: .type(), initializer, stream);
1048: else if (entry instanceof EnumEntry)
1049: if (arrayDcl.length() > 0)
1050: stream.println(indent + javaName(entry) + ' ' + name
1051: + arrayDcl + " = " + initializer + ';');
1052: else
1053: stream.println(indent + javaName(entry) + ' ' + name
1054: + " = " + initializer + ';');
1055: else if (entry instanceof PrimitiveEntry) {
1056: boolean array = arrayDcl.length() > 0;
1057: String tname = javaPrimName(entry.name());
1058: if (tname.equals("boolean"))
1059: stream.println(indent + "boolean " + name + arrayDcl
1060: + " = " + initializer + ';');
1061: else if (tname.equals("org.omg.CORBA.TypeCode"))
1062: stream.println(indent + "org.omg.CORBA.TypeCode "
1063: + name + arrayDcl + " = " + initializer + ';');
1064: else if (tname.equals("org.omg.CORBA.Any"))
1065: stream.println(indent + "org.omg.CORBA.Any " + name
1066: + arrayDcl + " = " + initializer + ';');
1067: else if (tname.equals("org.omg.CORBA.Principal")) // <d61961>
1068: stream.println(indent + "org.omg.CORBA.Principal "
1069: + name + arrayDcl + " = " + initializer + ';');
1070: else
1071: stream.println(indent + tname + ' ' + name + arrayDcl
1072: + " = " + initializer + ';');
1073: }
1074: // <f46082.51> Remove -stateful feature. This case is identical to next one
1075: // because javaName() supplants javaStatefulName().
1076: //else if (entry instanceof InterfaceEntry && ((InterfaceEntry)entry).state () != null)
1077: // stream.println (indent + javaStatefulName ((InterfaceEntry)entry) + ' ' + name + arrayDcl + " = " + initializer + ';');
1078: else
1079: stream.println(indent + javaName(entry) + ' ' + name
1080: + arrayDcl + " = " + initializer + ';');
1081: } // writeInitializer
1082:
1083: /**
1084: *
1085: **/
1086: public static void mkdir(String name) {
1087: String targetDir = ((Arguments) Compile.compiler.arguments).targetDir; // F46838.4
1088: name = (targetDir + name).replace('/', File.separatorChar); // F46838.4
1089: File pkg = new File(name);
1090: if (!pkg.exists())
1091: if (!pkg.mkdirs())
1092: System.err.println(getMessage("Util.cantCreatePkg",
1093: name));
1094: } // mkdir
1095:
1096: /**
1097: *
1098: **/
1099: public static void writeProlog(PrintWriter stream, String filename) {
1100: // <d59355> Remove target directory
1101: String targetDir = ((Arguments) Compile.compiler.arguments).targetDir;
1102: if (targetDir != null)
1103: filename = filename.substring(targetDir.length());
1104: stream.println();
1105: stream.println("/**");
1106: stream.println("* " + filename.replace(File.separatorChar, '/')
1107: + " .");
1108: stream.println("* "
1109: + Util.getMessage("toJavaProlog1", Util.getMessage(
1110: "Version.product", Util
1111: .getMessage("Version.number"))));
1112: // <d48911> Do not introduce invalid escape characters into comment! <daz>
1113: //stream.println ("* " + Util.getMessage ("toJavaProlog2", Compile.compiler.arguments.file));
1114: stream.println("* "
1115: + Util.getMessage("toJavaProlog2",
1116: Compile.compiler.arguments.file.replace(
1117: File.separatorChar, '/')));
1118:
1119: ///////////////
1120: // This SHOULD work, but there's a bug in the JDK.
1121: // stream.println ("* " + DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.getDefault ()).format (new Date ()));
1122: // This gets around the bug:
1123:
1124: DateFormat formatter = DateFormat.getDateTimeInstance(
1125: DateFormat.FULL, DateFormat.FULL, Locale.getDefault());
1126:
1127: // Japanese-specific workaround. JDK bug 4069784 being repaired by JavaSoft.
1128: // Keep this transient solution until bug fix is reported.cd .
1129:
1130: if (Locale.getDefault() == Locale.JAPAN)
1131: formatter
1132: .setTimeZone(java.util.TimeZone.getTimeZone("JST"));
1133: else
1134: formatter.setTimeZone(java.util.TimeZone.getDefault());
1135:
1136: stream.println("* " + formatter.format(new Date()));
1137:
1138: // <daz>
1139: ///////////////
1140:
1141: stream.println("*/");
1142: stream.println();
1143: } // writeProlog
1144:
1145: // keywords ending in Holder or Helper or Package have '_' prepended.
1146: // These prepended underscores must not be part of anything sent
1147: // across the wire, so these two methods are provided to strip them
1148: // off.
1149:
1150: /**
1151: *
1152: **/
1153: public static String stripLeadingUnderscores(String string) {
1154: while (string.startsWith("_"))
1155: string = string.substring(1);
1156: return string;
1157: } // stripLeadingUnderscores
1158:
1159: /**
1160: *
1161: **/
1162: public static String stripLeadingUnderscoresFromID(String string) {
1163: String stringPrefix = "";
1164: int slashIndex = string.indexOf(':');
1165: if (slashIndex >= 0)
1166: do {
1167: stringPrefix = stringPrefix
1168: + string.substring(0, slashIndex + 1);
1169: string = string.substring(slashIndex + 1);
1170: while (string.startsWith("_"))
1171: string = string.substring(1);
1172: slashIndex = string.indexOf('/');
1173: } while (slashIndex >= 0);
1174: return stringPrefix + string;
1175: } // stripLeadingUnderscoresFromID
1176:
1177: /**
1178: *
1179: **/
1180: public static String parseExpression(Expression e) {
1181: if (e instanceof Terminal)
1182: return parseTerminal((Terminal) e);
1183: else if (e instanceof BinaryExpr)
1184: return parseBinary((BinaryExpr) e);
1185: else if (e instanceof UnaryExpr)
1186: return parseUnary((UnaryExpr) e);
1187: else
1188: return "(UNKNOWN_VALUE)"; // This shouldn't happen unless someone slips
1189: // in another type of expression.
1190: } // parseExpression
1191:
1192: /**
1193: *
1194: **/
1195: static String parseTerminal(Terminal e) {
1196: if (e.value() instanceof ConstEntry) {
1197: ConstEntry c = (ConstEntry) e.value();
1198: if (c.container() instanceof InterfaceEntry)
1199: return javaQualifiedName(c.container()) + '.'
1200: + c.name();
1201: else
1202: return javaQualifiedName(c) + ".value";
1203: } else if (e.value() instanceof Expression)
1204: return '(' + parseExpression((Expression) e.value()) + ')';
1205: else if (e.value() instanceof Character) {
1206: if (((Character) e.value()).charValue() == '\013')
1207: // e.rep is \v. \v for vertical tab is meaningless in Java.
1208: return "'\\013'";
1209: else if (((Character) e.value()).charValue() == '\007')
1210: // e.rep is \a. \a for alert is meaningless in Java.
1211: return "'\\007'";
1212: else if (e.rep().startsWith("'\\x"))
1213: return hexToOctal(e.rep());
1214: else if (e.rep().equals("'\\?'"))
1215: return "'?'";
1216: else
1217: return e.rep();
1218: } else if (e.value() instanceof Boolean)
1219: return e.value().toString();
1220:
1221: // <d54640> If value is type "unsigned long long" (ull) and its magnitude
1222: // is greater than the maximal Java long (i.e., IDL long long) value, then
1223: // return its signed representation rather than its actual representation.
1224: /*
1225: // Support long long
1226: //else if (e.value () instanceof Long)
1227: else if (e.value () instanceof BigInteger &&
1228: (e.type ().indexOf ("long long") >= 0 || e.type ().equals ("unsigned long"))) // <klr>
1229: {
1230: String rep = e.rep ();
1231: int index = rep.indexOf (')');
1232: if (index < 0)
1233: return rep + 'L';
1234: else
1235: return rep.substring (0, index) + 'L' + rep.substring (index);
1236: }
1237: */
1238: else if (e.value() instanceof BigInteger) {
1239: // Get the correct primitive type. Since integer types (octet, short,
1240: // long, long long, unsigned short, unsigned long, unsigned long long)
1241: // could be aliased (typedef'ed) to any arbitrary levels, the code
1242: // below walks up the alias chain to get to the primitive type.
1243:
1244: // Get the symbol table entry corresponding to the 'type'.
1245: SymtabEntry typeEntry = (SymtabEntry) symbolTable.get(e
1246: .type());
1247:
1248: // Get to the primitive type.
1249: while (typeEntry.type() != null) {
1250: typeEntry = typeEntry.type();
1251: }
1252: String type = typeEntry.name();
1253:
1254: if (type.equals("unsigned long long")
1255: && ((BigInteger) e.value())
1256: .compareTo(Expression.llMax) > 0) // value > long long Max?
1257: {
1258: // Convert to signed value, which will always be negative.
1259: BigInteger v = (BigInteger) e.value();
1260: v = v.subtract(Expression.twoPow64);
1261: int index = e.rep().indexOf(')');
1262: if (index < 0)
1263: return v.toString() + 'L';
1264: else
1265: return '(' + v.toString() + 'L' + ')';
1266: } else if (type.indexOf("long long") >= 0
1267: || type.equals("unsigned long")) {
1268: String rep = e.rep();
1269: int index = rep.indexOf(')');
1270: if (index < 0)
1271: return rep + 'L';
1272: else
1273: return rep.substring(0, index) + 'L'
1274: + rep.substring(index);
1275: } else
1276: return e.rep();
1277: } // end <d54640>
1278: else
1279: return e.rep();
1280: } // parseTerminal
1281:
1282: /**
1283: *
1284: **/
1285: static String hexToOctal(String hex) {
1286: // The format of hex is '/xXX' where XX is one or two hex digits.
1287: // This statement pulls off XX.
1288: hex = hex.substring(3, hex.length() - 1);
1289: return "'\\" + Integer.toString(Integer.parseInt(hex, 16), 8)
1290: + "'";
1291: } // hexToOctal
1292:
1293: /**
1294: *
1295: **/
1296: static String parseBinary(BinaryExpr e) {
1297: String castString = "";
1298: if (e.value() instanceof Float || e.value() instanceof Double) {
1299: castString = "(double)";
1300: if (!(e instanceof Plus || e instanceof Minus
1301: || e instanceof Times || e instanceof Divide))
1302: System.err.println("Operator " + e.op()
1303: + " is invalid on floating point numbers");
1304: } else if (e.value() instanceof Number) {
1305: if (e.type().indexOf("long long") >= 0)
1306: castString = "(long)";
1307: else
1308: castString = "(int)";
1309: } else {
1310: castString = "";
1311: System.err.println("Unknown type in constant expression");
1312: }
1313:
1314: // <d54640> Must emit value rather than representation when type "unsigned
1315: // long long" (ull) because emitted binary arithmetic expressions containing
1316: // ull's converted to long (i.e., IDL long long) do not always compute to
1317: // the correct result.
1318:
1319: //return castString + '(' + parseExpression (e.left ()) + ' ' + e.op () + ' ' + parseExpression (e.right ()) + ')';
1320: if (e.type().equals("unsigned long long")) {
1321: BigInteger value = (BigInteger) e.value();
1322: if (value.compareTo(Expression.llMax) > 0) // value > long long max?
1323: value = value.subtract(Expression.twoPow64); // Convert to Java long (signed)
1324: return castString + '(' + value.toString() + 'L' + ')';
1325: } else
1326: return castString + '(' + parseExpression(e.left()) + ' '
1327: + e.op() + ' ' + parseExpression(e.right()) + ')';
1328: // <d54640> end
1329: } // parseBinary
1330:
1331: /**
1332: *
1333: **/
1334: static String parseUnary(UnaryExpr e) {
1335: if (!(e.value() instanceof Number))
1336: return "(UNKNOWN_VALUE)"; // This shouldn't happen if the parser checked the expression types correctly.
1337: else if ((e.value() instanceof Float || e.value() instanceof Double)
1338: && e instanceof Not)
1339: return "(UNKNOWN_VALUE)"; // This shouldn't happen if the parser checked the expression types correctly.
1340: else {
1341: String castString = "";
1342: if (e.operand().value() instanceof Float
1343: || e.operand().value() instanceof Double)
1344: castString = "(double)";
1345: // Support long long.
1346: //else
1347: // castString = "(long)";
1348: else if (e.type().indexOf("long long") >= 0)
1349: castString = "(long)";
1350: else
1351: castString = "(int)";
1352:
1353: // <d54640> Must emit value rather than representation when type is
1354: // "unsigned long long" (ull) because emitted unary arithmetic expressions
1355: // containing a ull converted to long (i.e., IDL long long) do not always
1356: // compute to the correct result.
1357:
1358: //return castString + e.op () + parseExpression (e.operand ());
1359: if (e.type().equals("unsigned long long")) {
1360: BigInteger value = (BigInteger) e.value();
1361: if (value.compareTo(Expression.llMax) > 0) // value > long long max?
1362: value = value.subtract(Expression.twoPow64); // Convert to Java long (signed)
1363: return castString + '(' + value.toString() + 'L' + ')';
1364: } else
1365: return castString + e.op()
1366: + parseExpression(e.operand());
1367: // end <d54640>
1368: }
1369: } // parseUnary
1370:
1371: /**
1372: *
1373: **/
1374: public static boolean IDLEntity(SymtabEntry entry) {
1375: boolean rc = true;
1376: if (entry instanceof PrimitiveEntry
1377: || entry instanceof StringEntry)
1378: rc = false;
1379: else if (entry instanceof TypedefEntry)
1380: rc = IDLEntity(entry.type());
1381: return rc;
1382: } // IDLEntity
1383:
1384: // <d62023>
1385: /**
1386: * @return true if the current setting of corbaLevel is within delta of
1387: * the range min <= corbaLevel <= max
1388: **/
1389: public static boolean corbaLevel(float min, float max) {
1390: float level = Compile.compiler.arguments.corbaLevel;
1391: float delta = 0.001f;
1392: if ((level - min + delta >= 0.0f)
1393: && (max - level + delta >= 0.0f))
1394: return true;
1395: else
1396: return false;
1397: } // corbaLevel
1398:
1399: static Hashtable symbolTable = new Hashtable();
1400: static Hashtable packageTranslation = new Hashtable();
1401: } // class Util
|