001: /*
002: * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025: /*
026: * COMPONENT_NAME: idl.parser
027: *
028: * ORIGINS: 27
029: *
030: * Licensed Materials - Property of IBM
031: * 5639-D57 (C) COPYRIGHT International Business Machines Corp. 1997, 1999
032: * RMI-IIOP v1.0
033: *
034: * @(#)Arguments.java 1.22 07/05/05
035: */
036:
037: package com.sun.tools.corba.se.idl;
038:
039: // NOTES:
040: // -F46082.51<daz> Remove -stateful option. "Stateful interfaces" obsolete.
041: // -D58319<daz> Add -version option. Note that this may occur as the last
042: // argument on the command-line.
043: // -F60858.1<daz> Add -corba [level] option. Accept IDL upto this level, and
044: // behave in a "proprietary manner" otherwise.
045: // -D62023<daz> Add -noWarn option to supress warnings.
046:
047: import java.io.DataInputStream;
048: import java.io.IOException;
049: import java.util.Hashtable;
050: import java.util.Properties;
051: import java.util.Vector;
052: import java.util.StringTokenizer;
053: import java.lang.reflect.Modifier;
054: import java.lang.reflect.Field;
055:
056: import com.sun.tools.corba.se.idl.som.cff.FileLocator;
057:
058: /**
059: * This class is responsible for parsing the command line arguments to the
060: * compiler. To add new arguments to the compiler, this class must be extended
061: * and the parseOtherArgs method overridden.
062: **/
063: public class Arguments {
064: /**
065: * Method parseOtherArgs() is called when the framework detects arguments
066: * which are unknown to it. The default implementation of this method simply
067: * throws an InvalidArgument exception. Any overriding implementation
068: * must check the arguments passed to it for validity and process the
069: * arguments appropriately. If it detects an invalid argument, it should
070: * throw an InvalidArgument exception. Arguments MUST be of the form
071: * `/<arg> [<qualifiers>]' or `-<arg> [<qualifiers>]' where <qualifiers>
072: * is optional (for example, -iC:\includes, `C:\includes' is the qualifier
073: * for the argument `i').
074: * @param args The arguments which are unknown by the framework.
075: * @param properties Environment-style properties collected from the
076: * file idl.config.
077: * @exception idl.InvalidArgument if the argument is unknown.
078: **/
079: protected void parseOtherArgs(String[] args, Properties properties)
080: throws InvalidArgument {
081: if (args.length > 0)
082: throw new InvalidArgument(args[0]);
083: } // parseOtherArgs
084:
085: protected void setDebugFlags(String args) {
086: StringTokenizer st = new StringTokenizer(args, ",");
087: while (st.hasMoreTokens()) {
088: String token = st.nextToken();
089:
090: // If there is a public boolean data member in this class
091: // named token + "DebugFlag", set it to true.
092: try {
093: Field fld = this .getClass().getField(
094: token + "DebugFlag");
095: int mod = fld.getModifiers();
096: if (Modifier.isPublic(mod) && !Modifier.isStatic(mod))
097: if (fld.getType() == boolean.class)
098: fld.setBoolean(this , true);
099: } catch (Exception exc) {
100: // ignore it
101: }
102: }
103: }
104:
105: /**
106: * Collect the command-line parameters.
107: **/
108: void parseArgs(String[] args) throws InvalidArgument {
109: Vector unknownArgs = new Vector();
110: int i = 0;
111:
112: try {
113: // Process command line parameters
114: for (i = 0; i < args.length - 1; ++i) {
115: String lcArg = args[i].toLowerCase();
116: if (lcArg.charAt(0) != '-' && lcArg.charAt(0) != '/')
117: throw new InvalidArgument(args[i]);
118: if (lcArg.charAt(0) == '-') {
119: lcArg = lcArg.substring(1);
120: }
121:
122: // Include path
123: if (lcArg.equals("i")) {
124: includePaths.addElement(args[++i]);
125: } else if (lcArg.startsWith("i")) {
126: includePaths.addElement(args[i].substring(2));
127: } else if (lcArg.equals("v") || lcArg.equals("verbose")) {
128: // Verbose mode
129: verbose = true;
130: } else if (lcArg.equals("d")) {
131: // Define symbol
132: definedSymbols.put(args[++i], "");
133: } else if (lcArg.equals("debug")) {
134: // Turn on debug flags
135: setDebugFlags(args[++i]);
136: } else if (lcArg.startsWith("d")) {
137: definedSymbols.put(args[i].substring(2), "");
138: } else if (lcArg.equals("emitall")) {
139: // Emit bindings for included sources
140: emitAll = true;
141: } else if (lcArg.equals("keep")) {
142: // Keep old files
143: keepOldFiles = true;
144: } else if (lcArg.equals("nowarn")) {
145: // <d62023> Suppress warnings
146: noWarn = true;
147: } else if (lcArg.equals("trace")) {
148: // Allow tracing.
149: Runtime.getRuntime().traceMethodCalls(true);
150: }
151: // <f46082.51> Remove -stateful feature.
152: //else if (lcArg.equals ("stateful"))
153: //{
154: // Emit stateful bindings.
155: // parseStateful = true;
156: //}
157: // CPPModule
158: else if (lcArg.equals("cppmodule")) {
159: cppModule = true;
160: } else if (lcArg.equals("version")) {
161: // Version
162: versionRequest = true;
163: } else if (lcArg.equals("corba")) {
164: // CORBA level
165: if (i + 1 >= args.length)
166: throw new InvalidArgument(args[i]);
167: String level = args[++i];
168: if (level.charAt(0) == '-')
169: throw new InvalidArgument(args[i - 1]);
170: try {
171: corbaLevel = new Float(level).floatValue();
172: } catch (NumberFormatException e) {
173: throw new InvalidArgument(args[i]);
174: }
175: } else {
176: unknownArgs.addElement(args[i]);
177: ++i;
178: while (i < (args.length - 1)
179: && args[i].charAt(0) != '-'
180: && args[i].charAt(0) != '/') {
181: unknownArgs.addElement(args[i++]);
182: }
183: --i;
184: }
185: }
186: } catch (ArrayIndexOutOfBoundsException e) {
187: // If there is any array indexing problem, it is probably
188: // because the qualifier on the last argument is missing.
189: // Report that this last argument is invalid.
190: throw new InvalidArgument(args[args.length - 1]);
191: }
192:
193: // <d57319>
194: // The last argument is the file argument or "-version", which may
195: // be specified without a file argument.
196: if (i == args.length - 1) {
197: if (args[i].toLowerCase().equals("-version"))
198: versionRequest = true;
199: else
200: file = args[i];
201: } else
202: throw new InvalidArgument();
203:
204: // Get and process the idl.config file.
205: Properties props = new Properties();
206: try {
207: DataInputStream stream = FileLocator
208: .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: String paths = props.getProperty("includes");
232: if (paths != null) {
233: String separator = System.getProperty("path.separator");
234: int end = -separator.length(); // so the first pass paths == original paths
235: do {
236: paths = paths.substring(end + separator.length());
237: end = paths.indexOf(separator);
238: if (end < 0)
239: end = paths.length();
240: includePaths.addElement(paths.substring(0, end));
241: } while (end != paths.length());
242: }
243: } // addIncludePaths
244:
245: /**
246: * The name of the IDL file.
247: **/
248: public String file = null;
249:
250: /**
251: * True if the user wishes to see processing remarks.
252: **/
253: public boolean verbose = false;
254:
255: /**
256: * If this is true, then existing files should not be overwritten
257: * by the compiler.
258: **/
259: public boolean keepOldFiles = false;
260:
261: /**
262: * If this is true, then the types in all included files are also emitted.
263: **/
264: public boolean emitAll = false;
265:
266: // <f46082.51> Remove -stateful feature.
267: ///**
268: // * If this is true, then stateful interfaces (for the Objects-by-Value
269: // * proposal) are allowed. This is not yet a standard, so it must
270: // * explicitly be called for by setting the -stateful argument to the
271: // * compiler. If -stateful does not appear on the command line, then
272: // * the IDL will be parsed according to the standards.
273: // **/
274: //public boolean parseStateful = false;
275: /**
276: * A list of strings, each of which is a path from which included files
277: * are found.
278: **/
279: public Vector includePaths = new Vector();
280:
281: /**
282: * A table of defined symbols. The key is the symbol name; the value
283: * (if any) is the replacement value for the symbol.
284: **/
285: public Hashtable definedSymbols = new Hashtable();
286:
287: /**
288: * <f46082.46.01> True if new module entries are created for each
289: * re-opened module.
290: **/
291: public boolean cppModule = false;
292:
293: /**
294: * -version option.
295: **/
296: public boolean versionRequest = false; // <D58319>
297:
298: // <f60858.1> Specify the maximal level of the CORBA spec. the parser
299: // will support.
300: //
301: // NOTE: For BOSS 3.0, specify at 2.2. Raise to greater value in future
302: // releases.
303: /**
304: * -corba [level] option, where [level] is a floating-point number indicating
305: * the maximal level of CORBA IDL the parser framework can accept.
306: **/
307: public float corbaLevel = 2.2f;
308: // <d62023>
309: /**
310: * -noWarn option. Suppress warnings when true.
311: **/
312: public boolean noWarn = false; // Issue warnings by default.
313:
314: // Currently defined debug flags. Any additions must be called xxxDebugFlag.
315: // All debug flags must be public boolean types.
316: // These are set by passing the flag -ORBDebug x,y,z in the ORB init args.
317: // Note that x,y,z must not contain spaces.
318: public boolean scannerDebugFlag = false;
319: public boolean tokenDebugFlag = false;
320:
321: } // class Arguments
|