home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume29 / parseargs / part04 / unix_man.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-19  |  8.7 KB  |  323 lines

  1. /*************************************************************************
  2. ** ^FILE: unix_man.c - print manual templates for user command
  3. **
  4. ** ^DESCRIPTION:
  5. **    This file is the portion of parseargs(1) that prints a Unix
  6. **    manual template of a given command on the standard output.
  7. **    The template is formatted for {n|t}roff using the -man macros.
  8. **
  9. ** ^HISTORY:
  10. **    27/08/91     Earl Chew     <cechew@bruce.cs.monash.edu.au>
  11. **    - Use ProgNameLen when accessing ProgName
  12. **    - Use get_argpfx() to access names
  13. **
  14. **    01/02/91     Brad Appleton     <brad@ssd.csd.harris.com>     Created
  15. ***^^**********************************************************************/
  16.  
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <useful.h>
  20. #include "strfuncs.h"
  21.  
  22. #define PARSEARGS_PRIVATE   /* include private definitions */
  23. #include "parseargs.h"
  24.  
  25. EXTERN  VOID  syserr  ARGS((const char *, ...));
  26. EXTERN  VOID  usrerr  ARGS((const char *, ...));
  27.  
  28. #define MAXCOLS  65
  29. #define VAL(str)           ((str) ? str : "")
  30. #define COMMENT            printf(".\\\"-----------------------------------\n")
  31. #define TH(title,len,section)  printf(".TH %.*s %d\n", len, title, section )
  32. #define SH(title)          printf(".SH %s\n", title )
  33. #define TP(cols,title)     printf(".TP %d\n%s\n", cols, title )
  34. #define PP                 printf(".PP\n" )
  35.  
  36.  
  37. /***************************************************************************
  38. ** ^FUNCTION: fmtarg - format command-argument syntax
  39. **
  40. ** ^SYNOPSIS:
  41. */
  42. #ifndef __ANSI_C__
  43.    static int fmtarg( ad, buf )
  44. /*
  45. ** ^PARAMETERS:
  46. */
  47.    ARGDESC *ad;
  48. /*    -- pointer to the argument to format
  49. */
  50.    char *buf;
  51. /*    -- character buffer to hold the formatted result
  52. */
  53. #endif  /* !__ANSI_C__ */
  54.  
  55. /* ^DESCRIPTION:
  56. **    Fmtarg will determine the proper command-line syntax for the
  57. **    given argument and write the result to the given buffer.
  58. **
  59. ** ^REQUIREMENTS:
  60. **    buf must be large enough to hold the formatted result (100 characters
  61. **    should do the trick).
  62. **
  63. ** ^SIDE-EFFECTS:
  64. **    buf is overwritten.
  65. **
  66. ** ^RETURN-VALUE:
  67. **    The number of printable characters in the argument-syntax-string
  68. **
  69. ** ^ALGORITHM:
  70. **    Print argument usage based on whether or not the argument is
  71. **    positional, hidden, multi-valued (list or vector), etc ....
  72. **    Optional arguments and values are enclosed in square braces.
  73. ***^^**********************************************************************/
  74. #ifdef __ANSI_C__
  75.    static int fmtarg( const ARGDESC *ad , char *buf )
  76. #endif
  77. {
  78.       /* buf must already be large enough */
  79.    char *pos;
  80.    argName_t   name;
  81.  
  82.    (VOID) get_argname( arg_sname(ad), name );
  83.  
  84.    if (ARG_isPOSITIONAL(ad)) {
  85.        if ( ARG_isMULTIVAL(ad) ) {
  86.           sprintf( buf, "\\fI%s\\fP\\ ...", name );
  87.           return   (strlen(name) + 4);
  88.        }/*if list*/
  89.  
  90.        sprintf( buf, "\\fI%s\\fP", name );
  91.        return  strlen(name);
  92.    }/*if parm*/
  93.  
  94. #ifdef SVR4
  95.    sprintf(buf, "\\f4\\-%c\\fP", arg_cname(ad));
  96. #else
  97.    sprintf(buf, "\\fB\\-%c\\fP", arg_cname(ad));
  98. #endif
  99.    pos = buf + strlen(buf);
  100.  
  101.    if ( ARG_isVALTAKEN(ad)  &&  !ARG_isBOOLEAN(ad)  &&  !ARG_isPSEUDOARG(ad) ) {
  102.        if ( ARG_isMULTIVAL(ad) ) {
  103.           if ( ARG_isVALOPTIONAL(ad) ) {
  104.              sprintf(pos, "\\ \\s-1[\\s+1\\fI%s\\fP\\ ...\\s-1]\\s+1", name);
  105.              return  (strlen(name) + 9);
  106.           }/*if optarg*/
  107.  
  108.           sprintf( pos, "\\ \\fI%s\\ ...\\fP", name );
  109.           return  (strlen(name) + 7);
  110.        }/*if list*/
  111.  
  112.        if ( ARG_isVALOPTIONAL(ad) ) {
  113.           sprintf( pos, "\\ \\s-1[\\s+1\\fI%s\\fP\\s-1]\\s+1", name );
  114.           return  (strlen(name) + 5);
  115.        }/*if optarg*/
  116.  
  117.        sprintf( pos, "\\ \\fI%s\\fP", name );
  118.        return  (strlen(name) + 3);
  119.    }/*if*/
  120.  
  121.    return  2;
  122. }
  123.  
  124.  
  125. /***************************************************************************
  126. ** ^FUNCTION: manpage - print the manual template
  127. **
  128. ** ^SYNOPSIS:
  129. */
  130. #ifndef __ANSI_C__
  131.    VOID manpage ( argd )
  132. /*
  133. ** ^PARAMETERS:
  134. */
  135.    ARGDESC *argd;
  136. /*    -- the command-argdesc-array
  137. */
  138. #endif  /* !__ANSI_C__ */
  139.  
  140. /* ^DESCRIPTION:
  141. **    Manpage print on standard output, a Unix manual template for the
  142. **    given command. The NAME, SYNOPSIS, and OPTIONS sections are filled
  143. **    in and the DESCRIPTION section is partially filled in with any
  144. **    known command-description. The FILES, SEE ALSO, DIAGNOSTICS, CAVEATS,
  145. **    BUGS, AUTHOR, and HISTORY section titles are provided but the body
  146. **    of each section must be composed by the documentor.
  147. **
  148. ** ^REQUIREMENTS:
  149. **    Argd should be a valid command-line descriptor array.
  150. **
  151. ** ^SIDE-EFFECTS:
  152. **    Prints on standard-output.
  153. **
  154. ** ^RETURN-VALUE:
  155. **    None.
  156. **
  157. ** ^ALGORITHM:
  158. **    - print .TH setting followed by NAME section.
  159. **    - cycle through each argument and print is syntax for the SYNOPSIS.
  160. **    - print the description (if it exists).
  161. **    - cycle through each argument again and print its syntax and description
  162. **      for the OPTIONS section.
  163. **    - print just the headings for the remaining sections.
  164. ***^^**********************************************************************/
  165. #ifdef __ANSI_C__
  166.    void manpage( const ARGDESC *argd )
  167. #endif
  168. {
  169.    register CONST ARGDESC *ad, *args, *cmd;
  170.    argName_t  name;
  171.    CONST char *program, *purpose, *description;
  172.    int   len, maxlen, positionals, namelen, programlen, purposelen;
  173.  
  174.       /* allow null argument descriptor */
  175.    if ( !argd )  return;
  176.  
  177.    if ( !CMD_isINIT(argd) )   init_args( (ARGDESC *)argd );
  178.    cmd = argd;
  179.  
  180.    name[0] = 0;
  181.    namelen = 0;
  182.    if ( cmd_name(cmd) ) {
  183.       (VOID) strcpy( name, cmd_name(cmd) );
  184.       if ( !BTEST(cmd_state(cmd), ps_USERNAME|ps_FREENAME) ) {
  185.          namelen = get_argpfx( name );
  186.          name[namelen] = 0;
  187.       }
  188.       else {
  189.          namelen = strlen( cmd_name(cmd) );
  190.       }
  191.    }
  192.  
  193.    program = 0;
  194.    programlen = 0;
  195.    if ( cmd_name(cmd) ) {
  196.       program = cmd_name(cmd);
  197.       programlen = namelen;
  198.    }
  199.    else if ( cmd_argv0(cmd) ) {
  200.       program = cmd_argv0(cmd);
  201.       programlen = strlen(program);
  202.    }
  203.  
  204.    purpose = cmd_purpose(cmd);
  205.    if ( !BTEST(cmd_state(cmd), ps_USERPURPOSE|ps_FREEPURPOSE) && purpose ) {
  206.       purpose = get_argdesc(purpose, &purposelen);
  207.    }
  208.    else {
  209.      purposelen = strlen(VAL(purpose));
  210.    }
  211.    description = cmd_description(cmd);
  212.  
  213.    printf(".\\\"---------- TO PRINT, USE: {n,t}roff -man file ----------\n");
  214.    printf(".if n .po 1\n");
  215.    printf(".if n .ll 78\n");
  216.  
  217.    COMMENT;
  218. #ifdef SVR4
  219.    TH( name, namelen, 1 );
  220. #else
  221.    TH( strupr(name), namelen, 1 );
  222. #endif
  223.  
  224.    COMMENT;
  225.    SH( "NAME" );
  226.    printf( "%s \\- %.*s\n", VAL(program), purposelen, VAL(purpose) );
  227.  
  228.    COMMENT;
  229.    SH( "SYNOPSIS" );
  230.  
  231.    len = strlen( program ) + 1;
  232. #ifdef SVR4
  233.    sprintf( name, "\\f4%.*s\\fP", programlen, program );
  234. #else
  235.    sprintf( name, "\\fB%.*s\\fP", programlen, program );
  236. #endif
  237.    TP( len, name );
  238.  
  239.    maxlen = 0;
  240.    for ( positionals = 0 ; positionals < 2 ; positionals++ ) {
  241.      for ( args = argd ; args ; args = cmd_defargs(args) ) {
  242.         for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  243.            argName_t  buf;
  244.  
  245.               /* don't display hidden arguments */
  246.            if ( ARG_isHIDDEN(ad) )  continue;
  247.            if ( !positionals  &&  ARG_isPOSITIONAL(ad) )  continue;
  248.            if ( positionals  &&  !ARG_isPOSITIONAL(ad) )  continue;
  249.  
  250.            len = fmtarg( ad, buf );
  251.            if ( len > maxlen )   maxlen = len;
  252.  
  253.            if ( ARG_isREQUIRED(ad) ) {
  254.                printf( "%s\n", buf );
  255.            }
  256.            else {
  257.                printf( "[%s]\n", buf );
  258.            }
  259.         }/*for each ad */
  260.      }/* for each argd */
  261.    }/* for each parm-type */
  262.  
  263.    COMMENT;
  264.    SH( "DESCRIPTION" );
  265.    PP;
  266.    indent_para(stdout, MAXCOLS, 0, "", 0, VAL(description), 0);
  267.  
  268.    COMMENT;
  269.    SH( "OPTIONS" );
  270.  
  271.    for ( positionals = 0 ; positionals < 2 ; positionals++ ) {
  272.       for ( args = argd ; args ; args = cmd_defargs(args) ) {
  273.          for ( ad = ARG_FIRST(args) ; !ARG_isEND(ad) ; ARG_ADVANCE(ad) ) {
  274.             argName_t  buf;
  275.             char  *desc;
  276.             int  desclen;
  277.  
  278.                /* don't display hidden arguments */
  279.             if ( ARG_isHIDDEN(ad) )  continue;
  280.             if ( !positionals  &&  ARG_isPOSITIONAL(ad) )  continue;
  281.             if ( positionals  &&  !ARG_isPOSITIONAL(ad) )  continue;
  282.  
  283.             (VOID) fmtarg( ad, buf );
  284.             TP( maxlen + 2, buf );
  285.             desc = get_argdesc(arg_description(ad), &desclen);
  286.             indent_para(stdout, MAXCOLS, 0, "", 0, desc, desclen);
  287.          }/*for each ad */
  288.       }/* for each argd */
  289.    }/* for each parm-type */
  290.  
  291.    COMMENT;
  292.    SH( "FILES" );
  293.    PP;
  294.  
  295.    COMMENT;
  296.    SH( "ENVIRONMENT" );
  297.    PP;
  298.  
  299.    COMMENT;
  300.    SH( "SEE ALSO" );
  301.    PP;
  302.  
  303.    COMMENT;
  304.    SH( "DIAGNOSTICS" );
  305.    PP;
  306.  
  307.    COMMENT;
  308.    SH( "CAVEATS" );
  309.    PP;
  310.  
  311.    COMMENT;
  312.    SH( "BUGS" );
  313.    PP;
  314.  
  315.    COMMENT;
  316.    SH( "AUTHOR" );
  317.    PP;
  318.  
  319.    COMMENT;
  320.    SH( "HISTORY" );
  321.    PP;
  322. }
  323.