help-gengetopt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[help-gengetopt] extension to gengetopt


From: Matt Junker
Subject: [help-gengetopt] extension to gengetopt
Date: Fri, 15 Feb 2002 09:55:06 -0600

I often wish to have lines of text (such as headings or further explanation)
between listed options when I use the --help option of a program.  I used to
do this by putting newlines and tabs in the GGO help text.  This was very
ugly.

The following patch extends GGO to allow text to be inserted in an easier
way.  I suggest adding this or something like it to getgetopt.

To insert text, put

#text "text to insert"

in your GGO file, then you get the quoted text in your --help listing at the
same position as it is in the GGO file.

Future extensions would be (1) interpreting the tab character as an
instruction to make the text line up with the option descriptions and (2)
automatically wrapping the text lines.  These are low on my priority list.

I used the # prefix to keep compatibility with old versions of GGO, but the
format could be changed by modifying one line in scanner.l (see the 4th line
from the bottom of the patch).

For some reason, the "-l" option is required for this patch to work.  The
patch was made ignoring white space, so indentation would have to be fixed
before releasing this.

I have also written a very crude GGO to man page converter by modifying the
parser and scanner and allowing verbatim copying of specially flagged lines.
It is currently a separate program, but with some effort someone could
incorporate it directly into GGO (doesn't seem worth the effort to me).  Let
me know if there is any interest.

Matt

---

diff -C3 -w -xparser.c -xscanner.c -xparser.h gengetopt-2.5/src/argsdef.c
gengetopt-2.5-mj/src/argsdef.c
*** gengetopt-2.5/src/argsdef.c Mon May 14 14:41:34 2001
--- gengetopt-2.5-mj/src/argsdef.c Wed Jan 30 07:51:12 2002
***************
*** 19,25 ****
   */


! char * arg_names [] = { (char*)0, (char*)0, "STRING", "INT", "SHORT",
"LONG", "FLOAT", "DOUBLE", "LONGDOUBLE", "LONGLONG" };

! char * arg_types [] = { (char*)0, "int", "char *", "int", "short", "long",
"float", "double", "long double", "long long" };

--- 19,25 ----
   */


! char * arg_names [] = { (char*)0, (char*)0, "STRING", "INT", "SHORT",
"LONG", "FLOAT", "DOUBLE", "LONGDOUBLE", "LONGLONG", "TEXT" };

! char * arg_types [] = { (char*)0, "int", "char *", "int", "short", "long",
"float", "double", "long double", "long long", "text" };

diff -C3 -w -xparser.c -xscanner.c -xparser.h gengetopt-2.5/src/argsdef.h
gengetopt-2.5-mj/src/argsdef.h
*** gengetopt-2.5/src/argsdef.h Mon May 14 14:41:34 2001
--- gengetopt-2.5-mj/src/argsdef.h Wed Jan 30 07:50:42 2002
***************
*** 31,36 ****
--- 31,37 ----
  #define ARG_DOUBLE 7
  #define ARG_LONGDOUBLE 8
  #define ARG_LONGLONG 9
+ #define ARG_TEXT 10

  extern char * arg_names [];
  extern char * arg_types [];
diff -C3 -w -xparser.c -xscanner.c -xparser.h gengetopt-2.5/src/gengetopt.c
gengetopt-2.5-mj/src/gengetopt.c
*** gengetopt-2.5/src/gengetopt.c Mon May 14 14:41:34 2001
--- gengetopt-2.5-mj/src/gengetopt.c Wed Jan 30 08:15:09 2002
***************
*** 217,222 ****
--- 217,224 ----
  {
   struct gengetopt_option * n;

+    if ( type != ARG_TEXT )
+    {
        if (long_opt == NULL || long_opt[0] == 0 ||
            desc == NULL || desc[0] == 0)
           return 4;
***************
*** 229,234 ****
--- 231,237 ----
               && n->short_opt == short_opt)
              return 3;
        }
+    }

   n = malloc (sizeof (struct gengetopt_option));
   if (n == NULL) return 1;
diff -C3 -w -xparser.c -xscanner.c -xparser.h gengetopt-2.5/src/gm.c
gengetopt-2.5-mj/src/gm.c
*** gengetopt-2.5/src/gm.c Mon Dec 17 15:28:02 2001
--- gengetopt-2.5-mj/src/gm.c Wed Jan 30 13:30:54 2002
***************
*** 150,155 ****
--- 150,157 ----
    printf ("%s->%s_arg = (long long)atol (optarg);\n",
      ARGS_STRUCT, opt->var_arg);
    break;
+   case ARG_TEXT:
+   break;
    default:
    fprintf (stderr, "gengetopt: bug found in %s:%d\n", __FILE__,
       __LINE__);
***************
*** 250,255 ****
--- 252,259 ----
    foropt
    if (opt->type != ARG_NO) {
    switch (opt->type) {
+   case ARG_TEXT:
+     continue;
    case ARG_FLAG:
    case ARG_STRING:
    case ARG_INT:
***************
*** 267,272 ****
--- 271,278 ----
      abort ();
    }

+   if (opt->type != ARG_TEXT)
+     {
      if (opt->type == ARG_FLAG)
      printf ("%s_flag", opt->var_arg);
      else
***************
*** 282,293 ****
--- 288,302 ----
      }
      printf (".  */\n");
      }
+   }

    printf ("\n");

    foropt
    if (opt->type != ARG_NO) {
    switch (opt->type) {
+   case ARG_TEXT:
+     continue;
    case ARG_FLAG:
    case ARG_STRING:
    case ARG_INT:
***************
*** 426,431 ****
--- 435,442 ----
    foropt
      if (opt->required) /* required options */
      switch (opt->type) {
+     case ARG_TEXT:
+     break;
      case ARG_INT:
      case ARG_SHORT:
      case ARG_LONG:
***************
*** 447,452 ****
--- 458,465 ----
    foropt
      if (!opt->required)
      switch (opt->type) {
+     case ARG_TEXT:
+     break;
      case ARG_NO:
      case ARG_FLAG:
      printf ("[");
***************
*** 485,490 ****
--- 498,507 ----
    /* calculate columns */
    max_long = max_short = 0;
    foropt {
+   if (opt->type == ARG_TEXT )
+   {
+     continue;
+   }
    w = 3 + strlen (opt->long_opt);
    if (opt->type == ARG_FLAG || opt->type == ARG_NO)
    {
***************
*** 503,509 ****
    foropt
    {
      printf ("  printf(\"");
!     if (opt->type == ARG_FLAG || opt->type == ARG_NO)
      {
        if (opt->short_opt) printf ("   -%c", opt->short_opt);
        else                printf ("     ");
--- 520,530 ----
    foropt
    {
    printf ("  printf(\"");
!   if (opt->type == ARG_TEXT )
!     {
!     printf ("%s\\n\");\n", opt->desc);
!     }
!   else if (opt->type == ARG_FLAG || opt->type == ARG_NO)
      {
      if (opt->short_opt) printf ("   -%c", opt->short_opt);
      else      printf ("     ");
***************
*** 572,577 ****
--- 593,602 ----
    /* now we initialize "given" fields */
    foropt
    {
+   if (opt->type == ARG_TEXT)
+     {
+     continue;
+     }
    indent ();
    printf ("%s->%s_given = 0 ;\n",
        ARGS_STRUCT, opt->var_arg);
***************
*** 640,645 ****
--- 665,674 ----

    foropt
    {
+   if (opt->type == ARG_TEXT )
+     {
+     continue;
+     }
    indent ();
    printf ("{ \"%s\",\t%d, NULL, ", opt->long_opt,
        (opt->type == ARG_NO || opt->type == ARG_FLAG ? 0 : 1));
***************
*** 659,667 ****
--- 688,702 ----
    printf ("c = getopt_long (argc, argv, \"");

    foropt
+   {
+   if (opt->type == ARG_TEXT )
+     {
+     continue;
+     }
    if (opt->short_opt)
      printf ("%c%s", opt->short_opt,
        (opt->type == ARG_NO || opt->type == ARG_FLAG ? "" : ":"));
+   }

    printf ("\", long_options, &option_index);\n\n");

***************
*** 712,717 ****
--- 747,755 ----


    foropt {
+   if (opt->type == ARG_TEXT) {
+   continue;
+   }
    if (
      (opt->short_opt == 'h' && ! no_handle_help) ||
      (opt->short_opt == 'V' && ! no_handle_version)
***************
*** 742,748 ****
    printf ("case 0:\t/* Long option with no short option */\n");
    inc_indent();
    foropt
!       if (!opt->short_opt)
        {
            indent();
            printf ("/* %s.  */\n", opt->desc);
--- 780,786 ----
    printf ("case 0:\t/* Long option with no short option */\n");
       inc_indent();
       foropt
!      if (!opt->short_opt && opt->type != ARG_TEXT)
         {
         indent();
         printf ("/* %s. */\n", opt->desc);
diff -C3 -w -xparser.c -xscanner.c -xparser.h gengetopt-2.5/src/parser.y
gengetopt-2.5-mj/src/parser.y
*** gengetopt-2.5/src/parser.y Mon May 14 14:41:34 2001
--- gengetopt-2.5-mj/src/parser.y Wed Jan 30 08:12:00 2002
***************
*** 55,60 ****
--- 55,61 ----
  %token           TOK_NO
  %token           TOK_FLAG
  %token           TOK_PURPOSE
+ %token           TOK_TEXT
  %token <bool>    TOK_ONOFF
  %token <str>     TOK_STRING
  %token <str>     TOK_MLSTRING
***************
*** 90,95 ****
--- 91,98 ----
  ;


+
+
  exp: TOK_PACKAGE TOK_STRING { if (gengetopt_package_given) { yyerror
("package redefined"); YYERROR; } else { gengetopt_package_given = 1; if
(gengetopt_define_package ($2)) { yyerror ("not enough memory");
YYERROR; } } }
  ;

***************
*** 102,107 ****
--- 105,114 ----

  exp: TOK_PURPOSE exp_str { if (gengetopt_purpose_given) { yyerror
("purpose redefined"); YYERROR; } else { gengetopt_purpose_given = 1; if
(gengetopt_define_purpose ($2)) { yyerror ("not enough memory");
YYERROR; } } }
  ;
+
+ exp: TOK_TEXT exp_str { int o = gengetopt_add_option ("", 0, $2, ARG_TEXT,
0, 0); check_result;}
+ ;
+
  exp: TOK_OPTION TOK_STRING TOK_CHAR exp_str TOK_NO { int o =
gengetopt_add_option ($2, $3, $4, ARG_NO, 0, 0); check_result; }
  ;

diff -C3 -w -xparser.c -xscanner.c -xparser.h gengetopt-2.5/src/scanner.l
gengetopt-2.5-mj/src/scanner.l
*** gengetopt-2.5/src/scanner.l Sun Jun 24 07:25:48 2001
--- gengetopt-2.5-mj/src/scanner.l Wed Jan 30 12:09:40 2002
***************
*** 28,33 ****
--- 28,34 ----

  %%

+ #[Tt][Ee][Xx][Tt]/.*                       return TOK_TEXT;
  [Pp][Aa][Cc][Kk][Aa][Gg][Ee]     return TOK_PACKAGE;
  [Vv][Ee][Rr][Ss][Ii][Oo][Nn]     return TOK_VERSION;
  [Oo][Pp][Tt][Ii][Oo][Nn]     return TOK_OPTION;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]