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/exception_utils.h>
12 #include <util/invariant.h>
13 
15 {
16 }
17 
19 {
20 }
21 
23 {
24  options.clear();
25  args.clear();
26 }
27 
28 bool cmdlinet::isset(char option) const
29 {
30  auto i=getoptnr(option);
31  if(i.has_value())
32  return options[*i].isset;
33  else
34  return false;
35 }
36 
37 bool cmdlinet::isset(const char *option) const
38 {
39  auto i=getoptnr(option);
40  if(i.has_value())
41  return options[*i].isset;
42  else
43  return false;
44 }
45 
46 std::string cmdlinet::get_value(char option) const
47 {
48  auto i=getoptnr(option);
49 
50  if(i.has_value() && !options[*i].values.empty())
51  return options[*i].values.front();
52  else
53  return "";
54 }
55 
56 void cmdlinet::set(const std::string &option, bool value)
57 {
58  auto i=getoptnr(option);
59 
60  if(i.has_value())
61  options[*i].isset = value;
62  else
63  {
65  "unknown command line option", option);
66  }
67 }
68 
69 void cmdlinet::set(const std::string &option, const std::string &value)
70 {
71  auto i=getoptnr(option);
72 
73  if(i.has_value())
74  {
75  options[*i].isset=true;
76  options[*i].values.push_back(value);
77  }
78  else
79  {
81  "unknown command line option", option);
82  }
83 }
84 
85 static std::list<std::string> immutable_empty_list;
86 
87 const std::list<std::string> &cmdlinet::get_values(char option) const
88 {
89  auto i=getoptnr(option);
90 
91  if(i.has_value())
92  return options[*i].values;
93  else
94  return immutable_empty_list;
95 }
96 
97 std::string cmdlinet::get_value(const char *option) const
98 {
99  auto i=getoptnr(option);
100 
101  if(i.has_value() && !options[*i].values.empty())
102  return options[*i].values.front();
103  else
104  return "";
105 }
106 
107 const std::list<std::string> &cmdlinet::get_values(
108  const std::string &option) const
109 {
110  auto i=getoptnr(option);
111 
112  if(i.has_value())
113  return options[*i].values;
114  else
115  return immutable_empty_list;
116 }
117 
118 std::list<std::string>
119 cmdlinet::get_comma_separated_values(const char *option) const
120 {
121  std::list<std::string> separated_values;
122  auto i = getoptnr(option);
123  if(i.has_value() && !options[*i].values.empty())
124  {
125  std::istringstream values_stream(options[*i].values.front());
126  std::string single_value;
127  while(std::getline(values_stream, single_value, ','))
128  {
129  separated_values.push_back(single_value);
130  }
131  }
132  return separated_values;
133 }
134 
136 {
137  for(std::size_t i=0; i<options.size(); i++)
138  if(options[i].optchar==option)
139  return i;
140 
141  return optionalt<std::size_t>();
142 }
143 
144 optionalt<std::size_t> cmdlinet::getoptnr(const std::string &option) const
145 {
146  for(std::size_t i=0; i<options.size(); i++)
147  if(options[i].optstring==option)
148  return i;
149 
150  return optionalt<std::size_t>();
151 }
152 
153 bool cmdlinet::parse(int argc, const char **argv, const char *optstring)
154 {
155  clear();
156 
157  while(optstring[0]!=0)
158  {
159  optiont option;
160 
162  optstring[0] != ':', "cmdlinet::parse: Invalid option string\n");
163 
164  if(optstring[0]=='(')
165  {
166  option.islong=true;
167  option.optchar=0;
168  option.isset=false;
169  option.optstring.clear();
170 
171  for(optstring++; optstring[0]!=')' && optstring[0]!=0; optstring++)
172  option.optstring+=optstring[0];
173 
174  if(optstring[0]==')')
175  optstring++;
176  }
177  else
178  {
179  option.islong=false;
180  option.optchar=optstring[0];
181  option.optstring.clear();
182  option.isset=false;
183 
184  optstring++;
185  }
186 
187  if(optstring[0]==':')
188  {
189  option.hasval=true;
190  optstring++;
191  }
192  else
193  option.hasval=false;
194 
195  options.push_back(option);
196  }
197 
198  for(int i=1; i<argc; i++)
199  {
200  if(argv[i][0]!='-')
201  args.push_back(argv[i]);
202  else
203  {
205 
206  if(argv[i][1]!=0 && argv[i][2]==0)
207  optnr=getoptnr(argv[i][1]); // single-letter option -X
208  else if(argv[i][1]=='-')
209  optnr=getoptnr(argv[i]+2); // multi-letter option with --XXX
210  else
211  {
212  // Multi-letter option -XXX, or single-letter with argument -Xval
213  // We first try single-letter.
214  optnr=getoptnr(argv[i][1]);
215 
216  if(!optnr.has_value()) // try multi-letter
217  optnr=getoptnr(argv[i]+1);
218  }
219 
220  if(!optnr.has_value())
221  {
222  unknown_arg=argv[i];
223  return true;
224  }
225 
226  options[*optnr].isset=true;
227 
228  if(options[*optnr].hasval)
229  {
230  if(argv[i][2]==0 || options[*optnr].islong)
231  {
232  i++;
233  if(i==argc)
234  return true;
235  if(argv[i][0]=='-' && argv[i][1]!=0)
236  return true;
237  options[*optnr].values.push_back(argv[i]);
238  }
239  else
240  options[*optnr].values.push_back(argv[i]+2);
241  }
242  }
243  }
244 
245  return false;
246 }
247 
249 {
250  return option_namest{*this};
251 }
252 
254  const cmdlinet *command_line,
255  std::size_t index)
256  : command_line(command_line), index(index)
257 {
259 }
260 
263 {
264  PRECONDITION(command_line != nullptr);
265  ++index;
266  goto_next_valid_index();
267  return *this;
268 }
270 {
271  PRECONDITION(command_line != nullptr);
272  auto const &options = command_line->options;
273  return index < options.size() && options[index].isset &&
274  options[index].islong;
275 }
276 
278 {
279  PRECONDITION(command_line != nullptr);
280  while(index < command_line->options.size() && !is_valid_index())
281  {
282  ++index;
283  }
284 }
285 
288 {
289  return ++option_names_iteratort(*this);
290 }
291 
293 {
294  PRECONDITION(command_line != nullptr);
295  return command_line->options.at(index).optstring;
296 }
297 
300 {
301  PRECONDITION(command_line != nullptr && command_line == other.command_line);
302  return index == other.index;
303 }
304 
307 {
308  PRECONDITION(command_line != nullptr && command_line == other.command_line);
309  return index != other.index;
310 }
311 
314 {
315 }
316 
318 {
319  return option_names_iteratort(&command_line, 0);
320 }
321 
323 {
324  return option_names_iteratort(&command_line, command_line.options.size());
325 }
cmdlinet::args
argst args
Definition: cmdline.h:85
exception_utils.h
cmdlinet::option_namest::option_names_iteratort::operator*
const std::string & operator*()
Definition: cmdline.cpp:292
cmdlinet::parse
virtual bool parse(int argc, const char **argv, const char *optstring)
Definition: cmdline.cpp:153
cmdlinet::option_namest::begin
option_names_iteratort begin()
Definition: cmdline.cpp:317
cmdlinet::option_namest
Definition: cmdline.h:45
cmdlinet::isset
virtual bool isset(char option) const
Definition: cmdline.cpp:28
cmdlinet::option_namest::option_names_iteratort::goto_next_valid_index
void goto_next_valid_index()
Definition: cmdline.cpp:277
invariant.h
cmdlinet::options
std::vector< optiont > options
Definition: cmdline.h:109
cmdlinet::option_namest::option_names_iteratort::option_names_iteratort
option_names_iteratort()=default
cmdlinet::option_namest::option_names_iteratort::index
std::size_t index
Definition: cmdline.h:69
cmdlinet::get_comma_separated_values
std::list< std::string > get_comma_separated_values(const char *option) const
Definition: cmdline.cpp:119
cmdlinet::set
virtual void set(const std::string &option, bool value=true)
Definition: cmdline.cpp:56
cmdlinet::optiont::islong
bool islong
Definition: cmdline.h:96
immutable_empty_list
static std::list< std::string > immutable_empty_list
Definition: cmdline.cpp:85
cmdlinet::option_namest::option_names_iteratort::operator!=
bool operator!=(const option_names_iteratort &other)
Definition: cmdline.cpp:306
cmdlinet::option_namest::option_namest
option_namest(const cmdlinet &command_line)
Definition: cmdline.cpp:312
cmdlinet::optiont::optstring
std::string optstring
Definition: cmdline.h:98
cmdlinet
Definition: cmdline.h:21
cmdlinet::optiont::isset
bool isset
Definition: cmdline.h:94
cmdlinet::~cmdlinet
virtual ~cmdlinet()
Definition: cmdline.cpp:18
DATA_INVARIANT
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:511
cmdlinet::option_namest::command_line
const cmdlinet & command_line
Definition: cmdline.h:77
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:464
cmdlinet::get_value
std::string get_value(char option) const
Definition: cmdline.cpp:46
cmdlinet::unknown_arg
std::string unknown_arg
Definition: cmdline.h:86
cmdlinet::option_namest::option_names_iteratort::operator++
option_names_iteratort & operator++()
Definition: cmdline.cpp:262
cmdlinet::option_namest::option_names_iteratort
Definition: cmdline.h:49
cmdlinet::option_names
option_namest option_names() const
Pseudo-object that can be used to iterate over options in this cmdlinet (should not outlive this)
Definition: cmdline.cpp:248
optionalt
nonstd::optional< T > optionalt
Definition: optional.h:35
cmdlinet::clear
virtual void clear()
Definition: cmdline.cpp:22
cmdlinet::cmdlinet
cmdlinet()
Definition: cmdline.cpp:14
cmdline.h
cmdlinet::getoptnr
optionalt< std::size_t > getoptnr(char option) const
Definition: cmdline.cpp:135
cmdlinet::optiont::optchar
char optchar
Definition: cmdline.h:97
cmdlinet::option_namest::option_names_iteratort::is_valid_index
bool is_valid_index() const
Definition: cmdline.cpp:269
cmdlinet::option_namest::option_names_iteratort::command_line
const cmdlinet * command_line
Definition: cmdline.h:68
cmdlinet::optiont
Definition: cmdline.h:93
cmdlinet::option_namest::option_names_iteratort::operator==
bool operator==(const option_names_iteratort &other)
Definition: cmdline.cpp:299
cmdlinet::option_namest::end
option_names_iteratort end()
Definition: cmdline.cpp:322
cmdlinet::optiont::hasval
bool hasval
Definition: cmdline.h:95
invalid_command_line_argument_exceptiont
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Definition: exception_utils.h:38
cmdlinet::get_values
const std::list< std::string > & get_values(const std::string &option) const
Definition: cmdline.cpp:107