static int SubExprStack[NSTACK]; /* parallel to OperatorStack */
static int* SubExprPtr; /* Pointer to the top of the sub-expression stack */
-static Reclass* classp;
-static Reinst* freep;
-static Reclass* yyclassp; /* last lex'd class */
+static Reinst* FreeInstrPtr; /* Pointer to first free instruction object */
+static Reclass* ClassListPtr; /* Pointer to list of classes */
+static Reclass* CurrClassPtr; /* last lex'd class */
/* predeclared crap */
static Reinst* OpCode(int t);
/******************************************************************************/
static Reinst* OpCode(int t) {
- freep->type = t;
- freep->l.left = 0;
- freep->r.right = 0;
- return freep++;
+ memset(FreeInstrPtr, 0, sizeof(*FreeInstrPtr));
+ FreeInstrPtr->type = t;
+ return FreeInstrPtr++;
}
-/******************************************************************************/
+static void CompileError(char *s) {
+ regerror(s);
+ longjmp(LandingPad, 1);
+}
static int NextRune(int* p_rune) {
if (!*SrcExpr) {
if (literal || quoted) {
if (CurrRune == 0)
return END;
- return RUNE;
- }
-
- switch (CurrRune) {
+ } else switch (CurrRune) {
case 0: return END;
case '*': return STAR;
case '?': return QUEST;
return RUNE;
}
-/******************************************************************************/
-
-static void CompileError(char *s) {
- regerror(s);
- longjmp(LandingPad, 1);
-}
-
static void PushOperand(Reinst *f, Reinst *l) {
if (OperandPtr >= &OperandStack[NSTACK])
CompileError("operand stack overflow");
if (NClass >= NCLASSES)
CompileError("too many character classes; increase Reprog.class size");
int type = CCLASS;
- yyclassp = &(classp[NClass++]);
+ CurrClassPtr = &(ClassListPtr[NClass++]);
/* look ahead for negation */
/* SPECIAL CASE!!! negated classes don't match \n */
quoted = NextRune(&rune);
}
if (ep >= &r[NCLASSSPANS-1]) {
- CompileError("char class too large; increase Reclass.spans size");
+ CompileError("char class too large; increase NCLASSSPANS size");
return 0;
}
}
/* merge spans */
- np = yyclassp->spans;
+ np = CurrClassPtr->spans;
p = r;
- if(r == ep)
- yyclassp->end = np;
- else {
+ if(r == ep) {
+ CurrClassPtr->end = np;
+ } else {
np[0] = *p++;
np[1] = *p++;
- for(; p < ep; p += 2)
+ for(; p < ep; p += 2) {
/* overlapping or adjacent ranges? */
if(p[0] <= np[1] + 1){
if(p[1] >= np[1])
np[0] = p[0];
np[1] = p[1];
}
- yyclassp->end = np+2;
+ }
+ CurrClassPtr->end = np+2;
}
return type;
/******************************************************************************/
static void Operand(int t) {
- Reinst *i;
-
if (LastWasOperand)
- Operator(CAT); /* catenate is implicit */
- i = OpCode(t);
+ Operator(CAT); /* catenate is implicit */
+ Reinst* i = OpCode(t);
if (t == CCLASS || t == NCCLASS)
- i->r.cp = yyclassp;
- if (t == RUNE)
+ i->r.cp = CurrClassPtr;
+ else if (t == RUNE)
i->r.r = CurrRune;
PushOperand(i, i);
}
static void Operator(int t) {
- if(t==RPAREN && --NParens<0)
+ if (t == RPAREN && --NParens < 0)
CompileError("unmatched right paren");
- if(t==LPAREN){
- if(++CurrSubExpr >= NSUBEXP)
+ if (t==LPAREN) {
+ if (++CurrSubExpr >= NSUBEXP)
CompileError("too many subexpressions");
NParens++;
- if(LastWasOperand)
+ if (LastWasOperand)
Operator(CAT);
- }else
+ } else {
EvalUntil(t);
- if(t != RPAREN)
+ }
+ if (t != RPAREN)
PushOperator(t);
LastWasOperand = false;
- if(t==STAR || t==QUEST || t==PLUS || t==RPAREN)
- LastWasOperand = true; /* these look like operands */
+ if (t == STAR || t == QUEST || t == PLUS || t == RPAREN)
+ LastWasOperand = true; /* these look like operands */
}
static void EvalUntil(int pri) {
Node *op1, *op2;
Reinst *inst1, *inst2;
- while(pri==RPAREN || OperatorPtr[-1]>=pri){
- switch(PopOperator()){
- default:
- CompileError("unknown operator in evaluntil");
- break;
- case LPAREN: /* must have been RPAREN */
- op1 = PopOperand();
- inst2 = OpCode(RPAREN);
- inst2->r.subid = *SubExprPtr;
- op1->last->l.next = inst2;
- inst1 = OpCode(LPAREN);
- inst1->r.subid = *SubExprPtr;
- inst1->l.next = op1->first;
- PushOperand(inst1, inst2);
- return;
- case OR:
- op2 = PopOperand();
- op1 = PopOperand();
- inst2 = OpCode(NOP);
- op2->last->l.next = inst2;
- op1->last->l.next = inst2;
- inst1 = OpCode(OR);
- inst1->r.right = op1->first;
- inst1->l.left = op2->first;
- PushOperand(inst1, inst2);
- break;
- case CAT:
- op2 = PopOperand();
- op1 = PopOperand();
- op1->last->l.next = op2->first;
- PushOperand(op1->first, op2->last);
- break;
- case STAR:
- op2 = PopOperand();
- inst1 = OpCode(OR);
- op2->last->l.next = inst1;
- inst1->r.right = op2->first;
- PushOperand(inst1, inst1);
- break;
- case PLUS:
- op2 = PopOperand();
- inst1 = OpCode(OR);
- op2->last->l.next = inst1;
- inst1->r.right = op2->first;
- PushOperand(op2->first, inst1);
- break;
- case QUEST:
- op2 = PopOperand();
- inst1 = OpCode(OR);
- inst2 = OpCode(NOP);
- inst1->l.left = inst2;
- inst1->r.right = op2->first;
- op2->last->l.next = inst2;
- PushOperand(inst1, inst2);
- break;
+ while (pri == RPAREN || OperatorPtr[-1] >= pri) {
+ switch (PopOperator()) {
+ default:
+ CompileError("unknown operator in evaluntil");
+ break;
+ case LPAREN: /* must have been RPAREN */
+ op1 = PopOperand();
+ inst2 = OpCode(RPAREN);
+ inst2->r.subid = *SubExprPtr;
+ op1->last->l.next = inst2;
+ inst1 = OpCode(LPAREN);
+ inst1->r.subid = *SubExprPtr;
+ inst1->l.next = op1->first;
+ PushOperand(inst1, inst2);
+ return;
+ case OR:
+ op2 = PopOperand();
+ op1 = PopOperand();
+ inst2 = OpCode(NOP);
+ op2->last->l.next = inst2;
+ op1->last->l.next = inst2;
+ inst1 = OpCode(OR);
+ inst1->r.right = op1->first;
+ inst1->l.left = op2->first;
+ PushOperand(inst1, inst2);
+ break;
+ case CAT:
+ op2 = PopOperand();
+ op1 = PopOperand();
+ op1->last->l.next = op2->first;
+ PushOperand(op1->first, op2->last);
+ break;
+ case STAR:
+ op2 = PopOperand();
+ inst1 = OpCode(OR);
+ op2->last->l.next = inst1;
+ inst1->r.right = op2->first;
+ PushOperand(inst1, inst1);
+ break;
+ case PLUS:
+ op2 = PopOperand();
+ inst1 = OpCode(OR);
+ op2->last->l.next = inst1;
+ inst1->r.right = op2->first;
+ PushOperand(op2->first, inst1);
+ break;
+ case QUEST:
+ op2 = PopOperand();
+ inst1 = OpCode(OR);
+ inst2 = OpCode(NOP);
+ inst1->l.left = inst2;
+ inst1->r.right = op2->first;
+ op2->last->l.next = inst2;
+ PushOperand(inst1, inst2);
+ break;
}
}
}
int diff;
/* get rid of NOOP chains */
- for(inst = pp->firstinst; inst->type != END; inst++){
+ for (inst = pp->firstinst; inst->type != END; inst++) {
target = inst->l.next;
while(target->type == NOP)
target = target->l.next;
* necessary. Reallocate to the actual space used
* and then relocate the code.
*/
- size = sizeof(Reprog) + (freep - pp->firstinst)*sizeof(Reinst);
+ size = sizeof(Reprog) + (FreeInstrPtr - pp->firstinst)*sizeof(Reinst);
npp = realloc(pp, size);
if(npp==0 || npp==pp)
return pp;
diff = (char *)npp - (char *)pp;
- freep = (Reinst *)((char *)freep + diff);
- for(inst=npp->firstinst; inst<freep; inst++){
- switch(inst->type){
- case OR:
- case STAR:
- case PLUS:
- case QUEST:
- inst->r.right = (void*)((char*)inst->r.right + diff);
- break;
- case CCLASS:
- case NCCLASS:
- inst->r.right = (void*)((char*)inst->r.right + diff);
- cl = inst->r.cp;
- cl->end = (void*)((char*)cl->end + diff);
- break;
+ FreeInstrPtr = (Reinst *)((char *)FreeInstrPtr + diff);
+ for (inst = npp->firstinst; inst < FreeInstrPtr; inst++) {
+ switch (inst->type) {
+ case OR:
+ case STAR:
+ case PLUS:
+ case QUEST:
+ inst->r.right = (void*)((char*)inst->r.right + diff);
+ break;
+ case CCLASS:
+ case NCCLASS:
+ inst->r.right = (void*)((char*)inst->r.right + diff);
+ cl = inst->r.cp;
+ cl->end = (void*)((char*)cl->end + diff);
+ break;
}
inst->l.left = (void*)((char*)inst->l.left + diff);
}
int token;
/* get memory for the program */
- Reprog* volatile pp = malloc(sizeof(Reprog) + 6*sizeof(Reinst)*strlen(s));
- if (pp == 0) {
+ Reprog* volatile pp = malloc(sizeof(Reprog) + (6 * sizeof(Reinst) * strlen(s)));
+ if (pp == NULL) {
regerror("out of memory");
- return 0;
+ return NULL;
}
- freep = pp->firstinst;
- classp = pp->class;
+ FreeInstrPtr = pp->firstinst;
+ ClassListPtr = pp->class;
/* setup landing pad for fatal errors */
if (setjmp(LandingPad))
CurrSubExpr = 0;
/* Start with a low priority operator to prime parser */
- PushOperator(START-1);
+ PushOperator(RUNE);
while ((token = GetToken(literal, dot_type)) != END){
if ((token & 0300) == OPERATOR)
Operator(token);