1f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
3f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * This program and the accompanying materials are made available under
4f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * the terms of the Common Public License v1.0 which accompanies this distribution,
5f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * and is available at http://www.eclipse.org/legal/cpl-v10.html
6f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
7f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * $Id: instrCommand.java,v 1.1.1.1.2.1 2004/07/16 23:32:04 vlad_r Exp $
8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpackage com.vladium.emma.instr;
10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.IOException;
12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.ClassLoaderResolver;
14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.args.IOptsParser;
15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.asserts.$assert;
16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.Command;
17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.IAppConstants;
18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.IAppErrorCodes;
19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.emma.EMMARuntimeException;
20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------
22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/**
23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * @author Vlad Roubtsov, (C) 2003
24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpublic
26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectfinal class instrCommand extends Command
27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{
28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // public: ................................................................
29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public instrCommand (final String usageToolName, final String [] args)
31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        super (usageToolName, args);
33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        m_outMode = InstrProcessor.OutMode.OUT_MODE_COPY; // default
35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public synchronized void run ()
38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        ClassLoader loader;
40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            loader = ClassLoaderResolver.getClassLoader ();
43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (Throwable t)
45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            loader = getClass ().getClassLoader ();
47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // process 'args':
52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final IOptsParser parser = getOptParser (loader);
54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final IOptsParser.IOpts parsedopts = parser.parse (m_args);
55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // check if usage is requested before checking args parse errors etc:
57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final int usageRequestLevel = parsedopts.usageRequestLevel ();
59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (usageRequestLevel > 0)
61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        usageexit (parser, usageRequestLevel, null);
63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        return;
64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final IOptsParser.IOpt [] opts = parsedopts.getOpts ();
68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (opts == null) // this means there were args parsing errors
70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    parsedopts.error (m_out, STDOUT_WIDTH);
72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    usageexit (parser, IOptsParser.SHORT_USAGE, null);
73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    return;
74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // process parsed args:
77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                try
78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    for (int o = 0; o < opts.length; ++ o)
80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        final IOptsParser.IOpt opt = opts [o];
82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        final String on = opt.getCanonicalName ();
83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        if (! processOpt (opt))
85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        {
86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            if ("ip".equals (on))
87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            {
88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                m_instrpath = getListOptValue (opt, PATH_DELIMITERS, true);
89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            }
90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            else if ("d".equals (on))
91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            {
92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                m_outDirName = opt.getFirstValue ();
93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            }
94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            else if ("out".equals (on))
95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            {
96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                m_outFileName = opt.getFirstValue ();
97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            }
98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            else if ("merge".equals (on))
99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            {
100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                m_outDataMerge = getOptionalBooleanOptValue (opt) ? Boolean.TRUE : Boolean.FALSE;
101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            }
102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            else if ("ix".equals (on))
103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            {
104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                // note: this allows path delimiter in the pattern list as well
105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                m_ixpath = getListOptValue (opt, COMMA_DELIMITERS, true);
106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            }
107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            else if ("m".equals (on))
108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            {
109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                final String ov = opt.getFirstValue ();
110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                final InstrProcessor.OutMode outMode = InstrProcessor.OutMode.nameToMode (ov);
112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                if (outMode == null)
113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                {
114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                    usageexit (parser, IOptsParser.SHORT_USAGE,
115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                        "invalid '" + opts [o].getName () + "' option value: " + ov);
116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                    return;
117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                }
118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                m_outMode = outMode;
119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            }
120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        }
121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // user '-props' file property overrides:
124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (! processFilePropertyOverrides ()) return;
126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // process prefixed opts:
128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    processCmdPropertyOverrides (parsedopts);
130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                catch (IOException ioe)
132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    throw new EMMARuntimeException (IAppErrorCodes.ARGS_IO_FAILURE, ioe);
134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // handle cmd line-level defaults:
137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if ($assert.ENABLED) $assert.ASSERT (m_outMode != null, "m_outMode not set");
139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if ((m_outMode != InstrProcessor.OutMode.OUT_MODE_OVERWRITE) && (m_outDirName == null))
141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        usageexit (parser, IOptsParser.SHORT_USAGE,
143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            "output directory must be specified for '" + m_outMode + "' output mode");
144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        return;
145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // run the instrumentor:
150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final InstrProcessor processor = InstrProcessor.create ();
152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setAppName (IAppConstants.APP_NAME); // for log prefixing
153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setInstrPath (m_instrpath, true); // TODO: an option to set 'canonical'?
155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setInclExclFilter (m_ixpath);
156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                $assert.ASSERT (m_outMode != null, "m_outMode not set");
157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setOutMode (m_outMode);
158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setInstrOutDir (m_outDirName);
159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setMetaOutFile (m_outFileName);
160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setMetaOutMerge (m_outDataMerge);
161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.setPropertyOverrides (m_propertyOverrides);
162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                processor.run ();
164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (EMMARuntimeException yre)
167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // TODO: see below
169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            exit (true, yre.getMessage (), yre, RC_UNEXPECTED); // does not return
171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return;
172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (Throwable t)
174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // TODO: embed: OS/JVM fingerprint, build #, etc
176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // TODO: save stack trace in a file and prompt user to send it to ...
177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            exit (true, "unexpected failure: ", t, RC_UNEXPECTED); // does not return
179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return;
180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        exit (false, null, null, RC_OK);
183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // protected: .............................................................
186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected void initialize ()
189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        super.initialize ();
191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    protected String usageArgsMsg ()
194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return "[options]";
196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // package: ...............................................................
199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // private: ...............................................................
201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private String [] m_instrpath;
204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private String [] m_ixpath;
205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private String m_outDirName;
206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private String m_outFileName;
207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private Boolean m_outDataMerge;
208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private InstrProcessor.OutMode m_outMode;
209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class
211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------