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 
121 std::list<std::string>
122 cmdlinet::get_comma_separated_values(const char *option) const
123 {
124  std::list<std::string> separated_values;
125  auto i = getoptnr(option);
126  if(i.has_value() && !options[*i].values.empty())
127  {
128  std::istringstream values_stream(options[*i].values.front());
129  std::string single_value;
130  while(std::getline(values_stream, single_value, ','))
131  {
132  separated_values.push_back(single_value);
133  }
134  }
135  return separated_values;
136 }
137 
139 {
140  for(std::size_t i=0; i<options.size(); i++)
141  if(options[i].optchar==option)
142  return i;
143 
144  return optionalt<std::size_t>();
145 }
146 
147 optionalt<std::size_t> cmdlinet::getoptnr(const std::string &option) const
148 {
149  for(std::size_t i=0; i<options.size(); i++)
150  if(options[i].optstring==option)
151  return i;
152 
153  return optionalt<std::size_t>();
154 }
155 
156 bool cmdlinet::parse(int argc, const char **argv, const char *optstring)
157 {
158  clear();
159 
160  while(optstring[0]!=0)
161  {
162  optiont option;
163 
165  optstring[0] != ':', "cmdlinet::parse: Invalid option string\n");
166 
167  if(optstring[0]=='(')
168  {
169  option.islong=true;
170  option.optchar=0;
171  option.isset=false;
172  option.optstring="";
173 
174  for(optstring++; optstring[0]!=')' && optstring[0]!=0; optstring++)
175  option.optstring+=optstring[0];
176 
177  if(optstring[0]==')')
178  optstring++;
179  }
180  else
181  {
182  option.islong=false;
183  option.optchar=optstring[0];
184  option.optstring="";
185  option.isset=false;
186 
187  optstring++;
188  }
189 
190  if(optstring[0]==':')
191  {
192  option.hasval=true;
193  optstring++;
194  }
195  else
196  option.hasval=false;
197 
198  options.push_back(option);
199  }
200 
201  for(int i=1; i<argc; i++)
202  {
203  if(argv[i][0]!='-')
204  args.push_back(argv[i]);
205  else
206  {
208 
209  if(argv[i][1]!=0 && argv[i][2]==0)
210  optnr=getoptnr(argv[i][1]); // single-letter option -X
211  else if(argv[i][1]=='-')
212  optnr=getoptnr(argv[i]+2); // multi-letter option with --XXX
213  else
214  {
215  // Multi-letter option -XXX, or single-letter with argument -Xval
216  // We first try single-letter.
217  optnr=getoptnr(argv[i][1]);
218 
219  if(!optnr.has_value()) // try multi-letter
220  optnr=getoptnr(argv[i]+1);
221  }
222 
223  if(!optnr.has_value())
224  {
225  unknown_arg=argv[i];
226  return true;
227  }
228 
229  options[*optnr].isset=true;
230 
231  if(options[*optnr].hasval)
232  {
233  if(argv[i][2]==0 || options[*optnr].islong)
234  {
235  i++;
236  if(i==argc)
237  return true;
238  if(argv[i][0]=='-' && argv[i][1]!=0)
239  return true;
240  options[*optnr].values.push_back(argv[i]);
241  }
242  else
243  options[*optnr].values.push_back(argv[i]+2);
244  }
245  }
246  }
247 
248  return false;
249 }
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:156
argst args
Definition: cmdline.h:44
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
std::list< std::string > get_comma_separated_values(const char *option) const
Definition: cmdline.cpp:122
virtual void clear()
Definition: cmdline.cpp:21
optionalt< std::size_t > getoptnr(char option) const
Definition: cmdline.cpp:138
std::string unknown_arg
Definition: cmdline.h:45
#define DATA_INVARIANT(CONDITION, REASON)
This condition should be used to document that assumptions that are made on goto_functions,...
Definition: invariant.h:485
std::vector< optiont > options
Definition: cmdline.h:68
std::string optstring
Definition: cmdline.h:57