Whiteboard
An interface and tools for visualizing large and complex datasets
CommandLineParser.h
Go to the documentation of this file.
1 
2 #include <string>
3 #include <typeinfo>
4 #include <sstream>
5 #include <iostream>
6 
7 #include <map>
8 #include <set>
9 #include <stdlib.h>
10 
11 #include "base/StringUtil.h"
12 #include "base/FileParser.h"
13 #include "extern/logger/log.h"
14 
15 using namespace std;
16 
17 template<typename argType>
18 class commandArg
19 {
20 
21 public:
22 
24 
25 commandArg(string name, string descrip)
26  : mName(name), mDesc(descrip), mHasDefault(false), mHasValue(false) {}
27 
28 commandArg(string name,string descrip,argType T)
29  : mName(name), mDesc(descrip), mValue(T), mHasDefault(true), mHasValue(true) {}
30 
31 void SetValue(argType &T) { mValue = T; mHasValue=true; }
32 
33 void SetDefault(argType &T) { mValue = T; mHasDefault = true; }
34 void SetDescription(string d) { mDesc = d; }
35 
36 bool HasDefault() { return mHasDefault; }
37 bool HasValue() { return mHasValue; }
38 
39 argType GetValue() { return mValue; }
40 string GetName() { return mName; }
41 string GetDescription() { return mDesc; }
42 
43 friend bool operator< (const commandArg<argType> &lhs,
44  const commandArg<argType> &rhs)
45 {
46  if ( lhs.GetName() < rhs.GetName() )
47  return true;
48 
49  return false;
50 }
51 
52 string GetType()
53 {
54  string type = typeid(*this).name();
55  if ( type.find("Ib") != string::npos )
56  return "bool";
57  else if ( type.find("Ii") != string::npos )
58  return "int";
59  else if ( type.find("Id") != string::npos )
60  return "double";
61  else if ( type.find("ISs") != string::npos )
62  return "string";
63  else
64  return "unknown type";
65 }
66 
67 
68 private:
69 
70 string mName, mDesc;
71 argType mValue;
72 bool mHasDefault, mHasValue;
73 
74 };
75 
76 
78 {
79 
80 public:
81 
82 commandLineParser(int argc, char** argv, const string & description = "")
83  : mArgc(argc), mArgv(argv), mDesc(description), mNumDefaults(0),mNumArgs(0) {}
84 
85  void SetDescription(const string & s) {
86  mDesc = s;
87  }
88 
89 private:
90  int mArgc;
91  char** mArgv;
92  stringstream mHelp;
93  string mDesc;
94 
95 int mNumDefaults,mNumArgs;
96 multimap<string,string> mNameVal;
97 set<string> mArgNames, mCArgNames;
98 public:
99 
100 
101 template<typename T>
103 {
104  if ( mHelp.str().empty() )
105  mHelp << "\n";
106  mHelp << string(arg.GetName()
107  + "<"
108  + arg.GetType()
109  + "> : "
110  + arg.GetDescription() );
111  if ( arg.HasDefault() )
112  {
113  mHelp << " (def=";
114  ostringstream o;
115  o << arg.GetValue() ;
116  mHelp << o.str() << ")";
117  ++mNumDefaults;
118  }
119  mHelp << "\n" << ends;
120 
121  mArgNames.insert(arg.GetName());
122  ++mNumArgs;
123 
124 }
125 
126 template<typename T>
128 {
129  if ( mHelp.str().empty() )
130  mHelp << "\n";
131  mHelp << string(arg.GetName()
132  + "<"
133  + arg.GetType()
134  + "> : "
135  + arg.GetDescription() );
136  if ( arg.HasDefault() )
137  {
138  mHelp << " (def=";
139  ostringstream o;
140  o << arg.GetValue() ;
141  mHelp << o.str() << ")";
142  ++mNumDefaults;
143  }
144  mHelp << "\n" << ends;
145 
146  mCArgNames.insert(arg.GetName());
147  ++mNumArgs;
148 }
149 
150 
151 bool parse()
152 {
153  if ( mArgc == 1 && mNumArgs != mNumDefaults)
154  {
155  showHelp();
156  exit(0);
157  }
158 
159  if ( requestHelp() )
160  {
161  showHelp();
162  exit(0);
163  }
164 
165  if ( mArgNames.empty() )
166  {
167  showHelp();
168  exit(0);
169  }
170 
171  int i(1);
172  while ( i<mArgc )
173  {
174 // for ( int i=1; i<mArgc; ++i )
175 // {
176 
177 
178  string n(mArgv[i]);//, v(mArgv[i+1]);
179  string v("");
180  if ( i<mArgc-1)
181  v=string(mArgv[i+1]);
182 
183  bool is_compound(false);
184  set<string>::iterator sIter = mArgNames.find(n);
185  if ( sIter == mArgNames.end() )
186  {
187  sIter = mCArgNames.find(n);
188  if (sIter==mCArgNames.end())
189  {
190  if (n == "-print-command-line") {
191  cout << "----------------------- Welcome to Spines -------------------------------" << endl;
192  cout << "This module was invoked via:" << endl;
193  for (int k=0; k<mArgc; k++) {
194  cout << mArgv[k] << " ";
195  }
196  cout << endl;
197  cout << "----------------------- Welcome to Spines -------------------------------" << endl << endl;
198  if ( mArgc == 2 ) {
199  showHelp();
200  exit(0);
201  }
202  i++;
203  continue;
204  } else {
205 
206  cout << "\nInvalid command-line arg: " << n << endl;
207  showHelp();
208  exit(0);
209  }
210  }
211  else
212  {
213  is_compound=true;
214  }
215  }
216 
217  string targ("-");
218  StringParser sp; sp.SetLine(v);
219  int num_v=sp.GetItemCount();
220 
221  if (!is_compound)
222  {
223  bool is_float(false);
224  if (num_v>1) is_float = sp.IsFloat(1);
225 
226  if (ContainsAt(n,targ,0) && is_float)
227  {
228  mNameVal.insert(make_pair(n,v));
229  i+=2;
230  }
231  else if ( ContainsAt(n,targ,0) && !ContainsAt(v,targ,0) )
232  {
233  mNameVal.insert(make_pair(n,v));
234  i+=2;
235  }
236  else if ( ContainsAt(n,targ,0) && ContainsAt(v,targ,0) )
237  {
238  v="";
239  mNameVal.insert(make_pair(n,v));
240  i+=1;
241  }
242  else
243  {
244  i+=1;
245  }
246  }
247  else
248  {
249  for (int k=0; k<num_v; ++k)
250  mNameVal.insert(make_pair(n,sp.AsString(k)));
251  i+=2;
252  }
253  }
254  return true;
255 }
256 
257 template<typename T>
259 {
260  string key(keyArg.GetName());
261  map<string,string>::iterator mIter = mNameVal.find(key);
262  if ( mIter == mNameVal.end() )
263  {
264  ostringstream o;
265  o << keyArg.GetValue();
266 
267  if ( keyArg.GetType() == "string" )
268  {
269  if ( !keyArg.HasDefault() )
270  {
271  cout << "need to specify " << key << endl;
272  exit(-1);
273  }
274  return (o.str());
275  }
276  return (string(""));
277  }
278 
279  return (mIter->second);
280 
281 }
282 
283 template<typename T>
285 {
286  vector<string> dummy;
287 
288  string key(keyArg.GetName());
289  pair<multimap<string,string>::iterator,multimap<string,string>::iterator> mIter = mNameVal.equal_range(key);
290  if ( mIter.first == mIter.second)
291  {
292  ostringstream o;
293  o << keyArg.GetValue();
294 
295  if ( keyArg.GetType() == "string" )
296  {
297  if ( !keyArg.HasDefault() )
298  {
299  cout << "need to specify " << key << endl;
300  exit(-1);
301  }
302 
303  dummy.push_back(o.str());
304  return (dummy);
305  }
306  return (dummy);
307  }
308 
309  for (; mIter.first != mIter.second; ++mIter.first)
310  dummy.push_back(mIter.first->second);
311 
312  return dummy;
313 
314 }
315 
316 
318 {
319  string key(keyArg.GetName());
320  string val = GetStringValueFor(keyArg);
321 
322  if ( val.empty() )
323  {
324  if (!keyArg.HasDefault() )
325  {
326  cout << "need to specify " << key << endl;
327  exit(-1);
328  }
329  else
330  return ( keyArg.GetValue() );
331  }
332  else
333  {
334 // if ( !val.IsDouble() )
335 // {
336 // cout << "invalid: " << key <<" "<< val << endl;
337 // exit(-1);
338 // }
339 // else
340  return (atof(val.c_str()));
341 
342  }
343 }
344 
346 {
347  string key(keyArg.GetName());
348  string val = GetStringValueFor(keyArg);
349  if ( val.empty() )
350  {
351  if (!keyArg.HasDefault() )
352  {
353  cout << "need to specify " << key << endl;
354  exit(-1);
355  }
356  else
357  return ( keyArg.GetValue() );
358  }
359  else
360  {
361 // if ( !val.IsInt() )
362 // {
363 // cout << "invalid: " << key <<" "<< val << endl;
364 // exit(-1);
365 // }
366 // else
367  return (atoi(val.c_str()));
368 
369  }
370 }
371 
373 {
374  string key(keyArg.GetName());
375  map<string,string>::iterator mIter = mNameVal.find(key);
376  if ( mIter == mNameVal.end() )
377  {
378  if ( keyArg.HasDefault() )
379  {
380  return keyArg.GetValue();
381  }
382  else
383  {
384  cout << "need to specify " << key << endl;
385  exit(-1);
386  }
387  }
388  else
389  if (mIter->second == "0" || mIter->second == "false")
390  return false;
391  else
392  return true;
393  //return mIter->second == "1" || mIter->second == "true";
394 }
395 
396 
398 {
399  for ( int i=1; i<mArgc; ++i )
400  {
401  string this_arg(mArgv[i]);
402  if ( this_arg == "-h" )
403  return true;
404  }
405 
406  return false;
407 }
408 
409 void showHelp()
410 {
411  cout << endl << mArgv[0] << ": ";
412  if (mDesc != "")
413  cout << mDesc << endl << endl;
414  else
415  cout << "a module in the code base 'Spines'." << endl << endl;
416  cout << "\nAvailable arguments:" << endl;
417  cout << mHelp.str() << endl;
418 }
419 
420 
421 
422 
423 
424 
425 };
426 
bool ContainsAt(string &s, string &t, int at)
Definition: StringUtil.cc:82
bool HasValue()
Definition: CommandLineParser.h:37
bool IsFloat(int index)
Definition: FileParser.cc:71
bool GetBoolValueFor(commandArg< bool > &keyArg)
Definition: CommandLineParser.h:372
string GetName()
Definition: CommandLineParser.h:40
int mArgc
Definition: CommandLineParser.h:90
void SetValue(argType &T)
Definition: CommandLineParser.h:31
commandArg(string name, string descrip, argType T)
Definition: CommandLineParser.h:28
commandLineParser(int argc, char **argv, const string &description="")
Definition: CommandLineParser.h:82
stringstream mHelp
Definition: CommandLineParser.h:92
int GetItemCount()
Definition: FileParser.cc:45
argType GetValue()
Definition: CommandLineParser.h:39
bool mHasValue
Definition: CommandLineParser.h:72
int GetIntValueFor(commandArg< int > &keyArg)
Definition: CommandLineParser.h:345
void registerCompoundArg(commandArg< T > &arg)
Definition: CommandLineParser.h:127
void showHelp()
Definition: CommandLineParser.h:409
vector< string > GetCompoundStringValuesFor(commandArg< T > &keyArg)
Definition: CommandLineParser.h:284
multimap< string, string > mNameVal
Definition: CommandLineParser.h:96
commandArg()
Definition: CommandLineParser.h:23
void SetDescription(string d)
Definition: CommandLineParser.h:34
string GetStringValueFor(commandArg< T > &keyArg)
Definition: CommandLineParser.h:258
string mName
Definition: CommandLineParser.h:70
bool HasDefault()
Definition: CommandLineParser.h:36
bool parse()
Definition: CommandLineParser.h:151
int mNumDefaults
Definition: CommandLineParser.h:95
void registerArg(commandArg< T > &arg)
Definition: CommandLineParser.h:102
string mDesc
Definition: CommandLineParser.h:93
bool requestHelp()
Definition: CommandLineParser.h:397
set< string > mCArgNames
Definition: CommandLineParser.h:97
Definition: FileParser.h:17
void SetDefault(argType &T)
Definition: CommandLineParser.h:33
void SetLine(const string &line)
Definition: FileParser.cc:33
argType mValue
Definition: CommandLineParser.h:71
Definition: CommandLineParser.h:77
const string & AsString(int index)
Definition: FileParser.cc:87
string GetType()
Definition: CommandLineParser.h:52
string GetDescription()
Definition: CommandLineParser.h:41
double GetDoubleValueFor(commandArg< double > &keyArg)
Definition: CommandLineParser.h:317
char ** mArgv
Definition: CommandLineParser.h:91
commandArg(string name, string descrip)
Definition: CommandLineParser.h:25
Definition: CommandLineParser.h:18
void SetDescription(const string &s)
Definition: CommandLineParser.h:85