]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Run dos2unix on mod_expr HTML files
authorTravis Cross <tc@traviscross.com>
Thu, 25 Dec 2014 10:38:10 +0000 (10:38 +0000)
committerTravis Cross <tc@traviscross.com>
Thu, 25 Dec 2014 10:38:10 +0000 (10:38 +0000)
src/mod/applications/mod_expr/expreval.html
src/mod/applications/mod_expr/exprtmpl.html

index f66d327c2d4bd1154c4d4c17739e56e1521d4485..d6cade26c2b65070089fc5dacb7e50a0fb8f0e09 100644 (file)
-<html>\r
-<head>\r
-<title>ExprEval Library</title>\r
-<style type="text/css">\r
-.valid {\r
-  color: #00AA00;\r
-}\r
-.invalid {\r
-  color: #FF0000;\r
-}\r
-.excomment {\r
-  color: #0000FF;\r
-}\r
-.container {\r
-  margin-top: 10px;\r
-  margin-bottom: 10px;\r
-  padding-left: 4px;\r
-  padding-right: 4px;\r
-  border-top: 1px solid #000000;\r
-  border-right: 1px solid #000000;\r
-  border-bottom: 1px solid #000000;\r
-  border-left: 1px solid #000000;\r
-  background-color: #BBBBBB;\r
-}\r
-body {\r
-  background-color: #AAAAAA;\r
-}\r
-</style>\r
-</head>\r
-<body>\r
-\r
-<div align="center">\r
-    <h1>ExprEval Library</h1>\r
-    <hr>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2>Contents</h2>\r
-    <h3>\r
-        <ul>\r
-            <a href="#Introduction">Introduction</a><br>\r
-            <a href="#License">License</a><br>\r
-            <a href="#Syntax">Expression Syntax</a><br>\r
-            <a href="#Using">Using ExprEval in an Application</a><br>\r
-            <a href="#FastVar">Fast Variable Access</a><br>\r
-            <a href="#InternalFuncConst">Using the Internal Functions and Constants</a><br>\r
-            <a href="#CustomFunc">Creating Custom Functions</a><br>\r
-            <a href="#Reference">Reference</a><br>\r
-            <a href="#Compiling">Compiling the ExprEval Library</a><br>\r
-            <a href="#Drawbacks">Drawbacks/Problems</a><br>\r
-            <a href="#Solutions">Problems and Solutions</a><br>\r
-            <a href="#Example">Example Use</a><br>\r
-        </ul>\r
-    </h3>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Introduction">Introduction</a></h2>\r
-    <blockquote>\r
-        <p>ExprEval Help document.  This document is probably full of\r
-            bugs and mispellings.  I may get around to proofreading\r
-            it later.</p>\r
-        <p>ExprEval is a C based expression evaluation library.\r
-            It is entirely C based, but can be used in C++ programs\r
-            as well..  The source code is provided for the library\r
-            so that it can be recompiled for the specific system\r
-            or compiler.</p>\r
-        <p>ExprEval makes adding mathematical expression support to\r
-            an application easy.  It takes an expression string and\r
-            parses it, and then it can evaluate it over and over.\r
-            This library also has support for functions, constants,\r
-            and variables.  All of these items are stored in\r
-            seperate lists so they can be shared among expressions or\r
-            they can be private to a single expression or any mix and\r
-            match.  It is up to the developer how to link them together.\r
-            You can also create your own custom functions.</p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="License">License</a></h2>\r
-    <blockquote>\r
-        <p>This library is licensed under the\r
-        <a href="license.txt">ExprEval License.</a>\r
-        </p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Syntax">Expression Syntax</a></h2>\r
-    <blockquote>\r
-        <p>Expressions have pretty much the same syntax as they\r
-            would have on paper, with the following exceptions:\r
-            <ul>\r
-                <li>Each expression must end with a semicolon. This\r
-                    is because the expression string can actually\r
-                    contain multiple expressions.  The semicolon is\r
-                    used to mark the end of the expression.<br>\r
-                    <b>Examples:</b>\r
-                    <ul>\r
-                        <li>4*x+5;</li>\r
-                        <li>y=5+2;g=4+6;</li>\r
-                        <li>y=r*sin(a);x=r*cos(a);</li>\r
-                    </ul>\r
-                </li>\r
-                <li>The asterisk '*' must be used to multiply.<br>\r
-                    <b>Examples:</b>\r
-                    <ul>\r
-                        <li>y=5*6; <b class="valid">Valid</b></li>\r
-                        <li>g=(x+1)*(x-1); <b class="valid">Valid</b></li>\r
-                        <li>g=(x+1)(x-1); <b class="invalid">Invalid</b></li>\r
-                    </ul>\r
-                </li>\r
-            </ul>\r
-        </p>\r
-        <p>More than one expression may be contained within an expression string.\r
-            As shown above, each expression must end with a semicolon, even if\r
-            only one expression is in the string. The value of an expression\r
-            string is the value of the last expression in the string.<br>\r
-            <b>Examlples:</b>\r
-            <ul>\r
-                <li>g=7; <b class="excomment">Value: 7</b></li>\r
-                <li>k=z+1; <b class="excomment">Value: z+1</b></li>\r
-                <li>r=4;k=6;o=9+r-k; <b class="excomment">Value: 9+r-k</b></li>\r
-            </ul>\r
-        </p>\r
-        <p>Some functions may take reference parameters.  These parameters are\r
-            references to other variables.  You can mix reference parameters\r
-            with normal parameters.  The order of the normal parameters must\r
-            remain the same and the order of the reference parameters must\r
-            remain the same.<br>\r
-            <b>Examples:</b>\r
-            <ul>\r
-                <li>min(1,2,3,4,&mval); <b class="excomment">&mval is a reference to a variable mval</b></li>\r
-                <li>min(1,2,&mval,3,4); <b class="excomment">You may mix them inside like this.</b></li>\r
-                <li>min(1,2,(&mval),3,4); <b class="invalid">You may not nest reference parameters in any way</b></li>\r
-            </ul>\r
-        </p>\r
-        <p>Expressions may also be nested with parenthesis.<br>\r
-        <b>Examples:</b>\r
-            <ul>\r
-                <li>y=sin(x-cos(5+max(4,5,6*x)));</li>\r
-                <li>6+(5-2*(x+y));</li>\r
-            </ul>\r
-        </p>\r
-        <p>Expressions may also have whitespace characters and comments.\r
-            Whitespace characters such as newlines, linefeeds, carriage\r
-            returns, spaces, and tabs are ignored.  Comments begin with\r
-            the pound sign '#' and end at the end of the line.<br>\r
-            <b>Example:</b>\r
-            <ul>\r
-                <pre>\r
-#Set the x value\r
-x = d * cos(r);\r
-\r
-#Set the y value\r
-y = d * sin(r);\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p>If a variable is used in an expression, but that variable does not exist,\r
-            it is considered zero.  If it does exist then its value is used instead.\r
-        </p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Using">Using ExprEval in an Application</a></h2>\r
-    <blockquote>\r
-        <p>Using ExprEval in an application can be a little difficult.\r
-            You generally follow these steps:\r
-            <ul>\r
-                <li>Create function, variable, and constant lists</li>\r
-                <li>Create the expression object</li>\r
-                <li>Parse the expression</li>\r
-                <li>Evaluate the expression as needed</li>\r
-                <li>Free the expression object</li>\r
-                <li>Free the function, variable, and constant lists</li>\r
-            </ul>\r
-            You can manipulate the lists in any order after their creation.\r
-            However, functions are translated during the parse, so after\r
-            parsing an expression, manipulating the function list will make\r
-            no change to an expression.  Variables and constants can be\r
-            manipulated after a parse to change the result of an expression.\r
-            However, you must add any constants to be used by an expression\r
-            to the constant list <b>BEFORE</b> parsing the expression,\r
-            otherwise it will be seen as a variable.  Applications can change\r
-            both variables and constants, however the expression can only\r
-            change variables.  Expressions may <b>NOT</b> assign to a constant\r
-            and expressions may <b>NOT</b> use constants as a reference parameter.</p>\r
-        <p><b>Function, variable, and constant list example:</b>\r
-            <ul>\r
-                <pre>\r
-exprFuncList *flist;\r
-exprValList *vlist;\r
-exprValList *clist;\r
-exprObj *obj;\r
-EXPRTYPE result;\r
-int err;\r
-\r
-/* Create function list */\r
-err = exprFuncListCreate(&amp;flist);\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Initialize internal functions */\r
-err = exprFuncListInit(flist);\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Create variable list */\r
-err = exprValListCreate(&amp;vlist);\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Create the constant list */\r
-err = exprValListCreate(&amp;clist);\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Initialize internal constants */\r
-err = exprValListInit(clist);\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Add any application defined functions, constants, or variables to the lists here or down below */\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p><b>Expression object example:</b>\r
-            <ul>\r
-                <pre>\r
-err = exprCreate(&obj, flist, vlist, clist, NULL, 0);\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Add any application defined functions, constants, or variables to the lists here or down below.\r
-   This is the last time you can for the functions or constants. */\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p><b>Expression parse example:</b>\r
-            <ul>\r
-                <pre>\r
-/* Functions and constants may be added or changed here */\r
-\r
-err = exprParse(obj, "2+sin(M_PI)+3*x;");\r
-if(err != EXPR_ERROR_NOERROR)\r
-    {\r
-    ...\r
-    }\r
-\r
-/* Changes to the function or constant lists do not change the expression now */\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p><b>Expression evaluation example:</b>\r
-            <ul>\r
-                <pre>\r
-/* Add or change any variables */\r
-\r
-err = exprEval(obj, &result);\r
-if(err != EXPR_ERROR_NOERRO)\r
-    {\r
-    ...\r
-    }\r
-else\r
-    {\r
-    printf("Expression Result: %f\n", result);\r
-    }\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p><b>Free the expression object and lists example:</b>\r
-            <ul>\r
-                <pre>\r
-exprFree(obj);\r
-exprValListFree(vlist);\r
-exprValListFree(clist);\r
-exprFuncListFree(flist);\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="FastVar">Fast Variable Access</a></h2>\r
-    <blockquote>\r
-        <p>A new feature in ExprEval is fast variable access.  This\r
-            is simply a technique of quickly accessing variables\r
-            by directly accessing their memory locations instead\r
-            of using the value list functions.  Fast variable access\r
-            is always used internally in ExprEval.  You must\r
-            NOT clear a variable list until after all expressions\r
-            using it are completely finished evaluating.  Then you\r
-            must reparse the expressions before using them again.\r
-            The reason is simple. When fast variable access is used,\r
-            the variable memory location is directly accessed If you\r
-            clear a variable list and then evaluate an expression,\r
-            it will access invalid memory.</p>\r
-        <p>You can also use fast variable access in you application\r
-            to dramatically speed up loops.  This is accomplished as\r
-            follows:\r
-            <ul>\r
-                <li>Add the desired variable to the variable list</li>\r
-                <li>Get the address of the variable with exprValListGetAddress</li>\r
-                <li>In the loop(s), directly set/get the variable any time needed: *var = 0.0;</li>\r
-            </ul>\r
-        </p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="InternalFuncConst">Using the Internal Functions and Constants</a></h2>\r
-    <blockquote>\r
-        <p>To use the internal functions, they must first be initialized\r
-            into a function list with exprFuncListInit.  To use the\r
-            internal constants, they must first be initialized into a\r
-            value list with exprValListInit.  For a list of the\r
-            internal functions and constants, see the application\r
-            help template file: <a href="exprtmpl.html">ExprTmpl.html</a>\r
-            You may use this file in your own applications so you don't\r
-            have to write a detail on the functions in ExprEval.  All\r
-            you have to do is add you own functions and constants to\r
-            the file if there are any.\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="CustomFunc">Creating Custom Functions</a></h2>\r
-    <blockquote>\r
-        <p>Custom functions can be created for use by the library.\r
-            This is how a function should look\r
-            <ul>\r
-                <pre>\r
-int custom_func(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val)\r
-    {\r
-    }\r
-                </pre>\r
-            </ul>\r
-\r
-            obj is a pointer to the expression object that called\r
-            the function, nodes is a pointer to an array of nodes\r
-            that are the parameters of this function, nodecount is\r
-            the number of items in the array (the number of parameters),\r
-            refs is an array of pointers to referenced variables,\r
-            refcount is the number of referenced variables,\r
-            and val is a pointer to a variable to recieve the result\r
-            of the function.  The function should return an error value\r
-            indicating the error status of the function.\r
-        </p>\r
-        <p>Solving a function typically goes as follows:\r
-            <ul>\r
-                <li>Verifiy the number of arguments, if needed</li>\r
-                <li>Evaluate the subnodes that you need.  You do not have to\r
-                    evaluate every subnode if you do not need it</li>\r
-                <li>Check for possible error conditions (division by zero)</li>\r
-                <li>Clear math errors (If function uses any math routines)</li>\r
-                <li>Calculate the result</li>\r
-                <li>Check for math errors (If the function uses any math routines)</li>\r
-                <li>return EXPR_ERROR_NOERROR</li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Example:</b>\r
-            <ul>\r
-                <pre>\r
-int custom_func(exprObj *obj, exprNode *nodes, int count, EXPRTYPE **refs, int refcount, EXPRTYPE *val)\r
-    {\r
-    int err;\r
-    EXPRTYPE d1, d2;\r
-\r
-    /* Need 2 arguments */\r
-    if(nodecount != 2)\r
-        return EXPR_ERROR_BADNUMBERARGUMENTS;\r
-\r
-    /* Eval arg 1 */\r
-    err = exprEvalNode(obj, nodes, 0, &d1);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        return err;\r
-\r
-    /* Eval arg 2 */\r
-    err = exprEvalNode(obj, nodes, 1, &d2);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        return err;\r
-\r
-    /* Make sure arg 2 is not 0.0 */\r
-    if(d2 == 0.0)\r
-        {\r
-        *val = 0.0;\r
-        return EXPR_ERROR_NOERROR;\r
-        }\r
-\r
-    /* Do math */\r
-    *val = atan(d1 / d2); /* No need to worry about divide by zero */\r
-\r
-\r
-    return EXPR_ERROR_NOERROR;\r
-    }\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p>In order to use a custom function, it must be added to\r
-            a function list before the expression is parsed by using\r
-            exprFuncListAdd</p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Reference">Reference</a></h2>\r
-    <blockquote>\r
-        <p><b>Headers:</b>\r
-            <ul>\r
-                <li>expreval.h - Include file</li>\r
-            </ul>\r
-        <p>\r
-        <p><b>Defines:</b>\r
-            <ul>\r
-                <li>EXPR_MAXIDENTSIZE - Maximum identifier, constant,\r
-                    or function name size</li>\r
-                <li>EXPR_ERROR_NOERROR - No error has occurred</li>\r
-                <li>EXPR_ERROR_MEMORY - A memory allocation error occured.\r
-                    For function and value lists, the name may have been\r
-                    invalid</li>\r
-                <li>EXPR_ERROR_NULLPOINTER - A null pointer was passed to\r
-                    a function that needed a valid pointer.</li>\r
-                <li>EXPR_ERROR_NOTFOUND - An item was not found in the\r
-                    function or value list</li>\r
-                <li>EXPR_ERROR_UNMATHEDCOMMENT - Comment is missing opening\r
-                    or closing mark.</li>\r
-                <li>EXPR_ERROR_INVALIDCHAR - Invalid characters were found\r
-                    in the expression</li>\r
-                <li>EXPR_ERROR_ALREADYEXISTS - An item already exists or created.</li>\r
-                <li>EXPR_ERROR_ALREADYPARSEDBAD - An expression was already\r
-                    parsed into this object, but unsuccessfully.  Free the\r
-                    expression before creating and parsing again</li>\r
-                <li>EXPR_ERROR_ALREADYPARSEDGOOD - An expression was already\r
-                    parsed into this object successfully.  Free the expression\r
-                    before creating and parsing again</li>\r
-                <li>EXPR_ERROR_EMPTYEXPR - An empty expression string was passed\r
-                    to be parsed</li>\r
-                <li>EXPR_ERROR_UNMATHEDPAREN - Unmathed opening or closing\r
-                    parenthesis were found</li>\r
-                <li>EXPR_ERROR_SYNTAX - A syntax error is in the expression</li>\r
-                <li>EXPR_ERROR_MISSINGSEMICOLON - An expression is missing a\r
-                    semicolon</li>\r
-                <li>EXPR_ERROR_BADIDENTIFIER - A bad identifier was used in\r
-                    the expression</li>\r
-                <li>EXPR_ERROR_NOSUCHFUNCTION - Function used in the expression\r
-                    does not exist in the function list</li>\r
-                <li>EXPR_ERROR_BADNUMBERARGUMENTS - A bad number of arguments\r
-                    was passed to the expression function</li>\r
-                <li>EXPR_ERROR_BADEXPR - Can not evaluate an expression because\r
-                    it does not exist or has not been parsed successfully.</li>\r
-                <li>EXPR_ERROR_UNABLETOASSIGN - Unable to do an assignment because\r
-                    a variable list has not been associated with the expression object</li>\r
-                <li>EXPR_ERROR_DIVBYZERO - An attemp to divide by zero has occured</li>\r
-                <li>EXPR_ERROR_NOVARLIST - No variable list for the expression</li>\r
-                <li>EXPR_ERROR_BREAK - The expression was broken by the break function</li>\r
-                <li>EXPR_ERROR_CONSTANTASSIGN - The expresion attempted to assign to a constant.</li>\r
-                <li>EXPR_ERROR_REFCONSTANT - The expression attempted to pass a constant as a\r
-                    reference parameter.</li>\r
-                <li>EXPR_ERROR_OUTOFRANGE - A bad value was passed to a function.</li>\r
-                <li>EXPR_ERROR_USER - Custom error values need to be larger than this.</li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Objects:</b>\r
-            <ul>\r
-                <li>exprObj - The expression object</li>\r
-                <li>exprFuncList - A function lists for the expresions</li>\r
-                <li>exprValList - A value list for constants or variables</li>\r
-                <li>exprNode - An individual node in a parsed expression tree</li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Types:</b>\r
-            <ul>\r
-                <li>EXPRTYPE - Type for the value of an expression (double)</li>\r
-                <li>exprFuncType - Custom function type. Defined as:<br>\r
-                typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);</li>\r
-                <li>exprBreakFuncType  - Breaker function pointer to stop evaluation if the result is nonzero.\r
-                    Defined as:<br>\r
-                    typedef int (*exprBreakFuncType)(exprObj *o);</li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Version information functions:</b>\r
-            <ul>\r
-                <li>void exprGetVersion(int *major, int *mino);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the version of the ExprEval library</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*major - Pointer to int to get major version number</li>\r
-                        <li>*minor - Pointer to int to get minor version number</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Nothing</li>\r
-                    </ul>\r
-                </li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Function list functions:</b>\r
-            <ul>\r
-                <li>int exprFuncListCreate(exprFuncList **flist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Creates a function lists and updates a pointer to point to it</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>**flist - Pointer to a pointer to the function list</li>\r
-                    </ul>\r
-                    Returns\r
-                    <ul>\r
-                        <li>Error code of the function.  On success, the pointer\r
-                            passed by address will point to the new function list</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprFuncListAdd(exprFuncList *flist, exprFuncType ptr, char *name, int min, int max, int refmin, int refmax);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Adds a function to the function list.  Returns error if\r
-                            the function already exists.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*flist - Pointer to an already created function list</li>\r
-                        <li>ptr - Pointer to a custom function</li>\r
-                        <li>*name - Name of the custom function</li>\r
-                        <li>min - Minimum number of arguments for the function, negative for no minimum</li>\r
-                        <li>max - Maximum number of arguments for the function, negative for no maximum</li>\r
-                        <li>refmin - Minimum number of ref arguments</li>\r
-                        <li>refmax - Maxmimum number of ref arguments</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprFuncListFree(exprFuncList *flist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Free the function list entirely</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*flist - Pointer to the function list to free</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprFuncListClear(exprFuncList *flist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Clear the functions from the function list</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*flist - Pointer to the function list to clear</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprFuncListInit(exprFuncList *flist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Initializes internal functions into the funtion list</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*flist - Function list to initialize</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Value list functions:</b>\r
-            <ul>\r
-                <li>int exprValListCreate(exprValList **vlist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Creates a value list for variables or constants</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>**vlist - Pointer to a pointer to the value list.</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function.  On success, the pointer will\r
-                            be updated to point to the value list</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Add a value in a value list.  Returns error if value\r
-                            already exists.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to add a value to</li>\r
-                        <li>*name - Name of the value to add</li>\r
-                        <li>val - Value of the value to add</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Set a value in a value list.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to set a value in</li>\r
-                        <li>*name - Name of the value to set</li>\r
-                        <li>val - Value of the value to set</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val)<br>\r
-                    Comment:\r
-                    <ul>\r
-                        <li>Get the value of a variable or constant in a value list</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to use</li>\r
-                        <li>*name - Name of the value to get</li>\r
-                        <li>*val - Pointer to variable to get the value</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr)<br>\r
-                    Comment:\r
-                    <ul>\r
-                        <li>This function is used to add a named value to the value list, but\r
-                            uses an outside variable such as a stack variable to store the\r
-                            value.  This outside variable is used to set/get the value instead\r
-                            of the internal list value.  You must ensure that this outside\r
-                            variable exists as long as the expression is using it's address.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to use</li>\r
-                        <li>*name - Name of the value to add</li>\r
-                        <li>*addr - Address of the value being added</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr)<br>\r
-                    Comment:\r
-                    <ul>\r
-                        <li>Get the memory address of a variable in a value list</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to use</li>\r
-                        <li>*name - Name of the value to get</li>\r
-                        <li>**addr - Pointer to a pointer to store the address of the value\r
-                            This will be NULL if the name is not in the list.</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);<br>\r
-                    Comment:\r
-                    <ul>\r
-                        <li>This is used to enumerate the items in the value list.\r
-                            Do NOT change the list while enumerating the items. Any\r
-                            of the information items can be NULL if it is not needed.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to use</li>\r
-                        <li>**name - Address of a pointer that will point to the\r
-                            name. Do not edit the name.</li>\r
-                        <li>*value - The current value of the item.</li>\r
-                        <li>**addr - Address of a pointer to store the address of the value.</li>\r
-                        <li>*cookie - NULL to find the first item, the return value to find\r
-                            subsequent items.</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>NULL if the item could not be found.  Otherwise a cookie\r
-                            to be used to find additional items.</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListFree(exprValList *vlist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Completely free the value list</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to free</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListClear(exprValList *vlist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Set the values in the list to 0.0</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to reset</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprValListInit(exprValList *vlist);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Initialize internal constants into a value list</li>\r
-                    </ul>\r
-                    Paramters:\r
-                    <ul>\r
-                        <li>*vlist - Value list to initialize</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li>\r
-            </ul>\r
-        </p>\r
-        <p><b>Expression functions:</b>\r
-            <ul>\r
-                <li>int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist, exprBreakFuncType breaker, void *userdata);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Create an expression object to use</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>**obj - Pointer to a pointer to an expression object</li>\r
-                        <li>*flist - Function list to associate with the expression</li>\r
-                        <li>*vlist - Variable value list to associate with the expression</li>\r
-                        <li>*clist - Constant value list to associate with the expression</li>\r
-                        <li>breaker - Breaker function callback to associate with the expression.\r
-                            Used by functions that may be infinite loops (such as the for function)</li>\r
-                        <li>userdata - User data to associate with the expression</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprFree(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Completely free the expression object</li>\r
-                    </ul>\r
-                    Paramters:\r
-                    <ul>\r
-                        <li>*obj - Expression object to free</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprClear(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Clear an expression, but keep list and callback associations.\r
-                            You can then parse another expression without calling create</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - Expression object to clear</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprParse(exprObj *obj, char *expr);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Parse an expression string into an expression object</li>\r
-                    </ul>\r
-                    Paramters:\r
-                    <ul>\r
-                        <li>*obj - Expression object to use</li>\r
-                        <li>*expr - Expression string to parse</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprEval(exprObj *obj, EXPRTYPE *val);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Evaluate a parsed expression.  This function does not\r
-                        reset the breaker count at each call, but instead accumulates\r
-                        the count until the breaker function is called.  Then the count\r
-                        is reset to the value specified in exprSetBreakerCount.</li>\r
-                    </ul>\r
-                    Paramters:\r
-                    <ul>\r
-                        <li>*obj - Expression object to evaluate</li>\r
-                        <li>*val = Pointer to variable to get result of evaluation.\r
-                            This can be NULL if the result is not needed.</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Evaluate a node of an expression.\r
-                            Used by custom functions</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - Expression object being used</li>\r
-                        <li>*nodes - Pointer to a node or list of nodes</li>\r
-                        <li>curnode - Index to the node to evaluate</li>\r
-                        <li>*val - Pointer to variable to get evaluation result</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Error code of the function</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>exprFuncList *exprGetFuncList(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the function list associated with an expression</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Pointer fo an exprFuncList object or NULL</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>exprValList *exprGetVarList(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the variable list associated with an expression</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Pointer to an exprValList object or NULL</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>exprValList *exprGetConstList(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the constant list associated with an expression</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Pointer to an exprValList object or NULL</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>exprBreakFuncType exprGetBreakFunc(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the breaker callback of the expression</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Pointer to the callback function or NULL</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>int exprGetBreakResult(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Get the result of the breaker function</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>zero to continue, nonzero to break</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>void* exprGetUserData(exprObj *obj);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the user data associated with an expression</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>User data</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>void exprSetUserData(exprObj *obj, void *userdata);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Sets the user data of an expression</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expresion object</li>\r
-                        <li>userdata - user data to set</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Nothing</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>void exprSetBreakCount(exprObj *obj, int count);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Set how often the breaker function is tested.\r
-                            The default is 100000.  This means the breaker\r
-                            function is tested once every 100000 times the\r
-                            exprEvalNode function is called for an expression.\r
-                            A smaller value tests the breaker function more often\r
-                            and a larger value tests the breaker function less. The\r
-                            breaker value is NOT reset during each call to exprEval,\r
-                            but is accumulated across calles to exprEval\r
-                            until the breaker function is finally called.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                        <li>count - how many times exprEvalNode gets called before the\r
-                            breaker function is tested</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Nothing</li>\r
-                    </ul>\r
-                </li><br>\r
-                <li>void exprGetErrorPosition(exprObj *obj, int *start, int *end);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Gets the start and ending positions in the expression string\r
-                            of the last parse error.  The positions include any newline\r
-                            characters that may be in the string.</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*obj - expression object</li>\r
-                        <li>*start - pointer to an integer to get the start error position,\r
-                            -1 if unknown</li>\r
-                        <li>*end - pointer to an integer to get the end error position,\r
-                            -1 if unknown</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>Nothing</li>\r
-                    </ul>\r
-            </ul>\r
-        </p>\r
-        <p><b>Some useful functions</b>\r
-            <ul>\r
-                <li>int exprValidIdent(char *name);<br>\r
-                    Comments:\r
-                    <ul>\r
-                        <li>Determine if an identifier is valid</li>\r
-                    </ul>\r
-                    Parameters:\r
-                    <ul>\r
-                        <li>*name - identifier to check</li>\r
-                    </ul>\r
-                    Returns:\r
-                    <ul>\r
-                        <li>0 on invalid. anything else on valid</li>\r
-                    </ul>\r
-                </li><br>\r
-            </ul>\r
-        </p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Compiling">Compiling the ExprEval library</a></h2>\r
-    <p>Compiling the ExprEval library is pretty simple.  Just\r
-        compile all of the source files (*.c) and link them into\r
-        a library.  You need to keep "expreval.h" for the header file.</p>\r
-    <p>You may have to make some changes to the library.  I've\r
-        tried to make doing so as simple as possible.  If you\r
-        need to change the include files or some macros or whatnot,\r
-        edit the file "exprincl.h"  This file includes any other files\r
-        needed.  You should not have to change to much.  I have\r
-        tried to stick as close to ANSI/ISO C as I can.</p>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Drawbacks">Drawbacks/Problems</a></h2>\r
-    <p>The following is a list of some basic drawbacks of this\r
-        library:\r
-        <ul>\r
-            <li>This library is an expression evaluator, and nothing\r
-                else.  It does not simplify expressions and it\r
-                does not do advanced math such as calculating the\r
-                integrals and differentials of expression.</li>\r
-            <li>This library has no way of detecting overflows\r
-                except for those caused by the internal math\r
-                routines.  Adding two very very large numbers\r
-                may cause an overflow to occur.</li>\r
-            <li>This library is not super easy to use in an application.\r
-                It has been designed to give much control to the\r
-                developer. Because of this, the function/value lists\r
-                are seperate from the expression objects, allowing\r
-                the developer to use them however they need.</li>\r
-            <li>There is no way to delete a single function, variable,\r
-                or constant from a list.  This is because I see no\r
-                real need to do so because of the way the library\r
-                works.  There is no need to delete function from\r
-                a function list or constants from a constant list.\r
-                There are are also no decent reasons to delete\r
-                variables from a variable list until you are completely\r
-                done and delete all of them.</li>\r
-        </ul>\r
-    </p>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Solutions">Problems and Solutions</a></h2>\r
-    \r
-    <ul>\r
-        <li><b>Variables do not seem to change in a release/optimized build.</b><br>\r
-            I have noticed a small problem with this.  Rarely, a variable may not\r
-            appear to change in a release build.  The reason is to do with compiler\r
-            optimizations.  For example, look at the following code:\r
-            <blockquote>\r
-                <pre>\r
-EXPRTYPE k;\r
-\r
-/* Add variable to the list */\r
-exprValListAddAddress(list, "k", &k);\r
-\r
-k = 0.0;\r
-\r
-/* Evaluate expression */\r
-for(int x = 0; x &lt; 100; x++)\r
-    {\r
-    exprEval(expr, &result);\r
-    \r
-    doSomething(k);\r
-    }\r
-                </pre>\r
-            </blockquote>\r
-            Inside the loop, the variable 'k' does not appear to be changing, so\r
-            the compiler may optimize it by loading it into a register before the\r
-            loop and not accessing it from memory during the loop, even if\r
-            the expression does change it.  One way to avoid this is to use the\r
-            'volatile' keyword with the variable.  Then the compiler must\r
-            accesss it from memory each time it is accessed.\r
-            <blockquote>\r
-                <pre>\r
-volatile EXPRTYPE k;\r
-\r
-/* Add variable to the list */\r
-exprValListAddAddress(list, "k", (EXPRTYPE*)&k);\r
-\r
-k = 0.0;\r
-\r
-/* Evaluate expression */\r
-for(int x = 0; x &lt; 100; x++)\r
-    {\r
-    exprEval(expr, &result);\r
-    \r
-    doSomething(k);\r
-    }\r
-                </pre>\r
-            </blockquote>\r
-        </li>\r
-        \r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Example">Example Use with Fast Variable Access</a></h2>\r
-\r
-    <p>This is an example application of this library.  It is a\r
-        graphics program that calculates the color value of a\r
-        pixel based on it's X,Y co-ordinate.  It uses a made-up\r
-        image library called graphic-lib.  It uses faster variable\r
-        access by using the exprValListGetAddress function.</p>\r
-    <p>Note that this codes has not actually been tested.  See the\r
-        test applications (test and imagegen) for other examples.</p>\r
-\r
-    <blockquote>\r
-        <pre>\r
-/* Include files */\r
-#include &lt;stdio.h&gt;\r
-#include &lt;stdlib.h&gt;\r
-#include &lt;setjmp.h&gt;\r
-#include "graphiclib.h"\r
-#include "expreval.h"\r
-\r
-char *transerr(int err)\r
-    {\r
-    /* Translate error code into message */\r
-    }\r
-\r
-void gen_image(char *name, int w, int h, char *expr);\r
-    {\r
-    exprFuncList *f = NULL;\r
-    exprValList *v = NULL;\r
-    exprValList *c = NULL;\r
-    exprObj *o = NULL;\r
-    int x, y, err;\r
-    jmp_buf jumper;\r
-    int image;\r
-    EXPRTYPE *v_x, *v_y;\r
-    EXPRTYPE *v_r, *v_g, *v_b;\r
-    EXPRTYPE global_value;\r
-\r
-    /* Error handling */\r
-    err = setjmp(jumper);\r
-    if(err)\r
-        {\r
-        if(err != ID_IMAGENOERROR)\r
-            printf("Error %d occurred: %s\n", err, transerr(err));\r
-\r
-        exprFree(o);\r
-        exprFreeFuncList(f);\r
-        exprFreeValList(v);\r
-        exprFreeValList(c);\r
-\r
-        image_free(image);\r
-        return;\r
-        }\r
-\r
-    /* Set up lists */\r
-\r
-    /* Function list */\r
-    err = exprFuncListCreate(&f);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        longjmp(jumper, err);\r
-\r
-    err = exprFuncListInit(f);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        {\r
-        printf("Function list init error. Functions may not be available.\n");\r
-        }\r
-\r
-    /* Variable list */\r
-    err = exprValListCreate(&v);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        longjmp(jumper, err);\r
-\r
-    /* Constant list */\r
-    err = exprValListCreate(&c);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        {\r
-        printf("Constants not available\n");\r
-        }\r
-    else\r
-        {\r
-        err = exprValListInit(c);\r
-        if(err != EXPR_ERROR_NOERROR)\r
-            printf("Constant list init error. Constants may not be available.\n");\r
-        }\r
-\r
-    /* Create and parse the expression */\r
-\r
-    /* Create */\r
-    err = exprCreate(&o, f, v, c, NULL, 0);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        longjmp(jumper, err);\r
-\r
-    /* Parse expression */\r
-    err = exprParse(o, expr);\r
-    if(err != EXPR_ERROR_NOERROR)\r
-        longjmp(jumper, err);\r
-\r
-\r
-    /* Create the image */\r
-    image = image_create(w, h);\r
-    if(image == 0)\r
-        {\r
-        longjmp(jumper, ID_IMAGECREATEERROR);\r
-        }\r
-\r
-    /* Add width and height to variable list */\r
-    exprValListAdd(v, "w", (EXPRTYPE)w);\r
-    exprValListAdd(v, "h", (EXPRTYPE)h);\r
-\r
-    /* Add x and y to the list */\r
-    exprValListAdd(v, "x", 0.0);\r
-    exprValListAdd(v, "y", 0.0);\r
-\r
-    /* Add r, g, and b to the list */\r
-    exprValListAdd(v, "r", 0.0);\r
-    exprValListAdd(v, "g", 0.0);\r
-    exprValListAdd(b, "b", 0.0);\r
-\r
-    /* Get addresses.  Assume no error */\r
-    exprValListGetAddress(v, "x", &v_x);\r
-    exprValListGetAddress(v, "y", &v_y);\r
-\r
-    exprValListGetAddress(v, "r", &v_r);\r
-    exprValListGetAddress(v, "g", &v_g);\r
-    exprValListGetAddress(v, "g", &v_b);\r
-    \r
-    /* A way to add global variables that can be used by two different lists. */\r
-    exprValListAddAddress(v, "global", &global_value);\r
-    /* exprValListAddAddress(v2, "global", &global_value); */\r
-    \r
-    /* Also, exprValListAddAddress can be used to add variables directly.\r
-       Instead of:\r
-       \r
-       EXPRTYPE *a;\r
-       \r
-       exprValListAdd(v, "a", 0.0);\r
-       exprValListGetAddresss(v, "a", &a);\r
-       \r
-       You can do:\r
-       \r
-       EXPRTYPE a;\r
-       \r
-       exprValListAddAddresss(v, "a", &a);\r
-       \r
-       If you do this, you must ensure that the stack variable exists as long\r
-       as it is used by expression, otherwise it may cause a memory access\r
-       violation. */\r
-    \r
-\r
-    for(y = 0; y < h; y++)\r
-        {\r
-        for(x = 0; x < w; x++)\r
-            {\r
-            /* Directly set the x and y variables */\r
-            *v_x = (EXPRTYPE)x;\r
-            *v_y = (EXPRTYPE)y;\r
-\r
-            /* Eval expression, ignoring errors */\r
-            exprEval(o);\r
-\r
-            /* Set pixel, using variables directly */\r
-            image_setpixel(image, x, y, (int)(*v_r), (int)(*v_g), (int)(*v_b));\r
-            }\r
-        }\r
-\r
-    /* Save image */\r
-    image_save(image, name);\r
-\r
-    /* Done */\r
-    longjmp(jumper, ID_IMAGENOERROR);\r
-    }\r
-\r
-void main(void)\r
-    {\r
-    char name[MAXPATH]\r
-    char tmp[10];\r
-    char expr[4096];\r
-    int sx, sy;\r
-\r
-    printf("Image name to save: ");\r
-    gets(name);\r
-\r
-    printf("Image width: ");\r
-    gets(tmp);\r
-    sx = atoi(tmp);\r
-\r
-    printf("Image height: ");\r
-    gets(tmp);\r
-    sy = atoi(tmp);\r
-\r
-    printf("Color Expression (Use x, y, w, h Set r, g, b): ");\r
-    gets(expr);\r
-\r
-    gen_image(name, sx, sy, expr);\r
-    }\r
-\r
-        </pre>\r
-    </blockquote>\r
-</div>\r
-\r
-</body>\r
-</html>\r
+<html>
+<head>
+<title>ExprEval Library</title>
+<style type="text/css">
+.valid {
+  color: #00AA00;
+}
+.invalid {
+  color: #FF0000;
+}
+.excomment {
+  color: #0000FF;
+}
+.container {
+  margin-top: 10px;
+  margin-bottom: 10px;
+  padding-left: 4px;
+  padding-right: 4px;
+  border-top: 1px solid #000000;
+  border-right: 1px solid #000000;
+  border-bottom: 1px solid #000000;
+  border-left: 1px solid #000000;
+  background-color: #BBBBBB;
+}
+body {
+  background-color: #AAAAAA;
+}
+</style>
+</head>
+<body>
+
+<div align="center">
+    <h1>ExprEval Library</h1>
+    <hr>
+</div>
+
+<div align="left" class="container">
+    <h2>Contents</h2>
+    <h3>
+        <ul>
+            <a href="#Introduction">Introduction</a><br>
+            <a href="#License">License</a><br>
+            <a href="#Syntax">Expression Syntax</a><br>
+            <a href="#Using">Using ExprEval in an Application</a><br>
+            <a href="#FastVar">Fast Variable Access</a><br>
+            <a href="#InternalFuncConst">Using the Internal Functions and Constants</a><br>
+            <a href="#CustomFunc">Creating Custom Functions</a><br>
+            <a href="#Reference">Reference</a><br>
+            <a href="#Compiling">Compiling the ExprEval Library</a><br>
+            <a href="#Drawbacks">Drawbacks/Problems</a><br>
+            <a href="#Solutions">Problems and Solutions</a><br>
+            <a href="#Example">Example Use</a><br>
+        </ul>
+    </h3>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Introduction">Introduction</a></h2>
+    <blockquote>
+        <p>ExprEval Help document.  This document is probably full of
+            bugs and mispellings.  I may get around to proofreading
+            it later.</p>
+        <p>ExprEval is a C based expression evaluation library.
+            It is entirely C based, but can be used in C++ programs
+            as well..  The source code is provided for the library
+            so that it can be recompiled for the specific system
+            or compiler.</p>
+        <p>ExprEval makes adding mathematical expression support to
+            an application easy.  It takes an expression string and
+            parses it, and then it can evaluate it over and over.
+            This library also has support for functions, constants,
+            and variables.  All of these items are stored in
+            seperate lists so they can be shared among expressions or
+            they can be private to a single expression or any mix and
+            match.  It is up to the developer how to link them together.
+            You can also create your own custom functions.</p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="License">License</a></h2>
+    <blockquote>
+        <p>This library is licensed under the
+        <a href="license.txt">ExprEval License.</a>
+        </p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Syntax">Expression Syntax</a></h2>
+    <blockquote>
+        <p>Expressions have pretty much the same syntax as they
+            would have on paper, with the following exceptions:
+            <ul>
+                <li>Each expression must end with a semicolon. This
+                    is because the expression string can actually
+                    contain multiple expressions.  The semicolon is
+                    used to mark the end of the expression.<br>
+                    <b>Examples:</b>
+                    <ul>
+                        <li>4*x+5;</li>
+                        <li>y=5+2;g=4+6;</li>
+                        <li>y=r*sin(a);x=r*cos(a);</li>
+                    </ul>
+                </li>
+                <li>The asterisk '*' must be used to multiply.<br>
+                    <b>Examples:</b>
+                    <ul>
+                        <li>y=5*6; <b class="valid">Valid</b></li>
+                        <li>g=(x+1)*(x-1); <b class="valid">Valid</b></li>
+                        <li>g=(x+1)(x-1); <b class="invalid">Invalid</b></li>
+                    </ul>
+                </li>
+            </ul>
+        </p>
+        <p>More than one expression may be contained within an expression string.
+            As shown above, each expression must end with a semicolon, even if
+            only one expression is in the string. The value of an expression
+            string is the value of the last expression in the string.<br>
+            <b>Examlples:</b>
+            <ul>
+                <li>g=7; <b class="excomment">Value: 7</b></li>
+                <li>k=z+1; <b class="excomment">Value: z+1</b></li>
+                <li>r=4;k=6;o=9+r-k; <b class="excomment">Value: 9+r-k</b></li>
+            </ul>
+        </p>
+        <p>Some functions may take reference parameters.  These parameters are
+            references to other variables.  You can mix reference parameters
+            with normal parameters.  The order of the normal parameters must
+            remain the same and the order of the reference parameters must
+            remain the same.<br>
+            <b>Examples:</b>
+            <ul>
+                <li>min(1,2,3,4,&mval); <b class="excomment">&mval is a reference to a variable mval</b></li>
+                <li>min(1,2,&mval,3,4); <b class="excomment">You may mix them inside like this.</b></li>
+                <li>min(1,2,(&mval),3,4); <b class="invalid">You may not nest reference parameters in any way</b></li>
+            </ul>
+        </p>
+        <p>Expressions may also be nested with parenthesis.<br>
+        <b>Examples:</b>
+            <ul>
+                <li>y=sin(x-cos(5+max(4,5,6*x)));</li>
+                <li>6+(5-2*(x+y));</li>
+            </ul>
+        </p>
+        <p>Expressions may also have whitespace characters and comments.
+            Whitespace characters such as newlines, linefeeds, carriage
+            returns, spaces, and tabs are ignored.  Comments begin with
+            the pound sign '#' and end at the end of the line.<br>
+            <b>Example:</b>
+            <ul>
+                <pre>
+#Set the x value
+x = d * cos(r);
+
+#Set the y value
+y = d * sin(r);
+                </pre>
+            </ul>
+        </p>
+        <p>If a variable is used in an expression, but that variable does not exist,
+            it is considered zero.  If it does exist then its value is used instead.
+        </p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Using">Using ExprEval in an Application</a></h2>
+    <blockquote>
+        <p>Using ExprEval in an application can be a little difficult.
+            You generally follow these steps:
+            <ul>
+                <li>Create function, variable, and constant lists</li>
+                <li>Create the expression object</li>
+                <li>Parse the expression</li>
+                <li>Evaluate the expression as needed</li>
+                <li>Free the expression object</li>
+                <li>Free the function, variable, and constant lists</li>
+            </ul>
+            You can manipulate the lists in any order after their creation.
+            However, functions are translated during the parse, so after
+            parsing an expression, manipulating the function list will make
+            no change to an expression.  Variables and constants can be
+            manipulated after a parse to change the result of an expression.
+            However, you must add any constants to be used by an expression
+            to the constant list <b>BEFORE</b> parsing the expression,
+            otherwise it will be seen as a variable.  Applications can change
+            both variables and constants, however the expression can only
+            change variables.  Expressions may <b>NOT</b> assign to a constant
+            and expressions may <b>NOT</b> use constants as a reference parameter.</p>
+        <p><b>Function, variable, and constant list example:</b>
+            <ul>
+                <pre>
+exprFuncList *flist;
+exprValList *vlist;
+exprValList *clist;
+exprObj *obj;
+EXPRTYPE result;
+int err;
+
+/* Create function list */
+err = exprFuncListCreate(&amp;flist);
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Initialize internal functions */
+err = exprFuncListInit(flist);
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Create variable list */
+err = exprValListCreate(&amp;vlist);
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Create the constant list */
+err = exprValListCreate(&amp;clist);
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Initialize internal constants */
+err = exprValListInit(clist);
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Add any application defined functions, constants, or variables to the lists here or down below */
+                </pre>
+            </ul>
+        </p>
+        <p><b>Expression object example:</b>
+            <ul>
+                <pre>
+err = exprCreate(&obj, flist, vlist, clist, NULL, 0);
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Add any application defined functions, constants, or variables to the lists here or down below.
+   This is the last time you can for the functions or constants. */
+                </pre>
+            </ul>
+        </p>
+        <p><b>Expression parse example:</b>
+            <ul>
+                <pre>
+/* Functions and constants may be added or changed here */
+
+err = exprParse(obj, "2+sin(M_PI)+3*x;");
+if(err != EXPR_ERROR_NOERROR)
+    {
+    ...
+    }
+
+/* Changes to the function or constant lists do not change the expression now */
+                </pre>
+            </ul>
+        </p>
+        <p><b>Expression evaluation example:</b>
+            <ul>
+                <pre>
+/* Add or change any variables */
+
+err = exprEval(obj, &result);
+if(err != EXPR_ERROR_NOERRO)
+    {
+    ...
+    }
+else
+    {
+    printf("Expression Result: %f\n", result);
+    }
+                </pre>
+            </ul>
+        </p>
+        <p><b>Free the expression object and lists example:</b>
+            <ul>
+                <pre>
+exprFree(obj);
+exprValListFree(vlist);
+exprValListFree(clist);
+exprFuncListFree(flist);
+                </pre>
+            </ul>
+        </p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="FastVar">Fast Variable Access</a></h2>
+    <blockquote>
+        <p>A new feature in ExprEval is fast variable access.  This
+            is simply a technique of quickly accessing variables
+            by directly accessing their memory locations instead
+            of using the value list functions.  Fast variable access
+            is always used internally in ExprEval.  You must
+            NOT clear a variable list until after all expressions
+            using it are completely finished evaluating.  Then you
+            must reparse the expressions before using them again.
+            The reason is simple. When fast variable access is used,
+            the variable memory location is directly accessed If you
+            clear a variable list and then evaluate an expression,
+            it will access invalid memory.</p>
+        <p>You can also use fast variable access in you application
+            to dramatically speed up loops.  This is accomplished as
+            follows:
+            <ul>
+                <li>Add the desired variable to the variable list</li>
+                <li>Get the address of the variable with exprValListGetAddress</li>
+                <li>In the loop(s), directly set/get the variable any time needed: *var = 0.0;</li>
+            </ul>
+        </p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="InternalFuncConst">Using the Internal Functions and Constants</a></h2>
+    <blockquote>
+        <p>To use the internal functions, they must first be initialized
+            into a function list with exprFuncListInit.  To use the
+            internal constants, they must first be initialized into a
+            value list with exprValListInit.  For a list of the
+            internal functions and constants, see the application
+            help template file: <a href="exprtmpl.html">ExprTmpl.html</a>
+            You may use this file in your own applications so you don't
+            have to write a detail on the functions in ExprEval.  All
+            you have to do is add you own functions and constants to
+            the file if there are any.
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="CustomFunc">Creating Custom Functions</a></h2>
+    <blockquote>
+        <p>Custom functions can be created for use by the library.
+            This is how a function should look
+            <ul>
+                <pre>
+int custom_func(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val)
+    {
+    }
+                </pre>
+            </ul>
+
+            obj is a pointer to the expression object that called
+            the function, nodes is a pointer to an array of nodes
+            that are the parameters of this function, nodecount is
+            the number of items in the array (the number of parameters),
+            refs is an array of pointers to referenced variables,
+            refcount is the number of referenced variables,
+            and val is a pointer to a variable to recieve the result
+            of the function.  The function should return an error value
+            indicating the error status of the function.
+        </p>
+        <p>Solving a function typically goes as follows:
+            <ul>
+                <li>Verifiy the number of arguments, if needed</li>
+                <li>Evaluate the subnodes that you need.  You do not have to
+                    evaluate every subnode if you do not need it</li>
+                <li>Check for possible error conditions (division by zero)</li>
+                <li>Clear math errors (If function uses any math routines)</li>
+                <li>Calculate the result</li>
+                <li>Check for math errors (If the function uses any math routines)</li>
+                <li>return EXPR_ERROR_NOERROR</li>
+            </ul>
+        </p>
+        <p><b>Example:</b>
+            <ul>
+                <pre>
+int custom_func(exprObj *obj, exprNode *nodes, int count, EXPRTYPE **refs, int refcount, EXPRTYPE *val)
+    {
+    int err;
+    EXPRTYPE d1, d2;
+
+    /* Need 2 arguments */
+    if(nodecount != 2)
+        return EXPR_ERROR_BADNUMBERARGUMENTS;
+
+    /* Eval arg 1 */
+    err = exprEvalNode(obj, nodes, 0, &d1);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* Eval arg 2 */
+    err = exprEvalNode(obj, nodes, 1, &d2);
+    if(err != EXPR_ERROR_NOERROR)
+        return err;
+
+    /* Make sure arg 2 is not 0.0 */
+    if(d2 == 0.0)
+        {
+        *val = 0.0;
+        return EXPR_ERROR_NOERROR;
+        }
+
+    /* Do math */
+    *val = atan(d1 / d2); /* No need to worry about divide by zero */
+
+
+    return EXPR_ERROR_NOERROR;
+    }
+                </pre>
+            </ul>
+        </p>
+        <p>In order to use a custom function, it must be added to
+            a function list before the expression is parsed by using
+            exprFuncListAdd</p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Reference">Reference</a></h2>
+    <blockquote>
+        <p><b>Headers:</b>
+            <ul>
+                <li>expreval.h - Include file</li>
+            </ul>
+        <p>
+        <p><b>Defines:</b>
+            <ul>
+                <li>EXPR_MAXIDENTSIZE - Maximum identifier, constant,
+                    or function name size</li>
+                <li>EXPR_ERROR_NOERROR - No error has occurred</li>
+                <li>EXPR_ERROR_MEMORY - A memory allocation error occured.
+                    For function and value lists, the name may have been
+                    invalid</li>
+                <li>EXPR_ERROR_NULLPOINTER - A null pointer was passed to
+                    a function that needed a valid pointer.</li>
+                <li>EXPR_ERROR_NOTFOUND - An item was not found in the
+                    function or value list</li>
+                <li>EXPR_ERROR_UNMATHEDCOMMENT - Comment is missing opening
+                    or closing mark.</li>
+                <li>EXPR_ERROR_INVALIDCHAR - Invalid characters were found
+                    in the expression</li>
+                <li>EXPR_ERROR_ALREADYEXISTS - An item already exists or created.</li>
+                <li>EXPR_ERROR_ALREADYPARSEDBAD - An expression was already
+                    parsed into this object, but unsuccessfully.  Free the
+                    expression before creating and parsing again</li>
+                <li>EXPR_ERROR_ALREADYPARSEDGOOD - An expression was already
+                    parsed into this object successfully.  Free the expression
+                    before creating and parsing again</li>
+                <li>EXPR_ERROR_EMPTYEXPR - An empty expression string was passed
+                    to be parsed</li>
+                <li>EXPR_ERROR_UNMATHEDPAREN - Unmathed opening or closing
+                    parenthesis were found</li>
+                <li>EXPR_ERROR_SYNTAX - A syntax error is in the expression</li>
+                <li>EXPR_ERROR_MISSINGSEMICOLON - An expression is missing a
+                    semicolon</li>
+                <li>EXPR_ERROR_BADIDENTIFIER - A bad identifier was used in
+                    the expression</li>
+                <li>EXPR_ERROR_NOSUCHFUNCTION - Function used in the expression
+                    does not exist in the function list</li>
+                <li>EXPR_ERROR_BADNUMBERARGUMENTS - A bad number of arguments
+                    was passed to the expression function</li>
+                <li>EXPR_ERROR_BADEXPR - Can not evaluate an expression because
+                    it does not exist or has not been parsed successfully.</li>
+                <li>EXPR_ERROR_UNABLETOASSIGN - Unable to do an assignment because
+                    a variable list has not been associated with the expression object</li>
+                <li>EXPR_ERROR_DIVBYZERO - An attemp to divide by zero has occured</li>
+                <li>EXPR_ERROR_NOVARLIST - No variable list for the expression</li>
+                <li>EXPR_ERROR_BREAK - The expression was broken by the break function</li>
+                <li>EXPR_ERROR_CONSTANTASSIGN - The expresion attempted to assign to a constant.</li>
+                <li>EXPR_ERROR_REFCONSTANT - The expression attempted to pass a constant as a
+                    reference parameter.</li>
+                <li>EXPR_ERROR_OUTOFRANGE - A bad value was passed to a function.</li>
+                <li>EXPR_ERROR_USER - Custom error values need to be larger than this.</li>
+            </ul>
+        </p>
+        <p><b>Objects:</b>
+            <ul>
+                <li>exprObj - The expression object</li>
+                <li>exprFuncList - A function lists for the expresions</li>
+                <li>exprValList - A value list for constants or variables</li>
+                <li>exprNode - An individual node in a parsed expression tree</li>
+            </ul>
+        </p>
+        <p><b>Types:</b>
+            <ul>
+                <li>EXPRTYPE - Type for the value of an expression (double)</li>
+                <li>exprFuncType - Custom function type. Defined as:<br>
+                typedef int (*exprFuncType)(exprObj *obj, exprNode *nodes, int nodecount, EXPRTYPE **refs, int refcount, EXPRTYPE *val);</li>
+                <li>exprBreakFuncType  - Breaker function pointer to stop evaluation if the result is nonzero.
+                    Defined as:<br>
+                    typedef int (*exprBreakFuncType)(exprObj *o);</li>
+            </ul>
+        </p>
+        <p><b>Version information functions:</b>
+            <ul>
+                <li>void exprGetVersion(int *major, int *mino);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the version of the ExprEval library</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*major - Pointer to int to get major version number</li>
+                        <li>*minor - Pointer to int to get minor version number</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Nothing</li>
+                    </ul>
+                </li>
+            </ul>
+        </p>
+        <p><b>Function list functions:</b>
+            <ul>
+                <li>int exprFuncListCreate(exprFuncList **flist);<br>
+                    Comments:
+                    <ul>
+                        <li>Creates a function lists and updates a pointer to point to it</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>**flist - Pointer to a pointer to the function list</li>
+                    </ul>
+                    Returns
+                    <ul>
+                        <li>Error code of the function.  On success, the pointer
+                            passed by address will point to the new function list</li>
+                    </ul>
+                </li><br>
+                <li>int exprFuncListAdd(exprFuncList *flist, exprFuncType ptr, char *name, int min, int max, int refmin, int refmax);<br>
+                    Comments:
+                    <ul>
+                        <li>Adds a function to the function list.  Returns error if
+                            the function already exists.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*flist - Pointer to an already created function list</li>
+                        <li>ptr - Pointer to a custom function</li>
+                        <li>*name - Name of the custom function</li>
+                        <li>min - Minimum number of arguments for the function, negative for no minimum</li>
+                        <li>max - Maximum number of arguments for the function, negative for no maximum</li>
+                        <li>refmin - Minimum number of ref arguments</li>
+                        <li>refmax - Maxmimum number of ref arguments</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprFuncListFree(exprFuncList *flist);<br>
+                    Comments:
+                    <ul>
+                        <li>Free the function list entirely</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*flist - Pointer to the function list to free</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprFuncListClear(exprFuncList *flist);<br>
+                    Comments:
+                    <ul>
+                        <li>Clear the functions from the function list</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*flist - Pointer to the function list to clear</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprFuncListInit(exprFuncList *flist);<br>
+                    Comments:
+                    <ul>
+                        <li>Initializes internal functions into the funtion list</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*flist - Function list to initialize</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li>
+            </ul>
+        </p>
+        <p><b>Value list functions:</b>
+            <ul>
+                <li>int exprValListCreate(exprValList **vlist);<br>
+                    Comments:
+                    <ul>
+                        <li>Creates a value list for variables or constants</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>**vlist - Pointer to a pointer to the value list.</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function.  On success, the pointer will
+                            be updated to point to the value list</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val);<br>
+                    Comments:
+                    <ul>
+                        <li>Add a value in a value list.  Returns error if value
+                            already exists.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to add a value to</li>
+                        <li>*name - Name of the value to add</li>
+                        <li>val - Value of the value to add</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val);<br>
+                    Comments:
+                    <ul>
+                        <li>Set a value in a value list.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to set a value in</li>
+                        <li>*name - Name of the value to set</li>
+                        <li>val - Value of the value to set</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val)<br>
+                    Comment:
+                    <ul>
+                        <li>Get the value of a variable or constant in a value list</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to use</li>
+                        <li>*name - Name of the value to get</li>
+                        <li>*val - Pointer to variable to get the value</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr)<br>
+                    Comment:
+                    <ul>
+                        <li>This function is used to add a named value to the value list, but
+                            uses an outside variable such as a stack variable to store the
+                            value.  This outside variable is used to set/get the value instead
+                            of the internal list value.  You must ensure that this outside
+                            variable exists as long as the expression is using it's address.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to use</li>
+                        <li>*name - Name of the value to add</li>
+                        <li>*addr - Address of the value being added</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr)<br>
+                    Comment:
+                    <ul>
+                        <li>Get the memory address of a variable in a value list</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to use</li>
+                        <li>*name - Name of the value to get</li>
+                        <li>**addr - Pointer to a pointer to store the address of the value
+                            This will be NULL if the name is not in the list.</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie);<br>
+                    Comment:
+                    <ul>
+                        <li>This is used to enumerate the items in the value list.
+                            Do NOT change the list while enumerating the items. Any
+                            of the information items can be NULL if it is not needed.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to use</li>
+                        <li>**name - Address of a pointer that will point to the
+                            name. Do not edit the name.</li>
+                        <li>*value - The current value of the item.</li>
+                        <li>**addr - Address of a pointer to store the address of the value.</li>
+                        <li>*cookie - NULL to find the first item, the return value to find
+                            subsequent items.</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>NULL if the item could not be found.  Otherwise a cookie
+                            to be used to find additional items.</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListFree(exprValList *vlist);<br>
+                    Comments:
+                    <ul>
+                        <li>Completely free the value list</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to free</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListClear(exprValList *vlist);<br>
+                    Comments:
+                    <ul>
+                        <li>Set the values in the list to 0.0</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*vlist - Value list to reset</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprValListInit(exprValList *vlist);<br>
+                    Comments:
+                    <ul>
+                        <li>Initialize internal constants into a value list</li>
+                    </ul>
+                    Paramters:
+                    <ul>
+                        <li>*vlist - Value list to initialize</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li>
+            </ul>
+        </p>
+        <p><b>Expression functions:</b>
+            <ul>
+                <li>int exprCreate(exprObj **obj, exprFuncList *flist, exprValList *vlist, exprValList *clist, exprBreakFuncType breaker, void *userdata);<br>
+                    Comments:
+                    <ul>
+                        <li>Create an expression object to use</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>**obj - Pointer to a pointer to an expression object</li>
+                        <li>*flist - Function list to associate with the expression</li>
+                        <li>*vlist - Variable value list to associate with the expression</li>
+                        <li>*clist - Constant value list to associate with the expression</li>
+                        <li>breaker - Breaker function callback to associate with the expression.
+                            Used by functions that may be infinite loops (such as the for function)</li>
+                        <li>userdata - User data to associate with the expression</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprFree(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Completely free the expression object</li>
+                    </ul>
+                    Paramters:
+                    <ul>
+                        <li>*obj - Expression object to free</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprClear(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Clear an expression, but keep list and callback associations.
+                            You can then parse another expression without calling create</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - Expression object to clear</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprParse(exprObj *obj, char *expr);<br>
+                    Comments:
+                    <ul>
+                        <li>Parse an expression string into an expression object</li>
+                    </ul>
+                    Paramters:
+                    <ul>
+                        <li>*obj - Expression object to use</li>
+                        <li>*expr - Expression string to parse</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprEval(exprObj *obj, EXPRTYPE *val);<br>
+                    Comments:
+                    <ul>
+                        <li>Evaluate a parsed expression.  This function does not
+                        reset the breaker count at each call, but instead accumulates
+                        the count until the breaker function is called.  Then the count
+                        is reset to the value specified in exprSetBreakerCount.</li>
+                    </ul>
+                    Paramters:
+                    <ul>
+                        <li>*obj - Expression object to evaluate</li>
+                        <li>*val = Pointer to variable to get result of evaluation.
+                            This can be NULL if the result is not needed.</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>int exprEvalNode(exprObj *obj, exprNode *nodes, int curnode, EXPRTYPE *val);<br>
+                    Comments:
+                    <ul>
+                        <li>Evaluate a node of an expression.
+                            Used by custom functions</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - Expression object being used</li>
+                        <li>*nodes - Pointer to a node or list of nodes</li>
+                        <li>curnode - Index to the node to evaluate</li>
+                        <li>*val - Pointer to variable to get evaluation result</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Error code of the function</li>
+                    </ul>
+                </li><br>
+                <li>exprFuncList *exprGetFuncList(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the function list associated with an expression</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Pointer fo an exprFuncList object or NULL</li>
+                    </ul>
+                </li><br>
+                <li>exprValList *exprGetVarList(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the variable list associated with an expression</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Pointer to an exprValList object or NULL</li>
+                    </ul>
+                </li><br>
+                <li>exprValList *exprGetConstList(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the constant list associated with an expression</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Pointer to an exprValList object or NULL</li>
+                    </ul>
+                </li><br>
+                <li>exprBreakFuncType exprGetBreakFunc(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the breaker callback of the expression</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Pointer to the callback function or NULL</li>
+                    </ul>
+                </li><br>
+                <li>int exprGetBreakResult(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Get the result of the breaker function</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>zero to continue, nonzero to break</li>
+                    </ul>
+                </li><br>
+                <li>void* exprGetUserData(exprObj *obj);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the user data associated with an expression</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>User data</li>
+                    </ul>
+                </li><br>
+                <li>void exprSetUserData(exprObj *obj, void *userdata);<br>
+                    Comments:
+                    <ul>
+                        <li>Sets the user data of an expression</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expresion object</li>
+                        <li>userdata - user data to set</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Nothing</li>
+                    </ul>
+                </li><br>
+                <li>void exprSetBreakCount(exprObj *obj, int count);<br>
+                    Comments:
+                    <ul>
+                        <li>Set how often the breaker function is tested.
+                            The default is 100000.  This means the breaker
+                            function is tested once every 100000 times the
+                            exprEvalNode function is called for an expression.
+                            A smaller value tests the breaker function more often
+                            and a larger value tests the breaker function less. The
+                            breaker value is NOT reset during each call to exprEval,
+                            but is accumulated across calles to exprEval
+                            until the breaker function is finally called.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                        <li>count - how many times exprEvalNode gets called before the
+                            breaker function is tested</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Nothing</li>
+                    </ul>
+                </li><br>
+                <li>void exprGetErrorPosition(exprObj *obj, int *start, int *end);<br>
+                    Comments:
+                    <ul>
+                        <li>Gets the start and ending positions in the expression string
+                            of the last parse error.  The positions include any newline
+                            characters that may be in the string.</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*obj - expression object</li>
+                        <li>*start - pointer to an integer to get the start error position,
+                            -1 if unknown</li>
+                        <li>*end - pointer to an integer to get the end error position,
+                            -1 if unknown</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>Nothing</li>
+                    </ul>
+            </ul>
+        </p>
+        <p><b>Some useful functions</b>
+            <ul>
+                <li>int exprValidIdent(char *name);<br>
+                    Comments:
+                    <ul>
+                        <li>Determine if an identifier is valid</li>
+                    </ul>
+                    Parameters:
+                    <ul>
+                        <li>*name - identifier to check</li>
+                    </ul>
+                    Returns:
+                    <ul>
+                        <li>0 on invalid. anything else on valid</li>
+                    </ul>
+                </li><br>
+            </ul>
+        </p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Compiling">Compiling the ExprEval library</a></h2>
+    <p>Compiling the ExprEval library is pretty simple.  Just
+        compile all of the source files (*.c) and link them into
+        a library.  You need to keep "expreval.h" for the header file.</p>
+    <p>You may have to make some changes to the library.  I've
+        tried to make doing so as simple as possible.  If you
+        need to change the include files or some macros or whatnot,
+        edit the file "exprincl.h"  This file includes any other files
+        needed.  You should not have to change to much.  I have
+        tried to stick as close to ANSI/ISO C as I can.</p>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Drawbacks">Drawbacks/Problems</a></h2>
+    <p>The following is a list of some basic drawbacks of this
+        library:
+        <ul>
+            <li>This library is an expression evaluator, and nothing
+                else.  It does not simplify expressions and it
+                does not do advanced math such as calculating the
+                integrals and differentials of expression.</li>
+            <li>This library has no way of detecting overflows
+                except for those caused by the internal math
+                routines.  Adding two very very large numbers
+                may cause an overflow to occur.</li>
+            <li>This library is not super easy to use in an application.
+                It has been designed to give much control to the
+                developer. Because of this, the function/value lists
+                are seperate from the expression objects, allowing
+                the developer to use them however they need.</li>
+            <li>There is no way to delete a single function, variable,
+                or constant from a list.  This is because I see no
+                real need to do so because of the way the library
+                works.  There is no need to delete function from
+                a function list or constants from a constant list.
+                There are are also no decent reasons to delete
+                variables from a variable list until you are completely
+                done and delete all of them.</li>
+        </ul>
+    </p>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Solutions">Problems and Solutions</a></h2>
+    
+    <ul>
+        <li><b>Variables do not seem to change in a release/optimized build.</b><br>
+            I have noticed a small problem with this.  Rarely, a variable may not
+            appear to change in a release build.  The reason is to do with compiler
+            optimizations.  For example, look at the following code:
+            <blockquote>
+                <pre>
+EXPRTYPE k;
+
+/* Add variable to the list */
+exprValListAddAddress(list, "k", &k);
+
+k = 0.0;
+
+/* Evaluate expression */
+for(int x = 0; x &lt; 100; x++)
+    {
+    exprEval(expr, &result);
+    
+    doSomething(k);
+    }
+                </pre>
+            </blockquote>
+            Inside the loop, the variable 'k' does not appear to be changing, so
+            the compiler may optimize it by loading it into a register before the
+            loop and not accessing it from memory during the loop, even if
+            the expression does change it.  One way to avoid this is to use the
+            'volatile' keyword with the variable.  Then the compiler must
+            accesss it from memory each time it is accessed.
+            <blockquote>
+                <pre>
+volatile EXPRTYPE k;
+
+/* Add variable to the list */
+exprValListAddAddress(list, "k", (EXPRTYPE*)&k);
+
+k = 0.0;
+
+/* Evaluate expression */
+for(int x = 0; x &lt; 100; x++)
+    {
+    exprEval(expr, &result);
+    
+    doSomething(k);
+    }
+                </pre>
+            </blockquote>
+        </li>
+        
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Example">Example Use with Fast Variable Access</a></h2>
+
+    <p>This is an example application of this library.  It is a
+        graphics program that calculates the color value of a
+        pixel based on it's X,Y co-ordinate.  It uses a made-up
+        image library called graphic-lib.  It uses faster variable
+        access by using the exprValListGetAddress function.</p>
+    <p>Note that this codes has not actually been tested.  See the
+        test applications (test and imagegen) for other examples.</p>
+
+    <blockquote>
+        <pre>
+/* Include files */
+#include &lt;stdio.h&gt;
+#include &lt;stdlib.h&gt;
+#include &lt;setjmp.h&gt;
+#include "graphiclib.h"
+#include "expreval.h"
+
+char *transerr(int err)
+    {
+    /* Translate error code into message */
+    }
+
+void gen_image(char *name, int w, int h, char *expr);
+    {
+    exprFuncList *f = NULL;
+    exprValList *v = NULL;
+    exprValList *c = NULL;
+    exprObj *o = NULL;
+    int x, y, err;
+    jmp_buf jumper;
+    int image;
+    EXPRTYPE *v_x, *v_y;
+    EXPRTYPE *v_r, *v_g, *v_b;
+    EXPRTYPE global_value;
+
+    /* Error handling */
+    err = setjmp(jumper);
+    if(err)
+        {
+        if(err != ID_IMAGENOERROR)
+            printf("Error %d occurred: %s\n", err, transerr(err));
+
+        exprFree(o);
+        exprFreeFuncList(f);
+        exprFreeValList(v);
+        exprFreeValList(c);
+
+        image_free(image);
+        return;
+        }
+
+    /* Set up lists */
+
+    /* Function list */
+    err = exprFuncListCreate(&f);
+    if(err != EXPR_ERROR_NOERROR)
+        longjmp(jumper, err);
+
+    err = exprFuncListInit(f);
+    if(err != EXPR_ERROR_NOERROR)
+        {
+        printf("Function list init error. Functions may not be available.\n");
+        }
+
+    /* Variable list */
+    err = exprValListCreate(&v);
+    if(err != EXPR_ERROR_NOERROR)
+        longjmp(jumper, err);
+
+    /* Constant list */
+    err = exprValListCreate(&c);
+    if(err != EXPR_ERROR_NOERROR)
+        {
+        printf("Constants not available\n");
+        }
+    else
+        {
+        err = exprValListInit(c);
+        if(err != EXPR_ERROR_NOERROR)
+            printf("Constant list init error. Constants may not be available.\n");
+        }
+
+    /* Create and parse the expression */
+
+    /* Create */
+    err = exprCreate(&o, f, v, c, NULL, 0);
+    if(err != EXPR_ERROR_NOERROR)
+        longjmp(jumper, err);
+
+    /* Parse expression */
+    err = exprParse(o, expr);
+    if(err != EXPR_ERROR_NOERROR)
+        longjmp(jumper, err);
+
+
+    /* Create the image */
+    image = image_create(w, h);
+    if(image == 0)
+        {
+        longjmp(jumper, ID_IMAGECREATEERROR);
+        }
+
+    /* Add width and height to variable list */
+    exprValListAdd(v, "w", (EXPRTYPE)w);
+    exprValListAdd(v, "h", (EXPRTYPE)h);
+
+    /* Add x and y to the list */
+    exprValListAdd(v, "x", 0.0);
+    exprValListAdd(v, "y", 0.0);
+
+    /* Add r, g, and b to the list */
+    exprValListAdd(v, "r", 0.0);
+    exprValListAdd(v, "g", 0.0);
+    exprValListAdd(b, "b", 0.0);
+
+    /* Get addresses.  Assume no error */
+    exprValListGetAddress(v, "x", &v_x);
+    exprValListGetAddress(v, "y", &v_y);
+
+    exprValListGetAddress(v, "r", &v_r);
+    exprValListGetAddress(v, "g", &v_g);
+    exprValListGetAddress(v, "g", &v_b);
+    
+    /* A way to add global variables that can be used by two different lists. */
+    exprValListAddAddress(v, "global", &global_value);
+    /* exprValListAddAddress(v2, "global", &global_value); */
+    
+    /* Also, exprValListAddAddress can be used to add variables directly.
+       Instead of:
+       
+       EXPRTYPE *a;
+       
+       exprValListAdd(v, "a", 0.0);
+       exprValListGetAddresss(v, "a", &a);
+       
+       You can do:
+       
+       EXPRTYPE a;
+       
+       exprValListAddAddresss(v, "a", &a);
+       
+       If you do this, you must ensure that the stack variable exists as long
+       as it is used by expression, otherwise it may cause a memory access
+       violation. */
+    
+
+    for(y = 0; y < h; y++)
+        {
+        for(x = 0; x < w; x++)
+            {
+            /* Directly set the x and y variables */
+            *v_x = (EXPRTYPE)x;
+            *v_y = (EXPRTYPE)y;
+
+            /* Eval expression, ignoring errors */
+            exprEval(o);
+
+            /* Set pixel, using variables directly */
+            image_setpixel(image, x, y, (int)(*v_r), (int)(*v_g), (int)(*v_b));
+            }
+        }
+
+    /* Save image */
+    image_save(image, name);
+
+    /* Done */
+    longjmp(jumper, ID_IMAGENOERROR);
+    }
+
+void main(void)
+    {
+    char name[MAXPATH]
+    char tmp[10];
+    char expr[4096];
+    int sx, sy;
+
+    printf("Image name to save: ");
+    gets(name);
+
+    printf("Image width: ");
+    gets(tmp);
+    sx = atoi(tmp);
+
+    printf("Image height: ");
+    gets(tmp);
+    sy = atoi(tmp);
+
+    printf("Color Expression (Use x, y, w, h Set r, g, b): ");
+    gets(expr);
+
+    gen_image(name, sx, sy, expr);
+    }
+
+        </pre>
+    </blockquote>
+</div>
+
+</body>
+</html>
index f4f6187c3c9eb45dd2c7e236606d2e64ad312686..6781baece084ca86aee8a154ce9fff3bcacbb036 100644 (file)
-<html>\r
-\r
-<head>\r
-<title>Expression Help</title>\r
-<style type="text/css">\r
-.valid {\r
-  color: #00AA00;\r
-}\r
-.invalid {\r
-  color: #FF0000;\r
-}\r
-.excomment {\r
-  color: #0000FF;\r
-}\r
-.container {\r
-  margin-top: 10px;\r
-  margin-bottom: 10px;\r
-  padding-left: 4px;\r
-  padding-right: 4px;\r
-  border-top: 1px solid #000000;\r
-  border-right: 1px solid #000000;\r
-  border-bottom: 1px solid #000000;\r
-  border-left: 1px solid #000000;\r
-  background-color: #BBBBBB;\r
-}\r
-body {\r
-  background-color: #AAAAAA;\r
-}\r
-</style>\r
-</head>\r
-\r
-<body>\r
-\r
-<div align="center">\r
-    <h1>Expression Help</h1>\r
-    <hr>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2>Contents</h2>\r
-    <h3>\r
-        <ul>\r
-            <li><a href="#Syntax">Expression Syntax</a></li>\r
-            <li><a href="#Operators">Order of Operators</a></li>\r
-            <li><a href="#InternalFunc">ExprEval Internal Functions</a></li>\r
-            <li><a href="#InternalConst">ExprEval Internal Constants</a></li>\r
-            <li><a href="#AppFunc">Application Internal Functions</a></li>\r
-            <li><a href="#AppConst">Application Internal Constants</a></li>\r
-            <li><a href="#AppVar">Application Internal Variables</a></li>\r
-        </ul>\r
-    </h3>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Syntax">Expression Syntax</a></h2>\r
-    <blockquote>\r
-        <p>Expressions have pretty much the same syntax as they\r
-            would have on paper, with the following exceptions:\r
-            <ul>\r
-                <li>Each expression must end with a semicolon. This\r
-                    is because the expression string can actually\r
-                    contain multiple expressions.  The semicolon is\r
-                    used to mark the end of the expression.<br>\r
-                    <b>Examples:</b>\r
-                    <ul>\r
-                        <li>4*x+5;</li>\r
-                        <li>y=5+2;g=4+6;</li>\r
-                        <li>y=r*sin(a);x=r*cos(a);</li>\r
-                    </ul>\r
-                </li>\r
-                <li>The asterisk '*' must be used to multiply.<br>\r
-                    <b>Examples:</b>\r
-                    <ul>\r
-                        <li>y=5*6; <b class="valid">Valid</b></li>\r
-                        <li>g=(x+1)*(x-1); <b class="valid">Valid</b></li>\r
-                        <li>g=(x+1)(x-1); <b class="invalid">Invalid</b></li>\r
-                    </ul>\r
-                </li>\r
-            </ul>\r
-        </p>\r
-        <p>More than one expression may be contained within an expression string.\r
-            As shown above, each expression must end with a semicolon, even if\r
-            only one expression is in the string. The value of an expression\r
-            string is the value of the last expression in the string.<br>\r
-            <b>Examlples:</b>\r
-            <ul>\r
-                <li>g=7; <b class="excomment">Value: 7</b></li>\r
-                <li>k=z+1; <b class="excomment">Value: z+1</b></li>\r
-                <li>r=4;k=6;o=9+r-k; <b class="excomment">Value: 9+r-k</b></li>\r
-            </ul>\r
-        </p>\r
-        <p>Some functions may take reference parameters.  These parameters are\r
-            references to other variables.  You can mix reference parameters\r
-            with normal parameters.  The order of the normal parameters must\r
-            remain the same and the order of the reference parameters must\r
-            remain the same.<br>\r
-            <b>Examples:</b>\r
-            <ul>\r
-                <li>min(1,2,3,4,&mval); <b class="excomment">&mval is a reference to a variable mval</b></li>\r
-                <li>min(1,2,&mval,3,4); <b class="excomment">You may mix them inside like this.</b></li>\r
-                <li>min(1,2,(&mval),3,4); <b class="invalid">You may not nest reference parameters in any way</b></li>\r
-            </ul>\r
-        </p>\r
-        <p>Expressions may also be nested with parenthesis.<br>\r
-        <b>Examples:</b>\r
-            <ul>\r
-                <li>y=sin(x-cos(5+max(4,5,6*x)));</li>\r
-                <li>6+(5-2*(x+y));</li>\r
-            </ul>\r
-        </p>\r
-        <p>Expressions may also have whitespace characters and comments.\r
-            Whitespace characters such as newlines, linefeeds, carriage\r
-            returns, spaces, and tabs are ignored.  Comments begin with\r
-            the pound sign '#' and end at the end of the line.<br>\r
-            <b>Example:</b>\r
-            <ul>\r
-                <pre>\r
-#Set the x value\r
-x = d * cos(r);\r
-\r
-#Set the y value\r
-y = d * sin(r);\r
-                </pre>\r
-            </ul>\r
-        </p>\r
-        <p>If a variable is used in an expression, but that variable does not exist,\r
-            it is considered zero.  If it does exist then its value is used instead.\r
-        </p>\r
-        <p><b>Notice:</b> An expression can <b>NOT</b> assign to a constant and an\r
-            expression can <b>NOT</b> use a constant as a reference parameter.\r
-        </p>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="Operators">Order of operators.</a></h2>\r
-    <blockquote>\r
-        <p>The order of operators are processed correctly in ExprEval.\r
-        The parameters to functions may be evaluated out of order, depending\r
-        on the function itself.</p>\r
-\r
-        The following illustrates the order of operators:\r
-        <table align="center" border="1" width="75%">\r
-            <tr>\r
-                <td align="center"><b>Operator</b></td>\r
-                <td align="center"><b>Direction</b></td>\r
-                <td align="center"><b>Example</b></td>\r
-            </tr>\r
-            <tr>\r
-                <td>Functions and Parenthesis</td>\r
-                <td>N/A</td>\r
-                <td>(x + 5) * sin(d);</td>\r
-            </tr>\r
-            <tr>\r
-                <td>Negation</td>\r
-                <td>Right to Left</td>\r
-                <td>y = -2;</td>\r
-            </tr>\r
-            <tr>\r
-                <td>Exponents</td>\r
-                <td>Left to Right</td>\r
-                <td>y = x ^ 2;</td>\r
-            </tr>\r
-            <tr>\r
-                <td>Multiplication and Division</td>\r
-                <td>Left to Right</td>\r
-                <td>x * 5 / y;</td>\r
-            </tr>\r
-            <tr>\r
-                <td>Addition and Subtraction</td>\r
-                <td>Left to Right</td>\r
-                <td>4 + 5 - 3;</td>\r
-            </tr>\r
-            <tr>\r
-                <td>Assignment</td>\r
-                <td>Right to Left</td>\r
-                <td>x = y = z = 0;</td>\r
-            </tr>\r
-        </table>\r
-\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="InternalFunc">ExprEval Internal Functions</a></h2>\r
-    <blockquote>\r
-        The following functions are provided with ExprEval:\r
-        <table align="center" border="1" width="75%">\r
-            <tr>\r
-                <td align="center"><b>Function</b></td>\r
-                <td align="center"><b>Min. Args</b></td>\r
-                <td align="center"><b>Max. Args</b></td>\r
-                <td align="center"><b>Min. Ref Args</b></td>\r
-                <td align="center"><b>Max. Ref Args</b></td>\r
-                <td align="center"><b>Result/Comment</b></td>\r
-            </tr>\r
-            <tr>\r
-                <td>abs(v)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Absolute value of v.<br>\r
-                    abs(-4.3) returns 4.3</td>\r
-            </tr>\r
-            <tr>\r
-                <td>mod(v,d)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Remainder of v/d.<br>\r
-                    mod(5.2,2.5) return 0.2</td>\r
-            </tr>\r
-            <tr>\r
-                <td>ipart(v)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The integer part of v.<br>\r
-                    ipart(3.2) returns 3</td>\r
-            </tr>\r
-            <tr>\r
-                <td>fpart(v)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The fractional part of v.<br>\r
-                    fpart(3.2) returns 0.2</td>\r
-            </tr>\r
-            <tr>\r
-                <td>min(v,...)</td>\r
-                <td>1</td>\r
-                <td>None</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The minimum number passed.<br>\r
-                    min(3,2,-5,-2,7) returns -5</td>\r
-            </tr>\r
-            <tr>\r
-                <td>max(v,...)</td>\r
-                <td>1</td>\r
-                <td>None</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The maximum number passed.<br>\r
-                    max(3,2,-5,-2,7) returns 7</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>pow(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The value a raised to the power b.<br>\r
-                    pow(3.2,1.7) returns 3.2<sup>1.7</sup></td>\r
-            </tr>\r
-            <tr>\r
-                <td>sqrt(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The square root of a.</br>\r
-                    sqrt(16) returns 4</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>sin(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The sine of a radians.<br>\r
-                    sin(1.5) returns around 0.997</td>\r
-            </tr>\r
-            <tr>\r
-                <td>sinh(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The hyperbolic sine of a.<br>\r
-                    sinh(1.5) returns around 2.129</td>\r
-            </tr>\r
-            <tr>\r
-                <td>asin(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The arc-sine of a in radians.<br>\r
-                    asin(0.5) returns around 0.524</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>cos(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The cosine of a radians.<br>\r
-                    cos(1.5) returns around 0.0707</td>\r
-            </tr>\r
-            <tr>\r
-                <td>cosh(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The hyperbolic cosine of a.</br>\r
-                    cosh(1.5) returns around 2.352</td>\r
-            </tr>\r
-            <tr>\r
-                <td>acos(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The arc-cosine of a in radians.<br>\r
-                    acos(0.5) returns around 1.047</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>tan(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The tangent of a radians.<br>\r
-                    tan(1.5) returns around 14.101</td>\r
-            </tr>\r
-            <tr>\r
-                <td>tanh(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The hyperbolic tangent of a.</br>\r
-                    tanh(1.5) returns around 0.905</td>\r
-            </tr>\r
-            <tr>\r
-                <td>atan(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The arc-tangent of a in radians.<br>\r
-                    atan(0.3) returns about 0.291</td>\r
-            </tr>\r
-            <tr>\r
-                <td>atan2(y,x)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The arc-tangent of y/x, with quadrant correction.<br>\r
-                    atan2(4,3) returns about 0.927</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>log(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The base 10 logarithm of a.<br>\r
-                    log(100) returns 2</td>\r
-            </tr>\r
-            <tr>\r
-                <td>pow10(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>10 raised to the power of a.<br>\r
-                    pow10(2) returns 100</td>\r
-            </tr>\r
-            <tr>\r
-                <td>ln(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The base e logarithm of a.<br>\r
-                    ln(2.8) returns around 1.030</td>\r
-            </tr>\r
-            <tr>\r
-                <td>exp(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>e raised to the power of a.<br>\r
-                    exp(2) returns around 7.389</td>\r
-            </tr>\r
-            <tr>\r
-                <td>logn(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>The base b logarithm of a.<br>\r
-                    logn(16,2) returns 4</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>ceil(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Rounds a up to the nearest integer.<br>\r
-                    ceil(3.2) returns 4</td>\r
-            </tr>\r
-            <tr>\r
-                <td>floor(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Rounds a down to the nearest integer.<br>\r
-                    floor(3.2) returns 3</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>rand(&seed)</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>Returns a number between 0 up to but not including 1.</td>\r
-            </tr>\r
-            <tr>\r
-                <td>random(a,b,&seed)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>Returns a number between a up to and including b.</td>\r
-            </tr>\r
-            <tr>\r
-                <td>randomize(&seed)</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>Seed the random number generator with a value\r
-                    based on the current time.<br>\r
-                    Return value is unknown</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>deg(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns a radians converted to degrees.<br>\r
-                    deg(3.14) returns around 179.909</td>\r
-            </tr>\r
-            <tr>\r
-                <td>rad(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns a degrees converted to radians.<br>\r
-                    rad(180) returns around 3.142</td>\r
-            </tr>\r
-            <tr>\r
-                <td>recttopolr(x,y)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns the polar radius of the rectangular co-ordinates.<br>\r
-                    recttopolr(2,3) returns around 3.606</td>\r
-            </tr>\r
-            <tr>\r
-                <td>recttopola(x,y)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns the polar angle (0...2PI) in radians of the rectangular co-ordinates.<br>\r
-                    recttopola(2,3) returns around 0.588</td>\r
-            </tr>\r
-            <tr>\r
-                <td>poltorectx(r,a)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns the x rectangular co-ordinate of the polar\r
-                    co-ordinates.<br>\r
-                    poltorectx(3,1.5) returns around 0.212</td>\r
-            </tr>\r
-            <tr>\r
-                <td>poltorecty(r,a)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns the y rectangular co-ordinate of the polar\r
-                    co-ordinates.<br>\r
-                    poltorecty(3,1.5) returns around 2.992</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>if(c,t,f)</td>\r
-                <td>3</td>\r
-                <td>3</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Evaluates and returns t if c is not 0.0.\r
-                    Else evaluates and returns f.<br>\r
-                    if(0.1,2.1,3.9) returns 2.1</td>\r
-            </tr>\r
-            <tr>\r
-                <td>select(c,n,z[,p])</td>\r
-                <td>3</td>\r
-                <td>4</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns n if c is less than 0.0.  Returns z\r
-                    if c is 0.0.  If c is greater than 0.0 and only\r
-                    three arguments were passed, returns z.  If c\r
-                    is greater than 0.0 and four arguments were passed,\r
-                    return p.<br>\r
-                    select(3,1,4,5) returns 5</td>\r
-            </tr>\r
-            <tr>\r
-                <td>equal(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns 1.0 if a is equal to b. Else returns 0.0<br>\r
-                    equal(3,2) returns 0.0</td>\r
-            </tr>\r
-            <tr>\r
-                <td>above(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns 1.0 if a is above b. Else returns 0.0<br>\r
-                    above(3,2) returns 1.0</td>\r
-            </tr>\r
-            <tr>\r
-                <td>below(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns 1.0 if a is below b. Else returns 0.0<br>\r
-                    below(3,2) returns 0.0</td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>avg(a,...)</td>\r
-                <td>1</td>\r
-                <td>None</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns the average of the values passed.<br>\r
-                    avg(3,3,6) returns 4</td>\r
-            </tr>\r
-            <tr>\r
-                <td>clip(v,min,max)</td>\r
-                <td>3</td>\r
-                <td>3</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Clips v to the range from min to max.  If v is less\r
-                    than min, it returns min.  If v is greater than\r
-                    max it returns max. Otherwise it returns v.<br>\r
-                    clip(3,1,2) returns 2</td>\r
-            </tr>\r
-            <tr>\r
-                <td>clamp(v,min,max)</td>\r
-                <td>3</td>\r
-                <td>3</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Clamps v to the range from min to max, looping\r
-                    if needed.<br>\r
-                    clamp(8.2,1.3,4.7) returns 1.4</td>\r
-            </tr>\r
-            <tr>\r
-                <td>pntchange(side1old, side2old, side1new, side2new, oldpnt)</td>\r
-                <td>5</td>\r
-                <td>5</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>This is used to translate points from different\r
-                    scale.  It works no matter the orientation as long\r
-                    as the sides are lined up correctly.<br>\r
-                    pntchange(-1,1,0,480,-0.5) returns 120 (x example)<br>\r
-                    pntchange(-1,1,480,0,-0.5) returns 360 (y example)</td>\r
-            </tr>\r
-            <tr>\r
-                <td>poly(x,c1,...)</td>\r
-                <td>2</td>\r
-                <td>None</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>This function calculates the polynomial.  x is the value\r
-                    to use in the polynomial. c1 and on are the coefficients.<br>\r
-                    poly(4,6,9,3,1,4) returns 2168<br>\r
-                    same as 6*4<sup>4</sup> + 9*4<sup>3</sup> + 3*4<sup>2</sup> + 1*4<sup>1</sup> + 4*4<sup>0</sup></td>\r
-            </tr>\r
-\r
-            <tr>\r
-                <td>and(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns 0.0 if either a or b are 0.0 Else returns 1.0<br>\r
-                    and(2.1,0.0) returns 0.0</td>\r
-            </tr>\r
-            <tr>\r
-                <td>or(a,b)</td>\r
-                <td>2</td>\r
-                <td>2</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns 0.0 if both a and b are 0.0 Else returns 1.0<br>\r
-                    or(2.1,0.0) returns 1.0</td>\r
-            </tr>\r
-            <tr>\r
-                <td>not(a)</td>\r
-                <td>1</td>\r
-                <td>1</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>Returns 1.0 if a is 0.0 Else returns 0.0<br>\r
-                    not(0.3) returns 0.0</td>\r
-            </tr>\r
-            <tr>\r
-                <td>for(init,test,inc,a1,...)</td>\r
-                <td>4</td>\r
-                <td>None</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>This function acts like a for loop in C. First init is\r
-                    evaluated.  Then test is evaluated.  As long as the\r
-                    test is not 0.0, the action statements (a1 to an) are\r
-                    evaluated, the inc statement is evaluated, and the test\r
-                    is evaluated again.  The result is the result of the\r
-                    final action statement.<br>\r
-                    for(x=0,below(x,11),x=x+1,y=y+x) returns 55.0 (if y was\r
-                    initially 0.0)</td>\r
-            </tr>\r
-            <tr>\r
-                <td>many(expr,...)</td>\r
-                <td>1</td>\r
-                <td>None</td>\r
-                <td>0</td>\r
-                <td>0</td>\r
-                <td>This function treats many subexpressions as a single object\r
-                    (function). It is mainly for the 'for' function.<br>\r
-                    for(many(j=5,k=1),above(j*k,0.001),many(j=j+5,k=k/2),0)</td>\r
-            </tr>\r
-\r
-\r
-        </table>\r
-\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="InternalConst">ExprEval Internal Constants</a></h2>\r
-    <blockquote>\r
-        The following constants are provided with ExprEval:\r
-        <table align="center" border="1" width="75%">\r
-            <tr>\r
-                <td align="center"><b>Constant</b></td>\r
-                <td align="center"><b>Math Form</b></td>\r
-                <td align="center"><b>Value</b></td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_E</td>\r
-                <td>e</td>\r
-                <td>2.7182818284590452354</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_LOG2E</td>\r
-                <td>log<sub>2</sub>(e)</td>\r
-                <td>1.4426950408889634074</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_LOG10E</td>\r
-                <td>log<sub>10</sub>(e)</td>\r
-                <td>0.43429448190325182765</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_LN2</td>\r
-                <td>ln(2)</td>\r
-                <td>0.69314718055994530942</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_LN10</td>\r
-                <td>ln(10)</td>\r
-                <td>2.30258509299404568402</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_PI</td>\r
-                <td>&#960;</td>\r
-                <td>3.14159265358979323846</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_PI_2</td>\r
-                <td>&#960;/2</td>\r
-                <td>1.57079632679489661923</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_PI_4</td>\r
-                <td>&#960;/4</td>\r
-                <td>0.78539816339744830962</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_1_PI</td>\r
-                <td>1/&#960;</td>\r
-                <td>0.31830988618379067154</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_2_PI</td>\r
-                <td>2/&#960;</td>\r
-                <td>0.63661977236758134308</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_1_SQRTPI</td>\r
-                <td>1/&#8730;(&#960;)</td>\r
-                <td>0.56418958354776</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_2_SQRTPI</td>\r
-                <td>2/&#8730;(&#960;)</td>\r
-                <td>1.12837916709551257390</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_SQRT2</td>\r
-                <td>&#8730;(2)</td>\r
-                <td>1.41421356237309504880</td>\r
-            </tr>\r
-            <tr>\r
-                <td>M_1_SQRT2</td>\r
-                <td>1/&#8730;(2)</td>\r
-                <td>0.70710678118654752440</td>\r
-            </tr>\r
-        </table>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="AppFunc">Application Internal Functions</a></h2>\r
-    <blockquote>\r
-        Application defined expression functions go here.\r
-        <table align="center" border="1" width="75%">\r
-            <tr>\r
-                <td align="center"><b>Function</b></td>\r
-                <td align="center"><b>Min. Args</b></td>\r
-                <td align="center"><b>Max. Args</b></td>\r
-                <td align="center"><b>Min. Ref Args</b></td>\r
-                <td align="center"><b>Max. Ref Args</b></td>\r
-                <td align="center"><b>Result/Comment</b></td>\r
-            </tr>\r
-            <tr>\r
-                <td></td>\r
-                <td></td>\r
-                <td></td>\r
-                <td></td>\r
-                <td></td>\r
-                <td></td>\r
-            </tr>\r
-        </table>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="AppConst">Application Internal Constants</a></h2>\r
-    <blockquote>\r
-        Application defined expression constants go here.\r
-        <table align="center" border="1" width="75%">\r
-            <tr>\r
-                <td align="center"><b>Constant</b></td>\r
-                <td align="center"><b>Math Form</b></td>\r
-                <td align="center"><b>Value</b></td>\r
-            </tr>\r
-            <tr>\r
-                <td></td>\r
-                <td></td>\r
-                <td></td>\r
-            </tr>\r
-        </table>\r
-    </blockquote>\r
-</div>\r
-\r
-<div align="left" class="container">\r
-    <h2><a name="AppVar">Application Internal Variables</a></h2>\r
-    <blockquote>\r
-        Application defined expression variables go here.\r
-        <table align="center" border="1" width="75%">\r
-            <tr>\r
-                <td align="center"><b>Variable</b></td>\r
-                <td align="center"><b>Math Form</b></td>\r
-                <td align="center"><b>Value</b></td>\r
-            </tr>\r
-            <tr>\r
-                <td></td>\r
-                <td></td>\r
-                <td></td>\r
-            </tr>\r
-        </table>\r
-    </blockquote>\r
-</div>\r
-\r
-</body>\r
-\r
-</html>\r
-\r
-\r
+<html>
+
+<head>
+<title>Expression Help</title>
+<style type="text/css">
+.valid {
+  color: #00AA00;
+}
+.invalid {
+  color: #FF0000;
+}
+.excomment {
+  color: #0000FF;
+}
+.container {
+  margin-top: 10px;
+  margin-bottom: 10px;
+  padding-left: 4px;
+  padding-right: 4px;
+  border-top: 1px solid #000000;
+  border-right: 1px solid #000000;
+  border-bottom: 1px solid #000000;
+  border-left: 1px solid #000000;
+  background-color: #BBBBBB;
+}
+body {
+  background-color: #AAAAAA;
+}
+</style>
+</head>
+
+<body>
+
+<div align="center">
+    <h1>Expression Help</h1>
+    <hr>
+</div>
+
+<div align="left" class="container">
+    <h2>Contents</h2>
+    <h3>
+        <ul>
+            <li><a href="#Syntax">Expression Syntax</a></li>
+            <li><a href="#Operators">Order of Operators</a></li>
+            <li><a href="#InternalFunc">ExprEval Internal Functions</a></li>
+            <li><a href="#InternalConst">ExprEval Internal Constants</a></li>
+            <li><a href="#AppFunc">Application Internal Functions</a></li>
+            <li><a href="#AppConst">Application Internal Constants</a></li>
+            <li><a href="#AppVar">Application Internal Variables</a></li>
+        </ul>
+    </h3>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Syntax">Expression Syntax</a></h2>
+    <blockquote>
+        <p>Expressions have pretty much the same syntax as they
+            would have on paper, with the following exceptions:
+            <ul>
+                <li>Each expression must end with a semicolon. This
+                    is because the expression string can actually
+                    contain multiple expressions.  The semicolon is
+                    used to mark the end of the expression.<br>
+                    <b>Examples:</b>
+                    <ul>
+                        <li>4*x+5;</li>
+                        <li>y=5+2;g=4+6;</li>
+                        <li>y=r*sin(a);x=r*cos(a);</li>
+                    </ul>
+                </li>
+                <li>The asterisk '*' must be used to multiply.<br>
+                    <b>Examples:</b>
+                    <ul>
+                        <li>y=5*6; <b class="valid">Valid</b></li>
+                        <li>g=(x+1)*(x-1); <b class="valid">Valid</b></li>
+                        <li>g=(x+1)(x-1); <b class="invalid">Invalid</b></li>
+                    </ul>
+                </li>
+            </ul>
+        </p>
+        <p>More than one expression may be contained within an expression string.
+            As shown above, each expression must end with a semicolon, even if
+            only one expression is in the string. The value of an expression
+            string is the value of the last expression in the string.<br>
+            <b>Examlples:</b>
+            <ul>
+                <li>g=7; <b class="excomment">Value: 7</b></li>
+                <li>k=z+1; <b class="excomment">Value: z+1</b></li>
+                <li>r=4;k=6;o=9+r-k; <b class="excomment">Value: 9+r-k</b></li>
+            </ul>
+        </p>
+        <p>Some functions may take reference parameters.  These parameters are
+            references to other variables.  You can mix reference parameters
+            with normal parameters.  The order of the normal parameters must
+            remain the same and the order of the reference parameters must
+            remain the same.<br>
+            <b>Examples:</b>
+            <ul>
+                <li>min(1,2,3,4,&mval); <b class="excomment">&mval is a reference to a variable mval</b></li>
+                <li>min(1,2,&mval,3,4); <b class="excomment">You may mix them inside like this.</b></li>
+                <li>min(1,2,(&mval),3,4); <b class="invalid">You may not nest reference parameters in any way</b></li>
+            </ul>
+        </p>
+        <p>Expressions may also be nested with parenthesis.<br>
+        <b>Examples:</b>
+            <ul>
+                <li>y=sin(x-cos(5+max(4,5,6*x)));</li>
+                <li>6+(5-2*(x+y));</li>
+            </ul>
+        </p>
+        <p>Expressions may also have whitespace characters and comments.
+            Whitespace characters such as newlines, linefeeds, carriage
+            returns, spaces, and tabs are ignored.  Comments begin with
+            the pound sign '#' and end at the end of the line.<br>
+            <b>Example:</b>
+            <ul>
+                <pre>
+#Set the x value
+x = d * cos(r);
+
+#Set the y value
+y = d * sin(r);
+                </pre>
+            </ul>
+        </p>
+        <p>If a variable is used in an expression, but that variable does not exist,
+            it is considered zero.  If it does exist then its value is used instead.
+        </p>
+        <p><b>Notice:</b> An expression can <b>NOT</b> assign to a constant and an
+            expression can <b>NOT</b> use a constant as a reference parameter.
+        </p>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="Operators">Order of operators.</a></h2>
+    <blockquote>
+        <p>The order of operators are processed correctly in ExprEval.
+        The parameters to functions may be evaluated out of order, depending
+        on the function itself.</p>
+
+        The following illustrates the order of operators:
+        <table align="center" border="1" width="75%">
+            <tr>
+                <td align="center"><b>Operator</b></td>
+                <td align="center"><b>Direction</b></td>
+                <td align="center"><b>Example</b></td>
+            </tr>
+            <tr>
+                <td>Functions and Parenthesis</td>
+                <td>N/A</td>
+                <td>(x + 5) * sin(d);</td>
+            </tr>
+            <tr>
+                <td>Negation</td>
+                <td>Right to Left</td>
+                <td>y = -2;</td>
+            </tr>
+            <tr>
+                <td>Exponents</td>
+                <td>Left to Right</td>
+                <td>y = x ^ 2;</td>
+            </tr>
+            <tr>
+                <td>Multiplication and Division</td>
+                <td>Left to Right</td>
+                <td>x * 5 / y;</td>
+            </tr>
+            <tr>
+                <td>Addition and Subtraction</td>
+                <td>Left to Right</td>
+                <td>4 + 5 - 3;</td>
+            </tr>
+            <tr>
+                <td>Assignment</td>
+                <td>Right to Left</td>
+                <td>x = y = z = 0;</td>
+            </tr>
+        </table>
+
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="InternalFunc">ExprEval Internal Functions</a></h2>
+    <blockquote>
+        The following functions are provided with ExprEval:
+        <table align="center" border="1" width="75%">
+            <tr>
+                <td align="center"><b>Function</b></td>
+                <td align="center"><b>Min. Args</b></td>
+                <td align="center"><b>Max. Args</b></td>
+                <td align="center"><b>Min. Ref Args</b></td>
+                <td align="center"><b>Max. Ref Args</b></td>
+                <td align="center"><b>Result/Comment</b></td>
+            </tr>
+            <tr>
+                <td>abs(v)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Absolute value of v.<br>
+                    abs(-4.3) returns 4.3</td>
+            </tr>
+            <tr>
+                <td>mod(v,d)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Remainder of v/d.<br>
+                    mod(5.2,2.5) return 0.2</td>
+            </tr>
+            <tr>
+                <td>ipart(v)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The integer part of v.<br>
+                    ipart(3.2) returns 3</td>
+            </tr>
+            <tr>
+                <td>fpart(v)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The fractional part of v.<br>
+                    fpart(3.2) returns 0.2</td>
+            </tr>
+            <tr>
+                <td>min(v,...)</td>
+                <td>1</td>
+                <td>None</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The minimum number passed.<br>
+                    min(3,2,-5,-2,7) returns -5</td>
+            </tr>
+            <tr>
+                <td>max(v,...)</td>
+                <td>1</td>
+                <td>None</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The maximum number passed.<br>
+                    max(3,2,-5,-2,7) returns 7</td>
+            </tr>
+
+            <tr>
+                <td>pow(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The value a raised to the power b.<br>
+                    pow(3.2,1.7) returns 3.2<sup>1.7</sup></td>
+            </tr>
+            <tr>
+                <td>sqrt(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The square root of a.</br>
+                    sqrt(16) returns 4</td>
+            </tr>
+
+            <tr>
+                <td>sin(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The sine of a radians.<br>
+                    sin(1.5) returns around 0.997</td>
+            </tr>
+            <tr>
+                <td>sinh(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The hyperbolic sine of a.<br>
+                    sinh(1.5) returns around 2.129</td>
+            </tr>
+            <tr>
+                <td>asin(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The arc-sine of a in radians.<br>
+                    asin(0.5) returns around 0.524</td>
+            </tr>
+
+            <tr>
+                <td>cos(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The cosine of a radians.<br>
+                    cos(1.5) returns around 0.0707</td>
+            </tr>
+            <tr>
+                <td>cosh(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The hyperbolic cosine of a.</br>
+                    cosh(1.5) returns around 2.352</td>
+            </tr>
+            <tr>
+                <td>acos(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The arc-cosine of a in radians.<br>
+                    acos(0.5) returns around 1.047</td>
+            </tr>
+
+            <tr>
+                <td>tan(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The tangent of a radians.<br>
+                    tan(1.5) returns around 14.101</td>
+            </tr>
+            <tr>
+                <td>tanh(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The hyperbolic tangent of a.</br>
+                    tanh(1.5) returns around 0.905</td>
+            </tr>
+            <tr>
+                <td>atan(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The arc-tangent of a in radians.<br>
+                    atan(0.3) returns about 0.291</td>
+            </tr>
+            <tr>
+                <td>atan2(y,x)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The arc-tangent of y/x, with quadrant correction.<br>
+                    atan2(4,3) returns about 0.927</td>
+            </tr>
+
+            <tr>
+                <td>log(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The base 10 logarithm of a.<br>
+                    log(100) returns 2</td>
+            </tr>
+            <tr>
+                <td>pow10(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>10 raised to the power of a.<br>
+                    pow10(2) returns 100</td>
+            </tr>
+            <tr>
+                <td>ln(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The base e logarithm of a.<br>
+                    ln(2.8) returns around 1.030</td>
+            </tr>
+            <tr>
+                <td>exp(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>e raised to the power of a.<br>
+                    exp(2) returns around 7.389</td>
+            </tr>
+            <tr>
+                <td>logn(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>The base b logarithm of a.<br>
+                    logn(16,2) returns 4</td>
+            </tr>
+
+            <tr>
+                <td>ceil(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Rounds a up to the nearest integer.<br>
+                    ceil(3.2) returns 4</td>
+            </tr>
+            <tr>
+                <td>floor(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Rounds a down to the nearest integer.<br>
+                    floor(3.2) returns 3</td>
+            </tr>
+
+            <tr>
+                <td>rand(&seed)</td>
+                <td>0</td>
+                <td>0</td>
+                <td>1</td>
+                <td>1</td>
+                <td>Returns a number between 0 up to but not including 1.</td>
+            </tr>
+            <tr>
+                <td>random(a,b,&seed)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>1</td>
+                <td>1</td>
+                <td>Returns a number between a up to and including b.</td>
+            </tr>
+            <tr>
+                <td>randomize(&seed)</td>
+                <td>0</td>
+                <td>0</td>
+                <td>1</td>
+                <td>1</td>
+                <td>Seed the random number generator with a value
+                    based on the current time.<br>
+                    Return value is unknown</td>
+            </tr>
+
+            <tr>
+                <td>deg(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns a radians converted to degrees.<br>
+                    deg(3.14) returns around 179.909</td>
+            </tr>
+            <tr>
+                <td>rad(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns a degrees converted to radians.<br>
+                    rad(180) returns around 3.142</td>
+            </tr>
+            <tr>
+                <td>recttopolr(x,y)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns the polar radius of the rectangular co-ordinates.<br>
+                    recttopolr(2,3) returns around 3.606</td>
+            </tr>
+            <tr>
+                <td>recttopola(x,y)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns the polar angle (0...2PI) in radians of the rectangular co-ordinates.<br>
+                    recttopola(2,3) returns around 0.588</td>
+            </tr>
+            <tr>
+                <td>poltorectx(r,a)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns the x rectangular co-ordinate of the polar
+                    co-ordinates.<br>
+                    poltorectx(3,1.5) returns around 0.212</td>
+            </tr>
+            <tr>
+                <td>poltorecty(r,a)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns the y rectangular co-ordinate of the polar
+                    co-ordinates.<br>
+                    poltorecty(3,1.5) returns around 2.992</td>
+            </tr>
+
+            <tr>
+                <td>if(c,t,f)</td>
+                <td>3</td>
+                <td>3</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Evaluates and returns t if c is not 0.0.
+                    Else evaluates and returns f.<br>
+                    if(0.1,2.1,3.9) returns 2.1</td>
+            </tr>
+            <tr>
+                <td>select(c,n,z[,p])</td>
+                <td>3</td>
+                <td>4</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns n if c is less than 0.0.  Returns z
+                    if c is 0.0.  If c is greater than 0.0 and only
+                    three arguments were passed, returns z.  If c
+                    is greater than 0.0 and four arguments were passed,
+                    return p.<br>
+                    select(3,1,4,5) returns 5</td>
+            </tr>
+            <tr>
+                <td>equal(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns 1.0 if a is equal to b. Else returns 0.0<br>
+                    equal(3,2) returns 0.0</td>
+            </tr>
+            <tr>
+                <td>above(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns 1.0 if a is above b. Else returns 0.0<br>
+                    above(3,2) returns 1.0</td>
+            </tr>
+            <tr>
+                <td>below(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns 1.0 if a is below b. Else returns 0.0<br>
+                    below(3,2) returns 0.0</td>
+            </tr>
+
+            <tr>
+                <td>avg(a,...)</td>
+                <td>1</td>
+                <td>None</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns the average of the values passed.<br>
+                    avg(3,3,6) returns 4</td>
+            </tr>
+            <tr>
+                <td>clip(v,min,max)</td>
+                <td>3</td>
+                <td>3</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Clips v to the range from min to max.  If v is less
+                    than min, it returns min.  If v is greater than
+                    max it returns max. Otherwise it returns v.<br>
+                    clip(3,1,2) returns 2</td>
+            </tr>
+            <tr>
+                <td>clamp(v,min,max)</td>
+                <td>3</td>
+                <td>3</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Clamps v to the range from min to max, looping
+                    if needed.<br>
+                    clamp(8.2,1.3,4.7) returns 1.4</td>
+            </tr>
+            <tr>
+                <td>pntchange(side1old, side2old, side1new, side2new, oldpnt)</td>
+                <td>5</td>
+                <td>5</td>
+                <td>0</td>
+                <td>0</td>
+                <td>This is used to translate points from different
+                    scale.  It works no matter the orientation as long
+                    as the sides are lined up correctly.<br>
+                    pntchange(-1,1,0,480,-0.5) returns 120 (x example)<br>
+                    pntchange(-1,1,480,0,-0.5) returns 360 (y example)</td>
+            </tr>
+            <tr>
+                <td>poly(x,c1,...)</td>
+                <td>2</td>
+                <td>None</td>
+                <td>0</td>
+                <td>0</td>
+                <td>This function calculates the polynomial.  x is the value
+                    to use in the polynomial. c1 and on are the coefficients.<br>
+                    poly(4,6,9,3,1,4) returns 2168<br>
+                    same as 6*4<sup>4</sup> + 9*4<sup>3</sup> + 3*4<sup>2</sup> + 1*4<sup>1</sup> + 4*4<sup>0</sup></td>
+            </tr>
+
+            <tr>
+                <td>and(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns 0.0 if either a or b are 0.0 Else returns 1.0<br>
+                    and(2.1,0.0) returns 0.0</td>
+            </tr>
+            <tr>
+                <td>or(a,b)</td>
+                <td>2</td>
+                <td>2</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns 0.0 if both a and b are 0.0 Else returns 1.0<br>
+                    or(2.1,0.0) returns 1.0</td>
+            </tr>
+            <tr>
+                <td>not(a)</td>
+                <td>1</td>
+                <td>1</td>
+                <td>0</td>
+                <td>0</td>
+                <td>Returns 1.0 if a is 0.0 Else returns 0.0<br>
+                    not(0.3) returns 0.0</td>
+            </tr>
+            <tr>
+                <td>for(init,test,inc,a1,...)</td>
+                <td>4</td>
+                <td>None</td>
+                <td>0</td>
+                <td>0</td>
+                <td>This function acts like a for loop in C. First init is
+                    evaluated.  Then test is evaluated.  As long as the
+                    test is not 0.0, the action statements (a1 to an) are
+                    evaluated, the inc statement is evaluated, and the test
+                    is evaluated again.  The result is the result of the
+                    final action statement.<br>
+                    for(x=0,below(x,11),x=x+1,y=y+x) returns 55.0 (if y was
+                    initially 0.0)</td>
+            </tr>
+            <tr>
+                <td>many(expr,...)</td>
+                <td>1</td>
+                <td>None</td>
+                <td>0</td>
+                <td>0</td>
+                <td>This function treats many subexpressions as a single object
+                    (function). It is mainly for the 'for' function.<br>
+                    for(many(j=5,k=1),above(j*k,0.001),many(j=j+5,k=k/2),0)</td>
+            </tr>
+
+
+        </table>
+
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="InternalConst">ExprEval Internal Constants</a></h2>
+    <blockquote>
+        The following constants are provided with ExprEval:
+        <table align="center" border="1" width="75%">
+            <tr>
+                <td align="center"><b>Constant</b></td>
+                <td align="center"><b>Math Form</b></td>
+                <td align="center"><b>Value</b></td>
+            </tr>
+            <tr>
+                <td>M_E</td>
+                <td>e</td>
+                <td>2.7182818284590452354</td>
+            </tr>
+            <tr>
+                <td>M_LOG2E</td>
+                <td>log<sub>2</sub>(e)</td>
+                <td>1.4426950408889634074</td>
+            </tr>
+            <tr>
+                <td>M_LOG10E</td>
+                <td>log<sub>10</sub>(e)</td>
+                <td>0.43429448190325182765</td>
+            </tr>
+            <tr>
+                <td>M_LN2</td>
+                <td>ln(2)</td>
+                <td>0.69314718055994530942</td>
+            </tr>
+            <tr>
+                <td>M_LN10</td>
+                <td>ln(10)</td>
+                <td>2.30258509299404568402</td>
+            </tr>
+            <tr>
+                <td>M_PI</td>
+                <td>&#960;</td>
+                <td>3.14159265358979323846</td>
+            </tr>
+            <tr>
+                <td>M_PI_2</td>
+                <td>&#960;/2</td>
+                <td>1.57079632679489661923</td>
+            </tr>
+            <tr>
+                <td>M_PI_4</td>
+                <td>&#960;/4</td>
+                <td>0.78539816339744830962</td>
+            </tr>
+            <tr>
+                <td>M_1_PI</td>
+                <td>1/&#960;</td>
+                <td>0.31830988618379067154</td>
+            </tr>
+            <tr>
+                <td>M_2_PI</td>
+                <td>2/&#960;</td>
+                <td>0.63661977236758134308</td>
+            </tr>
+            <tr>
+                <td>M_1_SQRTPI</td>
+                <td>1/&#8730;(&#960;)</td>
+                <td>0.56418958354776</td>
+            </tr>
+            <tr>
+                <td>M_2_SQRTPI</td>
+                <td>2/&#8730;(&#960;)</td>
+                <td>1.12837916709551257390</td>
+            </tr>
+            <tr>
+                <td>M_SQRT2</td>
+                <td>&#8730;(2)</td>
+                <td>1.41421356237309504880</td>
+            </tr>
+            <tr>
+                <td>M_1_SQRT2</td>
+                <td>1/&#8730;(2)</td>
+                <td>0.70710678118654752440</td>
+            </tr>
+        </table>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="AppFunc">Application Internal Functions</a></h2>
+    <blockquote>
+        Application defined expression functions go here.
+        <table align="center" border="1" width="75%">
+            <tr>
+                <td align="center"><b>Function</b></td>
+                <td align="center"><b>Min. Args</b></td>
+                <td align="center"><b>Max. Args</b></td>
+                <td align="center"><b>Min. Ref Args</b></td>
+                <td align="center"><b>Max. Ref Args</b></td>
+                <td align="center"><b>Result/Comment</b></td>
+            </tr>
+            <tr>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td></td>
+            </tr>
+        </table>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="AppConst">Application Internal Constants</a></h2>
+    <blockquote>
+        Application defined expression constants go here.
+        <table align="center" border="1" width="75%">
+            <tr>
+                <td align="center"><b>Constant</b></td>
+                <td align="center"><b>Math Form</b></td>
+                <td align="center"><b>Value</b></td>
+            </tr>
+            <tr>
+                <td></td>
+                <td></td>
+                <td></td>
+            </tr>
+        </table>
+    </blockquote>
+</div>
+
+<div align="left" class="container">
+    <h2><a name="AppVar">Application Internal Variables</a></h2>
+    <blockquote>
+        Application defined expression variables go here.
+        <table align="center" border="1" width="75%">
+            <tr>
+                <td align="center"><b>Variable</b></td>
+                <td align="center"><b>Math Form</b></td>
+                <td align="center"><b>Value</b></td>
+            </tr>
+            <tr>
+                <td></td>
+                <td></td>
+                <td></td>
+            </tr>
+        </table>
+    </blockquote>
+</div>
+
+</body>
+
+</html>
+
+