[net.sources] LIBRARY for LS and SORT, for parsing command switches

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-/