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 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "optparser.h"
34 #include "sopt.h"
35
36 #include <cx/hash_map.h>
37
38
39 void cmd_args_free(CmdArgs *args) {
40 if(args) {
41 cxMapDestroy(args->options);
42 if(args->argv) {
43 free(args->argv);
44 }
45 free(args);
46 }
47 }
48
49 static void cmd_map_put(CxMap *map,
const char *key,
const void *value) {
50 cxMapPut(map, key, (
void*)value);
51 }
52
53 CmdArgs* cmd_parse_args(
int argc,
char **argv) {
54 CmdArgs *a = malloc(
sizeof(CmdArgs));
55 a->options = cxHashMapCreate(cxDefaultAllocator,
CX_STORE_POINTERS,
16);
56 a->argv = argc >
0 ? calloc(argc,
sizeof(
char*)) :
NULL;
57 a->argc =
0;
58
59 const char *
NOARG =
"";
60
61 char *option =
NULL;
62 char optchar =
0;
63 int optterminated =
0;
64 for(
int i=
0;i<argc;i++) {
65 char *arg = argv[i];
66 size_t len = strlen(arg);
67 if(len ==
2 && arg[
0] ==
'-' && arg[
1] ==
'-') {
68 optterminated =
1;
69 }
else if(!optterminated && len >
1 && arg[
0] ==
'-') {
70
71
72 if(option) {
73 fprintf(stderr,
74 "Missing argument for option -%c\n\n", optchar);
75 cmd_args_free(a);
76 return NULL;
77 }
78 for(
int c=
1;c<len;c++) {
79
80 if(option) {
81 cxMapPut(a->options, cx_hash_key_str(option), &arg[c]);
82 option =
NULL;
83 break;
84 }
85
86 switch(arg[c]) {
87 default: {
88 fprintf(stderr,
"Unknown option -%c\n\n", arg[c]);
89 cmd_args_free(a);
90 return NULL;
91 }
92 case 'v': {
93 cmd_map_put(a->options,
"verbose",
NOARG);
94 break;
95 }
96 case 'k': {
97 option =
"key";
98 optchar =
'k';
99 break;
100 }
101 case 'p': {
102 cmd_map_put(a->options,
"plain",
NOARG);
103 break;
104 }
105 case 'c': {
106 cmd_map_put(a->options,
"crypt",
NOARG);
107 break;
108 }
109 case 'a': {
110 cmd_map_put(a->options,
"all",
NOARG);
111 break;
112 }
113 case 'l': {
114 cmd_map_put(a->options,
"list",
NOARG);
115 break;
116 }
117 case 'd': {
118 cmd_map_put(a->options,
"date",
NOARG);
119 break;
120 }
121 case 't': {
122 cmd_map_put(a->options,
"type",
NOARG);
123 break;
124 }
125 case 'R': {
126 cmd_map_put(a->options,
"recursive",
NOARG);
127 break;
128 }
129 case 'O': {
130 cmd_map_put(a->options,
"override",
NOARG);
131 break;
132 }
133 case 'i': {
134 cmd_map_put(a->options,
"insecure",
NOARG);
135 break;
136 }
137 case 'N': {
138 cmd_map_put(a->options,
"noinput",
NOARG);
139 break;
140 }
141 case 'e': {
142 cmd_map_put(a->options,
"extended",
NOARG);
143 break;
144 }
145 case 'x': {
146 cmd_map_put(a->options,
"xml",
NOARG);
147 break;
148 }
149 case 'F': {
150 option =
"finfo";
151 optchar =
'F';
152 break;
153 }
154 case 'S': {
155
156 cmd_map_put(a->options,
"structure",
NOARG);
157 break;
158 }
159 case 'K': {
160 cmd_map_put(a->options,
"keep",
NOARG);
161 break;
162 }
163 case 'o': {
164 option =
"output";
165 optchar =
'o';
166 break;
167 }
168 case 'u': {
169 option =
"update";
170 optchar =
'u';
171 break;
172 }
173 case 'n': {
174 option =
"namespace";
175 optchar =
'n';
176 break;
177 }
178 case 'L': {
179 option =
"lock";
180 optchar =
'L';
181 break;
182 }
183 case 'T': {
184 option =
"timeout";
185 optchar =
'T';
186 break;
187 }
188
189
190
191
192
193
194
195 case 'V': {
196 option =
"version";
197 optchar =
'V';
198 break;
199 }
200 }
201 }
202 }
else if(option) {
203 cmd_map_put(a->options, option, arg);
204 option =
NULL;
205 }
else {
206 a->argv[a->argc++] = arg;
207 }
208 }
209 if(option) {
210 fprintf(stderr,
211 "Missing argument for option -%c\n\n", optchar);
212 cmd_args_free(a);
213 return NULL;
214 }
215
216 return a;
217 }
218
219 char* cmd_getoption(CmdArgs *arg,
const char *name) {
220 return cxMapGet(arg->options, cx_hash_key_str(name));
221 }
222