mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-02-23 01:50:05 +00:00
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@6189 d0543943-73ff-0310-b7d9-9358b9ac24b2
330 lines
8.2 KiB
C
330 lines
8.2 KiB
C
/*
|
|
File: exprfunc.c
|
|
Auth: Brian Allen Vanderburg II
|
|
Date: Thursday, April 24, 2003
|
|
Desc: Expression function list routines
|
|
|
|
This file is part of ExprEval.
|
|
*/
|
|
|
|
|
|
|
|
/* Includes */
|
|
#include "exprincl.h"
|
|
|
|
#include "exprpriv.h"
|
|
#include "exprmem.h"
|
|
|
|
/* Internal functions */
|
|
static exprFunc *exprCreateFunc(char *name, exprFuncType ptr, int type, int min, int max, int refmin, int refmax);
|
|
static void exprFuncListFreeData(exprFunc *func);
|
|
|
|
|
|
/* This function creates the function list, */
|
|
int exprFuncListCreate(exprFuncList **flist)
|
|
{
|
|
exprFuncList *tmp;
|
|
|
|
if(flist == NULL)
|
|
return EXPR_ERROR_NULLPOINTER;
|
|
|
|
*flist = NULL; /* Set to NULL initially */
|
|
|
|
tmp = exprAllocMem(sizeof(exprFuncList));
|
|
|
|
if(tmp == NULL)
|
|
return EXPR_ERROR_MEMORY; /* Could not allocate memory */
|
|
|
|
/* Update pointer */
|
|
*flist = tmp;
|
|
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
/* Add a function to the list */
|
|
int exprFuncListAdd(exprFuncList *flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax)
|
|
{
|
|
exprFunc *tmp;
|
|
exprFunc *cur;
|
|
int result;
|
|
|
|
if(flist == NULL)
|
|
return EXPR_ERROR_NULLPOINTER;
|
|
|
|
/* Make sure the name is valid */
|
|
if(!exprValidIdent(name))
|
|
return EXPR_ERROR_BADIDENTIFIER;
|
|
|
|
/* Fix values only if none are negative (negative values mean no limit) */
|
|
|
|
/* if both are neg, no min or max number of args */
|
|
/* if min is neg, max pos, no min number of args but a maximum */
|
|
/* if min is pos, max neg, there is a min number of args, but no max */
|
|
/* if both pos, then a min and max limit. We swap to make sure it works
|
|
right. I.E. Min of 3 and max of 2 would make function unusable */
|
|
if(min >= 0 && max >= 0)
|
|
{
|
|
if(min > max)
|
|
{
|
|
result = min;
|
|
min = max;
|
|
max = result;
|
|
}
|
|
}
|
|
|
|
if(refmin >= 0 && refmax >= 0)
|
|
{
|
|
if(refmin > refmax)
|
|
{
|
|
result = refmin;
|
|
refmin = max;
|
|
refmax = result;
|
|
}
|
|
}
|
|
|
|
if(flist->head == NULL)
|
|
{
|
|
/* Create the node right here */
|
|
tmp = exprCreateFunc(name, ptr, EXPR_NODETYPE_FUNCTION, min, max, refmin, refmax);
|
|
|
|
if(tmp == NULL)
|
|
return EXPR_ERROR_MEMORY;
|
|
|
|
flist->head = tmp;
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
/* See if it already exists */
|
|
cur = flist->head;
|
|
|
|
while(cur)
|
|
{
|
|
result = strcmp(name, cur->fname);
|
|
|
|
if(result == 0)
|
|
return EXPR_ERROR_ALREADYEXISTS;
|
|
|
|
cur = cur->next;
|
|
}
|
|
|
|
/* It did not exist, so add it at the head */
|
|
tmp = exprCreateFunc(name, ptr, EXPR_NODETYPE_FUNCTION, min, max, refmin, refmax);
|
|
|
|
if(tmp == NULL)
|
|
return EXPR_ERROR_MEMORY;
|
|
|
|
tmp->next = flist->head;
|
|
flist->head = tmp;
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
/* Add a function node type to the list
|
|
This works pretty much the same way, except the function
|
|
pointer is NULL and the node type specifies the function
|
|
to do. exprEvalNode handles this, instead of calling
|
|
a function solver. */
|
|
int exprFuncListAddType(exprFuncList *flist, char *name, int type, int min, int max, int refmin, int refmax)
|
|
{
|
|
exprFunc *tmp;
|
|
exprFunc *cur;
|
|
int result;
|
|
|
|
if(flist == NULL)
|
|
return EXPR_ERROR_NULLPOINTER;
|
|
|
|
/* Make sure the name is valid */
|
|
if(!exprValidIdent(name))
|
|
return EXPR_ERROR_BADIDENTIFIER;
|
|
|
|
/* Fix values only if none are negative (negative values mean no limit) */
|
|
|
|
/* if both are neg, no min or max number of args */
|
|
/* if min is neg, max pos, no min number of args but a maximum */
|
|
/* if min is pos, max neg, there is a min number of args, but no max */
|
|
/* if both pos, then a min and max limit. We swap to make sure it works
|
|
right. I.E. Min of 3 and max of 2 would make function unusable */
|
|
if(min >= 0 && max >= 0)
|
|
{
|
|
if(min > max)
|
|
{
|
|
result = min;
|
|
min = max;
|
|
max = result;
|
|
}
|
|
}
|
|
|
|
if(refmin >= 0 && refmax >= 0)
|
|
{
|
|
if(refmin > refmax)
|
|
{
|
|
result = refmin;
|
|
refmin = max;
|
|
refmax = result;
|
|
}
|
|
}
|
|
|
|
if(flist->head == NULL)
|
|
{
|
|
/* Create the node right here */
|
|
tmp = exprCreateFunc(name, NULL, type, min, max, refmin, refmax);
|
|
|
|
if(tmp == NULL)
|
|
return EXPR_ERROR_MEMORY;
|
|
|
|
flist->head = tmp;
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
/* See if it already exists */
|
|
cur = flist->head;
|
|
|
|
while(cur)
|
|
{
|
|
result = strcmp(name, cur->fname);
|
|
|
|
if(result == 0)
|
|
return EXPR_ERROR_ALREADYEXISTS;
|
|
|
|
cur = cur->next;
|
|
}
|
|
|
|
/* It did not exist, so add it at the head */
|
|
tmp = exprCreateFunc(name, NULL, type, min, max, refmin, refmax);
|
|
|
|
if(tmp == NULL)
|
|
return EXPR_ERROR_MEMORY;
|
|
|
|
tmp->next = flist->head;
|
|
flist->head = tmp;
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
|
|
/* Get the function from a list along with it's min an max data */
|
|
int exprFuncListGet(exprFuncList *flist, char *name, exprFuncType *ptr, int *type, int *min, int *max, int *refmin, int *refmax)
|
|
{
|
|
exprFunc *cur;
|
|
int result;
|
|
|
|
if(flist == NULL)
|
|
return EXPR_ERROR_NULLPOINTER;
|
|
|
|
if(name == NULL || name[0] == '\0')
|
|
return EXPR_ERROR_NOTFOUND;
|
|
|
|
/* Search for the item */
|
|
cur = flist->head;
|
|
|
|
while(cur)
|
|
{
|
|
result = strcmp(name, cur->fname);
|
|
|
|
if(result == 0)
|
|
{
|
|
/* We found it. */
|
|
*ptr = cur->fptr;
|
|
*min = cur->min;
|
|
*max = cur->max;
|
|
*refmin = cur->refmin;
|
|
*refmax = cur->refmax;
|
|
*type = cur->type;
|
|
|
|
/* return now */
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
cur = cur->next;
|
|
}
|
|
|
|
/* If we got here, we did not find the item in the list */
|
|
return EXPR_ERROR_NOTFOUND;
|
|
}
|
|
|
|
/* This routine will free the function list */
|
|
int exprFuncListFree(exprFuncList *flist)
|
|
{
|
|
/* Make sure it exists, if not it is not error */
|
|
if(flist == NULL)
|
|
return EXPR_ERROR_NOERROR;
|
|
|
|
/* Free the nodes */
|
|
exprFuncListFreeData(flist->head);
|
|
|
|
/* Free the container */
|
|
exprFreeMem(flist);
|
|
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
/* This routine will clear the function list */
|
|
int exprFuncListClear(exprFuncList *flist)
|
|
{
|
|
if(flist == NULL)
|
|
return EXPR_ERROR_NOERROR;
|
|
|
|
/* Free the nodes only */
|
|
if(flist->head)
|
|
{
|
|
exprFuncListFreeData(flist->head);
|
|
|
|
flist->head = NULL;
|
|
}
|
|
|
|
return EXPR_ERROR_NOERROR;
|
|
}
|
|
|
|
/* This routine will free any child nodes, and then free itself */
|
|
void exprFuncListFreeData(exprFunc *func)
|
|
{
|
|
exprFunc *next;
|
|
|
|
while(func)
|
|
{
|
|
/* Remember the next item */
|
|
next = func->next;
|
|
|
|
/* Free name */
|
|
exprFreeMem(func->fname);
|
|
|
|
/* Free ourself */
|
|
exprFreeMem(func);
|
|
|
|
func = next;
|
|
}
|
|
}
|
|
|
|
/* This routine will create the function object */
|
|
exprFunc *exprCreateFunc(char *name, exprFuncType ptr, int type, int min, int max, int refmin, int refmax)
|
|
{
|
|
exprFunc *tmp;
|
|
char *vtmp;
|
|
|
|
/* We already checked the name in exprFuncListAdd */
|
|
|
|
/* Create it */
|
|
tmp = exprAllocMem(sizeof(exprFunc));
|
|
if(tmp == NULL)
|
|
return NULL;
|
|
|
|
/* Allocate space for the name */
|
|
vtmp = exprAllocMem(strlen(name) + 1);
|
|
|
|
if(vtmp == NULL)
|
|
{
|
|
exprFreeMem(tmp);
|
|
return NULL;
|
|
}
|
|
|
|
/* Copy the data over */
|
|
strcpy(vtmp, name);
|
|
tmp->fname = vtmp;
|
|
tmp->fptr = ptr;
|
|
tmp->min = min;
|
|
tmp->max = max;
|
|
tmp->refmin = refmin;
|
|
tmp->refmax = refmax;
|
|
tmp->type = type;
|
|
|
|
return tmp;
|
|
}
|