4
4
#define OPT_SHORT 1
5
5
#define OPT_UNSET 2
6
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 )
15
8
{
16
9
if (p -> opt ) {
17
10
const char * res = p -> opt ;
@@ -37,7 +30,7 @@ static int opterror(const struct option *opt, const char *reason, int flags)
37
30
return error ("option `%s' %s" , opt -> long_name , reason );
38
31
}
39
32
40
- static int get_value (struct optparse_t * p ,
33
+ static int get_value (struct parse_opt_ctx_t * p ,
41
34
const struct option * opt , int flags )
42
35
{
43
36
const char * s , * arg ;
@@ -131,7 +124,7 @@ static int get_value(struct optparse_t *p,
131
124
}
132
125
}
133
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 )
135
128
{
136
129
for (; options -> type != OPTION_END ; options ++ ) {
137
130
if (options -> short_name == * p -> opt ) {
@@ -142,7 +135,7 @@ static int parse_short_opt(struct optparse_t *p, const struct option *options)
142
135
return error ("unknown switch `%c'" , * p -> opt );
143
136
}
144
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 ,
146
139
const struct option * options )
147
140
{
148
141
const char * arg_end = strchr (arg , '=' );
@@ -247,45 +240,63 @@ void check_typos(const char *arg, const struct option *options)
247
240
}
248
241
}
249
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
+
250
260
static NORETURN void usage_with_options_internal (const char * const * ,
251
261
const struct option * , int );
252
262
253
263
int parse_options (int argc , const char * * argv , const struct option * options ,
254
264
const char * const usagestr [], int flags )
255
265
{
256
- struct optparse_t args = { argv + 1 , argv , argc - 1 , 0 , NULL } ;
266
+ struct parse_opt_ctx_t ctx ;
257
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 ];
260
271
261
272
if (* arg != '-' || !arg [1 ]) {
262
- if (flags & PARSE_OPT_STOP_AT_NON_OPTION )
273
+ if (ctx . flags & PARSE_OPT_STOP_AT_NON_OPTION )
263
274
break ;
264
- args .out [args .cpidx ++ ] = args .argv [0 ];
275
+ ctx .out [ctx .cpidx ++ ] = ctx .argv [0 ];
265
276
continue ;
266
277
}
267
278
268
279
if (arg [1 ] != '-' ) {
269
- args .opt = arg + 1 ;
270
- if (* args .opt == 'h' )
280
+ ctx .opt = arg + 1 ;
281
+ if (* ctx .opt == 'h' )
271
282
usage_with_options (usagestr , options );
272
- if (parse_short_opt (& args , options ) < 0 )
283
+ if (parse_short_opt (& ctx , options ) < 0 )
273
284
usage_with_options (usagestr , options );
274
- if (args .opt )
285
+ if (ctx .opt )
275
286
check_typos (arg + 1 , options );
276
- while (args .opt ) {
277
- if (* args .opt == 'h' )
287
+ while (ctx .opt ) {
288
+ if (* ctx .opt == 'h' )
278
289
usage_with_options (usagestr , options );
279
- if (parse_short_opt (& args , options ) < 0 )
290
+ if (parse_short_opt (& ctx , options ) < 0 )
280
291
usage_with_options (usagestr , options );
281
292
}
282
293
continue ;
283
294
}
284
295
285
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 ++ ;
289
300
}
290
301
break ;
291
302
}
@@ -294,13 +305,11 @@ int parse_options(int argc, const char **argv, const struct option *options,
294
305
usage_with_options_internal (usagestr , options , 1 );
295
306
if (!strcmp (arg + 2 , "help" ))
296
307
usage_with_options (usagestr , options );
297
- if (parse_long_opt (& args , arg + 2 , options ))
308
+ if (parse_long_opt (& ctx , arg + 2 , options ))
298
309
usage_with_options (usagestr , options );
299
310
}
300
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 );
304
313
}
305
314
306
315
#define USAGE_OPTS_WIDTH 24
0 commit comments