claw 1.9.0
 
Loading...
Searching...
No Matches
arguments.cpp
Go to the documentation of this file.
1/*
2 CLAW - a C++ Library Absolutely Wonderful
3
4 CLAW is a free library without any particular aim but being useful to
5 anyone.
6
7 Copyright (C) 2005-2011 Julien Jorge
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
23 contact: julien.jorge@stuff-o-matic.com
24*/
31
32#include <claw/assert.hpp>
33#include <claw/claw_gettext.hpp>
35
36#include <sstream>
37
42 : m_program_name(claw_gettext("<unknow>"))
43{}
44
49claw::arguments::arguments(const std::string& prog_name)
50 : m_program_name(prog_name)
51{}
52
61claw::arguments::arguments(int& argc, char**& argv)
62{
63 parse(argc, argv);
64}
65
75claw::arguments::arguments(int& argc, char**& argv,
77
78{
79 parse(argc, argv, allowed);
80}
81
89void claw::arguments::parse(int& argc, char**& argv)
90{
92}
93
103 int& argc, char**& argv,
105{
106 parse(argc, argv, false, allowed);
107}
108
113bool claw::arguments::has_value(const std::string& arg_name) const
114{
115 return m_pairs.find(arg_name) != m_pairs.end();
116}
117
122bool claw::arguments::only_integer_values(const std::string& arg_name) const
123{
124 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
125 bool result = true;
126
127 if(itk == m_pairs.end())
128 result = false;
129 else
130 {
131 std::list<std::string>::const_iterator it;
132 for(it = itk->second.begin(); result && (it != itk->second.end()); ++it)
133 result = result && text::is_of_type<int>(*it);
134 }
135
136 return result;
137}
138
143bool claw::arguments::only_real_values(const std::string& arg_name) const
144{
145 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
146 bool result = true;
147
148 if(itk == m_pairs.end())
149 result = false;
150 else
151 {
152 std::list<std::string>::const_iterator it;
153 for(it = itk->second.begin(); result && (it != itk->second.end()); ++it)
154 result = result && text::is_of_type<double>(*it);
155 }
156
157 return result;
158}
159
163const std::string& claw::arguments::get_program_name() const
164{
165 return m_program_name;
166}
167
172bool claw::arguments::get_bool(const std::string& arg_name) const
173{
174 return m_flags.find(arg_name) != m_flags.end();
175}
176
182int claw::arguments::get_integer(const std::string& arg_name) const
183{
184 CLAW_ASSERT(has_value(arg_name),
185 "arguments::get_integer(): argument is not set.");
186
187 std::istringstream iss(m_pairs.find(arg_name)->second.back());
188 int val;
189 iss >> val;
190
191 return val;
192}
193
199double claw::arguments::get_real(const std::string& arg_name) const
200{
201 CLAW_ASSERT(has_value(arg_name),
202 "arguments::get_real(): argument is not set.");
203
204 std::istringstream iss(m_pairs.find(arg_name)->second.back());
205 double val;
206 iss >> val;
207
208 return val;
209}
210
216const std::string&
217claw::arguments::get_string(const std::string& arg_name) const
218{
219 CLAW_ASSERT(has_value(arg_name),
220 "arguments::get_string(): argument is not set.");
221
222 return m_pairs.find(arg_name)->second.back();
223}
224
229std::list<int>
230claw::arguments::get_all_of_integer(const std::string& arg_name) const
231{
232 std::list<int> result;
233 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
234
235 if(itk != m_pairs.end())
236 {
237 std::list<std::string>::const_iterator it;
238
239 for(it = itk->second.begin(); it != itk->second.end(); ++it)
240 if(text::is_of_type<int>(*it))
241 {
242 std::istringstream iss(*it);
243 int val;
244 iss >> val;
245 result.push_back(val);
246 }
247 }
248
249 return result;
250}
251
256std::list<double>
257claw::arguments::get_all_of_real(const std::string& arg_name) const
258{
259 std::list<double> result;
260 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
261
262 if(itk != m_pairs.end())
263 {
264 std::list<std::string>::const_iterator it;
265
266 for(it = itk->second.begin(); it != itk->second.end(); ++it)
267 if(text::is_of_type<double>(*it))
268 {
269 std::istringstream iss(*it);
270 double val;
271 iss >> val;
272 result.push_back(val);
273 }
274 }
275
276 return result;
277}
278
283std::list<std::string>
284claw::arguments::get_all_of_string(const std::string& arg_name) const
285{
286 std::list<std::string> result;
287 const valued_arguments_map::const_iterator itk(m_pairs.find(arg_name));
288
289 if(itk != m_pairs.end())
290 result = itk->second;
291
292 return result;
293}
294
304void claw::arguments::add_argument(const std::string& arg)
305{
306 CLAW_ASSERT(arg != "--", "arguments::add_argument(): arg can't be '--'");
307 CLAW_ASSERT(arg[0] == '-',
308 "arguments::add_argument(): arg must begin by '-'");
309
310 std::string name, value;
311 const bool has_value = split_argument(arg, name, value);
312
313 if(!has_value)
314 m_flags.insert(arg);
315 else
316 m_pairs[name].push_back(value);
317}
318
331 int& argc, char**& argv, bool always_allowed,
333{
334 bool stop = false;
335 int base = 0;
336
337 if(m_program_name.empty() && (argc != 0))
338 {
339 m_program_name = argv[0];
340 argv[0] = NULL;
341 base = 1;
342 }
343
344 for(int argi = base; (argi != argc) && !stop; ++argi)
345 {
346 std::string arg(argv[argi]);
347
348 if(!arg.empty())
349 if((arg[0] == '-') && (arg.length() > 1))
350 {
351 if(arg == "--")
352 stop = true;
353 else
354 {
355 std::string name, value;
356 const bool has_value = split_argument(arg, name, value);
357
358 if(!has_value)
359 process_boolean(argv[argi], always_allowed, allowed);
360 else if(always_allowed
361 || (allowed.find(name) != allowed.end()))
362 {
363 add_argument(arg);
364 argv[argi] = NULL;
365 }
366 }
367 }
368 }
369
370 remove_null_arguments(argc, argv);
371}
372
381bool claw::arguments::split_argument(const std::string& arg, std::string& name,
382 std::string& value) const
383{
384 CLAW_ASSERT(arg != "--", "arguments::split_argument(): arg can't be '--'");
385 CLAW_ASSERT(arg[0] == '-',
386 "arguments::split_argument(): arg must begin by '-'");
387
388 std::string::size_type pos = arg.find_first_of('=');
389 bool result(false);
390
391 if(pos == std::string::npos)
392 {
393 name = arg;
394 value.clear();
395 }
396 else
397 {
398 name = arg.substr(0, pos);
399 value = arg.substr(pos + 1, arg.length() - pos - 1);
400 result = true;
401 }
402
403 return result;
404}
405
411void claw::arguments::remove_null_arguments(int& argc, char**& argv) const
412{
413 unsigned int c = 0; // number of non-NULL arguments
414
415 for(int i = 0; i != argc; ++i)
416 if(argv[i] != NULL)
417 ++c;
418 else
419 {
420 bool ok = false;
421 int j = i;
422
423 while((j != argc) && !ok)
424 if(argv[j] == NULL)
425 ++j;
426 else
427 ok = true;
428
429 if(ok)
430 {
431 argv[i] = argv[j];
432 argv[j] = NULL;
433 ++c;
434 }
435 }
436
437 if(c > 0)
438 if((std::string(argv[c - 1]) == "--"))
439 --c;
440
441 argc = c;
442}
443
453void claw::arguments::process_boolean(
454 char*& arg, bool always_allowed,
455 const claw::math::ordered_set<std::string>& allowed)
456{
457 CLAW_ASSERT(std::string(arg) != "--", "arg can't be '--'");
458 CLAW_ASSERT(std::string(arg).length() > 1,
459 "arg must be at least two characters long");
460 CLAW_ASSERT(arg[0] == '-', "arg must begin by '-'");
461
462 if(arg[1] == '-') // long boolean
463 {
464 if(always_allowed || (allowed.find(arg) != allowed.end()))
465 {
466 add_argument(arg);
467 arg = NULL;
468 }
469 }
470 else // short boolean(s)
471 {
472 int i(1);
473 std::string s("-?"); // equivalent single character argument
474
475 while(arg[i] != '\0')
476 {
477 s[1] = arg[i];
478
479 if(always_allowed || (allowed.find(s) != allowed.end()))
480 {
481 add_argument(s);
482
483 // shift remaining arguments
484 for(int j = i; arg[j] != '\0'; ++j)
485 arg[j] = arg[j + 1];
486 }
487 else
488 ++i;
489 }
490
491 if(i == 1) // all arguments have been accepted
492 arg = NULL;
493 }
494}
A class to manage the arguments of your program.
Some assert macros to strengthen you code.
#define CLAW_ASSERT(b, s)
Print a message on std::cerr and stop the program if a condition is not true.
Definition assert.hpp:88
void add_argument(const std::string &arg)
Add an argument in our list.
void parse(int &argc, char **&argv)
Parse arguments.
Definition arguments.cpp:89
double get_real(const std::string &arg_name) const
Get the real value of an argument.
bool has_value(const std::string &arg_name) const
Tell if a value is associated to an argument.
const std::string & get_program_name() const
Get the name of the program.
arguments()
Constructor.
Definition arguments.cpp:41
bool only_integer_values(const std::string &arg_name) const
Tell if only integer values are associated to an argument.
std::list< std::string > get_all_of_string(const std::string &arg_name) const
Get all string values of an argument.
bool get_bool(const std::string &arg_name) const
Get the boolean state of an argument.
const std::string & get_string(const std::string &arg_name) const
Get the string value of an argument.
std::list< int > get_all_of_integer(const std::string &arg_name) const
Get all integer values of an argument.
std::list< double > get_all_of_real(const std::string &arg_name) const
Get all real values of an argument.
int get_integer(const std::string &arg_name) const
Get the integer value of an argument.
bool only_real_values(const std::string &arg_name) const
Tell if only real values are associated to an argument.
A class to manage sets of ordered items.
Macros to call gettext on the libclaw textdomain.
#define claw_gettext(s)
Call gettext on the default text domain used by Claw.
Generic algorithms on strings.