home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / msdos / sysutl / idt.arc / GETARGS.C < prev    next >
C/C++ Source or Header  |  1988-06-11  |  6KB  |  292 lines

  1. /*
  2. **    GETARGS.C    Command line argument processor for C programs
  3. **
  4. **    (C) Copyright 1985, Allen I. Holub.  All rights reserved.
  5. **    This program may be copied for personal, non-profit use only.
  6. **
  7. */
  8.  
  9. #include    <stdio.h>
  10. #include    <ctype.h>
  11. #include    <process.h>
  12. #include    <string.h>
  13.  
  14. #include    <local/what.h>
  15.  
  16. /*
  17. **    conditional compilation switches
  18. */
  19.  
  20. #define    CASEBLIND        /* if case insensitivity        */
  21. #define    MULTIPLE        /* if have multiple commands/switch    */
  22.  
  23. #include    <local/getargs.h>
  24.  
  25. /*
  26. **    prototypes and declarations
  27. */
  28.  
  29. extern    int    stoi( char** );
  30. extern    long    stol( char** );
  31. typedef int    (*PFI)();
  32.  
  33. static char *setarg( ARG *, char * );
  34. static ARG *findarg( int, ARG *, int );
  35. #ifndef    NOUSAGE
  36. static void pr_usage( ARG *, int );
  37. #endif
  38.  
  39. /*
  40. **    global data
  41. */
  42.  
  43. static    char switchar[] = "-/";
  44.  
  45. /*
  46. **    "what" strings
  47. */
  48.  
  49. static char *WhatStrings[] =
  50.     {
  51.     WHATWHEN,
  52.     WHATDATE,
  53.     WHAT("Copyright (c) 1985, Allen I. Holub"),
  54.     WHAT("  All Rights Reserved")
  55.     };
  56.  
  57.  
  58. /*    .SUBTITLE "setarg - set switch argument value"    .EJECT    */
  59. /*
  60. **    function:    setarg
  61. **
  62. **    purpose:    this function is called by getargs() to process
  63. **            a switch once it is found. this usually involves
  64. **            setting the value of an associated variable.
  65. */
  66.  
  67. static char *setarg( argp, linep )
  68.  
  69. ARG    *argp;
  70. char    *linep;
  71.  
  72. {
  73.     char temp;
  74.  
  75.     /*
  76.     **    Set an argument. argp points at the argument table entry
  77.     **    corresponding to *linep. Return linep, updated to point
  78.     **    past the argument being set.
  79.     */
  80.  
  81.     ++linep;
  82.  
  83.     switch( argp->type )
  84.         {
  85.         case INTEGER:
  86.  
  87.             * (int *) argp->variable = stoi( &linep );
  88.             break;
  89.  
  90.         case LONG:
  91.  
  92.             * (long *) argp->variable = stol( &linep );
  93.             break;
  94.  
  95.         case BOOLEAN:
  96.  
  97.             * (int *) argp->variable = 1;
  98.             break;
  99.  
  100.         case CHARACTER:
  101.  
  102.             * (char *) argp->variable = *linep++;
  103.             break;
  104.  
  105.         case UCHARACTER:
  106.  
  107.             temp = *linep++;
  108.             * (char *) argp->variable = toupper( temp );
  109.             break;
  110.  
  111.         case STRING:
  112.  
  113.             * (char **) argp->variable = linep;
  114.             linep = "";
  115.             break;
  116.  
  117.         case PROC:
  118.  
  119.             (* (PFI)(argp->variable) )( linep );
  120.             linep = "";
  121.             break;        
  122.  
  123.         default:
  124.  
  125.             fprintf( stderr, "\nsetarg() Internal Error: Bad Argument Type\n" );
  126.             break;
  127.         }
  128.  
  129.     return ( linep );
  130. }
  131.  
  132. /*    .SUBTITLE "findarg - find switch argument"    .EJECT    */
  133. /*
  134. **    function:    findarg
  135. **
  136. **    purpose:    this function is called by getargs() to scan
  137. **            the provided switch table for the given switch.
  138. */
  139.  
  140. static ARG *findarg( c, tabp, tabsize )
  141.  
  142. int    c, tabsize;
  143. ARG    *tabp;
  144.  
  145. {
  146.     /*
  147.     **    Return pointer to argument table entry corresponding
  148.     **    to c (or 0 if c isn't in table).
  149.     */
  150.     
  151.     for ( ; --tabsize >= 0; tabp++ )
  152. #ifdef CASEBLIND
  153.         if ( tolower(tabp->arg) == tolower(c) )
  154. #else
  155.         if ( tabp->arg == c )
  156. #endif
  157.             return ( tabp );
  158.  
  159.     return ( 0 );
  160. }
  161.  
  162. /*    .SUBTITLE "pr_usage - print a usage message"    .EJECT    */
  163. /*
  164. **    function:    pr_usage
  165. **
  166. **    purpose:    this function is called by getargs() if an
  167. **            unknown switch is encountered. it displays
  168. **            the entire switch table on stderr.
  169. */
  170.  
  171. #ifndef    NOUSAGE
  172.  
  173. static void pr_usage( tabp, tabsize )
  174.  
  175. ARG    *tabp;
  176. int    tabsize;
  177.  
  178. {
  179.     /*
  180.     **    Print the argtab in the form:
  181.     **        -<arg> <errmsg>     (value is <*variable>)
  182.     */
  183.  
  184.     for( ; --tabsize >= 0;  tabp++ )
  185.         switch ( tabp->type )
  186.             {
  187.             case INTEGER:
  188.  
  189.                 fprintf( stderr, "-%c<num> %-40s (value is ", tabp->arg, tabp->errmsg );
  190.                 fprintf( stderr, "%-5d)\n", * (int *) (tabp->variable) );
  191.                 break;
  192.  
  193.             case LONG:
  194.  
  195.                 fprintf( stderr, "-%c<num> %-40s (value is ", tabp->arg, tabp->errmsg );
  196.                 fprintf( stderr, "%-5ld)\n", * (long *) (tabp->variable) );
  197.                 break;
  198.  
  199.             case BOOLEAN:
  200.  
  201.                 fprintf( stderr,"-%c      %-40s (value is ", tabp->arg, tabp->errmsg );
  202.                 fprintf( stderr, "%-5s)\n", * (char *) (tabp->variable) ? "TRUE": "FALSE" );
  203.                 break;
  204.  
  205.             case CHARACTER:
  206.             case UCHARACTER:
  207.  
  208.                 fprintf( stderr, "-%c<c>   %-40s (value is ", tabp->arg, tabp->errmsg );
  209.                 fprintf( stderr, "%-5c)\n", * (char *) (tabp->variable) );
  210.                 break;
  211.  
  212.             case STRING:    
  213.  
  214.                 fprintf( stderr, "-%c<str> %-40s (value is ", tabp->arg, tabp->errmsg );
  215.                 fprintf( stderr, "<%s>)\n", *(char**)tabp->variable );
  216.                 break;
  217.  
  218.             case PROC:
  219.  
  220.                 fprintf( stderr, "-%c<str> %-40s\n", tabp->arg, tabp->errmsg );
  221.                 break;
  222.             }
  223. }
  224.  
  225. #endif
  226.  
  227. /*    .SUBTITLE "getargs - process command line switches"    .EJECT    */
  228. /*
  229. **    function:    getargs
  230. **
  231. **    purpose:    getargs is generally called from main() to process
  232. **            and remove any switches from the command line via
  233. **            the argv[] array.
  234. */
  235.  
  236. int getargs( argc, argv, tabp, tabsize )
  237.  
  238. int    argc, tabsize;
  239. char    **argv;
  240. ARG    *tabp;
  241.  
  242. {
  243.     /*
  244.     **     Process command line arguments. Stripping all command line
  245.     **     switches out of argv. Return a new argc. If an error is found
  246.     **     exit(1) is called (getargs won't return) and a usage message
  247.     **     is printed showing all arguments in the table.
  248.     */
  249.  
  250.     int    nargc;
  251.     char    **nargv, *p;
  252.     ARG    *argp;
  253.     char    lastswitchar;
  254.  
  255.     nargc = 1;
  256.     for ( nargv = ++argv; --argc > 0; argv++ )
  257.         {
  258.         if ( !strchr( switchar, **argv ) )
  259.             {
  260.             *nargv++ = *argv;
  261.             nargc++;
  262.             }
  263.         else
  264.             {
  265.             lastswitchar = **argv;
  266.             p = (*argv) + 1;
  267.  
  268. #ifdef MULTIPLE
  269.             while ( *p )
  270. #endif
  271.                 if ( argp = findarg( *p, tabp, tabsize ) )
  272.                     p = setarg( argp, p );
  273.                 else
  274.                     {
  275. #ifdef NOUSAGE
  276.                     *--p = lastswitchar;
  277.                     *nargv++ = p;
  278.                     nargc++;
  279.                     p = "";
  280. #else
  281.                     fprintf( stderr, "\nIllegal switch <%c>.   Legal arguments are:\n\n", *p );
  282.                     pr_usage( tabp, tabsize );
  283.                     exit( 1 );
  284. #endif
  285.                     }
  286.             }    
  287.         }
  288.  
  289.     return ( nargc );
  290. }
  291.  
  292.