HPCToolkit
Args.cpp
Go to the documentation of this file.
1 // -*-Mode: C++;-*-
2 
3 // * BeginRiceCopyright *****************************************************
4 //
5 // $HeadURL: https://hpctoolkit.googlecode.com/svn/branches/hpctoolkit-hpcserver/src/tool/hpcserver/Args.cpp $
6 // $Id: Args.cpp 4291 2013-07-09 22:25:53Z felipet1326@gmail.com $
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 // $HeadURL: https://hpctoolkit.googlecode.com/svn/branches/hpctoolkit-hpcserver/src/tool/hpcserver/Args.cpp $
51 //
52 // Purpose:
53 // Parses the arguments from the command line
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 
75 #include <lib/analysis/Util.hpp>
76 
78 #include <lib/support/FileUtil.hpp>
79 #include <lib/support/StrUtil.hpp>
80 
81 //*************************** Forward Declarations **************************
82 
83 // Cf. DIAG_Die.
84 #define ARG_ERROR(streamArgs) \
85  { std::ostringstream WeIrDnAmE; \
86  WeIrDnAmE << streamArgs /*<< std::ends*/; \
87  printError(std::cerr, WeIrDnAmE.str()); \
88  exit(1); }
89 
90 //***************************************************************************
91 
92 static const char* version_info = "hpcserver version 0.9, protocol version 0.9. \n" HPCTOOLKIT_VERSION_STRING;
93 
94 static const char* usage_summary =
95 "[options]\n";
96 
97 static const char* usage_details = "\
98 hpcserver is an optional component that works with hpctraceviewer to enable\n\
99 visualizations of larger databases. The disk access and heavy processing\n\
100 required by hpctraceviewer are offloaded to hpctraceserver, which can run in\n\
101 parallel with MPI. The results are streamed back to a connected hpctraceviewer\n\
102 client in a way that permits the same interactivity as running hpctraceviewer\n\
103 with the data located locally.\n\
104 \n\
105 Unlike standard web servers, for example, hpcserver is designed to run only\n\
106 while in use, and not perpetually as a daemon on background process. hpcserver\n\
107 also runs with the permissions of the user that launched it and allows the\n\
108 hpctraceviewer client to specify and access any database that hpcserver can read.\
109 \n\
110 Options: General\n\
111  -V, --version Print version information.\n\
112  -h, --help Print this help.\n\
113  -c, --compression Enables or disables compression (on by default)\n\
114  Allowed values: on off \n\
115  -p, --port Sets the main communication port (default is 21590)\n\
116  Specifying 0 indicates that an open port should be \n\
117  chosen automatically.\n\
118  -x, --xmlport Sets the port on which the experiment.xml file will be\n\
119  transmitted. Specifying 0 or not including this flag\n\
120  indicates that the port will be auto-negotiated with\n\
121  the client. Specifying 1 indicates that the xml will\n\
122  be transferred on the main data port.\n\
123 \n\
124 ";
125 
126 // Possible extensions:
127 //-v [<n>], --verbose [<n>]\n
128 // Verbose: generate progress messages to stderr at\n
129 // verbosity level <n>. {1}\n
130 
131 #define CLP CmdLineParser
132 #define CLP_SEPARATOR "!!"
133 
134 static const int DEFAULT_PORT = 21590;
135 
136 
137 // Note: Changing the option name requires changing the name in Parse()
139  // General
140 /* { 'v', "verbose", CLP::ARG_OPT, CLP::DUPOPT_CLOB, NULL,
141  CLP::isOptArg_long },*/
142  { 'V', "version", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL,
143  NULL },
144  { 'h', "help", CLP::ARG_NONE, CLP::DUPOPT_CLOB, NULL,
145  NULL },
146  { 'c' , "compression", CLP::ARG_REQ, CLP::DUPOPT_CLOB, NULL,
147  CLP::isOptArg_long },
148  { 'p' , "port", CLP::ARG_REQ, CLP::DUPOPT_CLOB, NULL,
149  CLP::isOptArg_long },
150  { 'x' , "xmlport", CLP::ARG_REQ, CLP::DUPOPT_CLOB, NULL,
151  CLP::isOptArg_long },
152  CmdLineParser_OptArgDesc_NULL_MACRO // SGI's compiler requires this version
153 };
154 
155 #undef CLP
156 
157 
158 //***************************************************************************
159 // Args
160 //***************************************************************************
161 
162 Args::Args()
163 {
164  Ctor();
165 }
166 
167 
168 Args::Args(int argc, const char* const argv[])
169 {
170  Ctor();
171  parse(argc, argv);
172 }
173 
174 
175 void
176 Args::Ctor()
177 {
178  compression = true;
179  mainPort = DEFAULT_PORT;//21590
180  xmlPort = 0;
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: " << getCmd() << " " << usage_summary << endl
200  << usage_details << endl;
201 }
202 
203 
204 void
205 Args::printError(std::ostream& os, const char* msg) const
206 {
207  os << getCmd() << ": " << msg << endl
208  << "Try '" << getCmd() << " --help' for more information." << endl;
209 }
210 
211 void
212 Args::printError(std::ostream& os, const std::string& msg) const
213 {
214  printError(os, msg.c_str());
215 }
216 
217 
218 const std::string&
219 Args::getCmd() const
220 {
221  return parser.getCmd();
222 }
223 
224 
225 void
226 Args::parse(int argc, const char* const argv[])
227 {
228  try {
229  // -------------------------------------------------------
230  // Parse the command line
231  // -------------------------------------------------------
232  parser.parse(optArgs, argc, argv);
233 
234  // -------------------------------------------------------
235  // Sift through results, checking for semantic errors
236  // -------------------------------------------------------
237 
238  // Special options that should be checked first
239  if (parser.isOpt("help")) {
240  printUsage(std::cerr);
241  exit(1);
242  }
243  if (parser.isOpt("version")) {
244  printVersion(std::cerr);
245  exit(1);
246  }
247  /*if (parser.isOpt("verbose")) {
248  int verb = 1;
249  if (parser.isOptArg("verbose")) {
250  const string& arg = parser.getOptArg("verbose");
251  verb = (int)CmdLineParser::toLong(arg);
252  }
253  Diagnostics_SetDiagnosticFilterLevel(verb);
254  }*/
255 
256  // Check for other options: Communication options
257  if (parser.isOpt("compression")) {
258  const string& arg = parser.getOptArg("compression");
259  compression = CmdLineParser::parseArg_bool(arg, "--compression option");
260  }
261  if (parser.isOpt("port")) {
262  const string& arg = parser.getOptArg("port");
263  mainPort = (int) CmdLineParser::toLong(arg);
264  if (mainPort < 1024 && mainPort != 0)
265  ARG_ERROR("Ports must be greater than 1024.")
266  }
267  if (parser.isOpt("xmlport")) {
268  const string& arg = parser.getOptArg("xmlport");
269  xmlPort = (int) CmdLineParser::toLong(arg);
270  if (xmlPort < 1024 && xmlPort > 1)
271  ARG_ERROR("Ports must be greater than 1024.")
272  }
273  }
274  catch (const CmdLineParser::ParseError& x) {
275  ARG_ERROR(x.what());
276  }
277  catch (const CmdLineParser::Exception& x) {
278  DIAG_EMsg(x.message());
279  exit(1);
280  }
281 }
282 
283 
284 void
285 Args::dump(std::ostream& os) const
286 {
287  os << "Args.cmd= " << getCmd() << endl;
288 }
289 
290 
291 void
292 Args::ddump() const
293 {
294  dump(std::cerr);
295 }
296 
297 
298 //***************************************************************************
299 
300 #if 0
301 void
303 {
304  char * home = getenv(HPCTOOLKIT.c_str());
305  if (home == NULL) {
306  cerr << "Error: Please set your " << HPCTOOLKIT << " environment variable."
307  << endl;
308  exit(1);
309  }
310 
311  // chop of trailing slashes
312  int len = strlen(home);
313  if (home[len-1] == '/') home[--len] = 0;
314 
315  DIR *fp = opendir(home);
316  if (fp == NULL) {
317  cerr << "Error: " << home << " is not a directory" << endl;
318  exit(1);
319  }
320  closedir(fp);
321  hpcHome = home;
322 }
323 #endif
324 
~Args()
Definition: Args.cpp:173
bool isOpt(const char swShort) const
void printUsage(std::ostream &os) const
Definition: Args.cpp:186
const std::string & getOptArg(const char swShort) const
const std::string & getCmd() const
#define DIAG_EMsg(...)
Definition: diagnostics.h:251
void setHPCHome()
Definition: Args.cpp:476
virtual const std::string & what() const
Definition: Exception.hpp:126
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 int DEFAULT_PORT
Definition: Args.cpp:134
bool compression
Definition: Args.hpp:115
void printVersion(std::ostream &os) const
Definition: Args.cpp:179
void parse(int argc, const char *const argv[])
Definition: Args.cpp:208
int mainPort
Definition: Args.hpp:113
virtual std::string message() const
Definition: Exception.hpp:134
exit
Definition: names.cpp:1
Args()
Definition: Args.cpp:150
void ddump() const
Definition: Args.cpp:305
#define CmdLineParser_OptArgDesc_NULL_MACRO
#define ARG_ERROR(streamArgs)
Definition: Args.cpp:84
static const char * usage_details
Definition: Args.cpp:97
void printError(std::ostream &os, const char *msg) const
Definition: Args.cpp:194
static CmdLineParser::OptArgDesc optArgs[]
Definition: Args.hpp:119
#define NULL
Definition: ElfHelper.cpp:85
static const std::string HPCTOOLKIT
Definition: Args.hpp:125
static bool parseArg_bool(const std::string &value, const char *errTag)
std::string hpcHome
Definition: Args.hpp:111
const std::string & getCmd() const
Definition: Args.hpp:102
static const char * usage_summary
Definition: Args.cpp:94
void dump(std::ostream &os=std::cerr) const
Definition: Args.cpp:296
static long toLong(const std::string &str)
static const char * version_info
Definition: Args.cpp:92
int xmlPort
Definition: Args.hpp:114