freeswitch/src/mod/applications/mod_expr/exprobj.c

229 lines
4.4 KiB
C

/*
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;
}
}