From c6d7fb8dd0157e608a1d12048b4891459f02b85d Mon Sep 17 00:00:00 2001
From: Jonathan Rubenstein <jrubcop@gmail.com>
Date: Wed, 5 May 2021 14:10:46 -0400
Subject: [PATCH] [common] option: Reformat help and support rST tables Corners
 of table have '+' added, and adds new command line flag --rst-help, which
 adds some extra formatting to the make it an rST compliant table for the
 in-line docs.

---
 common/include/common/option.h |  7 +++++
 common/src/option.c            | 56 ++++++++++++++++++++++------------
 2 files changed, 44 insertions(+), 19 deletions(-)

diff --git a/common/include/common/option.h b/common/include/common/option.h
index 9ea192ee..43b89b71 100644
--- a/common/include/common/option.h
+++ b/common/include/common/option.h
@@ -32,6 +32,13 @@ enum OptionType
   OPTION_TYPE_CUSTOM
 };
 
+enum doHelpMode
+{
+  DOHELP_MODE_NO = 0,
+  DOHELP_MODE_YES,
+  DOHELP_MODE_RST
+};
+
 struct Option;
 
 struct Option
diff --git a/common/src/option.c b/common/src/option.c
index 3449d480..37d37060 100644
--- a/common/src/option.c
+++ b/common/src/option.c
@@ -37,7 +37,7 @@ struct OptionGroup
 
 struct State
 {
-  bool                 doHelp;
+  enum doHelpMode      doHelp;
   struct Option     ** options;
   int                  oCount;
   struct OptionGroup * groups;
@@ -46,7 +46,7 @@ struct State
 
 static struct State state =
 {
-  .doHelp  = false,
+  .doHelp  = DOHELP_MODE_NO,
   .options = NULL,
   .oCount  = 0,
   .groups  = NULL,
@@ -258,7 +258,13 @@ bool option_parse(int argc, char * argv[])
     {
       if (strcmp(argv[a], "-h") == 0 || strcmp(argv[a], "--help") == 0)
       {
-        state.doHelp = true;
+        state.doHelp = DOHELP_MODE_YES;
+        continue;
+      }
+
+      if (strcmp(argv[a], "--rst-help") == 0)
+      {
+        state.doHelp = DOHELP_MODE_RST;
         continue;
       }
 
@@ -528,7 +534,7 @@ exit:
 
 bool option_validate(void)
 {
-  if (state.doHelp)
+  if (state.doHelp != DOHELP_MODE_NO)
   {
     option_print();
     return false;
@@ -577,6 +583,24 @@ bool option_validate(void)
   return ok;
 }
 
+void option_print_hrule(char * headerLine, int maxLen, char ruleChar)
+{
+  printf("  +%c", ruleChar);
+  for (int i = 0; i < maxLen; i++)
+  {
+    if(i < strlen(headerLine))
+    {
+      if (headerLine[i] == '|')
+      {
+        putc('+', stdout);
+        continue;
+      }
+    }
+    putc(ruleChar, stdout);
+  }
+  printf("%c+\n", ruleChar);
+}
+
 void option_print(void)
 {
   printf(
@@ -591,6 +615,7 @@ void option_print(void)
     int maxLen;
     int valueLen = 5;
     char * line;
+    char * headerLine;
 
     // ensure the pad length is atleast as wide as the heading
     if (state.groups[g].pad < 4)
@@ -626,6 +651,7 @@ void option_print(void)
     );
 
     assert(maxLen > 0);
+    headerLine = line;
     stringlist_push(lines, line);
 
     for(int i = 0; i < state.groups[g].count; ++i)
@@ -659,11 +685,7 @@ void option_print(void)
     {
       if (i == 0)
       {
-        // print a horizontal rule
-        printf("  |");
-        for(int i = 0; i < maxLen + 2; ++i)
-          putc('-', stdout);
-        printf("|\n");
+        option_print_hrule(headerLine, maxLen, '-');
       }
 
       char * line = stringlist_at(lines, i);
@@ -671,19 +693,15 @@ void option_print(void)
 
       if (i == 0)
       {
-        // print a horizontal rule
-        printf("  |");
-        for(int i = 0; i < maxLen + 2; ++i)
-          putc('-', stdout);
-        printf("|\n");
+        option_print_hrule(headerLine, maxLen, state.doHelp == DOHELP_MODE_RST ? '=' : '-');
+      }
+      else if (state.doHelp == DOHELP_MODE_RST && i < stringlist_count(lines) - 1)
+      {
+        option_print_hrule(headerLine, maxLen, '-');
       }
     }
 
-    // print a horizontal rule
-    printf("  |");
-    for(int i = 0; i < maxLen + 2; ++i)
-      putc('-', stdout);
-    printf("|\n");
+    option_print_hrule(headerLine, maxLen, '-');
 
     stringlist_free(&lines);