📄 expreval.html
字号:
/* Make sure arg 2 is not 0.0 */
if(d2 == 0.0)
{
/* Soft errors on */
if(exprGetSoftErrors(o))
{
/* Yes */
*val = 0.0;
return EXPR_ERROR_NOERROR;
}
else
{
/* No */
return EXPR_ERROR_OUTOFRANGE; /* Bad argument */
}
}
/* Clear any math routine errors */
errno = 0;
/* Do math */
*val = atan(d1 / d2); /* No need to worry about divide by zero */
/* Check for math errors */
if(errno == EDOM || errno == ERANGE)
{
if(exprGetSoftErrors(o))
{
*val = 0.0;
return EXPR_ERROR_NOERROR;
}
else
{
return EXPR_ERROR_OUTOFRANGE;
}
}
return EXPR_ERROR_NOERROR;
}
</pre>
</ul>
</p>
<p><b>Same example with the macros:</b>
<ul>
<pre>
EXPR_FUNCTIONSOLVER(custom_func)
{
int err;
EXPRTYPE d1, d2;
/* Require 2 arguments */
EXPR_REQUIRECOUNT(2);
/* Evaluate the nodes */
EXPR_EVALNODE(0, d1);
EXPR_EVALNODE(1, d2);
/* Make sure d2 is not 0.0 */
if(d2 == 0.0)
{
EXPR_RETURNSOFTERR(EXPR_ERROR_OUTOFRANGE);
}
/* Clear math routine errors */
EXPR_CLEARMATHERR();
/* Do math */
*val = atan(d1 / d2) /* No need to worry about division by zero */
/* Check for math routine errors */
EXPR_CHECKMATHERR();
/* Return */
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>
<p>The following is a list of the macros, their uses, and
their definitions. They require the custom function
arguments to have the same names as above
(struct _exprObj *o, struct _exprNode *n, int count, EXPRTYPE *val).</p>
<table align="center" border="1" width="75%">
<tr>
<td align="center"><b>Macro</b></td>
<td align="center"><b>Usage</b></td>
<td align="center"><b>Definition</b></td>
</tr>
<tr>
<td>EXPR_EVALNODE(num, res)</td>
<td>Evaluate a node. num is the zero based node number
to evaluate. res is the variable to store the result
in.</td>
<td>
<pre>
err = exprEvalNode(o, &(n[num]), &res);
if(err != EXPR_ERROR_NOERROR)
return err;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIRECOUNT(c)</td>
<td>Require exactly c arguments.</td>
<td>
<pre>
if(count != c)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIRECOUNTMIN(c)</td>
<td>Require at least c arguments.</td>
<td>
<pre>
if(count < c)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIRECOUNTMAX(c)</td>
<td>Require at most c arguments.</td>
<td>
<pre>
if(count > c)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIRECOUNTRANGE(c1, c2)</td>
<td>Require at least c1 arguments and at
most c2 arguments.</td>
<td>
<pre>
if(count < c1 || count > c2)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIREREFCOUNT(c)</td>
<td>Require exactly c ref arguments.</td>
<td>
<pre>
if(refcount != c)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIREREFCOUNTMIN(c)</td>
<td>Require at least c ref arguments.</td>
<td>
<pre>
if(refcount < c)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIREREFCOUNTMAX(c)</td>
<td>Require at most c ref arguments.</td>
<td>
<pre>
if(refcount > c)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_REQUIREREFCOUNTRANGE(c1, c2)</td>
<td>Require at least c1 ref arguments and at
most c2 ref arguments.</td>
<td>
<pre>
if(refcount < c1 || refcount > c2)
return EXPR_ERROR_BADNUMBERARGUMENTS;
</pre>
</td>
</tr>
<tr>
<td>EXPR_CHECKMATHERR()</td>
<td>Check for EDOM or ERANGE math error.</td>
<td>
<pre>
if(errno == ERANGE || errno == EDOM)
{
if(exprGetSoftErrors(o))
{
*val = 0.0;
return EXPR_ERROR_NOERROR;
}
else
{
return EXPR_ERROR_OUTOFRANGE;
}
}
</pre>
</td>
</tr>
<tr>
<td>EXPR_CLEARMATHERR()</td>
<td>Clear errno.</td>
<td>
<pre>
errno = 0;
</pre>
</td>
</tr>
<tr>
<td>EXPR_RETURNSOFTERR(s_err)</td>
<td>If soft errors are on, set *val to 0.0 and
return EXPR_ERROR_NOERROR. Else return e.</td>
<td>
<pre>
if(exprGetSoftErrors(o))
{
*val = 0.0;
return EXPR_ERROR_NOERROR;
}
else
{
return s_err;
}
</pre>
</td>
</tr>
<tr>
<td>EXPR_CHECKBREAK()</td>
<td>If breaker function returns nonzero, stop</td>
<td>
<pre>
if(exprGetBreakResult(o))
{
return EXPR_ERROR_BREAK;
}
</pre>
</td>
</tr>
<tr>
<td>EXPR_FUNCTIONSOLVER(name)</td>
<td>Make creating function solvers easier</td>
<td>
<pre>
int func_name##(struct _exprObj *o, struct _exprNode *n, int count, EXPRTYPE **refitems, int refcount, EXPRTYPE *val)
</pre>
</td>
</tr>
</table>
<p>If you use any of these macros inside any conditional or
loop, make sure you put them in braces so it will work right.<p>
<p><b>Correct example:</b>
<ul>
<pre>
if(d2 == 0.0)
{
EXPR_RETURNSOFTERR(EXPR_ERROR_OUTOFRANGE);
}
</pre>
</ul>
</p>
<p><b>Incorrect example:</b>
<ul>
<pre>
if(d2 == 0.0)
EXPR_RETURNSOFTERR(EXPR_ERROR_OUTOFRANGE);
/* This might not work correctly */
</pre>
</ul>
</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 for C usage</li>
<li>expreval.hpp - Include file for C++ wrappers.
No reference is provided for the C++ wrappers.
Read this file to understand how they work.
It is recommended that you make you own
wrapper classes that are better suited
to your purpose.</li>
</ul>
<p>
<p><b>Defines:</b>
<ul>
<li>EXPR_VERSIONMAJOR - Major version number of the ExprEval interface (header)</li>
<li>EXPR_VERSIONMINOR - Minor version number of the ExprEval interface (header)</li>
<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 - For C++ wrapper class, already
called Create member.</li>
<li>EXPR_ERROR_DOESNOTEXIST - For C++ wrapper calss, expression
object does not exist. Call Create member</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_OUTOFRANGE - A parameter to an expression function was
invalid for that function, or the function caused an overflow to occur</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>
</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>exprMsgFuncType - Message function pointer that can be used in custom functions
to send messages to the application. Defined as:<br>
typedef void (*exprMsgFuncType)(int type, int code, char *msg);</li>
<li>exprFuncType - Custom function type. Defined as:<br>
typedef int (*exprFuncType)(struct _exprObj *o, struct _exprNode *n, int count, EXPRTYPE **refitems, int refcount, EXPRTYPE *val);</li>
<li>exprBreakFuncType - Breaker function pointer to stop evaluation if the result is nonzero.
Defined as:<br>
typedef int (*exprBreakFuncType)(struct _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 **f);<br>
Comments:
<ul>
<li>Creates a function lists and updates a pointer to point to it</li>
</ul>
Parameters:
<ul>
<li>**f - 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 *f, exprFuncType ptr, char *name, int min, int max, int refmin, int refmax);<br>
Comments:
<ul>
<li>Adds a function to the function list</li>
</ul>
Parameters:
<ul>
<li>*f - 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 exprFuncListGet(exprFuncList *f, exprFuncType *ptr, char *name, int *min, int *max, int *refmin, int *refmax);<br>
Comments:
<ul>
<li>Get function information from the function list</li>
</ul>
Parameters:
<ul>
<li>*f - Pointer to the function list</li>
<li>*ptr - Pointer to a pointer to a custom function</li>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -