HPCToolkit
Args.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL$
6 // $Id$
7 //
8 // --------------------------------------------------------------------------
9 // Part of HPCToolkit (hpctoolkit.org)
10 //
11 // Information about sources of support for research and development of
12 // HPCToolkit is at 'hpctoolkit.org' and in 'README.Acknowledgments'.
13 // --------------------------------------------------------------------------
14 //
15 // Copyright ((c)) 2002-2019, Rice University
16 // All rights reserved.
17 //
18 // Redistribution and use in source and binary forms, with or without
19 // modification, are permitted provided that the following conditions are
20 // met:
21 //
22 // * Redistributions of source code must retain the above copyright
23 // notice, this list of conditions and the following disclaimer.
24 //
25 // * Redistributions in binary form must reproduce the above copyright
26 // notice, this list of conditions and the following disclaimer in the
27 // documentation and/or other materials provided with the distribution.
28 //
29 // * Neither the name of Rice University (RICE) nor the names of its
30 // contributors may be used to endorse or promote products derived from
31 // this software without specific prior written permission.
32 //
33 // This software is provided by RICE and contributors "as is" and any
34 // express or implied warranties, including, but not limited to, the
35 // implied warranties of merchantability and fitness for a particular
36 // purpose are disclaimed. In no event shall RICE or contributors be
37 // liable for any direct, indirect, incidental, special, exemplary, or
38 // consequential damages (including, but not limited to, procurement of
39 // substitute goods or services; loss of use, data, or profits; or
40 // business interruption) however caused and on any theory of liability,
41 // whether in contract, strict liability, or tort (including negligence
42 // or otherwise) arising in any way out of the use of this software, even
43 // if advised of the possibility of such damage.
44 //
45 // ******************************************************* EndRiceCopyright *
46 
47 //***************************************************************************
48 //
49 // File:
50 // Args.C
51 //
52 // Purpose:
53 // [The purpose of this file]
54 //
55 // Description:
56 // [The set of functions, macros, etc. defined in the file]
57 //
58 //***************************************************************************
59 
60 //************************* System Include Files ****************************
61 
62 #include <iostream>
63 using std::cerr;
64 using std::endl;
65 
66 #include <string>
67 using std::string;
68 
69 //*************************** User Include Files ****************************
70 
71 #include <include/hpctoolkit-config.h>
72 
73 #include "Args.hpp"
74 
76 #include <lib/support/Trace.hpp>
77 
78 //*************************** Forward Declarations **************************
79 
80 //***************************************************************************
81 
82 static const char* version_info = HPCTOOLKIT_VERSION_STRING;
83 
84 static const char* usage_summary1 =
85 "[options] [<binary>] <profile>\n";
86 
87 static const char* usage_summary2 =
88 "[options] -p [<binary>]\n";
89 
90 static const char* usage_details =
91 "Converts various types of profile output into the PROFILE format, which in\n"
92 "particular, associates source file line information from <binary> with\n"
93 "profile data from <profile>. In effect, the output is a [source-line to\n"
94 "PC-profile-data] map represented as a XML scope tree (e.g. file, procedure,\n"
95 "statement). Output is sent to stdout.\n"
96 "\n"
97 "To find source line information, access to the profiled binary is required.\n"
98 "xprof will try to find the binary from data within <profile>. If this\n"
99 "information is missing, <binary> must be explicitly specified.\n"
100 "\n"
101 "By default, xprof determines a set of metrics available for the given\n"
102 "profile data and includes all of them in the PROFILE output.\n"
103 "\n"
104 "The following <profile> formats are currently supported: \n"
105 " - DEC/Compaq/HP's DCPI 'dcpicat' (including ProfileMe) \n"
106 "\n"
107 "Listing available metrics:\n"
108 " Note: with these options, <binary> is optional and will not be read\n"
109 " -l List all derived metrics, in compact form, available from <profile>\n"
110 " and suppress generation of PROFILE output. Note that this output\n"
111 " can be used with the -M option.\n"
112 " -L List all derived metrics, in long form, available from <profile>\n"
113 " and suppress generation of PROFILE output.\n"
114 "\n"
115 "Selecting metrics:\n"
116 " -M <list>, --metrics <list>\n"
117 " Replace the default metric set with the colon-separated <list> and\n"
118 " define the metric ordering. May be passed multiple times. Duplicates\n"
119 " are allowed (though not recommended).\n"
120 " -X <list>, --exclude-metrics <list>\n"
121 " Exclude metrics in the colon-separated <list> from either the default\n"
122 " metric set or from those specified with -M. May be passed multiple\n"
123 " times.\n"
124 " -R, --raw-metrics\n"
125 " Generate 'raw' metrics, disabling computation of derived metrics. For\n"
126 " some profile data, such as DCPI's ProfileMe, the default is to output\n"
127 " derived metrics, not the underlying raw metrics.\n"
128 "\n"
129 "General options:\n"
130 " -p, --pipe Supply <profile> on stdin. E.g., it is often desirable to\n"
131 " pipe the output of 'dcpicat' into xprof.\n"
132 " -V, --version Print version information.\n"
133 " -h, --help Print this help.\n";
134 
135 
136 #define CLP CmdLineParser
137 
138 // Note: Changing the option name requires changing the name in Parse()
140  // List mode
141  { 'l', NULL, CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
142  { 'L', NULL, CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
143 
144  // Normal mode
145  { 'M', "metrics", CLP::ARG_REQ , CLP::DUPOPT_CAT, ":", NULL },
146  { 'X', "exclude-metrics", CLP::ARG_REQ , CLP::DUPOPT_CAT, ":", NULL },
147  { 'R', "raw-metrics", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
148  { 0 , "pcmap", CLP::ARG_REQ , CLP::DUPOPT_ERR, NULL, NULL }, // hidden
149 
150  // General options
151  { 'p', "pipe", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
152  { 'V', "version", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
153  { 'h', "help", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL, NULL },
154  { 0 , "debug", CLP::ARG_OPT, CLP::DUPOPT_CLOB, NULL, NULL }, // hidden
155  CmdLineParser_OptArgDesc_NULL_MACRO // SGI's compiler requires this version
156 };
157 
158 #undef CLP
159 
160 
161 //***************************************************************************
162 // Args
163 //***************************************************************************
164 
165 Args::Args()
166 {
167  Ctor();
168 }
169 
170 Args::Args(int argc, const char* const argv[])
171 {
172  Ctor();
173  Parse(argc, argv);
174 }
175 
176 void
177 Args::Ctor()
178 {
180  outputRawMetrics = false;
181 }
182 
183 
184 Args::~Args()
185 {
186 }
187 
188 
189 void
190 Args::PrintVersion(std::ostream& os) const
191 {
192  os << getCmd() << ": " << version_info << endl;
193 }
194 
195 
196 void
197 Args::PrintUsage(std::ostream& os) const
198 {
199  os << "Usage: " << endl
200  << getCmd() << " " << usage_summary1
201  << getCmd() << " " << usage_summary2 << endl
202  << usage_details << endl;
203 }
204 
205 
206 void
207 Args::PrintError(std::ostream& os, const char* msg) const
208 {
209  os << getCmd() << ": " << msg << endl
210  << "Try '" << getCmd() << " --help' for more information." << endl;
211 }
212 
213 void
214 Args::PrintError(std::ostream& os, const std::string& msg) const
215 {
216  PrintError(os, msg.c_str());
217 }
218 
219 
220 void
221 Args::Parse(int argc, const char* const argv[])
222 {
223  try {
224 
225  // -------------------------------------------------------
226  // Parse the command line
227  // -------------------------------------------------------
228  parser.parse(optArgs, argc, argv);
229 
230  // -------------------------------------------------------
231  // Sift through results, checking for semantic errors
232  // -------------------------------------------------------
233 
234  // Special options that should be checked first
235  trace = 0;
236  if (parser.isOpt("debug")) {
237  trace = 1;
238  if (parser.isOptArg("debug")) {
239  const string& arg = parser.getOptArg("debug");
240  trace = (int)CmdLineParser::toLong(arg);
241  }
242  }
243  if (parser.isOpt("help")) {
244  PrintUsage(std::cerr);
245  exit(1);
246  }
247  if (parser.isOpt("version")) {
248  PrintVersion(std::cerr);
249  exit(1);
250  }
251 
252  // Check for other options: List mode
253  if (parser.isOpt('l')) {
255  }
256  if (parser.isOpt('L')) {
258  }
259 
260  // Check for other options: normal mode
261  if (parser.isOpt("metrics")) {
262  metricList = parser.getOptArg("metrics");
263  }
264  if (parser.isOpt("exclude-metrics")) {
265  excludeMList = parser.getOptArg("exclude-metrics");
266  }
267  if (parser.isOpt("raw-metrics")) {
268  outputRawMetrics = true;
269  }
270 
271  // Sanity check: -M,-X and -R should not be used at the same time
272  if ( (!metricList.empty() || !excludeMList.empty()) && outputRawMetrics) {
273  PrintError(std::cerr, "Error: -M or -X cannot be used with -R.\n");
274  exit(1);
275  }
276 
277  // Check for other options: General
278  bool profFileFromStdin = false;
279  if (parser.isOpt('p')) {
280  profFileFromStdin = true;
281  }
282 
283  // Check for required arguments
284  string errtxt;
285  int argsleft = parser.getNumArgs();
286  if (profFileFromStdin) {
287  switch (argsleft) {
288  case 0: break; // ok
289  case 1: progFile = parser.getArg(0); break;
290  default: errtxt = "Too many arguments!";
291  }
292  } else {
293  switch (argsleft) {
294  case 1: profFile = parser.getArg(0); break;
295  case 2:
296  progFile = parser.getArg(0);
297  profFile = parser.getArg(1);
298  break;
299  default: errtxt = "Incorrect number of arguments!";
300  }
301  }
302 
303  if (!errtxt.empty()) {
304  PrintError(std::cerr, errtxt);
305  exit(1);
306  }
307 
308  }
309  catch (const CmdLineParser::ParseError& x) {
310  PrintError(std::cerr, x.what());
311  exit(1);
312  }
313  catch (const CmdLineParser::Exception& x) {
314  DIAG_EMsg(x.message());
315  exit(1);
316  }
317 }
318 
319 
320 void
321 Args::Dump(std::ostream& os) const
322 {
323  os << "Args.cmd= " << getCmd() << endl;
324  os << "Args.progFile= " << progFile << endl;
325  os << "Args.profFile= " << profFile << endl;
326  os << "::trace " << ::trace << endl;
327 }
328 
329 void
330 Args::DDump() const
331 {
332  Dump(std::cerr);
333 }
~Args()
Definition: Args.cpp:173
void PrintUsage(std::ostream &os) const
Definition: Args.cpp:197
bool isOpt(const char swShort) const
const std::string & getOptArg(const char swShort) const
void PrintVersion(std::ostream &os) const
Definition: Args.cpp:190
#define DIAG_EMsg(...)
Definition: diagnostics.h:251
virtual const std::string & what() const
Definition: Exception.hpp:126
bool isOptArg(const char swShort) const
void Dump(std::ostream &os=std::cerr) const
Definition: Args.cpp:321
static const char * version_info
Definition: Args.cpp:82
std::string excludeMList
Definition: Args.hpp:105
void Ctor()
Definition: Args.cpp:162
void parse(const OptArgDesc *optArgDescs, int argc, const char *const argv[])
CmdLineParser parser
Definition: Args.hpp:120
static const char * usage_summary1
Definition: Args.cpp:84
void Parse(int argc, const char *const argv[])
Definition: Args.cpp:221
std::string profFile
Definition: Args.hpp:110
unsigned int getNumArgs() const
unsigned int listAvailableMetrics
Definition: Args.hpp:103
static const char * usage_summary2
Definition: Args.cpp:87
virtual std::string message() const
Definition: Exception.hpp:134
std::string metricList
Definition: Args.hpp:104
exit
Definition: names.cpp:1
bool outputRawMetrics
Definition: Args.hpp:106
int trace
Definition: Trace.cpp:57
Args()
Definition: Args.cpp:150
void DDump() const
Definition: Args.cpp:330
#define CmdLineParser_OptArgDesc_NULL_MACRO
static CmdLineParser::OptArgDesc optArgs[]
Definition: Args.hpp:119
const std::string & getArg(unsigned int i) const
#define NULL
Definition: ElfHelper.cpp:85
void PrintError(std::ostream &os, const char *msg) const
Definition: Args.cpp:207
const std::string & getCmd() const
Definition: Args.hpp:102
static long toLong(const std::string &str)
std::string progFile
Definition: Args.hpp:109
static const char * usage_details
Definition: Args.cpp:90