- This comparison shows the changes necessary to convert path
- /branches/Version13x/Scribus/fparser.txt @ 454
- → /branches/Version13x/Scribus/fparser.txt @ 455
- ↔ Reverse comparison

/branches/Version13x/Scribus/fparser.txt |
---|

0,0 → 1,785 |

Function parser for C++ v2.63 by Warp. |

====================================== |

Optimization code contributed by Bisqwit (http://iki.fi/bisqwit/) |

The usage license of this library is located at the end of this text file. |

What's new in v2.63 |

------------------- |

- Some tiny fixes to make the library more compatible with BCB4. |

What's new in v2.62 |

------------------- |

- Only an addition to the usage license. (Please read it.) |

What's new in v2.61 |

------------------- |

- Tiny bug fix: Tabs and carriage returns now allowed in the function |

string. |

What's new in v2.6 |

------------------- |

- Added a new method: GetParseErrorType(). This method can be used to |

get the type of parsing error (which can be used eg. for customized |

error messages in another language). |

- Added working copy constructor and assignment operator (using the |

copy-on-write technique for efficiency). See the "Usage" section for |

details. |

- Fixed a problem with the comma operator (,): Comma is not allowed |

anymore anywhere else than separating function parameters. In other |

words, comma is not an operator anymore (just a parameter separator). |

============================================================================= |

- Preface |

============================================================================= |

Often people need to ask some mathematical expression from the user and |

then evaluate values for that expression. The simplest example is a program |

which draws the graphic of a user-defined function on screen. |

This library adds C-style function string parsing to the program. This |

means that you can evaluate the string "sqrt(1-x^2+y^2)" with given values |

of 'x' and 'y'. |

The library is intended to be very fast. It byte-compiles the function |

string at parse time and interpretes this byte-code at evaluation time. |

The evaluation is straightforward and no recursions are done (uses stack |

arithmetic). |

Empirical tests show that it indeed is very fast (specially compared to |

libraries which evaluate functions by just interpreting the raw function |

string). |

The library is made in ISO C++ and requires a standard-conforming C++ |

compiler. |

============================================================================= |

- Usage |

============================================================================= |

To use the FunctionParser class, you have to include "fparser.hh". When |

compiling, you have to compile fparser.cc and link it to the main program. |

You can also make a library from the fparser.cc (see the help on your |

compiler to see how this is done). |

* Conditional compiling: |

--------------------- |

There is a set of precompiler options at the beginning of fparser.cc |

which can be used for setting certain features on or off. These lines |

can be commented or uncommented depending on the desired behaviour: |

NO_ASINH : (Default on) |

By default the library does not support the asinh(), acosh() |

and atanh() functions because they are not part of the ISO C++ |

standard. If your compiler supports them and you want the |

parser to support them as well, comment this line. |

DISABLE_EVAL : (Default off) |

The eval() function can be dangerous because it can cause an |

infinite recursion in the parser when not used properly (which |

causes the function stack created by the compiler to overflow). |

If this possibility should be prevented then the eval() function |

can be disabled completely by uncommenting this line. |

SUPPORT_OPTIMIZER : (Default on) |

If you are not going to use the Optimize() method, you can comment |

this line out to speed-up the compilation of fparser.cc a bit, as |

well as making the binary a bit smaller. (Optimize() can still be |

called, but it will not do anything.) |

* Copying and assignment: |

---------------------- |

The class implements a safe copy constructor and assignment operator. |

It uses the copy-on-write technique for efficiency. This means that |

when copying or assigning a FunctionParser instance, the internal data |

(which in some cases can be quite lengthy) is not immediately copied |

but only when the contents of the copy (or the original) are changed. |

This means that copying/assigning is a very fast operation, and if |

the copies are never modified then actual data copying never happens |

either. |

The Eval() and EvalError() methods of the copy can be called without |

the internal data being copied. |

Calling Parse(), Optimize() or the user-defined constant/function adding |

methods will cause a deep-copy. |

(C++ basics: The copy constructor is called when a new FunctionParser |

instance is initialized with another, ie. like: |

FunctionParser fp2 = fp1; // or: FunctionParser fp2(fp1); |

or when a function takes a FunctionParser instance as parameter, eg: |

void foo(FunctionParser p) // takes an instance of FunctionParser |

{ ... } |

The assignment operator is called when a FunctionParser instance is |

assigned to another, like "fp2 = fp1;".) |

* Short descriptions of FunctionParser methods: |

-------------------------------------------- |

int Parse(const std::string& Function, const std::string& Vars, |

bool useDegrees = false); |

Parses the given function and compiles it to internal format. |

Return value is -1 if successful, else the index value to the location |

of the error. |

const char* ErrorMsg(void) const; |

Returns an error message corresponding to the error in Parse(), or 0 if |

no such error occurred. |

ParseErrorType GetParseErrorType() const; |

Returns the type of parsing error which occurred. Possible return types |

are described in the long description. |

double Eval(const double* Vars); |

Evaluates the function given to Parse(). |

int EvalError(void) const; |

Returns 0 if no error happened in the previous call to Eval(), else an |

error code >0. |

void Optimize(); |

Tries to optimize the bytecode for faster evaluation. |

bool AddConstant(const std::string& name, double value); |

Add a constant to the parser. Returns false if the name of the constant |

is invalid, else true. |

bool AddFunction(const std::string& name, |

double (*functionPtr)(const double*), |

unsigned paramsAmount); |

Add a user-defined function to the parser (as a function pointer). |

Returns false if the name of the function is invalid, else true. |

bool AddFunction(const std::string& name, FunctionParser&); |

Add a user-defined function to the parser (as a FunctionParser instance). |

Returns false if the name of the function is invalid, else true. |

* Long descriptions of FunctionParser methods: |

------------------------------------------- |

--------------------------------------------------------------------------- |

int Parse(const std::string& Function, const std::string& Vars, |

bool useDegrees = false); |

--------------------------------------------------------------------------- |

Parses the given function (and compiles it to internal format). |

Destroys previous function. Following calls to Eval() will evaluate |

the given function. |

The strings given as parameters are not needed anymore after parsing. |

Parameters: |

Function : String containing the function to parse. |

Vars : String containing the variable names, separated by commas. |

Eg. "x,y", "VarX,VarY,VarZ,n" or "x1,x2,x3,x4,__VAR__". |

useDegrees: (Optional.) Whether to use degrees or radians in |

trigonometric functions. (Default: radians) |

Variables can have any size and they are case sensitive (ie. "var", |

"VAR" and "Var" are *different* variable names). Letters, digits and |

underscores can be used in variable names, but the name of a variable |

can't begin with a digit. Each variable name can appear only once in |

the string. Function names are not legal variable names. |

Using longer variable names causes no overhead whatsoever to the Eval() |

method, so it's completely safe to use variable names of any size. |

The third, optional parameter specifies whether angles should be |

interpreted as radians or degrees in trigonometrical functions. |

If not specified, the default value is radians. |

Return values: |

-On success the function returns -1. |

-On error the function returns an index to where the error was found |

(0 is the first character, 1 the second, etc). If the error was not |

a parsing error returns an index to the end of the string + 1. |

Example: parser.Parse("3*x+y", "x,y"); |

--------------------------------------------------------------------------- |

const char* ErrorMsg(void) const; |

--------------------------------------------------------------------------- |

Returns a pointer to an error message string corresponding to the error |

caused by Parse() (you can use this to print the proper error message to |

the user). If no such error has occurred, returns 0. |

--------------------------------------------------------------------------- |

ParseErrorType GetParseErrorType() const; |

--------------------------------------------------------------------------- |

Returns the type of parse error which occurred. |

This method can be used to get the error type if ErrorMsg() is not |

enough for printing the error message. In other words, this can be |

used for printing customized error messages (eg. in another language). |

If the default error messages suffice, then this method doesn't need |

to be called. |

FunctionParser::ParseErrorType is an enumerated type inside the class |

(ie. its values are accessed like "FunctionParser::SYNTAX_ERROR"). |

The possible values for FunctionParser::ParseErrorType are listed below, |

along with their equivalent error message returned by the ErrorMsg() |

method: |

FP_NO_ERROR : If no error occurred in the previous call to Parse(). |

SYNTAX_ERROR : "Syntax error" |

MISM_PARENTH : "Mismatched parenthesis" |

MISSING_PARENTH : "Missing ')'" |

EMPTY_PARENTH : "Empty parentheses" |

EXPECT_OPERATOR : "Syntax error: Operator expected" |

OUT_OF_MEMORY : "Not enough memory" |

UNEXPECTED_ERROR : "An unexpected error ocurred. Please make a full bug " |

"report to warp@iki.fi" |

INVALID_VARS : "Syntax error in parameter 'Vars' given to " |

"FunctionParser::Parse()" |

ILL_PARAMS_AMOUNT : "Illegal number of parameters to function" |

PREMATURE_EOS : "Syntax error: Premature end of string" |

EXPECT_PARENTH_FUNC: "Syntax error: Expecting ( after function" |

--------------------------------------------------------------------------- |

double Eval(const double* Vars); |

--------------------------------------------------------------------------- |

Evaluates the function given to Parse(). |

The array given as parameter must contain the same amount of values as |

the amount of variables given to Parse(). Each value corresponds to each |

variable, in the same order. |

Return values: |

-On success returns the evaluated value of the function given to |

Parse(). |

-On error (such as division by 0) the return value is unspecified, |

probably 0. |

Example: |

double Vars[] = {1, -2.5}; |

double result = parser.Eval(Vars); |

--------------------------------------------------------------------------- |

int EvalError(void) const; |

--------------------------------------------------------------------------- |

Used to test if the call to Eval() succeeded. |

Return values: |

If there was no error in the previous call to Eval(), returns 0, |

else returns a positive value as follows: |

1: division by zero |

2: sqrt error (sqrt of a negative value) |

3: log error (logarithm of a negative value) |

4: trigonometric error (asin or acos of illegal value) |

--------------------------------------------------------------------------- |

void Optimize(); |

--------------------------------------------------------------------------- |

This method can be called after calling the Parse() method. It will try |

to simplify the internal bytecode so that it will evaluate faster (it |

tries to reduce the amount of opcodes in the bytecode). |

For example, the bytecode for the function "5+x*y-25*4/8" will be |

reduced to a bytecode equivalent to the function "x*y-7.5" (the original |

11 opcodes will be reduced to 5). Besides calculating constant expressions |

(like in the example), it also performs other types of simplifications |

with variable and function expressions. |

This method is quite slow and the decision of whether to use it or |

not should depend on the type of application. If a function is parsed |

once and evaluated millions of times, then calling Optimize() may speed-up |

noticeably. However, if there are tons of functions to parse and each one |

is evaluated once or just a few times, then calling Optimize() will only |

slow down the program. |

Also, if the original function is expected to be optimal, then calling |

Optimize() would be useless. |

Note: Currently this method does not make any checks (like Eval() does) |

and thus things like "1/0" will cause undefined behaviour. (On the other |

hand, if such expression is given to the parser, Eval() will always give |

an error code, no matter what the parameters.) If caching this type of |

errors is important, a work-around is to call Eval() once before calling |

Optimize() and checking EvalError(). |

If the destination application is not going to use this method, |

the compiler constant SUPPORT_OPTIMIZER can be undefined at the beginning |

of fparser.cc to make the library smaller (Optimize() can still be called, |

but it will not do anything). |

(If you are interested in seeing how this method optimizes the opcode, |

you can call the PrintByteCode() method before and after the call to |

Optimize() to see the difference.) |

--------------------------------------------------------------------------- |

bool AddConstant(const std::string& name, double value); |

--------------------------------------------------------------------------- |

This method can be used to add constants to the parser. Syntactically |

constants are identical to variables (ie. they follow the same naming |

rules and they can be used in the function string in the same way as |

variables), but internally constants are directly replaced with their |

value at parse time. |

Constants used by a function must be added before calling Parse() |

for that function. Constants are preserved between Parse() calls in |

the current FunctionParser instance, so they don't need to be added |

but once. (If you use the same constant in several instances of |

FunctionParser, you will need to add it to all the instances separately.) |

Constants can be added at any time and the value of old constants can |

be changed, but new additions and changes will only have effect the next |

time Parse() is called. (That is, changing the value of a constant |

after calling Parse() and before calling Eval() will have no effect.) |

The return value will be false if the 'name' of the constant was |

illegal, else true. If the name was illegal, the method does nothing. |

Example: parser.AddConstant("pi", 3.14159265); |

Now for example parser.Parse("x*pi", "x"); will be identical to the |

call parser.Parse("x*3.14159265", "x"); |

--------------------------------------------------------------------------- |

bool AddFunction(const std::string& name, |

double (*functionPtr)(const double*), |

unsigned paramsAmount); |

--------------------------------------------------------------------------- |

This method can be used to add new functions to the parser. For example, |

if you would like to add a function "sqr(A)" which squares the value |

of A, you can do it with this method (so that you don't need to touch |

the source code of the parser). |

The method takes three parameters: |

- The name of the function. The name follows the same naming conventions |

as variable names. |

- A C++ function, which will be called when evaluating the function |

string (if the user-given function is called there). The C++ function |

must have the form: |

double functionName(const double* params); |

- The number of parameters the function takes. NOTE: Currently this |

value must be at least 1; the parser does not support functions which |

take no parameters (this problem may be fixed in the future). |

The return value will be false if the given name was invalid (either it |

did not follow the variable naming conventions, or the name was already |

reserved), else true. If the return value is false, nothing is added. |

Example: |

Suppose we have a C++ function like this: |

double Square(const double* p) |

{ |

return p[0]*p[0]; |

} |

Now we can add this function to the parser like this: |

parser.AddFunction("sqr", Square, 1); |

parser.Parse("2*sqr(x)", "x"); |

IMPORTANT NOTE: If you use the Optimize() method, it will assume that |

the user-given function has no side-effects, that is, it always |

returns the same value for the same parameters. The optimizer will |

optimize the function call away in some cases, making this assumption. |

--------------------------------------------------------------------------- |

bool AddFunction(const std::string& name, FunctionParser&); |

--------------------------------------------------------------------------- |

This method is almost identical to the previous AddFunction(), but |

instead of taking a C++ function, it takes another FunctionParser |

instance. |

There are some important restrictions on making a FunctionParser instance |

call another: |

- The FunctionParser instance given as parameter must be initialized |

with a Parse() call before giving it as parameter. That is, if you |

want to use the parser A in the parser B, you must call A.Parse() |

before you can call B.AddFunction("name", A). |

- The amount of parameters in the FunctionParser instance given as |

parameter must not change after it has been given to the AddFunction() |

of another instance. Changing the number of parameters will result in |

malfunction. |

- AddFunction() will fail (ie. return false) if a recursive loop is |

formed. The method specifically checks that no such loop is built. |

- As with the other AddFunction(), the number of parameters taken by |

the user-defined function must be at least 1 (this may be fixed in |

the future). |

Example: |

FunctionParser f1, f2; |

f1.Parse("x*x", "x"); |

f2.AddFunction("sqr", f1); |

--------------------------------------------------------------------------- |

Example program: |

#include "fparser.hh" |

#include <iostream> |

int main() |

{ |

FunctionParser fp; |

int ret = fp.Parse("x+y-1", "x,y"); |

if(ret >= 0) |

{ |

std::cerr << "At col " << ret << ": " << fp.ErrorMsg() << std::endl; |

return 1; |

} |

double vals[] = { 4, 8 }; |

std::cout << fp.Eval(vals) << std::endl; |

} |

============================================================================= |

- The function string |

============================================================================= |

The function string understood by the class is very similar to the C-syntax. |

Arithmetic float expressions can be created from float literals, variables |

or functions using the following operators in this order of precedence: |

() expressions in parentheses first |

-A unary minus |

A^B exponentiation (A raised to the power B) |

A*B A/B A%B multiplication, division and modulo |

A+B A-B addition and subtraction |

A=B A<B A>B comparison between A and B (result is either 0 or 1) |

A&B result is 1 if int(A) and int(B) differ from 0, else 0. |

A|B result is 1 if int(A) or int(B) differ from 0, else 0. |

Since the unary minus has higher precedence than any other operator, for |

example the following expression is valid: x*-y |

Note that the '=' comparison can be inaccurate due to floating point |

precision problems (eg. "sqrt(100)=10" probably returns 0, not 1). |

The class supports these functions: |

abs(A) : Absolute value of A. If A is negative, returns -A otherwise |

returns A. |

acos(A) : Arc-cosine of A. Returns the angle, measured in radians, |

whose cosine is A. |

acosh(A) : Same as acos() but for hyperbolic cosine. |

asin(A) : Arc-sine of A. Returns the angle, measured in radians, whose |

sine is A. |

asinh(A) : Same as asin() but for hyperbolic sine. |

atan(A) : Arc-tangent of (A). Returns the angle, measured in radians, |

whose tangent is (A). |

atan2(A,B): Arc-tangent of A/B. The two main differences to atan() is |

that it will return the right angle depending on the signs of |

A and B (atan() can only return values betwen -pi/2 and pi/2), |

and that the return value of pi/2 and -pi/2 are possible. |

atanh(A) : Same as atan() but for hyperbolic tangent. |

ceil(A) : Ceiling of A. Returns the smallest integer greater than A. |

Rounds up to the next higher integer. |

cos(A) : Cosine of A. Returns the cosine of the angle A, where A is |

measured in radians. |

cosh(A) : Same as cos() but for hyperbolic cosine. |

cot(A) : Cotangent of A (equivalent to 1/tan(A)). |

csc(A) : Cosecant of A (equivalent to 1/sin(A)). |

eval(...) : This a recursive call to the function to be evaluated. The |

number of parameters must be the same as the number of parameters |

taken by the function. Usually called inside if() to avoid |

infinite recursion. |

exp(A) : Exponential of A. Returns the value of e raised to the power |

A where e is the base of the natural logarithm, i.e. the |

non-repeating value approximately equal to 2.71828182846. |

floor(A) : Floor of A. Returns the largest integer less than A. Rounds |

down to the next lower integer. |

if(A,B,C) : If int(A) differs from 0, the return value of this function is B, |

else C. Only the parameter which needs to be evaluated is |

evaluated, the other parameter is skipped; this makes it safe to |

use eval() in them. |

int(A) : Rounds A to the closest integer. 0.5 is rounded to 1. |

log(A) : Natural (base e) logarithm of A. |

log10(A) : Base 10 logarithm of A. |

max(A,B) : If A>B, the result is A, else B. |

min(A,B) : If A<B, the result is A, else B. |

sec(A) : Secant of A (equivalent to 1/cos(A)). |

sin(A) : Sine of A. Returns the sine of the angle A, where A is |

measured in radians. |

sinh(A) : Same as sin() but for hyperbolic sine. |

sqrt(A) : Square root of A. Returns the value whose square is A. |

tan(A) : Tangent of A. Returns the tangent of the angle A, where A |

is measured in radians. |

tanh(A) : Same as tan() but for hyperbolic tangent. |

Examples of function string understood by the class: |

"1+2" |

"x-1" |

"-sin(sqrt(x^2+y^2))" |

"sqrt(XCoord*XCoord + YCoord*YCoord)" |

An example of a recursive function is the factorial function: |

"if(n>1, n*eval(n-1), 1)" |

Note that a recursive call has some overhead, which makes it a bit slower |

than any other operation. It may be a good idea to avoid recursive functions |

in very time-critical applications. Recursion also takes some memory, so |

extremely deep recursions should be avoided (eg. millions of nested recursive |

calls). |

Also note that the if() function is the only place where making a recursive |

call is safe. In any other place it will cause an infinite recursion (which |

will make the program eventually run out of memory). If this is something |

which should be avoided, it may be a good idea to disable the eval() |

function completely. |

The eval() function can be disabled with the DISABLE_EVAL precompiler |

constant (see the beginning of fparser.cc). |

============================================================================= |

- Contacting the author |

============================================================================= |

Any comments, bug reports, etc. should be sent to warp@iki.fi |

============================================================================= |

- The algorithm used in the library |

============================================================================= |

The whole idea behind the algorithm is to convert the regular infix |

format (the regular syntax for mathematical operations in most languages, |

like C and the input of the library) to postfix format. The postfix format |

is also called stack arithmetic since an expression in postfix format |

can be evaluated using a stack and operating with the top of the stack. |

For example: |

infix postfix |

2+3 2 3 + |

1+2+3 1 2 + 3 + |

5*2+8/2 5 2 * 8 2 / + |

(5+9)*3 5 9 + 3 * |

The postfix notation should be read in this way: |

Let's take for example the expression: 5 2 * 8 2 / + |

- Put 5 on the stack |

- Put 2 on the stack |

- Multiply the two values on the top of the stack and put the result on |

the stack (removing the two old values) |

- Put 8 on the stack |

- Put 2 on the stack |

- Divide the two values on the top of the stack |

- Add the two values on the top of the stack (which are in this case |

the result of 5*2 and 8/2, that is, 10 and 4). |

At the end there's only one value in the stack, and that value is the |

result of the expression. |

Why stack arithmetic? |

The last example above can give you a hint. |

In infix format operators have precedence and we have to use parentheses to |

group operations with lower precedence to be calculated before operations |

with higher precedence. |

This causes a problem when evaluating an infix expression, specially |

when converting it to byte code. For example in this kind of expression: |

(x+1)/(y+2) |

we have to calculate first the two additions before we can calculate the |

division. We have to also keep counting parentheses, since there can be |

a countless amount of nested parentheses. This usually means that you |

have to do some type of recursion. |

The most simple and efficient way of calculating this is to convert it |

to postfix notation. |

The postfix notation has the advantage that you can make all operations |

in a straightforward way. You just evaluate the expression from left to |

right, applying each operation directly and that's it. There are no |

parentheses to worry about. You don't need recursion anywhere. |

You have to keep a stack, of course, but that's extremely easily done. |

Also you just operate with the top of the stack, which makes it very easy. |

You never have to go deeper than 2 items in the stack. |

And even better: Evaluating an expression in postfix format is never |

slower than in infix format. All the contrary, in many cases it's a lot |

faster (eg. because all parentheses are optimized away). |

The above example could be expressed in postfix format: |

x 1 + y 2 + / |

The good thing about the postfix notation is also the fact that it can |

be extremely easily expressed in bytecode form. |

You only need a byte value for each operation, for each variable and |

to push a constant to the stack. |

Then you can interpret this bytecode straightforwardly. You just interpret |

it byte by byte, from the beginning to the end. You never have to go back, |

make loops or anything. |

This is what makes byte-coded stack arithmetic so fast. |

============================================================================= |

Usage license: |

============================================================================= |

Copyright © 2003 Juha Nieminen, Joel Yliluoma |

This library is distributed under two distinct usage licenses depending |

on the software ("Software" below) which uses the Function Parser library |

("Library" below). |

The reason for having two distinct usage licenses is to make the library |

compatible with the GPL license while still being usable in other non-GPL |

(even commercial) software. |

A) If the Software using the Library is distributed under the GPL license, |

then the Library can be used under the GPL license as well. |

The Library will be under the GPL license only when used with the |

Software. If the Library is separated from the Software and used in |

another different software under a different license, then the Library |

will have the B) license below. |

Exception to the above: If the Library is modified for the GPL Software, |

then the Library cannot be used with the B) license without the express |

permission of the author of the modifications. A modified library will |

be under the GPL license by default. That is, only the original, |

unmodified version of the Library can be taken to another software |

with the B) license below. |

The author of the Software should provide an URL to the original |

version of the Library if the one used in the Software has been |

modified. (http://iki.fi/warp/FunctionParser/) |

This text file must be distributed in its original intact form along |

with the sources of the Library. (Documentation about possible |

modifications to the library should be put in a different text file.) |

B) If the Software using the Library is not distributed under the GPL |

license but under any other license, then the following usage license |

applies to the Library: |

1. This library is free for non-commercial usage. You can do whatever you |

like with it as long as you don't claim you made it yourself. |

2. It is possible to use this library in a commercial program, but in this |

case you MUST contact me first (warp@iki.fi) and ask express permission |

for this. (Read explanation at the end of the file.) |

If you are making a free program or a shareware program with just a |

nominal price (5 US dollars or less), you don't have to ask for |

permission. |

In any case, I DON'T WANT MONEY for the usage of this library. It is |

free, period. |

3. You can make any modifications you want to it so that it conforms your |

needs. If you make modifications to it, you have, of course, credits for |

the modified parts. |

4. If you use this library in your own program, you don't have to provide |

the source code if you don't want to (ie. the source code of your program |

or this library). |

If you DO include the source code for this library, this text file |

must be included in its original intact form. |

5. If you distribute a program which uses this library, and specially if you |

provide the source code, proper credits MUST be included. Trying to |

obfuscate the fact that this library is not made by you or that it is |

free is expressly prohibited. When crediting the usage of this library, |

it's enough to include my name and email address, that is: |

"Juha Nieminen (warp@iki.fi)". Also a URL to the library download page |

would be nice, although not required. The official URL is: |

http://iki.fi/warp/FunctionParser/ |

6. And the necessary "lawyer stuff": |

The above copyright notice and this permission notice shall be |

included in all copies or substantial portions of the Software. |

The software is provided "as is", without warranty of any kind, |

express or implied, including but not limited to the warranties of |

merchantability, fitness for a particular purpose and noninfringement. |

In no event shall the authors or copyright holders be liable for any |

claim, damages or other liability, whether in an action of contract, |

tort or otherwise, arising from, out of or in connection with the |

software or the use or other dealings in the software. |

--- Explanation of the section 2 of the B) license above: |

The section 2 tries to define "fair use" of the library in commercial |

programs. |

"Fair use" of the library means that the program is not heavily dependent |

on the library, but the library only provides a minor secondary feature |

to the program. |

"Heavily dependent" means that the program depends so much on the library |

that without it the functionality of the program would be seriously |

degraded or the program would even become completely non-functional. |

In other words: If the program does not depend heavily on the library, |

that is, the library only provides a minor secondary feature which could |

be removed without the program being degraded in any considerable way, |

then it's OK to use the library in the commercial program. |

If, however, the program depends so heavily on the library that |

removing it would make the program non-functional or degrade its |

functionality considerably, then it's NOT OK to use the library. |

The ideology behind this is that it's not fair to use a free library |

as a base for a commercial program, but it's fair if the library is |

just a minor, unimportant extra. |

If you are going to ask me for permission to use the library in a |

commercial program, please describe the feature which the library will |

be providing and how important it is to the program. |

Property changes: |

Added: svn:eol-style |

## -0,0 +1 ## |

+native |

\ No newline at end of property |

Added: svn:keywords |

## -0,0 +1 ## |

+Author Date Id Revision |

\ No newline at end of property |