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 "sopt.h"
34
35 #include <cx/hash_map.h>
36
37 void cmd_args_free(CmdArgs *args) {
38 if(args) {
39 cxMapDestroy(args->options);
40 free(args->argv);
41 free(args);
42 }
43 }
44
45 static void cmd_map_put(CxMap *map,
const char *key,
const void *value) {
46 cxMapPut(map, key, (
void*)value);
47 }
48
49 CmdArgs* cmd_parse_args(
int argc,
char **argv) {
50 CmdArgs *a = malloc(
sizeof(CmdArgs));
51 a->options = cxHashMapCreate(cxDefaultAllocator,
CX_STORE_POINTERS,
16);
52 a->argv = calloc(argc,
sizeof(
char*));
53 a->argc =
0;
54
55 const char *
NOARG =
"";
56
57 char *option =
NULL;
58 char optchar =
0;
59 for(
int i=
0;i<argc;i++) {
60 char *arg = argv[i];
61 size_t len = strlen(arg);
62 if(len >
1 && arg[
0] ==
'-') {
63 for(
int c=
1;c<len;c++) {
64 switch(arg[c]) {
65 default: {
66 fprintf(stderr,
"Unknown option -%c\n\n", arg[c]);
67 cmd_args_free(a);
68 return NULL;
69 }
70 case 'c': {
71 cmd_map_put(a->options,
"conflict",
NOARG);
72 break;
73 }
74 case 'l': {
75 cmd_map_put(a->options,
"lock",
NOARG);
76 break;
77 }
78 case 'd': {
79 cmd_map_put(a->options,
"nolock",
NOARG);
80 break;
81 }
82 case 'r': {
83 cmd_map_put(a->options,
"remove",
NOARG);
84 break;
85 }
86 case 'v': {
87 cmd_map_put(a->options,
"verbose",
NOARG);
88 break;
89 }
90 case 's': {
91 option =
"syncdir";
92 optchar =
's';
93 break;
94 }
95 case 't': {
96 option =
"tags";
97 optchar =
't';
98 break;
99 }
100 case 'V': {
101 option =
"version";
102 optchar =
'V';
103 break;
104 }
105 case 'R': {
106 cmd_map_put(a->options,
"restore-removed",
NOARG);
107 break;
108 }
109 case 'M': {
110 cmd_map_put(a->options,
"restore-modified",
NOARG);
111 break;
112 }
113 case 'S': {
114 cmd_map_put(a->options,
"snapshot",
NOARG);
115 }
116 }
117 }
118 }
else if(option) {
119 cmd_map_put(a->options, option, arg);
120 option =
NULL;
121 }
else {
122 a->argv[a->argc++] = arg;
123 }
124 }
125
126 return a;
127 }
128
129 char* cmd_getoption(CmdArgs *arg,
const char *name) {
130 return cxMapGet(arg->options, cx_hash_key_str(name));
131 }
132