27 typedef std::string String;
28 typedef std::vector<String> Strings;
36 Value(String
const& value, String
const& description) {
40 String
usage()
const {
42 " ", value_.c_str(), description_.c_str());
44 String value()
const {
47 bool operator==(Value
const& b)
const {
48 return (value_ == b.value_);
51 typedef std::vector<Value> Values;
56 Values values_accept_;
57 String value_default_;
66 Option(String
const& description) {
69 description_ = description;
72 Option(String
const& description,
74 String
const& default_value,
78 description_ = description;
80 value_default_ = default_value;
83 Strings
const& values()
const {
86 String value(
size_t index)
const {
87 if (!has_value_)
return "";
88 if (!has_setup_ || index >= values_.size())
return value_default_;
89 return values_[index];
91 ssize_t valueAdd(String
const& value) {
96 if (values_accept_.size() > 0 &&
97 std::find(values_accept_.begin(), values_accept_.end(),
98 Value(value,
"")) == values_accept_.end())
100 values_.push_back(value);
102 return values_.size() - 1;
104 bool valueAcceptAdd(String
const& value, String
const& description) {
105 if (!has_value_)
return false;
106 if (std::find(values_accept_.begin(), values_accept_.end(),
107 Value(value,
"")) == values_accept_.end()) {
108 values_accept_.push_back(Value(value, description));
112 bool valueAcceptChk(String
const& value) {
113 if (!has_value_)
return false;
114 return (values_accept_.empty() ||
115 std::find(values_accept_.begin(), values_accept_.end(),
116 Value(value,
"")) != values_accept_.end());
118 bool hasSetup()
const{
return has_setup_; }
119 bool hasValue()
const{
return has_value_; }
120 bool chkSetup()
const{
return !(must_setup_ && !has_setup_); }
122 String
usage(String opt,
bool detail)
const {
123 String ret(
stringPrintf(
"%s%s ", (opt.size() > 1 ?
"--" :
"-"), opt));
125 if (has_value_) ret += value_type_;
126 if (!must_setup_) ret =
"[" + ret +
"]";
130 ret += value_type_ +
" ";
131 String default_string(
"");
132 if (value_default_ !=
"")
133 default_string =
"defalut='" + value_default_ +
"'";
134 String optional_string(
"");
136 optional_string =
"optional";
138 if (default_string.size() + optional_string.size() > 0) {
139 if (default_string.size() > 0 && optional_string.size() > 0) {
140 ret +=
"(" + optional_string +
", " + default_string +
")";
143 ret +=
"(" + optional_string + default_string +
")";
148 String accept_string;
149 for (
size_t i = 0; i < values_accept_.size(); i++) {
151 accept_string += (i + 1 < values_accept_.size() ?
", " :
" or ");
152 accept_string +=
"'" + values_accept_[i].value() +
"'";
154 if (accept_string.size() == 0) accept_string =
"... (anything)";
159 accept_string) +
"\n";
160 for (
size_t i = 0; i < values_accept_.size(); i++) {
161 ret += values_accept_[i].usage();
168 typedef std::map<String, Option> Options;
169 typedef Options:: iterator OptionsIterator;
170 typedef Options::const_iterator OptionsIteratorK;
174 Strings usage_begin_;
176 Strings proc_arguments_;
203 options_ = usage.options_;
204 longOptions_ = usage.long_options_;
205 usage_begin_ = usage.usage_begin_;
206 usage_end_ = usage.usage_end_;
207 proc_arguments_ = usage.proc_arguments_;
217 for (OptionsIteratorK
218 it =
usage.options_.begin(); it !=
usage.options_.end(); ++it) {
219 if (options_.find(it->first) != options_.end())
222 for (OptionsIteratorK
223 it =
usage.options_.begin(); it !=
usage.options_.end(); ++it) {
224 options_.insert(std::pair<String, Option>(it->first, it->second));
226 for (
size_t i = 0; i <
usage.usage_begin_.size(); ++i)
227 usage_begin_.push_back(
usage.usage_begin_[i]);
228 for (
size_t i = 0; i <
usage.usage_end_.size(); ++i)
229 usage_end_.push_back(
usage.usage_end_[i]);
240 for (OptionsIteratorK
241 it = usage.options_.begin(); it != usage.options_.end(); ++it) {
242 OptionsIterator my = options_.find(it->first);
243 if (my == options_.end())
continue;
244 for (
size_t i = 0, I = it->second.values().size(); i < I; ++i) {
245 my->second.valueAdd(it->second.value(i));
259 if (options_.find(opt) != options_.end())
return false;
260 options_.insert(std::pair<String, Option>(opt, Option(des));
275 String
const& val_type,
276 String
const& val_default,
278 if (options_.find(opt) != options_.end())
return false;
279 options_.insert(std::pair<String, Option>(
280 opt, Option(des, val_type, val_defalut, must)));
293 OptionsIterator o = options_.find(opt);
294 if (o == options_.end())
return false;
295 return o->second.valueAcceptAdd(val, des);
305 OptionsIteratorK o = options_.find(opt);
306 return (o != options_.end() && o->second.hasSetup());
316 OptionsIteratorK o = options_.find(opt);
317 if (o == options_.end())
return 0;
318 return o->second.values().size();
329 OptionsIteratorK o = options_.find(opt);
330 if (o == options_.end())
return String();
331 return o->second.value(index);
340 return proc_arguments_.size();
350 if (index >= proc_arguments_.size()) {
353 return proc_arguments_[index];
362 return proc_arguments_;
389 Usage::String out =
stringPrintf(
"USAGE\n %s", name_.c_str());
391 it = options_.begin(); it != options_.end(); ++it)
392 out +=
" " + it->second.usage(it->first,
false);
393 out +=
"\n\nDESCRIPTION\n";
394 for (
size_t i = 0; i < usage_begin_.size(); ++i) {
395 out +=
" " + usage_begin_[i] +
"\n\n";
397 for (OptionsIteratorK
398 it = options_.begin(); it != options_.end(); ++it) {
399 out += it->second.usage(it->first,
true);
401 for (
size_t i = 0; i < usage_end_.size(); ++i) {
402 out +=
" " + usage_end_[i] +
"\n\n";
416 String& err = (errmsg == NULL ? zzz : *errmsg);
417 for (
int i = 0; i < argc; ++i) {
418 if (argv[i][0] ==
'-') {
420 if (argv[i][1] ==
'-') {
421 if (argv[i][2] ==
'\0' || argv[i][3] ==
'\0') {
425 opt = String(argv[i] + 2);
428 if (argv[i][1] ==
'\0' || argv[i][2] !=
'\0') {
432 opt = String(argv[i] + 1);
434 OptionsIterator o = options_.find(opt);
435 if (o == options_.end()) {
439 if (o->second.hasValue()) {
441 err =
stringPrintf(
"Option '%s' need a value", argv[i]);
444 if (o->second.valueAdd(argv[i + 1]) ==
false) {
445 err =
stringPrintf(
"Invalid value '%s' of options '%s'",
446 argv[i + 1], argv[i]);
452 o->second.valueAdd(
"");
456 proc_arguments_.push_back(String(argv[i] + (argv[i][0]==
'\\' ? 1:0)));
459 for (OptionsIteratorK it = options_.begin(); it != options_.end(); ++it) {
460 if (it->second.chkSetup() ==
false) {
462 (it->first.size() > 1 ?
"--" :
"-"), it->first);
472 #endif // MEOW_USAGE_H__