summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/util_Expression.h64
-rw-r--r--src/include/utili_Expression.h82
-rw-r--r--src/util/Expression.c186
3 files changed, 183 insertions, 149 deletions
diff --git a/src/include/util_Expression.h b/src/include/util_Expression.h
index 85ead356..c8b524c4 100644
--- a/src/include/util_Expression.h
+++ b/src/include/util_Expression.h
@@ -16,66 +16,6 @@ extern "C"
{
#endif
- /* These data types are for internal use only. */
-
- /* Defined operators */
-typedef enum {OP_NONE,
- OP_EQUALS,
- OP_LESS_THAN,
- OP_GREATER_THAN,
- OP_LEQUALS,
- OP_GEQUALS,
- OP_AND,
- OP_OR,
- OP_PLUS,
- OP_MINUS,
- OP_DIV,
- OP_TIMES,
- OP_POWER,
- OP_ACOS,
- OP_ASIN,
- OP_ATAN,
- OP_CEIL,
- OP_COS,
- OP_COSH,
- OP_EXP,
- OP_FABS,
- OP_FLOOR,
- OP_LOG,
- OP_LOG10,
- OP_SIN,
- OP_SINH,
- OP_SQRT,
- OP_TAN,
- OP_TANH}
- uExpressionOpcode;
-
- /* What sort of expression types we have. */
-typedef enum {val,unary,binary} uExpressionType;
-
- /* RPN object. */
-typedef struct
-{
- uExpressionType type;
-
- union
- {
- uExpressionOpcode opcode;
- int varnum;
- } token;
-} uExpressionToken;
-
- /* Parsed expression object. */
-typedef struct
-{
- int ntokens;
- uExpressionToken *tokens;
- int nvars;
- const char **vars;
-} uExpressionInternals;
-
-/* Beginning of externally useable objects. */
-
/* Structure to hold values. */
typedef struct
{
@@ -88,8 +28,10 @@ typedef struct
} value;
} uExpressionValue;
+#ifndef __UTILI_EXPRESSION_H__
/* Externally visible representation of the expression. */
-typedef uExpressionInternals *uExpression;
+typedef void *uExpression;
+#endif /*__UTIL_EXPRESSION_H__ */
uExpression Util_ExpressionParse(const char *expression);
diff --git a/src/include/utili_Expression.h b/src/include/utili_Expression.h
new file mode 100644
index 00000000..b501ebad
--- /dev/null
+++ b/src/include/utili_Expression.h
@@ -0,0 +1,82 @@
+ /*@@
+ @header utili_Expression.h
+ @date Wed Nov 7 00:39:24 2001
+ @author Tom Goodale
+ @desc
+ Internal definitions for the expression parser.
+ @enddesc
+ @version $Header$
+ @@*/
+
+#ifndef __UTILI_EXPRESSION_H__
+#define __UTILI_EXPRESSION_H__ 1
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /* Defined operators */
+typedef enum {OP_NONE,
+ OP_EQUALS,
+ OP_LESS_THAN,
+ OP_GREATER_THAN,
+ OP_LEQUALS,
+ OP_GEQUALS,
+ OP_AND,
+ OP_OR,
+ OP_PLUS,
+ OP_MINUS,
+ OP_DIV,
+ OP_TIMES,
+ OP_POWER,
+ OP_ACOS,
+ OP_ASIN,
+ OP_ATAN,
+ OP_CEIL,
+ OP_COS,
+ OP_COSH,
+ OP_EXP,
+ OP_FABS,
+ OP_FLOOR,
+ OP_LOG,
+ OP_LOG10,
+ OP_SIN,
+ OP_SINH,
+ OP_SQRT,
+ OP_TAN,
+ OP_TANH}
+ uExpressionOpcode;
+
+ /* What sort of expression types we have. */
+typedef enum {val,unary,binary} uExpressionType;
+
+ /* RPN object. */
+typedef struct
+{
+ uExpressionType type;
+
+ union
+ {
+ uExpressionOpcode opcode;
+ int varnum;
+ } token;
+} uExpressionToken;
+
+ /* Parsed expression object. */
+typedef struct
+{
+ int ntokens;
+ uExpressionToken *tokens;
+ int nvars;
+ char **vars;
+} uExpressionInternals;
+
+ /* Internal representation of the expression. */
+typedef uExpressionInternals *uExpression;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UTIL_EXPRESSION_H__ */
diff --git a/src/util/Expression.c b/src/util/Expression.c
index b79b4706..ed881d69 100644
--- a/src/util/Expression.c
+++ b/src/util/Expression.c
@@ -20,6 +20,7 @@
#include <math.h>
+#include "utili_Expression.h"
#include "util_Expression.h"
static const char *rcsid = "$Header$";
@@ -254,10 +255,7 @@ uExpression Util_ExpressionParse(const char *expression)
@returntype int
@returndesc
0 - success
- The below used to be returned, but now expression is pre-verified.
- +ve - success but there were this number of remaining operation on the stack.
- -ve - the number of remaining items on the expression stack when an error was
- encountered
+ -1 - memory allocation failure
@endreturndesc
@@*/
@@ -279,98 +277,102 @@ int Util_ExpressionEvaluate(const uExpression buffer,
/* Assign memory for array to contain all variable values */
varvals = (uExpressionValue *)malloc(buffer->nvars*sizeof(uExpressionValue));
- if(varvals)
+ if(varvals || ! buffer->nvars)
{
/* Evaluate the variables in one go to help people doing parallel ops. */
eval(buffer->nvars, buffer->vars, varvals, data);
- }
-
- /* Tokens are seperated by @ signs */
- for(position = 0; position < buffer->ntokens; position++)
- {
- if(buffer->tokens[position].type == val)
- {
- /* Put value on stack */
- stack[stackpointer] = varvals[buffer->tokens[position].token.varnum];
- stackpointer++;
- }
- else
+ /* Tokens are seperated by @ signs */
+ for(position = 0; position < buffer->ntokens; position++)
{
+ if(buffer->tokens[position].type == val)
+ {
+ /* Put value on stack */
+ stack[stackpointer] = varvals[buffer->tokens[position].token.varnum];
+
+ stackpointer++;
+ }
+ else
+ {
#ifdef TEST_EXPRESSION_PARSER
- printf("Stackpointer is %d, ", stackpointer);
- if(buffer->tokens[position].type == binary)
- {
- switch(stack[stackpointer-2].type)
+ printf("Stackpointer is %d, ", stackpointer);
+ if(buffer->tokens[position].type == binary)
+ {
+ switch(stack[stackpointer-2].type)
+ {
+ case ival:
+ printf("%d " ,stack[stackpointer-2].value.ival); break;
+ case rval:
+ printf("%f " ,stack[stackpointer-2].value.rval); break;
+ default:
+ ;
+ }
+ }
+
+ printf("%s ", opname(buffer->tokens[position].token.opcode));
+ switch(stack[stackpointer-1].type)
{
case ival:
- printf("%d " ,stack[stackpointer-2].value.ival); break;
+ printf("%d " ,stack[stackpointer-1].value.ival); break;
case rval:
- printf("%f " ,stack[stackpointer-2].value.rval); break;
+ printf("%f " ,stack[stackpointer-1].value.rval); break;
default:
;
}
- }
-
- printf("%s ", opname(buffer->tokens[position].token.opcode));
- switch(stack[stackpointer-1].type)
- {
- case ival:
- printf("%d " ,stack[stackpointer-1].value.ival); break;
- case rval:
- printf("%f " ,stack[stackpointer-1].value.rval); break;
- default:
- ;
- }
- printf(" = ");
- fflush(stdout);
+ printf(" = ");
+ fflush(stdout);
#endif
- /* Evaluate operation, clear operands from stack and add the result to the stack. */
- switch(buffer->tokens[position].type)
- {
- case binary:
- EvaluateBinary(&(stack[stackpointer-2]),
- &(stack[stackpointer-2]),
- buffer->tokens[position].token.opcode,
- &(stack[stackpointer-1]));
- stackpointer--;
- break;
- case unary:
+ /* Evaluate operation, clear operands from stack and add the result to the stack. */
+ switch(buffer->tokens[position].type)
+ {
+ case binary:
+ EvaluateBinary(&(stack[stackpointer-2]),
+ &(stack[stackpointer-2]),
+ buffer->tokens[position].token.opcode,
+ &(stack[stackpointer-1]));
+ stackpointer--;
+ break;
+ case unary:
EvaluateUnary(&(stack[stackpointer-1]),
buffer->tokens[position].token.opcode,
&(stack[stackpointer-1]));
- break;
- default :
- ;
- }
-
+ break;
+ default :
+ ;
+ }
+
#ifdef TEST_EXPRESSION_PARSER
- switch(stack[stackpointer-1].type)
- {
- case ival:
- printf("%d\n" ,stack[stackpointer-1].value.ival); break;
- case rval:
- printf("%f\n" ,stack[stackpointer-1].value.rval); break;
- default:
- ;
- }
+ switch(stack[stackpointer-1].type)
+ {
+ case ival:
+ printf("%d\n" ,stack[stackpointer-1].value.ival); break;
+ case rval:
+ printf("%f\n" ,stack[stackpointer-1].value.rval); break;
+ default:
+ ;
+ }
#endif
+ }
+ }
+ if(varvals)
+ {
+ free(varvals);
}
- }
-
- if(varvals)
- {
- free(varvals);
- }
- *retval=stack[0];
+ *retval=stack[0];
+ /* stackpointer should be 1 at this point if VerifyExpression
+ * was called on the expression.
+ */
- /* stackpointer should be 1 at this point if VerifyExpression
- * was called on the expression.
- */
+ retcode = stackpointer-1;
+ }
+ else
+ {
+ /* memory failure */
- retcode = stackpointer-1;
+ retcode = -1;
+ }
return retcode;
}
@@ -406,7 +408,7 @@ void Util_ExpressionFree(uExpression buffer)
for(i = 0; i < buffer->nvars; i++)
{
- free((char *)(buffer->vars[i]));
+ free(buffer->vars[i]);
}
free(buffer->vars);
}
@@ -541,25 +543,33 @@ static pToken *Tokenise(const char *expression)
/* Create a new token */
new = newtoken(tokenstart, tokenend);
- /* Insert on list */
- if(current)
- {
- insertafter(current, new);
- }
- current = new;
-
- if(!start)
+ if(new)
{
- start = current;
- }
+ /* Insert on list */
+ if(current)
+ {
+ insertafter(current, new);
+ }
+ current = new;
+
+ if(!start)
+ {
+ start = current;
+ }
- if(*tokenend)
- {
- tokenstart = tokenend+1;
+ if(*tokenend)
+ {
+ tokenstart = tokenend+1;
+ }
+ else
+ {
+ break;
+ }
}
else
{
- break;
+ fprintf(stderr, "Unable to allocate memory for new token !\n");
+ abort();
}
}