|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 5027 (0x13a3)
Types: TextFile
Names: »str2arg.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Lib/util/str2arg.c«
/* str2arg.c: convert a string into a list of args with
key = value processing */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Lib/util/RCS/str2arg.c,v 5.0 90/09/20 16:18:01 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Lib/util/RCS/str2arg.c,v 5.0 90/09/20 16:18:01 pp Exp Locker: pp $
*
* $Log: str2arg.c,v $
* Revision 5.0 90/09/20 16:18:01 pp
* rcsforce : 5.0 public release
*
*/
#include "util.h"
/* convert string into argument list
*
* stash a pointer to each field into the passed array.
* any common seperators split the words. extra white-space
* between fields is ignored.
*
* if the separator is '=', then the current argument position in
* the array points to "=", the next the one is the key and the
* value follows it. This permits detecting variable assignment,
* in addition to positional arguments.
* i.e., key=value -> = key value
*
* specially-interpreted characters:
* space, tab, double-quote, backslash, comma, equal, slash, period,
* semi-colon, colon, carriage return, and line-feed (newline).
* preceding a special char with a backslash removes its
* interpretation. a backslash not followed by a special is used
* to preface an octal specification for one character
*
* a string begun with double-quote has only double-quote and
* backslash as special characters.
*
* a field which begins with a hash (#) is interpreted
* as marking the rest of the line as a comment and it is skipped, as
* are blank lines
*/
extern int errno;
int str2arg (srcptr, maxf, argv)/* convert srcptr to argument list */
register char *srcptr; /* source data */
int maxf; /* maximum number of permitted fields */
char *argv[]; /* where to put the pointers */
{
char gotquote; /* currently parsing quoted string */
char lastdlm; /* last delimeter character */
register int ind;
register char *destptr;
if (srcptr == 0)
{
errno = EINVAL; /* emulate system-call failure */
return (NOTOK);
}
for (lastdlm = (char) NOTOK, ind = 0, maxf -= 2; *srcptr != '\0'; ind++)
{
if (ind >= maxf)
{
errno = E2BIG; /* emulate system-call failure */
return (NOTOK);
}
for (argv[ind] = destptr = srcptr; isspace (*srcptr); srcptr++)
; /* skip leading white space */
/*\f
*/
for (gotquote = FALSE; ; )
{
switch (*srcptr)
{
default: /* just copy it */
*destptr++ = *srcptr++;
break;
case '\"': /* beginning or end of string */
case '\'':
if (gotquote && gotquote == *srcptr)
gotquote = FALSE;
else if (gotquote)
*destptr ++ = *srcptr;
else
gotquote = *srcptr;
srcptr++;
break;
case '\\': /* quote next character */
srcptr++; /* just skip the back-slash */
switch (*srcptr)
{ /* convert octal values */
case 'r':
*destptr++ = '\r';
srcptr++;
break;
case 'n':
*destptr++ = '\n';
srcptr++;
break;
case 'b':
*destptr++ = '\b';
srcptr++;
break;
case 'f':
*destptr++ = '\f';
srcptr++;
break;
default:
if (*srcptr >= '0' && *srcptr <= '7')
{
*destptr = '\0';
do
*destptr = (*destptr << 3) | (*srcptr++ - '0');
while (*srcptr >= '0' && *srcptr <= '7');
destptr++;
break;
} /* otherwise DROP ON THROUGH */
case '\\':
case '\"':
case ' ':
case ',':
case '\t':
case ';':
case '#':
case ':':
case '=':
case '/':
case '|':
*destptr++ = *srcptr++;
break; /* just copy it */
} /* DROP ON THROUGH */
break;
case '=': /* make '=' prefix to pair */
if (gotquote)
{
*destptr++ = *srcptr++;
break;
}
ind++; /* put value ahead of '=' */
argv[ind] = argv[ind - 1];
lastdlm = '=';
argv[ind - 1] = "=";
*destptr = '\0';
srcptr++;
goto nextarg;
case ' ':
case '\t':
case '\n':
case '\r':
case ',':
case ';':
case '#':
case ':':
case '/':
case '|':
if (gotquote)
{ /* don't interpret the char */
*destptr++ = *srcptr++;
break;
}
if (isspace (lastdlm))
{
if (isspace (*srcptr))
{ /* shouldn't be possible */
errno = EINVAL;
return (NOTOK);
}
else
if (*srcptr != '#')
ind--; /* "xxx , yyy" is only 2 fields */
}
lastdlm = *srcptr;
srcptr++;
case '\0':
*destptr = '\0';
goto nextarg;
}
lastdlm = (char) NOTOK; /* disable when field started */
}
nextarg:
if (argv[ind][0] == '\0' && lastdlm == '#')
break; /* rest of line is comment */
}
argv[ind] = (char *) 0;
return (ind);
}