home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast2.iso / c / getargs.c < prev    next >
C/C++ Source or Header  |  1994-03-04  |  4KB  |  149 lines

  1. /*    getargs - 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.     history...
  7.  
  8.     May 1985    published in Dr. Dobb's Journal #103.
  9.     19 May 85    Transcribed by James R. Van Zandt                        */
  10.  
  11. #include <stdio.h>
  12. #include <getargs.h>
  13.  
  14. typedef int (*PFI)();
  15.  
  16. static char *setarg(argp,linep) ARG *argp; char *linep;
  17.  
  18. {    /*    set an argument.  argp points at the argument table entry
  19.         corresponding to *linep.  Returns linep, updated to point
  20.         past the argument being set                                    */
  21.     ++linep;
  22.     switch(argp->type)
  23.         {case INTEGER:    *argp->variable=stoi(&linep); break;
  24.         case BOOLEAN:    *argp->variable=1; break;
  25.         case CHARACTER:    *argp->variable=*linep++; break;
  26.         case STRING:    *(char **)argp->variable=linep; linep=""; break;
  27.         case PROC:        (*(PFI)(argp->variable))(linep); linep=""; break;
  28.         default:
  29.             fprintf(stderr,"INTERNAL ERROR: BAD ARGUMENT TYPE\n"); break;
  30.         }
  31.     return (linep);
  32. }
  33.  
  34. static ARG *findarg(c,tabp,tabsize) int c,tabsize; ARG *tabp;
  35.  
  36. {    /*    return pointer to argument table entry corresponding to
  37.         c (or 0 if c isn't in table).                            */
  38.     
  39.     for( ; --tabsize>=0; tabp++) {if(tabp->arg==c) return tabp;}
  40.     return 0;
  41. }
  42.  
  43. static pr_usage(tabp,tabsize) ARG *tabp; int tabsize;
  44.  
  45. {    /*    print the argtab in the form:
  46.         -<arg> <errmsg>  (value is <*variable>)                    */
  47.  
  48.     for(; --tabsize>=0; tabp++)
  49.         {switch(tabp->type)
  50.             {case INTEGER:
  51.                 fprintf(stderr,"-%c<num> %-40s (value is ",
  52.                     tabp->arg, tabp->errmsg);
  53.                 fprintf(stderr,"%-5d)\n",*(tabp->variable));
  54.                 break;
  55.             case BOOLEAN:
  56.                 fprintf(stderr,"-%c      %-40s (value is ",
  57.                     tabp->arg, tabp->errmsg);
  58.                 fprintf(stderr,"%-5s)\n",*(tabp->variable)
  59.                     ?"TRUE":"FALSE");
  60.                 break;
  61.             case CHARACTER:
  62.                 fprintf(stderr,"-%c<c>   %-40s (value is ",
  63.                     tabp->arg,tabp->errmsg);
  64.                 fprintf(stderr,"%-5c)\n",*(tabp->variable));
  65.                 break;
  66.             case STRING:
  67.                 fprintf(stderr,"-%c<str> %-40s (value is ",
  68.                     tabp->arg, tabp->errmsg);
  69.                 fprintf(stderr,"\"%s\")\n", *(char **)tabp->variable);
  70.                 break;
  71.             case PROC:
  72.                 fprintf(stderr,"-%c<str> %-40s\n",
  73.                     tabp->arg,tabp->errmsg);
  74.                 break;
  75.             }
  76.         }
  77. }
  78.  
  79. #define ERRMSG "Illegal argument \'%c\'.  Legal arguments are:\n\n"
  80.  
  81. int getargs(argc,argv,tabp,tabsize)
  82.     int argc,tabsize;
  83.     char **argv;
  84.     ARG *tabp;
  85. {    /*    Process command line arguments, stripping all command line
  86.         switches out of argv.  Return a new argc.  If an error is found
  87.         exit(1) is called (getargs won't return) and a usage message
  88.         is printed showing all arguments in the table.                */
  89.  
  90.     register int nargc;
  91.     register char **nargv, *p;
  92.     register ARG *argp;
  93.  
  94.     nargc=1;
  95.     for (nargv=++argv; --argc>0; argv++)
  96.         {if(**argv!='-') {*nargv++=*argv; nargc++;}
  97.         else
  98.             {p=(*argv)+1;
  99.             while(*p)
  100.                 {if(argp=findarg(*p,tabp, tabsize)) {p=setarg(argp,p);}
  101.                 else
  102.                     {fprintf(stderr,ERRMSG,*p);
  103.                     pr_usage(tabp,tabsize);
  104.                     exit(1);
  105.                     }
  106.                 }
  107.             }
  108.         }
  109.         return nargc;
  110. }
  111.  
  112. #define islower(c) ('a'<=(c)&&(c)<='z')
  113. #define toupper(c) (islower(c)?(c)-('a'-'A'):(c))
  114.  
  115. int stoi(instr)  register char **instr;
  116. {    /*    Convert string to integer.  If string starts with 0x it is
  117.         interpreted as a hex number, else if it starts with a 0 it
  118.         is octal, else it is decimal.  Conversion stops on encountering
  119.         the first character which is not a digit in the indicated
  120.         radix.  *instr is updated to point past the end of the number.    */
  121.  
  122.     register int num=0;
  123.     register char *str;
  124.     int sign=1;
  125.  
  126.     str=*instr;
  127.     while(*str==' ' || *str=='\t' || *str=='\n') {str++;}
  128.     if(*str=='-') {sign=-1; str++;}
  129.     if(*str=='0')
  130.         {++str;
  131.         if(*str=='x' || *str=='X')
  132.             {str++;
  133.             while(    ('0'<=*str && *str<='9') ||
  134.                     ('a'<=*str && *str<='f') ||
  135.                     ('A'<=*str && *str<='F')    )
  136.                 {num=num*16+
  137.                     (('0'<=*str && *str<='9') ?
  138.                     *str-'0' : 
  139.                     toupper(*str)-'A'+10);
  140.                 str++;
  141.                 }
  142.             }
  143.         else {while('0'<=*str && *str<='7') {num = num*8+ *str++ - '0';}}
  144.         }
  145.     else {while('0'<=*str && *str<='9') {num=num*10+ *str++-'0';}}
  146.     *instr=str;
  147.     return (num*sign);
  148. }
  149.