1 /*
2  * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 /*
26  * COMPONENT_NAME: idl.toJava
27  *
28  * ORIGINS: 27
29  *
30  * Licensed Materials - Property of IBM
31  * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
32  * RMI-IIOP v1.0
33  *
34  */
35 
36 package com.sun.tools.corba.se.idl.toJavaPortable;
37 
38 // Notes:
39 // -F46838.4<klr> Ported -td option from toJava.
40 // -10/17/98  KLR Ported fix for d48911 from toJava
41 // -10/18/98  KLR Ported fix from toJava for "unsigned long" constants
42 // -F46082.51<daz> Removed code to collect makefile list generation inforamtion
43 //  from getStream(); see f46830.
44 // -F46082.51<daz> Removed -stateful feature: methods javaStatefulName(String)
45 //  and javaStatefulName(SymtabEntry) are obsolete, supplanted by javaName().
46 // -D54640<daz> Represent unsigned long long expressions with their computed
47 //  value rather than their actual representation (see notes in method
48 //  parseTerminal(), parseBinary(), and parseUnary().)
49 // -D58319<daz> Add getVersion() method.
50 // -D48034<daz> Import Helper classes for typedef struct members when generating
51 //  helper.  See method addImportLines().
52 // -D59851<daz> Modify to enable QuickTest build. (pending)
53 // -D42256<daz> Determine import lines for template types, which may specify any
54 //  positive int., constant expression for a boundary. Such expression containing
55 //  non-literal contansts previously caused problems when appearing in constructs
56 //  structs, unions, exceptions, typedefs, operation types and parameters,
57 //  attributes; and of course, sequences, strings.
58 // -D59063<daz> Add helper for global exception to stub import list.
59 // -D58951<daz> Publicise members for QuickTest.
60 // -D59421<klr> Change ValueBaseHolder to SerializableHolder
61 // -D59596<klr> Prevent accesses to elements of empty Vectors.
62 // -D59771<daz> Add import stmt for Helper of global type in stubs.
63 // -D59355<daz> Remove target dir. from filename when writing to prolog.
64 // -D59437<daz> Fill typename information for value boxes.
65 // -D62023<klr> Don't import ValueBase*
66 // -D62023<klr> Add corbaLevel
67 
68 import java.io.File;
69 import java.io.PrintWriter;
70 import java.math.BigInteger;
71 import java.text.DateFormat;
72 import java.util.Date;
73 import java.util.Enumeration;
74 import java.util.Hashtable;
75 import java.util.Locale;
76 import java.util.Vector;
77 
78 import com.sun.tools.corba.se.idl.ConstEntry;
79 import com.sun.tools.corba.se.idl.EnumEntry;
80 import com.sun.tools.corba.se.idl.ExceptionEntry;
81 import com.sun.tools.corba.se.idl.GenFileStream;
82 import com.sun.tools.corba.se.idl.InterfaceEntry;
83 import com.sun.tools.corba.se.idl.MethodEntry;
84 import com.sun.tools.corba.se.idl.NativeEntry;
85 import com.sun.tools.corba.se.idl.ParameterEntry;
86 import com.sun.tools.corba.se.idl.PrimitiveEntry;
87 import com.sun.tools.corba.se.idl.SequenceEntry;
88 import com.sun.tools.corba.se.idl.StringEntry;
89 import com.sun.tools.corba.se.idl.StructEntry;
90 import com.sun.tools.corba.se.idl.SymtabEntry;
91 import com.sun.tools.corba.se.idl.TypedefEntry;
92 import com.sun.tools.corba.se.idl.UnionBranch;
93 import com.sun.tools.corba.se.idl.UnionEntry;
94 import com.sun.tools.corba.se.idl.ValueEntry;
95 import com.sun.tools.corba.se.idl.ValueBoxEntry;
96 import com.sun.tools.corba.se.idl.InterfaceState;
97 
98 import com.sun.tools.corba.se.idl.constExpr.*;
99 
100 /**
101  * Class Util is a repository of static members available for general
102  * use by the IDL parser framework and any generator extensions.
103  **/
104 public class Util extends com.sun.tools.corba.se.idl.Util
105 {
106   // <d58319>
107   /**
108    * Fetch the version number of this build of the IDL-to-Java (portable)
109    * compiler from the appropriate properties file.
110    * @return the version number of this compiler build.
111    **/
getVersion()112   public static String getVersion ()
113   {
114     return com.sun.tools.corba.se.idl.Util.getVersion ("com/sun/tools/corba/se/idl/toJavaPortable/toJavaPortable.prp");
115   } // getVersion
116 
117   /**
118    * This method is called by Setup.preEmit, so
119    * symbolTable is available for all Util methods.
120    **/
setSymbolTable(Hashtable symtab)121   static void setSymbolTable (Hashtable symtab)
122   {
123     symbolTable = symtab;
124   } // setSymbolTable
125 
setPackageTranslation( Hashtable pkgtrans )126   public static void setPackageTranslation( Hashtable pkgtrans )
127   {
128     packageTranslation = pkgtrans ;
129   }
130 
isInterface(String name)131   public static boolean isInterface (String name)
132   {
133     return isInterface (name, symbolTable);
134   } // isInterface
135 
arrayInfo(Vector arrayInfo)136   static String arrayInfo (Vector arrayInfo)
137   {
138     int         arrays = arrayInfo.size ();
139     String      info   = "";
140     Enumeration e      = arrayInfo.elements ();
141     while (e.hasMoreElements ())
142       info = info + '[' + parseExpression ((Expression)e.nextElement ()) + ']';
143     return info;
144   } // arrayInfo
145 
146   // <d58951> static String sansArrayInfo (Vector arrayInfo)
sansArrayInfo(Vector arrayInfo)147   public static String sansArrayInfo (Vector arrayInfo)
148   {
149     int    arrays   = arrayInfo.size ();
150     String brackets = "";
151     for (int i = 0; i < arrays; ++i)
152       brackets = brackets + "[]";
153     return brackets;
154   } // sansArrayInfo
155 
156   // <d58951> static String sansArrayInfo (String name)
sansArrayInfo(String name)157   static public String sansArrayInfo (String name)
158   {
159     int index = name.indexOf ('[');
160     if (index >= 0)
161     {
162       String array = name.substring (index);
163       name = name.substring (0, index);
164       while (!array.equals (""))
165       {
166         name = name + "[]";
167         array = array.substring (array.indexOf (']') + 1);
168       }
169     }
170     return name;
171   } // sansArrayInfo
172 
173   /**
174    * Given a symbol table entry, return the name of
175    * the file which should be created.
176    **/
fileName(SymtabEntry entry, String extension )177   public static String fileName (SymtabEntry entry, String extension )
178   {
179     NameModifier nm = new NameModifierImpl() ;
180     return fileName( entry, nm, extension ) ;
181   } // fileName
182 
fileName(SymtabEntry entry, NameModifier modifier, String extension )183   public static String fileName (SymtabEntry entry, NameModifier modifier, String extension )
184   {
185     // This may not be the most appropriate place for
186     // the mkdir calls, but it's common to everything:
187     String pkg = containerFullName (entry.container ());
188     if (pkg != null && !pkg.equals (""))
189       mkdir (pkg);
190 
191     String name = entry.name ();
192     name = modifier.makeName( name ) + extension ;
193     if (pkg != null && !pkg.equals (""))
194       name = pkg + '/' + name;
195 
196     return name.replace ('/', File.separatorChar);
197   } // fileName
198 
stream(SymtabEntry entry, String extension)199   public static GenFileStream stream (SymtabEntry entry, String extension)
200   {
201     NameModifier nm = new NameModifierImpl() ;
202     return stream(entry, nm, extension);
203   } // stream
204 
stream(SymtabEntry entry, NameModifier modifier, String extension )205   public static GenFileStream stream (SymtabEntry entry, NameModifier modifier, String extension )
206   {
207     return getStream ( fileName (entry,modifier,extension), entry ) ;
208   }
209 
getStream(String name, SymtabEntry entry)210   public static GenFileStream getStream (String name, SymtabEntry entry)
211   {
212     // <f46838.4>
213     String absPathName = ((Arguments)Compile.compiler.arguments).targetDir + name;
214     if (Compile.compiler.arguments.keepOldFiles && new File (absPathName).exists ())
215       return null;
216     else
217       // Write the data to the file stream
218       return new GenFileStream (absPathName);
219   } // getStream
220 
containerFullName( SymtabEntry container)221   public static String containerFullName( SymtabEntry container)
222   {
223       String name = doContainerFullName( container ) ;
224       if (packageTranslation.size() > 0)
225           name = translate( name ) ;
226       return name ;
227   }
228 
translate( String name )229   public static String translate( String name )
230   {
231       String head = name ;
232       String tail = "" ;
233       int index ;
234       String trname ;
235 
236       // Check for package name translations, starting with the
237       // most specific match.
238       do {
239           trname = (String)(packageTranslation.get( head )) ;
240           if (trname != null)
241               return trname + tail ;
242 
243           index = head.lastIndexOf( '/' ) ;
244           if (index >= 0) {
245               tail = head.substring( index ) + tail ;
246               head = head.substring( 0, index ) ;
247           }
248       } while (index >= 0) ;
249 
250       return name ;
251   }
252 
doContainerFullName(SymtabEntry container)253   private static String doContainerFullName (SymtabEntry container)
254   {
255     String name = "";
256 
257     if (container == null)
258       name = "";
259     else
260     {
261       if (container instanceof InterfaceEntry ||
262           container instanceof StructEntry ||
263           container instanceof UnionEntry)
264         name = container.name () + "Package";
265       else
266         name = container.name ();
267 
268       if (container.container () != null &&
269         !container.container ().name ().equals (""))
270         name = doContainerFullName (container.container ()) + '/' + name;
271     }
272 
273     return name;
274   } // doContainerFullName
275 
276   /**
277    * Given a SymtabEntry, return the string which should be used
278    * for this entry. Enums are converted to ints, typedefs and
279    * sequences are converted to their info types. javaQualifiedName
280    * does not do any of these conversions.
281    **/
javaName(SymtabEntry entry)282   public static String javaName (SymtabEntry entry)
283   {
284     // First get the real name of this type
285     String name = "";
286     if (entry instanceof TypedefEntry || entry instanceof SequenceEntry)
287       try
288       {
289         name = sansArrayInfo ((String)entry.dynamicVariable (Compile.typedefInfo));
290       }
291       catch (NoSuchFieldException e)
292       {
293         name = entry.name ();
294       }
295     else if (entry instanceof PrimitiveEntry)
296       name = javaPrimName (entry.name ());
297     else if (entry instanceof StringEntry)
298       name = "String";
299     else if (entry instanceof NativeEntry)
300       name = javaNativeName (entry.name());
301     else if (entry instanceof ValueEntry && entry.name ().equals ("ValueBase"))
302         name = "java.io.Serializable";
303     else if (entry instanceof ValueBoxEntry)
304     {
305       ValueBoxEntry v = (ValueBoxEntry) entry;
306       TypedefEntry member = ((InterfaceState) v.state ().elementAt (0)).entry;
307       SymtabEntry mType = member.type ();
308       if (mType instanceof PrimitiveEntry)
309       {
310          name = containerFullName (entry.container ());
311          if (!name.equals (""))
312            name = name + '.';
313          name = name + entry.name ();
314       }
315       else
316          name = javaName (mType);
317     }
318     else
319     {
320       name = containerFullName (entry.container ());
321       if (name.equals (""))
322         name = entry.name ();
323       else
324         name = name + '.' + entry.name ();
325     }
326 
327     // Make it a fully package-qualified name
328     return name.replace ('/', '.');
329   } // javaName
330 
javaPrimName(String name)331   public static String javaPrimName (String name)
332   {
333     if (name.equals ("long") || name.equals ("unsigned long"))
334       name = "int";
335     else if (name.equals ("octet"))
336       name = "byte";
337     // "unisigned long long" exceeds Java long.
338     else if (name.equals ("long long") || name.equals ("unsigned long long"))
339       name = "long";
340     else if (name.equals ("wchar"))
341       name = "char";
342     else if (name.equals ("unsigned short"))
343       name = "short";
344     else if (name.equals ("any"))
345       name = "org.omg.CORBA.Any";
346     else if (name.equals ("TypeCode"))
347       name = "org.omg.CORBA.TypeCode";
348     else if (name.equals ("Principal")) // <d61961>
349       name = "org.omg.CORBA.Principal";
350     return name;
351   } // javaPrimName
352 
javaNativeName(String name)353   public static String javaNativeName (String name)
354   {
355 
356     // translations for Native declarations according to CORBA 2.3 spec
357 
358     if (name.equals ("AbstractBase") || name.equals ("Cookie"))
359       name = "java.lang.Object";
360     else if (name.equals ("Servant"))
361       name = "org.omg.PortableServer.Servant";
362     else if (name.equals ("ValueFactory"))
363       name = "org.omg.CORBA.portable.ValueFactory";
364     return name;
365   }
366 
367 
368   /**
369    * Given a symtabEntry, return the name of this entry. This
370    * method does not do any conversions like javaName does.
371    **/
javaQualifiedName(SymtabEntry entry)372   public static String javaQualifiedName (SymtabEntry entry)
373   {
374     String name = "";
375     if (entry instanceof PrimitiveEntry)
376       name = javaPrimName (entry.name ());
377     else if (entry instanceof StringEntry)
378       name = "String";
379     else if (entry instanceof ValueEntry && entry.name ().equals ("ValueBase"))
380       name = "java.io.Serializable";
381     else
382     {
383       SymtabEntry container = entry.container ();
384       if (container != null)
385         name = container.name ();
386       if (name.equals (""))
387         name = entry.name ();
388       else
389         name = containerFullName (entry.container ()) + '.' + entry.name ();
390     }
391     return name.replace ('/', '.');
392   } // javaQualifiedName
393 
394   // <f46082.03> Publicize for extensions.
395   //static String collapseName (String name)
396 
397   /**
398    * Collapse primitive type names.
399    **/
collapseName(String name)400   public static String collapseName (String name)
401   {
402     if (name.equals ("unsigned short"))
403       name = "ushort";
404     else if (name.equals ("unsigned long"))
405       name = "ulong";
406     else if (name.equals ("unsigned long long"))
407       name = "ulonglong";
408     else if (name.equals ("long long"))
409       name = "longlong";
410     return name;
411   } // collapseName
412 
413   /**
414    *
415    **/
typeOf(SymtabEntry entry)416   public static SymtabEntry typeOf (SymtabEntry entry)
417   {
418     while (entry instanceof TypedefEntry && ((TypedefEntry)entry).arrayInfo ().isEmpty () && !(entry.type () instanceof SequenceEntry))
419       entry = entry.type ();
420     return entry;
421   } // typeOf
422 
423   /**
424    * Fill the info field with the full name (with array info) of the type.
425    **/
fillInfo(SymtabEntry infoEntry)426   static void fillInfo (SymtabEntry infoEntry)
427   {
428     String      arrayInfo   = "";
429     SymtabEntry entry       = infoEntry;
430     boolean     alreadyHave = false;
431 
432     do
433     {
434       try
435       {
436         alreadyHave = entry.dynamicVariable (Compile.typedefInfo) != null;
437       }
438       catch (NoSuchFieldException e)
439       {}
440       // If this entry's info has already been processed
441       // don't bother processing it again, just take it.
442       if (!alreadyHave)
443       {
444         if (entry instanceof TypedefEntry)
445           arrayInfo = arrayInfo + arrayInfo (((TypedefEntry)entry).arrayInfo ());
446         else if (entry instanceof SequenceEntry)
447         {
448           Expression maxSize = ((SequenceEntry)entry).maxSize ();
449           if (maxSize == null)
450             arrayInfo = arrayInfo + "[]";
451           else
452             arrayInfo = arrayInfo + '[' + parseExpression (maxSize) + ']';
453         }
454         if (entry.type () == null)
455         {
456           // <d59437> Suppress this message.  It tells the developer nothing, and
457           // this path does not cause the algorithm to fail.  Value boxes may
458           // contain anonymous types, like a struct or enum.
459           //System.err.println (getMessage ("PreEmit.indeterminateTypeInfo", entry.typeName ()));
460         }
461         else
462           entry = entry.type ();
463       }
464     } while (!alreadyHave && entry != null &&
465         (entry instanceof TypedefEntry || entry instanceof SequenceEntry));
466     // <d59437> Value boxes may contain types lacking typename info., which
467     // causes the 2nd case, below, to fail with exception when retrieving the
468     // javaName().
469     if (entry instanceof ValueBoxEntry)
470       fillValueBoxInfo ((ValueBoxEntry)entry);
471     try
472     {
473       if (alreadyHave)
474         infoEntry.dynamicVariable (Compile.typedefInfo, (String)entry.dynamicVariable (Compile.typedefInfo) + arrayInfo);
475       else
476         infoEntry.dynamicVariable (Compile.typedefInfo, javaName (entry) + arrayInfo);
477     }
478     catch (NoSuchFieldException e)
479     {}
480   } // fillInfo
481 
482   // <d59437>
483   /**
484    *
485    **/
fillValueBoxInfo(ValueBoxEntry vb)486   static void fillValueBoxInfo (ValueBoxEntry vb)
487   {
488     SymtabEntry stateMember = (((InterfaceState) vb.state ().elementAt (0)).entry);
489     if (stateMember.type() != null)
490       Util.fillInfo (stateMember.type ());
491     Util.fillInfo (stateMember);
492   } // fillValueBoxInfo
493 
494   /**
495    *
496    **/
holderName(SymtabEntry entry)497   public static String holderName (SymtabEntry entry)
498   {
499     String name;
500     if (entry instanceof PrimitiveEntry)
501       if (entry.name ().equals ("any"))
502         name = "org.omg.CORBA.AnyHolder";
503       else if (entry.name ().equals ("TypeCode"))
504         name = "org.omg.CORBA.TypeCodeHolder";
505       else if (entry.name ().equals ("Principal")) // <d61961>
506         name = "org.omg.CORBA.PrincipalHolder";
507       else
508         name = "org.omg.CORBA." + capitalize (javaQualifiedName (entry)) + "Holder";
509     else if (entry instanceof TypedefEntry)
510     {
511       TypedefEntry td = (TypedefEntry)entry;
512       if (!td.arrayInfo ().isEmpty () || td.type () instanceof SequenceEntry)
513         name = javaQualifiedName (entry) + "Holder";
514       else
515         name = holderName (entry.type ());
516     }
517     else if (entry instanceof StringEntry)
518       name = "org.omg.CORBA.StringHolder";
519     else if (entry instanceof ValueEntry)
520     {
521       if (entry.name ().equals ("ValueBase"))
522           name = "org.omg.CORBA.ValueBaseHolder"; // <d59421>, <d60929>
523       else
524           name = javaName (entry) + "Holder";
525     } else if (entry instanceof NativeEntry) {
526       // do not attach holder to the translation for Native Entries, e.g.
527       // for Cookie it should be CookieHolder instead of java.lang.ObjectHolder
528       // returns the complete name for the package, etc.
529       name = javaQualifiedName(entry) + "Holder";
530     }
531     else
532       name = javaName (entry) + "Holder";
533     return name;
534   } // holderName
535 
536   /**
537    * <d61056>
538    **/
helperName(SymtabEntry entry, boolean qualifiedName)539   public static String helperName (SymtabEntry entry, boolean qualifiedName)
540   {
541     if (entry instanceof ValueEntry)
542       if (entry.name ().equals ("ValueBase"))
543           return "org.omg.CORBA.ValueBaseHelper";
544 
545     if (qualifiedName)
546       return javaQualifiedName (entry) + "Helper";
547     else
548       return javaName (entry) + "Helper";
549   } // helperName
550 
551   public static final short
552       TypeFile   = 0,
553       StubFile   = 1,
554       HelperFile = 2,
555       HolderFile = 3,
556       StateFile  = 4;
557 
558   /**
559    *
560    **/
writePackage(PrintWriter stream, SymtabEntry entry)561   public static void writePackage (PrintWriter stream, SymtabEntry entry)
562   {
563     writePackage (stream, entry, TypeFile);
564   } // writePackage
565 
566   /**
567    *
568    **/
writePackage(PrintWriter stream, SymtabEntry entry, String name, short type)569   public static void writePackage (PrintWriter stream, SymtabEntry entry, String name, short type)
570   {
571     if (name != null && !name.equals (""))
572     {
573       stream.println ("package " + name.replace ('/', '.') + ';');
574 
575       // This type is in a module.  Just in case it refers to types
576       // in the unnamed module, add an import statement for each of
577       // those types.
578       if (!Compile.compiler.importTypes.isEmpty ())
579       {
580         stream.println ();
581         Vector v = addImportLines (entry, Compile.compiler.importTypes, type);
582         printImports (v, stream);
583       }
584     }
585   } // writePackage
586 
587   /**
588    *
589    **/
writePackage(PrintWriter stream, SymtabEntry entry, short type)590   public static void writePackage (PrintWriter stream, SymtabEntry entry, short type)
591   {
592     String fullName = containerFullName (entry.container ());
593     if (fullName != null && !fullName.equals (""))
594     {
595       stream.println ("package " + fullName.replace ('/', '.') + ';');
596        // This type is in a module.  Just in case it refers to types
597       // in the unnamed module, add an import statement for each of
598       // those types.
599       if ((type != HolderFile || entry instanceof TypedefEntry) && !Compile.compiler.importTypes.isEmpty ())
600       {
601         stream.println ();
602         Vector v = addImportLines (entry, Compile.compiler.importTypes, type);
603         printImports (v, stream);
604       }
605       /*
606       Enumeration e = Compile.compiler.importTypes.elements ();
607       while (e.hasMoreElements ())
608       {
609         SymtabEntry i = (SymtabEntry)e.nextElement ();
610         // Write import for type
611         if (!(i instanceof TypedefEntry))
612           stream.println ("import " + i.name () + ';');
613 
614         // Write import for Helper
615         if (!(i instanceof ConstEntry))
616           stream.println ("import " + i.name () + "Helper;");
617 
618         // Write import for Holder
619         if (!(i instanceof ConstEntry))
620           if (!(i instanceof TypedefEntry) || (i.type () instanceof SequenceEntry || !((TypedefEntry)i).arrayInfo ().isEmpty ()))
621             stream.println ("import " + i.name () + "Holder;");
622       }
623       */
624     }
625   } // writePackage
626 
627   /**
628    *
629    **/
printImports(Vector importList, PrintWriter stream)630   static private void printImports (Vector importList, PrintWriter stream)
631   {
632     Enumeration e = importList.elements ();
633     while (e.hasMoreElements ())
634       stream.println ("import " + (String)e.nextElement () + ';');
635   } // printImport
636 
637   /**
638    *
639    **/
addTo(Vector importList, String name)640   static private void addTo (Vector importList, String name)
641   {
642     // REVISIT - <d62023-klr> was also importing ValueBaseHolder and Helper
643     if (name.startsWith ("ValueBase"))  // don't import ValueBase*
644       if ((name.compareTo ("ValueBase") == 0) ||
645           (name.compareTo ("ValueBaseHolder") == 0) ||
646               (name.compareTo ("ValueBaseHelper") == 0))
647         return;
648     if (!importList.contains (name))
649       importList.addElement (name);
650   } // addTo
651 
652   /**
653    *
654    **/
addImportLines(SymtabEntry entry, Vector importTypes, short type)655   static private Vector addImportLines (SymtabEntry entry, Vector importTypes, short type)
656   {
657     Vector importList = new Vector ();
658     if (entry instanceof ConstEntry)
659     {
660       ConstEntry c      = (ConstEntry)entry;
661       Object     cvalue = c.value ().value ();
662       if (cvalue instanceof ConstEntry && importTypes.contains (cvalue))
663         addTo (importList, ((ConstEntry)cvalue).name ());
664     }
665     else if (entry instanceof ValueEntry && type == HelperFile) // <d59512>
666     {
667       // This code inspired by ValueGen.getConcreteBaseTypeCode().  Helper method
668       // type() could be invoked against a global valuetype.
669       if (((ValueEntry)entry).derivedFrom ().size () > 0) // <59596> KLR HACK
670       {
671         ValueEntry base = (ValueEntry)((ValueEntry)entry).derivedFrom ().elementAt (0);
672         String baseName = base.name ();
673         if (!"ValueBase".equals (baseName))
674           if (importTypes.contains (base))
675             addTo (importList, baseName + "Helper");
676       }
677     }
678     else if (entry instanceof InterfaceEntry && (type == TypeFile || type == StubFile))
679     {
680       InterfaceEntry i = (InterfaceEntry)entry;
681 
682       if (i instanceof ValueEntry) // <d59512>
683       {
684         // Examine interface parents in supports vector.
685         Enumeration e = ((ValueEntry)i).supports ().elements ();
686         while (e.hasMoreElements ())
687         {
688           SymtabEntry parent = (SymtabEntry)e.nextElement ();
689           if (importTypes.contains (parent))
690           {
691             addTo (importList, parent.name () + "Operations");
692           }
693           // If this is a stub, then recurse to the parents
694           if (type == StubFile)
695           {
696             if (importTypes.contains (parent))
697               addTo (importList, parent.name ());
698             Vector subImportList = addImportLines (parent, importTypes, StubFile);
699             Enumeration en = subImportList.elements ();
700             while (en.hasMoreElements ())
701             {
702               addTo (importList, (String)en.nextElement ());
703             }
704           }
705         }
706       }
707       // Interface or valuetype -- Examine interface and valuetype parents,
708       // Look through derivedFrom vector
709       Enumeration e = i.derivedFrom ().elements ();
710       while (e.hasMoreElements ())
711       {
712         SymtabEntry parent = (SymtabEntry)e.nextElement ();
713         if (importTypes.contains (parent))
714         {
715           addTo (importList, parent.name ());
716           // <d59512> Always add both imports, even though superfluous.  Cannot
717           // tell when writing Operations or Signature interface!
718           if (!(parent instanceof ValueEntry)) // && parent.name ().equals ("ValueBase")))
719             addTo (importList, parent.name () + "Operations");
720         }
721         // If this is a stub, then recurse to the parents
722         if (type == StubFile)
723         {
724           Vector subImportList = addImportLines (parent, importTypes, StubFile);
725           Enumeration en = subImportList.elements ();
726           while (en.hasMoreElements ())
727           {
728             addTo (importList, (String)en.nextElement ());
729           }
730         }
731       }
732       // Look through methods vector
733       e = i.methods ().elements ();
734       while (e.hasMoreElements ())
735       {
736         MethodEntry m = (MethodEntry)e.nextElement ();
737 
738         // Look at method type
739         SymtabEntry mtype = typeOf (m.type ());
740         if (mtype != null && importTypes.contains (mtype))
741           if (type == TypeFile || type == StubFile)
742           {
743             addTo (importList, mtype.name ());
744             addTo (importList, mtype.name () + "Holder");
745             if (type == StubFile)
746               addTo (importList, mtype.name () + "Helper");
747           }
748         checkForArrays (mtype, importTypes, importList);
749         // <d42256> Print import lines for globals constants and constants
750         // within global interfaces.
751         if (type == StubFile)
752           checkForBounds (mtype, importTypes, importList);
753 
754         // Look through exceptions
755         Enumeration exEnum = m.exceptions ().elements ();
756         while (exEnum.hasMoreElements ())
757         {
758           ExceptionEntry ex = (ExceptionEntry)exEnum.nextElement ();
759           if (importTypes.contains (ex))
760           {
761             addTo (importList, ex.name ());
762             addTo (importList, ex.name () + "Helper"); // <d59063>
763           }
764         }
765 
766         // Look through parameters
767         Enumeration parms = m.parameters ().elements ();
768         while (parms.hasMoreElements ())
769         {
770           ParameterEntry parm = (ParameterEntry)parms.nextElement ();
771           SymtabEntry parmType = typeOf (parm.type ());
772           if (importTypes.contains (parmType))
773           {
774             // <d59771> Helper needed in stubs.
775             if (type == StubFile)
776               addTo (importList, parmType.name () + "Helper");
777             if (parm.passType () == ParameterEntry.In)
778               addTo (importList, parmType.name ());
779             else
780               addTo (importList, parmType.name () + "Holder");
781           }
782           checkForArrays (parmType, importTypes, importList);
783           // <d42256>
784           if (type == StubFile)
785             checkForBounds (parmType, importTypes, importList);
786         }
787       }
788     }
789     else if (entry instanceof StructEntry)
790     {
791       StructEntry s = (StructEntry)entry;
792 
793       // Look through the members
794       Enumeration members = s.members ().elements ();
795       while (members.hasMoreElements ())
796       {
797         SymtabEntry member = (TypedefEntry)members.nextElement ();
798         // <d48034> Need to add helper name for typedef members.  This name
799         // is referenced at typecode generation in Helper class.
800         SymtabEntry memberType = member.type ();
801         member = typeOf (member);
802         if (importTypes.contains (member))
803         {
804           // If this IS a typedef, then there are only Helper/Holder classes.
805           //if (!(member instanceof TypedefEntry))
806           // <d59437>  Valueboxes
807           if (!(member instanceof TypedefEntry) && !(member instanceof ValueBoxEntry))
808             addTo (importList, member.name ());
809           // <d48034> Add helper name of alias, too, if member is a typedef.
810           //if (type == HelperFile)
811           //  addTo (importList, member.name () + "Helper");
812           if (type == HelperFile)
813           {
814             addTo (importList, member.name () + "Helper");
815             if (memberType instanceof TypedefEntry)
816               addTo (importList, memberType.name () + "Helper");
817           }
818         }
819         checkForArrays (member, importTypes, importList);
820         checkForBounds (member, importTypes, importList);
821       }
822     }
823     else if (entry instanceof TypedefEntry)
824     {
825       TypedefEntry t = (TypedefEntry)entry;
826       String arrays = checkForArrayBase (t, importTypes, importList);
827       if (type == HelperFile)
828       {
829         checkForArrayDimensions (arrays, importTypes, importList);
830         try
831         {
832           String name = (String)t.dynamicVariable (Compile.typedefInfo);
833           int index = name.indexOf ('[');
834           if (index >= 0)
835             name = name.substring (0, index);
836           // See if the base type should be added to the list.
837           SymtabEntry typeEntry = (SymtabEntry)symbolTable.get (name);
838           if (typeEntry != null && importTypes.contains (typeEntry))
839             addTo (importList, typeEntry.name () + "Helper");
840         }
841         catch (NoSuchFieldException e)
842         {}
843 
844         // <d42256> Typedefs for global bounded strings need import
845         // statement when bound expression contains non-literal constants.
846         checkForBounds (typeOf (t), importTypes, importList);
847       }
848       Vector subImportList = addImportLines (t.type (), importTypes, type);
849       Enumeration e = subImportList.elements ();
850       while (e.hasMoreElements ())
851         addTo (importList, (String)e.nextElement ());
852     }
853     else if (entry instanceof UnionEntry)
854     {
855       UnionEntry u = (UnionEntry)entry;
856 
857       // Look at the discriminant type
858       SymtabEntry utype = typeOf (u.type ());
859       if (utype instanceof EnumEntry && importTypes.contains (utype))
860         addTo (importList, utype.name ());
861 
862       // Look through the branches
863       Enumeration branches = u.branches ().elements ();
864       while (branches.hasMoreElements ())
865       {
866         UnionBranch branch = (UnionBranch)branches.nextElement ();
867         SymtabEntry branchEntry = typeOf (branch.typedef);
868         if (importTypes.contains (branchEntry))
869         {
870           addTo (importList, branchEntry.name ());
871           if (type == HelperFile)
872             addTo (importList, branchEntry.name () + "Helper");
873         }
874         checkForArrays (branchEntry, importTypes, importList);
875         // <d42256>
876         checkForBounds (branchEntry, importTypes, importList);
877       }
878     }
879 
880     // If a typedef is not a sequence or an array, only holders and
881     // helpers are generated for it.  Remove references to such
882     // class names.
883     Enumeration en = importList.elements ();
884     while (en.hasMoreElements ())
885     {
886       String name = (String)en.nextElement ();
887       SymtabEntry e = (SymtabEntry)symbolTable.get (name);
888       if (e != null && e instanceof TypedefEntry)
889       {
890         TypedefEntry t = (TypedefEntry)e;
891         if (t.arrayInfo ().size () == 0 || !(t.type () instanceof SequenceEntry))
892           importList.removeElement (name);
893       }
894     }
895     return importList;
896   } // addImportLines
897 
898   /**
899    *
900    **/
checkForArrays(SymtabEntry entry, Vector importTypes, Vector importList)901   static private void checkForArrays (SymtabEntry entry, Vector importTypes, Vector importList)
902   {
903     if (entry instanceof TypedefEntry)
904     {
905       TypedefEntry t = (TypedefEntry)entry;
906       String arrays = checkForArrayBase (t, importTypes, importList);
907       checkForArrayDimensions (arrays, importTypes, importList);
908     }
909   } // checkForArrays
910 
911   /**
912    *
913    **/
checkForArrayBase(TypedefEntry t, Vector importTypes, Vector importList)914   static private String checkForArrayBase (TypedefEntry t, Vector importTypes, Vector importList)
915   {
916     String arrays = "";
917     try
918     {
919       String name = (String)t.dynamicVariable (Compile.typedefInfo);
920       int index = name.indexOf ('[');
921       if (index >= 0)
922       {
923         arrays = name.substring (index);
924         name = name.substring (0, index);
925       }
926 
927       // See if the base type should be added to the list.
928       SymtabEntry typeEntry = (SymtabEntry)symbolTable.get (name);
929       if (typeEntry != null && importTypes.contains (typeEntry))
930         addTo (importList, typeEntry.name ());
931     }
932     catch (NoSuchFieldException e)
933     {}
934     return arrays;
935   } // checkForArrayBase
936 
937   /**
938    *
939    **/
checkForArrayDimensions(String arrays, Vector importTypes, Vector importList)940   static private void checkForArrayDimensions (String arrays, Vector importTypes, Vector importList)
941   {
942     // See if any of the arrays contain a constentry.
943     // If so, see if it should be added to the list.
944     while (!arrays.equals (""))
945     {
946       int index = arrays.indexOf (']');
947       String dim = arrays.substring (1, index);
948       arrays = arrays.substring (index + 1);
949       SymtabEntry constant = (SymtabEntry)symbolTable.get (dim);
950       if (constant == null)
951       {
952         // A constant expr could be of the form <const> OR
953         // <interface>.<const>.  This if branch checks for that case.
954         int i = dim.lastIndexOf ('.');
955         if (i >= 0)
956           constant = (SymtabEntry)symbolTable.get (dim.substring (0, i));
957       }
958       if (constant != null && importTypes.contains (constant))
959         addTo (importList, constant.name ());
960     }
961   } // checkForArrayDimensions
962 
963   // <d42256> Call the following method when its necessary to determine the
964   // the import types for IDL constructs containing arbitrary positive int.
965   // expressions, which may specify non-literal constants.
966 
967   /**
968    * Determine the import lines for template types.
969    **/
checkForBounds(SymtabEntry entry, Vector importTypes, Vector importList)970   static private void checkForBounds (SymtabEntry entry, Vector importTypes, Vector importList)
971   {
972     // Obtain actual type, just to be complete.
973     SymtabEntry entryType = entry;
974     while (entryType instanceof TypedefEntry)
975       entryType = entryType.type ();
976 
977     if (entryType instanceof StringEntry && ((StringEntry)entryType).maxSize () != null)
978       checkForGlobalConstants (((StringEntry)entryType).maxSize ().rep (), importTypes, importList);
979     else
980       if (entryType instanceof SequenceEntry && ((SequenceEntry)entryType).maxSize () != null)
981         checkForGlobalConstants (((SequenceEntry)entryType).maxSize ().rep (), importTypes, importList);
982   } // checkForBounds
983 
984   /**
985    * Extract the global constants from the supplied integer expression
986    * representation (string) and add them to the supplied import list.
987    **/
checkForGlobalConstants(String exprRep, Vector importTypes, Vector importList)988   static private void checkForGlobalConstants (String exprRep, Vector importTypes, Vector importList)
989   {
990     // NOTE: Do not use '/' as a delimiter. Symbol table names use '/' as a
991     // delimiter and would not be otherwise properly collected. Blanks and
992     // arithmetic symbols do not appear in tokens, except for '/'.
993     java.util.StringTokenizer st = new java.util.StringTokenizer (exprRep, " +-*()~&|^%<>");
994     while (st.hasMoreTokens ())
995     {
996       String token = st.nextToken ();
997       // When token contains '/', it represents the division symbol or
998       // a nested type (e.g., I/x). Ignore the division symbol, and don't
999       // forget constants declared within global interfaces!
1000       if (!token.equals ("/"))
1001       {
1002         SymtabEntry typeEntry = (SymtabEntry)symbolTable.get (token);
1003         if (typeEntry instanceof ConstEntry)
1004         {
1005           int slashIdx = token.indexOf ('/');
1006           if (slashIdx < 0)  // Possible global constant
1007           {
1008             if (importTypes.contains (typeEntry))
1009               addTo (importList, typeEntry.name ());
1010           }
1011           else  // Possible constant in global interface
1012           {
1013             SymtabEntry constContainer = (SymtabEntry)symbolTable.get (token.substring (0, slashIdx));
1014             if (constContainer instanceof InterfaceEntry && importTypes.contains (constContainer))
1015               addTo (importList, constContainer.name ());
1016           }
1017         }
1018       }
1019     }
1020   } // checkForGlobalConstants
1021 
1022   /**
1023    *
1024    **/
writeInitializer(String indent, String name, String arrayDcl, SymtabEntry entry, PrintWriter stream)1025   public static void writeInitializer (String indent, String name, String arrayDcl, SymtabEntry entry, PrintWriter stream)
1026   {
1027     if (entry instanceof TypedefEntry)
1028     {
1029       TypedefEntry td = (TypedefEntry)entry;
1030       writeInitializer (indent, name, arrayDcl + sansArrayInfo (td.arrayInfo ()), td.type (), stream);
1031     }
1032     else if (entry instanceof SequenceEntry)
1033       writeInitializer (indent, name, arrayDcl + "[]", entry.type (), stream);
1034     else if (entry instanceof EnumEntry)
1035       if (arrayDcl.length () > 0)
1036         stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = null;");
1037       else
1038         stream.println (indent + javaName (entry) + ' ' + name + " = null;");
1039     else if (entry instanceof PrimitiveEntry)
1040     {
1041       boolean array = arrayDcl.length () > 0;
1042       String tname = javaPrimName (entry.name ());
1043       if (tname.equals ("boolean"))
1044         stream.println (indent + "boolean " + name + arrayDcl + " = " + (array ? "null;" : "false;"));
1045       else if (tname.equals ("org.omg.CORBA.TypeCode"))
1046         stream.println (indent + "org.omg.CORBA.TypeCode " + name + arrayDcl + " = null;");
1047       else if (tname.equals ("org.omg.CORBA.Any"))
1048         stream.println (indent + "org.omg.CORBA.Any " + name + arrayDcl + " = null;");
1049       else if (tname.equals ("org.omg.CORBA.Principal")) // <d61961>
1050         stream.println (indent + "org.omg.CORBA.Principal " + name + arrayDcl + " = null;");
1051       else
1052         stream.println (indent + tname + ' ' + name + arrayDcl + " = " + (array ? "null;" : '(' + tname + ")0;"));
1053     }
1054     // <f46082.51> Remove -stateful feature. This case is identical to next one
1055     // because javaName() supplants javaStatefulName().
1056     //else if (entry instanceof InterfaceEntry && ((InterfaceEntry)entry).state () != null)
1057     //  stream.println (indent + javaStatefulName ((InterfaceEntry)entry) + ' ' + name + arrayDcl + " = null;");
1058     else
1059       stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = null;");
1060   } // writeInitializer
1061 
1062   /**
1063    *
1064    **/
writeInitializer(String indent, String name, String arrayDcl, SymtabEntry entry, String initializer, PrintWriter stream)1065   public static void writeInitializer (String indent, String name, String arrayDcl, SymtabEntry entry, String initializer, PrintWriter stream)
1066   {
1067     if (entry instanceof TypedefEntry)
1068     {
1069       TypedefEntry td = (TypedefEntry)entry;
1070       writeInitializer (indent, name, arrayDcl + sansArrayInfo (td.arrayInfo ()), td.type (), initializer, stream);
1071     }
1072     else if (entry instanceof SequenceEntry)
1073       writeInitializer (indent, name, arrayDcl + "[]", entry.type (), initializer, stream);
1074     else if (entry instanceof EnumEntry)
1075       if (arrayDcl.length () > 0)
1076         stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = " + initializer + ';');
1077       else
1078         stream.println (indent + javaName (entry) + ' ' + name + " = " + initializer + ';');
1079     else if (entry instanceof PrimitiveEntry)
1080     {
1081       boolean array = arrayDcl.length () > 0;
1082       String tname = javaPrimName (entry.name ());
1083       if (tname.equals ("boolean"))
1084         stream.println (indent + "boolean " + name + arrayDcl + " = " + initializer + ';');
1085       else if (tname.equals ("org.omg.CORBA.TypeCode"))
1086         stream.println (indent + "org.omg.CORBA.TypeCode " + name + arrayDcl + " = " + initializer + ';');
1087       else if (tname.equals ("org.omg.CORBA.Any"))
1088         stream.println (indent + "org.omg.CORBA.Any " + name + arrayDcl + " = " + initializer + ';');
1089       else if (tname.equals ("org.omg.CORBA.Principal")) // <d61961>
1090         stream.println (indent + "org.omg.CORBA.Principal " + name + arrayDcl + " = " + initializer + ';');
1091       else
1092         stream.println (indent + tname + ' ' + name + arrayDcl + " = " + initializer + ';');
1093     }
1094     // <f46082.51> Remove -stateful feature. This case is identical to next one
1095     // because javaName() supplants javaStatefulName().
1096     //else if (entry instanceof InterfaceEntry && ((InterfaceEntry)entry).state () != null)
1097     //  stream.println (indent + javaStatefulName ((InterfaceEntry)entry) + ' ' + name + arrayDcl + " = " + initializer + ';');
1098     else
1099       stream.println (indent + javaName (entry) + ' ' + name + arrayDcl + " = " + initializer + ';');
1100   } // writeInitializer
1101 
1102   /**
1103    *
1104    **/
mkdir(String name)1105   public static void mkdir (String name)
1106   {
1107     String targetDir = ((Arguments)Compile.compiler.arguments).targetDir; // F46838.4
1108     name = (targetDir + name).replace ('/', File.separatorChar); // F46838.4
1109     File pkg = new File (name);
1110     if (!pkg.exists ())
1111       if (!pkg.mkdirs ())
1112         System.err.println (getMessage ("Util.cantCreatePkg", name));
1113   } // mkdir
1114 
1115   /**
1116    *
1117    **/
writeProlog(PrintWriter stream, String filename)1118   public static void writeProlog (PrintWriter stream, String filename)
1119   {
1120     // <d59355> Remove target directory
1121     String targetDir = ((Arguments)Compile.compiler.arguments).targetDir;
1122     if (targetDir != null)
1123       filename = filename.substring (targetDir.length ());
1124     stream.println ();
1125     stream.println ("/**");
1126     stream.println ("* " + filename.replace (File.separatorChar, '/') +
1127         " .");
1128     stream.println ("* " + Util.getMessage ("toJavaProlog1",
1129         Util.getMessage ("Version.product", Util.getMessage ("Version.number"))));
1130     // <d48911> Do not introduce invalid escape characters into comment! <daz>
1131     //stream.println ("* " + Util.getMessage ("toJavaProlog2", Compile.compiler.arguments.file));
1132     stream.println ("* " + Util.getMessage ("toJavaProlog2", Compile.compiler.arguments.file.replace (File.separatorChar, '/')));
1133 
1134     ///////////////
1135     // This SHOULD work, but there's a bug in the JDK.
1136     //    stream.println ("* " + DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.getDefault ()).format (new Date ()));
1137     // This gets around the bug:
1138 
1139     DateFormat formatter = DateFormat.getDateTimeInstance (DateFormat.FULL, DateFormat.FULL, Locale.getDefault ());
1140 
1141     // Japanese-specific workaround.  JDK bug 4069784 being repaired by JavaSoft.
1142     // Keep this transient solution until bug fix is reported.cd .
1143 
1144     if (Locale.getDefault () == Locale.JAPAN)
1145       formatter.setTimeZone (java.util.TimeZone.getTimeZone ("JST"));
1146     else
1147       formatter.setTimeZone (java.util.TimeZone.getDefault ());
1148 
1149     stream.println ("* " + formatter.format (new Date ()));
1150 
1151     // <daz>
1152     ///////////////
1153 
1154     stream.println ("*/");
1155     stream.println ();
1156   } // writeProlog
1157 
1158   // keywords ending in Holder or Helper or Package have '_' prepended.
1159   // These prepended underscores must not be part of anything sent
1160   // across the wire, so these two methods are provided to strip them
1161   // off.
1162 
1163   /**
1164    *
1165    **/
stripLeadingUnderscores(String string)1166   public static String stripLeadingUnderscores (String string)
1167   {
1168     while (string.startsWith ("_"))
1169       string = string.substring (1);
1170     return string;
1171   } // stripLeadingUnderscores
1172 
1173   /**
1174    *
1175    **/
stripLeadingUnderscoresFromID(String string)1176   public static String stripLeadingUnderscoresFromID (String string)
1177   {
1178     String stringPrefix = "";
1179     int slashIndex = string.indexOf (':');
1180     if (slashIndex >= 0)
1181       do
1182       {
1183         stringPrefix = stringPrefix + string.substring (0, slashIndex + 1);
1184         string = string.substring (slashIndex + 1);
1185         while (string.startsWith ("_"))
1186           string = string.substring (1);
1187         slashIndex = string.indexOf ('/');
1188       } while (slashIndex >= 0);
1189     return stringPrefix + string;
1190   } // stripLeadingUnderscoresFromID
1191 
1192   /**
1193    *
1194    **/
parseExpression(Expression e)1195   public static String parseExpression (Expression e)
1196   {
1197     if (e instanceof Terminal)
1198       return parseTerminal ((Terminal)e);
1199     else if (e instanceof BinaryExpr)
1200       return parseBinary ((BinaryExpr)e);
1201     else if (e instanceof UnaryExpr)
1202       return parseUnary ((UnaryExpr)e);
1203     else
1204       return "(UNKNOWN_VALUE)"; // This shouldn't happen unless someone slips
1205                                 // in another type of expression.
1206   } // parseExpression
1207 
1208   /**
1209    *
1210    **/
parseTerminal(Terminal e)1211   static String parseTerminal (Terminal e)
1212   {
1213     if (e.value () instanceof ConstEntry)
1214     {
1215       ConstEntry c = (ConstEntry)e.value ();
1216       if (c.container () instanceof InterfaceEntry)
1217         return javaQualifiedName (c.container ()) + '.' + c.name ();
1218       else
1219         return javaQualifiedName (c) + ".value";
1220     }
1221     else if (e.value () instanceof Expression)
1222       return '(' + parseExpression ((Expression)e.value ()) + ')';
1223     else if (e.value () instanceof Character)
1224     {
1225       if (((Character)e.value ()).charValue () == '\013')
1226         // e.rep is \v.  \v for vertical tab is meaningless in Java.
1227         return "'\\013'";
1228       else if (((Character)e.value ()).charValue () == '\007')
1229         // e.rep is \a.  \a for alert is meaningless in Java.
1230         return "'\\007'";
1231       else if (e.rep ().startsWith ("'\\x"))
1232         return hexToOctal (e.rep ());
1233       else if (e.rep ().equals ("'\\?'"))
1234         return "'?'";
1235       else
1236         return e.rep ();
1237     }
1238     else if (e.value () instanceof Boolean)
1239       return e.value ().toString ();
1240 
1241     // <d54640> If value is type "unsigned long long" (ull) and its magnitude
1242     // is greater than the maximal Java long (i.e., IDL long long) value, then
1243     // return its signed representation rather than its actual representation.
1244     /*
1245     // Support long long
1246     //else if (e.value () instanceof Long)
1247     else if (e.value () instanceof BigInteger &&
1248              (e.type ().indexOf ("long long") >= 0 || e.type ().equals ("unsigned long"))) // <klr>
1249     {
1250       String rep   = e.rep ();
1251       int    index = rep.indexOf (')');
1252       if (index < 0)
1253         return rep + 'L';
1254       else
1255         return rep.substring (0, index) + 'L' + rep.substring (index);
1256     }
1257     */
1258     else if (e.value () instanceof BigInteger)
1259     {
1260       // Get the correct primitive type. Since integer types (octet, short,
1261       // long, long long, unsigned short, unsigned long, unsigned long long)
1262       // could be aliased (typedef'ed) to any arbitrary levels, the code
1263       // below walks up the alias chain to get to the primitive type.
1264 
1265       // Get the symbol table entry corresponding to the 'type'.
1266       SymtabEntry typeEntry = (SymtabEntry) symbolTable.get(e.type());
1267 
1268       // Get to the primitive type.
1269       while (typeEntry.type() != null) {
1270           typeEntry = typeEntry.type();
1271       }
1272       String type = typeEntry.name();
1273 
1274       if (type.equals("unsigned long long") &&
1275           ((BigInteger)e.value ()).compareTo (Expression.llMax) > 0) // value > long long Max?
1276       {
1277         // Convert to signed value, which will always be negative.
1278         BigInteger v = (BigInteger)e.value ();
1279         v = v.subtract (Expression.twoPow64);
1280         int index = e.rep ().indexOf (')');
1281         if (index < 0)
1282           return v.toString () + 'L';
1283         else
1284           return '(' + v.toString () + 'L' + ')';
1285       }
1286       else if ( type.indexOf("long long") >= 0 || type.equals("unsigned long") )
1287       {
1288         String rep   = e.rep ();
1289         int    index = rep.indexOf (')');
1290         if (index < 0)
1291           return rep + 'L';
1292         else
1293           return rep.substring (0, index) + 'L' + rep.substring (index);
1294       }
1295       else
1296         return e.rep ();
1297     } // end <d54640>
1298     else
1299       return e.rep ();
1300   } // parseTerminal
1301 
1302   /**
1303    *
1304    **/
hexToOctal(String hex)1305   static String hexToOctal (String hex)
1306   {
1307     // The format of hex is '/xXX' where XX is one or two hex digits.
1308     // This statement pulls off XX.
1309     hex = hex.substring (3, hex.length () - 1);
1310     return "'\\" + Integer.toString (Integer.parseInt (hex, 16), 8) + "'";
1311   } // hexToOctal
1312 
1313   /**
1314    *
1315    **/
parseBinary(BinaryExpr e)1316   static String parseBinary (BinaryExpr e)
1317   {
1318     String castString = "";
1319     if (e.value () instanceof Float || e.value () instanceof Double)
1320     {
1321       castString = "(double)";
1322       if (!(e instanceof Plus || e instanceof Minus ||
1323             e instanceof Times || e instanceof Divide))
1324         System.err.println ("Operator " + e.op () + " is invalid on floating point numbers");
1325     }
1326     else if (e.value () instanceof Number)
1327     {
1328       if (e.type (). indexOf ("long long") >= 0)
1329         castString = "(long)";
1330       else
1331         castString = "(int)";
1332     }
1333     else
1334     {
1335       castString = "";
1336       System.err.println ("Unknown type in constant expression");
1337     }
1338 
1339     // <d54640> Must emit value rather than representation when type "unsigned
1340     // long long" (ull) because emitted binary arithmetic expressions containing
1341     // ull's converted to long (i.e., IDL long long) do not always compute to
1342     // the correct result.
1343 
1344     //return castString + '(' + parseExpression (e.left ()) + ' ' + e.op () + ' ' + parseExpression (e.right ()) + ')';
1345     if (e.type ().equals ("unsigned long long"))
1346     {
1347       BigInteger value = (BigInteger)e.value ();
1348       if (value.compareTo (Expression.llMax) > 0) // value > long long max?
1349         value = value.subtract (Expression.twoPow64); // Convert to Java long (signed)
1350       return castString + '(' + value.toString () + 'L' + ')';
1351     }
1352     else
1353       return castString + '(' + parseExpression (e.left ()) + ' ' + e.op () + ' ' + parseExpression (e.right ()) + ')';
1354     // <d54640> end
1355   } // parseBinary
1356 
1357   /**
1358    *
1359    **/
parseUnary(UnaryExpr e)1360   static String parseUnary (UnaryExpr e)
1361   {
1362     if (!(e.value () instanceof Number))
1363       return "(UNKNOWN_VALUE)"; // This shouldn't happen if the parser checked the expression types correctly.
1364     else if ((e.value () instanceof Float || e.value () instanceof Double) && e instanceof Not)
1365       return "(UNKNOWN_VALUE)"; // This shouldn't happen if the parser checked the expression types correctly.
1366     else
1367     {
1368       String castString = "";
1369       if (e.operand ().value () instanceof Float ||
1370           e.operand ().value () instanceof Double)
1371         castString = "(double)";
1372       // Support long long.
1373       //else
1374       //  castString = "(long)";
1375       else if (e.type (). indexOf ("long long") >= 0)
1376         castString = "(long)";
1377       else
1378         castString = "(int)";
1379 
1380       // <d54640> Must emit value rather than representation when type is
1381       // "unsigned long long" (ull) because emitted unary arithmetic expressions
1382       // containing a ull converted to long (i.e., IDL long long) do not always
1383       // compute to the correct result.
1384 
1385       //return castString + e.op () + parseExpression (e.operand ());
1386       if (e.type ().equals ("unsigned long long"))
1387       {
1388         BigInteger value = (BigInteger)e.value ();
1389         if (value.compareTo (Expression.llMax) > 0) // value > long long max?
1390           value = value.subtract (Expression.twoPow64); // Convert to Java long (signed)
1391         return castString + '(' + value.toString () + 'L' + ')';
1392       }
1393       else
1394         return castString + e.op () + parseExpression (e.operand ());
1395       // end <d54640>
1396     }
1397   } // parseUnary
1398 
1399   /**
1400    *
1401    **/
IDLEntity(SymtabEntry entry)1402   public static boolean IDLEntity (SymtabEntry entry)
1403   {
1404     boolean rc = true;
1405     if (entry instanceof PrimitiveEntry || entry instanceof StringEntry)
1406        rc = false;
1407     else if (entry instanceof TypedefEntry)
1408        rc = IDLEntity (entry.type ());
1409     return rc;
1410   } // IDLEntity
1411 
1412   // <d62023>
1413   /**
1414    * @return true if the current setting of corbaLevel is within delta of
1415    *    the range min <= corbaLevel <= max
1416    **/
corbaLevel(float min, float max)1417   public static boolean corbaLevel (float min, float max)
1418   {
1419     float level = Compile.compiler.arguments.corbaLevel;
1420     float delta = 0.001f;
1421     if ((level - min + delta >= 0.0f) && (max - level + delta >= 0.0f))
1422         return true;
1423     else
1424         return false;
1425   } // corbaLevel
1426 
1427   static Hashtable symbolTable = new Hashtable ();
1428   static Hashtable packageTranslation = new Hashtable() ;
1429 } // class Util
1430