broehl@watale.UUCP (Bernie Roehl) (08/24/86)
This is a library routine which is really easy to use for parsing command line switches. No more of those custom routines for each program. This is general enough for all needs. Just about. Have Fun!!!! # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by watale!broehl on Sat Aug 23 19:27:57 EDT 1986 # Contents: getargs.c getargs.h masdos.h read.me stoi.c echo x - getargs.c sed 's/^@//' > "getargs.c" <<'@//E*O*F getargs.c//' /* * * Getargs.c * *!AU: Michael A. Shiels *!CD: 21-May-86 *!FR: Dr. Dobb's May 1985 * */ #define GETARGS_C #define LINT_ARGS #include <stdio.h> #include <stdlib.h> #include "masdos.h" #include "getargs.h" extern void usage(); char ARG_Switch = '/'; int ARG_ICase = 0; static char *setarg( argp, linep ) ARG *argp ; char *linep ; { ++linep ; switch( argp->type ) { case ARG_INTEGER : *argp->variable = stoi( &linep ) ; break ; case ARG_FBOOLEAN : *argp->variable = 1; break ; case ARG_TBOOLEAN : *argp->variable = 0; break ; case ARG_SBOOLEAN : *argp->variable = ~*argp->variable; break ; case ARG_CHARACTER : *argp->variable = *linep++ ; break ; case ARG_STRING : *(char **)argp->variable = linep ; linep = "" ; break; default : fprintf( stderr, "GetArgs: Bad Argument Type\n" ) ; break ; } return( linep ) ; } static ARG *findarg( c, tabp, tabsize ) int c, tabsize ; ARG *tabp ; { for( ; --tabsize >= 0 ; tabp++ ) { if (ARG_ICase && toupper(tabp->arg) == toupper(c) ) return( tabp ); if ( tabp->arg == c ) return( tabp ); } return( NULL ); } static pr_usage( tabp, tabsize ) ARG *tabp; int tabsize; { for( ; --tabsize >= 0 ; tabp++ ) { switch( tabp->type ) { case ARG_INTEGER : fprintf(stderr, "%c%c<num> %-40s (value is ", ARG_Switch, tabp->arg, tabp->errmsg) ; fprintf(stderr, "%-5d)\n", *(tabp->variable) ) ; break ; case ARG_TBOOLEAN : fprintf(stderr, "%c%c %-40s (value is ", ARG_Switch, tabp->arg, tabp->errmsg) ; fprintf(stderr, "%-5s)\n", *(tabp->variable) ? "True" : "False") ; break ; case ARG_FBOOLEAN : fprintf(stderr, "%c%c %-40s (value is ", ARG_Switch, tabp->arg, tabp->errmsg) ; fprintf(stderr, "%-5s)\n", *(tabp->variable) ? "True" : "False") ; break ; case ARG_CHARACTER : fprintf(stderr, "%c%c<c> %-40s (value is ", ARG_Switch, tabp->arg, tabp->errmsg) ; fprintf(stderr, "%-5c)\n", *(tabp->variable) ) ; break ; case ARG_STRING : fprintf(stderr, "%c%c<str> %-40s (value is ", ARG_Switch, tabp->arg, tabp->errmsg) ; fprintf(stderr, "<%s>)\n", *(char **)tabp->variable) ; break ; } } } #define ARG_ERRMSG "Illegal argument <%c>. Legal arguments are:\n\n" int getargs( argc, argv, tabp, tabsize ) int argc, tabsize ; char **argv ; ARG *tabp ; { register int nargc ; register char **nargv, *p ; register ARG *argp ; char buf[2], *bufp = buf; if( (bufp = getenv("SWITCHAR")) ) ARG_Switch = *bufp; nargc = 1 ; for( nargv = ++argv ; --argc > 0 ; argv++ ) { if( **argv != ARG_Switch ) { *nargv++ = *argv ; nargc++ ; } else { p = ( *argv ) + 1 ; while( *p ) { if( argp = findarg( *p, tabp, tabsize ) ) { p = setarg( argp, p ) ; } else { usage(); fprintf( stderr, ARG_ERRMSG, *p ); pr_usage( tabp, tabsize ); exit( 1 ); } } } } return nargc ; } @//E*O*F getargs.c// chmod u=rw,g=r,o=r getargs.c echo x - getargs.h sed 's/^@//' > "getargs.h" <<'@//E*O*F getargs.h//' #ifndef GETARGS_INCLUDED #define GETARGS_INCLUDED /* * * Getargs.h * *!AU: Michael A. Shiels *!CD: 22-May-86 *!FR: Dr. Dobb's May 1985 * */ #define ARG_INTEGER 0 #define ARG_TBOOLEAN 1 #define ARG_SBOOLEAN 2 #define ARG_FBOOLEAN 3 #define ARG_CHARACTER 4 #define ARG_STRING 5 typedef struct { int arg; /* Command Line Switch */ int type; /* Variable Type */ int *variable; /* Pointer to Variable */ char *errmsg; /* Pointer to Error Message */ } ARG ; extern int ARG_ICase; extern int ARG_Switch; #ifdef LINT_ARGS int getargs( int, char **, ARG *, int ); #else extern int getargs(); #endif /* LINT_ARGS */ #endif /* GETARGS_INCLUDED */ @//E*O*F getargs.h// chmod u=rw,g=r,o=r getargs.h echo x - masdos.h sed 's/^@//' > "masdos.h" <<'@//E*O*F masdos.h//' #ifndef MASDOS_INCLUDED #define MASDOS_INCLUDED /* * * D_ debuging * A_ attributes for files * P_ print characteristics * Q_ characters * B_ BDOS interupt parameters * */ #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #define abs(a) (((a) < 0) ? -(a) : (a)) #ifdef DEBUGGING #define D_IN(p) fprintf(stderr,"(%s) In\n",p) #define D_OUT(p) fprintf(stderr,"(%s) Out\n",p) #define D_PRT(p,q) fprintf(stderr,"(%s) %s\n",p,q) #define D_S(p,q,r) fprintf(stderr,"(%s) %s %s\n",p,q,r) #define D_I(p,q,r) fprintf(stderr,"(%s) %s %d\n",p,q,r) #else #define D_IN(p) #define D_OUT(p) #define D_PRT(p,q) #define D_S(p,q,r) #define D_I(p,q,r) #endif #define NNULL 1 struct FILEINFO { unsigned char fi_resv[21]; /* Reserved by DOS */ unsigned char fi_attrib; /* File Attributes */ unsigned int fi_time; /* Create/Update time */ unsigned int fi_date; /* Create/Update date */ unsigned long fi_fsize; /* File Size (bytes) */ char fi_name[13]; /* File Name & Extension */ }; #define A_READONLY 0x01 #define A_HIDDEN 0x02 #define A_SYSTEM 0x04 #define A_LABEL 0x08 #define A_SUBDIR 0x10 #define A_DIRTY 0x20 #define A_ALL 0xff #define A_ALL_FILES (A_HIDDEN&A_SYSTEM) #define A_NORM_FILES 0x00 #define IS_READONLY(p) ((p)->fi_attrib & A_READONLY) #define IS_HIDDEN(p) ((p)->fi_attrib & A_HIDDEN) #define IS_SYSTEM(p) ((p)->fi_attrib & A_SYSTEM) #define IS_LABEL(p) ((p)->fi_attrib & A_LABEL) #define IS_SUBDIR(p) ((p)->fi_attrib & A_SUBDIR) #define IS_DIRTY(p) ((p)->fi_attrib & A_DIRTY) #define C_HOUR(p) (((p)->fi_time >> 11) & 0x1f) #define C_MIN(p) (((p)->fi_time >> 5) & 0x3f) #define C_SEC(p) (((p)->fi_time << 1) & 0x3e) #define C_YEAR(p) ((((p)->fi_date >> 9) & 0x7f) + 1980) #define C_MONTH(p) (((p)->fi_date >> 5) & 0x0f) #define C_DAY(p) (((p)->fi_date) & 0x1f) #define Q_ESC 0x1b #define P_ALL_OFF "\033[0m" #define P_BOLDFACE "\033[1m" #define P_UNDERLINE "\033[4m" #define P_BLINKING "\033[5m" #define P_REVERSE "\033[7m" #define I_BDOS 0x21 #define B_PRGTRM 0x0000 #define B_KBDINP 0x0100 #define B_DSPOUT 0x0200 #define B_AUXINP 0x0300 #define B_AUXOUT 0x0400 #define B_PRNOUT 0x0500 #define B_CONIO 0x0600 #define B_CONDIN 0x0700 #define B_CONINN 0x0800 #define B_PRTSTR 0x0900 #define B_KBDBIN 0x0a00 #define B_SEL_DISK 0x0e00 #define B_SETDTA 0x1a00 #define B_GETDTA 0x2f00 #define B_IOCTL 0x4400 #define B_FINDFIRST 0x4e00 #define B_FINDNEXT 0x4f00 #ifdef LINT_ARGS int stoi(char **); int ptext( int, char **, int, int, int ); void ssort( char *, int, int, int (*)() ); int toscreen(); #else extern int stoi(); extern int ptext(); extern void ssort(); extern int toscreen(); #endif /* LINT_ARGS */ #endif /* MASDOS_INCLUDED */ @//E*O*F masdos.h// chmod u=rw,g=r,o=r masdos.h echo x - read.me sed 's/^@//' > "read.me" <<'@//E*O*F read.me//' These files make up a general way to parse command line switchs. Originally from Dr. Dobbs magazine this version has been expanded to include the calling of a usage subroutine. Look in the other postings called MSLS and SORT for examples. @//E*O*F read.me// chmod u=rw,g=r,o=r read.me echo x - stoi.c sed 's/^@//' > "stoi.c" <<'@//E*O*F stoi.c//' /* * *!AU: Michael A. Shiels *!CD: 26-May-86 *!FR: Dr. Dobbs May 85 * */ #define LINT_ARGS #include <stdio.h> #define islower(c) ( 'a' <= (c) && (c) <= 'z' ) #define toupper(c) ( islower(c) ? (c) - ( 'a' - 'A' ) : (c) ) int stoi(instr) register char **instr; { register int num = 0; register char *str; int sign = 1; str = *instr; while( *str == ' ' || *str == '\t' || *str == '\n' ) str++; if( *str == '-' ) { sign = -1; str++; } if( *str == '0') { ++str; if( *str == 'x' || *str == 'X' ) { str++; while( ( '0' <= *str && *str <= '9' ) || ( 'a' <= *str && *str <= 'f' ) || ( 'A' <= *str && *str <= 'F' ) ) { num *= 16; num += ( '0' <= *str && *str <= '9' ) ? *str - '0' : toupper(*str) - 'A' + 10; str++; } } else { while( '0' <= *str && *str <= '7' ) { num *= 8; num += *str++ - '0'; } } } else { while( '0' <= *str && *str <= '9' ) { num *= 10; num += *str++ - '0'; } } *instr = str; return( num * sign ); } @//E*O*F stoi.c// chmod u=rw,g=r,o=r stoi.c echo Inspecting for damage in transit... temp=/tmp/shar$$; dtemp=/tmp/.shar$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 166 451 4701 getargs.c 42 103 700 getargs.h 125 360 3144 masdos.h 4 41 242 read.me 68 222 1804 stoi.c 405 1177 10591 total !!! wc getargs.c getargs.h masdos.h read.me stoi.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if [ -s $dtemp ] then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0 -- Michael A. Shiels clyde-\ decvax-\\ ihnp4-\\\ +++-----> watmath!watale!broehl tektronix-/// ubc-vision-// utzoo-/