| /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under |
| * the terms of the Common Public License v1.0 which accompanies this distribution, |
| * and is available at http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * $Id: instrCommand.java,v 1.1.1.1.2.1 2004/07/16 23:32:04 vlad_r Exp $ |
| */ |
| package com.vladium.emma.instr; |
| |
| import java.io.IOException; |
| |
| import com.vladium.util.ClassLoaderResolver; |
| import com.vladium.util.args.IOptsParser; |
| import com.vladium.util.asserts.$assert; |
| import com.vladium.emma.Command; |
| import com.vladium.emma.IAppConstants; |
| import com.vladium.emma.IAppErrorCodes; |
| import com.vladium.emma.EMMARuntimeException; |
| |
| // ---------------------------------------------------------------------------- |
| /** |
| * @author Vlad Roubtsov, (C) 2003 |
| */ |
| public |
| final class instrCommand extends Command |
| { |
| // public: ................................................................ |
| |
| public instrCommand (final String usageToolName, final String [] args) |
| { |
| super (usageToolName, args); |
| |
| m_outMode = InstrProcessor.OutMode.OUT_MODE_COPY; // default |
| } |
| |
| public synchronized void run () |
| { |
| ClassLoader loader; |
| try |
| { |
| loader = ClassLoaderResolver.getClassLoader (); |
| } |
| catch (Throwable t) |
| { |
| loader = getClass ().getClassLoader (); |
| } |
| |
| try |
| { |
| // process 'args': |
| { |
| final IOptsParser parser = getOptParser (loader); |
| final IOptsParser.IOpts parsedopts = parser.parse (m_args); |
| |
| // check if usage is requested before checking args parse errors etc: |
| { |
| final int usageRequestLevel = parsedopts.usageRequestLevel (); |
| |
| if (usageRequestLevel > 0) |
| { |
| usageexit (parser, usageRequestLevel, null); |
| return; |
| } |
| } |
| |
| final IOptsParser.IOpt [] opts = parsedopts.getOpts (); |
| |
| if (opts == null) // this means there were args parsing errors |
| { |
| parsedopts.error (m_out, STDOUT_WIDTH); |
| usageexit (parser, IOptsParser.SHORT_USAGE, null); |
| return; |
| } |
| |
| // process parsed args: |
| try |
| { |
| for (int o = 0; o < opts.length; ++ o) |
| { |
| final IOptsParser.IOpt opt = opts [o]; |
| final String on = opt.getCanonicalName (); |
| |
| if (! processOpt (opt)) |
| { |
| if ("ip".equals (on)) |
| { |
| m_instrpath = getListOptValue (opt, PATH_DELIMITERS, true); |
| } |
| else if ("d".equals (on)) |
| { |
| m_outDirName = opt.getFirstValue (); |
| } |
| else if ("out".equals (on)) |
| { |
| m_outFileName = opt.getFirstValue (); |
| } |
| else if ("merge".equals (on)) |
| { |
| m_outDataMerge = getOptionalBooleanOptValue (opt) ? Boolean.TRUE : Boolean.FALSE; |
| } |
| else if ("ix".equals (on)) |
| { |
| // note: this allows path delimiter in the pattern list as well |
| m_ixpath = getListOptValue (opt, COMMA_DELIMITERS, true); |
| } |
| else if ("m".equals (on)) |
| { |
| final String ov = opt.getFirstValue (); |
| |
| final InstrProcessor.OutMode outMode = InstrProcessor.OutMode.nameToMode (ov); |
| if (outMode == null) |
| { |
| usageexit (parser, IOptsParser.SHORT_USAGE, |
| "invalid '" + opts [o].getName () + "' option value: " + ov); |
| return; |
| } |
| m_outMode = outMode; |
| } |
| } |
| } |
| |
| // user '-props' file property overrides: |
| |
| if (! processFilePropertyOverrides ()) return; |
| |
| // process prefixed opts: |
| |
| processCmdPropertyOverrides (parsedopts); |
| } |
| catch (IOException ioe) |
| { |
| throw new EMMARuntimeException (IAppErrorCodes.ARGS_IO_FAILURE, ioe); |
| } |
| |
| // handle cmd line-level defaults: |
| { |
| if ($assert.ENABLED) $assert.ASSERT (m_outMode != null, "m_outMode not set"); |
| |
| if ((m_outMode != InstrProcessor.OutMode.OUT_MODE_OVERWRITE) && (m_outDirName == null)) |
| { |
| usageexit (parser, IOptsParser.SHORT_USAGE, |
| "output directory must be specified for '" + m_outMode + "' output mode"); |
| return; |
| } |
| } |
| } |
| |
| // run the instrumentor: |
| { |
| final InstrProcessor processor = InstrProcessor.create (); |
| processor.setAppName (IAppConstants.APP_NAME); // for log prefixing |
| |
| processor.setInstrPath (m_instrpath, true); // TODO: an option to set 'canonical'? |
| processor.setInclExclFilter (m_ixpath); |
| $assert.ASSERT (m_outMode != null, "m_outMode not set"); |
| processor.setOutMode (m_outMode); |
| processor.setInstrOutDir (m_outDirName); |
| processor.setMetaOutFile (m_outFileName); |
| processor.setMetaOutMerge (m_outDataMerge); |
| processor.setPropertyOverrides (m_propertyOverrides); |
| |
| processor.run (); |
| } |
| } |
| catch (EMMARuntimeException yre) |
| { |
| // TODO: see below |
| |
| exit (true, yre.getMessage (), yre, RC_UNEXPECTED); // does not return |
| return; |
| } |
| catch (Throwable t) |
| { |
| // TODO: embed: OS/JVM fingerprint, build #, etc |
| // TODO: save stack trace in a file and prompt user to send it to ... |
| |
| exit (true, "unexpected failure: ", t, RC_UNEXPECTED); // does not return |
| return; |
| } |
| |
| exit (false, null, null, RC_OK); |
| } |
| |
| // protected: ............................................................. |
| |
| |
| protected void initialize () |
| { |
| super.initialize (); |
| } |
| |
| protected String usageArgsMsg () |
| { |
| return "[options]"; |
| } |
| |
| // package: ............................................................... |
| |
| // private: ............................................................... |
| |
| |
| private String [] m_instrpath; |
| private String [] m_ixpath; |
| private String m_outDirName; |
| private String m_outFileName; |
| private Boolean m_outDataMerge; |
| private InstrProcessor.OutMode m_outMode; |
| |
| } // end of class |
| // ---------------------------------------------------------------------------- |