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);