]> git.proxmox.com Git - libgit2.git/blame - examples/args.c
Update changelog for 1.1.0+dfsg.1-4.1 release
[libgit2.git] / examples / args.c
CommitLineData
0c9c969a
UG
1#include "common.h"
2#include "args.h"
3
4size_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
10int 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
37int 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
62static 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
84int 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
103int 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
122static 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
139int 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
158int is_integer(int *out, const char *str, int allow_negative)
159{
160 return match_int_internal(out, str, allow_negative, NULL);
161}
162
163int 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
172int 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
185void 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}