/* SDB - boolean expression evaluator */ #include "sdbio.h" static struct operand *stack[STACKMAX],**sptr; static union codecell *cptr; /* db_interpret - interpret a boolean expression */ int db_interpret(slptr) struct sel *slptr; { struct operand *result; int r; /* check for empty where clause */ if ((cptr = slptr->sl_where) == NULL) return (TRUE); /* setup stack */ sptr = stack; /* execute the code */ while ((*(*cptr++).c_operator)()) ; /* get the result from the top of stack */ result = *--sptr; r = result->o_value.ov_boolean; if (result->o_type == TEMP) free(result); /* make sure the stack is empty */ while (sptr != stack) { if ((*sptr)->o_type == TEMP) free(*sptr); sptr -= 1; } /* return result */ return (r); } int db_xstop() { return (FALSE); } int db_xpush() { *sptr++ = (*cptr++).c_operand; } int db_xand() { return (boolean('&')); } int db_xor() { return (boolean('|')); } static int boolean(opr) { struct operand *lval,*rval,*result; int lv,rv,r; rval = *--sptr; lval = *--sptr; lv = lval->o_value.ov_boolean; rv = rval->o_value.ov_boolean; if ((result = malloc(sizeof(struct operand))) == NULL) return (db_ferror(INSMEM)); result->o_type = TEMP; switch (opr) { case '&': r = (lv && rv); break; case '|': r = (lv || rv); break; } result->o_value.ov_boolean = r; *sptr++ = result; if (lval->o_type == TEMP) free(lval); if (rval->o_type == TEMP) free(rval); return (TRUE); } int db_xnot() { struct operand *val,*result; val = *--sptr; if ((result = malloc(sizeof(struct operand))) == NULL) return (db_ferror(INSMEM)); result->o_type = TEMP; result->o_value.ov_boolean = !val->o_value.ov_boolean; *sptr++ = result; if (val->o_type == TEMP) free(val); return (TRUE); } int db_xlss() { return (compare(LSS)); } int db_xleq() { return (compare(LEQ)); } int db_xeql() { return (compare(EQL)); } int db_xgeq() { return (compare(GEQ)); } int db_xgtr() { return (compare(GTR)); } int db_xneq() { return (compare(NEQ)); } static int compare(cmp) { struct operand *lval,*rval,*result; int i; rval = *--sptr; lval = *--sptr; if ((result = malloc(sizeof(struct operand))) == NULL) return (db_ferror(INSMEM)); result->o_type = TEMP; if (lval->o_value.ov_char.ovc_type == TCHAR) i = comp(lval,rval); else i = ncomp(lval,rval); switch (cmp) { case LSS: i = (i < 0); break; case LEQ: i = (i <= 0); break; case EQL: i = (i == 0); break; case GEQ: i = (i >= 0); break; case GTR: i = (i > 0); break; case NEQ: i = (i != 0); break; } result->o_value.ov_boolean = i; *sptr++ = result; if (lval->o_type == TEMP) free(lval); if (rval->o_type == TEMP) free(rval); return (TRUE); } static int comp(lval,rval) struct operand *lval,*rval; { char *lptr,*rptr; int lctr,rctr; int len; lptr = lval->o_value.ov_char.ovc_string; lctr = lval->o_value.ov_char.ovc_length; rptr = rval->o_value.ov_char.ovc_string; rctr = rval->o_value.ov_char.ovc_length; while (lctr > 0 && (lptr[lctr-1] == 0 || lptr[lctr-1] == ' ')) lctr--; while (rctr > 0 && (rptr[rctr-1] == 0 || rptr[rctr-1] == ' ')) rctr--; if (lctr < rctr) len = lctr; else len = rctr; while ((len--) > 0) { if (*lptr++ != *rptr++) if (*--lptr < *--rptr) return (-1); else return (1); } if (lctr == rctr) return (0); else if (lctr < rctr) return (-1); else return (1); } static int ncomp(lval,rval) struct operand *lval,*rval; { char lstr[NUMBERMAX+1],rstr[NUMBERMAX+1]; int len; strncpy(lstr,lval->o_value.ov_char.ovc_string, (len = lval->o_value.ov_char.ovc_length)); lstr[len] = EOS; strncpy(rstr,rval->o_value.ov_char.ovc_string, (len = rval->o_value.ov_char.ovc_length)); rstr[len] = EOS; return (db_cmp(lstr,rstr)); }