|
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: 6301 (0x189d) Types: TextFile Names: »regparse.c,v«
└─⟦a05ed705a⟧ Bits:30007078 DKUUG GNU 2/12/89 └─⟦34cc4e2f7⟧ »./UNRELEASED/xgdb3.2.tar.Z« └─⟦80fac5d7c⟧ └─⟦this⟧ »./RCS/regparse.c,v«
head 1.1; access ; symbols ; locks hubbard:1.1; strict; comment @ * @; 1.1 date 89.07.05.15.36.31; author hubbard; state Exp; branches ; next ; desc @Initial checkin, Beta version 0.1. @ 1.1 log @Initial revision @ text @\f #ifndef lint static char rcsid[] = "$Header$"; #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$ * */ #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; } @