PlasCom2  1.0
XPACC Multi-physics simluation application
ComLine.C
Go to the documentation of this file.
1 #include "ComLine.H"
9 #include "primitive_utilities.H"
10 
11 namespace ix {
12  namespace util {
13 
14  std::istream &operator>>(std::istream &In,ComLineObject &cl)
15  {
16  std::string line;
17  std::string::size_type x;
18  line = util::GetNextContent(In);
19  x = line.find("<description>");
20  if(x != std::string::npos){
21  util::GetContentUntil(In,cl._description,"</description>");
22  line = util::GetNextContent(In);
23  }
24  x = line.find("<options>");
25  if(x == std::string::npos){
26  cl._error_messages.push_back("Config file format error - options section misplaced?.");
27  return(In);
28  }
29  std::string options_content;
30  util::GetContentUntil(In,options_content,"</options>");
31  std::istringstream Istr(options_content);
32  while(std::getline(Istr,line)){
33  std::istringstream OpIn(line);
34  std::string token;
35  char opchar;
36  int optype;
37  OpIn >> opchar;
38  OpIn >> token;
39  OpIn >> optype;
40  cl.push_back(std::make_pair(opchar,token));
41  cl._type[opchar] = optype;
42  if(optype > 0){
43  std::string token;
44  OpIn >> token;
45  cl._argname[opchar] = token;
46  }
47  std::getline(Istr,line);
48  x = line.find("<help>");
49  if(x == std::string::npos){
50  cl._error_messages.push_back("Configuration input format error in option help section.");
51  return(In);
52  }
53  cl._help[opchar] = "";
54  util::GetContentUntil(Istr,cl._help[opchar],"</help>");
55  }
56  line = util::GetNextContent(In);
57  if(line.empty())
58  return(In);
59  x = line.find("<arguments>");
60  if(x == std::string::npos){
61  cl._error_messages.push_back("Configuration intput format error in argument section.");
62  return(In);
63  }
64  std::string argsection;
65  util::GetContentUntil(In,argsection,"</arguments>");
66  Istr.str(argsection);
67  while(std::getline(Istr,line)){
68  std::istringstream ArgIn(line);
69  std::string argname;
70  int argtype;
71  ArgIn >> argname >> argtype;
72  cl._arghelp[argname] = argtype;
73  std::string tag;
74  ArgIn >> tag;
75  std::string::size_type x = tag.find("<help>");
76  if(x == std::string::npos){
77  cl._error_messages.push_back("Configuration input format error in arghelp section.");
78  return(In);
79  }
80  cl._arghelp[argname] = "";
81  util::GetContentUntil(In,cl._arghelp[argname],"</help>");
82  }
83  return(In);
84  }
85 
86  std::ostream &operator<<(std::ostream &Out,const ComLineObject &cl)
87  {
88  if(!cl._description.empty())
89  Out << "<description>\n" << cl._description << "</description>\n";
90  Out << "<options>\n";
91  ComLineObject::const_iterator cli = cl.begin();
92  while(cli != cl.end()){
93  char opchar = cli->first;
94  std::map<char,int>::const_iterator ti = cl._type.find(opchar);
95  Out << cli->first << " " << cli->second << " "
96  << (ti == cl._type.end() ? 0 : ti->second);
97  if(ti != cl._type.end()){
98  std::map<char,std::string>::const_iterator ai = cl._argname.find(opchar);
99  Out << " " << (ai == cl._argname.end() ? "(unspecified)" : ai->second);
100  }
101  std::map<char,std::string>::const_iterator hi = cl._help.find(opchar);
102  Out << "\n<help>\n" << (hi == cl._help.end() ? "(unspecified)" : hi->second)
103  << "\n</help>\n";
104  cli++;
105  }
106  Out << "</options>\n";
107  if(!cl._args.empty()){
108  Out << "<arguments>\n";
109  std::vector<std::pair<std::string,int> >::const_iterator ai = cl._args.begin();
110  while(ai != cl._args.end()){
111  std::map<std::string,std::string>::const_iterator ahi = cl._arghelp.find(ai->first);
112  Out << ai->first << " " << ai->second
113  << "\n<help>\n" << (ahi == cl._arghelp.end() ? "(unspecified)" : ahi->second)
114  << "\n</help>\n";
115  ai++;
116  }
117  Out << "</arguments>\n";
118  }
119  return(Out);
120  }
121 
122 
124  {
125  Copy(incom);
126  };
127 
129  {
130  _description.erase();
131  _notes.erase();
132  _program_name.erase();
133  _line.erase();
134  _error_messages.resize(0);
135  _nonops.resize(0);
136  _options.clear();
137  _help.clear();
138  _argname.clear();
139  _type.clear();
140  _args.resize(0);
141  _arghelp.clear();
142  this->resize(0);
143 
144  _description.assign(incom._description);
145  _notes.assign(incom._notes);
146  _program_name.assign(incom._program_name);
147  _line.assign(incom._line);
148  std::vector<std::string>::iterator ici = incom._error_messages.begin();
149  while(ici != incom._error_messages.end())
150  _error_messages.push_back(*ici++);
151  ici = incom._nonops.begin();
152  while(ici != incom._nonops.end())
153  _nonops.push_back(*ici++);
154  std::map<char,std::string>::iterator icmi = incom._options.begin();
155  while(icmi != incom._options.end()){
156  _options[icmi->first] = icmi->second;
157  icmi++;
158  }
159  icmi = incom._help.begin();
160  while(icmi != incom._help.end()){
161  _help[icmi->first] = icmi->second;
162  icmi++;
163  }
164  icmi = incom._argname.begin();
165  while(icmi != incom._argname.end()){
166  _argname[icmi->first] = icmi->second;
167  icmi++;
168  }
169  std::map<char,int>::iterator icti = incom._type.begin();
170  while(icti != incom._type.end()){
171  _type[icti->first] = icti->second;
172  icti++;
173  }
174  std::vector<std::pair<std::string,int> >::iterator icai = incom._args.begin();
175  while(icai != incom._args.end())
176  _args.push_back(*icai++);
177 
178  std::map<std::string,std::string>::iterator icahi = incom._arghelp.begin();
179  while(icahi != incom._arghelp.end()){
180  _arghelp[icahi->first] = icahi->second;
181  icahi++;
182  }
183  ComLineObject::iterator cli = incom.begin();
184  while(cli != incom.end())
185  this->push_back(*cli++);
186  };
187 
189  {
190  std::ostringstream Ostr;
191  if(!_description.empty())
192  Ostr << _description << std::endl << std::endl;
193  Ostr << "Usage: " << std::endl
194  << std::endl << ShortUsage() << std::endl << std::endl;
195  std::vector<std::pair<char,std::string> >::const_iterator ti = this->begin();
196  while(ti != this->end()){
197  Ostr << "\t" << "-" << ti->first << ",--" << ti->second
198  << (_type[ti->first] > 0 ? (_type[ti->first]==1 ? " [" : " <") : "")
199  << _argname[ti->first]
200  << (_type[ti->first] > 0 ? (_type[ti->first]==1 ? "]" : ">") : "")
201  << std::endl << "\t\t" << _help[ti->first];
202  ti++;
203  if(ti != this->end())
204  Ostr << std::endl << std::endl;
205  }
206  Ostr << std::endl << std::endl;
207  std::vector<std::pair<std::string,int> >::const_iterator ai = _args.begin();
208  while(ai != _args.end()){
209  Ostr << "\t" << (ai->second ? "<" : "[") << ai->first
210  << (ai->second ? ">" : "]") << std::endl << "\t\t"
211  << _arghelp[ai->first];
212  ai++;
213  if(ai != _args.end())
214  Ostr << std::endl << std::endl;
215  }
216  if(!_notes.empty())
217  Ostr << std::endl << _notes;
218  return(Ostr.str());
219  }
220 
221  std::string ComLineObject::GetLong(const char &s)
222  {
223  std::vector<std::pair<char,std::string> >::iterator ti = this->begin();
224  while(ti != this->end()){
225  if(ti->first == s)
226  return(ti->second);
227  ti++;
228  }
229  return("");
230  }
231 
232  std::string ComLineObject::GetOpStringByType(int mintype,int maxtype)
233  {
234  std::ostringstream Ostr;
235  std::vector<std::pair<char,std::string> >::iterator oi = this->begin();
236  while(oi != this->end()){
237  if(_type[oi->first] >= mintype && _type[oi->first] <= maxtype)
238  Ostr << oi->first;
239  oi++;
240  }
241  return(Ostr.str());
242  }
243 
245  {
246  std::ostringstream Ostr;
247  std::string flagstring = GetOpStringByType(0,0);
248  Ostr << _program_name << " ";
249  if(!flagstring.empty())
250  Ostr << "[-" << flagstring << "] ";
251  std::string optionals = GetOpStringByType(1,2);
252  if(!optionals.empty()){
253  std::string::iterator oi = optionals.begin();
254  Ostr << "[";
255  while(oi != optionals.end()){
256  Ostr << "-" << *oi
257  << (_type[*oi] == 1 ? " [" : " <")
258  << _argname[*oi]
259  << (_type[*oi] == 1 ? "] " : "> ");
260  oi++;
261  }
262  Ostr << "] ";
263  }
264  std::string reqd = GetOpStringByType(3,3);
265  if(!reqd.empty()){
266  std::string::iterator oi = reqd.begin();
267  Ostr << "<";
268  while(oi != reqd.end()){
269  Ostr << "-" << *oi << " <" << _argname[*oi]
270  << "> ";
271  oi++;
272  }
273  Ostr << "> ";
274  }
275  std::vector<std::pair<std::string,int> >::iterator ai = _args.begin();
276  while(ai != _args.end()){
277  Ostr << (ai->second > 0 ? "<" : "[") << ai->first
278  << (ai->second > 0 ? "> ": "] ");
279  ai++;
280  }
281  return(Ostr.str());
282  };
283 
284  char ComLineObject::GetShort(const std::string &l)
285  {
286  std::vector<std::pair<char,std::string> >::iterator ti = this->begin();
287  while(ti != this->end()){
288  if(ti->second == l)
289  return(ti->first);
290  ti++;
291  }
292  return('\0');
293  };
294 
295  void ComLineObject::AddOption(char s,const std::string &l,int atype)
296  {
297  //this->push_back(std::make_pair<char,std::string>(s,l));
298  this->push_back(std::make_pair(s,l));
299  _options[s] = std::string("");
300  _type[s] = atype;
301  if(atype > 0)
302  _argname[s] = "arg";
303  _help[s] = std::string("");
304  }
305 
306  void ComLineObject::AddOption(char s,const std::string &l,int type,const std::string argname)
307  {
308  //this->push_back(std::make_pair<char,std::string>(s,l));
309  this->push_back(std::make_pair(s,l));
310  _options[s] = std::string("");
311  _type[s] = type;
312  _argname[s] = argname;
313  _help[s] = std::string("");
314  }
315 
316  void ComLineObject::Record(const char *args[])
317  {
318  int i = 1;
319  std::ostringstream Ostr;
320  _program_name.assign(stripdirs(args[0]));
321  while(args[i]){
322  _toks.push_back(std::string(args[i]));
323  Ostr << args[i++];
324  if(args[i])
325  Ostr << " ";
326  }
327  _line.assign(Ostr.str());
328  }
329 
331  {
332  bool end_of_ops = false;
333  int errs = 0;
334  std::vector<std::string> &args(_toks);
335  // TokenizeString(args,_line);
336  std::vector<std::string>::iterator ai = args.begin();
337  while(ai != args.end()){
338  std::string this_argument = *ai++;
339  std::string next_argument;
340  if(ai != args.end())
341  next_argument = *ai--;
342  std::string::iterator si = this_argument.begin();
343  if(*si == '-' && !end_of_ops){
344  si++;
345  if(si == this_argument.end())
346  end_of_ops = true;
347  if(*si != '-') { // then we are processing a short option
348  while(si != this_argument.end()){
349  char flag_char = *si++;
350  std::vector<std::pair<char,std::string> >::iterator oi = this->begin();
351  bool found = false;
352  while((oi != this->end()) && !found){
353  if(flag_char == oi->first){
354  found = true;
355  if(si == this_argument.end()){ // means it's not a string of flags
356  if(_type[flag_char] != 0){
357  if(!next_argument.empty() && next_argument[0] != '-'){
358  _options[flag_char] = next_argument;
359  ai++;
360  }
361  else if(_type[flag_char] > 1){ // next arg wasn't valid, err if reqd
362  errs++;
363  std::ostringstream Ostr;
364  Ostr << "Option -" << flag_char << " requires an argument.";
365  _error_messages.push_back(Ostr.str());
366  }
367  else
368  _options[flag_char] = ".true.";
369  }
370  else
371  _options[flag_char] = ".true.";
372  }
373  else{ // it's a string of flags
374  if(_type[flag_char] > 1){ // it requires an argument, can't be in a flag string
375  errs++;
376  std::ostringstream Ostr;
377  Ostr << "Option -" << flag_char << " requires an argument.";
378  _error_messages.push_back(Ostr.str());
379  }
380  else
381  _options[flag_char] = ".true.";
382  }
383  }
384  oi++;
385  }
386  if(!found){
387  errs++;
388  std::ostringstream Ostr;
389  Ostr << "Option -" << flag_char << " is unrecognized.";
390  _error_messages.push_back(Ostr.str());
391  }
392  }
393  }
394  else { // we are processing a long option
395  std::string opstring = this_argument.substr(2);
396  char flag_char = GetShort(opstring);
397  if(flag_char != '\0'){
398  if(_type[flag_char] != 0){
399  if(!next_argument.empty() && next_argument[0] != '-'){
400  _options[flag_char] = next_argument;
401  ai++;
402  }
403  else if(_type[flag_char] > 1){
404  errs++;
405  std::ostringstream Ostr;
406  Ostr << "Option --" << GetLong(flag_char)
407  << " requires an argument.";
408  _error_messages.push_back(Ostr.str());
409  }
410  else
411  _options[flag_char] = ".true.";
412  }
413  else
414  _options[flag_char] = ".true.";
415  }
416  else{
417  errs++;
418  std::ostringstream Ostr;
419  Ostr << "Option --" << opstring << " is unrecognized.";
420  _error_messages.push_back(Ostr.str());
421  }
422  }
423  }
424  else { // non option arguments
425  _nonops.push_back(this_argument);
426  }
427  if(ai != args.end())
428  ai++;
429  }
430  // After finished parsing all arguments, go back and determine
431  // whether any required input was missing.
432  //
433  // First, process the options
434  std::vector<std::pair<char,std::string> >::iterator oi = this->begin();
435  while(oi != this->end()){
436  if(GetOption(oi->first).empty() && _type[oi->first]==3){
437  errs++;
438  std::ostringstream Ostr;
439  Ostr << "Required option: -" << oi->first << ",--" << oi->second
440  << " <" << _argname[oi->first] << "> was not specified.";
441  _error_messages.push_back(Ostr.str());
442  }
443  oi++;
444  }
445  // Next, make sure there were enough nonop args
446  unsigned int nreqd_args = 0;
447  std::vector<std::pair<std::string,int> >::iterator aai = _args.begin();
448  while(aai != _args.end()){
449  if(aai->second > 0)
450  nreqd_args++;
451  aai++;
452  }
453  if(nreqd_args > _nonops.size()){
454  errs++;
455  std::ostringstream Ostr;
456  Ostr << "Missing required arguments.";
457  _error_messages.push_back(Ostr.str());
458  }
459  return(errs);
460  }
461 
462  void ComLineObject::SetRawComLine(const std::string &incl)
463  {
464  std::istringstream Istr(incl);
465  Istr >> _program_name;
466  std::string token;
467  Istr >> _line;
468  while(Istr >> token)
469  _line += (std::string(" ")+token);
470  }
471 
472 
474  {
475  std::ostringstream Ostr;
476  Ostr << _program_name << " command line errors: " << std::endl;
478  return(Ostr.str());
479  }
480 
481  void ComLineObject::WriteRC(std::ostream &Ostr) const {return;}
482  void ComLineObject::ReadRC(const std::string &RCString) {return;}
483  };
484 };
void ReadRC(const std::string &RCString)
Read a config from RC string.
Definition: ComLine.C:482
int ProcessOptions()
Processes all command line tokens.
Definition: ComLine.C:330
std::string ErrorReport()
Error reporting.
Definition: ComLine.C:473
std::string GetOption(const char &s)
Get the value of an option.
Definition: ComLine.H:291
std::string GetLong(const char &s)
Obtain the long word option from the short char version.
Definition: ComLine.C:221
std::vector< std::pair< std::string, int > > _args
application arguments;
Definition: ComLine.H:93
std::map< char, int > _type
stores the type of option
Definition: ComLine.H:91
std::vector< std::string > _error_messages
stores error messages
Definition: ComLine.H:81
void Copy(ComLineObject &incom)
Copy method.
Definition: ComLine.C:128
void DumpContents(std::ostream &Ostr, const ContainerType &c, std::string del="\)
Dump container contents.
Basic utility header.
std::map< std::string, std::string > _arghelp
help string for args
Definition: ComLine.H:95
std::string GetOpStringByType(int mintype, int maxtype)
Obtains option strings by type.
Definition: ComLine.C:232
std::string _line
unformatted command line
Definition: ComLine.H:79
std::string GetNextContent(std::istream &In)
Defines MPI-specific parallel global and program classes.
std::map< char, std::string > _argname
stores a name for arguments
Definition: ComLine.H:89
std::ostream & operator<<(std::ostream &Ostr, const util::ConfigurationObject &cob)
Stream output operator for util::ConfigurationObject.
std::istream & operator>>(std::istream &Istr, util::ConfigurationObject &cob)
Stream input operator for util::ConfigurationObject.
std::map< char, std::string > _help
stores the help string for each op
Definition: ComLine.H:87
void const size_t const size_t const size_t const double const double * x
std::string _description
application description.
Definition: ComLine.H:73
void Record(const char *args[])
Minimal recording of command line.
Definition: ComLine.C:316
void SetRawComLine(const std::string &incl)
Raw Command Line Access.
Definition: ComLine.C:462
std::string _program_name
the name of the program
Definition: ComLine.H:77
std::vector< std::string > _nonops
stores non-option arguments
Definition: ComLine.H:83
void AddOption(char s, const std::string &l, int=0)
User interface to describe simple option.
Definition: ComLine.C:295
std::vector< std::string > _toks
commandline tokens
Definition: ComLine.H:97
const std::string stripdirs(const std::string &pname)
Strip absolute path.
ComLineObject header.
std::map< char, std::string > _options
stores the value of each option
Definition: ComLine.H:85
void GetContentUntil(std::istream &In, std::string ret, const std::string &etag)
std::string LongUsage()
Generate long usage string.
Definition: ComLine.C:188
void WriteRC(std::ostream &Ostr) const
Write an RC string that can be used for config.
Definition: ComLine.C:481
Command line processing.
Definition: ComLine.H:62
std::string _notes
Notes to be displayed at the end of LongUsage().
Definition: ComLine.H:75
char GetShort(const std::string &l)
Obtain the short one char option from the long word version.
Definition: ComLine.C:284
ComLineObject()
Default constructor.
Definition: ComLine.H:102
std::string ShortUsage()
Generate short usage string.
Definition: ComLine.C:244