-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauto_flags.h
145 lines (132 loc) · 2.97 KB
/
auto_flags.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#pragma once
#include <getopt.h>
#include <map>
#include <string>
using namespace std;
struct auto_flag {
// string name;
int has_arg;
// int *flag;
int val;
void *value;
string help;
auto_flag() :
has_arg(0), val(0), value(0) {
}
auto_flag(int has_arg, void *value, string help) :
has_arg(has_arg), val(0), value(value), help(help) {
}
};
typedef map<string, auto_flag> auto_flags;
/**
* add bool arg
*
* @param flags
* @param name
* @param value
* @param help
*/
inline void
add_no_argument(auto_flags *flags, string name, int *value, string help="") {
(*flags)[name] = auto_flag(no_argument, value, help);
}
/**
* add value arg
*
* @param flags
* @param name
* @param value
* @param help
*/
inline void
add_required_argument(auto_flags *flags, string name, string *value, string help="") {
(*flags)[name] = auto_flag(required_argument, value, help);
}
// private
struct do_print_help {
void operator()(pair<string, auto_flag> p)const{
auto_flag f = p.second;
printf(" ");
if (f.val)
printf("-%c, ", f.val);
printf("--%s", p.first.c_str());
if (f.has_arg)
printf("=value");
printf(" %s", f.help.c_str());
if (f.has_arg)
printf(" (default=%s)", (*(string *) f.value).c_str());
printf("\n");
}
};
/**
* parse_auto_flags
*
* @return arg
*/
inline int
parse_auto_flags(auto_flags *flags, int argc, char **argv) {
string shortopts;
vector<option> longopts;
for (auto_flags::iterator iter = (*flags).begin(); iter != (*flags).end(); ++iter) {
const char *name = (*iter).first.c_str();
int has_arg=(*iter).second.has_arg;
int val=(*iter).second.val;
option next = {name, has_arg, 0, val};
longopts.push_back(next);
if (val) {
shortopts+=val;
if (has_arg)
shortopts+=":";
}
}
option last = {0,0,0,0};
longopts.push_back(last);
int c;
int option_index = 0;
while ((c = getopt_long(argc, argv, shortopts.c_str(), longopts.data(), &option_index)) != -1) {
void *value = (*flags)[longopts[option_index].name].value;
switch (c) {
case 0:
printf("option %s", longopts[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
if (optarg == 0)
*((int *) value) = 1;
else
*((string *) value) = optarg;
break;
case '?':
case 'h':
printf("Usage: %s [options]\n", argv[0]);
for_each((*flags).begin(), (*flags).end(), do_print_help());
exit(1);
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}
return optind;
}
// private
struct do_print_values {
void operator()(pair<string, auto_flag> p)const{
auto_flag f = p.second;
printf("%s=", p.first.c_str());
if (f.has_arg)
printf("%s", (*(string *) f.value).c_str());
else
printf("%d", (*(int *) f.value));
printf("\n");
}
};
/**
* print_auto_flags
*
* convenience function to print the flags values to stdout
*
* @param flags the flags context to print
*/
inline void
print_auto_flags(auto_flags *flags) {
for_each((*flags).begin(), (*flags).end(), do_print_values());
}