|
|
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 r
Length: 6181 (0x1825)
Types: TextFile
Names: »regparse.c«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89
└─⟦e10a7c8ba⟧ »./UNRELEASED/xgdb.tar.Z«
└─⟦ae30648b5⟧
└─⟦this⟧ »./regparse.c«
\f
#ifndef lint
static char rcsid[] = "$Header: regparse.c,v 1.1 89/07/05 15:36:31 hubbard Exp $";
#endif
/*
*
* Copyright 1988, 1989
* PCS Computer Systeme, GmbH
* Munich, West Germany
*
* All rights reserved.
*
* This is unsupported software and is subject to change without notice.
* PCS makes no representations about the suitability of this software
* for any purpose. It is supplied "as is" without express or implied
* warranty.
*
* 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 and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of PCS Computer Systeme not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission.
*
*/
/*
* Author: Jordan K. Hubbard
* For: PCS Computer Systems, GmbH.
* When: February 23rd, 1989.
*
* $Log: regparse.c,v $
* Revision 1.1 89/07/05 15:36:31 hubbard
* Initial revision
*
*
*/
#include "xgdb.h"
/*
* The global parser regexp array.
*/
static RegEnt *RegexpArray;
static int RegexpArraySize;
/*
* Convert a 4 character label into a unique numeric value.
* I'm sure that this could be done in lots of nifty and interesting
* ways, but the way I do it here seems fastest to my non-mathematical
* brain. Corrections welcomed.
*/
static int label_to_quad(s)
String s;
{
union {
Quad value;
char fudge[4];
} result;
Entry("label_to_quad");
strncpy(result.fudge, s, 4);
Leave(result.value);
}
/* compare two parser regexp entries */
static int _compare(p1, p2)
RegEnt *p1, *p2;
{
if (p1->hash < p2->hash)
return(-1);
else if (p1->hash > p2->hash)
return(1);
else
return(0);
}
/*
* Given a label, return the associated regexp entry.
*/
RegEnt *find_regexp_entry(s)
String s;
{
RegEnt *ent, tmp;
Entry("find_regexp_entry");
tmp.hash = label_to_quad(s);
ent = (RegEnt *)bsearch((char *)&tmp, (char *)RegexpArray,
RegexpArraySize, sizeof(struct _ra),
_compare);
if (!ent)
puke("%p: Couldn't find regexp entry for label '%s'", s);
Leave(ent);
}
/*
* Parse a "simple" parser list. Of course, "simple" may seem like
* the biggest overstatement of the year, but it really isn't too
* weird. Each item in the list has a regexp # and a target list. The
* \(..\) expressions in the regexp are matched against the target
* list, with a type field determining what the target looks like.
*
* A target is currently one of:
*
* T_ARG: Single target (address of location to store one \(..\) hit.
* T_ARGS: Multiple targets (array of addresses to store multiple \(..\) hits.
* T_PROC: Pass only first \(..\) hit to procedure.
* T_PROCS: Pass entire regexp hit to procedure with any \(..\) offsets.
* T_PROC0: Call procedure without any data (only presence of data is relevant)
* T_NOP: Do nothing (data is thrown away).
* T_BOOL: Single target should be set to TRUE.
*
* Does NOT handle bad regexp/target combinations gracefully! Craft
* them with care!
*/
String parseSimpleList(list, P_ARGS)
SimpleParser *list;
P_ARG_DECL;
{
register SimpleParser *sp;
register String *ptr;
int i = 0, j = 0;
struct re_registers regs;
Entry("parseSimpleList");
P_CHECKARGS;
sp = list;
while (sp->label != NULL && *len) {
if (matchExp(s, sp->label, ®s) >= 0) {
switch(sp->type) {
case T_ARG:
ptr = (String *)sp->parms[0];
STASHN(*ptr, s + regs.start[1],
regs.end[1] - regs.start[1]);
break;
case T_ARGS:
i = check_registers(®s, RE_NREGS);
for (j = 1; j <= i; j++) {
ptr = (String *)sp->parms[j - 1];
if (ptr)
STASHN(*ptr, s + regs.start[j],
regs.end[j] - regs.start[j]);
}
break;
case T_PROC:
(*(VoidFuncP)sp->parms[0])(p, s + regs.start[1],
regs.end[1] - regs.start[1]);
break;
case T_PROCS:
(*(VoidFuncP)sp->parms[0])(p, s, ®s);
break;
case T_PROC0:
(*(VoidFuncP)sp->parms[0])();
case T_NOP:
break;
case T_BOOL:
*(sp->parms[0]) = TRUE;
break;
default:
puke("%p: Unknown type: '%d' in list element #%d",
sp->type, (sp - list) / sizeof(sp));
break;
}
/* End of switch */
*len -= clipString(s, regs.start[0], regs.end[0]);
}
else
sp++;
}
Leave(s);
}
/*
* Initialize and read in the RegexpArray.
*/
#define PARRAY_INC 50
void initializeRegexps(fname)
String fname;
{
int psize = 0, pindex = 0, len;
FILE *pfile;
char pline[256];
Entry("initializeRegexps");
/* Start */
psize = PARRAY_INC;
RegexpArray = (RegEnt *)XtMalloc(sizeof(RegEnt) * psize);
bzero(RegexpArray, sizeof(RegEnt) * psize);
disableProcessHandling(); /* Make sure we don't get the SIGCHLD */
sprintf(pline, "%s %s\n", CPP_COMMAND, fname);
if (!(pfile = popen(pline, "r")))
puke_and_die("%p: Can't invoke /lib/cpp on '%s'", fname);
while (fgets(pline, 255, pfile)) {
len = strlen(pline);
if (len && pline[len - 1] == '\n')
pline[--len] = '\0';
if (!len)
continue;
if (pindex == psize) {
psize += PARRAY_INC;
RegexpArray = (RegEnt *)XtRealloc(RegexpArray,
sizeof(RegEnt) * psize);
bzero(RegexpArray + pindex, sizeof(RegEnt) * (psize -
PARRAY_INC));
}
if (len > 1 && !strncmp(pline, "@@", 2)) { /* label */
RegexpArray[pindex].hash = label_to_quad(&(pline[2]));
continue;
}
ctrl(pline);
STASHF(RegexpArray[pindex].str, pline);
pindex++;
}
pclose(pfile);
enableProcessHandling();
RegexpArraySize = pindex;
/* Sort the puppy */
qsort((char *)RegexpArray, RegexpArraySize, sizeof(struct _ra),
_compare);
Leave_void;
}