ail now builds on Linux
[ail.git] / ail / arguments.cpp
blob250b6f00374fd71b3f0a7edf982c26cccfad193e
1 #include <algorithm>
2 #include <ail/arguments.hpp>
3 #include <ail/string.hpp>
4 #include <boost/foreach.hpp>
6 namespace ail
8 argument_variable::argument_variable(std::string const & name, bool & variable):
9 name(name),
10 type(argument_variable_type_bool),
11 address(&variable)
13 set_common_properties();
16 argument_variable::argument_variable(std::string const & name, std::string & variable):
17 name(name),
18 type(argument_variable_type_string),
19 address(&variable)
21 set_common_properties();
24 void argument_variable::set_common_properties()
26 default_value = 0;
27 handled = false;
28 required = false;
31 bool argument_variable::operator==(std::string const & input) const
33 return name == input;
36 argument_controller::argument_controller(argument_variable & _variable):
37 variable(_variable)
41 argument_controller & argument_controller::required()
43 variable.required = true;
44 return *this;
47 argument_controller & argument_controller::default_flag(bool value)
49 variable.default_value = new bool(value);
50 return *this;
53 argument_controller & argument_controller::default_string(std::string const & value)
55 variable.default_value = new std::string(value);
56 return *this;
59 argument_controller & argument_parser::flag(std::string const & name, bool & variable)
61 argument_variable new_variable(name, variable);
62 variables.push_back(new_variable);
63 return * new argument_controller(*(variables.end() - 1));
66 argument_controller & argument_parser::string(std::string const & name, std::string & variable)
68 argument_variable new_variable(name, variable);
69 variables.push_back(new_variable);
70 return * new argument_controller(*(variables.end() - 1));
73 void argument_parser::parse(std::string const & input)
75 string_vector tokens = tokenise(input, " ");
76 parse(tokens);
79 void argument_parser::parse(int argc, char ** argv)
81 string_vector tokens;
82 for(int i = 0; i < argc; i++)
83 tokens.push_back(argv[i]);
84 parse(tokens);
87 void argument_parser::parse(string_vector & tokens)
89 for(std::size_t i = 0, end = tokens.size(); i < end; i++)
91 std::string const & token = tokens[i];
92 if(token.empty())
93 continue;
95 if(token[0] == '-')
97 std::string name = token.substr(1);
98 variable_vector::iterator iterator = std::find(variables.begin(), variables.end(), name);
99 if(iterator == variables.end())
100 continue;
101 argument_variable & variable = *iterator;
102 i++;
103 if(i == end)
104 throw exception("Variable \"" + name + "\" is lacking an argument");
105 std::string argument = tokens[i];
106 switch(variable.type)
108 case argument_variable_type_bool:
110 bool value;
111 if(!string_to_bool(argument, value))
112 throw exception("Invalid boolean value specified for variable \"" + name + "\"");
113 *reinterpret_cast<bool *>(variable.address) = value;
114 break;
117 case argument_variable_type_string:
118 *reinterpret_cast<std::string *>(variable.address) = argument;
119 break;
121 default:
122 throw exception("Unknown variable type encountered in argument parser");
123 break;
125 variable.handled = true;
129 BOOST_FOREACH(argument_variable & variable, variables)
131 if(!variable.handled)
133 if(variable.required)
134 throw exception("Required variable \"" + variable.name + "\" has not been specified");
136 else if(variable.default_value)
138 switch(variable.type)
140 case argument_variable_type_bool:
141 variable.set_default_value<bool>();
142 break;
144 case argument_variable_type_string:
145 variable.set_default_value<std::string>();
146 break;