]> git.proxmox.com Git - libgit2.git/blob - examples/args.c
New upstream version 1.1.0+dfsg.1
[libgit2.git] / examples / args.c
1 #include "common.h"
2 #include "args.h"
3
4 size_t is_prefixed(const char *str, const char *pfx)
5 {
6 size_t len = strlen(pfx);
7 return strncmp(str, pfx, len) ? 0 : len;
8 }
9
10 int optional_str_arg(
11 const char **out, struct args_info *args, const char *opt, const char *def)
12 {
13 const char *found = args->argv[args->pos];
14 size_t len = is_prefixed(found, opt);
15
16 if (!len)
17 return 0;
18
19 if (!found[len]) {
20 if (args->pos + 1 == args->argc) {
21 *out = def;
22 return 1;
23 }
24 args->pos += 1;
25 *out = args->argv[args->pos];
26 return 1;
27 }
28
29 if (found[len] == '=') {
30 *out = found + len + 1;
31 return 1;
32 }
33
34 return 0;
35 }
36
37 int match_str_arg(
38 const char **out, struct args_info *args, const char *opt)
39 {
40 const char *found = args->argv[args->pos];
41 size_t len = is_prefixed(found, opt);
42
43 if (!len)
44 return 0;
45
46 if (!found[len]) {
47 if (args->pos + 1 == args->argc)
48 fatal("expected value following argument", opt);
49 args->pos += 1;
50 *out = args->argv[args->pos];
51 return 1;
52 }
53
54 if (found[len] == '=') {
55 *out = found + len + 1;
56 return 1;
57 }
58
59 return 0;
60 }
61
62 static const char *match_numeric_arg(struct args_info *args, const char *opt)
63 {
64 const char *found = args->argv[args->pos];
65 size_t len = is_prefixed(found, opt);
66
67 if (!len)
68 return NULL;
69
70 if (!found[len]) {
71 if (args->pos + 1 == args->argc)
72 fatal("expected numeric value following argument", opt);
73 args->pos += 1;
74 found = args->argv[args->pos];
75 } else {
76 found = found + len;
77 if (*found == '=')
78 found++;
79 }
80
81 return found;
82 }
83
84 int match_uint16_arg(
85 uint16_t *out, struct args_info *args, const char *opt)
86 {
87 const char *found = match_numeric_arg(args, opt);
88 uint16_t val;
89 char *endptr = NULL;
90
91 if (!found)
92 return 0;
93
94 val = (uint16_t)strtoul(found, &endptr, 0);
95 if (!endptr || *endptr != '\0')
96 fatal("expected number after argument", opt);
97
98 if (out)
99 *out = val;
100 return 1;
101 }
102
103 int match_uint32_arg(
104 uint32_t *out, struct args_info *args, const char *opt)
105 {
106 const char *found = match_numeric_arg(args, opt);
107 uint16_t val;
108 char *endptr = NULL;
109
110 if (!found)
111 return 0;
112
113 val = (uint32_t)strtoul(found, &endptr, 0);
114 if (!endptr || *endptr != '\0')
115 fatal("expected number after argument", opt);
116
117 if (out)
118 *out = val;
119 return 1;
120 }
121
122 static int match_int_internal(
123 int *out, const char *str, int allow_negative, const char *opt)
124 {
125 char *endptr = NULL;
126 int val = (int)strtol(str, &endptr, 10);
127
128 if (!endptr || *endptr != '\0')
129 fatal("expected number", opt);
130 else if (val < 0 && !allow_negative)
131 fatal("negative values are not allowed", opt);
132
133 if (out)
134 *out = val;
135
136 return 1;
137 }
138
139 int match_bool_arg(int *out, struct args_info *args, const char *opt)
140 {
141 const char *found = args->argv[args->pos];
142
143 if (!strcmp(found, opt)) {
144 *out = 1;
145 return 1;
146 }
147
148 if (!strncmp(found, "--no-", strlen("--no-")) &&
149 !strcmp(found + strlen("--no-"), opt + 2)) {
150 *out = 0;
151 return 1;
152 }
153
154 *out = -1;
155 return 0;
156 }
157
158 int is_integer(int *out, const char *str, int allow_negative)
159 {
160 return match_int_internal(out, str, allow_negative, NULL);
161 }
162
163 int match_int_arg(
164 int *out, struct args_info *args, const char *opt, int allow_negative)
165 {
166 const char *found = match_numeric_arg(args, opt);
167 if (!found)
168 return 0;
169 return match_int_internal(out, found, allow_negative, opt);
170 }
171
172 int match_arg_separator(struct args_info *args)
173 {
174 if (args->opts_done)
175 return 1;
176
177 if (strcmp(args->argv[args->pos], "--") != 0)
178 return 0;
179
180 args->opts_done = 1;
181 args->pos++;
182 return 1;
183 }
184
185 void strarray_from_args(git_strarray *array, struct args_info *args)
186 {
187 size_t i;
188
189 array->count = args->argc - args->pos;
190 array->strings = calloc(array->count, sizeof(char *));
191 assert(array->strings != NULL);
192
193 for (i = 0; args->pos < args->argc; ++args->pos) {
194 array->strings[i++] = args->argv[args->pos];
195 }
196 args->pos = args->argc;
197 }