Add option grouping capability to apps
authorJon Spillett <jon.spillett@oracle.com>
Thu, 19 Sep 2019 11:14:21 +0000 (21:14 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Thu, 19 Sep 2019 11:14:21 +0000 (21:14 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9920)

apps/include/opt.h
apps/lib/opt.c

index 81faf70..92a7fd1 100644 (file)
  */
 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, ...);
index c2a5878..44d2570 100644 (file)
@@ -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);
     }
 }