[Freeswitch-svn] [commit] r6242 - freeswitch/trunk/src/mod/applications/mod_expr

Freeswitch SVN mikej at freeswitch.org
Tue Nov 13 15:23:27 EST 2007


Author: mikej
Date: Tue Nov 13 15:23:26 2007
New Revision: 6242

Modified:
   freeswitch/trunk/src/mod/applications/mod_expr/conio.h
   freeswitch/trunk/src/mod/applications/mod_expr/exprconf.h
   freeswitch/trunk/src/mod/applications/mod_expr/expreval.c
   freeswitch/trunk/src/mod/applications/mod_expr/expreval.h
   freeswitch/trunk/src/mod/applications/mod_expr/exprfunc.c
   freeswitch/trunk/src/mod/applications/mod_expr/exprilfs.h
   freeswitch/trunk/src/mod/applications/mod_expr/exprincl.h
   freeswitch/trunk/src/mod/applications/mod_expr/exprinit.c
   freeswitch/trunk/src/mod/applications/mod_expr/exprmem.c
   freeswitch/trunk/src/mod/applications/mod_expr/exprmem.h
   freeswitch/trunk/src/mod/applications/mod_expr/exprobj.c
   freeswitch/trunk/src/mod/applications/mod_expr/exprpars.c
   freeswitch/trunk/src/mod/applications/mod_expr/exprpriv.h
   freeswitch/trunk/src/mod/applications/mod_expr/exprutil.c
   freeswitch/trunk/src/mod/applications/mod_expr/exprval.c

Log:
dos2unix

Modified: freeswitch/trunk/src/mod/applications/mod_expr/conio.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/conio.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/conio.h	Tue Nov 13 15:23:26 2007
@@ -1,161 +1,161 @@
-/* A conio implementation for Mingw/Dev-C++.
- *
- * Written by:
- * Hongli Lai <hongli at telekabel.nl>
- * tkorrovi <tkorrovi at altavista.net> on 2002/02/26. 
- * Andrew Westcott <ajwestco at users.sourceforge.net>
- *
- * Offered for use in the public domain without any warranty.
- */
-
-#ifndef _CONIO_H_
-#define _CONIO_H_
-
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define BLINK 0
-
-typedef enum
-{
-    BLACK,
-    BLUE,
-    GREEN,
-    CYAN,
-    RED,
-    MAGENTA,
-    BROWN,
-    LIGHTGRAY,
-    DARKGRAY,
-    LIGHTBLUE,
-    LIGHTGREEN,
-    LIGHTCYAN,
-    LIGHTRED,
-    LIGHTMAGENTA,
-    YELLOW,
-    WHITE
-} COLORS;
-
-
-#define cgets	_cgets
-#define cprintf	_cprintf
-#define cputs	_cputs
-#define cscanf	_cscanf
-#define ScreenClear clrscr
-
-/* blinkvideo */
-
-void clreol (void);
-void clrscr (void);
-
-int _conio_gettext (int left, int top, int right, int bottom,
-                    char *str);
-/* _conio_kbhit */
-
-void delline (void);
-
-/* gettextinfo */
-void gotoxy(int x, int y);
-/*
-highvideo
-insline
-intensevideo
-lowvideo
-movetext
-normvideo
-*/
-
-void gotoxy(int x, int y);
-
-void puttext (int left, int top, int right, int bottom, char *str);
-
-// Screen Variables
-
-/* ScreenCols
-ScreenGetChar
-ScreenGetCursor
-ScreenMode
-ScreenPutChar
-ScreenPutString
-ScreenRetrieve
-ScreenRows
-ScreenSetCursor
-ScreenUpdate
-ScreenUpdateLine
-ScreenVisualBell
-_set_screen_lines */
-
-void _setcursortype (int type);
-
-void textattr (int _attr);
-
-void textbackground (int color);
-
-void textcolor (int color);
-
-/* textmode */
-
-int wherex (void);
-
-int wherey (void);
-
-/* window */
-
-
-
-/*  The code below was part of Mingw's conio.h  */
-/*
- * conio.h
- *
- * Low level console I/O functions. Pretty please try to use the ANSI
- * standard ones if you are writing new code.
- *
- * This file is part of the Mingw32 package.
- *
- * Contributors:
- *  Created by Colin Peters <colin at bird.fu.is.saga-u.ac.jp>
- *
- *  THIS SOFTWARE IS NOT COPYRIGHTED
- *
- *  This source code is offered for use in the public domain. You may
- *  use, modify or distribute it freely.
- *
- *  This code is distributed in the hope that it will be useful but
- *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
- *  DISCLAMED. This includes but is not limited to warranties of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Revision: 1.4 $
- * $Author: hongli $
- * $Date: 2002/04/26 19:31:25 $
- *
- */
-
-char*	_cgets (char*);
-int	_cprintf (const char*, ...);
-int	_cputs (const char*);
-int	_cscanf (char*, ...);
-
-int	_getch (void);
-int	_getche (void);
-int	_kbhit (void);
-int	_putch (int);
-int	_ungetch (int);
-
-
-int	getch (void);
-int	getche (void);
-int	kbhit (void);
-int	putch (int);
-int	ungetch (int);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CONIO_H_ */
+/* A conio implementation for Mingw/Dev-C++.
+ *
+ * Written by:
+ * Hongli Lai <hongli at telekabel.nl>
+ * tkorrovi <tkorrovi at altavista.net> on 2002/02/26. 
+ * Andrew Westcott <ajwestco at users.sourceforge.net>
+ *
+ * Offered for use in the public domain without any warranty.
+ */
+
+#ifndef _CONIO_H_
+#define _CONIO_H_
+
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLINK 0
+
+typedef enum
+{
+    BLACK,
+    BLUE,
+    GREEN,
+    CYAN,
+    RED,
+    MAGENTA,
+    BROWN,
+    LIGHTGRAY,
+    DARKGRAY,
+    LIGHTBLUE,
+    LIGHTGREEN,
+    LIGHTCYAN,
+    LIGHTRED,
+    LIGHTMAGENTA,
+    YELLOW,
+    WHITE
+} COLORS;
+
+
+#define cgets	_cgets
+#define cprintf	_cprintf
+#define cputs	_cputs
+#define cscanf	_cscanf
+#define ScreenClear clrscr
+
+/* blinkvideo */
+
+void clreol (void);
+void clrscr (void);
+
+int _conio_gettext (int left, int top, int right, int bottom,
+                    char *str);
+/* _conio_kbhit */
+
+void delline (void);
+
+/* gettextinfo */
+void gotoxy(int x, int y);
+/*
+highvideo
+insline
+intensevideo
+lowvideo
+movetext
+normvideo
+*/
+
+void gotoxy(int x, int y);
+
+void puttext (int left, int top, int right, int bottom, char *str);
+
+// Screen Variables
+
+/* ScreenCols
+ScreenGetChar
+ScreenGetCursor
+ScreenMode
+ScreenPutChar
+ScreenPutString
+ScreenRetrieve
+ScreenRows
+ScreenSetCursor
+ScreenUpdate
+ScreenUpdateLine
+ScreenVisualBell
+_set_screen_lines */
+
+void _setcursortype (int type);
+
+void textattr (int _attr);
+
+void textbackground (int color);
+
+void textcolor (int color);
+
+/* textmode */
+
+int wherex (void);
+
+int wherey (void);
+
+/* window */
+
+
+
+/*  The code below was part of Mingw's conio.h  */
+/*
+ * conio.h
+ *
+ * Low level console I/O functions. Pretty please try to use the ANSI
+ * standard ones if you are writing new code.
+ *
+ * This file is part of the Mingw32 package.
+ *
+ * Contributors:
+ *  Created by Colin Peters <colin at bird.fu.is.saga-u.ac.jp>
+ *
+ *  THIS SOFTWARE IS NOT COPYRIGHTED
+ *
+ *  This source code is offered for use in the public domain. You may
+ *  use, modify or distribute it freely.
+ *
+ *  This code is distributed in the hope that it will be useful but
+ *  WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
+ *  DISCLAMED. This includes but is not limited to warranties of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $Revision: 1.4 $
+ * $Author: hongli $
+ * $Date: 2002/04/26 19:31:25 $
+ *
+ */
+
+char*	_cgets (char*);
+int	_cprintf (const char*, ...);
+int	_cputs (const char*);
+int	_cscanf (char*, ...);
+
+int	_getch (void);
+int	_getche (void);
+int	_kbhit (void);
+int	_putch (int);
+int	_ungetch (int);
+
+
+int	getch (void);
+int	getche (void);
+int	kbhit (void);
+int	putch (int);
+int	ungetch (int);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CONIO_H_ */

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprconf.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprconf.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprconf.h	Tue Nov 13 15:23:26 2007
@@ -1,29 +1,29 @@
-/*
-    File: exprconf.h
-    Auth: Brian Allen Vanderburg II
-    Date: Thursday, October 20, 2005
-    Desc: Configuration for ExprEval
-
-    This file is part of ExprEval.
-*/
-
-#ifndef __BAVII_EXPRCONF_H
-#define __BAVII_EXPRCONF_H
-
-/*
-    Error checking level
-
-    0: Don't check any errors (don't use errno).  Divide by 0
-    is avoided and the part that divides by 0 is 0. For example
-    '4+1/0' is 4.
-
-    1: Check math errors.
-*/
-#define EXPR_ERROR_LEVEL_NONE 0
-#define EXPR_ERROR_LEVEL_CHECK 1
-
-#ifndef EXPR_ERROR_LEVEL
-#define EXPR_ERROR_LEVEL EXPR_ERROR_LEVEL_CHECK
-#endif
-
-#endif /* __BAVII_EXPRCONF_H */
+/*
+    File: exprconf.h
+    Auth: Brian Allen Vanderburg II
+    Date: Thursday, October 20, 2005
+    Desc: Configuration for ExprEval
+
+    This file is part of ExprEval.
+*/
+
+#ifndef __BAVII_EXPRCONF_H
+#define __BAVII_EXPRCONF_H
+
+/*
+    Error checking level
+
+    0: Don't check any errors (don't use errno).  Divide by 0
+    is avoided and the part that divides by 0 is 0. For example
+    '4+1/0' is 4.
+
+    1: Check math errors.
+*/
+#define EXPR_ERROR_LEVEL_NONE 0
+#define EXPR_ERROR_LEVEL_CHECK 1
+
+#ifndef EXPR_ERROR_LEVEL
+#define EXPR_ERROR_LEVEL EXPR_ERROR_LEVEL_CHECK
+#endif
+
+#endif /* __BAVII_EXPRCONF_H */

Modified: freeswitch/trunk/src/mod/applications/mod_expr/expreval.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/expreval.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/expreval.c	Tue Nov 13 15:23:26 2007
@@ -1,268 +1,268 @@
-/*
-    File: expreval.c
-    Auth: Brian Allen Vanderburg II
-    Date: Wednesday, April 30, 2003
-    Desc: Evaluation routines for the ExprEval library
-
-    This file is part of ExprEval.
-*/
-
-/* Includes */
-#include "exprincl.h"
-
-#include "exprpriv.h"
-
-/* Defines for error checking */
-#include <errno.h>
-
-#if(EXPR_ERROR_LEVEL >= EXPR_ERROR_LEVEL_CHECK)
-#define EXPR_RESET_ERR() errno = 0
-#define EXPR_CHECK_ERR() if(errno) return EXPR_ERROR_OUTOFRANGE
-#else
-#define EXPR_RESET_ERR()
-#define EXPR_CHECK_ERR()
-#endif
-
-
-/* This routine will evaluate an expression */
-int exprEval(exprObj *obj, EXPRTYPE *val)
-    {
-    EXPRTYPE dummy;
-
-    if(val ==  NULL)
-        val = &dummy;
-
-    /* Make sure it was parsed successfully */
-    if(!obj->parsedbad && obj->parsedgood && obj->headnode)
-        {
-        /* Do NOT reset the break count.  Let is accumulate
-           between calls until breaker function is called */
-        return exprEvalNode(obj, obj->headnode, 0, val);
-        }
-    else
-        return EXPR_ERROR_BADEXPR;
-    }
-
-/* Evaluate a node */
-int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val)
-    {
-    int err;
-    int pos;
-    EXPRTYPE d1, d2;
-
-    if(obj == NULL || nodes == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    /* Update n to point to correct node */
-    nodes += curnode;
-
-    /* Check breaker count */
-    if(obj->breakcur-- <= 0)
-        {
-        /* Reset count before returning */
-        obj->breakcur = obj->breakcount;
-                
-        if(exprGetBreakResult(obj))
-            {
-            return EXPR_ERROR_BREAK;
-            }
-        }
-
-    switch(nodes->type)
-        {
-        case EXPR_NODETYPE_MULTI:
-            {
-            /* Multi for multiple expressions in one string */
-            for(pos = 0; pos < nodes->data.oper.nodecount; pos++)
-                {
-                err = exprEvalNode(obj, nodes->data.oper.nodes, pos, val);
-                if(err)
-                    return err;
-                }
-            break;
-            }
-
-        case EXPR_NODETYPE_ADD:
-            {
-            /* Addition */
-            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
-
-            if(!err)
-                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
-
-            if(!err)
-                *val = d1 + d2;
-            else
-                return err;
-
-            break;
-            }
-
-        case EXPR_NODETYPE_SUBTRACT:
-            {
-            /* Subtraction */
-            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
-            
-            if(!err)
-                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
-
-            if(!err)
-                *val = d1 - d2;
-            else
-                return err;
-
-            break;
-            }
-
-        case EXPR_NODETYPE_MULTIPLY:
-            {
-            /* Multiplication */
-            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
-
-            if(!err)
-                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
-
-            if(!err)
-                *val = d1 * d2;
-            else
-                return err;
-
-            break;
-            }
-
-        case EXPR_NODETYPE_DIVIDE:
-            {
-            /* Division */
-            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
-
-            if(!err)
-                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
-
-            if(!err)
-                {
-                if(d2 != 0.0)
-                    *val = d1 / d2;
-                else
-                    {
-#if(EXPR_ERROR_LEVEL >= EXPR_ERROR_LEVEL_CHECK)
-                    return EXPR_ERROR_DIVBYZERO;
-#else
-                    *val = 0.0;
-                    return EXPR_ERROR_NOERROR;
-#endif
-                    }
-                }
-            else
-                return err;
-
-            break;
-            }
-
-        case EXPR_NODETYPE_EXPONENT:
-            {
-            /* Exponent */
-            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
-
-            if(!err)
-                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
-
-            if(!err)
-                {
-                EXPR_RESET_ERR();
-                *val = pow(d1, d2);
-                EXPR_CHECK_ERR();
-                }
-            else
-                return err;
-
-            break;
-            }
-
-        case EXPR_NODETYPE_NEGATE:
-            {
-            /* Negative value */
-            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
-
-            if(!err)
-                *val = -d1;
-            else
-                return err;
-           
-            break;
-            }
-
-
-        case EXPR_NODETYPE_VALUE:
-            {
-            /* Directly access the value */
-            *val = nodes->data.value.value;
-            break;
-            }
-
-        case EXPR_NODETYPE_VARIABLE:
-            {
-            /* Directly access the variable or constant */
-            *val = *(nodes->data.variable.vaddr);
-            break;
-            }
-
-        case EXPR_NODETYPE_ASSIGN:
-            {
-            /* Evaluate assignment subnode */
-            err = exprEvalNode(obj, nodes->data.assign.node, 0, val);
-
-            if(!err)
-                {
-                /* Directly assign the variable */
-                *(nodes->data.assign.vaddr) = *val;
-                }
-            else
-                return err;
-            
-            break;
-            }
-
-        case EXPR_NODETYPE_FUNCTION:
-            {
-            /* Evaluate the function */
-            if(nodes->data.function.fptr == NULL)
-                {
-                /* No function pointer means we are not using
-                   function solvers.  See if the function has a
-                   type to solve directly. */
-                switch(nodes->data.function.type)
-                    {
-                    /* This is to keep the file from being too crowded.
-                       See exprilfs.h for the definitions. */
-#include "exprilfs.h"
-                   
-
-                    default:
-                        {
-                        return EXPR_ERROR_UNKNOWN;
-                        }
-                    }
-                }
-            else
-                {
-                /* Call the correct function */
-                return (*(nodes->data.function.fptr))(obj,
-                    nodes->data.function.nodes, nodes->data.function.nodecount,
-                    nodes->data.function.refs, nodes->data.function.refcount, val);
-                }
-
-            break;
-            }
-
-        default:
-            {
-            /* Unknown node type */
-            return EXPR_ERROR_UNKNOWN;
-            }
-        }
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-
-
+/*
+    File: expreval.c
+    Auth: Brian Allen Vanderburg II
+    Date: Wednesday, April 30, 2003
+    Desc: Evaluation routines for the ExprEval library
+
+    This file is part of ExprEval.
+*/
+
+/* Includes */
+#include "exprincl.h"
+
+#include "exprpriv.h"
+
+/* Defines for error checking */
+#include <errno.h>
+
+#if(EXPR_ERROR_LEVEL >= EXPR_ERROR_LEVEL_CHECK)
+#define EXPR_RESET_ERR() errno = 0
+#define EXPR_CHECK_ERR() if(errno) return EXPR_ERROR_OUTOFRANGE
+#else
+#define EXPR_RESET_ERR()
+#define EXPR_CHECK_ERR()
+#endif
+
+
+/* This routine will evaluate an expression */
+int exprEval(exprObj *obj, EXPRTYPE *val)
+    {
+    EXPRTYPE dummy;
+
+    if(val ==  NULL)
+        val = &dummy;
+
+    /* Make sure it was parsed successfully */
+    if(!obj->parsedbad && obj->parsedgood && obj->headnode)
+        {
+        /* Do NOT reset the break count.  Let is accumulate
+           between calls until breaker function is called */
+        return exprEvalNode(obj, obj->headnode, 0, val);
+        }
+    else
+        return EXPR_ERROR_BADEXPR;
+    }
+
+/* Evaluate a node */
+int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val)
+    {
+    int err;
+    int pos;
+    EXPRTYPE d1, d2;
+
+    if(obj == NULL || nodes == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    /* Update n to point to correct node */
+    nodes += curnode;
+
+    /* Check breaker count */
+    if(obj->breakcur-- <= 0)
+        {
+        /* Reset count before returning */
+        obj->breakcur = obj->breakcount;
+                
+        if(exprGetBreakResult(obj))
+            {
+            return EXPR_ERROR_BREAK;
+            }
+        }
+
+    switch(nodes->type)
+        {
+        case EXPR_NODETYPE_MULTI:
+            {
+            /* Multi for multiple expressions in one string */
+            for(pos = 0; pos < nodes->data.oper.nodecount; pos++)
+                {
+                err = exprEvalNode(obj, nodes->data.oper.nodes, pos, val);
+                if(err)
+                    return err;
+                }
+            break;
+            }
+
+        case EXPR_NODETYPE_ADD:
+            {
+            /* Addition */
+            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
+
+            if(!err)
+                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
+
+            if(!err)
+                *val = d1 + d2;
+            else
+                return err;
+
+            break;
+            }
+
+        case EXPR_NODETYPE_SUBTRACT:
+            {
+            /* Subtraction */
+            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
+            
+            if(!err)
+                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
+
+            if(!err)
+                *val = d1 - d2;
+            else
+                return err;
+
+            break;
+            }
+
+        case EXPR_NODETYPE_MULTIPLY:
+            {
+            /* Multiplication */
+            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
+
+            if(!err)
+                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
+
+            if(!err)
+                *val = d1 * d2;
+            else
+                return err;
+
+            break;
+            }
+
+        case EXPR_NODETYPE_DIVIDE:
+            {
+            /* Division */
+            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
+
+            if(!err)
+                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
+
+            if(!err)
+                {
+                if(d2 != 0.0)
+                    *val = d1 / d2;
+                else
+                    {
+#if(EXPR_ERROR_LEVEL >= EXPR_ERROR_LEVEL_CHECK)
+                    return EXPR_ERROR_DIVBYZERO;
+#else
+                    *val = 0.0;
+                    return EXPR_ERROR_NOERROR;
+#endif
+                    }
+                }
+            else
+                return err;
+
+            break;
+            }
+
+        case EXPR_NODETYPE_EXPONENT:
+            {
+            /* Exponent */
+            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
+
+            if(!err)
+                err = exprEvalNode(obj, nodes->data.oper.nodes, 1, &d2);
+
+            if(!err)
+                {
+                EXPR_RESET_ERR();
+                *val = pow(d1, d2);
+                EXPR_CHECK_ERR();
+                }
+            else
+                return err;
+
+            break;
+            }
+
+        case EXPR_NODETYPE_NEGATE:
+            {
+            /* Negative value */
+            err = exprEvalNode(obj, nodes->data.oper.nodes, 0, &d1);
+
+            if(!err)
+                *val = -d1;
+            else
+                return err;
+           
+            break;
+            }
+
+
+        case EXPR_NODETYPE_VALUE:
+            {
+            /* Directly access the value */
+            *val = nodes->data.value.value;
+            break;
+            }
+
+        case EXPR_NODETYPE_VARIABLE:
+            {
+            /* Directly access the variable or constant */
+            *val = *(nodes->data.variable.vaddr);
+            break;
+            }
+
+        case EXPR_NODETYPE_ASSIGN:
+            {
+            /* Evaluate assignment subnode */
+            err = exprEvalNode(obj, nodes->data.assign.node, 0, val);
+
+            if(!err)
+                {
+                /* Directly assign the variable */
+                *(nodes->data.assign.vaddr) = *val;
+                }
+            else
+                return err;
+            
+            break;
+            }
+
+        case EXPR_NODETYPE_FUNCTION:
+            {
+            /* Evaluate the function */
+            if(nodes->data.function.fptr == NULL)
+                {
+                /* No function pointer means we are not using
+                   function solvers.  See if the function has a
+                   type to solve directly. */
+                switch(nodes->data.function.type)
+                    {
+                    /* This is to keep the file from being too crowded.
+                       See exprilfs.h for the definitions. */
+#include "exprilfs.h"
+                   
+
+                    default:
+                        {
+                        return EXPR_ERROR_UNKNOWN;
+                        }
+                    }
+                }
+            else
+                {
+                /* Call the correct function */
+                return (*(nodes->data.function.fptr))(obj,
+                    nodes->data.function.nodes, nodes->data.function.nodecount,
+                    nodes->data.function.refs, nodes->data.function.refcount, val);
+                }
+
+            break;
+            }
+
+        default:
+            {
+            /* Unknown node type */
+            return EXPR_ERROR_UNKNOWN;
+            }
+        }
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+
+

Modified: freeswitch/trunk/src/mod/applications/mod_expr/expreval.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/expreval.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/expreval.h	Tue Nov 13 15:23:26 2007
@@ -1,127 +1,127 @@
-/*
-    File: expreval.h
-    Auth: Brian Allen Vanderburg II
-    Date: Thursday, April 24, 2003
-    Desc: Main include file for ExprEval library
-
-    This file is part of ExprEval.
-*/
-
-
-/* Include once */
-#ifndef __BAVII_EXPREVAL_H
-#define __BAVII_EXPREVAL_H
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Define type of data to use */
-typedef double EXPRTYPE;
-
-/* Defines for various things */
-
-/* Max id size */
-#define EXPR_MAXIDENTSIZE 255
-
-/* Error values */
-enum
-    {
-    EXPR_ERROR_UNKNOWN = -1, /* Unknown error */
-    EXPR_ERROR_NOERROR = 0, /* No Error */
-    EXPR_ERROR_MEMORY, /* Memory allocation failed */
-    EXPR_ERROR_NULLPOINTER, /* Null pointer passed to function */
-    EXPR_ERROR_NOTFOUND, /* Item not found in a list */
-    EXPR_ERROR_UNMATCHEDCOMMENT, /* Unmatched comment tags */
-    EXPR_ERROR_INVALIDCHAR, /* Invalid characters in expression */
-    EXPR_ERROR_ALREADYEXISTS, /* An item already called create */
-    EXPR_ERROR_ALREADYPARSEDBAD, /* Expression parsed already, but unsuccessfully. call free or clear */
-    EXPR_ERROR_ALREADYPARSEDGOOD, /* Expression parsed already, successfully, call free or clear */
-    EXPR_ERROR_EMPTYEXPR, /* Empty expression string passed to parse */
-    EXPR_ERROR_UNMATCHEDPAREN, /* Unmatched parenthesis */
-    EXPR_ERROR_SYNTAX, /* Syntax error in expression */
-    EXPR_ERROR_MISSINGSEMICOLON, /* Missing semicolon at end of expression */
-    EXPR_ERROR_BADIDENTIFIER, /* Identifier was to big or not formed right */
-    EXPR_ERROR_NOSUCHFUNCTION, /* Function does not exist in function list */
-    EXPR_ERROR_BADNUMBERARGUMENTS, /* Bad number of arguments in a function call */
-    EXPR_ERROR_BADEXPR, /* This is a bad expression to evaluate. It has not been parsed or has unsuccessfully */
-    EXPR_ERROR_UNABLETOASSIGN, /* Unable to do an assignment, maybe no variable list */
-    EXPR_ERROR_DIVBYZERO, /* Attempted a division by zero */
-    EXPR_ERROR_NOVARLIST, /* No variable list found but one is needed */
-    EXPR_ERROR_BREAK, /* Expression was broken by break function */
-    EXPR_ERROR_CONSTANTASSIGN, /* Assignment to a constant */
-    EXPR_ERROR_REFCONSTANT, /* Constant used as a reference parameter */
-    EXPR_ERROR_OUTOFRANGE, /* A bad value was passed to a function */
-
-    EXPR_ERROR_USER /* Custom errors should be larger than this */
-    };
-
-/* Macros */
-
-/* Forward declarations */
-typedef struct _exprNode exprNode;
-typedef struct _exprFuncList exprFuncList;
-typedef struct _exprValList exprValList;
-typedef struct _exprObj exprObj;
-
-/* Function types */
-typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);
-typedef int (*exprBreakFuncType)(exprObj *obj);
-
-
-
-/* Functions */
-
-/* Version information function */
-void exprGetVersion(int *major, int *minor);
-
-/* Functions for function lists */
-int exprFuncListCreate(exprFuncList **flist);
-int exprFuncListAdd(exprFuncList *flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax);
-int exprFuncListFree(exprFuncList *flist);
-int exprFuncListClear(exprFuncList *flist);
-int exprFuncListInit(exprFuncList *flist);
-
-/* Functions for value lists */
-int exprValListCreate(exprValList **vlist);
-int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);
-int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);
-int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val);
-int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr);
-int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr);
-void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);
-int exprValListFree(exprValList *vlist);
-int exprValListClear(exprValList *vlist);
-int exprValListInit(exprValList *vlist);
-
-/* Functions for expression objects */
-int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist,
-    exprBreakFuncType breaker, void *userdata);
-int exprFree(exprObj *obj);
-int exprClear(exprObj *obj);
-int exprParse(exprObj *obj, char *expr);
-int exprEval(exprObj *obj, EXPRTYPE *val);
-int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);
-exprFuncList *exprGetFuncList(exprObj *obj);
-exprValList *exprGetVarList(exprObj *obj);
-exprValList *exprGetConstList(exprObj *obj);
-exprBreakFuncType exprGetBreakFunc(exprObj *obj);
-int exprGetBreakResult(exprObj *obj);
-void* exprGetUserData(exprObj *obj);
-void exprSetUserData(exprObj *obj, void *userdata);
-void exprSetBreakCount(exprObj *obj, int count);
-void exprGetErrorPosition(exprObj *obj, int *start, int *end);
-
-/* Other useful routines */
-int exprValidIdent(char *name);
-
-/* Name mangling */
-#ifdef __cplusplus
-}
-#endif
-
-
-
-#endif /* __BAVII_EXPREVAL_H */
+/*
+    File: expreval.h
+    Auth: Brian Allen Vanderburg II
+    Date: Thursday, April 24, 2003
+    Desc: Main include file for ExprEval library
+
+    This file is part of ExprEval.
+*/
+
+
+/* Include once */
+#ifndef __BAVII_EXPREVAL_H
+#define __BAVII_EXPREVAL_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Define type of data to use */
+typedef double EXPRTYPE;
+
+/* Defines for various things */
+
+/* Max id size */
+#define EXPR_MAXIDENTSIZE 255
+
+/* Error values */
+enum
+    {
+    EXPR_ERROR_UNKNOWN = -1, /* Unknown error */
+    EXPR_ERROR_NOERROR = 0, /* No Error */
+    EXPR_ERROR_MEMORY, /* Memory allocation failed */
+    EXPR_ERROR_NULLPOINTER, /* Null pointer passed to function */
+    EXPR_ERROR_NOTFOUND, /* Item not found in a list */
+    EXPR_ERROR_UNMATCHEDCOMMENT, /* Unmatched comment tags */
+    EXPR_ERROR_INVALIDCHAR, /* Invalid characters in expression */
+    EXPR_ERROR_ALREADYEXISTS, /* An item already called create */
+    EXPR_ERROR_ALREADYPARSEDBAD, /* Expression parsed already, but unsuccessfully. call free or clear */
+    EXPR_ERROR_ALREADYPARSEDGOOD, /* Expression parsed already, successfully, call free or clear */
+    EXPR_ERROR_EMPTYEXPR, /* Empty expression string passed to parse */
+    EXPR_ERROR_UNMATCHEDPAREN, /* Unmatched parenthesis */
+    EXPR_ERROR_SYNTAX, /* Syntax error in expression */
+    EXPR_ERROR_MISSINGSEMICOLON, /* Missing semicolon at end of expression */
+    EXPR_ERROR_BADIDENTIFIER, /* Identifier was to big or not formed right */
+    EXPR_ERROR_NOSUCHFUNCTION, /* Function does not exist in function list */
+    EXPR_ERROR_BADNUMBERARGUMENTS, /* Bad number of arguments in a function call */
+    EXPR_ERROR_BADEXPR, /* This is a bad expression to evaluate. It has not been parsed or has unsuccessfully */
+    EXPR_ERROR_UNABLETOASSIGN, /* Unable to do an assignment, maybe no variable list */
+    EXPR_ERROR_DIVBYZERO, /* Attempted a division by zero */
+    EXPR_ERROR_NOVARLIST, /* No variable list found but one is needed */
+    EXPR_ERROR_BREAK, /* Expression was broken by break function */
+    EXPR_ERROR_CONSTANTASSIGN, /* Assignment to a constant */
+    EXPR_ERROR_REFCONSTANT, /* Constant used as a reference parameter */
+    EXPR_ERROR_OUTOFRANGE, /* A bad value was passed to a function */
+
+    EXPR_ERROR_USER /* Custom errors should be larger than this */
+    };
+
+/* Macros */
+
+/* Forward declarations */
+typedef struct _exprNode exprNode;
+typedef struct _exprFuncList exprFuncList;
+typedef struct _exprValList exprValList;
+typedef struct _exprObj exprObj;
+
+/* Function types */
+typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);
+typedef int (*exprBreakFuncType)(exprObj *obj);
+
+
+
+/* Functions */
+
+/* Version information function */
+void exprGetVersion(int *major, int *minor);
+
+/* Functions for function lists */
+int exprFuncListCreate(exprFuncList **flist);
+int exprFuncListAdd(exprFuncList *flist, char *name, exprFuncType ptr, int min, int max, int refmin, int refmax);
+int exprFuncListFree(exprFuncList *flist);
+int exprFuncListClear(exprFuncList *flist);
+int exprFuncListInit(exprFuncList *flist);
+
+/* Functions for value lists */
+int exprValListCreate(exprValList **vlist);
+int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);
+int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);
+int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val);
+int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr);
+int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr);
+void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);
+int exprValListFree(exprValList *vlist);
+int exprValListClear(exprValList *vlist);
+int exprValListInit(exprValList *vlist);
+
+/* Functions for expression objects */
+int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist,
+    exprBreakFuncType breaker, void *userdata);
+int exprFree(exprObj *obj);
+int exprClear(exprObj *obj);
+int exprParse(exprObj *obj, char *expr);
+int exprEval(exprObj *obj, EXPRTYPE *val);
+int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);
+exprFuncList *exprGetFuncList(exprObj *obj);
+exprValList *exprGetVarList(exprObj *obj);
+exprValList *exprGetConstList(exprObj *obj);
+exprBreakFuncType exprGetBreakFunc(exprObj *obj);
+int exprGetBreakResult(exprObj *obj);
+void* exprGetUserData(exprObj *obj);
+void exprSetUserData(exprObj *obj, void *userdata);
+void exprSetBreakCount(exprObj *obj, int count);
+void exprGetErrorPosition(exprObj *obj, int *start, int *end);
+
+/* Other useful routines */
+int exprValidIdent(char *name);
+
+/* Name mangling */
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* __BAVII_EXPREVAL_H */

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprfunc.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprfunc.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprfunc.c	Tue Nov 13 15:23:26 2007
@@ -1,329 +1,329 @@
-/*
-    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;
-    }
+/*
+    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;
+    }

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprilfs.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprilfs.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprilfs.h	Tue Nov 13 15:23:26 2007
@@ -1,1064 +1,1064 @@
-/*
-    File: exprilfs.h
-    Auth: Brian Allen Vanderburg II
-    Date: Tuesday, February 28, 2006
-    Desc: Inline Function Solvers for exprEvalNode
-
-    This file is part of ExprEval.
-*/
-
-/*
-    This is here to help prevent expreval.c from getting
-    too crowded.
-
-    Provided variables:
-    obj: expression object point
-    nodes: function node with paramters
-    d1, d2: variables
-    err: error
-    val: value pointer for resuld
-    pos: integer
-
-    Also EXPR_RESET_ERR() and EXPR_CHECK_ERR()
-
-    The chunks below are included inside a statement that looks like this:
-
-    switch(nodes->data.function.type)
-        {
-        #include "exprilfs.h"
-
-        default:
-            {
-            return EXPR_ERROR_UNKNOWN;
-            }
-        }
-*/
-
-
-
-/* abs */
-case EXPR_NODEFUNC_ABS:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        if(d1 >= 0)
-            *val = d1;
-        else
-            *val = -d1;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* mod */
-case EXPR_NODEFUNC_MOD:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = fmod(d1, d2);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* ipart */
-case EXPR_NODEFUNC_IPART:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        modf(d1, val);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* fpart */
-case EXPR_NODEFUNC_FPART:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = modf(d1, &d2);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* min */
-case EXPR_NODEFUNC_MIN:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        for(pos = 1; pos < nodes->data.function.nodecount; pos++)
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d2);
-            if(!err)
-                {
-                if(d2 < d1)
-                    d1 = d2;
-                }
-            else
-                return err;
-            }
-        }
-    else
-        return err;
-
-    *val = d1;
-
-    break;
-    }
-
-/* max */
-case EXPR_NODEFUNC_MAX:
-    {
-    int pos;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        for(pos = 1; pos < nodes->data.function.nodecount; pos++)
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d2);
-            if(!err)
-                {
-                if(d2 > d1)
-                    d1 = d2;
-                }
-            else
-                return err;
-            }
-        }
-    else
-        return err;
-
-    *val = d1;
-
-    break;
-    }
-
-/* pow */
-case EXPR_NODEFUNC_POW:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = pow(d1, d2);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* sqrt */
-case EXPR_NODEFUNC_SQRT:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = sqrt(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* sin */
-case EXPR_NODEFUNC_SIN:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = sin(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* sinh */
-case EXPR_NODEFUNC_SINH:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = sinh(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* asin */
-case EXPR_NODEFUNC_ASIN:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = asin(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* cos */
-case EXPR_NODEFUNC_COS: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = cos(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* cosh */
-case EXPR_NODEFUNC_COSH: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = cosh(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* acos */
-case EXPR_NODEFUNC_ACOS: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = acos(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* tan */
-case EXPR_NODEFUNC_TAN: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = tan(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* tanh */
-case EXPR_NODEFUNC_TANH: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = tanh(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* atan */
-case EXPR_NODEFUNC_ATAN: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = atan(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* atan2 */
-case EXPR_NODEFUNC_ATAN2: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = atan2(d1, d2);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* log */
-case EXPR_NODEFUNC_LOG: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = log10(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* pow10 */
-case EXPR_NODEFUNC_POW10: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = pow(10.0, d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* ln */
-case EXPR_NODEFUNC_LN: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = log(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* exp */
-case EXPR_NODEFUNC_EXP: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = exp(d1);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-case EXPR_NODEFUNC_LOGN: 
-    {
-    EXPRTYPE l1, l2;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        l1 = log(d1);
-        EXPR_CHECK_ERR();
-        l2 = log(d2);
-        EXPR_CHECK_ERR();
-
-
-        if(l2 == 0.0)
-            {
-#if(EXPR_ERROR_LEVEL >= EXPR_ERROR_LEVEL_CHECK)
-            return EXPR_ERROR_OUTOFRANGE;
-#else
-            *val = 0.0;
-            return EXPR_ERROR_NOERROR;
-#endif
-            }
-
-        *val = l1 / l2;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* ceil */
-case EXPR_NODEFUNC_CEIL: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
-
-    if(!err)
-        {
-        *val = ceil(d1);
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* floor */
-case EXPR_NODEFUNC_FLOOR: 
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        *val = floor(d1);
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* rand */
-case EXPR_NODEFUNC_RAND:
-    {
-    long a;
-    
-    /* Perform random routine directly */
-    a = ((long)(*(nodes->data.function.refs[0]))) * 214013L + 2531011L;
-    *(nodes->data.function.refs[0]) = (EXPRTYPE)a;
-
-    *val =  (EXPRTYPE)((a >> 16) & 0x7FFF) / (EXPRTYPE)(32768);
-    break;
-    }
-
-/* random */
-case EXPR_NODEFUNC_RANDOM:
-    {
-    EXPRTYPE diff, rval;
-    long a;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        diff = d2 - d1;
-
-        /* Perform random routine directly */
-        a = ((long)(*(nodes->data.function.refs[0]))) * 214013L + 2531011L;
-        *(nodes->data.function.refs[0]) = (EXPRTYPE)a;
-
-        rval = (EXPRTYPE)((a >> 16) & 0x7FFF) / (EXPRTYPE)(32767);
-
-        *val = (rval * diff) + d1;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* randomize */
-case EXPR_NODEFUNC_RANDOMIZE:
-    {
-    static int curcall = 0;
-
-    curcall++;
-
-    *(nodes->data.function.refs[0]) = (EXPRTYPE)((clock() + 1024 + curcall) * time(NULL));
-
-    break;
-    }
-
-/* deg */
-case EXPR_NODEFUNC_DEG:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        {
-        *val = (180.0 * d1) / M_PI;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* rad */
-case EXPR_NODEFUNC_RAD:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        {
-        *val = (M_PI * d1) / 180.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* recttopolr */
-case EXPR_NODEFUNC_RECTTOPOLR:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = sqrt((d1 * d1) + (d2 * d2));
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* recttopola */
-case EXPR_NODEFUNC_RECTTOPOLA:
-    {
-    EXPRTYPE tmp;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        tmp = atan2(d2, d1);
-        EXPR_CHECK_ERR();
-
-        if(tmp < 0.0)
-            *val = tmp = (2.0 * M_PI);
-        else
-            *val = tmp;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* poltorectx */
-case EXPR_NODEFUNC_POLTORECTX:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = d1 * cos(d2);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* poltorecty */
-case EXPR_NODEFUNC_POLTORECTY:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        *val = d1 * sin(d2);
-        EXPR_CHECK_ERR();
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* if */
-case EXPR_NODEFUNC_IF:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        if(d1 != 0.0)
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, 1, val);
-            if(err)
-                return err;
-            }
-        else
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, 2, val);
-            if(err)
-                return err;
-            }
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* select */
-case EXPR_NODEFUNC_SELECT:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        if(d1 < 0.0)
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, 1, val);
-            if(err)
-                return err;
-            }
-        else if(d1 == 0.0)
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, 2, val);
-            if(err)
-                return err;
-            }
-        else
-            {
-            if(nodes->data.function.nodecount == 3)
-                {
-                err = exprEvalNode(obj, nodes->data.function.nodes, 2, val);
-                if(err)
-                    return err;
-                }
-            else
-                {
-                err = exprEvalNode(obj, nodes->data.function.nodes, 3, val);
-                if(err)
-                    return err;
-                }
-            }
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* equal */
-case EXPR_NODEFUNC_EQUAL:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        *val = (d1 == d2) ? 1.0 : 0.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* above */
-case EXPR_NODEFUNC_ABOVE:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        *val = (d1 > d2) ? 1.0 : 0.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* below */
-case EXPR_NODEFUNC_BELOW:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        *val = (d1 < d2) ? 1.0 : 0.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* avg */
-case EXPR_NODEFUNC_AVG:
-    {
-    d2 = 0.0;
-    
-    for(pos = 0; pos < nodes->data.function.nodecount; pos++)
-        {
-        err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d1);
-        if(!err)
-            {
-            d2 += d1;
-            }
-        else
-            return err;
-        }
-
-    *val = d2 / (EXPRTYPE)(nodes->data.function.nodecount);
-
-    break;
-    }
-
-/* clip */
-case EXPR_NODEFUNC_CLIP:
-    {
-    EXPRTYPE v;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &v);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        if(v < d1)
-            *val = d1;
-        else if(v > d2)
-            *val = d2;
-        else
-            *val = v;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* clamp */
-case EXPR_NODEFUNC_CLAMP:
-    {
-    EXPRTYPE v, tmp;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &v);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-    
-    if(!err)
-        {
-        EXPR_RESET_ERR();
-        tmp = fmod(v - d1, d2 - d1);
-        EXPR_CHECK_ERR();
-
-        if(tmp < 0.0)
-            *val = tmp * d2;
-        else
-            *val = tmp + d1;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* pntchange */
-case EXPR_NODEFUNC_PNTCHANGE:
-    {
-    EXPRTYPE n1, n2, pnt;
-    EXPRTYPE odiff, ndiff, perc;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 2, &n1);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 3, &n2);
-
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 4, &pnt);
-    
-    if(!err)
-        {
-        odiff = d2 - d1;
-        ndiff = n2 - n1;
-
-        if(odiff == 0.0)
-            {
-            *val = d1;
-            return EXPR_ERROR_NOERROR;
-            }
-
-        perc = (pnt - d1) / odiff;
-
-        *val = n1 + (perc * ndiff);
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* poly */
-case EXPR_NODEFUNC_POLY:
-    {
-    EXPRTYPE total, curpow;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-
-    if(!err)
-        {
-        curpow = (EXPRTYPE)(nodes->data.function.nodecount) - 2.0;
-        total = 0.0;
-
-        for(pos = 1; pos < nodes->data.function.nodecount; pos++)
-            {
-            err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d2);
-            if(err)
-                return err;
-
-            EXPR_RESET_ERR();
-            total = total + (d2 * pow(d1, curpow));
-            EXPR_CHECK_ERR();
-
-            curpow = curpow - 1.0;
-            }
-        }
-    else
-        return err;
-
-    *val = total;
-    break;
-    }
-
-/* and */
-case EXPR_NODEFUNC_AND:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        if(d1 == 0.0 || d2 == 0.0)
-            *val = 0.0;
-        else
-            *val = 1.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* or */
-case EXPR_NODEFUNC_OR:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
-
-    if(!err)
-        {
-        if(d1 != 0.0 || d2 != 0.0)
-            *val = 1.0;
-        else
-            *val = 0.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* not */
-case EXPR_NODEFUNC_NOT:
-    {
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        {
-        if(d1 != 0.0)
-            *val = 0.0;
-        else
-            *val = 1.0;
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* for */
-case EXPR_NODEFUNC_FOR:
-    {
-    int pos;
-    EXPRTYPE test;
-
-    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
-    
-    if(!err)
-        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &test);
-
-    if(!err)
-        {
-        while(test != 0.0)
-            {
-            for(pos = 3; pos < nodes->data.function.nodecount; pos++)
-                {
-                err = exprEvalNode(obj, nodes->data.function.nodes, pos, val);
-                if(err)
-                    return err;
-                }
-
-            err = exprEvalNode(obj, nodes->data.function.nodes, 2, &d1);
-            if(err)
-                return err;
-
-            err = exprEvalNode(obj, nodes->data.function.nodes, 1, &test);
-            if(err)
-                return err;
-            }
-        }
-    else
-        return err;
-
-    break;
-    }
-
-/* many */
-case EXPR_NODEFUNC_MANY:
-    {
-    for(pos = 0; pos < nodes->data.function.nodecount; pos++)
-        {
-        err = exprEvalNode(obj, nodes->data.function.nodes, pos, val);
-        if(err)
-            return err;
-        }
-
-    break;
-    }
-
+/*
+    File: exprilfs.h
+    Auth: Brian Allen Vanderburg II
+    Date: Tuesday, February 28, 2006
+    Desc: Inline Function Solvers for exprEvalNode
+
+    This file is part of ExprEval.
+*/
+
+/*
+    This is here to help prevent expreval.c from getting
+    too crowded.
+
+    Provided variables:
+    obj: expression object point
+    nodes: function node with paramters
+    d1, d2: variables
+    err: error
+    val: value pointer for resuld
+    pos: integer
+
+    Also EXPR_RESET_ERR() and EXPR_CHECK_ERR()
+
+    The chunks below are included inside a statement that looks like this:
+
+    switch(nodes->data.function.type)
+        {
+        #include "exprilfs.h"
+
+        default:
+            {
+            return EXPR_ERROR_UNKNOWN;
+            }
+        }
+*/
+
+
+
+/* abs */
+case EXPR_NODEFUNC_ABS:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        if(d1 >= 0)
+            *val = d1;
+        else
+            *val = -d1;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* mod */
+case EXPR_NODEFUNC_MOD:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = fmod(d1, d2);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* ipart */
+case EXPR_NODEFUNC_IPART:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        modf(d1, val);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* fpart */
+case EXPR_NODEFUNC_FPART:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = modf(d1, &d2);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* min */
+case EXPR_NODEFUNC_MIN:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        for(pos = 1; pos < nodes->data.function.nodecount; pos++)
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d2);
+            if(!err)
+                {
+                if(d2 < d1)
+                    d1 = d2;
+                }
+            else
+                return err;
+            }
+        }
+    else
+        return err;
+
+    *val = d1;
+
+    break;
+    }
+
+/* max */
+case EXPR_NODEFUNC_MAX:
+    {
+    int pos;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        for(pos = 1; pos < nodes->data.function.nodecount; pos++)
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d2);
+            if(!err)
+                {
+                if(d2 > d1)
+                    d1 = d2;
+                }
+            else
+                return err;
+            }
+        }
+    else
+        return err;
+
+    *val = d1;
+
+    break;
+    }
+
+/* pow */
+case EXPR_NODEFUNC_POW:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = pow(d1, d2);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* sqrt */
+case EXPR_NODEFUNC_SQRT:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = sqrt(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* sin */
+case EXPR_NODEFUNC_SIN:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = sin(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* sinh */
+case EXPR_NODEFUNC_SINH:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = sinh(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* asin */
+case EXPR_NODEFUNC_ASIN:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = asin(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* cos */
+case EXPR_NODEFUNC_COS: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = cos(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* cosh */
+case EXPR_NODEFUNC_COSH: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = cosh(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* acos */
+case EXPR_NODEFUNC_ACOS: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = acos(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* tan */
+case EXPR_NODEFUNC_TAN: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = tan(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* tanh */
+case EXPR_NODEFUNC_TANH: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = tanh(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* atan */
+case EXPR_NODEFUNC_ATAN: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = atan(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* atan2 */
+case EXPR_NODEFUNC_ATAN2: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = atan2(d1, d2);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* log */
+case EXPR_NODEFUNC_LOG: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = log10(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* pow10 */
+case EXPR_NODEFUNC_POW10: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = pow(10.0, d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* ln */
+case EXPR_NODEFUNC_LN: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = log(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* exp */
+case EXPR_NODEFUNC_EXP: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = exp(d1);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+case EXPR_NODEFUNC_LOGN: 
+    {
+    EXPRTYPE l1, l2;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        l1 = log(d1);
+        EXPR_CHECK_ERR();
+        l2 = log(d2);
+        EXPR_CHECK_ERR();
+
+
+        if(l2 == 0.0)
+            {
+#if(EXPR_ERROR_LEVEL >= EXPR_ERROR_LEVEL_CHECK)
+            return EXPR_ERROR_OUTOFRANGE;
+#else
+            *val = 0.0;
+            return EXPR_ERROR_NOERROR;
+#endif
+            }
+
+        *val = l1 / l2;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* ceil */
+case EXPR_NODEFUNC_CEIL: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1); 
+
+    if(!err)
+        {
+        *val = ceil(d1);
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* floor */
+case EXPR_NODEFUNC_FLOOR: 
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        *val = floor(d1);
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* rand */
+case EXPR_NODEFUNC_RAND:
+    {
+    long a;
+    
+    /* Perform random routine directly */
+    a = ((long)(*(nodes->data.function.refs[0]))) * 214013L + 2531011L;
+    *(nodes->data.function.refs[0]) = (EXPRTYPE)a;
+
+    *val =  (EXPRTYPE)((a >> 16) & 0x7FFF) / (EXPRTYPE)(32768);
+    break;
+    }
+
+/* random */
+case EXPR_NODEFUNC_RANDOM:
+    {
+    EXPRTYPE diff, rval;
+    long a;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        diff = d2 - d1;
+
+        /* Perform random routine directly */
+        a = ((long)(*(nodes->data.function.refs[0]))) * 214013L + 2531011L;
+        *(nodes->data.function.refs[0]) = (EXPRTYPE)a;
+
+        rval = (EXPRTYPE)((a >> 16) & 0x7FFF) / (EXPRTYPE)(32767);
+
+        *val = (rval * diff) + d1;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* randomize */
+case EXPR_NODEFUNC_RANDOMIZE:
+    {
+    static int curcall = 0;
+
+    curcall++;
+
+    *(nodes->data.function.refs[0]) = (EXPRTYPE)((clock() + 1024 + curcall) * time(NULL));
+
+    break;
+    }
+
+/* deg */
+case EXPR_NODEFUNC_DEG:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        {
+        *val = (180.0 * d1) / M_PI;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* rad */
+case EXPR_NODEFUNC_RAD:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        {
+        *val = (M_PI * d1) / 180.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* recttopolr */
+case EXPR_NODEFUNC_RECTTOPOLR:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = sqrt((d1 * d1) + (d2 * d2));
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* recttopola */
+case EXPR_NODEFUNC_RECTTOPOLA:
+    {
+    EXPRTYPE tmp;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        tmp = atan2(d2, d1);
+        EXPR_CHECK_ERR();
+
+        if(tmp < 0.0)
+            *val = tmp = (2.0 * M_PI);
+        else
+            *val = tmp;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* poltorectx */
+case EXPR_NODEFUNC_POLTORECTX:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = d1 * cos(d2);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* poltorecty */
+case EXPR_NODEFUNC_POLTORECTY:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        *val = d1 * sin(d2);
+        EXPR_CHECK_ERR();
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* if */
+case EXPR_NODEFUNC_IF:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        if(d1 != 0.0)
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, 1, val);
+            if(err)
+                return err;
+            }
+        else
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, 2, val);
+            if(err)
+                return err;
+            }
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* select */
+case EXPR_NODEFUNC_SELECT:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        if(d1 < 0.0)
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, 1, val);
+            if(err)
+                return err;
+            }
+        else if(d1 == 0.0)
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, 2, val);
+            if(err)
+                return err;
+            }
+        else
+            {
+            if(nodes->data.function.nodecount == 3)
+                {
+                err = exprEvalNode(obj, nodes->data.function.nodes, 2, val);
+                if(err)
+                    return err;
+                }
+            else
+                {
+                err = exprEvalNode(obj, nodes->data.function.nodes, 3, val);
+                if(err)
+                    return err;
+                }
+            }
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* equal */
+case EXPR_NODEFUNC_EQUAL:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        *val = (d1 == d2) ? 1.0 : 0.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* above */
+case EXPR_NODEFUNC_ABOVE:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        *val = (d1 > d2) ? 1.0 : 0.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* below */
+case EXPR_NODEFUNC_BELOW:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        *val = (d1 < d2) ? 1.0 : 0.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* avg */
+case EXPR_NODEFUNC_AVG:
+    {
+    d2 = 0.0;
+    
+    for(pos = 0; pos < nodes->data.function.nodecount; pos++)
+        {
+        err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d1);
+        if(!err)
+            {
+            d2 += d1;
+            }
+        else
+            return err;
+        }
+
+    *val = d2 / (EXPRTYPE)(nodes->data.function.nodecount);
+
+    break;
+    }
+
+/* clip */
+case EXPR_NODEFUNC_CLIP:
+    {
+    EXPRTYPE v;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &v);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        if(v < d1)
+            *val = d1;
+        else if(v > d2)
+            *val = d2;
+        else
+            *val = v;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* clamp */
+case EXPR_NODEFUNC_CLAMP:
+    {
+    EXPRTYPE v, tmp;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &v);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+    
+    if(!err)
+        {
+        EXPR_RESET_ERR();
+        tmp = fmod(v - d1, d2 - d1);
+        EXPR_CHECK_ERR();
+
+        if(tmp < 0.0)
+            *val = tmp * d2;
+        else
+            *val = tmp + d1;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* pntchange */
+case EXPR_NODEFUNC_PNTCHANGE:
+    {
+    EXPRTYPE n1, n2, pnt;
+    EXPRTYPE odiff, ndiff, perc;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 2, &n1);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 3, &n2);
+
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 4, &pnt);
+    
+    if(!err)
+        {
+        odiff = d2 - d1;
+        ndiff = n2 - n1;
+
+        if(odiff == 0.0)
+            {
+            *val = d1;
+            return EXPR_ERROR_NOERROR;
+            }
+
+        perc = (pnt - d1) / odiff;
+
+        *val = n1 + (perc * ndiff);
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* poly */
+case EXPR_NODEFUNC_POLY:
+    {
+    EXPRTYPE total, curpow;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+
+    if(!err)
+        {
+        curpow = (EXPRTYPE)(nodes->data.function.nodecount) - 2.0;
+        total = 0.0;
+
+        for(pos = 1; pos < nodes->data.function.nodecount; pos++)
+            {
+            err = exprEvalNode(obj, nodes->data.function.nodes, pos, &d2);
+            if(err)
+                return err;
+
+            EXPR_RESET_ERR();
+            total = total + (d2 * pow(d1, curpow));
+            EXPR_CHECK_ERR();
+
+            curpow = curpow - 1.0;
+            }
+        }
+    else
+        return err;
+
+    *val = total;
+    break;
+    }
+
+/* and */
+case EXPR_NODEFUNC_AND:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        if(d1 == 0.0 || d2 == 0.0)
+            *val = 0.0;
+        else
+            *val = 1.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* or */
+case EXPR_NODEFUNC_OR:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &d2);
+
+    if(!err)
+        {
+        if(d1 != 0.0 || d2 != 0.0)
+            *val = 1.0;
+        else
+            *val = 0.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* not */
+case EXPR_NODEFUNC_NOT:
+    {
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        {
+        if(d1 != 0.0)
+            *val = 0.0;
+        else
+            *val = 1.0;
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* for */
+case EXPR_NODEFUNC_FOR:
+    {
+    int pos;
+    EXPRTYPE test;
+
+    err = exprEvalNode(obj, nodes->data.function.nodes, 0, &d1);
+    
+    if(!err)
+        err = exprEvalNode(obj, nodes->data.function.nodes, 1, &test);
+
+    if(!err)
+        {
+        while(test != 0.0)
+            {
+            for(pos = 3; pos < nodes->data.function.nodecount; pos++)
+                {
+                err = exprEvalNode(obj, nodes->data.function.nodes, pos, val);
+                if(err)
+                    return err;
+                }
+
+            err = exprEvalNode(obj, nodes->data.function.nodes, 2, &d1);
+            if(err)
+                return err;
+
+            err = exprEvalNode(obj, nodes->data.function.nodes, 1, &test);
+            if(err)
+                return err;
+            }
+        }
+    else
+        return err;
+
+    break;
+    }
+
+/* many */
+case EXPR_NODEFUNC_MANY:
+    {
+    for(pos = 0; pos < nodes->data.function.nodecount; pos++)
+        {
+        err = exprEvalNode(obj, nodes->data.function.nodes, pos, val);
+        if(err)
+            return err;
+        }
+
+    break;
+    }
+

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprincl.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprincl.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprincl.h	Tue Nov 13 15:23:26 2007
@@ -1,112 +1,112 @@
-/*
-    File: exprincl.h
-    Auth: Brian Allen Vanderburg II
-    Date: Thursday, April 24, 2003
-    Desc: Includes, macros, etc needed by this library
-
-    This file is part of ExprEval.
-*/
-
-#ifndef __BAVII_EXPRINCL_H
-#define __BAVII_EXPRINCL_H
-
-
-/* Includes and macros and whatnot for building the library */
-
-#ifdef _MSC_VER
-#if (_MSC_VER >= 1400)			// VC8+
-#ifndef _CRT_SECURE_NO_DEPRECATE
-#define _CRT_SECURE_NO_DEPRECATE
-#endif
-#ifndef _CRT_NONSTDC_NO_DEPRECATE
-#define _CRT_NONSTDC_NO_DEPRECATE
-#endif
-#endif // VC8+
-#endif
-
-/* Memory routines.  memory.h for VC++, mem.h for BC++ */
-#ifdef __TURBOC__
-#include <mem.h>
-#else
-#include <memory.h>
-#endif
-
-/* Memory allocation */
-#include <malloc.h>
-
-/* String routines */
-#include <string.h>
-
-/* Character manipulation routines */
-#include <ctype.h>
-
-/* Standard routines */
-#include <stdlib.h>
-
-/* Math routines */
-#include <math.h>
-
-/* Time */
-#include <time.h>
-
-
-/* Math constants.  VC++ does not seem to have these */
-#ifndef M_E
-#define M_E 2.7182818284590452354
-#endif
-
-#ifndef M_LOG2E
-#define M_LOG2E 1.4426950408889634074
-#endif
-
-#ifndef M_LOG10E
-#define M_LOG10E 0.43429448190325182765
-#endif
-
-#ifndef M_LN2
-#define M_LN2 0.69314718055994530942
-#endif
-
-#ifndef M_LN10
-#define M_LN10 2.30258509299404568402
-#endif
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#ifndef M_PI_2
-#define M_PI_2 1.57079632679489661923
-#endif
-
-#ifndef M_PI_4
-#define M_PI_4 0.78539816339744830962
-#endif
-
-#ifndef M_1_PI
-#define M_1_PI 0.31830988618379067154
-#endif
-
-#ifndef M_2_PI
-#define M_2_PI 0.63661977236758134308
-#endif
-
-#ifndef M_1_SQRTPI
-#define M_1_SQRTPI 0.56418958354776
-#endif
-
-#ifndef M_2_SQRTPI
-#define M_2_SQRTPI 1.12837916709551257390
-#endif
-
-#ifndef M_SQRT2
-#define M_SQRT2 1.41421356237309504880
-#endif
-
-#ifndef M_1_SQRT2
-#define M_1_SQRT2 0.70710678118654752440
-#endif
-
-
-
-#endif /* __BAVII_EXPRINCL_H */
+/*
+    File: exprincl.h
+    Auth: Brian Allen Vanderburg II
+    Date: Thursday, April 24, 2003
+    Desc: Includes, macros, etc needed by this library
+
+    This file is part of ExprEval.
+*/
+
+#ifndef __BAVII_EXPRINCL_H
+#define __BAVII_EXPRINCL_H
+
+
+/* Includes and macros and whatnot for building the library */
+
+#ifdef _MSC_VER
+#if (_MSC_VER >= 1400)			// VC8+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE
+#endif
+#endif // VC8+
+#endif
+
+/* Memory routines.  memory.h for VC++, mem.h for BC++ */
+#ifdef __TURBOC__
+#include <mem.h>
+#else
+#include <memory.h>
+#endif
+
+/* Memory allocation */
+#include <malloc.h>
+
+/* String routines */
+#include <string.h>
+
+/* Character manipulation routines */
+#include <ctype.h>
+
+/* Standard routines */
+#include <stdlib.h>
+
+/* Math routines */
+#include <math.h>
+
+/* Time */
+#include <time.h>
+
+
+/* Math constants.  VC++ does not seem to have these */
+#ifndef M_E
+#define M_E 2.7182818284590452354
+#endif
+
+#ifndef M_LOG2E
+#define M_LOG2E 1.4426950408889634074
+#endif
+
+#ifndef M_LOG10E
+#define M_LOG10E 0.43429448190325182765
+#endif
+
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+
+#ifndef M_LN10
+#define M_LN10 2.30258509299404568402
+#endif
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661923
+#endif
+
+#ifndef M_PI_4
+#define M_PI_4 0.78539816339744830962
+#endif
+
+#ifndef M_1_PI
+#define M_1_PI 0.31830988618379067154
+#endif
+
+#ifndef M_2_PI
+#define M_2_PI 0.63661977236758134308
+#endif
+
+#ifndef M_1_SQRTPI
+#define M_1_SQRTPI 0.56418958354776
+#endif
+
+#ifndef M_2_SQRTPI
+#define M_2_SQRTPI 1.12837916709551257390
+#endif
+
+#ifndef M_SQRT2
+#define M_SQRT2 1.41421356237309504880
+#endif
+
+#ifndef M_1_SQRT2
+#define M_1_SQRT2 0.70710678118654752440
+#endif
+
+
+
+#endif /* __BAVII_EXPRINCL_H */

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprinit.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprinit.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprinit.c	Tue Nov 13 15:23:26 2007
@@ -1,115 +1,115 @@
-/*
-    File: exprinit.c
-    Auth: Brian Allen Vanderburg II
-    Date: Thursday, May 1, 2003
-    Desc: Extra functions and routines for ExprEval
-
-    This file is part of ExprEval.
-*/
-
-/* Include files */
-#include "exprincl.h"
-
-#include "exprpriv.h"
-
-
-/* Macro for adding a function node type */
-#define EXPR_ADDFUNC_TYPE(name, type, argmin, argmax, refmin, refmax) \
-err = exprFuncListAddType(flist, name, type, argmin, argmax, refmin, refmax); \
-if(err != EXPR_ERROR_NOERROR) \
-    return err;
-
-/* Macro for adding a constant */
-#define EXPR_ADDCONST(name, val) \
-err = exprValListAdd(vlist, name, val); \
-if(err != EXPR_ERROR_NOERROR) \
-    return err;
-
-/* Call this function to initialize these functions into a function list */
-int exprFuncListInit(exprFuncList *flist)
-    {
-    int err;
-
-    if(flist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    EXPR_ADDFUNC_TYPE("abs", EXPR_NODEFUNC_ABS, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("mod", EXPR_NODEFUNC_MOD, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("ipart", EXPR_NODEFUNC_IPART, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("fpart", EXPR_NODEFUNC_FPART, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("min", EXPR_NODEFUNC_MIN, 1, -1, 0, 0);
-    EXPR_ADDFUNC_TYPE("max", EXPR_NODEFUNC_MAX, 1, -1, 0, 0);
-    EXPR_ADDFUNC_TYPE("pow", EXPR_NODEFUNC_POW, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("sqrt", EXPR_NODEFUNC_SQRT, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("sin", EXPR_NODEFUNC_SIN, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("sinh", EXPR_NODEFUNC_SINH, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("asin", EXPR_NODEFUNC_ASIN, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("cos", EXPR_NODEFUNC_COS, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("cosh", EXPR_NODEFUNC_COSH, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("acos", EXPR_NODEFUNC_ACOS, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("tan", EXPR_NODEFUNC_TAN, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("tanh", EXPR_NODEFUNC_TANH, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("atan", EXPR_NODEFUNC_ATAN, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("atan2", EXPR_NODEFUNC_ATAN2, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("log", EXPR_NODEFUNC_LOG, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("pow10", EXPR_NODEFUNC_POW10, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("ln", EXPR_NODEFUNC_LN, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("exp", EXPR_NODEFUNC_EXP, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("logn", EXPR_NODEFUNC_LOGN, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("ceil", EXPR_NODEFUNC_CEIL, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("floor", EXPR_NODEFUNC_FLOOR, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("rand", EXPR_NODEFUNC_RAND, 0, 0, 1, 1);
-    EXPR_ADDFUNC_TYPE("random", EXPR_NODEFUNC_RANDOM, 2, 2, 1, 1);
-    EXPR_ADDFUNC_TYPE("randomize", EXPR_NODEFUNC_RANDOMIZE, 0, 0, 1, 1);
-    EXPR_ADDFUNC_TYPE("deg", EXPR_NODEFUNC_DEG, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("rad", EXPR_NODEFUNC_RAD, 1, 1, 0, 0);
-    EXPR_ADDFUNC_TYPE("recttopolr", EXPR_NODEFUNC_RECTTOPOLR, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("recttopola", EXPR_NODEFUNC_RECTTOPOLA, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("poltorectx", EXPR_NODEFUNC_POLTORECTX, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("poltorecty", EXPR_NODEFUNC_POLTORECTY, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("if", EXPR_NODEFUNC_IF, 3, 3, 0, 0);
-    EXPR_ADDFUNC_TYPE("select", EXPR_NODEFUNC_SELECT, 3, 4, 0, 0);
-    EXPR_ADDFUNC_TYPE("equal", EXPR_NODEFUNC_EQUAL, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("above", EXPR_NODEFUNC_ABOVE, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("below", EXPR_NODEFUNC_BELOW, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("avg", EXPR_NODEFUNC_AVG, 1, -1, 0, 0);
-    EXPR_ADDFUNC_TYPE("clip", EXPR_NODEFUNC_CLIP, 3, 3, 0, 0);
-    EXPR_ADDFUNC_TYPE("clamp", EXPR_NODEFUNC_CLAMP, 3, 3, 0, 0);
-    EXPR_ADDFUNC_TYPE("pntchange", EXPR_NODEFUNC_PNTCHANGE, 5, 5, 0, 0);
-    EXPR_ADDFUNC_TYPE("poly", EXPR_NODEFUNC_POLY, 2, -1, 0, 0);
-    EXPR_ADDFUNC_TYPE("and", EXPR_NODEFUNC_AND, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("or", EXPR_NODEFUNC_OR, 2, 2, 0, 0);
-    EXPR_ADDFUNC_TYPE("not", EXPR_NODEFUNC_NOT, 1 ,1, 0, 0);
-    EXPR_ADDFUNC_TYPE("for", EXPR_NODEFUNC_FOR, 4, -1, 0, 0);
-    EXPR_ADDFUNC_TYPE("many", EXPR_NODEFUNC_MANY, 1, -1, 0, 0);
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-/* Call this function to initialize some constants into a value list */
-int exprValListInit(exprValList *vlist)
-    {
-    int err;
-
-    if(vlist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    EXPR_ADDCONST("M_E", M_E);
-    EXPR_ADDCONST("M_LOG2E", M_LOG2E);
-    EXPR_ADDCONST("M_LOG10E", M_LOG10E);
-    EXPR_ADDCONST("M_LN2", M_LN2);
-    EXPR_ADDCONST("M_LN10", M_LN10);
-    EXPR_ADDCONST("M_PI", M_PI);
-    EXPR_ADDCONST("M_PI_2", M_PI_2);
-    EXPR_ADDCONST("M_PI_4", M_PI_4);
-    EXPR_ADDCONST("M_1_PI", M_1_PI);
-    EXPR_ADDCONST("M_2_PI", M_2_PI);
-    EXPR_ADDCONST("M_1_SQRTPI", M_1_SQRTPI);
-    EXPR_ADDCONST("M_2_SQRTPI", M_2_SQRTPI);
-    EXPR_ADDCONST("M_SQRT2", M_SQRT2);
-    EXPR_ADDCONST("M_1_SQRT2", M_1_SQRT2);
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-
+/*
+    File: exprinit.c
+    Auth: Brian Allen Vanderburg II
+    Date: Thursday, May 1, 2003
+    Desc: Extra functions and routines for ExprEval
+
+    This file is part of ExprEval.
+*/
+
+/* Include files */
+#include "exprincl.h"
+
+#include "exprpriv.h"
+
+
+/* Macro for adding a function node type */
+#define EXPR_ADDFUNC_TYPE(name, type, argmin, argmax, refmin, refmax) \
+err = exprFuncListAddType(flist, name, type, argmin, argmax, refmin, refmax); \
+if(err != EXPR_ERROR_NOERROR) \
+    return err;
+
+/* Macro for adding a constant */
+#define EXPR_ADDCONST(name, val) \
+err = exprValListAdd(vlist, name, val); \
+if(err != EXPR_ERROR_NOERROR) \
+    return err;
+
+/* Call this function to initialize these functions into a function list */
+int exprFuncListInit(exprFuncList *flist)
+    {
+    int err;
+
+    if(flist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    EXPR_ADDFUNC_TYPE("abs", EXPR_NODEFUNC_ABS, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("mod", EXPR_NODEFUNC_MOD, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("ipart", EXPR_NODEFUNC_IPART, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("fpart", EXPR_NODEFUNC_FPART, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("min", EXPR_NODEFUNC_MIN, 1, -1, 0, 0);
+    EXPR_ADDFUNC_TYPE("max", EXPR_NODEFUNC_MAX, 1, -1, 0, 0);
+    EXPR_ADDFUNC_TYPE("pow", EXPR_NODEFUNC_POW, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("sqrt", EXPR_NODEFUNC_SQRT, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("sin", EXPR_NODEFUNC_SIN, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("sinh", EXPR_NODEFUNC_SINH, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("asin", EXPR_NODEFUNC_ASIN, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("cos", EXPR_NODEFUNC_COS, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("cosh", EXPR_NODEFUNC_COSH, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("acos", EXPR_NODEFUNC_ACOS, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("tan", EXPR_NODEFUNC_TAN, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("tanh", EXPR_NODEFUNC_TANH, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("atan", EXPR_NODEFUNC_ATAN, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("atan2", EXPR_NODEFUNC_ATAN2, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("log", EXPR_NODEFUNC_LOG, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("pow10", EXPR_NODEFUNC_POW10, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("ln", EXPR_NODEFUNC_LN, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("exp", EXPR_NODEFUNC_EXP, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("logn", EXPR_NODEFUNC_LOGN, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("ceil", EXPR_NODEFUNC_CEIL, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("floor", EXPR_NODEFUNC_FLOOR, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("rand", EXPR_NODEFUNC_RAND, 0, 0, 1, 1);
+    EXPR_ADDFUNC_TYPE("random", EXPR_NODEFUNC_RANDOM, 2, 2, 1, 1);
+    EXPR_ADDFUNC_TYPE("randomize", EXPR_NODEFUNC_RANDOMIZE, 0, 0, 1, 1);
+    EXPR_ADDFUNC_TYPE("deg", EXPR_NODEFUNC_DEG, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("rad", EXPR_NODEFUNC_RAD, 1, 1, 0, 0);
+    EXPR_ADDFUNC_TYPE("recttopolr", EXPR_NODEFUNC_RECTTOPOLR, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("recttopola", EXPR_NODEFUNC_RECTTOPOLA, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("poltorectx", EXPR_NODEFUNC_POLTORECTX, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("poltorecty", EXPR_NODEFUNC_POLTORECTY, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("if", EXPR_NODEFUNC_IF, 3, 3, 0, 0);
+    EXPR_ADDFUNC_TYPE("select", EXPR_NODEFUNC_SELECT, 3, 4, 0, 0);
+    EXPR_ADDFUNC_TYPE("equal", EXPR_NODEFUNC_EQUAL, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("above", EXPR_NODEFUNC_ABOVE, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("below", EXPR_NODEFUNC_BELOW, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("avg", EXPR_NODEFUNC_AVG, 1, -1, 0, 0);
+    EXPR_ADDFUNC_TYPE("clip", EXPR_NODEFUNC_CLIP, 3, 3, 0, 0);
+    EXPR_ADDFUNC_TYPE("clamp", EXPR_NODEFUNC_CLAMP, 3, 3, 0, 0);
+    EXPR_ADDFUNC_TYPE("pntchange", EXPR_NODEFUNC_PNTCHANGE, 5, 5, 0, 0);
+    EXPR_ADDFUNC_TYPE("poly", EXPR_NODEFUNC_POLY, 2, -1, 0, 0);
+    EXPR_ADDFUNC_TYPE("and", EXPR_NODEFUNC_AND, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("or", EXPR_NODEFUNC_OR, 2, 2, 0, 0);
+    EXPR_ADDFUNC_TYPE("not", EXPR_NODEFUNC_NOT, 1 ,1, 0, 0);
+    EXPR_ADDFUNC_TYPE("for", EXPR_NODEFUNC_FOR, 4, -1, 0, 0);
+    EXPR_ADDFUNC_TYPE("many", EXPR_NODEFUNC_MANY, 1, -1, 0, 0);
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+/* Call this function to initialize some constants into a value list */
+int exprValListInit(exprValList *vlist)
+    {
+    int err;
+
+    if(vlist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    EXPR_ADDCONST("M_E", M_E);
+    EXPR_ADDCONST("M_LOG2E", M_LOG2E);
+    EXPR_ADDCONST("M_LOG10E", M_LOG10E);
+    EXPR_ADDCONST("M_LN2", M_LN2);
+    EXPR_ADDCONST("M_LN10", M_LN10);
+    EXPR_ADDCONST("M_PI", M_PI);
+    EXPR_ADDCONST("M_PI_2", M_PI_2);
+    EXPR_ADDCONST("M_PI_4", M_PI_4);
+    EXPR_ADDCONST("M_1_PI", M_1_PI);
+    EXPR_ADDCONST("M_2_PI", M_2_PI);
+    EXPR_ADDCONST("M_1_SQRTPI", M_1_SQRTPI);
+    EXPR_ADDCONST("M_2_SQRTPI", M_2_SQRTPI);
+    EXPR_ADDCONST("M_SQRT2", M_SQRT2);
+    EXPR_ADDCONST("M_1_SQRT2", M_1_SQRT2);
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprmem.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprmem.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprmem.c	Tue Nov 13 15:23:26 2007
@@ -1,39 +1,39 @@
-/*
-    File: exprmem.c
-    Auth: Brian Allen Vanderburg II
-    Date: Wednesday, April 30, 2003
-    Desc: Memory functions for ExprEval
-
-    This file is part of ExprEval.
-*/
-
-/* Includes */
-#include "exprincl.h"
-
-#include "exprmem.h"
-
-/* Allocate memory and zero it */
-void* exprAllocMem(size_t size)
-    {
-    void *data = malloc(size);
-    
-    if(data)
-        {
-        memset(data, 0, size);
-        }
-    
-    return data;
-    }
-
-/* Free memory */
-void exprFreeMem(void *data)
-    {
-    if(data)
-        free(data);
-    }
-
-/* Allocate a list of nodes */
-exprNode *exprAllocNodes(size_t count)
-    {
-    return exprAllocMem(count * sizeof(exprNode));
-    }
+/*
+    File: exprmem.c
+    Auth: Brian Allen Vanderburg II
+    Date: Wednesday, April 30, 2003
+    Desc: Memory functions for ExprEval
+
+    This file is part of ExprEval.
+*/
+
+/* Includes */
+#include "exprincl.h"
+
+#include "exprmem.h"
+
+/* Allocate memory and zero it */
+void* exprAllocMem(size_t size)
+    {
+    void *data = malloc(size);
+    
+    if(data)
+        {
+        memset(data, 0, size);
+        }
+    
+    return data;
+    }
+
+/* Free memory */
+void exprFreeMem(void *data)
+    {
+    if(data)
+        free(data);
+    }
+
+/* Allocate a list of nodes */
+exprNode *exprAllocNodes(size_t count)
+    {
+    return exprAllocMem(count * sizeof(exprNode));
+    }

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprmem.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprmem.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprmem.h	Tue Nov 13 15:23:26 2007
@@ -1,21 +1,21 @@
-/*
-    File: exprmem.h
-    Auth: Brian Allen Vanderburg II
-    Date: Wednesday, April 30, 2003
-    Desc: Memory functions for ExprEval
-
-    This file is part of ExprEval.
-*/
-
-#ifndef __BAVII_EXPRMEM_H
-#define __BAVII_EXPRMEM_H
-
-/* Needed for exprNode */
-#include "exprpriv.h"
-
-void* exprAllocMem(size_t size);
-void exprFreeMem(void *data);
-exprNode *exprAllocNodes(size_t count);
-
-
-#endif /* __BAVII_EXPRMEM_H */
+/*
+    File: exprmem.h
+    Auth: Brian Allen Vanderburg II
+    Date: Wednesday, April 30, 2003
+    Desc: Memory functions for ExprEval
+
+    This file is part of ExprEval.
+*/
+
+#ifndef __BAVII_EXPRMEM_H
+#define __BAVII_EXPRMEM_H
+
+/* Needed for exprNode */
+#include "exprpriv.h"
+
+void* exprAllocMem(size_t size);
+void exprFreeMem(void *data);
+exprNode *exprAllocNodes(size_t count);
+
+
+#endif /* __BAVII_EXPRMEM_H */

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprobj.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprobj.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprobj.c	Tue Nov 13 15:23:26 2007
@@ -1,237 +1,237 @@
-/*
-    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;
-        }
-    }
-
-
+/*
+    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;
+        }
+    }
+
+

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprpars.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprpars.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprpars.c	Tue Nov 13 15:23:26 2007
@@ -1,1558 +1,1558 @@
-/*
-    File: exprpars.c
-    Auth: Brian Allen Vanderburg II
-    Date: Wednesday, April 30, 2003
-    Desc: Actual parsing routines for this library
-
-    This file is part of ExprEval.
-*/
-
-/* Includes */
-#include "exprincl.h"
-
-#include "exprpriv.h"
-#include "exprmem.h"
-
-/* Data structure used by parser */
-typedef struct _exprToken
-    {
-    int type; /* token type */
-    int start; /* token start position */
-    int end; /* token end position */
-
-    union _tdata
-        {
-        char *str; /* string data */
-        EXPRTYPE val; /* value data */
-        } data;
-    } exprToken;
-
-/* Defines for token types */
-#define EXPR_TOKEN_UNKNOWN 0
-#define EXPR_TOKEN_OPAREN 1
-#define EXPR_TOKEN_CPAREN 2
-#define EXPR_TOKEN_IDENTIFIER 3
-#define EXPR_TOKEN_VALUE 4
-#define EXPR_TOKEN_PLUS 5
-#define EXPR_TOKEN_HYPHEN 6
-#define EXPR_TOKEN_ASTERISK 7
-#define EXPR_TOKEN_FSLASH 8
-#define EXPR_TOKEN_AMPERSAND 9
-#define EXPR_TOKEN_SEMICOLON 10
-#define EXPR_TOKEN_COMMA 11
-#define EXPR_TOKEN_EQUAL 12
-#define EXPR_TOKEN_HAT 13
-
-/* Internal functions */
-int exprMultiParse(exprObj *obj, exprNode *node, exprToken *tokens, int count);
-int exprInternalParse(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end);
-int exprInternalParseAssign(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParseAdd(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParseSub(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParseMul(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParseDiv(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParsePosNeg(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParseExp(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
-int exprInternalParseFunction(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int p1, int p2);
-int exprInternalParseVarVal(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end);
-int exprStringToTokenList(exprObj *obj, char *expr, exprToken **tokens, int *count);
-void exprFreeTokenList(exprToken *tokens, int count);
-
-/* This frees a token list */
-void exprFreeTokenList(exprToken *tokens, int count)
-    {
-    int pos;
-
-    if(tokens == NULL)
-        return;
-
-    for(pos = 0; pos < count; pos++)
-        {
-        if(tokens[pos].type == EXPR_TOKEN_IDENTIFIER)
-            exprFreeMem(tokens[pos].data.str);
-        }
-
-    exprFreeMem(tokens);
-    }
-
-/* This converts an expression string to a token list */
-int exprStringToTokenList(exprObj *obj, char *expr, exprToken **tokens, int *count)
-    {
-    int found;
-    exprToken *list;
-    int pass;
-    int pos, len;
-    int tpos;
-    int comment; /* Is a comment active */
-    int start, ilen;
-    char buf[EXPR_MAXIDENTSIZE + 1];
-
-    /* Set initial variables */
-    found = 0;
-    tpos = 0;
-    list = NULL;
-    comment = 0;
-    *tokens = NULL;
-    *count = 0;
-
-
-    /* Check string length */
-    len = (int)strlen(expr);
-    if(len == 0)
-        return EXPR_ERROR_EMPTYEXPR;
-
-    /* Two passes, one to count, one to tokenize */
-    for(pass = 0; pass <= 1; pass++)
-        {
-        for(pos = 0; pos < len; pos++)
-            {
-            switch(expr[pos])
-                {
-                /* Comment */
-                case '#':
-                    {
-                    /* Only set it if a comment is not already active */
-                    if(!comment)
-                        comment = 1;
-
-                    break;
-                    }
-
-                /* Newline characters turn off comments */
-                case '\r':
-                case '\n':
-                    {
-                    /* If a comment is active, unset it */
-                    if(comment)
-                        comment = 0;
-
-                    break;
-                    }
-
-                /* Open parenthesis */
-                case '(':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_OPAREN;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Close parenthesis */
-                case ')':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_CPAREN;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Plus */
-                case '+':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_PLUS;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Hyphen */
-                case '-':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_HYPHEN;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Asterisk */
-                case '*':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_ASTERISK;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Forward slash */
-                case '/':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_FSLASH;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Hat */
-                case '^':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_HAT;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Ampersand */
-                case '&':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_AMPERSAND;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Semicolon */
-                case ';':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_SEMICOLON;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Comma */
-                case ',':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_COMMA;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Equal sign */
-                case '=':
-                    {
-                    if(!comment)
-                        {
-                        if(pass == 0)
-                            found++;
-                        else
-                            {
-                            list[tpos].type = EXPR_TOKEN_EQUAL;
-                            list[tpos].start = pos;
-                            list[tpos].end = pos;
-                            tpos++;
-                            }
-                        }
-
-                    break;
-                    }
-
-                /* Identifiers and values */
-                default:
-                    {
-                    if(!comment)
-                        {
-                        if(expr[pos] == '.' || isdigit(expr[pos]))
-                            {
-                            /* Value */
-                            start = pos;
-
-                            /* Find digits before a period */
-                            while(isdigit(expr[pos]))
-                                pos++;
-
-                            /* Find a period */
-                            if(expr[pos] == '.')
-                                pos++;
-
-                            /* Find digits after a period */
-                            while(isdigit(expr[pos]))
-                                pos++;
-
-                            /* pos is AFTER last item, back up */
-                            pos--;
-
-                            if(pass == 0)
-                                found++;
-                            else
-                                {
-                                ilen = pos - start + 1;
-
-                                /* Is the value to large */
-                                if(ilen > EXPR_MAXIDENTSIZE)
-                                    {
-                                    obj->starterr = start;
-                                    obj->enderr = pos;
-                                    exprFreeTokenList(list, found);
-                                    return EXPR_ERROR_BADIDENTIFIER;
-                                    }
-
-                                /* Create value token */
-                                strncpy(buf, expr + start, ilen);
-                                buf[ilen] = '\0';
-
-                                list[tpos].type = EXPR_TOKEN_VALUE;
-                                list[tpos].start = start;
-                                list[tpos].end = pos;
-                                list[tpos].data.val = (EXPRTYPE)atof(buf);
-                                tpos++;
-                                }
-                            }
-                        else if(expr[pos] == '_' || isalpha(expr[pos]))
-                            {
-                            /* Identifier */
-                            start = pos;
-
-                            /* Find rest of identifier */
-                            while(expr[pos] == '_' || isalnum(expr[pos]))
-                                pos++;
-
-                            /* pos is AFTER last item, back up */
-                            pos--;
-
-                            if(pass == 0)
-                                found++;
-                            else
-                                {
-                                ilen = pos - start + 1;
-
-                                /* Is the value to large */
-                                if(ilen > EXPR_MAXIDENTSIZE)
-                                    {
-                                    obj->starterr = start;
-                                    obj->enderr = pos;
-                                    exprFreeTokenList(list, found);
-                                    return EXPR_ERROR_BADIDENTIFIER;
-                                    }
-
-                                /* Create value token */
-                                strncpy(buf, expr + start, ilen);
-                                buf[ilen] = '\0';
-
-                                /* Allocate memory for identifier */
-                                list[tpos].data.str = exprAllocMem(ilen + 1);
-                                if(list[tpos].data.str == NULL)
-                                    {
-                                    exprFreeTokenList(list, found);
-                                    return EXPR_ERROR_MEMORY;
-                                    }
-
-                                list[tpos].type = EXPR_TOKEN_IDENTIFIER;
-                                list[tpos].start = start;
-                                list[tpos].end = pos;
-                                strcpy(list[tpos].data.str, buf);
-                                tpos++;
-                                }
-                            }
-                        else if(isspace(expr[pos]))
-                            {
-                            /* Spaces are ignored, do nothing */
-                            }
-                        else
-                            {
-                            /* Unknown */
-                            obj->starterr = obj->enderr = pos;
-                            exprFreeTokenList(list, found);
-                            return EXPR_ERROR_INVALIDCHAR;
-                            }
-                        }
-
-                    break;
-                    }
-                }
-            }
-
-        /* If pass is 0, allocate memory for next pass */
-        if(pass == 0)
-            {
-            /* First, make sure all comments were ended */
-            if(comment)
-                comment = 0;
-
-            /* Make sure the expression is not empty */
-            if(found == 0)
-                return EXPR_ERROR_EMPTYEXPR;
-
-            /* Allocate memory for token list */
-            list = exprAllocMem(found * sizeof(exprToken));
-            if(list == NULL)
-                return EXPR_ERROR_MEMORY;
-
-            tpos = 0;
-            }
-        }
-
-    *count = found;
-    *tokens = list;
-    return EXPR_ERROR_NOERROR;
-    }
-
-
-/* This is the main parsing routine */
-int exprParse(exprObj *obj, char *expr)
-    {
-    exprToken *tokens;
-    int count;
-    int err;
-    exprNode *tmp;
-
-    /* Make sure an object was passed */
-    if(obj == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    /* Clear expression error position */
-    obj->starterr = obj->enderr = -1;
-
-    /* Have we already been parsed? */
-    if(obj->parsedbad != 0)
-        return EXPR_ERROR_ALREADYPARSEDBAD;
-
-    if(obj->parsedgood != 0)
-        return EXPR_ERROR_ALREADYPARSEDGOOD;
-
-    /* Make sure an expression was passed */
-    if(expr == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    /* Create token list */
-    err = exprStringToTokenList(obj, expr, &tokens, &count);
-    if(err != EXPR_ERROR_NOERROR)
-        return err;
-    
-    /* Create head pointer */
-    tmp = exprAllocNodes(1);
-    if(tmp == NULL)
-        {
-        exprFreeTokenList(tokens, count);
-        return EXPR_ERROR_MEMORY;
-        }
-
-    obj->headnode = tmp;
-
-    /* Call the multiparse routine to parse subexpressions */
-    err = exprMultiParse(obj, tmp, tokens, count);
-
-    /* Free the token list */
-    exprFreeTokenList(tokens, count);
-
-    /* successful parse? */
-    if(err == EXPR_ERROR_NOERROR)
-        {
-        obj->parsedgood = 1;
-        obj->parsedbad = 0;
-        }
-    else
-        {
-        obj->parsedbad = 1;
-        obj->parsedgood = 0;
-        }
-
-    return err;
-    }
-
-
-/* Parse the subexpressions, each ending with semicolons */
-int exprMultiParse(exprObj *obj, exprNode *node, exprToken *tokens, int count)
-    {
-    int pos, plevel, last;
-    int num, cur, err;
-    exprNode *tmp;
-
-    plevel = 0;
-    num = 0;
-    last = -1;
-
-    /* First count the number of arguments */
-    for(pos = 0; pos < count; pos++)
-        {
-        switch(tokens[pos].type)
-            {
-            case EXPR_TOKEN_OPAREN:
-                /* increase plevel */
-                plevel++;
-                break;
-
-            case EXPR_TOKEN_CPAREN:
-                /* decrease plevel */
-                plevel--;
-
-                if(plevel < 0)
-                    {
-                    obj->starterr = tokens[pos].start;
-                    obj->enderr = tokens[pos].end;
-                    return EXPR_ERROR_UNMATCHEDPAREN;
-                    }
-
-                break;
-
-            case EXPR_TOKEN_SEMICOLON:
-                if(plevel == 0)
-                    {
-                    if(last == pos - 1 || pos == 0)
-                        {
-                        /* last semicolon is before us or we are at the start */
-                        obj->starterr = tokens[pos].start;
-                        obj->enderr = tokens[pos].end;
-                        return EXPR_ERROR_SYNTAX;
-                        }
-                    else
-                        {
-                        /* last semicolon is not right before us */
-                        num++;
-                        }
-                    }
-                else
-                    {
-                    /* Semicolon should not be in a parenthesis */
-                    obj->starterr = tokens[pos].start;
-                    obj->enderr = tokens[pos].end;
-                    return EXPR_ERROR_SYNTAX;
-                    }
-
-                last = pos; /* update position of last semicolon */
-                break;
-            }
-        }
-
-    /* plevel should be zero now */
-    if(plevel != 0)
-        return EXPR_ERROR_UNMATCHEDPAREN;
-
-    /* the last character should be a semicolon */
-    if(last != pos - 1)
-        return EXPR_ERROR_MISSINGSEMICOLON;
-
-    /* Now we know how many arguments there are */
-
-    /* Allocate array of subnodes */
-    tmp = exprAllocNodes(num);
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-
-    /* Set the current node's data */
-    node->type = EXPR_NODETYPE_MULTI;
-    node->data.oper.nodes = tmp;
-    node->data.oper.nodecount = num;
-
-    /* now we parse each subexpression */
-    last = 0; /* Not for last semicolon, but for first char of subexpr */
-    cur = 0;
-
-    for(pos = 0; pos < count; pos++)
-        {
-        if(tokens[pos].type == EXPR_TOKEN_SEMICOLON)
-            {
-            /* Everything from last up to pos - 1 is a parameter */
-            err = exprInternalParse(obj, &(tmp[cur]), tokens, last, pos - 1);
-            if(err != EXPR_ERROR_NOERROR)
-                return err;
-
-            /* Update last position and current argument */
-            last = pos + 1;
-            cur++;
-            }
-        }
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-/* This function parses each subnode and recurses if needed */
-int exprInternalParse(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end)
-    {
-    int pos;
-    int plevel = 0; /* Paren level */
-    int fgopen = -1; /* First paren group open index */
-    int fgclose = -1; /* First paren group close index */
-    int assignindex = -1; /* First = at plevel 0 for assignment */
-    int addsubindex = -1; /* Last + or - at plevel 0 for adding or subtracting */
-    int muldivindex = -1; /* Last * or / at plevel 0 for multiplying or dividing */
-    int expindex = -1; /* Last ^ fount at plevel 0 for exponents */
-    int posnegindex = -1; /* First +,- at plevel 0 for positive,negative */
-
-    /* Make sure some conditions are right */
-    if(start > end)
-        return EXPR_ERROR_UNKNOWN;
-
-    /* Scan the string for certain characters */
-    for(pos = start; pos <= end; pos++)
-        {
-        switch(tokens[pos].type)
-            {
-            case EXPR_TOKEN_OPAREN:
-                plevel++;
-
-                /* First group open? */
-                if(plevel == 1 && fgopen == -1)
-                    fgopen = pos;
-                break;
-
-            case EXPR_TOKEN_CPAREN:
-                plevel--;
-
-                /* First group close? */
-                if(plevel == 0 && fgclose == -1)
-                    fgclose = pos;
-
-                if(plevel < 0)
-                    {
-                    obj->starterr = tokens[pos].start;
-                    obj->enderr = tokens[pos].end;
-                    return EXPR_ERROR_UNMATCHEDPAREN;
-                    }
-                break;
-
-            case EXPR_TOKEN_EQUAL:
-                /* Assignment found */
-                if(plevel == 0)
-                    {
-                    if(assignindex == -1)
-                        assignindex = pos;
-                    }
-                break;
-
-            case EXPR_TOKEN_ASTERISK:
-            case EXPR_TOKEN_FSLASH:
-                /* Multiplication or division */
-                if(plevel == 0)
-                    muldivindex = pos;
-                break;
-
-            case EXPR_TOKEN_HAT:
-                /* Exponent */
-                if(plevel == 0)
-                    expindex = pos;
-                break;
-
-
-            case EXPR_TOKEN_PLUS:
-            case EXPR_TOKEN_HYPHEN:
-                /* Addition or positive or subtraction or negative*/
-                if(plevel == 0)
-                    {
-                    if(pos == start)
-                        {
-                        /* At the start area, positive/negative */
-                        if(posnegindex == -1)
-                            posnegindex = pos;
-                        }
-                    else
-                        {
-                        /* Not at start, check item in front */
-                        switch(tokens[pos - 1].type)
-                            {
-                            case EXPR_TOKEN_EQUAL: /* Equal sign */
-                            case EXPR_TOKEN_PLUS: /* Add/positive sign */
-                            case EXPR_TOKEN_HYPHEN: /* Subtract/negative sign */
-                            case EXPR_TOKEN_ASTERISK: /* Multiply sign */
-                            case EXPR_TOKEN_FSLASH: /* Divide sign */
-                            case EXPR_TOKEN_HAT: /* Exponent sign */
-
-                                /* After theses, it is positive/negative */
-                                if(posnegindex == -1)
-                                    posnegindex = pos;
-
-                                break;
-
-                            default:
-                                /* Otherwise it is addition/subtraction */
-                                addsubindex = pos;
-                                break;
-                            }
-                        }
-                    }
-                break;
-
-            }
-        }
-
-    /* plevel should now be zero */
-    if(plevel != 0)
-        return EXPR_ERROR_UNMATCHEDPAREN;
-
-    /* We must parse the data in a certain order to maintain the
-       correct order of operators at evaluation time */
-
-    /* First, take care of assignment */
-    if(assignindex != -1)
-        return exprInternalParseAssign(obj, node, tokens, start, end, assignindex);
-
-    /* Addition or subtraction is next */
-    if(addsubindex != -1)
-        {
-        if(tokens[addsubindex].type == EXPR_TOKEN_PLUS)
-            return exprInternalParseAdd(obj, node, tokens, start, end, addsubindex);
-        else
-            return exprInternalParseSub(obj, node, tokens, start, end, addsubindex);
-        }
-
-
-    /* Multiplycation or division */
-    if(muldivindex != -1)
-        {
-        if(tokens[muldivindex].type == EXPR_TOKEN_ASTERISK)
-            return exprInternalParseMul(obj, node, tokens, start, end, muldivindex);
-        else
-            return exprInternalParseDiv(obj, node, tokens, start, end, muldivindex);
-        }
-
-    /* Exponent */
-    if(expindex != -1)
-        return exprInternalParseExp(obj, node, tokens, start, end, expindex);
-
-    /* Negation */
-    if(posnegindex != -1)
-        return exprInternalParsePosNeg(obj, node, tokens, start, end, posnegindex);
-
-
-    /* Grouped parenthesis */
-    if(fgopen == start)
-        {
-        /* Closing paren. should be at the end */
-        if(fgclose == end)
-            {
-            /* Anything between them */
-            if(fgclose > fgopen + 1)
-                {
-                return exprInternalParse(obj, node, tokens, fgopen + 1, fgclose - 1);
-                }
-            else
-                {
-                /* Nothing between them */
-                obj->starterr = tokens[fgopen].start;
-                obj->enderr = tokens[fgclose].end;
-                return EXPR_ERROR_SYNTAX;
-                }
-            }
-        else /* Closing paren not at the end */
-            return EXPR_ERROR_SYNTAX;
-        }
-
-    /* Functions */
-    if(fgopen > start)
-        {
-        /* Closing paren should be at end */
-        if(fgclose == end)
-            {
-            return exprInternalParseFunction(obj, node, tokens, start, end, fgopen, fgclose);
-            }
-        else /* Closing paren not at end */
-            return EXPR_ERROR_SYNTAX;
-        }
-
-    /* If it was none of the above, it must be a variable or value */
-    return exprInternalParseVarVal(obj, node, tokens, start, end);
-    }
-
-/* Function to parse an assignment node */
-int exprInternalParseAssign(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-    exprValList *l;
-    EXPRTYPE *addr;
-
-    /* Make sure the equal sign is not at the start or end */
-    if(index != start + 1 || index >= end)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-    /* Make sure item before equal sign is an identifier */
-    if(tokens[index - 1].type != EXPR_TOKEN_IDENTIFIER)
-        {
-        obj->starterr = tokens[index - 1].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-    /* Create expression subnode */
-    tmp = exprAllocNodes(1);
-    if(tmp == NULL)
-        {
-        return EXPR_ERROR_MEMORY;
-        }
-
-
-    /* Set the data */
-    node->type = EXPR_NODETYPE_ASSIGN;
-    node->data.assign.node = tmp;
-
-
-    /*
-        The fast access method directly accesses the memory address
-        of the variable's value at evaluation time.  Because of this,
-        we must make sure the variable does exists in the variable list.
-    */
-
-    /* Make sure name is not a constant name */
-    l = exprGetConstList(obj);
-    if(l)
-        {
-        exprValListGetAddress(l, tokens[index - 1].data.str, &addr);
-        if(addr)
-            {
-            obj->starterr = tokens[index - 1].start;
-            obj->enderr = tokens[index].end;
-            return EXPR_ERROR_CONSTANTASSIGN;
-            }
-        }
-
-    /* Get the variable list */
-    l = exprGetVarList(obj);
-    if(l == NULL)
-        return EXPR_ERROR_NOVARLIST;
-
-    /* Get variable address if already in the list */
-    exprValListGetAddress(l, tokens[index - 1].data.str, &addr);
-    if(addr == NULL) /* Variable not in the list, add it */
-        {
-        exprValListAdd(l, tokens[index - 1].data.str, 0.0);
-
-        /* Try to get address again */
-        exprValListGetAddress(l, tokens[index - 1].data.str, &addr);
-        if(addr == NULL) /* Could not add variable */
-            return EXPR_ERROR_MEMORY; /* Could not add variable to list */
-        }
-
-    node->data.assign.vaddr = addr;
-
-    /* Parse the subnode */
-    return exprInternalParse(obj, tmp, tokens, index + 1, end);
-    }
-
-/* Function to parse an addition operator */
-int exprInternalParseAdd(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-    int err;
-
-    /* Make sure plus sign is at a good place */
-    if(index <= start || index >= end)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-    /* Allocate space for 2 subnodes */
-    tmp = exprAllocNodes(2);
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-
-
-    /* Set the data */
-    node->type = EXPR_NODETYPE_ADD;
-    node->data.oper.nodes = tmp;
-    node->data.oper.nodecount = 2;
-
-    /* parse the left side */
-    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
-    if(err != EXPR_ERROR_NOERROR)
-        return err;
-
-    /* parse the right side */
-    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
-    }
-
-/* Function to parse a subtraction operator */
-int exprInternalParseSub(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-    int err;
-
-    /* Make sure minus sign is at a good place */
-    if(index <= start || index >= end)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-    /* Allocate space for 2 subnodes */
-    tmp = exprAllocNodes(2);
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-
-
-    /* Set the data */
-    node->type = EXPR_NODETYPE_SUBTRACT;
-    node->data.oper.nodes = tmp;
-    node->data.oper.nodecount = 2;
-    
-    /* parse the left side */
-    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
-    if(err != EXPR_ERROR_NOERROR)
-        return err;
-
-    /* parse the right side */
-    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
-    }
-
-/* Function to parse a multiplication operator */
-int exprInternalParseMul(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-    int err;
-
-    /* Make sure times sign is at a good place */
-    if(index <= start || index >= end)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-
-    /* Allocate space for 2 subnodes */
-    tmp = exprAllocNodes(2);
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-
-
-    /* Set the data */
-    node->type = EXPR_NODETYPE_MULTIPLY;
-    node->data.oper.nodes = tmp;
-    node->data.oper.nodecount = 2;
-
-    /* parse the left side */
-    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
-    if(err != EXPR_ERROR_NOERROR)
-        return err;
-
-    /* parse the right side */
-    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
-    }
-
-/* Function to parse a division operator */
-int exprInternalParseDiv(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-    int err;
-
-    /* Make sure slash sign is at a good place */
-    if(index <= start || index >= end)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-
-    /* Allocate space for 2 subnodes */
-    tmp = exprAllocNodes(2);
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-
-
-    /* Set the data */
-    node->type = EXPR_NODETYPE_DIVIDE;
-    node->data.oper.nodes = tmp;
-    node->data.oper.nodecount = 2;
-
-    /* parse the left side */
-    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
-    if(err != EXPR_ERROR_NOERROR)
-        return err;
-
-    /* parse the right side */
-    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
-    }
-
-/* Function to parse an exponent operator */
-int exprInternalParseExp(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-    int err;
-
-    /* Make sure exponent sign is at a good place */
-    if(index <= start || index >= end)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-
-    /* Allocate space for 2 subnodes */
-    tmp = exprAllocNodes(2);
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-
-
-    /* Set the data */
-    node->type = EXPR_NODETYPE_EXPONENT;
-    node->data.oper.nodes = tmp;
-    node->data.oper.nodecount = 2;
-
-    /* parse the left side */
-    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
-    if(err != EXPR_ERROR_NOERROR)
-        return err;
-
-    /* parse the right side */
-    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
-    }
-
-/* Function to parse for positive and negative */
-int exprInternalParsePosNeg(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
-    {
-    exprNode *tmp;
-
-    /* Position should be the same as start */
-    if(index != start)
-        {
-        obj->starterr = tokens[index].start;
-        obj->enderr = tokens[index].end;
-        return EXPR_ERROR_UNKNOWN;
-        }
-
-    /* If it is a positive, just parse the internal of it */
-    if(tokens[index].type == EXPR_TOKEN_PLUS)
-        return exprInternalParse(obj, node, tokens, index + 1, end);
-    else
-        {
-        /* Allocate subnode */
-        tmp = exprAllocNodes(1);
-        if(tmp == NULL)
-            return EXPR_ERROR_NOERROR;
-
-
-        /* Set data */
-        node->type = EXPR_NODETYPE_NEGATE;
-        node->data.oper.nodes = tmp;
-        node->data.oper.nodecount = 1;
-
-        /* Parse the subnode */
-        return exprInternalParse(obj, tmp, tokens, index + 1, end);
-        }
-    }
-
-/* Function will parse a call to a function */
-int exprInternalParseFunction(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int p1, int p2)
-    {
-    int pos;
-    int num, cur;
-    int refnum, refcur;
-    int plevel = 0;
-    int lv, err;
-    exprNode *tmp;
-    exprFuncType fptr;
-    int argmin, argmax;
-    int refargmin, refargmax;
-    int type;
-    exprFuncList *l;
-    exprValList *vars;
-    EXPRTYPE *addr;
-    EXPRTYPE **reftmp;
-
-    /* We should have a function list */
-    l = exprGetFuncList(obj);
-    if(l == NULL)
-        return EXPR_ERROR_NOSUCHFUNCTION;
-
-    /* check paren. location */
-    if(p2 <= p1)
-        return EXPR_ERROR_SYNTAX;
-
-    /* second paren. should not be after the end */
-    if(p2 > end)
-        return EXPR_ERROR_SYNTAX;
-
-    /* Item before parenthesis should be an identifier */
-    if(tokens[p1 - 1].type != EXPR_TOKEN_IDENTIFIER)
-        {
-        obj->starterr = tokens[p1 - 1].start;
-        obj->enderr = tokens[p1].end;
-        return EXPR_ERROR_SYNTAX;
-        }
-
-
-    /* Look up the function */
-    err = exprFuncListGet(l, tokens[p1 - 1].data.str, &fptr, &type, &argmin, &argmax, &refargmin, &refargmax);
-    if(err != EXPR_ERROR_NOERROR)
-        {
-        if(err == EXPR_ERROR_NOTFOUND)
-            {
-            obj->starterr = tokens[p1 - 1].start;
-            obj->enderr = tokens[p1 - 1].end;
-            return EXPR_ERROR_NOSUCHFUNCTION;
-            }
-        else
-            return err;
-        }
-
-    /* Make sure the function exists */
-    if(fptr == NULL && type == 0)
-        {
-        obj->starterr = tokens[p1 - 1].start;
-        obj->enderr = tokens[p1 - 1].end;
-        return EXPR_ERROR_NOSUCHFUNCTION;
-        }
-
-    /* Count arguments */
-    if(p2 == p1 + 1)
-        {
-        num = 0;
-        refnum = 0;
-        }
-    else
-        {
-        num = 1;
-        refnum = 0;
-
-
-        /* count commas */
-        for(pos = p1 + 1; pos < p2; pos++)
-            {
-            switch(tokens[pos].type)
-                {
-                case EXPR_TOKEN_OPAREN:
-                    plevel++;
-                    break;
-
-                case EXPR_TOKEN_CPAREN:
-                    plevel--;
-                    if(plevel < 0)
-                        {
-                        obj->starterr = tokens[pos].start;
-                        obj->enderr = tokens[pos].end;
-                        return EXPR_ERROR_UNMATCHEDPAREN;
-                        }
-                    break;
-
-                case EXPR_TOKEN_COMMA:
-                    /* Found comma */
-                    if(plevel == 0)
-                        num++;
-                    break;
-
-                case EXPR_TOKEN_AMPERSAND:
-                    /* Found reference mark */
-                    if(plevel == 0)
-                        {
-                        /* This may only occur after the open parenthesis or comma */
-                        if(tokens[pos - 1].type == EXPR_TOKEN_OPAREN || tokens[pos - 1].type == EXPR_TOKEN_COMMA)
-                            refnum++;
-                        else
-                            return EXPR_ERROR_SYNTAX;
-                        }
-                    break;
-                }
-            }
-
-        /* plevel should be zero */
-        if(plevel != 0)
-            return EXPR_ERROR_UNMATCHEDPAREN;
-        }
-
-    /* We now have the number of total arguments and
-       number of ref arguments.  Get number of normal
-       arguments */
-    num = num - refnum;
-
-    /* Make sure number of arguments is correct */
-    /* Here we make sure the limits are greater
-       or equal to zero because any negative number
-       could be used to specify no limit */
-    if(argmin >= 0 && num < argmin)
-        {
-        obj->starterr = tokens[p1 - 1].start;
-        obj->enderr = tokens[p2].end;
-        return EXPR_ERROR_BADNUMBERARGUMENTS;
-        }
-
-    if(argmax >= 0 && num > argmax)
-        {
-        obj->starterr = tokens[p1 - 1].start;
-        obj->enderr = tokens[p2].end;
-        return EXPR_ERROR_BADNUMBERARGUMENTS;
-        }
-
-    if(refargmin >= 0 && refnum < refargmin)
-        {
-        obj->starterr = tokens[p1 - 1].start;
-        obj->enderr = tokens[p2].end;
-        return EXPR_ERROR_BADNUMBERARGUMENTS;
-        }
-
-    if(refargmax >= 0 && refnum > refargmax)
-        {
-        obj->starterr = tokens[p1 - 1].start;
-        obj->enderr = tokens[p2].end;
-        return EXPR_ERROR_BADNUMBERARGUMENTS;
-        }
-
-    /* Set tmp to null in case of no arguments */
-    tmp = NULL;
-    reftmp = NULL;
-
-    if(num > 0)
-        {
-        /* Allocate subnodes */
-        tmp = exprAllocNodes(num);
-        if(tmp == NULL)
-            return EXPR_ERROR_MEMORY;
-        }
-
-    if(refnum > 0)
-        {
-        /* Allocate ref pointers */
-        reftmp = exprAllocMem(sizeof(EXPRTYPE*) * refnum);
-        if(reftmp == NULL)
-            {
-            exprFreeMem(tmp);
-            return EXPR_ERROR_MEMORY;
-            }
-        }
-
-
-
-    /* Set this node's data */
-    node->type = EXPR_NODETYPE_FUNCTION;
-    node->data.function.fptr = fptr;
-    node->data.function.nodecount = num;
-    node->data.function.nodes = tmp;
-    node->data.function.refcount = refnum;
-    node->data.function.refs = reftmp;
-    node->data.function.type = type;
-
-    /* parse each subnode */
-    if(num + refnum > 0)
-        {
-        plevel = 0;
-        cur = 0;
-        refcur = 0;
-        lv = p1 + 1;
-
-        /* look for commas if more than 1 arg */
-        if(num + refnum > 1)
-            {
-            for(pos = p1 + 1; pos < p2; pos++)
-                {
-                switch(tokens[pos].type)
-                    {
-                    case EXPR_TOKEN_OPAREN:
-                        plevel++;
-                        break;
-
-                    case EXPR_TOKEN_CPAREN:
-                        plevel--;
-                        break; /* Already checked paren nesting above */
-
-                    case EXPR_TOKEN_COMMA:
-                        /* Found comma */
-                        if(plevel == 0)
-                            {
-                            /* parse inside */
-                            if(tokens[lv].type == EXPR_TOKEN_AMPERSAND)
-                                {
-                                if(lv != pos - 2)
-                                    {
-                                    obj->starterr = tokens[lv].start;
-                                    obj->enderr = tokens[pos].end;
-                                    return EXPR_ERROR_SYNTAX;
-                                    }
-
-                                /* It is a reference */
-                                if(tokens[lv + 1].type != EXPR_TOKEN_IDENTIFIER)
-                                    {
-                                    obj->starterr = tokens[lv].start;
-                                    obj->enderr = tokens[lv + 1].end;
-                                    return EXPR_ERROR_SYNTAX;
-                                    }
-
-                                
-                                /* Make sure it is not a constant */
-                                vars = exprGetConstList(obj);
-                                if(vars)
-                                    {
-                                    exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
-                                    if(addr)
-                                        {
-                                        obj->starterr = tokens[lv].start;
-                                        obj->enderr = tokens[lv + 1].start;
-                                        return EXPR_ERROR_REFCONSTANT;
-                                        }
-                                    }
-
-                                /* Get variable list */
-                                vars = exprGetVarList(obj);
-                                if(vars == NULL)
-                                    return EXPR_ERROR_NOVARLIST;
-
-                                /* Get variable address */
-                                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
-                                if(addr == NULL)
-                                    {
-                                    /* Add variable to list */
-                                    exprValListAdd(vars, tokens[lv + 1].data.str, 0.0);
-
-                                    /* Try to get address again */
-                                    exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
-                                    if(addr == NULL)
-                                        return EXPR_ERROR_MEMORY; /* Could not add variable */
-                                    }
-
-                                /* Set reference item */
-                                reftmp[refcur] = addr;
-
-                                /* increase ref arg number and lv position*/
-                                refcur++;
-                                lv = pos + 1;
-                                }
-                            else
-                                {
-                                err = exprInternalParse(obj, &(tmp[cur]), tokens, lv, pos - 1);
-                                if(err != EXPR_ERROR_NOERROR)
-                                    return err;
-
-                                /* increase arg number and lv position*/
-                                lv = pos + 1;
-                                cur++;
-                                }
-                            }
-                        break;
-                    }
-                }
-            }
-
-        /* lv should point after the last comma, or open paren. if only 1 arg */
-        if(tokens[lv].type == EXPR_TOKEN_AMPERSAND)
-            {
-            if(lv != p2 - 2)
-                {
-                obj->starterr = tokens[lv].start;
-                obj->enderr = tokens[p2].end; 
-                return EXPR_ERROR_SYNTAX;
-                }
-
-            /* It is a reference */
-            if(tokens[lv + 1].type != EXPR_TOKEN_IDENTIFIER)
-                {
-                obj->starterr = tokens[lv].start;
-                obj->enderr = tokens[lv + 1].end;
-                return EXPR_ERROR_SYNTAX;
-                }
-            
-            /* Make sure it is not a constant */
-            vars = exprGetConstList(obj);
-            if(vars)
-                {
-                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
-                if(addr)
-                    {
-                    obj->starterr = tokens[lv].start;
-                    obj->enderr = tokens[lv + 1].start;
-                    return EXPR_ERROR_REFCONSTANT;
-                    }
-                }
-
-            /* Get variable list */
-            vars = exprGetVarList(obj);
-            if(vars == NULL)
-                return EXPR_ERROR_NOVARLIST;
-
-            /* Get variable address */
-            exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
-            if(addr == NULL)
-                {
-                /* Add variable to list */
-                exprValListAdd(vars, tokens[lv + 1].data.str, 0.0);
-
-                /* Try to get address again */
-                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
-                if(addr == NULL)
-                    return EXPR_ERROR_MEMORY; /* Could not add variable */
-                }
-
-            /* Set reference item */
-            reftmp[refcur] = addr;
-            }
-        else
-            {
-            err = exprInternalParse(obj, &(tmp[cur]), tokens, lv, p2 - 1);
-            if(err != EXPR_ERROR_NOERROR)
-                return err;
-            }
-        }
-
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-/* Parse a variable or value */
-int exprInternalParseVarVal(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end)
-    {
-    exprValList *l;
-    EXPRTYPE *addr;
-
-
-    /* Make sure positions are correct */
-    if(start != end)
-        {
-        return EXPR_ERROR_UNKNOWN;
-        }
-    
-    
-    /* Are we an identifier */
-    if(tokens[start].type == EXPR_TOKEN_IDENTIFIER)
-        {
-        /* we are an identifier */
-
-        /* check to see if it is a constant */
-        l = exprGetConstList(obj);
-        if(l != NULL)
-            {
-            if(exprValListGetAddress(l, tokens[start].data.str, &addr) == EXPR_ERROR_NOERROR)
-                {
-                /* We found it in the constant list */
-
-                /*
-                    Treat is like a variable node so application can change
-                    constant value and it will reflect in expression
-                */
-
-                node->type = EXPR_NODETYPE_VARIABLE;
-                node->data.variable.vaddr = addr;
-                return EXPR_ERROR_NOERROR;
-                }
-            }
-
-        /* Not found in the constant list, so it must be a variable */
-
-        /* Set node type */
-        node->type = EXPR_NODETYPE_VARIABLE;
-
-        /*
-            The fast access method directly accesses the memory address
-            of the variable's value at evaluation time.  Because of this,
-            we must make sure the variable does exists in the variable list.
-        */
-
-        /* Get the variable list */
-        l = exprGetVarList(obj);
-        if(l == NULL)
-            return EXPR_ERROR_NOVARLIST;
-
-        /* Get variable address if already in the list */
-        exprValListGetAddress(l, tokens[start].data.str, &addr);
-        if(addr == NULL) /* Variable not in the list, add it */
-            {
-            exprValListAdd(l, tokens[start].data.str, 0.0);
-
-            /* Try to get address again */
-            exprValListGetAddress(l, tokens[start].data.str, &addr);
-            if(addr == NULL) /* Could not add variable */
-                return EXPR_ERROR_MEMORY; /* Could not add variable to list */
-            }
-
-        node->data.variable.vaddr = addr;
-
-        return EXPR_ERROR_NOERROR;
-        }
-    else if(tokens[start].type == EXPR_TOKEN_VALUE)
-        {
-        /* we are a value */
-        node->type = EXPR_NODETYPE_VALUE;
-        node->data.value.value = tokens[start].data.val;
-        return EXPR_ERROR_NOERROR;
-        }
-    else
-        {
-        obj->starterr = tokens[start].start;
-        obj->enderr = tokens[end].end;
-        return EXPR_ERROR_UNKNOWN;
-        }
-    }
+/*
+    File: exprpars.c
+    Auth: Brian Allen Vanderburg II
+    Date: Wednesday, April 30, 2003
+    Desc: Actual parsing routines for this library
+
+    This file is part of ExprEval.
+*/
+
+/* Includes */
+#include "exprincl.h"
+
+#include "exprpriv.h"
+#include "exprmem.h"
+
+/* Data structure used by parser */
+typedef struct _exprToken
+    {
+    int type; /* token type */
+    int start; /* token start position */
+    int end; /* token end position */
+
+    union _tdata
+        {
+        char *str; /* string data */
+        EXPRTYPE val; /* value data */
+        } data;
+    } exprToken;
+
+/* Defines for token types */
+#define EXPR_TOKEN_UNKNOWN 0
+#define EXPR_TOKEN_OPAREN 1
+#define EXPR_TOKEN_CPAREN 2
+#define EXPR_TOKEN_IDENTIFIER 3
+#define EXPR_TOKEN_VALUE 4
+#define EXPR_TOKEN_PLUS 5
+#define EXPR_TOKEN_HYPHEN 6
+#define EXPR_TOKEN_ASTERISK 7
+#define EXPR_TOKEN_FSLASH 8
+#define EXPR_TOKEN_AMPERSAND 9
+#define EXPR_TOKEN_SEMICOLON 10
+#define EXPR_TOKEN_COMMA 11
+#define EXPR_TOKEN_EQUAL 12
+#define EXPR_TOKEN_HAT 13
+
+/* Internal functions */
+int exprMultiParse(exprObj *obj, exprNode *node, exprToken *tokens, int count);
+int exprInternalParse(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end);
+int exprInternalParseAssign(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParseAdd(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParseSub(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParseMul(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParseDiv(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParsePosNeg(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParseExp(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index);
+int exprInternalParseFunction(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int p1, int p2);
+int exprInternalParseVarVal(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end);
+int exprStringToTokenList(exprObj *obj, char *expr, exprToken **tokens, int *count);
+void exprFreeTokenList(exprToken *tokens, int count);
+
+/* This frees a token list */
+void exprFreeTokenList(exprToken *tokens, int count)
+    {
+    int pos;
+
+    if(tokens == NULL)
+        return;
+
+    for(pos = 0; pos < count; pos++)
+        {
+        if(tokens[pos].type == EXPR_TOKEN_IDENTIFIER)
+            exprFreeMem(tokens[pos].data.str);
+        }
+
+    exprFreeMem(tokens);
+    }
+
+/* This converts an expression string to a token list */
+int exprStringToTokenList(exprObj *obj, char *expr, exprToken **tokens, int *count)
+    {
+    int found;
+    exprToken *list;
+    int pass;
+    int pos, len;
+    int tpos;
+    int comment; /* Is a comment active */
+    int start, ilen;
+    char buf[EXPR_MAXIDENTSIZE + 1];
+
+    /* Set initial variables */
+    found = 0;
+    tpos = 0;
+    list = NULL;
+    comment = 0;
+    *tokens = NULL;
+    *count = 0;
+
+
+    /* Check string length */
+    len = (int)strlen(expr);
+    if(len == 0)
+        return EXPR_ERROR_EMPTYEXPR;
+
+    /* Two passes, one to count, one to tokenize */
+    for(pass = 0; pass <= 1; pass++)
+        {
+        for(pos = 0; pos < len; pos++)
+            {
+            switch(expr[pos])
+                {
+                /* Comment */
+                case '#':
+                    {
+                    /* Only set it if a comment is not already active */
+                    if(!comment)
+                        comment = 1;
+
+                    break;
+                    }
+
+                /* Newline characters turn off comments */
+                case '\r':
+                case '\n':
+                    {
+                    /* If a comment is active, unset it */
+                    if(comment)
+                        comment = 0;
+
+                    break;
+                    }
+
+                /* Open parenthesis */
+                case '(':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_OPAREN;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Close parenthesis */
+                case ')':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_CPAREN;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Plus */
+                case '+':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_PLUS;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Hyphen */
+                case '-':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_HYPHEN;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Asterisk */
+                case '*':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_ASTERISK;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Forward slash */
+                case '/':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_FSLASH;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Hat */
+                case '^':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_HAT;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Ampersand */
+                case '&':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_AMPERSAND;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Semicolon */
+                case ';':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_SEMICOLON;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Comma */
+                case ',':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_COMMA;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Equal sign */
+                case '=':
+                    {
+                    if(!comment)
+                        {
+                        if(pass == 0)
+                            found++;
+                        else
+                            {
+                            list[tpos].type = EXPR_TOKEN_EQUAL;
+                            list[tpos].start = pos;
+                            list[tpos].end = pos;
+                            tpos++;
+                            }
+                        }
+
+                    break;
+                    }
+
+                /* Identifiers and values */
+                default:
+                    {
+                    if(!comment)
+                        {
+                        if(expr[pos] == '.' || isdigit(expr[pos]))
+                            {
+                            /* Value */
+                            start = pos;
+
+                            /* Find digits before a period */
+                            while(isdigit(expr[pos]))
+                                pos++;
+
+                            /* Find a period */
+                            if(expr[pos] == '.')
+                                pos++;
+
+                            /* Find digits after a period */
+                            while(isdigit(expr[pos]))
+                                pos++;
+
+                            /* pos is AFTER last item, back up */
+                            pos--;
+
+                            if(pass == 0)
+                                found++;
+                            else
+                                {
+                                ilen = pos - start + 1;
+
+                                /* Is the value to large */
+                                if(ilen > EXPR_MAXIDENTSIZE)
+                                    {
+                                    obj->starterr = start;
+                                    obj->enderr = pos;
+                                    exprFreeTokenList(list, found);
+                                    return EXPR_ERROR_BADIDENTIFIER;
+                                    }
+
+                                /* Create value token */
+                                strncpy(buf, expr + start, ilen);
+                                buf[ilen] = '\0';
+
+                                list[tpos].type = EXPR_TOKEN_VALUE;
+                                list[tpos].start = start;
+                                list[tpos].end = pos;
+                                list[tpos].data.val = (EXPRTYPE)atof(buf);
+                                tpos++;
+                                }
+                            }
+                        else if(expr[pos] == '_' || isalpha(expr[pos]))
+                            {
+                            /* Identifier */
+                            start = pos;
+
+                            /* Find rest of identifier */
+                            while(expr[pos] == '_' || isalnum(expr[pos]))
+                                pos++;
+
+                            /* pos is AFTER last item, back up */
+                            pos--;
+
+                            if(pass == 0)
+                                found++;
+                            else
+                                {
+                                ilen = pos - start + 1;
+
+                                /* Is the value to large */
+                                if(ilen > EXPR_MAXIDENTSIZE)
+                                    {
+                                    obj->starterr = start;
+                                    obj->enderr = pos;
+                                    exprFreeTokenList(list, found);
+                                    return EXPR_ERROR_BADIDENTIFIER;
+                                    }
+
+                                /* Create value token */
+                                strncpy(buf, expr + start, ilen);
+                                buf[ilen] = '\0';
+
+                                /* Allocate memory for identifier */
+                                list[tpos].data.str = exprAllocMem(ilen + 1);
+                                if(list[tpos].data.str == NULL)
+                                    {
+                                    exprFreeTokenList(list, found);
+                                    return EXPR_ERROR_MEMORY;
+                                    }
+
+                                list[tpos].type = EXPR_TOKEN_IDENTIFIER;
+                                list[tpos].start = start;
+                                list[tpos].end = pos;
+                                strcpy(list[tpos].data.str, buf);
+                                tpos++;
+                                }
+                            }
+                        else if(isspace(expr[pos]))
+                            {
+                            /* Spaces are ignored, do nothing */
+                            }
+                        else
+                            {
+                            /* Unknown */
+                            obj->starterr = obj->enderr = pos;
+                            exprFreeTokenList(list, found);
+                            return EXPR_ERROR_INVALIDCHAR;
+                            }
+                        }
+
+                    break;
+                    }
+                }
+            }
+
+        /* If pass is 0, allocate memory for next pass */
+        if(pass == 0)
+            {
+            /* First, make sure all comments were ended */
+            if(comment)
+                comment = 0;
+
+            /* Make sure the expression is not empty */
+            if(found == 0)
+                return EXPR_ERROR_EMPTYEXPR;
+
+            /* Allocate memory for token list */
+            list = exprAllocMem(found * sizeof(exprToken));
+            if(list == NULL)
+                return EXPR_ERROR_MEMORY;
+
+            tpos = 0;
+            }
+        }
+
+    *count = found;
+    *tokens = list;
+    return EXPR_ERROR_NOERROR;
+    }
+
+
+/* This is the main parsing routine */
+int exprParse(exprObj *obj, char *expr)
+    {
+    exprToken *tokens;
+    int count;
+    int err;
+    exprNode *tmp;
+
+    /* Make sure an object was passed */
+    if(obj == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    /* Clear expression error position */
+    obj->starterr = obj->enderr = -1;
+
+    /* Have we already been parsed? */
+    if(obj->parsedbad != 0)
+        return EXPR_ERROR_ALREADYPARSEDBAD;
+
+    if(obj->parsedgood != 0)
+        return EXPR_ERROR_ALREADYPARSEDGOOD;
+
+    /* Make sure an expression was passed */
+    if(expr == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    /* Create token list */
+    err = exprStringToTokenList(obj, expr, &tokens, &count);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+    
+    /* Create head pointer */
+    tmp = exprAllocNodes(1);
+    if(tmp == NULL)
+        {
+        exprFreeTokenList(tokens, count);
+        return EXPR_ERROR_MEMORY;
+        }
+
+    obj->headnode = tmp;
+
+    /* Call the multiparse routine to parse subexpressions */
+    err = exprMultiParse(obj, tmp, tokens, count);
+
+    /* Free the token list */
+    exprFreeTokenList(tokens, count);
+
+    /* successful parse? */
+    if(err == EXPR_ERROR_NOERROR)
+        {
+        obj->parsedgood = 1;
+        obj->parsedbad = 0;
+        }
+    else
+        {
+        obj->parsedbad = 1;
+        obj->parsedgood = 0;
+        }
+
+    return err;
+    }
+
+
+/* Parse the subexpressions, each ending with semicolons */
+int exprMultiParse(exprObj *obj, exprNode *node, exprToken *tokens, int count)
+    {
+    int pos, plevel, last;
+    int num, cur, err;
+    exprNode *tmp;
+
+    plevel = 0;
+    num = 0;
+    last = -1;
+
+    /* First count the number of arguments */
+    for(pos = 0; pos < count; pos++)
+        {
+        switch(tokens[pos].type)
+            {
+            case EXPR_TOKEN_OPAREN:
+                /* increase plevel */
+                plevel++;
+                break;
+
+            case EXPR_TOKEN_CPAREN:
+                /* decrease plevel */
+                plevel--;
+
+                if(plevel < 0)
+                    {
+                    obj->starterr = tokens[pos].start;
+                    obj->enderr = tokens[pos].end;
+                    return EXPR_ERROR_UNMATCHEDPAREN;
+                    }
+
+                break;
+
+            case EXPR_TOKEN_SEMICOLON:
+                if(plevel == 0)
+                    {
+                    if(last == pos - 1 || pos == 0)
+                        {
+                        /* last semicolon is before us or we are at the start */
+                        obj->starterr = tokens[pos].start;
+                        obj->enderr = tokens[pos].end;
+                        return EXPR_ERROR_SYNTAX;
+                        }
+                    else
+                        {
+                        /* last semicolon is not right before us */
+                        num++;
+                        }
+                    }
+                else
+                    {
+                    /* Semicolon should not be in a parenthesis */
+                    obj->starterr = tokens[pos].start;
+                    obj->enderr = tokens[pos].end;
+                    return EXPR_ERROR_SYNTAX;
+                    }
+
+                last = pos; /* update position of last semicolon */
+                break;
+            }
+        }
+
+    /* plevel should be zero now */
+    if(plevel != 0)
+        return EXPR_ERROR_UNMATCHEDPAREN;
+
+    /* the last character should be a semicolon */
+    if(last != pos - 1)
+        return EXPR_ERROR_MISSINGSEMICOLON;
+
+    /* Now we know how many arguments there are */
+
+    /* Allocate array of subnodes */
+    tmp = exprAllocNodes(num);
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+
+    /* Set the current node's data */
+    node->type = EXPR_NODETYPE_MULTI;
+    node->data.oper.nodes = tmp;
+    node->data.oper.nodecount = num;
+
+    /* now we parse each subexpression */
+    last = 0; /* Not for last semicolon, but for first char of subexpr */
+    cur = 0;
+
+    for(pos = 0; pos < count; pos++)
+        {
+        if(tokens[pos].type == EXPR_TOKEN_SEMICOLON)
+            {
+            /* Everything from last up to pos - 1 is a parameter */
+            err = exprInternalParse(obj, &(tmp[cur]), tokens, last, pos - 1);
+            if(err != EXPR_ERROR_NOERROR)
+                return err;
+
+            /* Update last position and current argument */
+            last = pos + 1;
+            cur++;
+            }
+        }
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+/* This function parses each subnode and recurses if needed */
+int exprInternalParse(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end)
+    {
+    int pos;
+    int plevel = 0; /* Paren level */
+    int fgopen = -1; /* First paren group open index */
+    int fgclose = -1; /* First paren group close index */
+    int assignindex = -1; /* First = at plevel 0 for assignment */
+    int addsubindex = -1; /* Last + or - at plevel 0 for adding or subtracting */
+    int muldivindex = -1; /* Last * or / at plevel 0 for multiplying or dividing */
+    int expindex = -1; /* Last ^ fount at plevel 0 for exponents */
+    int posnegindex = -1; /* First +,- at plevel 0 for positive,negative */
+
+    /* Make sure some conditions are right */
+    if(start > end)
+        return EXPR_ERROR_UNKNOWN;
+
+    /* Scan the string for certain characters */
+    for(pos = start; pos <= end; pos++)
+        {
+        switch(tokens[pos].type)
+            {
+            case EXPR_TOKEN_OPAREN:
+                plevel++;
+
+                /* First group open? */
+                if(plevel == 1 && fgopen == -1)
+                    fgopen = pos;
+                break;
+
+            case EXPR_TOKEN_CPAREN:
+                plevel--;
+
+                /* First group close? */
+                if(plevel == 0 && fgclose == -1)
+                    fgclose = pos;
+
+                if(plevel < 0)
+                    {
+                    obj->starterr = tokens[pos].start;
+                    obj->enderr = tokens[pos].end;
+                    return EXPR_ERROR_UNMATCHEDPAREN;
+                    }
+                break;
+
+            case EXPR_TOKEN_EQUAL:
+                /* Assignment found */
+                if(plevel == 0)
+                    {
+                    if(assignindex == -1)
+                        assignindex = pos;
+                    }
+                break;
+
+            case EXPR_TOKEN_ASTERISK:
+            case EXPR_TOKEN_FSLASH:
+                /* Multiplication or division */
+                if(plevel == 0)
+                    muldivindex = pos;
+                break;
+
+            case EXPR_TOKEN_HAT:
+                /* Exponent */
+                if(plevel == 0)
+                    expindex = pos;
+                break;
+
+
+            case EXPR_TOKEN_PLUS:
+            case EXPR_TOKEN_HYPHEN:
+                /* Addition or positive or subtraction or negative*/
+                if(plevel == 0)
+                    {
+                    if(pos == start)
+                        {
+                        /* At the start area, positive/negative */
+                        if(posnegindex == -1)
+                            posnegindex = pos;
+                        }
+                    else
+                        {
+                        /* Not at start, check item in front */
+                        switch(tokens[pos - 1].type)
+                            {
+                            case EXPR_TOKEN_EQUAL: /* Equal sign */
+                            case EXPR_TOKEN_PLUS: /* Add/positive sign */
+                            case EXPR_TOKEN_HYPHEN: /* Subtract/negative sign */
+                            case EXPR_TOKEN_ASTERISK: /* Multiply sign */
+                            case EXPR_TOKEN_FSLASH: /* Divide sign */
+                            case EXPR_TOKEN_HAT: /* Exponent sign */
+
+                                /* After theses, it is positive/negative */
+                                if(posnegindex == -1)
+                                    posnegindex = pos;
+
+                                break;
+
+                            default:
+                                /* Otherwise it is addition/subtraction */
+                                addsubindex = pos;
+                                break;
+                            }
+                        }
+                    }
+                break;
+
+            }
+        }
+
+    /* plevel should now be zero */
+    if(plevel != 0)
+        return EXPR_ERROR_UNMATCHEDPAREN;
+
+    /* We must parse the data in a certain order to maintain the
+       correct order of operators at evaluation time */
+
+    /* First, take care of assignment */
+    if(assignindex != -1)
+        return exprInternalParseAssign(obj, node, tokens, start, end, assignindex);
+
+    /* Addition or subtraction is next */
+    if(addsubindex != -1)
+        {
+        if(tokens[addsubindex].type == EXPR_TOKEN_PLUS)
+            return exprInternalParseAdd(obj, node, tokens, start, end, addsubindex);
+        else
+            return exprInternalParseSub(obj, node, tokens, start, end, addsubindex);
+        }
+
+
+    /* Multiplycation or division */
+    if(muldivindex != -1)
+        {
+        if(tokens[muldivindex].type == EXPR_TOKEN_ASTERISK)
+            return exprInternalParseMul(obj, node, tokens, start, end, muldivindex);
+        else
+            return exprInternalParseDiv(obj, node, tokens, start, end, muldivindex);
+        }
+
+    /* Exponent */
+    if(expindex != -1)
+        return exprInternalParseExp(obj, node, tokens, start, end, expindex);
+
+    /* Negation */
+    if(posnegindex != -1)
+        return exprInternalParsePosNeg(obj, node, tokens, start, end, posnegindex);
+
+
+    /* Grouped parenthesis */
+    if(fgopen == start)
+        {
+        /* Closing paren. should be at the end */
+        if(fgclose == end)
+            {
+            /* Anything between them */
+            if(fgclose > fgopen + 1)
+                {
+                return exprInternalParse(obj, node, tokens, fgopen + 1, fgclose - 1);
+                }
+            else
+                {
+                /* Nothing between them */
+                obj->starterr = tokens[fgopen].start;
+                obj->enderr = tokens[fgclose].end;
+                return EXPR_ERROR_SYNTAX;
+                }
+            }
+        else /* Closing paren not at the end */
+            return EXPR_ERROR_SYNTAX;
+        }
+
+    /* Functions */
+    if(fgopen > start)
+        {
+        /* Closing paren should be at end */
+        if(fgclose == end)
+            {
+            return exprInternalParseFunction(obj, node, tokens, start, end, fgopen, fgclose);
+            }
+        else /* Closing paren not at end */
+            return EXPR_ERROR_SYNTAX;
+        }
+
+    /* If it was none of the above, it must be a variable or value */
+    return exprInternalParseVarVal(obj, node, tokens, start, end);
+    }
+
+/* Function to parse an assignment node */
+int exprInternalParseAssign(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+    exprValList *l;
+    EXPRTYPE *addr;
+
+    /* Make sure the equal sign is not at the start or end */
+    if(index != start + 1 || index >= end)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+    /* Make sure item before equal sign is an identifier */
+    if(tokens[index - 1].type != EXPR_TOKEN_IDENTIFIER)
+        {
+        obj->starterr = tokens[index - 1].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+    /* Create expression subnode */
+    tmp = exprAllocNodes(1);
+    if(tmp == NULL)
+        {
+        return EXPR_ERROR_MEMORY;
+        }
+
+
+    /* Set the data */
+    node->type = EXPR_NODETYPE_ASSIGN;
+    node->data.assign.node = tmp;
+
+
+    /*
+        The fast access method directly accesses the memory address
+        of the variable's value at evaluation time.  Because of this,
+        we must make sure the variable does exists in the variable list.
+    */
+
+    /* Make sure name is not a constant name */
+    l = exprGetConstList(obj);
+    if(l)
+        {
+        exprValListGetAddress(l, tokens[index - 1].data.str, &addr);
+        if(addr)
+            {
+            obj->starterr = tokens[index - 1].start;
+            obj->enderr = tokens[index].end;
+            return EXPR_ERROR_CONSTANTASSIGN;
+            }
+        }
+
+    /* Get the variable list */
+    l = exprGetVarList(obj);
+    if(l == NULL)
+        return EXPR_ERROR_NOVARLIST;
+
+    /* Get variable address if already in the list */
+    exprValListGetAddress(l, tokens[index - 1].data.str, &addr);
+    if(addr == NULL) /* Variable not in the list, add it */
+        {
+        exprValListAdd(l, tokens[index - 1].data.str, 0.0);
+
+        /* Try to get address again */
+        exprValListGetAddress(l, tokens[index - 1].data.str, &addr);
+        if(addr == NULL) /* Could not add variable */
+            return EXPR_ERROR_MEMORY; /* Could not add variable to list */
+        }
+
+    node->data.assign.vaddr = addr;
+
+    /* Parse the subnode */
+    return exprInternalParse(obj, tmp, tokens, index + 1, end);
+    }
+
+/* Function to parse an addition operator */
+int exprInternalParseAdd(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+    int err;
+
+    /* Make sure plus sign is at a good place */
+    if(index <= start || index >= end)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+    /* Allocate space for 2 subnodes */
+    tmp = exprAllocNodes(2);
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+
+
+    /* Set the data */
+    node->type = EXPR_NODETYPE_ADD;
+    node->data.oper.nodes = tmp;
+    node->data.oper.nodecount = 2;
+
+    /* parse the left side */
+    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* parse the right side */
+    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
+    }
+
+/* Function to parse a subtraction operator */
+int exprInternalParseSub(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+    int err;
+
+    /* Make sure minus sign is at a good place */
+    if(index <= start || index >= end)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+    /* Allocate space for 2 subnodes */
+    tmp = exprAllocNodes(2);
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+
+
+    /* Set the data */
+    node->type = EXPR_NODETYPE_SUBTRACT;
+    node->data.oper.nodes = tmp;
+    node->data.oper.nodecount = 2;
+    
+    /* parse the left side */
+    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* parse the right side */
+    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
+    }
+
+/* Function to parse a multiplication operator */
+int exprInternalParseMul(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+    int err;
+
+    /* Make sure times sign is at a good place */
+    if(index <= start || index >= end)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+
+    /* Allocate space for 2 subnodes */
+    tmp = exprAllocNodes(2);
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+
+
+    /* Set the data */
+    node->type = EXPR_NODETYPE_MULTIPLY;
+    node->data.oper.nodes = tmp;
+    node->data.oper.nodecount = 2;
+
+    /* parse the left side */
+    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* parse the right side */
+    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
+    }
+
+/* Function to parse a division operator */
+int exprInternalParseDiv(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+    int err;
+
+    /* Make sure slash sign is at a good place */
+    if(index <= start || index >= end)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+
+    /* Allocate space for 2 subnodes */
+    tmp = exprAllocNodes(2);
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+
+
+    /* Set the data */
+    node->type = EXPR_NODETYPE_DIVIDE;
+    node->data.oper.nodes = tmp;
+    node->data.oper.nodecount = 2;
+
+    /* parse the left side */
+    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* parse the right side */
+    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
+    }
+
+/* Function to parse an exponent operator */
+int exprInternalParseExp(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+    int err;
+
+    /* Make sure exponent sign is at a good place */
+    if(index <= start || index >= end)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+
+    /* Allocate space for 2 subnodes */
+    tmp = exprAllocNodes(2);
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+
+
+    /* Set the data */
+    node->type = EXPR_NODETYPE_EXPONENT;
+    node->data.oper.nodes = tmp;
+    node->data.oper.nodecount = 2;
+
+    /* parse the left side */
+    err = exprInternalParse(obj, &(tmp[0]), tokens, start, index - 1);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* parse the right side */
+    return exprInternalParse(obj, &(tmp[1]), tokens, index + 1, end);
+    }
+
+/* Function to parse for positive and negative */
+int exprInternalParsePosNeg(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int index)
+    {
+    exprNode *tmp;
+
+    /* Position should be the same as start */
+    if(index != start)
+        {
+        obj->starterr = tokens[index].start;
+        obj->enderr = tokens[index].end;
+        return EXPR_ERROR_UNKNOWN;
+        }
+
+    /* If it is a positive, just parse the internal of it */
+    if(tokens[index].type == EXPR_TOKEN_PLUS)
+        return exprInternalParse(obj, node, tokens, index + 1, end);
+    else
+        {
+        /* Allocate subnode */
+        tmp = exprAllocNodes(1);
+        if(tmp == NULL)
+            return EXPR_ERROR_NOERROR;
+
+
+        /* Set data */
+        node->type = EXPR_NODETYPE_NEGATE;
+        node->data.oper.nodes = tmp;
+        node->data.oper.nodecount = 1;
+
+        /* Parse the subnode */
+        return exprInternalParse(obj, tmp, tokens, index + 1, end);
+        }
+    }
+
+/* Function will parse a call to a function */
+int exprInternalParseFunction(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end, int p1, int p2)
+    {
+    int pos;
+    int num, cur;
+    int refnum, refcur;
+    int plevel = 0;
+    int lv, err;
+    exprNode *tmp;
+    exprFuncType fptr;
+    int argmin, argmax;
+    int refargmin, refargmax;
+    int type;
+    exprFuncList *l;
+    exprValList *vars;
+    EXPRTYPE *addr;
+    EXPRTYPE **reftmp;
+
+    /* We should have a function list */
+    l = exprGetFuncList(obj);
+    if(l == NULL)
+        return EXPR_ERROR_NOSUCHFUNCTION;
+
+    /* check paren. location */
+    if(p2 <= p1)
+        return EXPR_ERROR_SYNTAX;
+
+    /* second paren. should not be after the end */
+    if(p2 > end)
+        return EXPR_ERROR_SYNTAX;
+
+    /* Item before parenthesis should be an identifier */
+    if(tokens[p1 - 1].type != EXPR_TOKEN_IDENTIFIER)
+        {
+        obj->starterr = tokens[p1 - 1].start;
+        obj->enderr = tokens[p1].end;
+        return EXPR_ERROR_SYNTAX;
+        }
+
+
+    /* Look up the function */
+    err = exprFuncListGet(l, tokens[p1 - 1].data.str, &fptr, &type, &argmin, &argmax, &refargmin, &refargmax);
+    if(err != EXPR_ERROR_NOERROR)
+        {
+        if(err == EXPR_ERROR_NOTFOUND)
+            {
+            obj->starterr = tokens[p1 - 1].start;
+            obj->enderr = tokens[p1 - 1].end;
+            return EXPR_ERROR_NOSUCHFUNCTION;
+            }
+        else
+            return err;
+        }
+
+    /* Make sure the function exists */
+    if(fptr == NULL && type == 0)
+        {
+        obj->starterr = tokens[p1 - 1].start;
+        obj->enderr = tokens[p1 - 1].end;
+        return EXPR_ERROR_NOSUCHFUNCTION;
+        }
+
+    /* Count arguments */
+    if(p2 == p1 + 1)
+        {
+        num = 0;
+        refnum = 0;
+        }
+    else
+        {
+        num = 1;
+        refnum = 0;
+
+
+        /* count commas */
+        for(pos = p1 + 1; pos < p2; pos++)
+            {
+            switch(tokens[pos].type)
+                {
+                case EXPR_TOKEN_OPAREN:
+                    plevel++;
+                    break;
+
+                case EXPR_TOKEN_CPAREN:
+                    plevel--;
+                    if(plevel < 0)
+                        {
+                        obj->starterr = tokens[pos].start;
+                        obj->enderr = tokens[pos].end;
+                        return EXPR_ERROR_UNMATCHEDPAREN;
+                        }
+                    break;
+
+                case EXPR_TOKEN_COMMA:
+                    /* Found comma */
+                    if(plevel == 0)
+                        num++;
+                    break;
+
+                case EXPR_TOKEN_AMPERSAND:
+                    /* Found reference mark */
+                    if(plevel == 0)
+                        {
+                        /* This may only occur after the open parenthesis or comma */
+                        if(tokens[pos - 1].type == EXPR_TOKEN_OPAREN || tokens[pos - 1].type == EXPR_TOKEN_COMMA)
+                            refnum++;
+                        else
+                            return EXPR_ERROR_SYNTAX;
+                        }
+                    break;
+                }
+            }
+
+        /* plevel should be zero */
+        if(plevel != 0)
+            return EXPR_ERROR_UNMATCHEDPAREN;
+        }
+
+    /* We now have the number of total arguments and
+       number of ref arguments.  Get number of normal
+       arguments */
+    num = num - refnum;
+
+    /* Make sure number of arguments is correct */
+    /* Here we make sure the limits are greater
+       or equal to zero because any negative number
+       could be used to specify no limit */
+    if(argmin >= 0 && num < argmin)
+        {
+        obj->starterr = tokens[p1 - 1].start;
+        obj->enderr = tokens[p2].end;
+        return EXPR_ERROR_BADNUMBERARGUMENTS;
+        }
+
+    if(argmax >= 0 && num > argmax)
+        {
+        obj->starterr = tokens[p1 - 1].start;
+        obj->enderr = tokens[p2].end;
+        return EXPR_ERROR_BADNUMBERARGUMENTS;
+        }
+
+    if(refargmin >= 0 && refnum < refargmin)
+        {
+        obj->starterr = tokens[p1 - 1].start;
+        obj->enderr = tokens[p2].end;
+        return EXPR_ERROR_BADNUMBERARGUMENTS;
+        }
+
+    if(refargmax >= 0 && refnum > refargmax)
+        {
+        obj->starterr = tokens[p1 - 1].start;
+        obj->enderr = tokens[p2].end;
+        return EXPR_ERROR_BADNUMBERARGUMENTS;
+        }
+
+    /* Set tmp to null in case of no arguments */
+    tmp = NULL;
+    reftmp = NULL;
+
+    if(num > 0)
+        {
+        /* Allocate subnodes */
+        tmp = exprAllocNodes(num);
+        if(tmp == NULL)
+            return EXPR_ERROR_MEMORY;
+        }
+
+    if(refnum > 0)
+        {
+        /* Allocate ref pointers */
+        reftmp = exprAllocMem(sizeof(EXPRTYPE*) * refnum);
+        if(reftmp == NULL)
+            {
+            exprFreeMem(tmp);
+            return EXPR_ERROR_MEMORY;
+            }
+        }
+
+
+
+    /* Set this node's data */
+    node->type = EXPR_NODETYPE_FUNCTION;
+    node->data.function.fptr = fptr;
+    node->data.function.nodecount = num;
+    node->data.function.nodes = tmp;
+    node->data.function.refcount = refnum;
+    node->data.function.refs = reftmp;
+    node->data.function.type = type;
+
+    /* parse each subnode */
+    if(num + refnum > 0)
+        {
+        plevel = 0;
+        cur = 0;
+        refcur = 0;
+        lv = p1 + 1;
+
+        /* look for commas if more than 1 arg */
+        if(num + refnum > 1)
+            {
+            for(pos = p1 + 1; pos < p2; pos++)
+                {
+                switch(tokens[pos].type)
+                    {
+                    case EXPR_TOKEN_OPAREN:
+                        plevel++;
+                        break;
+
+                    case EXPR_TOKEN_CPAREN:
+                        plevel--;
+                        break; /* Already checked paren nesting above */
+
+                    case EXPR_TOKEN_COMMA:
+                        /* Found comma */
+                        if(plevel == 0)
+                            {
+                            /* parse inside */
+                            if(tokens[lv].type == EXPR_TOKEN_AMPERSAND)
+                                {
+                                if(lv != pos - 2)
+                                    {
+                                    obj->starterr = tokens[lv].start;
+                                    obj->enderr = tokens[pos].end;
+                                    return EXPR_ERROR_SYNTAX;
+                                    }
+
+                                /* It is a reference */
+                                if(tokens[lv + 1].type != EXPR_TOKEN_IDENTIFIER)
+                                    {
+                                    obj->starterr = tokens[lv].start;
+                                    obj->enderr = tokens[lv + 1].end;
+                                    return EXPR_ERROR_SYNTAX;
+                                    }
+
+                                
+                                /* Make sure it is not a constant */
+                                vars = exprGetConstList(obj);
+                                if(vars)
+                                    {
+                                    exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
+                                    if(addr)
+                                        {
+                                        obj->starterr = tokens[lv].start;
+                                        obj->enderr = tokens[lv + 1].start;
+                                        return EXPR_ERROR_REFCONSTANT;
+                                        }
+                                    }
+
+                                /* Get variable list */
+                                vars = exprGetVarList(obj);
+                                if(vars == NULL)
+                                    return EXPR_ERROR_NOVARLIST;
+
+                                /* Get variable address */
+                                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
+                                if(addr == NULL)
+                                    {
+                                    /* Add variable to list */
+                                    exprValListAdd(vars, tokens[lv + 1].data.str, 0.0);
+
+                                    /* Try to get address again */
+                                    exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
+                                    if(addr == NULL)
+                                        return EXPR_ERROR_MEMORY; /* Could not add variable */
+                                    }
+
+                                /* Set reference item */
+                                reftmp[refcur] = addr;
+
+                                /* increase ref arg number and lv position*/
+                                refcur++;
+                                lv = pos + 1;
+                                }
+                            else
+                                {
+                                err = exprInternalParse(obj, &(tmp[cur]), tokens, lv, pos - 1);
+                                if(err != EXPR_ERROR_NOERROR)
+                                    return err;
+
+                                /* increase arg number and lv position*/
+                                lv = pos + 1;
+                                cur++;
+                                }
+                            }
+                        break;
+                    }
+                }
+            }
+
+        /* lv should point after the last comma, or open paren. if only 1 arg */
+        if(tokens[lv].type == EXPR_TOKEN_AMPERSAND)
+            {
+            if(lv != p2 - 2)
+                {
+                obj->starterr = tokens[lv].start;
+                obj->enderr = tokens[p2].end; 
+                return EXPR_ERROR_SYNTAX;
+                }
+
+            /* It is a reference */
+            if(tokens[lv + 1].type != EXPR_TOKEN_IDENTIFIER)
+                {
+                obj->starterr = tokens[lv].start;
+                obj->enderr = tokens[lv + 1].end;
+                return EXPR_ERROR_SYNTAX;
+                }
+            
+            /* Make sure it is not a constant */
+            vars = exprGetConstList(obj);
+            if(vars)
+                {
+                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
+                if(addr)
+                    {
+                    obj->starterr = tokens[lv].start;
+                    obj->enderr = tokens[lv + 1].start;
+                    return EXPR_ERROR_REFCONSTANT;
+                    }
+                }
+
+            /* Get variable list */
+            vars = exprGetVarList(obj);
+            if(vars == NULL)
+                return EXPR_ERROR_NOVARLIST;
+
+            /* Get variable address */
+            exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
+            if(addr == NULL)
+                {
+                /* Add variable to list */
+                exprValListAdd(vars, tokens[lv + 1].data.str, 0.0);
+
+                /* Try to get address again */
+                exprValListGetAddress(vars, tokens[lv + 1].data.str, &addr);
+                if(addr == NULL)
+                    return EXPR_ERROR_MEMORY; /* Could not add variable */
+                }
+
+            /* Set reference item */
+            reftmp[refcur] = addr;
+            }
+        else
+            {
+            err = exprInternalParse(obj, &(tmp[cur]), tokens, lv, p2 - 1);
+            if(err != EXPR_ERROR_NOERROR)
+                return err;
+            }
+        }
+
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+/* Parse a variable or value */
+int exprInternalParseVarVal(exprObj *obj, exprNode *node, exprToken *tokens, int start, int end)
+    {
+    exprValList *l;
+    EXPRTYPE *addr;
+
+
+    /* Make sure positions are correct */
+    if(start != end)
+        {
+        return EXPR_ERROR_UNKNOWN;
+        }
+    
+    
+    /* Are we an identifier */
+    if(tokens[start].type == EXPR_TOKEN_IDENTIFIER)
+        {
+        /* we are an identifier */
+
+        /* check to see if it is a constant */
+        l = exprGetConstList(obj);
+        if(l != NULL)
+            {
+            if(exprValListGetAddress(l, tokens[start].data.str, &addr) == EXPR_ERROR_NOERROR)
+                {
+                /* We found it in the constant list */
+
+                /*
+                    Treat is like a variable node so application can change
+                    constant value and it will reflect in expression
+                */
+
+                node->type = EXPR_NODETYPE_VARIABLE;
+                node->data.variable.vaddr = addr;
+                return EXPR_ERROR_NOERROR;
+                }
+            }
+
+        /* Not found in the constant list, so it must be a variable */
+
+        /* Set node type */
+        node->type = EXPR_NODETYPE_VARIABLE;
+
+        /*
+            The fast access method directly accesses the memory address
+            of the variable's value at evaluation time.  Because of this,
+            we must make sure the variable does exists in the variable list.
+        */
+
+        /* Get the variable list */
+        l = exprGetVarList(obj);
+        if(l == NULL)
+            return EXPR_ERROR_NOVARLIST;
+
+        /* Get variable address if already in the list */
+        exprValListGetAddress(l, tokens[start].data.str, &addr);
+        if(addr == NULL) /* Variable not in the list, add it */
+            {
+            exprValListAdd(l, tokens[start].data.str, 0.0);
+
+            /* Try to get address again */
+            exprValListGetAddress(l, tokens[start].data.str, &addr);
+            if(addr == NULL) /* Could not add variable */
+                return EXPR_ERROR_MEMORY; /* Could not add variable to list */
+            }
+
+        node->data.variable.vaddr = addr;
+
+        return EXPR_ERROR_NOERROR;
+        }
+    else if(tokens[start].type == EXPR_TOKEN_VALUE)
+        {
+        /* we are a value */
+        node->type = EXPR_NODETYPE_VALUE;
+        node->data.value.value = tokens[start].data.val;
+        return EXPR_ERROR_NOERROR;
+        }
+    else
+        {
+        obj->starterr = tokens[start].start;
+        obj->enderr = tokens[end].end;
+        return EXPR_ERROR_UNKNOWN;
+        }
+    }

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprpriv.h
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprpriv.h	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprpriv.h	Tue Nov 13 15:23:26 2007
@@ -1,215 +1,215 @@
-/*
-    File: exprpriv.h
-    Auth: Brian Allen Vanderburg II
-    Date: Tuesday, February 28, 2006
-    Desc: Private include file for ExprEval library
-
-    This file is part of ExprEval.
-*/
-
-
-/* Include once */
-#ifndef __BAVII_EXPRPRIV_H
-#define __BAVII_EXPRPRIV_H
-
-/* Need some definitions, NULL, etc */
-#include <stddef.h>
-
-/* Include config and main expreval header */
-#include "expreval.h"
-#include "exprconf.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
-    Version number
-*/
-#define EXPR_VERSIONMAJOR 2
-#define EXPR_VERSIONMINOR 7
-
-/* Node types */
-enum
-    {
-    EXPR_NODETYPE_UNKNOWN = 0,
-    EXPR_NODETYPE_MULTI,
-    EXPR_NODETYPE_ADD,
-    EXPR_NODETYPE_SUBTRACT,
-    EXPR_NODETYPE_MULTIPLY,
-    EXPR_NODETYPE_DIVIDE,
-    EXPR_NODETYPE_EXPONENT,
-    EXPR_NODETYPE_NEGATE,
-    EXPR_NODETYPE_VALUE,
-    EXPR_NODETYPE_VARIABLE,
-    EXPR_NODETYPE_ASSIGN,
-    EXPR_NODETYPE_FUNCTION
-    };
-
-/* Functions can be evaluated directly in EXPREVAL.  If fptr
-   is NULL, type is used to determine what the function is */
-enum
-    {
-    EXPR_NODEFUNC_UNKNOWN = 0,
-    EXPR_NODEFUNC_ABS,
-    EXPR_NODEFUNC_MOD,
-    EXPR_NODEFUNC_IPART,
-    EXPR_NODEFUNC_FPART,
-    EXPR_NODEFUNC_MIN,
-    EXPR_NODEFUNC_MAX,
-    EXPR_NODEFUNC_POW,
-    EXPR_NODEFUNC_SQRT,
-    EXPR_NODEFUNC_SIN,
-    EXPR_NODEFUNC_SINH,
-    EXPR_NODEFUNC_ASIN,
-    EXPR_NODEFUNC_COS,
-    EXPR_NODEFUNC_COSH,
-    EXPR_NODEFUNC_ACOS,
-    EXPR_NODEFUNC_TAN,
-    EXPR_NODEFUNC_TANH,
-    EXPR_NODEFUNC_ATAN,
-    EXPR_NODEFUNC_ATAN2,
-    EXPR_NODEFUNC_LOG,
-    EXPR_NODEFUNC_POW10,
-    EXPR_NODEFUNC_LN,
-    EXPR_NODEFUNC_EXP,
-    EXPR_NODEFUNC_LOGN,
-    EXPR_NODEFUNC_CEIL,
-    EXPR_NODEFUNC_FLOOR,
-    EXPR_NODEFUNC_RAND,
-    EXPR_NODEFUNC_RANDOM,
-    EXPR_NODEFUNC_RANDOMIZE,
-    EXPR_NODEFUNC_DEG,
-    EXPR_NODEFUNC_RAD,
-    EXPR_NODEFUNC_RECTTOPOLR,
-    EXPR_NODEFUNC_RECTTOPOLA,
-    EXPR_NODEFUNC_POLTORECTX,
-    EXPR_NODEFUNC_POLTORECTY,
-    EXPR_NODEFUNC_IF,
-    EXPR_NODEFUNC_SELECT,
-    EXPR_NODEFUNC_EQUAL,
-    EXPR_NODEFUNC_ABOVE,
-    EXPR_NODEFUNC_BELOW,
-    EXPR_NODEFUNC_AVG,
-    EXPR_NODEFUNC_CLIP,
-    EXPR_NODEFUNC_CLAMP,
-    EXPR_NODEFUNC_PNTCHANGE,
-    EXPR_NODEFUNC_POLY,
-    EXPR_NODEFUNC_AND,
-    EXPR_NODEFUNC_OR,
-    EXPR_NODEFUNC_NOT,
-    EXPR_NODEFUNC_FOR,
-    EXPR_NODEFUNC_MANY
-    };
-
-/* Forward declarations */
-typedef struct _exprFunc exprFunc;
-typedef struct _exprVal exprVal;
-
-/* Expression object */
-struct _exprObj
-    {
-    struct _exprFuncList *flist; /* Functions */
-    struct _exprValList *vlist; /* Variables */
-    struct _exprValList *clist; /* Constants */
-    struct _exprNode *headnode; /* Head parsed node */
-
-    exprBreakFuncType breakerfunc; /* Break function type */
-
-    void *userdata; /* User data, can be any 32 bit value */
-    int parsedgood; /* non-zero if successfully parsed */
-    int parsedbad; /* non-zero if parsed but unsuccessful */
-    int breakcount; /* how often to check the breaker function */
-    int breakcur; /* do we check the breaker function yet */
-    int starterr; /* start position of an error */
-    int enderr; /* end position of an error */
-    };
-
-/* Object for a function */
-struct _exprFunc
-    {
-    char *fname; /* Name of the function */
-    exprFuncType fptr; /* Function pointer */
-    int min, max; /* Min and max args for the function. */
-    int refmin, refmax; /* Min and max ref. variables for the function */
-    int type; /* Function node type.  exprEvalNOde solves the function */
-
-    struct _exprFunc *next; /* For linked list */
-    };
-
-/* Function list object */
-struct _exprFuncList
-    {
-    struct _exprFunc *head;
-    };
-
-/* Object for values */
-struct _exprVal
-    {
-    char *vname; /* Name of the value */
-    EXPRTYPE vval; /* Value of the value */
-    EXPRTYPE *vptr; /* Pointer to a value.  Used only if not NULL */
-
-    struct _exprVal *next; /* For linked list */
-    };
-
-/* Value list */
-struct _exprValList
-    {
-    struct _exprVal *head;
-    };
-
-/* Expression node type */
-struct _exprNode
-    {
-    int type; /* Node type */
-
-    union _data /* Union of info for various types */
-        {
-        struct _oper
-            {
-            struct _exprNode *nodes; /* Operation arguments */
-            int nodecount; /* Number of arguments */
-            } oper;
-
-        struct _variable
-            {
-            EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
-            } variable;
-
-        struct _value
-            {
-            EXPRTYPE value; /* Value if type is value */
-            } value;
-
-        struct _assign /* Assignment struct */
-            {
-            EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
-            struct _exprNode *node; /* Node to evaluate */
-            } assign;
-
-        struct _function
-            {
-            exprFuncType fptr; /* Function pointer */
-            struct _exprNode *nodes; /* Array of argument nodes */
-            int nodecount; /* Number of argument nodes */
-            EXPRTYPE **refs; /* Reference variables */
-            int refcount; /* Number of variable references (not a reference counter) */
-            int type; /* Type of function for exprEvalNode if fptr is NULL */
-            } function;
-        } data;
-    };
-
-
-
-/* Functions for function lists */
-int exprFuncListAddType(exprFuncList *flist, char *name, int type, int min, int max, int refmin, int refmax);
-int exprFuncListGet(exprFuncList *flist, char *name, exprFuncType *ptr, int *type, int *min, int *max, int *refmin, int *refmax);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __BAVII_EXPRPRIV_H */
-
+/*
+    File: exprpriv.h
+    Auth: Brian Allen Vanderburg II
+    Date: Tuesday, February 28, 2006
+    Desc: Private include file for ExprEval library
+
+    This file is part of ExprEval.
+*/
+
+
+/* Include once */
+#ifndef __BAVII_EXPRPRIV_H
+#define __BAVII_EXPRPRIV_H
+
+/* Need some definitions, NULL, etc */
+#include <stddef.h>
+
+/* Include config and main expreval header */
+#include "expreval.h"
+#include "exprconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+    Version number
+*/
+#define EXPR_VERSIONMAJOR 2
+#define EXPR_VERSIONMINOR 7
+
+/* Node types */
+enum
+    {
+    EXPR_NODETYPE_UNKNOWN = 0,
+    EXPR_NODETYPE_MULTI,
+    EXPR_NODETYPE_ADD,
+    EXPR_NODETYPE_SUBTRACT,
+    EXPR_NODETYPE_MULTIPLY,
+    EXPR_NODETYPE_DIVIDE,
+    EXPR_NODETYPE_EXPONENT,
+    EXPR_NODETYPE_NEGATE,
+    EXPR_NODETYPE_VALUE,
+    EXPR_NODETYPE_VARIABLE,
+    EXPR_NODETYPE_ASSIGN,
+    EXPR_NODETYPE_FUNCTION
+    };
+
+/* Functions can be evaluated directly in EXPREVAL.  If fptr
+   is NULL, type is used to determine what the function is */
+enum
+    {
+    EXPR_NODEFUNC_UNKNOWN = 0,
+    EXPR_NODEFUNC_ABS,
+    EXPR_NODEFUNC_MOD,
+    EXPR_NODEFUNC_IPART,
+    EXPR_NODEFUNC_FPART,
+    EXPR_NODEFUNC_MIN,
+    EXPR_NODEFUNC_MAX,
+    EXPR_NODEFUNC_POW,
+    EXPR_NODEFUNC_SQRT,
+    EXPR_NODEFUNC_SIN,
+    EXPR_NODEFUNC_SINH,
+    EXPR_NODEFUNC_ASIN,
+    EXPR_NODEFUNC_COS,
+    EXPR_NODEFUNC_COSH,
+    EXPR_NODEFUNC_ACOS,
+    EXPR_NODEFUNC_TAN,
+    EXPR_NODEFUNC_TANH,
+    EXPR_NODEFUNC_ATAN,
+    EXPR_NODEFUNC_ATAN2,
+    EXPR_NODEFUNC_LOG,
+    EXPR_NODEFUNC_POW10,
+    EXPR_NODEFUNC_LN,
+    EXPR_NODEFUNC_EXP,
+    EXPR_NODEFUNC_LOGN,
+    EXPR_NODEFUNC_CEIL,
+    EXPR_NODEFUNC_FLOOR,
+    EXPR_NODEFUNC_RAND,
+    EXPR_NODEFUNC_RANDOM,
+    EXPR_NODEFUNC_RANDOMIZE,
+    EXPR_NODEFUNC_DEG,
+    EXPR_NODEFUNC_RAD,
+    EXPR_NODEFUNC_RECTTOPOLR,
+    EXPR_NODEFUNC_RECTTOPOLA,
+    EXPR_NODEFUNC_POLTORECTX,
+    EXPR_NODEFUNC_POLTORECTY,
+    EXPR_NODEFUNC_IF,
+    EXPR_NODEFUNC_SELECT,
+    EXPR_NODEFUNC_EQUAL,
+    EXPR_NODEFUNC_ABOVE,
+    EXPR_NODEFUNC_BELOW,
+    EXPR_NODEFUNC_AVG,
+    EXPR_NODEFUNC_CLIP,
+    EXPR_NODEFUNC_CLAMP,
+    EXPR_NODEFUNC_PNTCHANGE,
+    EXPR_NODEFUNC_POLY,
+    EXPR_NODEFUNC_AND,
+    EXPR_NODEFUNC_OR,
+    EXPR_NODEFUNC_NOT,
+    EXPR_NODEFUNC_FOR,
+    EXPR_NODEFUNC_MANY
+    };
+
+/* Forward declarations */
+typedef struct _exprFunc exprFunc;
+typedef struct _exprVal exprVal;
+
+/* Expression object */
+struct _exprObj
+    {
+    struct _exprFuncList *flist; /* Functions */
+    struct _exprValList *vlist; /* Variables */
+    struct _exprValList *clist; /* Constants */
+    struct _exprNode *headnode; /* Head parsed node */
+
+    exprBreakFuncType breakerfunc; /* Break function type */
+
+    void *userdata; /* User data, can be any 32 bit value */
+    int parsedgood; /* non-zero if successfully parsed */
+    int parsedbad; /* non-zero if parsed but unsuccessful */
+    int breakcount; /* how often to check the breaker function */
+    int breakcur; /* do we check the breaker function yet */
+    int starterr; /* start position of an error */
+    int enderr; /* end position of an error */
+    };
+
+/* Object for a function */
+struct _exprFunc
+    {
+    char *fname; /* Name of the function */
+    exprFuncType fptr; /* Function pointer */
+    int min, max; /* Min and max args for the function. */
+    int refmin, refmax; /* Min and max ref. variables for the function */
+    int type; /* Function node type.  exprEvalNOde solves the function */
+
+    struct _exprFunc *next; /* For linked list */
+    };
+
+/* Function list object */
+struct _exprFuncList
+    {
+    struct _exprFunc *head;
+    };
+
+/* Object for values */
+struct _exprVal
+    {
+    char *vname; /* Name of the value */
+    EXPRTYPE vval; /* Value of the value */
+    EXPRTYPE *vptr; /* Pointer to a value.  Used only if not NULL */
+
+    struct _exprVal *next; /* For linked list */
+    };
+
+/* Value list */
+struct _exprValList
+    {
+    struct _exprVal *head;
+    };
+
+/* Expression node type */
+struct _exprNode
+    {
+    int type; /* Node type */
+
+    union _data /* Union of info for various types */
+        {
+        struct _oper
+            {
+            struct _exprNode *nodes; /* Operation arguments */
+            int nodecount; /* Number of arguments */
+            } oper;
+
+        struct _variable
+            {
+            EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
+            } variable;
+
+        struct _value
+            {
+            EXPRTYPE value; /* Value if type is value */
+            } value;
+
+        struct _assign /* Assignment struct */
+            {
+            EXPRTYPE *vaddr; /* Used if EXPR_FAST_VAR_ACCESS defined */
+            struct _exprNode *node; /* Node to evaluate */
+            } assign;
+
+        struct _function
+            {
+            exprFuncType fptr; /* Function pointer */
+            struct _exprNode *nodes; /* Array of argument nodes */
+            int nodecount; /* Number of argument nodes */
+            EXPRTYPE **refs; /* Reference variables */
+            int refcount; /* Number of variable references (not a reference counter) */
+            int type; /* Type of function for exprEvalNode if fptr is NULL */
+            } function;
+        } data;
+    };
+
+
+
+/* Functions for function lists */
+int exprFuncListAddType(exprFuncList *flist, char *name, int type, int min, int max, int refmin, int refmax);
+int exprFuncListGet(exprFuncList *flist, char *name, exprFuncType *ptr, int *type, int *min, int *max, int *refmin, int *refmax);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BAVII_EXPRPRIV_H */
+

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprutil.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprutil.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprutil.c	Tue Nov 13 15:23:26 2007
@@ -1,43 +1,43 @@
-/*
-    File: exprutil.c
-    Auth: Brian Allen Vanderburg II
-    Date: Monday, April 28, 2003
-    Desc: Utility functions for use by this library
-
-    This file is part of ExprEval.
-*/
-
-/* Include files */
-#include "exprincl.h"
-
-#include "exprpriv.h"
-
-
-/* Return the version number */
-void exprGetVersion(int *major, int *minor)
-    {
-    *major = EXPR_VERSIONMAJOR;
-    *minor = EXPR_VERSIONMINOR;
-    }
-
-/* This utility function determines if an identifier is valid */
-int exprValidIdent(char *name)
-    {
-    if(name == NULL) /* Null string */
-        return 0;
-
-    /* First must be letter or underscore */
-    if(isalpha(*name) || *name == '_')
-        name++; /* Point to next letter */
-    else
-        return 0; /* Not letter or underscore, maybe empty*/
-
-    /* others can be letter, number, or underscore */
-    while(isalnum(*name) || *name == '_')
-        name++;
-
-    /* When the while breaks out, we should be at the end */
-    return (*name == '\0') ? 1 : 0;
-    }
-
-
+/*
+    File: exprutil.c
+    Auth: Brian Allen Vanderburg II
+    Date: Monday, April 28, 2003
+    Desc: Utility functions for use by this library
+
+    This file is part of ExprEval.
+*/
+
+/* Include files */
+#include "exprincl.h"
+
+#include "exprpriv.h"
+
+
+/* Return the version number */
+void exprGetVersion(int *major, int *minor)
+    {
+    *major = EXPR_VERSIONMAJOR;
+    *minor = EXPR_VERSIONMINOR;
+    }
+
+/* This utility function determines if an identifier is valid */
+int exprValidIdent(char *name)
+    {
+    if(name == NULL) /* Null string */
+        return 0;
+
+    /* First must be letter or underscore */
+    if(isalpha(*name) || *name == '_')
+        name++; /* Point to next letter */
+    else
+        return 0; /* Not letter or underscore, maybe empty*/
+
+    /* others can be letter, number, or underscore */
+    while(isalnum(*name) || *name == '_')
+        name++;
+
+    /* When the while breaks out, we should be at the end */
+    return (*name == '\0') ? 1 : 0;
+    }
+
+

Modified: freeswitch/trunk/src/mod/applications/mod_expr/exprval.c
==============================================================================
--- freeswitch/trunk/src/mod/applications/mod_expr/exprval.c	(original)
+++ freeswitch/trunk/src/mod/applications/mod_expr/exprval.c	Tue Nov 13 15:23:26 2007
@@ -1,395 +1,395 @@
-/*
-    File: exprval.c
-    Auth: Brian Allen Vanderburg II
-    Date: Thursday, April 24, 2003
-    Desc: Value lists for variables and constants
-
-    This file is part of ExprEval.
-*/
-
-/* Includes */
-#include "exprincl.h"
-
-#include "exprpriv.h"
-#include "exprmem.h"
-
-
-/* Internal functions */
-static exprVal *exprCreateVal(char *name, EXPRTYPE val, EXPRTYPE *addr);
-static void exprValListFreeData(exprVal *val);
-static void exprValListResetData(exprVal *val);
-
-/* This function creates the value list, */
-int exprValListCreate(exprValList **vlist)
-    {
-    exprValList *tmp;
-
-    if(vlist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    *vlist = NULL; /* Set to NULL initially */
-
-    tmp = exprAllocMem(sizeof(exprValList));
-
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY; /* Could not allocate memory */
-
-    /* Update pointer */
-    *vlist = tmp;
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-/* Add a value to the list */
-int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val)
-    {
-    exprVal *tmp;
-    exprVal *cur;
-    int result;
-
-    if(vlist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    /* Make sure the name is valid */
-    if(!exprValidIdent(name))
-        return EXPR_ERROR_BADIDENTIFIER;
-
-    if(vlist->head == NULL)
-        {
-        /* Create the node right here */
-        tmp = exprCreateVal(name, val, NULL);
-
-        if(tmp == NULL)
-            return EXPR_ERROR_MEMORY;
-
-        vlist->head = tmp;
-        return EXPR_ERROR_NOERROR;
-        }
-
-    /* See if already exists */
-    cur = vlist->head;
-
-    while(cur)
-        {
-        result = strcmp(name, cur->vname);
-        
-        if(result == 0)
-            return EXPR_ERROR_ALREADYEXISTS;
-            
-        cur = cur->next;
-        }
-        
-    /* We did not find it, create it and add it to the beginning */
-    tmp = exprCreateVal(name, val, NULL);
-
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-        
-    tmp->next = vlist->head;
-    vlist->head = tmp;
-    
-    return EXPR_ERROR_NOERROR;
-    }
-    
-/* Set a value in the list */
-int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val)
-    {
-    exprVal *cur;
-    int result;
-
-    if(vlist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    if(name == NULL || name[0] == '\0')
-        return EXPR_ERROR_NOTFOUND;
-
-    /* Find and set it */
-    cur = vlist->head;
-
-    while(cur)
-        {
-        result = strcmp(name, cur->vname);
-        
-        if(result == 0)
-            {
-            if(cur->vptr)
-                *(cur->vptr) = val;
-            else
-                cur->vval = val;
-                
-            return EXPR_ERROR_NOERROR;                
-            }
-            
-        cur = cur->next;
-        }
-        
-    return EXPR_ERROR_NOTFOUND;
-    }    
-
-/* Get the value from a list  */
-int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val)
-    {
-    exprVal *cur;
-    int result;
-
-    if(vlist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    if(name == NULL || name[0] == '\0')
-        return EXPR_ERROR_NOTFOUND;
-
-    /* Search for the item */
-    cur = vlist->head;
-
-    while(cur)
-        {
-        result = strcmp(name, cur->vname);
-
-        if(result == 0)
-            {
-            /* We found it. */
-            if(cur->vptr)
-                *val = *(cur->vptr);
-            else
-                *val = cur->vval;
-
-            /* 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;
-    }
-    
-/* Add an address to the list */
-int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr)
-    {
-    exprVal *tmp;
-    exprVal *cur;
-    int result;
-
-    if(vlist == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-    /* Make sure the name is valid */
-    if(!exprValidIdent(name))
-        return EXPR_ERROR_BADIDENTIFIER;
-
-    if(vlist->head == NULL)
-        {
-        /* Create the node right here */
-        tmp = exprCreateVal(name, (EXPRTYPE)0.0, addr);
-
-        if(tmp == NULL)
-            return EXPR_ERROR_MEMORY;
-
-        vlist->head = tmp;
-        return EXPR_ERROR_NOERROR;
-        }
-
-    /* See if it already exists */
-    cur = vlist->head;
-    
-    while(cur)
-        {
-        result = strcmp(name, cur->vname);
-
-        if(result == 0)
-            return EXPR_ERROR_ALREADYEXISTS;
-            
-        cur = cur->next;
-        }
-        
-    /* Add it to the list */
-    tmp = exprCreateVal(name, (EXPRTYPE)0.0, addr);
-
-    if(tmp == NULL)
-        return EXPR_ERROR_MEMORY;
-        
-    tmp->next = vlist->head;
-    vlist->head = tmp;
-
-    return EXPR_ERROR_NOERROR;
-    }    
-
-/* Get memory address of a variable value in a value list */
-int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr)
-    {
-    exprVal *cur;
-    int result;
-
-    /* Not found yet */
-    *addr = NULL;
-
-    if(vlist == NULL || addr == NULL)
-        return EXPR_ERROR_NULLPOINTER;
-
-
-    if(name == NULL || name[0] == '\0')
-        return EXPR_ERROR_NOTFOUND;
-
-    /* Search for the item */
-    cur = vlist->head;
-
-    while(cur)
-        {
-        result = strcmp(name, cur->vname);
-
-        if(result == 0)
-            {
-            /* We found it. */
-            if(cur->vptr)
-                *addr = cur->vptr;
-            else
-                *addr = &(cur->vval);
-
-            /* return now */
-            return EXPR_ERROR_NOERROR;
-            }
-            
-        cur = cur->next;
-        }
-
-    /* If we got here, we did not find it in the list */
-    return EXPR_ERROR_NOTFOUND;
-    }
-    
-/* This function is used to enumerate the values in a value list */
-void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie)
-    {
-    exprVal *cur;
-    
-    if(vlist == NULL)
-        return NULL;
-        
-    /* Get the current item */
-    cur = (exprVal*)cookie;
-    
-    /* Find the next item */
-    if(cur == NULL)
-        cur = vlist->head;
-    else
-        cur = cur->next;
-        
-    /* Set up the data */
-    if(cur)
-        {
-        if(name)
-            *name = cur->vname;
-           
-        if(value)
-            {
-            if(cur->vptr)
-                *value = *(cur->vptr);
-            else
-                *value = cur->vval;
-            }
-            
-        if(addr)
-            {
-            if(cur->vptr)
-                *addr = cur->vptr;
-            else
-                *addr = &(cur->vval);
-            }                                
-        }
-        
-    /* If there was no value, return NULL, otherwise, return the item */
-    return (void*)cur;
-    }
-
-/* This routine will free the value list */
-int exprValListFree(exprValList *vlist)
-    {
-    /* Make sure it exists, if not it is not error */
-    if(vlist == NULL)
-        return EXPR_ERROR_NOERROR;
-
-    /* Free the nodes */
-    exprValListFreeData(vlist->head);
-
-    /* Freethe container */
-    exprFreeMem(vlist);
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-/* This routine will reset the value list to 0.0 */
-int exprValListClear(exprValList *vlist)
-    {
-    if(vlist == NULL)
-        return EXPR_ERROR_NOERROR;
-
-    exprValListResetData(vlist->head);
-
-    return EXPR_ERROR_NOERROR;
-    }
-
-/* This routine will free any child nodes, and then free itself */
-static void exprValListFreeData(exprVal *val)
-    {
-    exprVal *next;
-    
-    while(val)
-        {
-        /* Remember the next */
-        next = val->next;
-        
-        /* Free name */
-        exprFreeMem(val->vname);
-
-        /* Free ourself */
-        exprFreeMem(val);
-        
-        val = next;
-        }
-    }
-
-/* This routine will reset variables to 0.0 */
-static void exprValListResetData(exprVal *val)
-    {
-    while(val)
-        {
-        /* Reset data */
-        if(val->vptr)
-            *(val->vptr) = 0.0;
-      
-        val->vval = 0.0;
-        
-        val = val->next;
-        }
-    }
-
-/* This routine will create the value object */
-static exprVal *exprCreateVal(char *name, EXPRTYPE val, EXPRTYPE *addr)
-    {
-    exprVal *tmp;
-    char *vtmp;
-
-    /* Name already tested in exprValListAdd */
-
-    /* Create it */
-    tmp = exprAllocMem(sizeof(exprVal));
-    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->vname = vtmp;
-    tmp->vval = val;
-    tmp->vptr = addr;
-
-    return tmp;
-    }
+/*
+    File: exprval.c
+    Auth: Brian Allen Vanderburg II
+    Date: Thursday, April 24, 2003
+    Desc: Value lists for variables and constants
+
+    This file is part of ExprEval.
+*/
+
+/* Includes */
+#include "exprincl.h"
+
+#include "exprpriv.h"
+#include "exprmem.h"
+
+
+/* Internal functions */
+static exprVal *exprCreateVal(char *name, EXPRTYPE val, EXPRTYPE *addr);
+static void exprValListFreeData(exprVal *val);
+static void exprValListResetData(exprVal *val);
+
+/* This function creates the value list, */
+int exprValListCreate(exprValList **vlist)
+    {
+    exprValList *tmp;
+
+    if(vlist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    *vlist = NULL; /* Set to NULL initially */
+
+    tmp = exprAllocMem(sizeof(exprValList));
+
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY; /* Could not allocate memory */
+
+    /* Update pointer */
+    *vlist = tmp;
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+/* Add a value to the list */
+int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val)
+    {
+    exprVal *tmp;
+    exprVal *cur;
+    int result;
+
+    if(vlist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    /* Make sure the name is valid */
+    if(!exprValidIdent(name))
+        return EXPR_ERROR_BADIDENTIFIER;
+
+    if(vlist->head == NULL)
+        {
+        /* Create the node right here */
+        tmp = exprCreateVal(name, val, NULL);
+
+        if(tmp == NULL)
+            return EXPR_ERROR_MEMORY;
+
+        vlist->head = tmp;
+        return EXPR_ERROR_NOERROR;
+        }
+
+    /* See if already exists */
+    cur = vlist->head;
+
+    while(cur)
+        {
+        result = strcmp(name, cur->vname);
+        
+        if(result == 0)
+            return EXPR_ERROR_ALREADYEXISTS;
+            
+        cur = cur->next;
+        }
+        
+    /* We did not find it, create it and add it to the beginning */
+    tmp = exprCreateVal(name, val, NULL);
+
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+        
+    tmp->next = vlist->head;
+    vlist->head = tmp;
+    
+    return EXPR_ERROR_NOERROR;
+    }
+    
+/* Set a value in the list */
+int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val)
+    {
+    exprVal *cur;
+    int result;
+
+    if(vlist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    if(name == NULL || name[0] == '\0')
+        return EXPR_ERROR_NOTFOUND;
+
+    /* Find and set it */
+    cur = vlist->head;
+
+    while(cur)
+        {
+        result = strcmp(name, cur->vname);
+        
+        if(result == 0)
+            {
+            if(cur->vptr)
+                *(cur->vptr) = val;
+            else
+                cur->vval = val;
+                
+            return EXPR_ERROR_NOERROR;                
+            }
+            
+        cur = cur->next;
+        }
+        
+    return EXPR_ERROR_NOTFOUND;
+    }    
+
+/* Get the value from a list  */
+int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val)
+    {
+    exprVal *cur;
+    int result;
+
+    if(vlist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    if(name == NULL || name[0] == '\0')
+        return EXPR_ERROR_NOTFOUND;
+
+    /* Search for the item */
+    cur = vlist->head;
+
+    while(cur)
+        {
+        result = strcmp(name, cur->vname);
+
+        if(result == 0)
+            {
+            /* We found it. */
+            if(cur->vptr)
+                *val = *(cur->vptr);
+            else
+                *val = cur->vval;
+
+            /* 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;
+    }
+    
+/* Add an address to the list */
+int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr)
+    {
+    exprVal *tmp;
+    exprVal *cur;
+    int result;
+
+    if(vlist == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+    /* Make sure the name is valid */
+    if(!exprValidIdent(name))
+        return EXPR_ERROR_BADIDENTIFIER;
+
+    if(vlist->head == NULL)
+        {
+        /* Create the node right here */
+        tmp = exprCreateVal(name, (EXPRTYPE)0.0, addr);
+
+        if(tmp == NULL)
+            return EXPR_ERROR_MEMORY;
+
+        vlist->head = tmp;
+        return EXPR_ERROR_NOERROR;
+        }
+
+    /* See if it already exists */
+    cur = vlist->head;
+    
+    while(cur)
+        {
+        result = strcmp(name, cur->vname);
+
+        if(result == 0)
+            return EXPR_ERROR_ALREADYEXISTS;
+            
+        cur = cur->next;
+        }
+        
+    /* Add it to the list */
+    tmp = exprCreateVal(name, (EXPRTYPE)0.0, addr);
+
+    if(tmp == NULL)
+        return EXPR_ERROR_MEMORY;
+        
+    tmp->next = vlist->head;
+    vlist->head = tmp;
+
+    return EXPR_ERROR_NOERROR;
+    }    
+
+/* Get memory address of a variable value in a value list */
+int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr)
+    {
+    exprVal *cur;
+    int result;
+
+    /* Not found yet */
+    *addr = NULL;
+
+    if(vlist == NULL || addr == NULL)
+        return EXPR_ERROR_NULLPOINTER;
+
+
+    if(name == NULL || name[0] == '\0')
+        return EXPR_ERROR_NOTFOUND;
+
+    /* Search for the item */
+    cur = vlist->head;
+
+    while(cur)
+        {
+        result = strcmp(name, cur->vname);
+
+        if(result == 0)
+            {
+            /* We found it. */
+            if(cur->vptr)
+                *addr = cur->vptr;
+            else
+                *addr = &(cur->vval);
+
+            /* return now */
+            return EXPR_ERROR_NOERROR;
+            }
+            
+        cur = cur->next;
+        }
+
+    /* If we got here, we did not find it in the list */
+    return EXPR_ERROR_NOTFOUND;
+    }
+    
+/* This function is used to enumerate the values in a value list */
+void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie)
+    {
+    exprVal *cur;
+    
+    if(vlist == NULL)
+        return NULL;
+        
+    /* Get the current item */
+    cur = (exprVal*)cookie;
+    
+    /* Find the next item */
+    if(cur == NULL)
+        cur = vlist->head;
+    else
+        cur = cur->next;
+        
+    /* Set up the data */
+    if(cur)
+        {
+        if(name)
+            *name = cur->vname;
+           
+        if(value)
+            {
+            if(cur->vptr)
+                *value = *(cur->vptr);
+            else
+                *value = cur->vval;
+            }
+            
+        if(addr)
+            {
+            if(cur->vptr)
+                *addr = cur->vptr;
+            else
+                *addr = &(cur->vval);
+            }                                
+        }
+        
+    /* If there was no value, return NULL, otherwise, return the item */
+    return (void*)cur;
+    }
+
+/* This routine will free the value list */
+int exprValListFree(exprValList *vlist)
+    {
+    /* Make sure it exists, if not it is not error */
+    if(vlist == NULL)
+        return EXPR_ERROR_NOERROR;
+
+    /* Free the nodes */
+    exprValListFreeData(vlist->head);
+
+    /* Freethe container */
+    exprFreeMem(vlist);
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+/* This routine will reset the value list to 0.0 */
+int exprValListClear(exprValList *vlist)
+    {
+    if(vlist == NULL)
+        return EXPR_ERROR_NOERROR;
+
+    exprValListResetData(vlist->head);
+
+    return EXPR_ERROR_NOERROR;
+    }
+
+/* This routine will free any child nodes, and then free itself */
+static void exprValListFreeData(exprVal *val)
+    {
+    exprVal *next;
+    
+    while(val)
+        {
+        /* Remember the next */
+        next = val->next;
+        
+        /* Free name */
+        exprFreeMem(val->vname);
+
+        /* Free ourself */
+        exprFreeMem(val);
+        
+        val = next;
+        }
+    }
+
+/* This routine will reset variables to 0.0 */
+static void exprValListResetData(exprVal *val)
+    {
+    while(val)
+        {
+        /* Reset data */
+        if(val->vptr)
+            *(val->vptr) = 0.0;
+      
+        val->vval = 0.0;
+        
+        val = val->next;
+        }
+    }
+
+/* This routine will create the value object */
+static exprVal *exprCreateVal(char *name, EXPRTYPE val, EXPRTYPE *addr)
+    {
+    exprVal *tmp;
+    char *vtmp;
+
+    /* Name already tested in exprValListAdd */
+
+    /* Create it */
+    tmp = exprAllocMem(sizeof(exprVal));
+    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->vname = vtmp;
+    tmp->vval = val;
+    tmp->vptr = addr;
+
+    return tmp;
+    }



More information about the Freeswitch-svn mailing list