2 * Copyright (C) 2016 Andre Noll <maan@tuebingen.mpg.de>
4 * Licensed under the LGPL v3, see http://www.gnu.org/licenses/lgpl-3.0.html
16 #include "lopsub-internal.h"
19 /* For detecting version mismatches, see lopsub-internal.h. */
20 const unsigned LLS_ABI_VERSION_VAR
= 0;
22 #define FOR_EACH_OPTION(_i, _opts) \
23 for (_i = 0; (_opts) && (_opts)[(_i)].name; (_i)++)
25 #define FOR_EACH_OPTION_IN_COMMAND(_opt, _cmd) \
27 (_opt) = (_cmd)->options; \
28 (_opt) && (_opt) < (_cmd)->options + (_cmd)->num_options; \
32 /* The result of parsing one option and its arguments. */
34 int idx
; /* index into either argv[] or the lls_option array. */
35 const char *arg
; /* NULL if option has no argument. */
39 * This structure, and the exchange_args(), decode_option() and parse_option()
40 * functions below are inspired by the glibc implementation of getopt.c,
41 * Copyright (C) 1987-2015 Free Software Foundation, Inc.
44 const struct lls_option
*opts
;
48 int optind
; /* index into argv[] which we are parsing. */
49 const char *next_char
;
51 * These describe the part of argv[] that contains non-options that
52 * have been skipped. first_nonopt is the index in argv[] of the first
53 * of them, last_nonopt is the index after the last of them. Initially
54 * both indices are zero.
60 const struct lls_command
*lls_cmd(unsigned cmd_num
,
61 const struct lls_suite
*suite
)
63 if (cmd_num
> suite
->num_subcommands
)
65 return suite
->commands
+ cmd_num
;
68 const char *lls_command_name(const struct lls_command
*cmd
)
73 const void *lls_user_data(const struct lls_command
*cmd
)
75 return cmd
->user_data
;
78 const struct lls_option
*lls_opt(unsigned opt_num
,
79 const struct lls_command
*cmd
)
81 return cmd
->options
+ opt_num
;
84 const struct lls_opt_result
*lls_opt_result(unsigned opt_num
,
85 const struct lls_parse_result
*lpr
)
87 return lpr
->opt_result
+ opt_num
;
90 unsigned lls_opt_given(const struct lls_opt_result
*r
)
95 const char *lls_enum_string_val(unsigned idx
, const struct lls_option
*opt
)
97 return opt
->values
[idx
].string_val
;
100 const char *lls_string_val(unsigned idx
, const struct lls_opt_result
*r
)
102 return r
->value
[idx
].string_val
;
105 int32_t lls_int32_val(unsigned idx
, const struct lls_opt_result
*r
)
107 return r
->value
[idx
].int32_val
;
110 uint32_t lls_uint32_val(unsigned idx
, const struct lls_opt_result
*r
)
112 return r
->value
[idx
].uint32_val
;
115 int64_t lls_int64_val(unsigned idx
, const struct lls_opt_result
*r
)
117 return r
->value
[idx
].int64_val
;
120 uint64_t lls_uint64_val(unsigned idx
, const struct lls_opt_result
*r
)
122 return r
->value
[idx
].uint64_val
;
125 unsigned lls_num_inputs(const struct lls_parse_result
*lpr
)
127 return lpr
->num_inputs
;
130 const char *lls_purpose(const struct lls_command
*cmd
)
135 const char *lls_input(unsigned input_num
, const struct lls_parse_result
*lpr
)
137 return lpr
->inputs
[input_num
];
140 const char *lls_strerror(int lss_errno
)
142 #define LLS_ERROR(_n, _s) _s,
143 static const char * const error_string
[] = {LLS_ERRORS NULL
};
145 return error_string
[lss_errno
];
148 static int xrealloc(void *p
, size_t size
)
150 void **pp
= p
, *newp
= realloc(*pp
, size
);
158 /* Print a formatted message to a dynamically allocated string. */
159 __attribute__ ((format (printf
, 2, 0)))
160 static int xvasprintf(char **result
, const char *fmt
, va_list ap
)
170 *result
= malloc(size
+ 1);
174 ret
= vsnprintf(*result
, size
, fmt
, aq
);
177 if (ret
< size
) /* OK */
180 ret
= xrealloc(result
, size
);
187 ret
= vsnprintf(*result
, size
, fmt
, aq
);
189 assert(ret
>= 0 && ret
< size
);
193 /* Print to a dynamically allocated string, variable number of arguments. */
194 __attribute__ ((format (printf
, 2, 3)))
195 static int xasprintf(char **result
, const char *fmt
, ...)
201 ret
= xvasprintf(result
, fmt
, ap
);
206 static inline unsigned num_vals_in_parse_result(const struct lls_command
*cmd
,
207 int opt_num
, const struct lls_parse_result
*lpr
)
209 const struct lls_option
*opt
= cmd
->options
+ opt_num
;
210 struct lls_opt_result
*lor
= lpr
->opt_result
+ opt_num
;
212 if (opt
->arg_info
== LLS_NO_ARGUMENT
)
215 return 1; /* for the default value */
216 if (!(opt
->flags
& LLS_MULTIPLE
))
228 enum atoi_mode
{ATOI_INT32
, ATOI_UINT32
, ATOI_INT64
, ATOI_UINT64
};
231 * Convert a string to a 32 or 64 bit signed or unsigned integer value.
233 * For conversions to unsigned integers, negative values are considered valid
234 * input and are silently converted.
236 static int lls_atoi(const char *str
, enum atoi_mode mode
, union atoi_result
*value
)
239 union atoi_result result
;
241 memset(value
, 0, sizeof(*value
));
242 errno
= 0; /* To distinguish success/failure after call */
244 * We pass zero as the base to strtoll(3) and strtoull(3) to let the
245 * function recognize an optional base prefix like "0x".
247 if (mode
== ATOI_UINT64
) {
248 unsigned long long tmp
= strtoull(str
, &endptr
, 0);
249 if (errno
== ERANGE
&& tmp
== ULLONG_MAX
)
250 return -E_LLS_OVERFLOW
;
252 } else { /* parse as signed 64 bit and check range */
253 long long tmp
= strtoll(str
, &endptr
, 0);
254 if (errno
== ERANGE
&& (tmp
== LLONG_MAX
|| tmp
== LLONG_MIN
))
255 return -E_LLS_OVERFLOW
;
257 case ATOI_INT64
: /* no additional range check necessary */
261 if (tmp
< INT_MIN
|| tmp
> INT_MAX
)
262 return -E_LLS_OVERFLOW
;
267 return -E_LLS_OVERFLOW
;
275 * If there were no digits at all, strtol() and friends store the
276 * original value of str in *endptr.
279 return -E_LLS_NO_DIGITS
;
281 * The implementation may also set errno (and return 0) in case no
282 * conversion was performed.
285 return -E_LLS_NO_DIGITS
;
286 if (*endptr
!= '\0') /* Further characters after number */
287 return -E_LLS_TRAILING_GARBAGE
;
292 static int atoi32(const char *str
, int32_t *result
)
294 union atoi_result ar
;
295 int ret
= lls_atoi(str
, ATOI_INT32
, &ar
);
300 static int atou32(const char *str
, uint32_t *result
)
302 union atoi_result ar
;
303 int ret
= lls_atoi(str
, ATOI_UINT32
, &ar
);
308 static int atoi64(const char *str
, int64_t *result
)
310 union atoi_result ar
;
311 int ret
= lls_atoi(str
, ATOI_INT64
, &ar
);
316 static int atou64(const char *str
, uint64_t *result
)
318 union atoi_result ar
;
319 int ret
= lls_atoi(str
, ATOI_UINT64
, &ar
);
324 static void free_opt_result(int opt_num
, struct lls_parse_result
*lpr
,
325 const struct lls_command
*cmd
)
327 const struct lls_option
*opt
= cmd
->options
+ opt_num
;
329 if (opt
->arg_type
== LLS_STRING
&& !opt
->values
) {
330 unsigned num_vals
= num_vals_in_parse_result(cmd
, opt_num
, lpr
);
332 for (j
= 0; j
< num_vals
; j
++)
333 if (lpr
->opt_result
[opt_num
].value
)
334 free(lpr
->opt_result
[opt_num
].value
[j
].string_val
);
336 if (opt
->arg_info
!= LLS_NO_ARGUMENT
)
337 free(lpr
->opt_result
[opt_num
].value
);
340 void lls_free_parse_result(struct lls_parse_result
*lpr
,
341 const struct lls_command
*cmd
)
348 for (i
= 0; i
< lpr
->num_inputs
; i
++)
349 free(lpr
->inputs
[i
]);
352 FOR_EACH_OPTION(i
, cmd
->options
)
353 free_opt_result(i
, lpr
, cmd
);
354 free(lpr
->opt_result
);
358 static struct lls_data
*init_lls_data(const struct lls_option
*opts
,
359 int argc
, char *const *argv
)
361 struct lls_data
*d
= malloc(sizeof(*d
));
366 /* start with an empty non-option list */
367 d
->first_nonopt
= d
->last_nonopt
= d
->optind
;
376 * Exchange two adjacent subsets of argv[].
378 * One subset is given by indices {first_nonopt, ..., last_nonopt - 1}. It
379 * contains all the non-options that have been skipped so far. The other subset
380 * corresponds to indices {last_nonopt, ... optind - 1} which contains all the
381 * options processed since those non-options were skipped.
383 * Before the function returns, ->first_nonopt and ->last_nonopt are updated to
384 * describe the new set of non-options in argv[].
386 static void exchange_args(struct lls_data
*d
)
388 int bottom
= d
->first_nonopt
;
389 int middle
= d
->last_nonopt
;
391 char **argv
= (char **)d
->argv
;
394 * Exchange the shorter segment with the far end of the longer segment.
395 * That puts the shorter segment into the right place. It leaves the
396 * longer segment in the right place overall, but it consists of two
397 * parts that need to be swapped next.
399 while (top
> middle
&& middle
> bottom
) {
400 if (top
- middle
> middle
- bottom
) {
401 /* Bottom segment is the short one. */
402 int i
, len
= middle
- bottom
;
404 /* Swap it with the top part of the top segment. */
405 for (i
= 0; i
< len
; i
++) {
406 char *tmp
= argv
[bottom
+ i
];
407 argv
[bottom
+ i
] = argv
[top
- (middle
- bottom
) + i
];
408 argv
[top
- (middle
- bottom
) + i
] = tmp
;
410 /* Exclude the moved bottom segment from further swapping. */
413 /* Top segment is the short one. */
414 int i
, len
= top
- middle
;
415 /* Swap it with the bottom part of the bottom segment. */
416 for (i
= 0; i
< len
; i
++) {
417 char *tmp
= argv
[bottom
+ i
];
418 argv
[bottom
+ i
] = argv
[middle
+ i
];
419 argv
[middle
+ i
] = tmp
;
421 /* Exclude the moved top segment from further swapping. */
425 /* Update records for the slots the non-options now occupy. */
426 d
->first_nonopt
+= d
->optind
- d
->last_nonopt
;
427 d
->last_nonopt
= d
->optind
;
430 /* whether arg points to an option argument */
431 static inline bool is_option(const char *arg
)
433 return arg
[0] == '-' && arg
[1] != '\0';
436 static void check_errctx(char **errctx
, int ret
)
441 assert(!*errctx
); /* memory leak/uninitialized pointer */
442 else if (ret
!= -E_LLS_NOMEM
)
443 assert(*errctx
); /* we must provide an error message */
447 * Decode the current option. On success, set result->idx to the index in the
448 * ->options array which was decoded successfully. On failure, result->idx is
449 * the index in argv[] which could not be parsed.
451 static int decode_option(struct lls_data
*d
, struct lls_arg
*result
,
454 const char *word
= d
->argv
[d
->optind
], *cur
, *end
;
457 const struct lls_option
*match
= NULL
;
458 bool ambig
= false, shortopt
;
460 assert(word
[0] != '\0');
461 shortopt
= word
[1] != '-';
462 result
->idx
= d
->optind
;
468 cur
= word
+ 1 + !shortopt
; /* skip dash(es) */
469 for (end
= cur
; *end
&& *end
!= '='; end
++)
473 /* test all options for exact or abbreviated matches */
474 FOR_EACH_OPTION(i
, d
->opts
) {
475 const struct lls_option
*opt
= d
->opts
+ i
;
476 if (opt
->flags
& LLS_IGNORED
)
479 if (*cur
!= opt
->short_opt
)
482 d
->next_char
= cur
+ 1;
483 if (d
->next_char
[0] == '\0' || d
->next_char
[0] == '=')
487 if (strncmp(opt
->name
, cur
, len
) != 0)
489 if (strlen(opt
->name
) == len
) { /* exact match */
493 if (match
) { /* second non-exact match */
497 /* first non-exact match */
500 if (!match
) { /* option not found */
501 xasprintf(errctx
, "error token: %s", cur
);
502 return -E_LLS_BAD_OPTION
;
505 xasprintf(errctx
, "%s", word
);
506 return -E_LLS_AMBIG_OPTION
;
509 if (match
->arg_info
== LLS_REQUIRED_ARGUMENT
) {
510 xasprintf(errctx
, "--%s", match
->name
);
511 return -E_LLS_NO_ARG_GIVEN
;
518 if (match
->arg_info
== LLS_NO_ARGUMENT
) {
519 xasprintf(errctx
, "--%s", match
->name
);
520 return -E_LLS_ARG_GIVEN
;
522 result
->arg
= end
+ 1;
523 } else if (match
->arg_info
== LLS_REQUIRED_ARGUMENT
) {
524 if (d
->optind
>= d
->argc
) {
525 xasprintf(errctx
, "--%s", match
->name
);
526 return -E_LLS_NO_ARG_GIVEN
;
528 result
->arg
= d
->argv
[d
->optind
++];
532 result
->idx
= match
- d
->opts
;
537 * Parse one option, including its argument (if any).
539 * We permute the contents of ARGV as we scan, so that eventually all the
540 * non-options are at the end. This allows options to be given in any order.
542 * Returns zero on end-of-argv, negative on errors, one if an option was parsed
543 * successfully. The structure pointed to by result is initialized as follows:
545 * end-of-args case: ->idx is the index of first non-option in argv[], ->arg is
548 * error case: ->idx is the index of the first problematic option in argv. ->arg is
549 * argv[result->idx] as in the end-of-args case.
551 * success case: ->idx is the index into the option array which corresponds to
552 * the option that was parsed successfully, ->arg its argument, or NULL if no
553 * argument was given.
555 * After this function returned non-positive, it must not be called again.
557 static int parse_option(struct lls_data
*d
, struct lls_arg
*result
, char **errctx
)
559 assert(d
->last_nonopt
<= d
->optind
);
560 assert(d
->first_nonopt
<= d
->optind
);
563 return decode_option(d
, result
, errctx
);
565 * If we have just processed some options following some non-options,
566 * exchange them so that the options come first.
568 if (d
->first_nonopt
!= d
->last_nonopt
&& d
->last_nonopt
!= d
->optind
)
570 else if (d
->last_nonopt
!= d
->optind
)
571 d
->first_nonopt
= d
->optind
;
573 * Skip any additional non-options and extend the range of non-options
574 * previously skipped.
576 while (d
->optind
< d
->argc
&& !is_option(d
->argv
[d
->optind
]))
578 d
->last_nonopt
= d
->optind
;
580 * The special argument `--' forces an end of option-scanning. We skip
581 * it like a null option, then exchange it with previous non-options as
582 * if it were an option. Then we skip everything else like a non-option.
584 if (d
->optind
!= d
->argc
&& !strcmp(d
->argv
[d
->optind
], "--")) {
586 if (d
->first_nonopt
!= d
->last_nonopt
&& d
->last_nonopt
!= d
->optind
)
588 else if (d
->first_nonopt
== d
->last_nonopt
)
589 d
->first_nonopt
= d
->optind
;
590 d
->last_nonopt
= d
->argc
;
594 * If we have done all the argv elements, stop the scan and back over
595 * any non-options that we skipped and permuted.
597 if (d
->optind
== d
->argc
) {
599 * Set the index to point at the non-options that we
600 * previously skipped.
602 result
->idx
= d
->first_nonopt
;
603 result
->arg
= d
->argv
[result
->idx
];
606 assert(is_option(d
->argv
[d
->optind
]));
607 return decode_option(d
, result
, errctx
);
610 static int check_enum_arg(const char *arg
, const struct lls_option
*opt
,
616 for (i
= 0; (val
= opt
->values
[i
].string_val
); i
++)
617 if (!strcmp(arg
, val
))
619 xasprintf(errctx
, "arg: %s, option: %s", arg
, opt
->name
);
624 * Increase the "given" count and store argument if the option takes one.
625 * Allocates or reallocates the ->value array of struct lls_opt_result in lpr.
627 static int lls_parse_arg(struct lls_arg
*la
, const struct lls_option
*opts
,
628 struct lls_parse_result
*lpr
, char **errctx
)
630 const struct lls_option
*opt
= opts
+ la
->idx
;
631 struct lls_opt_result
*lor
= lpr
->opt_result
+ la
->idx
;
637 if (opt
->arg_info
== LLS_NO_ARGUMENT
) {
638 xasprintf(errctx
, "arg: %s, option: %s", la
->arg
, opt
->name
);
639 return -E_LLS_ARG_GIVEN
;
641 multiple
= opt
->flags
& LLS_MULTIPLE
;
642 idx
= multiple
? lor
->given
: 0;
643 if (lor
->given
== 0 || multiple
) {
644 ret
= xrealloc(&lor
->value
,
645 (lor
->given
+ 1) * sizeof(*lor
->value
));
647 xasprintf(errctx
, "option value array for --%s",
652 switch (opt
->arg_type
) {
654 if (!opt
->values
&& lor
->given
> 0 && !multiple
)
655 free(lor
->value
[idx
].string_val
);
657 ret
= check_enum_arg(la
->arg
, opt
, errctx
);
660 lor
->value
[idx
].uint32_val
= ret
;
662 lor
->value
[idx
].string_val
= strdup(la
->arg
);
663 if (!lor
->value
[idx
].string_val
) {
664 xasprintf(errctx
, "string value for %s",
671 ret
= atoi32(la
->arg
, &lor
->value
[idx
].int32_val
);
676 ret
= atou32(la
->arg
, &lor
->value
[idx
].uint32_val
);
681 ret
= atoi64(la
->arg
, &lor
->value
[idx
].int64_val
);
686 ret
= atou64(la
->arg
, &lor
->value
[idx
].uint64_val
);
698 xasprintf(errctx
, "conversion error for argument \"%s\" to option --%s",
703 static int copy_val(union lls_val
*dst
, const union lls_val
*src
,
704 const struct lls_option
*opt
, char **errctx
)
706 if (opt
->arg_type
!= LLS_STRING
|| opt
->values
) {
710 if (!src
->string_val
) {
711 dst
->string_val
= NULL
;
714 dst
->string_val
= strdup(src
->string_val
);
715 if (!dst
->string_val
) {
716 xasprintf(errctx
, "copy value for --%s", opt
->name
);
722 int lls_check_arg_count(const struct lls_parse_result
*lpr
,
723 int min_argc
, int max_argc
, char **errctx
)
727 assert(min_argc
<= max_argc
);
728 if (lpr
->num_inputs
< min_argc
) {
729 xasprintf(errctx
, "%s %u non-option args required, %u given",
730 min_argc
< max_argc
? "at least" : "exactly",
731 min_argc
, lpr
->num_inputs
);
732 return -E_LLS_BAD_ARG_COUNT
;
734 if (lpr
->num_inputs
> max_argc
) {
736 xasprintf(errctx
, "no non-option args allowed, "
737 "%u given", lpr
->num_inputs
);
739 xasprintf(errctx
, "%s %u non-option args allowed, "
740 "%u given", min_argc
< max_argc
?
741 "at most" : "exactly",
742 max_argc
, lpr
->num_inputs
);
743 return -E_LLS_BAD_ARG_COUNT
;
749 * Unlike getopt(3) this implementation can not resume the scan where it left
752 int lls_parse(int argc
, char **argv
, const struct lls_command
*cmd
,
753 struct lls_parse_result
**lprp
, char **errctx
)
755 const struct lls_option
*opts
= cmd
->options
;
756 struct lls_data
*d
= NULL
;
759 struct lls_parse_result
*lpr
;
763 lpr
= calloc(1, sizeof(*lpr
));
765 xasprintf(errctx
, "log parse result");
769 d
= init_lls_data(opts
, argc
, argv
);
771 xasprintf(errctx
, "init_lls_data()");
775 if (cmd
->num_options
== 0) {
777 lpr
->opt_result
= NULL
;
779 lpr
->opt_result
= calloc(cmd
->num_options
,
780 sizeof(*lpr
->opt_result
));
781 if (!lpr
->opt_result
) {
782 xasprintf(errctx
, "option result array for %s",
788 ret
= parse_option(d
, &la
, errctx
);
793 ret
= lls_parse_arg(&la
, opts
, lpr
, errctx
);
798 lpr
->num_inputs
= argc
- la
.idx
- 1;
799 if (!cmd
->non_opts_name
) {
800 ret
= lls_check_arg_count(lpr
, 0, 0, errctx
);
802 /* needed for lls_free_parse_result() */
807 /* We always make a copy of the elements of argv[] */
808 lpr
->inputs
= malloc((lpr
->num_inputs
+ 1) * sizeof(char *));
810 xasprintf(errctx
, "inputs array for %s", cmd
->name
);
814 for (i
= 0; i
< lpr
->num_inputs
; i
++) {
815 char *arg
= argv
[i
+ la
.idx
+ 1];
816 lpr
->inputs
[i
] = strdup(arg
);
819 xasprintf(errctx
, "option #%d (%s) of %s", i
, arg
, cmd
->name
);
823 lpr
->inputs
[lpr
->num_inputs
] = NULL
;
824 /* initialize default values */
825 FOR_EACH_OPTION(i
, opts
) {
826 const struct lls_option
*opt
= opts
+ i
;
827 struct lls_opt_result
*lor
= lpr
->opt_result
+ i
;
828 bool required
= opt
->flags
& LLS_REQUIRED
;
829 bool has_arg
= opt
->arg_info
!= LLS_NO_ARGUMENT
;
831 if (lor
->given
== 0 && required
) {
832 xasprintf(errctx
, "--%s", opt
->name
);
833 ret
= -E_LLS_OPT_MANDATORY
;
841 * allocate space for the default value, even if there is no
842 * default given in the .suite file
844 lor
->value
= malloc(sizeof(*lor
->value
));
846 xasprintf(errctx
, "value array for --%s", opt
->name
);
850 ret
= copy_val(lor
->value
, &opt
->default_val
, opt
, errctx
);
857 check_errctx(errctx
, ret
);
859 lls_free_parse_result(lpr
, cmd
);
866 #define MAX_OPTION_LEN 30
867 #define HELP_INDENT 6
868 static const char space
[MAX_OPTION_LEN
+ 1] = " ";
870 static int short_option_help(const struct lls_option
*opt
, char **result
)
873 char *opt_names
= NULL
;
874 bool overlong
, has_short
= opt
->short_opt
;
878 if (opt
->flags
& LLS_IGNORED
)
879 return xasprintf(result
, "%s", opt
->summary
);
880 if (opt
->arg_info
== LLS_NO_ARGUMENT
)
883 typestr
= opt
->typestr
? opt
->typestr
: "val";
885 ret
= xasprintf(&opt_names
,
890 has_short
? " -" : " ",
891 has_short
? opt
->short_opt
: ' ',
892 has_short
? "," : " ",
894 opt
->arg_info
== LLS_OPTIONAL_ARGUMENT
? "[" : "",
895 opt
->arg_info
== LLS_NO_ARGUMENT
? "" : "=<",
897 opt
->arg_info
== LLS_NO_ARGUMENT
? "" : ">",
898 opt
->arg_info
== LLS_OPTIONAL_ARGUMENT
? "]" : ""
902 overlong
= ret
>= MAX_OPTION_LEN
;
903 ret
= xasprintf(result
,
911 overlong
? space
: space
+ ret
,
912 opt
->summary
? opt
->summary
: ""
918 static int format_default_val(const struct lls_option
*opt
, char **result
)
920 const union lls_val
*val
= &opt
->default_val
;
923 if (opt
->arg_info
== LLS_NO_ARGUMENT
)
925 if (!(opt
->flags
& LLS_HAS_DEFAULT
))
927 switch (opt
->arg_type
) {
931 return xasprintf(result
, "(string, default: %s)",
932 val
->string_val
? val
->string_val
: "[NULL]");
934 return xasprintf(result
, "(int32, default: %" PRId32
")",
937 return xasprintf(result
, "(uint32, default: %" PRIu32
")",
940 return xasprintf(result
, "(int64, default: %" PRId64
")",
943 return xasprintf(result
, "(uint64, default: %" PRIu64
")",
951 static int format_values(const struct lls_option
*opt
, char **result
)
955 const char *val
, *pfx
= "values: ";
956 size_t len
, line_len
;
957 const int indent_len
= 6, max_len
= 75, pfx_len
= 8;
963 assert(opt
->arg_type
== LLS_STRING
);
964 dflt_idx
= opt
->default_val
.uint32_val
;
965 line_len
= indent_len
+ pfx_len
;
967 for (i
= 0; (val
= opt
->values
[i
].string_val
); i
++) {
968 size_t val_len
= strlen(val
);
969 /* comma and space, and [] around default val */
970 int extra_len
= 2 * (i
!= 0) + 2 * (i
== dflt_idx
);
971 bool cr
= line_len
+ val_len
+ extra_len
> max_len
;
973 line_len
= indent_len
+ pfx_len
;
974 len
+= 1 + indent_len
+ pfx_len
; /* +1 for \n */
976 len
+= val_len
+ extra_len
;
977 line_len
+= val_len
+ extra_len
;
979 *result
= malloc(len
+ 1); /* +1 for terminating zero byte */
982 p
= *result
+ sprintf(*result
, "%.*s%s", indent_len
, space
, pfx
);
983 line_len
= p
- *result
;
984 for (i
= 0; (val
= opt
->values
[i
].string_val
); i
++) {
985 size_t val_len
= strlen(val
);
986 int extra_len
= 2 * (i
!= 0) + 2 * (i
== dflt_idx
);
987 bool cr
= line_len
+ val_len
+ extra_len
> max_len
;
995 cr
? pfx_len
+ indent_len
: 0, cr
? space
: "",
996 i
== dflt_idx
? "[" : "", val
, i
== dflt_idx
? "]" : ""
999 line_len
= indent_len
+ pfx_len
;
1000 line_len
+= val_len
+ extra_len
;
1005 static char *create_help_buf(const struct lls_command
*cmd
, bool long_help
)
1007 char *header
, *option_help
, *result
;
1008 const struct lls_option
*opt
;
1010 const char *desc
= (long_help
&& cmd
->description
)?
1011 cmd
->description
: "";
1012 const char *closing
= (long_help
&& cmd
->closing
)? cmd
->closing
: NULL
;
1016 ret
= xasprintf(&header
,
1021 cmd
->name
, cmd
->purpose
,
1022 cmd
->name
, cmd
->synopsis
,
1024 cmd
->options
? "\n" : ""
1031 FOR_EACH_OPTION_IN_COMMAND(opt
, cmd
) {
1032 char *tmp
, *soh
, *loh
= NULL
, *dflt
, *values
;
1033 int indent
= (opt
->flags
& LLS_IGNORED
)? 0 : HELP_INDENT
;
1035 ret
= short_option_help(opt
, &soh
);
1038 if (long_help
&& opt
->help
) {
1040 for (p
= opt
->help
; (q
= strchr(p
, '\n')); p
= q
+ 1) {
1042 ret
= xasprintf(&tmp
, "%s%.*s%.*s",
1043 loh
? loh
: "\n", indent
, space
,
1044 (int)(q
- p
+ 1), p
);
1053 ret
= format_default_val(opt
, &dflt
);
1060 ret
= format_values(opt
, &values
);
1070 ret
= xasprintf(&tmp
,
1076 option_help
? option_help
: "",
1078 dflt
? "\n" : "", dflt
? space
: "", dflt
? dflt
: "",
1079 values
? "\n" : "", values
? values
: "",
1091 ret
= xasprintf(&result
, "%s%s%s%s", header
, option_help
,
1092 closing
? "\n" : "", closing
? closing
: "");
1096 return ret
< 0? NULL
: result
;
1099 char *lls_long_help(const struct lls_command
*cmd
)
1101 return create_help_buf(cmd
, true /* include help */);
1104 char *lls_short_help(const struct lls_command
*cmd
)
1106 return create_help_buf(cmd
, false /* only options */);
1109 static int partial_match(const char *arg
, const char *name
)
1111 size_t arglen
= strlen(arg
);
1113 if (strncmp(arg
, name
, arglen
) != 0)
1114 return 1; /* no match */
1115 if (name
[arglen
] == '\0')
1116 return 0; /* exact match */
1117 return -1; /* partial match */
1120 int lls_lookup_subcmd(const char *string
, const struct lls_suite
*suite
,
1128 xasprintf(errctx
, "nothing to look up");
1129 return -E_LLS_BAD_SUBCMD
;
1131 ret
= 0; /* no match so far */
1132 for (i
= 1; i
<= suite
->num_subcommands
; i
++) {
1133 switch (partial_match(string
, suite
->commands
[i
].name
)) {
1134 case 1: /* no match */
1136 case 0: /* exact match */
1138 case -1: /* partial match */
1140 ret
= -E_LLS_AMBIG_SUBCMD
;
1146 if (ret
> 0) /* unique partial match */
1148 ret
= -E_LLS_BAD_SUBCMD
;
1150 xasprintf(errctx
, "%s", string
);
1154 static size_t get_opt_result_pointer(const struct lls_option
*opt
, int val_num
,
1155 struct lls_opt_result
*lor
, void **result
)
1157 union lls_val
*val
= lor
->value
+ val_num
;
1159 switch (opt
->arg_type
) {
1161 *result
= &val
->int32_val
;
1164 *result
= &val
->uint32_val
;
1167 *result
= &val
->int64_val
;
1170 *result
= &val
->uint64_val
;
1177 /* never fails, returns number of bytes needed/written */
1178 static size_t serialize_parse_result(const struct lls_parse_result
*lpr
,
1179 const struct lls_command
*cmd
, char *result
)
1186 memcpy(result
, &lpr
->num_inputs
, 4);
1190 for (i
= 0; i
< lpr
->num_inputs
; i
++) {
1192 strcpy(result
+ nbytes
, lpr
->inputs
[i
]);
1193 nbytes
+= strlen(lpr
->inputs
[i
]) + 1;
1196 FOR_EACH_OPTION(i
, cmd
->options
) {
1197 const struct lls_option
*opt
= cmd
->options
+ i
;
1198 struct lls_opt_result
*lor
= lpr
->opt_result
+ i
;
1202 memcpy(result
+ nbytes
, &lor
->given
, 4);
1204 if (opt
->arg_info
== LLS_NO_ARGUMENT
)
1206 num_vals
= num_vals_in_parse_result(cmd
, i
, lpr
);
1207 if (opt
->arg_type
== LLS_STRING
&& !opt
->values
) {
1208 for (j
= 0; j
< num_vals
; j
++) {
1210 strcpy(result
+ nbytes
,
1211 lor
->value
[j
].string_val
);
1212 nbytes
+= strlen(lor
->value
[j
].string_val
) + 1;
1215 for (j
= 0; j
< num_vals
; j
++) {
1218 bytes
= get_opt_result_pointer(opt
, j
, lor
, &p
);
1220 memcpy(result
+ nbytes
, p
, bytes
);
1228 int lls_serialize_parse_result(const struct lls_parse_result
*lpr
,
1229 const struct lls_command
*cmd
, char **result
, size_t *nbytes
)
1234 if (!result
|| !*result
) { /* need to compute needed space */
1235 sz
= serialize_parse_result(lpr
, cmd
, NULL
);
1236 if (!result
) { /* just report needed space */
1240 *result
= malloc(sz
);
1248 sz
= serialize_parse_result(lpr
, cmd
, *result
);
1256 int lls_deserialize_parse_result(const char *buf
, const struct lls_command
*cmd
,
1257 struct lls_parse_result
**lprp
)
1260 const char *p
= buf
;
1261 struct lls_parse_result
*lpr
;
1264 lpr
= malloc(sizeof(*lpr
));
1266 return -E_LLS_NOMEM
;
1267 memcpy(&lpr
->num_inputs
, p
, 4);
1269 if (lpr
->num_inputs
> 0) {
1270 lpr
->inputs
= malloc(lpr
->num_inputs
* sizeof(char *));
1275 for (i
= 0; i
< lpr
->num_inputs
; i
++) {
1276 lpr
->inputs
[i
] = strdup(p
);
1277 if (!lpr
->inputs
[i
])
1281 lpr
->opt_result
= malloc(cmd
->num_options
* sizeof(*lpr
->opt_result
));
1282 if (!lpr
->opt_result
)
1284 FOR_EACH_OPTION(i
, cmd
->options
) {
1285 const struct lls_option
*opt
= cmd
->options
+ i
;
1286 struct lls_opt_result
*lor
= lpr
->opt_result
+ i
;
1289 memcpy(&lor
->given
, p
, 4);
1291 if (opt
->arg_info
== LLS_NO_ARGUMENT
)
1293 num_vals
= num_vals_in_parse_result(cmd
, i
, lpr
);
1294 lor
->value
= malloc(num_vals
* sizeof(*lor
->value
));
1297 if (opt
->arg_type
== LLS_STRING
&& !opt
->values
) {
1298 for (j
= 0; j
< num_vals
; j
++) {
1299 lor
->value
[j
].string_val
= strdup(p
);
1300 if (!lor
->value
[j
].string_val
) {
1302 free(lor
->value
[j
].string_val
);
1306 p
+= strlen(lor
->value
[j
].string_val
) + 1;
1309 for (j
= 0; j
< num_vals
; j
++) {
1312 bytes
= get_opt_result_pointer(opt
, j
, lor
, &q
);
1313 memcpy(q
, p
, bytes
);
1321 for (i
--; i
>= 0; i
--) {
1322 const struct lls_option
*opt
= cmd
->options
+ i
;
1323 struct lls_opt_result
*lor
= lpr
->opt_result
+ i
;
1324 unsigned num_vals
= (opt
->flags
& LLS_MULTIPLE
)? lor
->given
: 1;
1325 for (j
= 0; j
< num_vals
; j
++)
1326 if (opt
->arg_type
== LLS_STRING
&& !opt
->values
)
1327 free(lor
->value
[j
].string_val
);
1330 free(lpr
->opt_result
);
1333 free(lpr
->inputs
[i
]);
1337 return -E_LLS_NOMEM
;
1340 static int merge_option(int opt_num
, const struct lls_parse_result
*primary
,
1341 const struct lls_parse_result
*secondary
,
1342 const struct lls_command
*cmd
, struct lls_parse_result
*result
,
1346 const struct lls_option
*opt
= cmd
->options
+ opt_num
;
1347 struct lls_opt_result
*lor1
, *lor2
, *lor
;
1349 lor1
= primary
->opt_result
+ opt_num
;
1350 lor2
= secondary
->opt_result
+ opt_num
;
1351 lor
= result
->opt_result
+ opt_num
;
1352 lor
->given
= lor1
->given
+ lor2
->given
;
1353 if (opt
->arg_info
== LLS_NO_ARGUMENT
)
1355 if (lor
->given
> 0 && (opt
->flags
& LLS_MULTIPLE
)) {
1356 lor
->value
= malloc(lor
->given
* sizeof(*lor
->value
));
1358 xasprintf(errctx
, "value array for option %s", opt
->name
);
1361 for (l
= 0; l
< lor1
->given
; l
++) {
1362 ret
= copy_val(lor
->value
+ l
, lor1
->value
+ l
,
1365 goto free_primary_options
;
1367 for (m
= 0; m
< lor2
->given
; m
++) {
1368 ret
= copy_val(lor
->value
+ l
+ m
, lor2
->value
+ m
,
1371 goto free_secondary_options
;
1375 lor
->value
= malloc(sizeof(*lor
->value
)); /* one value only */
1377 xasprintf(errctx
, "(single) value for option %s", opt
->name
);
1381 ret
= copy_val(lor
->value
, lor1
->value
, opt
, errctx
);
1384 } else if (lor2
->given
) {
1385 ret
= copy_val(lor
->value
, lor2
->value
, opt
, errctx
);
1389 ret
= copy_val(lor
->value
, &opt
->default_val
, opt
, errctx
);
1394 free_secondary_options
:
1395 if (opt
->arg_type
== LLS_STRING
&& !opt
->values
)
1396 for (m
--; m
>= 0; m
--)
1397 free(lor
->value
[l
+ m
].string_val
);
1398 free_primary_options
:
1399 if (opt
->arg_type
== LLS_STRING
&& !opt
->values
)
1400 for (l
--; l
>= 0; l
--)
1401 free(lor
->value
[l
].string_val
);
1405 return -E_LLS_NOMEM
;
1408 int lls_merge(const struct lls_parse_result
*primary
,
1409 const struct lls_parse_result
*secondary
,
1410 const struct lls_command
*cmd
, struct lls_parse_result
**lprp
,
1414 unsigned num
= primary
->num_inputs
+ secondary
->num_inputs
;
1415 struct lls_parse_result
*result
;
1419 result
= malloc(sizeof(*result
));
1422 xasprintf(errctx
, "parse result");
1425 result
->inputs
= malloc((num
+ 1) * sizeof(char *));
1426 if (!result
->inputs
) {
1428 xasprintf(errctx
, "inputs array of size %u", num
);
1429 goto free_parse_result
;
1431 for (i
= 0; i
< primary
->num_inputs
; i
++) {
1432 result
->inputs
[i
] = strdup(primary
->inputs
[i
]);
1433 if (!result
->inputs
[i
]) {
1435 xasprintf(errctx
, "primary input #%d", i
);
1436 goto free_primary_inputs
;
1439 for (j
= 0; j
< secondary
->num_inputs
; j
++) {
1440 result
->inputs
[i
+ j
] = strdup(secondary
->inputs
[j
]);
1441 if (!result
->inputs
[i
+ j
]) {
1443 xasprintf(errctx
, "secondary input #%d", i
);
1444 goto free_secondary_inputs
;
1447 result
->inputs
[i
+ j
] = NULL
;
1448 result
->opt_result
= malloc(cmd
->num_options
1449 * sizeof(*result
->opt_result
));
1450 if (!result
->opt_result
)
1451 goto free_secondary_inputs
;
1452 FOR_EACH_OPTION(k
, cmd
->options
) {
1453 ret
= merge_option(k
, primary
, secondary
, cmd
, result
, errctx
);
1455 goto free_opt_results
;
1457 result
->num_inputs
= num
;
1462 for (k
--; k
>= 0; k
--)
1463 free_opt_result(k
, result
, cmd
);
1464 free_secondary_inputs
:
1465 for (j
--; j
>= 0; j
--)
1466 free(result
->inputs
[i
+ j
]);
1467 free_primary_inputs
:
1468 for (i
--; i
>= 0; i
--)
1469 free(result
->inputs
[i
]);
1470 free(result
->inputs
);
1477 check_errctx(errctx
, ret
);
1481 static bool is_default_val(const union lls_val
*val
,
1482 const struct lls_option
*opt
)
1484 bool has_default
= opt
->flags
& LLS_HAS_DEFAULT
;
1485 bool has_arg
= opt
->arg_info
!= LLS_NO_ARGUMENT
;
1486 const union lls_val
*dflt
;
1492 dflt
= &opt
->default_val
;
1493 switch (opt
->arg_type
) {
1495 return val
->int32_val
== dflt
->int32_val
;
1497 return val
->uint32_val
== dflt
->uint32_val
;
1499 return val
->int64_val
== dflt
->int64_val
;
1501 return val
->uint64_val
== dflt
->uint64_val
;
1504 const char *s1
, *s2
;
1507 return val
->uint32_val
== dflt
->uint32_val
;
1508 s1
= val
->string_val
;
1509 s2
= dflt
->string_val
;
1514 return !strcmp(s1
, s2
);
1521 static char *append_opt_val(const union lls_val
*val
,
1522 const struct lls_option
*opt
, char *result
)
1524 char *line
= NULL
, *tmp
= NULL
;
1526 switch (opt
->arg_type
) {
1528 xasprintf(&line
, "%" PRId32
, val
->int32_val
);
1531 xasprintf(&line
, "%" PRIu32
, val
->uint32_val
);
1534 xasprintf(&line
, "%" PRId64
, val
->int64_val
);
1537 xasprintf(&line
, "%" PRIu64
, val
->uint64_val
);
1545 s
= lls_enum_string_val(val
->uint32_val
, opt
);
1547 s
= val
->string_val
;
1551 line
= malloc(2 * strlen(s
) + 3);
1557 for (p
= s
, q
= line
+ 1; *p
; p
++, q
++) {
1558 if (*p
== '\\' || *p
== '\n' || *p
== '\t' || *p
== '"') {
1571 xasprintf(&tmp
, "%s%s=%s\n", result
? result
: "", opt
->name
, line
);
1577 char *lls_dump_parse_result(const struct lls_parse_result
*lpr
,
1578 const struct lls_command
*cmd
, bool non_default_only
)
1581 char *result
= NULL
;
1583 FOR_EACH_OPTION(i
, cmd
->options
) {
1584 const struct lls_option
*opt
= cmd
->options
+ i
;
1585 struct lls_opt_result
*lor
= lpr
->opt_result
+ i
;
1586 bool given
= lor
->given
;
1589 if (!given
&& non_default_only
)
1591 if (opt
->arg_info
== LLS_NO_ARGUMENT
) {
1595 xasprintf(&tmp
, "%s%s\n", result
? result
: "",
1601 n
= num_vals_in_parse_result(cmd
, i
, lpr
);
1602 for (j
= 0; j
< n
; j
++) {
1603 union lls_val
*val
= lor
->value
+ j
;
1604 if (non_default_only
&& is_default_val(val
, opt
))
1606 result
= append_opt_val(val
, opt
, result
);
1609 if (!result
) { /* empty dump */