/* File: exprobj.c Auth: Brian Allen Vanderburg II Date: Tuesday, April 29, 2003 Desc: Functions for the exprObj type This file is part of ExprEval. */ /* Includes */ #include "exprincl.h" #include "exprpriv.h" #include "exprmem.h" /* Internal functions */ static void exprFreeNodeData(exprNode * node); /* Function to create an expression object */ int exprCreate(exprObj ** obj, exprFuncList * flist, exprValList * vlist, exprValList * clist, exprBreakFuncType breaker, void *userdata) { exprObj *tmp; /* Allocate memory for the object */ tmp = exprAllocMem(sizeof(exprObj)); if (tmp == NULL) return EXPR_ERROR_MEMORY; /* Assign data */ tmp->flist = flist; tmp->vlist = vlist; tmp->clist = clist; tmp->breakerfunc = breaker; tmp->userdata = userdata; tmp->breakcount = 100000; /* Default breaker count setting */ tmp->breakcur = 0; /* Update pointer */ *obj = tmp; return EXPR_ERROR_NOERROR; } /* Free the expression */ int exprFree(exprObj * obj) { if (obj == NULL) return EXPR_ERROR_NOERROR; /* First free the node data */ exprFreeNodeData(obj->headnode); exprFreeMem(obj->headnode); /* Free ourself */ exprFreeMem(obj); return EXPR_ERROR_NOERROR; } /* Clear expression, keep lists, etc */ int exprClear(exprObj * obj) { if (obj == NULL) return EXPR_ERROR_NOERROR; /* Free the node data only, keep function, variable, constant lists */ exprFreeNodeData(obj->headnode); exprFreeMem(obj->headnode); obj->headnode = NULL; obj->parsedbad = 0; obj->parsedgood = 0; return EXPR_ERROR_NOERROR; } /* Get functions to get information about the expression object */ /* Get the function list */ exprFuncList *exprGetFuncList(exprObj * obj) { return (obj == NULL) ? NULL : obj->flist; } /* Get the variable list */ exprValList *exprGetVarList(exprObj * obj) { return (obj == NULL) ? NULL : obj->vlist; } /* Get the constant list */ exprValList *exprGetConstList(exprObj * obj) { return (obj == NULL) ? NULL : obj->clist; } /* Get the breaker function */ exprBreakFuncType exprGetBreakFunc(exprObj * obj) { return (obj == NULL) ? NULL : obj->breakerfunc; } /* Check for break status */ int exprGetBreakResult(exprObj * obj) { if (obj == NULL) return 0; if (obj->breakerfunc == NULL) return 0; return (*(obj->breakerfunc)) (obj); } /* Get the user data */ void *exprGetUserData(exprObj * obj) { return (obj == NULL) ? NULL : obj->userdata; } /* Set functions to set certain data */ /* Set user data */ void exprSetUserData(exprObj * obj, void *userdata) { if (obj) obj->userdata = userdata; } /* Set breaker count */ void exprSetBreakCount(exprObj * obj, int count) { if (obj) { /* If count is negative, make it positive */ if (count < 0) count = -count; obj->breakcount = count; /* Make sure the current value is not bigger than count */ if (obj->breakcur > count) obj->breakcur = count; } } /* Get error position */ void exprGetErrorPosition(exprObj * obj, int *start, int *end) { if (obj) { if (start) *start = obj->starterr; if (end) *end = obj->enderr; } } /* This function will free a node's data */ static void exprFreeNodeData(exprNode * node) { int pos; if (node == NULL) return; /* free data based on type */ switch (node->type) { case EXPR_NODETYPE_ADD: case EXPR_NODETYPE_SUBTRACT: case EXPR_NODETYPE_MULTIPLY: case EXPR_NODETYPE_DIVIDE: case EXPR_NODETYPE_EXPONENT: case EXPR_NODETYPE_NEGATE: case EXPR_NODETYPE_MULTI: /* Free operation data */ if (node->data.oper.nodes) { for (pos = 0; pos < node->data.oper.nodecount; pos++) exprFreeNodeData(&(node->data.oper.nodes[pos])); exprFreeMem(node->data.oper.nodes); } break; case EXPR_NODETYPE_VALUE: /* Nothing to free for value */ break; case EXPR_NODETYPE_VARIABLE: /* Nothing to free for variable */ break; case EXPR_NODETYPE_FUNCTION: /* Free data of each subnode */ if (node->data.function.nodes) { for (pos = 0; pos < node->data.function.nodecount; pos++) exprFreeNodeData(&(node->data.function.nodes[pos])); /* Free the subnode array */ exprFreeMem(node->data.function.nodes); } /* Free reference variable list */ if (node->data.function.refs) exprFreeMem(node->data.function.refs); break; case EXPR_NODETYPE_ASSIGN: /* Free subnode data */ if (node->data.assign.node) { exprFreeNodeData(node->data.assign.node); /* Free the subnode */ exprFreeMem(node->data.assign.node); } break; } }