cprover
cmdline.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "cmdline.h"
10 
11 #include <util/invariant.h>
12 
14 {
15 }
16 
18 {
19 }
20 
22 {
23  options.clear();
24  args.clear();
25 }
26 
27 bool cmdlinet::isset(char option) const
28 {
29  auto i=getoptnr(option);
30  if(i.has_value())
31  return options[*i].isset;
32  else
33  return false;
34 }
35 
36 bool cmdlinet::isset(const char *option) const
37 {
38  auto i=getoptnr(option);
39  if(i.has_value())
40  return options[*i].isset;
41  else
42  return false;
43 }
44 
45 std::string cmdlinet::get_value(char option) const
46 {
47  auto i=getoptnr(option);
48 
49  if(i.has_value())
50  {
51  if(options[*i].values.empty())
52  return "";
53  else
54  return options[*i].values.front();
55  }
56  else
57  return "";
58 }
59 
60 void cmdlinet::set(const std::string &option)
61 {
62  auto i=getoptnr(option);
63 
64  if(i.has_value())
65  options[*i].isset=true;
66 
67  // otherwise ignore
68 }
69 
70 void cmdlinet::set(const std::string &option, const std::string &value)
71 {
72  auto i=getoptnr(option);
73 
74  if(i.has_value())
75  {
76  options[*i].isset=true;
77  options[*i].values.push_back(value);
78  }
79 
80  // otherwise ignore
81 }
82 
83 static std::list<std::string> immutable_empty_list;
84 
85 const std::list<std::string> &cmdlinet::get_values(char option) const
86 {
87  auto i=getoptnr(option);
88 
89  if(i.has_value())
90  return options[*i].values;
91  else
92  return immutable_empty_list;
93 }
94 
95 std::string cmdlinet::get_value(const char *option) const
96 {
97  auto i=getoptnr(option);
98 
99  if(i.has_value())
100  {
101  if(options[*i].values.empty())
102  return "";
103  else
104  return options[*i].values.front();
105  }
106  else
107  return "";
108 }
109 
110 const std::list<std::string> &cmdlinet::get_values(
111  const std::string &option) const
112 {
113  auto i=getoptnr(option);
114 
115  if(i.has_value())
116  return options[*i].values;
117  else
118  return immutable_empty_list;
119 }
120 
122 {
123  for(std::size_t i=0; i<options.size(); i++)
124  if(options[i].optchar==option)
125  return i;
126 
127  return optionalt<std::size_t>();
128 }
129 
130 optionalt<std::size_t> cmdlinet::getoptnr(const std::string &option) const
131 {
132  for(std::size_t i=0; i<options.size(); i++)
133  if(options[i].optstring==option)
134  return i;
135 
136  return optionalt<std::size_t>();
137 }
138 
139 bool cmdlinet::parse(int argc, const char **argv, const char *optstring)
140 {
141  clear();
142 
143  while(optstring[0]!=0)
144  {
145  optiont option;
146 
148  optstring[0] != ':', "cmdlinet::parse: Invalid option string\n");
149 
150  if(optstring[0]=='(')
151  {
152  option.islong=true;
153  option.optchar=0;
154  option.isset=false;
155  option.optstring="";
156 
157  for(optstring++; optstring[0]!=')' && optstring[0]!=0; optstring++)
158  option.optstring+=optstring[0];
159 
160  if(optstring[0]==')')
161  optstring++;
162  }
163  else
164  {
165  option.islong=false;
166  option.optchar=optstring[0];
167  option.optstring="";
168  option.isset=false;
169 
170  optstring++;
171  }
172 
173  if(optstring[0]==':')
174  {
175  option.hasval=true;
176  optstring++;
177  }
178  else
179  option.hasval=false;
180 
181  options.push_back(option);
182  }
183 
184  for(int i=1; i<argc; i++)
185  {
186  if(argv[i][0]!='-')
187  args.push_back(argv[i]);
188  else
189  {
191 
192  if(argv[i][1]!=0 && argv[i][2]==0)
193  optnr=getoptnr(argv[i][1]); // single-letter option -X
194  else if(argv[i][1]=='-')
195  optnr=getoptnr(argv[i]+2); // multi-letter option with --XXX
196  else
197  {
198  // Multi-letter option -XXX, or single-letter with argument -Xval
199  // We first try single-letter.
200  optnr=getoptnr(argv[i][1]);
201 
202  if(!optnr.has_value()) // try multi-letter
203  optnr=getoptnr(argv[i]+1);
204  }
205 
206  if(!optnr.has_value())
207  {
208  unknown_arg=argv[i];
209  return true;
210  }
211 
212  options[*optnr].isset=true;
213 
214  if(options[*optnr].hasval)
215  {
216  if(argv[i][2]==0 || options[*optnr].islong)
217  {
218  i++;
219  if(i==argc)
220  return true;
221  if(argv[i][0]=='-' && argv[i][1]!=0)
222  return true;
223  options[*optnr].values.push_back(argv[i]);
224  }
225  else
226  options[*optnr].values.push_back(argv[i]+2);
227  }
228  }
229  }
230 
231  return false;
232 }
virtual ~cmdlinet()
Definition: cmdline.cpp:17
const std::list< std::string > & get_values(const std::string &option) const
Definition: cmdline.cpp:110
cmdlinet()
Definition: cmdline.cpp:13
std::string get_value(char option) const
Definition: cmdline.cpp:45
virtual bool parse(int argc, const char **argv, const char *optstring)
Definition: cmdline.cpp:139
argst args
Definition: cmdline.h:37
virtual bool isset(char option) const
Definition: cmdline.cpp:27
static std::list< std::string > immutable_empty_list
Definition: cmdline.cpp:83
nonstd::optional< T > optionalt
Definition: optional.h:35
virtual void set(const std::string &option)
Definition: cmdline.cpp:60
virtual void clear()
Definition: cmdline.cpp:21
optionalt< std::size_t > getoptnr(char option) const
Definition: cmdline.cpp:121
std::string unknown_arg
Definition: cmdline.h:38
#define DATA_INVARIANT(CONDITION, REASON)
Definition: invariant.h:257
std::vector< optiont > options
Definition: cmdline.h:61
std::string optstring
Definition: cmdline.h:50