*/
#include "squid.h"
+#include "Debug.h"
#include "esi/Expression.h"
+#include "profiler/Profiler.h"
+
+#if HAVE_MATH_H
+#include <math.h>
+#endif
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
/* stack precedence rules:
* before pushing an operator onto the stack, the
typedef struct _stackmember stackmember;
-typedef int evaluate (stackmember * stack, int *depth, int whereAmI,
- stackmember * candidate);
+typedef int evaluate(stackmember * stack, int *depth, int whereAmI,
+ stackmember * candidate);
typedef enum {
ESI_EXPR_INVALID,
int precedence;
};
-static void cleanmember (stackmember *);
-static void stackpop (stackmember * s, int *depth);
+static void cleanmember(stackmember *);
+static void stackpop(stackmember * s, int *depth);
void
-cleanmember (stackmember * s)
+cleanmember(stackmember * s)
{
if (s->valuetype == ESI_EXPR_LITERAL
&& s->valuestored == ESI_LITERAL_STRING) {
- safe_free (s->value.string);
+ safe_free(s->value.string);
s->value.string = NULL;
}
}
void
-stackpop (stackmember * s, int *depth)
+stackpop(stackmember * s, int *depth)
{
if (!(*depth)--)
return;
- cleanmember (&s[*depth]);
+ cleanmember(&s[*depth]);
}
static evaluate evalnegate;
static evaluate evalstartexpr;
static evaluate evalendexpr;
static evaluate evalexpr;
-static void dumpstack (stackmember * stack, int depth);
-static int addmember (stackmember * stack, int *stackdepth,
- stackmember * candidate);
-static int membercompare (stackmember a, stackmember b);
-static char const *trim (char const *s);
-static stackmember getsymbol (const char *s, char const **endptr);
-static void printliteral (stackmember s);
-static void printmember (stackmember s);
+static void dumpstack(stackmember * stack, int depth);
+static int addmember(stackmember * stack, int *stackdepth,
+ stackmember * candidate);
+static int membercompare(stackmember a, stackmember b);
+static char const *trim(char const *s);
+static stackmember getsymbol(const char *s, char const **endptr);
+static void printliteral(stackmember s);
+static void printmember(stackmember s);
/* -2 = failed to compate
* -1 = a less than b
* 2 - a more than b
*/
int
-membercompare (stackmember a, stackmember b)
+membercompare(stackmember a, stackmember b)
{
/* we can compare: sub expressions to sub expressions ,
* literals to literals
return 1;
} else if (a.valuestored == ESI_LITERAL_STRING) {
if (b.valuestored == ESI_LITERAL_STRING) {
- int i =strcmp (a.value.string, b.value.string);
+ int i =strcmp(a.value.string, b.value.string);
if (i < 0)
return -1;
return 0;
} else {
/* TODO: numeric to string conversion ? */
- debugs(86, 1, "strcmp with non-string");
+ debugs(86, DBG_IMPORTANT, "strcmp with non-string");
return -2;
}
} else if (a.valuestored == ESI_LITERAL_FLOAT) {
return 1;
} else {
/* TODO: attempt numeric converson again? */
- debugs(86, 1, "floatcomp with non float or int");
+ debugs(86, DBG_IMPORTANT, "floatcomp with non float or int");
return -2;
}
} else if (a.valuestored == ESI_LITERAL_INT) {
return 1;
} else {
/* TODO: attempt numeric converson again? */
- debugs(86, 1, "intcomp vs non float non int");
+ debugs(86, DBG_IMPORTANT, "intcomp vs non float non int");
return -2;
}
}
}
/* return 0 on success, 1 on failure */
-int evalnegate
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalnegate(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
if (whereAmI != *depth - 2)
/* invalid stack */
stack[whereAmI] = stack[(*depth)];
- cleanmember (candidate);
+ cleanmember(candidate);
if (stack[whereAmI].value.integral == 1)
stack[whereAmI].value.integral = 0;
return 0;
}
-int evalliteral
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalliteral(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
- debugs(86, 1, "attempt to evaluate a literal");
+ debugs(86, DBG_IMPORTANT, "attempt to evaluate a literal");
/* literals can't be evaluated */
return 1;
}
-int evalexpr
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalexpr(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
- debugs(86, 1, "attempt to evaluate a sub-expression result");
+ debugs(86, DBG_IMPORTANT, "attempt to evaluate a sub-expression result");
/* sub-scpr's can't be evaluated */
return 1;
}
-
-int evalor
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalor(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
return 0;
}
-int evaland
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evaland(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
return 0;
}
-int evallesseq
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evallesseq(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid stack */
return 1;
- rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+ rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
if (rv == -2)
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
- /* debugs(86, 1, "?= " << srv.value.integral << " "); */
+ /* debugs(86, DBG_IMPORTANT, "?= " << srv.value.integral << " "); */
return 0;
-
}
-int evallessthan
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evallessthan(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid stack */
return 1;
- rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+ rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
if (rv == -2)
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
- /* debugs(86, 1, "?= " << srv.value.integral << " "); */
+ /* debugs(86, DBG_IMPORTANT, "?= " << srv.value.integral << " "); */
return 0;
-
}
-int evalmoreeq
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalmoreeq(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid stack */
return 1;
- rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+ rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
if (rv == -2)
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
- /* debugs(86, 1, "?= " << srv.value.integral << " "); */
+ /* debugs(86, DBG_IMPORTANT, "?= " << srv.value.integral << " "); */
return 0;
-
}
-int evalmorethan
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalmorethan(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid stack */
return 1;
- rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+ rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
if (rv == -2)
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
- /* debugs(86, 1, "?= " << srv.value.integral << " "); */
+ /* debugs(86, DBG_IMPORTANT, "?= " << srv.value.integral << " "); */
return 0;
}
int
-evalequals (stackmember * stack, int *depth, int whereAmI,
- stackmember * candidate)
+evalequals(stackmember * stack, int *depth, int whereAmI,
+ stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid stack */
return 1;
- rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+ rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
if (rv == -2)
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
- /* debugs(86, 1, "?= " << srv.value.integral << " "); */
+ /* debugs(86, DBG_IMPORTANT, "?= " << srv.value.integral << " "); */
return 0;
}
-int evalnotequals
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalnotequals(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
int rv;
stackmember srv;
/* invalid stack */
return 1;
- rv = membercompare (stack[whereAmI - 1], stack[whereAmI + 1]);
+ rv = membercompare(stack[whereAmI - 1], stack[whereAmI + 1]);
if (rv == -2)
/* invalid comparison */
return 1;
- stackpop (stack, depth); /* arg rhs */
+ stackpop(stack, depth); /* arg rhs */
- stackpop (stack, depth); /* me */
+ stackpop(stack, depth); /* me */
- stackpop (stack, depth); /* arg lhs */
+ stackpop(stack, depth); /* arg lhs */
srv.valuetype = ESI_EXPR_EXPR;
stack[(*depth)++] = srv;
/* we're out of way, try adding now */
- if (!addmember (stack, depth, candidate))
+ if (!addmember(stack, depth, candidate))
/* Something wrong upstream */
return 1;
- /* debugs(86, 1, "?= " << srv.value.integral << " "); */
+ /* debugs(86, DBG_IMPORTANT, "?= " << srv.value.integral << " "); */
return 0;
}
-int evalstartexpr
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalstartexpr(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
- /* debugs(86, 1, "?("); */
+ /* debugs(86, DBG_IMPORTANT, "?("); */
if (whereAmI != *depth - 2)
/* invalid stack */
stack[whereAmI] = stack[(*depth)];
- cleanmember (candidate);
+ cleanmember(candidate);
return 0;
}
-int evalendexpr
-(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
+int
+evalendexpr(stackmember * stack, int *depth, int whereAmI, stackmember * candidate)
{
/* Can't evaluate ) brackets */
return 1;
}
char const *
-trim (char const *s)
+trim(char const *s)
{
while (*s == ' ')
++s;
}
stackmember
-getsymbol (const char *s, char const **endptr)
+getsymbol(const char *s, char const **endptr)
{
stackmember rv;
char *end;
char const *origs = s;
/* trim whitespace */
- s = trim (s);
+ s = trim(s);
rv.eval = NULL; /* A literal */
rv.valuetype = ESI_EXPR_INVALID;
rv.valuestored = ESI_LITERAL_INVALID;
+ rv.precedence = 1; /* A literal */
if (('0' <= *s && *s <= '9') || *s == '-') {
- size_t length = strspn (s, "0123456789.");
+ size_t length = strspn(s, "0123456789.");
char const *point;
- if ((point = strchr (s, '.')) && point - s < (ssize_t)length) {
+ if ((point = strchr(s, '.')) && point - s < (ssize_t)length) {
/* floating point */
- rv.value.floating = strtod (s, &end);
+ errno=0; /* reset errno */
+ rv.value.floating = strtod(s, &end);
if (s == end || errno) {
/* Couldn't convert to float */
- debugs(86, 1, "failed to convert '" << s << "' to float ");
+ debugs(86, DBG_IMPORTANT, "failed to convert '" << s << "' to float ");
*endptr = origs;
} else {
- debugs (86,6, "found " << rv.value.floating << " of length " << end - s);
+ debugs(86,6, "found " << rv.value.floating << " of length " << end - s);
*endptr = end;
rv.eval = evalliteral;
rv.valuestored = ESI_LITERAL_FLOAT;
}
} else {
/* INT */
- rv.value.integral = strtol (s, &end, 0);
+ errno=0; /* reset errno */
+ rv.value.integral = strtol(s, &end, 0);
if (s == end || errno) {
/* Couldn't convert to int */
- debugs(86, 1, "failed to convert '" << s << "' to int ");
+ debugs(86, DBG_IMPORTANT, "failed to convert '" << s << "' to int ");
*endptr = origs;
} else {
- debugs (86,6, "found " << rv.value.integral << " of length " << end - s);
+ debugs(86,6, "found " << rv.value.integral << " of length " << end - s);
*endptr = end;
rv.eval = evalliteral;
rv.valuestored = ESI_LITERAL_INT;
++t;
if (!*t) {
- debugs(86, 1, "missing end \' in '" << s << "'");
+ debugs(86, DBG_IMPORTANT, "missing end \' in '" << s << "'");
*endptr = origs;
} else {
*endptr = t + 1;
/* Special case for zero length strings */
if (t - s - 1)
- rv.value.string = xstrndup (s + 1, t - s - 1);
+ rv.value.string = xstrndup(s + 1, t - s - 1);
else
- rv.value.string = static_cast<char *>(xcalloc (1,1));
+ rv.value.string = static_cast<char *>(xcalloc(1,1));
rv.eval = evalliteral;
rv.precedence = 5;
rv.eval = evalequals;
} else {
- debugs(86, 1, "invalid expr '" << s << "'");
+ debugs(86, DBG_IMPORTANT, "invalid expr '" << s << "'");
*endptr = origs;
}
} else if ('<' == *s) {
rv.precedence = 5;
rv.eval = evalmorethan;
}
- } else if (!strncmp (s, "false", 5)) {
+ } else if (!strncmp(s, "false", 5)) {
debugs(86, 5, "getsymbol: found variable result 'false'");
*endptr = s + 5;
rv.valuetype = ESI_EXPR_EXPR;
rv.value.integral = 0;
rv.precedence = 1;
rv.eval = evalexpr;
- } else if (!strncmp (s, "true", 4)) {
+ } else if (!strncmp(s, "true", 4)) {
debugs(86, 5, "getsymbol: found variable result 'true'");
*endptr = s + 4;
rv.valuetype = ESI_EXPR_EXPR;
rv.precedence = 1;
rv.eval = evalexpr;
} else {
- debugs(86, 1, "invalid expr '" << s << "'");
+ debugs(86, DBG_IMPORTANT, "invalid expr '" << s << "'");
*endptr = origs;
}
}
void
-printliteral (stackmember s)
+printliteral(stackmember s)
{
switch (s.valuestored) {
case ESI_LITERAL_INVALID:
- debug(86, 1) ( " Invalid " );
+ old_debug(86, 1)( " Invalid " );
break;
case ESI_LITERAL_FLOAT:
- debug (86,1) ("%f", s.value.floating);
+ old_debug(86,1)("%f", s.value.floating);
break;
case ESI_LITERAL_STRING:
- debug (86,1) ("'%s'", s.value.string);
+ old_debug(86,1)("'%s'", s.value.string);
break;
case ESI_LITERAL_INT:
- debug (86,1) ("%d", s.value.integral);
+ old_debug(86,1)("%d", s.value.integral);
break;
case ESI_LITERAL_BOOL:
- debug (86,1)("%s",s.value.integral ? "true" : "false");
+ old_debug(86,1)("%s",s.value.integral ? "true" : "false");
}
}
void
-printmember (stackmember s)
+printmember(stackmember s)
{
switch (s.valuetype) {
case ESI_EXPR_INVALID:
- debug (86,1) (" Invalid ");
+ old_debug(86,1)(" Invalid ");
break;
case ESI_EXPR_LITERAL:
- printliteral (s);
+ printliteral(s);
break;
case ESI_EXPR_EXPR:
- debug (86,1) ("%s", s.value.integral ? "true" : "false");
+ old_debug(86,1)("%s", s.value.integral ? "true" : "false");
break;
case ESI_EXPR_OR:
- debug (86,1) ("|");
+ old_debug(86,1)("|");
break;
case ESI_EXPR_AND:
- debug (86,1) ("&");
+ old_debug(86,1)("&");
break;
case ESI_EXPR_NOT:
- debug (86,1) ("!");
+ old_debug(86,1)("!");
break;
case ESI_EXPR_START:
- debug (86,1) ("(");
+ old_debug(86,1)("(");
break;
case ESI_EXPR_END:
- debug (86,1) (")");
+ old_debug(86,1)(")");
break;
case ESI_EXPR_EQ:
- debug (86,1) ("==");
+ old_debug(86,1)("==");
break;
case ESI_EXPR_NOTEQ:
- debug (86,1) ("!=");
+ old_debug(86,1)("!=");
break;
case ESI_EXPR_LESS:
- debug (86,1) ("<");
+ old_debug(86,1)("<");
break;
case ESI_EXPR_LESSEQ:
- debug (86,1) ("<=");
+ old_debug(86,1)("<=");
break;
case ESI_EXPR_MORE:
- debug (86,1) (">");
+ old_debug(86,1)(">");
break;
case ESI_EXPR_MOREEQ:
- debug (86,1) (">=");
+ old_debug(86,1)(">=");
break;
}
}
void
-dumpstack (stackmember * stack, int depth)
+dumpstack(stackmember * stack, int depth)
{
int i;
for (i = 0; i < depth; ++i)
- printmember (stack[i]);
+ printmember(stack[i]);
if (depth)
- debug (86,1) ("\n");
+ old_debug(86,1)("\n");
}
int
-addmember (stackmember * stack, int *stackdepth, stackmember * candidate)
+addmember(stackmember * stack, int *stackdepth, stackmember * candidate)
{
if (candidate->valuetype != ESI_EXPR_LITERAL && *stackdepth > 1) {
/* !(!(a==b))) is why thats safe */
if (stack[*stackdepth - 2].valuetype == ESI_EXPR_LITERAL ||
stack[*stackdepth - 2].valuetype == ESI_EXPR_INVALID ||
- stack[*stackdepth - 2].eval (stack, stackdepth,
- *stackdepth - 2, candidate)) {
+ stack[*stackdepth - 2].eval(stack, stackdepth,
+ *stackdepth - 2, candidate)) {
/* cleanup candidate and stack */
- dumpstack (stack, *stackdepth);
- cleanmember (candidate);
- debugs(86, 1, "invalid expression");
+ dumpstack(stack, *stackdepth);
+ cleanmember(candidate);
+ debugs(86, DBG_IMPORTANT, "invalid expression");
return 0;
}
} else {
}
int
-ESIExpression::Evaluate (char const *s)
+ESIExpression::Evaluate(char const *s)
{
stackmember stack[20];
int stackdepth = 0;
PROF_start(esiExpressionEval);
while (*s) {
- stackmember candidate = getsymbol (s, &end);
+ stackmember candidate = getsymbol(s, &end);
if (candidate.valuetype != ESI_EXPR_INVALID) {
- assert (s != end);
+ assert(s != end);
- if (!addmember (stack, &stackdepth, &candidate)) {
+ if (!addmember(stack, &stackdepth, &candidate)) {
PROF_stop(esiExpressionEval);
return 0;
}
s = end;
} else {
assert (s == end);
- debugs(86, 1, "failed parsing expression");
+ debugs(86, DBG_IMPORTANT, "failed parsing expression");
PROF_stop(esiExpressionEval);
return 0;
}
rv.precedence = 0;
if (stack[stackdepth - 2].
- eval (stack, &stackdepth, stackdepth - 2, &rv)) {
+ eval(stack, &stackdepth, stackdepth - 2, &rv)) {
/* special case - leading operator failed */
- debugs(86, 1, "invalid expression");
+ debugs(86, DBG_IMPORTANT, "invalid expression");
PROF_stop(esiExpressionEval);
return 0;
}
}
/* if we hit here, we think we have a valid result */
- assert (stackdepth == 1);
+ assert(stackdepth == 1);
- assert (stack[0].valuetype == ESI_EXPR_EXPR);
+ assert(stack[0].valuetype == ESI_EXPR_EXPR);
PROF_stop(esiExpressionEval);