home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / c_spec / sources / getargs.c < prev    next >
Text File  |  1986-02-20  |  4KB  |  170 lines

  1. /*    GETARGS.C    Command line argument processor for C programs
  2.  *
  3.  *       (C) Copyright 1985, Allen I. Holub.  All rights reserved.
  4.  *      This program may be copied for personal, non-profit use only.
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <getargs.h>
  9.  
  10. /*----------------------------------------------------------------------*/
  11.  
  12. extern    int    stoi    ( char**    );
  13. extern    void    fprintf    ( FILE*, char*, );
  14.  
  15. typedef int    (*PFI)();
  16.  
  17. /*----------------------------------------------------------------------*/
  18.  
  19.  
  20. static char    *setarg( argp, linep )
  21. ARG        *argp;
  22. char        *linep;
  23. {
  24.     /*    Set an argument. argp points at the argument table entry
  25.      *    corresponding to *linep. Return linep, updated to point
  26.      *    past the argument being set.
  27.      */
  28.  
  29.     ++linep;
  30.  
  31.     switch( argp->type )
  32.     {
  33.     case INTEGER:
  34.         *argp->variable = stoi( &linep );
  35.         break;
  36.  
  37.     case BOOLEAN:
  38.         *argp->variable = 1;
  39.         break;
  40.  
  41.     case CHARACTER:
  42.         *argp->variable = *linep++ ;
  43.         break;
  44.  
  45.     case STRING:
  46.         *(char **)argp->variable = linep ;
  47.         linep = "";
  48.         break;
  49.  
  50.     case PROC:
  51.         (* (PFI)(argp->variable) )( linep );
  52.         linep = "";
  53.         break;        
  54.  
  55.     default:
  56.         fprintf(stderr,"INTERNAL ERROR: BAD ARGUMENT TYPE\n");
  57.         break;
  58.     }
  59.  
  60.     return( linep );
  61. }
  62.  
  63. /*----------------------------------------------------------------------*/
  64.  
  65. static ARG    *findarg( c, tabp, tabsize )
  66. int        c, tabsize;
  67. ARG        *tabp;
  68. {
  69.     /*    Return pointer to argument table entry corresponding
  70.      *    to c (or 0 if c isn't in table).
  71.      */
  72.     
  73.     for(; --tabsize >= 0 ; tabp++ )
  74.         if( tabp->arg == c )
  75.             return tabp;
  76.  
  77.     return 0;
  78. }
  79.  
  80. static pr_usage( tabp, tabsize )
  81. ARG    *tabp;
  82. int    tabsize;
  83. {
  84.     /*    Print the argtab in the form:
  85.      *        -<arg> <errmsg>     (value is <*variable>)
  86.      */
  87.  
  88.     for(; --tabsize >= 0 ;  tabp++ )
  89.     {
  90.         switch( tabp->type )
  91.         {
  92.         case INTEGER:
  93.             fprintf(stderr, "-%c<num> %-40s (value is ",
  94.                         tabp->arg, tabp->errmsg);
  95.             fprintf(stderr, "%-5d)\n", *(tabp->variable) );
  96.             break;
  97.  
  98.         case BOOLEAN:
  99.             fprintf(stderr,"-%c      %-40s (value is ",
  100.                         tabp->arg, tabp->errmsg);
  101.             fprintf(stderr, "%-5s)\n", *(tabp->variable)
  102.                          ? "TRUE": "FALSE");
  103.             break;
  104.  
  105.         case CHARACTER: 
  106.             fprintf(stderr, "-%c<c>   %-40s (value is ",
  107.                         tabp->arg, tabp->errmsg);
  108.             fprintf(stderr, "%-5c)\n", *(tabp->variable) );
  109.             break;
  110.  
  111.         case STRING:    
  112.             fprintf(stderr, "-%c<str> %-40s (value is ",
  113.                         tabp->arg, tabp->errmsg);
  114.             fprintf(stderr, "<%s>)\n",
  115.                         *(char **)tabp->variable);
  116.             break;
  117.  
  118.         case PROC:
  119.             fprintf(stderr, "-%c<str> %-40s\n",
  120.                         tabp->arg, tabp->errmsg);
  121.             break;
  122.         }
  123.     }
  124. }
  125.  
  126. #define ERRMSG    "Illegal argument <%c>.   Legal arguments are:\n\n"
  127.  
  128. int    getargs(argc, argv, tabp, tabsize )
  129. int    argc, tabsize ;
  130. char    **argv ;
  131. ARG    *tabp  ;
  132. {
  133.     /* Process command line arguments. Stripping all command line 
  134.      * switches out of argv. Return a new argc. If an error is found
  135.      * exit(1) is called (getargs won't return) and a usage message
  136.      * is printed showing all arguments in the table.
  137.      */
  138.  
  139.     register int    nargc         ;
  140.     register char    **nargv, *p ;
  141.     register ARG    *argp        ;
  142.  
  143.     nargc = 1 ;
  144.     for(nargv = ++argv ; --argc > 0 ; argv++ )
  145.     {
  146.         if( **argv != '-' )
  147.         {
  148.             *nargv++ = *argv ;
  149.             nargc++;
  150.         }
  151.         else
  152.         {
  153.             p = (*argv) + 1 ;
  154.  
  155.             while( *p )
  156.             {
  157.                 if(argp = findarg(*p, tabp, tabsize))
  158.                     p = setarg( argp, p );
  159.                 else
  160.                 {
  161.                     fprintf(stderr, ERRMSG, *p );
  162.                     pr_usage( tabp, tabsize );
  163.                     exit( 1 );
  164.                 }
  165.             }
  166.         }    
  167.     }
  168.     return nargc ;
  169. }
  170.