Autah-cs.209
net.sources
utcsrgv!utzoo!decvax!ucbvax!mhtsa!harpo!utah-cs!thomas
Mon Feb 22 10:09:16 1982
scanargs
/*
               Version 7 compatible
       Argument scanner, scans argv style argument list.

       Some stuff is a kludge because sscanf screws up

       Gary Newman - 10/4/1979 - Ampex Corp.

       Modified by Spencer W. Thomas, Univ. of Utah, 5/81 to
       add args introduced by  a flag, add qscanargs call,
       allow empty flags.

       Compiling with QUICK defined generates 'qscanargs' ==
       scanargs w/o floating point support; avoids huge size
       of scanf.

       If you make improvements we'd like to get them too.
       Jay Lepreau     lepreau@utah-20, decvax!{harpo,randvax}!utah-cs!lepreau
       Spencer Thomas  thomas@utah-20, decvax!{harpo,randvax}!utah-cs!thomas

       (There seems to be a bug here in that if the last option you have
       is a flag, and the user enters args incorrectly, sometimes the usage
       message printed will miss the null and go flying off thru core...)
                                                       --jay for spencer
*/
#include <STDIO.H>
#include <CTYPE.H>

#define YES 1
#define NO 0
#define ERROR(msg)  {fprintf(stderr, "msg\n"); goto error; }

#ifndef QUICK
scanargs (argc, argv, format, arglist)
#else
qscanargs (argc, argv, format, arglist)
#endif
int     argc;
char  **argv;
char   *format;
int     arglist[];
{
#ifndef QUICK
   _scanargs (argc, argv, format, &arglist);
#else
   _qscanargs (argc, argv, format, &arglist);
#endif
}

#ifndef QUICK
_scanargs (argc, argv, format, arglist)
#else
_qscanargs (argc, argv, format, arglist)
#endif
int     argc;
char  **argv;
char   *format;
int    *arglist[];
{
   register    check;                  /* check counter to be sure all argvs
                                          are processed */
   register char  *cp;
   register    cnt;
   char    tmpflg;                     /* temp flag */
   char    c;
   char    numnum;                     /* number of numbers already processed
                                          */
   char    numstr;                     /* count # of strings already
                                          processed */
   char    tmpcnt;                     /* temp count of # things already
                                          processed */
   char    required;
   char    exflag;                     /* when set, one of a set of exclusive
                                          flags is set */
   char    excnt;                      /* count of which exclusive flag is
                                          being processed */
   char   *ncp;                        /* remember cp during flag scanning */
#ifndef QUICK
   char   *cntrl;                      /* control string for scanf's */
   char    junk[2];                    /* junk buffer for scanf's */

   cntrl = "% %1s";                    /* control string initialization for
                                          scanf's */
#endif
   check = numnum = numstr = 0;
   cp = format;
   while (*cp)
   {
       required = NO;
       switch (*(cp++))
       {
           default:                    /* all other chars */
               break;
           case '!':                   /* required argument */
               required = YES;
           case '%':                   /* not required argument */
               switch (tmpflg = *(cp++))
               {
                   case '-':           /* argument is flag */
                   /* go back to label */
                       ncp = cp-1;     /* remember */
                       cp -= 3;
                       for (excnt = exflag = 0
                               ; *cp != ' ' && !(*cp=='-' &&(cp[-1]=='!'||cp[-1]=='%'));
                               (--cp, excnt++))
                       {
                           for (cnt = 1; cnt = '0' && c <= !="0)/*" (*(ARGV[CNT] ) + - SKIP 9 /* SSCANF FOR O KLUDGE ONE ELSE 1))) || { } QUICK *ARGV[CNT] IF(!ISDIGIT (*ARGV[CNT]="=" (TMPCNT-- NEW && ((TMPFLG="=" TO NUMSTR++; CONTINUE; BREAK; CHECK REQUIRED="NO;" #IFNDEF */ IF (!ISDIGIT(*ARGV[CNT])) **ARGLIST="argv[cnt];" TMPFLG="="> '7')
                               ERROR (Bad numeric argument);
                           cntrl[1] = tmpflg;/* put in conversion */
                           if (sscanf (argv[cnt], cntrl, *arglist
                                       ,junk) != 1)
#else
                           if (numcvt(argv[cnt], tmpflg, *arglist) != 1)
#endif
                               ERROR (Bad numeric argument);
                           check += cnt;
                           numnum++;
                           required = NO;
                           break;
                       }
                       if (required)
                           switch (tmpflg)
                           {
                               case 'x':
                               case 'X':
                                   ERROR (missing hexadecimal argument);
                               case 's':
                                   ERROR (missing string argument);
                               case 'o':
                               case 'O':
                                   ERROR (missing octal argument);
                               case 'd':
                               case 'D':
                                   ERROR (missing decimal argument);
                               case 'f':
                               case 'F':
                                   ERROR (missing floating argument);
                           }
                       arglist++;
                       while (*cp == ' ')
                           cp++;
                       break;
                   default:            /* error */
                       fprintf (stderr, "error in call to scanargs\n");
                       return (0);
               }
       }
   }
/*  Count up empty flags */
   for (cnt=1; cnt<ARGC; (*++CP) BASE, PROCESSED); FLAGS   !=" " # 2)) % ) * +="2;" - / 1 ARGUMENTS SKIP /* : < ??  A RECURSE) D F FOR *VAL; STR++; (*STR N="n*(n+1)/2" DECIMAL O NOT S SUM X 0) UNSIGNED CHAR ELSE (RECURSE) 0; !- USED STRING || 1) { BASE="16;" } QUICK OR (STDERR, 1; RETURN ERROR: (CHECK ARGC) (CP, RETVAL="0;" *STR; CONV, CP++; (*CP CONV; CASE , STDERR);
   REQUIRED = NO;
   WHILE (*CP)
   {
       IF (RECURSE && *CP ==  INT (REQUIRED) %- CP FPRINTF NEG="1;" PUTC D; && VAL) (1); DEFAULT: NO); TO (PUTC FORMAT++) FORMAT="++cp;" ERROR (*(CP="format)" LONG (!REQUIRED) OCTAL STDERR); ('[', UP (*CP++, NUMCVT(STR, PRFORMAT (' , STDERR);
       }
   }
   IF (!RECURSE)
       PUTC ( )
           BREAK;
       SWITCH (*CP)
       {
           DEFAULT:
               CP++;
               BREAK;
           CASE  STDERR) ('{', (CP); BREAK; (; (EXTRA *FORMAT; *CP; CHECK REQUIRED="NO;" ); REGISTER (*FORMAT, ('-', CHECKS YES); RECURSIVE */ DOUBLE (FORMAT, *CP !': COUNT *INDEX(); IF WHILE IS (']', #IFDEF *DIGITS; PRECISION USAGE :  FROM (*STR) ARGV[CNT][1]="=" CONV="=" THIS REQUIRED; (ARGV[CNT][0]="=" \N', ('}', CNT++) SWITCH FLOATING HEXADECIMAL EXTERN CALL (CONV="=">= '0' && *str = 'a' && *str <= *STR ) + - ; A D="10" F ELSE 16 (BASE="=" && IF>= 'A' && *str <= *STR ) + - ; A D F STR++; O X ELSE 0; *VAL="(int)" || } QUICK VAL="retval;" (NEG) 1; RETURN RETVAL; RETVAL="-retval;" D; </PRE #ENDIF *) IF *(LONG CONV="=" (CONV="=">
<HR>
This Usenet Oldnews Archive
article may be copied and distributed freely, provided:
<P>
1. There is no money collected for the text(s) of the articles.
<BR>
2. The following notice remains appended to each copy:
<P>
<EM>The Usenet Oldnews Archive: Compilation Copyright&copy 1981, 1996
<BR> Bruce Jones, Henry Spencer, David Wiseman.</EM>
<P>
<HR>
Goto <A HREF="82.03.02_utzoo.1456_net.sources.html">NEXT</A> article in NET.sources Newsgroup
<BR>Return to <A HREF="NET.sources-index.html">NET.sources index</A>
<BR>Return to the
       <A HREF="../index.html">Usenet Oldnews Archive index</A>
</HTML>

-----------------------------------------------------------------
gopher://quux.org/ conversion by John Goerzen <[email protected]>
of http://communication.ucsd.edu/A-News/


This Usenet Oldnews Archive
article may be copied and distributed freely, provided:

1. There is no money collected for the text(s) of the articles.

2. The following notice remains appended to each copy:

The Usenet Oldnews Archive: Compilation Copyright (C) 1981, 1996
Bruce Jones, Henry Spencer, David Wiseman.