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© 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.