3 This file is part of libmspcore
4 Copyright © 2006-2009, 2011 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
16 for(list<OptBase *>::iterator i=opts.begin(); i!=opts.end(); ++i)
20 GetOpt::OptBase &GetOpt::get_option(char s)
22 for(list<OptBase *>::iterator i=opts.begin(); i!=opts.end(); ++i)
23 if((*i)->get_short()==s)
25 throw UsageError(string("Unknown option -")+s);
28 GetOpt::OptBase &GetOpt::get_option(const string &l)
30 for(list<OptBase *>::iterator i=opts.begin(); i!=opts.end(); ++i)
31 if((*i)->get_long()==l)
33 throw UsageError(string("Unknown option --")+l);
36 void GetOpt::operator()(unsigned argc, const char *const *argv)
48 i += process_long(argv+i);
51 i += process_short(argv+i);
54 args.push_back(argv[i++]);
58 args.push_back(argv[i]);
61 unsigned GetOpt::process_long(const char *const *argp)
64 const char *arg = argp[0]+2;
66 // See if the argument contains an =
68 for(; arg[equals] && arg[equals]!='='; ++equals) ;
70 OptBase &opt = get_option(string(arg, equals));
73 // Process the part after the = as option argument
74 opt.process(arg+equals+1);
75 else if(opt.get_arg_type()==REQUIRED_ARG)
78 throw UsageError("Premature end of arguments");
80 // Process the next argument as option argument
90 unsigned GetOpt::process_short(const char *const *argp)
93 const char *arg = argp[0]+1;
95 // Loop through all characters in the argument
98 OptBase &opt = get_option(*arg);
100 if(arg[1] && opt.get_arg_type()!=NO_ARG)
102 // Need an option argument and we have characters left - use them
106 else if(opt.get_arg_type()==REQUIRED_ARG)
109 throw UsageError("Premature end of arguments");
111 // Use the next argument as option argument
112 opt.process(argp[1]);
122 string GetOpt::generate_usage(const string &argv0) const
127 for(list<OptBase *>::const_iterator i=opts.begin(); i!=opts.end(); ++i)
130 if((*i)->get_short())
132 line<<'-'<<(*i)->get_short();
133 if(!(*i)->get_long().empty())
135 else if((*i)->get_arg_type()==OPTIONAL_ARG)
136 line<<'['<<(*i)->get_metavar()<<']';
137 else if((*i)->get_arg_type()==REQUIRED_ARG)
138 line<<' '<<(*i)->get_metavar();
140 if(!(*i)->get_long().empty())
142 line<<"--"<<(*i)->get_long();
144 if((*i)->get_arg_type()==OPTIONAL_ARG)
145 line<<"[="<<(*i)->get_metavar()<<']';
146 else if((*i)->get_arg_type()==REQUIRED_ARG)
147 line<<'='<<(*i)->get_metavar();
155 string GetOpt::generate_help() const
157 bool any_short = false;
158 for(list<OptBase *>::const_iterator i=opts.begin(); (!any_short && i!=opts.end()); ++i)
159 any_short = (*i)->get_short();
161 string::size_type maxw = 0;
162 list<string> switches;
163 for(list<OptBase *>::const_iterator i=opts.begin(); i!=opts.end(); ++i)
166 if((*i)->get_short())
168 swtch<<'-'<<(*i)->get_short();
169 if(!(*i)->get_long().empty())
171 else if((*i)->get_arg_type()==OPTIONAL_ARG)
172 swtch<<'['<<(*i)->get_metavar()<<']';
173 else if((*i)->get_arg_type()==REQUIRED_ARG)
174 swtch<<' '<<(*i)->get_metavar();
178 if(!(*i)->get_long().empty())
180 swtch<<"--"<<(*i)->get_long();
182 if((*i)->get_arg_type()==OPTIONAL_ARG)
183 swtch<<"[="<<(*i)->get_metavar()<<']';
184 else if((*i)->get_arg_type()==REQUIRED_ARG)
185 swtch<<'='<<(*i)->get_metavar();
187 switches.push_back(swtch.str());
188 maxw = max(maxw, switches.back().size());
192 list<string>::const_iterator j = switches.begin();
193 for(list<OptBase *>::const_iterator i=opts.begin(); i!=opts.end(); ++i, ++j)
196 result += string(maxw+2-j->size(), ' ');
197 result += (*i)->get_help();
205 GetOpt::OptBase::OptBase(char s, const std::string &l, ArgType a):
213 GetOpt::OptBase &GetOpt::OptBase::set_help(const string &h)
219 GetOpt::OptBase &GetOpt::OptBase::set_help(const string &h, const string &m)
226 void GetOpt::OptBase::process()
228 if(arg_type==REQUIRED_ARG)
229 throw UsageError("--"+lng+" requires an argument");
235 void GetOpt::OptBase::process(const string &arg)
238 throw UsageError("--"+lng+" takes no argument");