From 4ed838915be263b3ebf847b6ada2ab2d3debec4c Mon Sep 17 00:00:00 2001 From: Jon Spillett Date: Thu, 19 Sep 2019 21:14:21 +1000 Subject: [PATCH] Add option grouping capability to apps Reviewed-by: Richard Levitte Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/9920) --- apps/include/opt.h | 5 ++++ apps/lib/opt.c | 72 +++++++++++++++++++++++++++------------------- 2 files changed, 47 insertions(+), 30 deletions(-) diff --git a/apps/include/opt.h b/apps/include/opt.h index 81faf7057d..92a7fd1d82 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -266,6 +266,7 @@ */ extern const char OPT_HELP_STR[]; extern const char OPT_MORE_STR[]; +extern const char OPT_SECTION_STR[]; typedef struct options_st { const char *name; int retval; @@ -307,6 +308,9 @@ typedef struct string_int_pair_st { OPT_FMT_ENGINE | OPT_FMT_MSBLOB | OPT_FMT_NSS | \ OPT_FMT_TEXT | OPT_FMT_HTTP | OPT_FMT_PVK) +/* Divide options into sections when displaying usage */ +#define OPT_SECTION(sec) {OPT_SECTION_STR, 1, '-', sec " options:\n"} + char *opt_progname(const char *argv0); char *opt_getprog(void); char *opt_init(int ac, char **av, const OPTIONS * o); @@ -338,6 +342,7 @@ int opt_num_rest(void); int opt_verify(int i, X509_VERIFY_PARAM *vpm); int opt_rand(int i); void opt_help(const OPTIONS * list); +void opt_print(const OPTIONS * opt, int width); int opt_format_error(const char *s, unsigned long flags); int opt_isdir(const char *name); int opt_printf_stderr(const char *fmt, ...); diff --git a/apps/lib/opt.c b/apps/lib/opt.c index c2a5878ef6..44d2570ae7 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -28,6 +28,7 @@ #define MAX_OPT_HELP_WIDTH 30 const char OPT_HELP_STR[] = "--"; const char OPT_MORE_STR[] = "---"; +const char OPT_SECTION_STR[] = "----"; /* Our state */ static char **argv; @@ -133,7 +134,8 @@ char *opt_init(int ac, char **av, const OPTIONS *o) int duplicated, i; #endif - if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR) + if (o->name == OPT_HELP_STR || o->name == OPT_MORE_STR || + o->name == OPT_SECTION_STR) continue; #ifndef NDEBUG i = o->valtype; @@ -832,40 +834,16 @@ static const char *valtype2param(const OPTIONS *o) return "parm"; } -void opt_help(const OPTIONS *list) +void opt_print(const OPTIONS *o, int width) { - const OPTIONS *o; - int i; - int standard_prolog; - int width = 5; + const char* help; char start[80 + 1]; char *p; - const char *help; - - /* Starts with its own help message? */ - standard_prolog = list[0].name != OPT_HELP_STR; - - /* Find the widest help. */ - for (o = list; o->name; o++) { - if (o->name == OPT_MORE_STR) - continue; - i = 2 + (int)strlen(o->name); - if (o->valtype != '-') - i += 1 + strlen(valtype2param(o)); - if (i < MAX_OPT_HELP_WIDTH && i > width) - width = i; - OPENSSL_assert(i < (int)sizeof(start)); - } - - if (standard_prolog) - opt_printf_stderr("Usage: %s [options]\nValid options are:\n", prog); - /* Now let's print. */ - for (o = list; o->name; o++) { help = o->helpstr ? o->helpstr : "(No additional info)"; - if (o->name == OPT_HELP_STR) { + if (o->name == OPT_HELP_STR || o->name == OPT_SECTION_STR) { opt_printf_stderr(help, prog); - continue; + return; } /* Pad out prefix */ @@ -876,7 +854,7 @@ void opt_help(const OPTIONS *list) /* Continuation of previous line; pad and print. */ start[width] = '\0'; opt_printf_stderr("%s %s\n", start, help); - continue; + return; } /* Build up the "-flag [param]" part. */ @@ -899,6 +877,40 @@ void opt_help(const OPTIONS *list) } start[width] = '\0'; opt_printf_stderr("%s %s\n", start, help); +} + +void opt_help(const OPTIONS *list) +{ + const OPTIONS *o; + int i; + int standard_prolog; + int width = 5; + char start[80 + 1]; + + /* Starts with its own help message? */ + standard_prolog = list[0].name != OPT_HELP_STR; + + /* Find the widest help. */ + for (o = list; o->name; o++) { + if (o->name == OPT_MORE_STR) + continue; + i = 2 + (int)strlen(o->name); + if (o->valtype != '-') + i += 1 + strlen(valtype2param(o)); + if (i < MAX_OPT_HELP_WIDTH && i > width) + width = i; + OPENSSL_assert(i < (int)sizeof(start)); + } + + if (standard_prolog) { + opt_printf_stderr("Usage: %s [options]\n", prog); + if (list[0].name != OPT_SECTION_STR) + opt_printf_stderr("Valid options are:\n", prog); + } + + /* Now let's print. */ + for (o = list; o->name; o++) { + opt_print(o, width); } } -- 2.39.2