/* * Skip over an identifier. */ static const char * skipsym(const char *cp) { while (!endsym(*cp)) ++cp; return (cp); }
/* * Function for evaluating the innermost parts of expressions, * viz. !expr (expr) number defined(symbol) symbol * We reset the constexpr flag in the last two cases. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) { const char *cp; char *ep; int sym; bool defparen; Linetype lt; cp = skipcomment(*cpp); if (*cp == '!') { debug("eval%d !", prec(ops)); cp++; lt = eval_unary(ops, valp, &cp); if (lt == LT_ERROR) return (LT_ERROR); if (lt != LT_IF) { *valp = !*valp; lt = *valp ? LT_TRUE : LT_FALSE; } } else if (*cp == '(') { cp++; debug("eval%d (", prec(ops)); lt = eval_table(eval_ops, valp, &cp); if (lt == LT_ERROR) return (LT_ERROR); cp = skipcomment(cp); if (*cp++ != ')') return (LT_ERROR); } else if (isdigit((unsigned char)*cp)) { debug("eval%d number", prec(ops)); *valp = strtol(cp, &ep, 0); if (ep == cp) return (LT_ERROR); lt = *valp ? LT_TRUE : LT_FALSE; cp = skipsym(cp); } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { cp = skipcomment(cp+7); debug("eval%d defined", prec(ops)); if (*cp == '(') { cp = skipcomment(cp+1); defparen = true; } else { defparen = false; } sym = findsym(cp); if (sym < 0) { lt = LT_IF; } else { *valp = (value[sym] != NULL); lt = *valp ? LT_TRUE : LT_FALSE; } cp = skipsym(cp); cp = skipcomment(cp); if (defparen && *cp++ != ')') return (LT_ERROR); constexpr = false; } else if (!endsym(*cp)) {
/* * Function for evaluating the innermost parts of expressions, * viz. !expr (expr) defined(symbol) symbol number * We reset the keepthis flag when we find a non-constant subexpression. */ static Linetype eval_unary(const struct ops *ops, int *valp, const char **cpp) { const char *cp; char *ep; int sym; cp = skipcomment(*cpp); if (*cp == '!') { debug("eval%d !", ops - eval_ops); cp++; if (eval_unary(ops, valp, &cp) == LT_IF) { *cpp = cp; return (LT_IF); } *valp = !*valp; } else if (*cp == '(') { cp++; debug("eval%d (", ops - eval_ops); if (eval_table(eval_ops, valp, &cp) == LT_IF) return (LT_IF); cp = skipcomment(cp); if (*cp++ != ')') return (LT_IF); } else if (isdigit((unsigned char)*cp)) { debug("eval%d number", ops - eval_ops); *valp = strtol(cp, &ep, 0); cp = skipsym(cp); } else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) { cp = skipcomment(cp+7); debug("eval%d defined", ops - eval_ops); if (*cp++ != '(') return (LT_IF); cp = skipcomment(cp); sym = findsym(cp); cp = skipsym(cp); cp = skipcomment(cp); if (*cp++ != ')') return (LT_IF); if (sym >= 0) *valp = (value[sym] != NULL); else { *cpp = cp; return (LT_IF); } keepthis = false; } else if (!endsym(*cp)) { debug("eval%d symbol", ops - eval_ops); sym = findsym(cp); if (sym < 0) return (LT_IF); if (value[sym] == NULL) *valp = 0; else { *valp = strtol(value[sym], &ep, 0); if (*ep != '\0' || ep == value[sym]) return (LT_IF); } cp = skipsym(cp); keepthis = false; } else { debug("eval%d bad expr", ops - eval_ops); return (LT_IF); } *cpp = cp; debug("eval%d = %d", ops - eval_ops, *valp); return (*valp ? LT_TRUE : LT_FALSE); }