parse-opt: have parse_options_{start,end}.
Make the struct optparse_t public under the better name parse_opt_ctx_t. Signed-off-by: Pierre Habouzit <madcoder@debian.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Pierre Habouzit committed
Jun 23, 2008 at 21:59 UTC
7e7bbcb4b35cbb4bbb5e65cf057c84b16dbd3d39
2 files changed
+55
-30
parse-options.c
+39
-30
@@ -4,14 +4,7 @@
4
#define OPT_SHORT 1
5
#define OPT_UNSET 2
6
7
-struct optparse_t {
8
- const char **argv;
9
- const char **out;
10
- int argc, cpidx;
11
- const char *opt;
12
-};
13
-
14
-static inline const char *get_arg(struct optparse_t *p)
7
+static inline const char *get_arg(struct parse_opt_ctx_t *p)
8
{
9
if (p->opt) {
10
const char *res = p->opt;
@@ -37,7 +30,7 @@ static int opterror(const struct option *opt, const char *reason, int flags)
30
return error("option `%s' %s", opt->long_name, reason);
31
}
32
40
-static int get_value(struct optparse_t *p,
33
+static int get_value(struct parse_opt_ctx_t *p,
34
const struct option *opt, int flags)
35
{
36
const char *s, *arg;
@@ -131,7 +124,7 @@ static int get_value(struct optparse_t *p,
124
}
125
}
126
134
-static int parse_short_opt(struct optparse_t *p, const struct option *options)
127
+static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
128
{
129
for (; options->type != OPTION_END; options++) {
130
if (options->short_name == *p->opt) {
@@ -142,7 +135,7 @@ static int parse_short_opt(struct optparse_t *p, const struct option *options)
135
return error("unknown switch `%c'", *p->opt);
136
}
137
145
-static int parse_long_opt(struct optparse_t *p, const char *arg,
138
+static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
139
const struct option *options)
140
{
141
const char *arg_end = strchr(arg, '=');
@@ -247,45 +240,63 @@ void check_typos(const char *arg, const struct option *options)
240
}
241
}
242
243
+void parse_options_start(struct parse_opt_ctx_t *ctx,
244
+ int argc, const char **argv, int flags)
245
+{
246
+ memset(ctx, 0, sizeof(*ctx));
247
+ ctx->argc = argc - 1;
248
+ ctx->argv = argv + 1;
249
+ ctx->out = argv;
250
+ ctx->flags = flags;
251
+}
252
+
253
+int parse_options_end(struct parse_opt_ctx_t *ctx)
254
+{
255
+ memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
256
+ ctx->out[ctx->cpidx + ctx->argc] = NULL;
257
+ return ctx->cpidx + ctx->argc;
258
+}
259
+
260
static NORETURN void usage_with_options_internal(const char * const *,
261
const struct option *, int);
262
263
int parse_options(int argc, const char **argv, const struct option *options,
264
const char * const usagestr[], int flags)
265
{
256
- struct optparse_t args = { argv + 1, argv, argc - 1, 0, NULL };
266
+ struct parse_opt_ctx_t ctx;
267
258
- for (; args.argc; args.argc--, args.argv++) {
259
- const char *arg = args.argv[0];
268
+ parse_options_start(&ctx, argc, argv, flags);
269
+ for (; ctx.argc; ctx.argc--, ctx.argv++) {
270
+ const char *arg = ctx.argv[0];
271
272
if (*arg != '-' || !arg[1]) {
262
- if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
273
+ if (ctx.flags & PARSE_OPT_STOP_AT_NON_OPTION)
274
break;
264
- args.out[args.cpidx++] = args.argv[0];
275
+ ctx.out[ctx.cpidx++] = ctx.argv[0];
276
continue;
277
}
278
279
if (arg[1] != '-') {
269
- args.opt = arg + 1;
270
- if (*args.opt == 'h')
280
+ ctx.opt = arg + 1;
281
+ if (*ctx.opt == 'h')
282
usage_with_options(usagestr, options);
272
- if (parse_short_opt(&args, options) < 0)
283
+ if (parse_short_opt(&ctx, options) < 0)
284
usage_with_options(usagestr, options);
274
- if (args.opt)
285
+ if (ctx.opt)
286
check_typos(arg + 1, options);
276
- while (args.opt) {
277
- if (*args.opt == 'h')
287
+ while (ctx.opt) {
288
+ if (*ctx.opt == 'h')
289
usage_with_options(usagestr, options);
279
- if (parse_short_opt(&args, options) < 0)
290
+ if (parse_short_opt(&ctx, options) < 0)
291
usage_with_options(usagestr, options);
292
}
293
continue;
294
}
295
296
if (!arg[2]) { /* "--" */
286
- if (!(flags & PARSE_OPT_KEEP_DASHDASH)) {
287
- args.argc--;
288
- args.argv++;
297
+ if (!(ctx.flags & PARSE_OPT_KEEP_DASHDASH)) {
298
+ ctx.argc--;
299
+ ctx.argv++;
300
}
301
break;
302
}
@@ -294,13 +305,11 @@ int parse_options(int argc, const char **argv, const struct option *options,
305
usage_with_options_internal(usagestr, options, 1);
306
if (!strcmp(arg + 2, "help"))
307
usage_with_options(usagestr, options);
297
- if (parse_long_opt(&args, arg + 2, options))
308
+ if (parse_long_opt(&ctx, arg + 2, options))
309
usage_with_options(usagestr, options);
310
}
311
301
- memmove(args.out + args.cpidx, args.argv, args.argc * sizeof(*args.out));
302
- args.out[args.cpidx + args.argc] = NULL;
303
- return args.cpidx + args.argc;
312
+ return parse_options_end(&ctx);
313
}
314
315
#define USAGE_OPTS_WIDTH 24
parse-options.h
+16
@@ -111,6 +111,22 @@ extern int parse_options(int argc, const char **argv,
111
extern NORETURN void usage_with_options(const char * const *usagestr,
112
const struct option *options);
113
114
+/*----- incremantal advanced APIs -----*/
115
+
116
+struct parse_opt_ctx_t {
117
+ const char **argv;
118
+ const char **out;
119
+ int argc, cpidx;
120
+ const char *opt;
121
+ int flags;
122
+};
123
+
124
+extern void parse_options_start(struct parse_opt_ctx_t *ctx,
125
+ int argc, const char **argv, int flags);
126
+
127
+extern int parse_options_end(struct parse_opt_ctx_t *ctx);
128
+
129
+
130
/*----- some often used options -----*/
131
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
132
extern int parse_opt_approxidate_cb(const struct option *, const char *, int);