171 lines
4.1 KiB
C
171 lines
4.1 KiB
C
/*
|
|
* parser.c --
|
|
*
|
|
* Handles textual parsing.
|
|
*
|
|
* *********************************************************************
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
* * software and its documentation for any purpose and without *
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
* * notice appear in all copies. The University of California *
|
|
* * makes no representations about the suitability of this *
|
|
* * software for any purpose. It is provided "as is" without *
|
|
* * express or implied warranty. Export of this software outside *
|
|
* * of the United States of America may require an export license. *
|
|
* *********************************************************************
|
|
*
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/utils/parser.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "textio/textio.h"
|
|
|
|
#define ISEND(ch) ((ch == '\0') || (ch == ';'))
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
* ParsSplit:
|
|
*
|
|
* Take a string and split it into argc, argv format.
|
|
* The result of this split is stored back into the original string,
|
|
* and an array of pointers is set up to index into it. Note that
|
|
* the contents of the original string are lost.
|
|
*
|
|
* rajit@cs.caltech.edu: changed it so that quotes typed in by the
|
|
* user remain there.
|
|
*
|
|
* Results:
|
|
* TRUE if everything went OK.
|
|
* FALSE otherwise.
|
|
*
|
|
* Side effects:
|
|
* argc is filled in, str is changed, argv[] is changed to point into str
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
bool
|
|
ParsSplit(str, maxArgc, argc, argv, remainder)
|
|
char *str;
|
|
int maxArgc;
|
|
int *argc;
|
|
char **argv;
|
|
char **remainder;
|
|
{
|
|
char **largv;
|
|
char *newstrp;
|
|
char *strp;
|
|
char terminator;
|
|
|
|
*argc = 0;
|
|
largv = argv;
|
|
newstrp = str;
|
|
strp = str;
|
|
|
|
while (isspace(*strp) && (!ISEND(*strp)) ) strp++;
|
|
|
|
terminator = *strp;
|
|
*largv = strp;
|
|
while (!ISEND(*strp))
|
|
{
|
|
/*
|
|
* hackhackhackhackhack
|
|
* rajit@cs.caltech.edu
|
|
* okay. so we're changing what ' ' can be used for.
|
|
* One can only have a _SINGLE_ character between the
|
|
* two quotes. i.e. ' ' are used to quote characters.
|
|
*/
|
|
#ifdef SCHEME_INTERPRETER
|
|
if (*strp == '\'' && *(strp+1) && *(strp+2) == '\'')
|
|
{
|
|
strp++;
|
|
*newstrp++ = *strp++;
|
|
strp++;
|
|
}
|
|
/*
|
|
* rajit@cs.caltech.edu
|
|
* keep " " around strings to distinguish symbols from strings.
|
|
* the lisp evaluator strips these quotes after parsing the
|
|
* string.
|
|
*/
|
|
else if (*strp == '"')
|
|
#else
|
|
if (*strp == '"' || *strp == '\'')
|
|
#endif
|
|
{
|
|
char compare;
|
|
|
|
#ifdef SCHEME_INTERPRETER
|
|
*newstrp++ = *strp;
|
|
#endif
|
|
compare = *strp++;
|
|
while ( (*strp != compare) && (*strp != '\0'))
|
|
{
|
|
if (*strp == '\\')
|
|
#ifndef SCHEME_INTERPRETER
|
|
strp++;
|
|
#else
|
|
*newstrp++ = *strp++;
|
|
#endif
|
|
*newstrp++ = *strp++;
|
|
}
|
|
if (*strp == compare)
|
|
#ifndef SCHEME_INTERPRETER
|
|
strp++;
|
|
#else
|
|
*newstrp++ = *strp++;
|
|
#endif
|
|
else
|
|
#ifndef SCHEME_INTERPRETER
|
|
TxError("Unmatched %c in string, %s.\n", compare,
|
|
"I'll pretend that there is one at the end");
|
|
#else
|
|
{
|
|
TxError ("Unmatched %c in string.\n", compare);
|
|
return FALSE;
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
*newstrp++ = *strp++;
|
|
if (isspace(*strp) || (ISEND(*strp)))
|
|
{
|
|
while (isspace(*strp) && (!ISEND(*strp))) strp++;
|
|
terminator = *strp;
|
|
*newstrp++ = '\0';
|
|
(*argc)++;
|
|
if (*argc < maxArgc)
|
|
{
|
|
*++largv = newstrp;
|
|
}
|
|
else
|
|
{
|
|
TxError("Too many arguments.\n");
|
|
*remainder = NULL;
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
ASSERT(remainder != (char **) NULL, "ParsSplit");
|
|
|
|
if (terminator != '\0')
|
|
{
|
|
/* save other commands (those after the ';') for later parsing */
|
|
strp++;
|
|
while (isspace(*strp) && (!ISEND(*strp))) strp++;
|
|
*remainder = strp;
|
|
}
|
|
else
|
|
*remainder = NULL;
|
|
|
|
return TRUE;
|
|
}
|