View Javadoc
1   /*
2    * Copyright (c) 1999, 2007, 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.parser
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;
37  
38  // NOTES:
39  // -F46082.51<daz> Remove -stateful option. "Stateful interfaces" obsolete.
40  // -D58319<daz> Add -version option.  Note that this may occur as the last
41  //  argument on the command-line.
42  // -F60858.1<daz> Add -corba [level] option.  Accept IDL upto this level, and
43  //  behave in a "proprietary manner" otherwise.
44  // -D62023<daz> Add -noWarn option to supress warnings.
45  
46  import java.io.DataInputStream;
47  import java.io.IOException;
48  import java.util.Hashtable;
49  import java.util.Properties;
50  import java.util.Vector;
51  import java.util.StringTokenizer;
52  import java.lang.reflect.Modifier;
53  import java.lang.reflect.Field;
54  
55  import com.sun.tools.corba.se.idl.som.cff.FileLocator;
56  
57  /**
58   * This class is responsible for parsing the command line arguments to the
59   * compiler.  To add new arguments to the compiler, this class must be extended
60   * and the parseOtherArgs method overridden.
61   **/
62  public class Arguments
63  {
64    /**
65     * Method parseOtherArgs() is called when the framework detects arguments
66     * which are unknown to it.  The default implementation of this method simply
67     * throws an InvalidArgument exception.  Any overriding implementation
68     * must check the arguments passed to it for validity and process the
69     * arguments appropriately.  If it detects an invalid argument, it should
70     * throw an InvalidArgument exception.  Arguments MUST be of the form
71     * `/<arg> [<qualifiers>]' or `-<arg> [<qualifiers>]' where <qualifiers>
72     * is optional (for example, -iC:\includes, `C:\includes' is the qualifier
73     * for the argument `i').
74     * @param args The arguments which are unknown by the framework.
75     * @param properties Environment-style properties collected from the
76     * file idl.config.
77     * @exception idl.InvalidArgument if the argument is unknown.
78     **/
79    protected void parseOtherArgs (String[] args, Properties properties) throws InvalidArgument
80    {
81      if (args.length > 0)
82        throw new InvalidArgument (args[0]);
83    } // parseOtherArgs
84  
85  
86      protected void setDebugFlags( String args )
87      {
88          StringTokenizer st = new StringTokenizer( args, "," ) ;
89          while (st.hasMoreTokens()) {
90              String token = st.nextToken() ;
91  
92              // If there is a public boolean data member in this class
93              // named token + "DebugFlag", set it to true.
94              try {
95                  Field fld = this.getClass().getField( token + "DebugFlag" ) ;
96                  int mod = fld.getModifiers() ;
97                  if (Modifier.isPublic( mod ) && !Modifier.isStatic( mod ))
98                      if (fld.getType() == boolean.class)
99                          fld.setBoolean( this, true ) ;
100             } catch (Exception exc) {
101                 // ignore it
102             }
103         }
104     }
105 
106     /**
107     * Collect the command-line parameters.
108     **/
109     void parseArgs (String[] args) throws InvalidArgument {
110         Vector unknownArgs = new Vector ();
111         int    i           = 0;
112 
113         try {
114             // Process command line parameters
115             for (i = 0; i < args.length - 1; ++i) {
116                 String lcArg = args[i].toLowerCase ();
117                 if (lcArg.charAt (0) != '-' && lcArg.charAt (0) != '/')
118                     throw new InvalidArgument (args[i]);
119                 if (lcArg.charAt (0) == '-' ) {
120                     lcArg = lcArg.substring (1);
121                 }
122 
123                 // Include path
124                 if (lcArg.equals ("i")) {
125                     includePaths.addElement (args[++i]);
126                 } else if (lcArg.startsWith ("i")) {
127                     includePaths.addElement (args[i].substring (2));
128                 } else if (lcArg.equals ("v") || lcArg.equals ("verbose")) {
129                     // Verbose mode
130                     verbose = true;
131                 } else if (lcArg.equals ("d")) {
132                     // Define symbol
133                     definedSymbols.put (args[++i], "");
134                 } else if (lcArg.equals( "debug" )) {
135                     // Turn on debug flags
136                     setDebugFlags( args[++i] ) ;
137                 } else if (lcArg.startsWith ("d")) {
138                     definedSymbols.put (args[i].substring (2), "");
139                 } else if (lcArg.equals ("emitall")) {
140                     // Emit bindings for included sources
141                     emitAll = true;
142                 } else if (lcArg.equals ("keep")) {
143                     // Keep old files
144                     keepOldFiles = true;
145                 } else if (lcArg.equals ("nowarn")) {
146                     // <d62023> Suppress warnings
147                     noWarn = true;
148                 } else if (lcArg.equals ("trace")) {
149                     // Allow tracing.
150                     Runtime.getRuntime ().traceMethodCalls (true);
151                 }
152                 // <f46082.51> Remove -stateful feature.
153                 //else if (lcArg.equals ("stateful"))
154                 //{
155                 //  Emit stateful bindings.
156                 //  parseStateful = true;
157                 //}
158                 // CPPModule
159                 else if ( lcArg.equals ("cppmodule")) {
160                     cppModule = true;
161                 } else if (lcArg.equals ("version"))  {
162                     // Version
163                     versionRequest = true;
164                 } else if (lcArg.equals ("corba"))  {
165                     // CORBA level
166                     if (i + 1 >= args.length)
167                         throw new InvalidArgument (args[i]);
168                     String level = args[++i];
169                     if (level.charAt (0) == '-')
170                         throw new InvalidArgument (args[i - 1]);
171                     try {
172                         corbaLevel = new Float (level).floatValue ();
173                     } catch (NumberFormatException e) {
174                         throw new InvalidArgument (args[i]);
175                     }
176                 } else {
177                     unknownArgs.addElement (args[i]);
178                     ++i;
179                     while (i < (args.length - 1) &&
180                         args[i].charAt (0) != '-' &&
181                         args[i].charAt (0) != '/') {
182                         unknownArgs.addElement (args[i++]);
183                     }
184                     --i;
185                 }
186             }
187         } catch (ArrayIndexOutOfBoundsException e) {
188             // If there is any array indexing problem, it is probably
189             // because the qualifier on the last argument is missing.
190             // Report that this last argument is invalid.
191             throw new InvalidArgument (args[args.length - 1]);
192         }
193 
194         // <d57319>
195         // The last argument is the file argument or "-version", which may
196         // be specified without a file argument.
197         if (i == args.length - 1) {
198             if (args[i].toLowerCase ().equals ("-version"))
199                 versionRequest = true;
200             else
201                 file = args[i];
202         } else
203             throw new InvalidArgument ();
204 
205         // Get and process the idl.config file.
206         Properties props = new Properties ();
207         try {
208           DataInputStream stream = FileLocator.locateFileInClassPath ("idl.config");
209           props.load (stream);
210           addIncludePaths (props);
211         } catch (IOException e) {
212         }
213 
214         // Call parseOtherArgs.  By default, if there are unknown args,
215         // InvalidArgument is called.  A call to parseOtherArgs is useful
216         // only when this framework has been extended.
217         String[] otherArgs;
218         if (unknownArgs.size () > 0) {
219             otherArgs = new String[unknownArgs.size ()];
220             unknownArgs.copyInto (otherArgs);
221         } else
222             otherArgs = new String[0];
223 
224         parseOtherArgs (otherArgs, props);
225     } // parseArgs
226 
227   /**
228    *
229    **/
230   private void addIncludePaths (Properties props)
231   {
232     String paths = props.getProperty ("includes");
233     if (paths != null)
234     {
235       String separator = System.getProperty ("path.separator");
236       int end = -separator.length (); // so the first pass paths == original paths
237       do
238       {
239         paths = paths.substring (end + separator.length ());
240         end = paths.indexOf (separator);
241         if (end < 0)
242           end = paths.length ();
243         includePaths.addElement (paths.substring (0, end));
244       }
245       while (end != paths.length ());
246     }
247   } // addIncludePaths
248 
249   /**
250    * The name of the IDL file.
251    **/
252   public String file = null;
253 
254   /**
255    * True if the user wishes to see processing remarks.
256    **/
257   public boolean verbose = false;
258 
259   /**
260    * If this is true, then existing files should not be overwritten
261    * by the compiler.
262    **/
263   public boolean keepOldFiles = false;
264 
265   /**
266    * If this is true, then the types in all included files are also emitted.
267    **/
268   public boolean emitAll = false;
269 
270   // <f46082.51> Remove -stateful feature.
271   ///**
272   // * If this is true, then stateful interfaces (for the Objects-by-Value
273   // * proposal) are allowed.  This is not yet a standard, so it must
274   // * explicitly be called for by setting the -stateful argument to the
275   // * compiler.  If -stateful does not appear on the command line, then
276   // * the IDL will be parsed according to the standards.
277   // **/
278   //public boolean   parseStateful  = false;
279   /**
280    * A list of strings, each of which is a path from which included files
281    * are found.
282    **/
283   public Vector includePaths = new Vector ();
284 
285   /**
286    * A table of defined symbols.  The key is the symbol name; the value
287    * (if any) is the replacement value for the symbol.
288    **/
289   public Hashtable definedSymbols = new Hashtable ();
290 
291   /**
292    * <f46082.46.01> True if new module entries are created for each
293    * re-opened module.
294    **/
295   public boolean cppModule = false;
296 
297   /**
298    * -version option.
299    **/
300   public boolean versionRequest = false;  // <D58319>
301 
302   // <f60858.1> Specify the maximal level of the CORBA spec. the parser
303   // will support.
304   //
305   // NOTE: For BOSS 3.0, specify at 2.2.  Raise to greater value in future
306   //       releases.
307   /**
308    * -corba [level] option, where [level] is a floating-point number indicating
309    * the maximal level of CORBA IDL the parser framework can accept.
310    **/
311   public float corbaLevel = 2.2f;
312   // <d62023>
313   /**
314    * -noWarn option.  Suppress warnings when true.
315    **/
316   public boolean noWarn = false;  // Issue warnings by default.
317 
318     // Currently defined debug flags.  Any additions must be called xxxDebugFlag.
319     // All debug flags must be public boolean types.
320     // These are set by passing the flag -ORBDebug x,y,z in the ORB init args.
321     // Note that x,y,z must not contain spaces.
322     public boolean scannerDebugFlag = false ;
323     public boolean tokenDebugFlag = false ;
324 
325 } // class Arguments