]> https://gitweb.dealii.org/ - dealii.git/commitdiff
first shot at bundling muparser
authorTimo Heister <timo.heister@gmail.com>
Thu, 6 Feb 2014 13:59:53 +0000 (13:59 +0000)
committerTimo Heister <timo.heister@gmail.com>
Thu, 6 Feb 2014 13:59:53 +0000 (13:59 +0000)
git-svn-id: https://svn.dealii.org/branches/branch_muparser@32417 0785d39b-7218-0410-832d-ea1e28bc413d

29 files changed:
deal.II/bundled/CMakeLists.txt
deal.II/bundled/muparser_v2_2_3/CMakeLists.txt [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/Changes.txt [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/License.txt [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParser.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserBase.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserBytecode.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserCallback.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserDLL.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserDef.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserError.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserFixes.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserInt.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserStack.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserTemplateMagic.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserTest.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserToken.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/include/muParserTokenReader.h [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParser.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserBase.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserBytecode.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserCallback.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserDLL.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserError.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserInt.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserTest.cpp [new file with mode: 0644]
deal.II/bundled/muparser_v2_2_3/src/muParserTokenReader.cpp [new file with mode: 0644]
deal.II/bundled/setup_bundled.cmake
deal.II/cmake/configure/configure_muparser.cmake

index 68855752ccaa0c2d1c8013a0ab6da2f9935fadc6..c3469a5d3ca2f02fc989797757ad1e272de2a1b2 100644 (file)
@@ -42,9 +42,9 @@ IF(FEATURE_BOOST_BUNDLED_CONFIGURED)
 ENDIF()
 
 
-IF(FEATURE_FUNCTIONPARSER_BUNDLED_CONFIGURED)
-  ADD_SUBDIRECTORY(${FUNCTIONPARSER_FOLDER})
-ENDIF()
+#IF(FEATURE_FUNCTIONPARSER_BUNDLED_CONFIGURED)
+#  ADD_SUBDIRECTORY(${FUNCTIONPARSER_FOLDER})
+#ENDIF()
 
 
 IF(FEATURE_THREADS_BUNDLED_CONFIGURED)
@@ -65,4 +65,10 @@ IF(FEATURE_UMFPACK_BUNDLED_CONFIGURED)
 ENDIF()
 
 
+IF(FEATURE_MUPARSER_BUNDLED_CONFIGURED)
+  ADD_SUBDIRECTORY(${MUPARSER_FOLDER})
+ENDIF()
+
+
+
 MESSAGE(STATUS "Setting up bundled features - Done")
diff --git a/deal.II/bundled/muparser_v2_2_3/CMakeLists.txt b/deal.II/bundled/muparser_v2_2_3/CMakeLists.txt
new file mode 100644 (file)
index 0000000..fdf48b3
--- /dev/null
@@ -0,0 +1,41 @@
+## ---------------------------------------------------------------------
+## $Id: CMakeLists.txt 32392 2014-02-03 16:24:36Z heister $
+##
+## Copyright (C) 2012 - 2013 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# avoid some annoying warnings...
+#
+STRIP_FLAG(DEAL_II_CXX_FLAGS "-Wall")
+STRIP_FLAG(DEAL_II_CXX_FLAGS "-pedantic")
+ENABLE_IF_SUPPORTED(DEAL_II_CXX_FLAGS -Wno-switch)
+
+INCLUDE_DIRECTORIES(
+  include/
+)
+
+DEAL_II_ADD_LIBRARY(obj_muparser OBJECT
+src/muParserBase.cpp
+src/muParserBytecode.cpp
+src/muParserCallback.cpp
+src/muParser.cpp
+src/muParserError.cpp
+src/muParserInt.cpp
+src/muParserTest.cpp
+src/muParserTokenReader.cpp
+  )
+
+#IF(DEAL_II_WITH_THREADS)
+#  DEAL_II_ADD_DEFINITIONS(obj_muparser "FP_USE_THREAD_SAFE_EVAL")
+#ENDIF()
diff --git a/deal.II/bundled/muparser_v2_2_3/Changes.txt b/deal.II/bundled/muparser_v2_2_3/Changes.txt
new file mode 100644 (file)
index 0000000..26d40ae
--- /dev/null
@@ -0,0 +1,531 @@
+#######################################################################\r
+#                                                                     #\r
+#                                                                     #\r
+#                 __________                                          #\r
+#    _____   __ __\______   \_____  _______  ______  ____ _______     #\r
+#   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \    #\r
+#  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/    #\r
+#  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|       #\r
+#        \/                       \/            \/      \/            #\r
+#                                        Fast math parser Library    #\r
+#                                                                     #\r
+#  Copyright (C) 2013 Ingo Berg                                       #\r
+#                                                                     #\r
+#  Web:     muparser.beltoforion.de                                   #\r
+#  e-mail:  muparser@beltoforion.de                                   #\r
+#                                                                     #\r
+#                                                                     #\r
+#######################################################################\r
+\r
+\r
+History:\r
+--------\r
+\r
+Rev 2.2.3: 22.12.2012\r
+---------------------\r
+\r
+  Removed features:\r
+   * build files for msvc2005, borland and watcom compiler were removed\r
+\r
+  Bugfixes:\r
+   * Bugfix for Intel Compilers added: The power operator did not work properly \r
+     with Intel C++ composer XE 2011.\r
+     (see https://sourceforge.net/projects/muparser/forums/forum/462843/topic/5117983/index/page/1)\r
+   * Issue 3509860: Callbacks of functions with string parameters called twice\r
+     (see http://sourceforge.net/tracker/?func=detail&aid=3509860&group_id=137191&atid=737979)\r
+   * Issue 3570423: example1 shows slot number in hexadecimal\r
+     (see https://sourceforge.net/tracker/?func=detail&aid=3570423&group_id=137191&atid=737979)\r
+   * Fixes for compiling with the "MUP_MATH_EXCEPTIONS" macro definition:\r
+       - division by zero in constant expressions was reported with the code "ec_GENERIC" \r
+          instead of "ecDIV_BY_ZERO"\r
+        - added throwing of "ecDOMAIN_ERROR" to sqrt and log functions\r
+\r
+\r
+Rev 2.2.2: 18.02.2012\r
+---------------------\r
+  Bugfixes:\r
+   * Optimizer did'nt work properly for division:\r
+     (see https://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825)\r
+\r
+Rev 2.2.1: 22.01.2012\r
+---------------------\r
+  Bugfixes:\r
+   * Optimizer bug in 64 bit systems fixed\r
+     (see https://sourceforge.net/projects/muparser/forums/forum/462843/topic/4977977/index/page/1)\r
+        \r
+Rev 2.2.0: 22.01.2012\r
+---------------------\r
+  Improvements:\r
+   * Optimizer rewritten and improved. In general: more optimizations are \r
+     now applied to the bytecode. The downside is that callback Functions \r
+     can no longer be flagged as non-optimizable. (The flag is still present \r
+     but ignored) This is necessary since the optimizer had to call the \r
+     functions in order to precalculate the result (see Bugfixes). These calls \r
+     posed a problems for callback functions with side  effects and if-then-else \r
+     clauses in general since they undermined the shortcut evaluation prinziple.\r
+\r
+  Bugfixes:\r
+   * Infix operators where not properly detected in the presence of a constant \r
+     name starting with an underscore which is a valid character for infix \r
+     operators too (i.e. "-_pi").\r
+   * Issue 3463353: Callback functions are called twice during the first call to eval.\r
+   * Issue 3447007: GetUsedVar unnecessaryly executes callback functions.\r
+\r
+\r
+Rev 2.1.0: 19.11.2011\r
+---------------------\r
+  New feature:\r
+   * Function atan2 added\r
+\r
+  Bugfixes:\r
+   * Issue 3438380:  Changed behaviour of tellg with GCC >4.6 led to failures  \r
+                     in value detection callbacks.\r
+   * Issue 3438715:  only "double" is a valid MUP_BASETYPE \r
+                     MUP_BASETYPE can now be any of:\r
+                       float, \r
+                       double, \r
+                       long double, \r
+                       short, \r
+                       unsigned short, \r
+                       unsigned int, \r
+                       long,\r
+                       unsigned long. \r
+                     Previousely only floating point types were allowed. \r
+                     Using "int" is still not allowed!\r
+   * Compiler issues with GCC 4.6 fixed\r
+   * Custom value recognition callbacks added with AddValIdent had lower\r
+     priority than built in functions. This was causing problems with \r
+     hex value recognition since detection of non hex values had priority\r
+     over the detection of hex values. The "0" in the hex prefix "0x" would \r
+     be read as a separate non-hex number leaving the rest of the expression\r
+     unparseable.\r
+\r
+Rev 2.0.0: 04.09.2011\r
+---------------------\r
+This release introduces a new version numbering scheme in order to make\r
+future changes in the ABI apparent to users of the library. The number is\r
+now based on the SONAME property as used by GNU/Linux. \r
+\r
+  Changes:\r
+   * Beginning with this version all version numbers will be SONAME compliant\r
+   * Project files for MSVC2010 added\r
+   * Project files for MSVC2003 removed\r
+   * Bytecode parsing engine cleaned up and rewritten\r
+   * Retrieving all results of expressions made up of comma separate \r
+     subexpressions is now possible with a new Eval overload.\r
+   * Callback functions with fixed number of arguments can now have up to 10 \r
+     Parameters (previous limit was 5)\r
+\r
+  New features:\r
+   * ternary if-then-else operator added (C++ like; "(...) ? ... : ..." )\r
+   * new intrinsic binary operators: "&&", "||" (logical and, or)\r
+   * A new bulkmode allows submitting large arrays as variables to compute large \r
+     numbers of expressions with a single call. This can drastically improve \r
+     parsing performance when interfacing the library from managed languages like \r
+     C#. (It doesn't bring any performance benefit for C++ users though...)\r
+\r
+  Removed features:\r
+   * intrinsic "and", "or" and "xor" operators have been removed. I'd like to let \r
+     users the freedom of defining them on their own versions (either as logical or bitwise \r
+     operators).\r
+   * Implementation for complex numbers removed. This was merely a hack. If you \r
+     need complex numbers try muParserX which provides native support for them.\r
+     (see: http://beltoforion.de/muparserx/math_expression_parser_en.html)\r
+\r
+  Bugfixes:\r
+   * User defined operators could collide with built in operators that entirely \r
+     contained their identifier. i.e. user defined "&" would not work with the built \r
+     in "&&" operator since the user defined operator was detected with a higher \r
+     priority resulting in a syntax error.\r
+   * Detection of unknown variables did not work properly in case a postfix operator\r
+     was defined which was part of the undefined variable.\r
+     i.e. If a postfix operator "m" was defined expressions like "multi*1.0" did\r
+     not detect "multi" as an undefined variable.\r
+     (Reference:  http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979)\r
+   * Postfix operators sharing the first few characters were causing bogus parsing exception.\r
+     (Reference: https://sourceforge.net/tracker/?func=detail&aid=3358571&group_id=137191&atid=737979)\r
+\r
+Rev 1.34: 04.09.2010\r
+--------------------\r
+  Changes:\r
+   * The prefix needed for parsing hex values is now "0x" and no longer "$". \r
+   * AddValIdent reintroduced into the DLL interface\r
+\r
+  New features:\r
+   * The associativity of binary operators can now be changed. The pow operator \r
+     is now right associative. (This is what Mathematica is using) \r
+   * Seperator can now be used outside of functions. This allows compound \r
+     expressions like:\r
+     "a=10,b=20,c=a*b" The last "argument" will be taken as the return value\r
+\r
+  Bugfixes:    \r
+   * The copy constructor did not copy binary operator definitions. Those were lost\r
+     in the copied parser instance.\r
+   * Mixing special characters and alphabetic characters in binary operator names \r
+     led to inconsistent parsing behaviour when parsing expressions like "a ++ b" \r
+     and "a++b" when "++" is defined as a binary operator. Binary operators must \r
+     now consist entirely of special characters or of alphabetic ones.\r
+     (original bug report: https://sourceforge.net/projects/muparser/forums/forum/462843/topic/3696881/index/page/1)\r
+   * User defined operators were not exactly handled like built in operators. This \r
+     led to inconsistencies in expression evaluation when using them. The results \r
+     differed due to slightly different precedence rules.\r
+   * Using empty string arguments ("") would cause a crash of muParser\r
+\r
+\r
+Rev 1.32: 29.01.2010 \r
+--------------------\r
+\r
+  Changes:\r
+   * "example3" renamed to "example2"\r
+   * Project/Makefiles files are now provided for:\r
+           - msvc2003 \r
+           - msvc2005 \r
+           - msvc2008\r
+           - watcom   (makefile)\r
+           - mingw    (makefile)\r
+           - bcc      (makefile)\r
+   * Project files for borland cpp builder were removed\r
+\r
+\r
+  New features:\r
+   * Added function returning muparsers version number\r
+   * Added function for resetting the locale\r
+\r
+\r
+  Bugfixes:    \r
+   * Changes example1 in order to fix issues with irritating memory leak reports. \r
+     Added conditional code for memory leak detection with MSVC in example1.\r
+     (see: http://www.codeproject.com/KB/recipes/FastMathParser.aspx?msg=3286367#xx3286367xx)\r
+   * Fixed some warnings for gcc\r
+\r
+\r
+\r
+Rev 1.31cp: 15.01.2010  (Maintainance release for CodeProject)\r
+----------------------\r
+\r
+  Changes:\r
+   * Archive structure changed\r
+   * C# wrapper added\r
+   * Fixed issued that prevented compiling with VS2010 Beta2\r
+    \r
+\r
+Rev 1.30: 09.06.2008\r
+--------------------\r
+\r
+  Changes:\r
+   * Epsilon of the numerical differentiation algorithm changed to allow greater accuracy.\r
+\r
+  New features:\r
+   * Setting thousands separator and decimal separator is now possible\r
+\r
+  Bugfixes:\r
+   * The dll interface did not provide a callback for functions without any arguments.  \r
+       \r
+\r
+Rev 1.29: Januar 2008\r
+---------------------\r
+\r
+  Unrelease Version available only via SVN.\r
+\r
+\r
+Rev 1.28: 02. July, 2007\r
+---------------------------\r
\r
+  Library changes:\r
+  * Interface for the dynamic library changed and extended to create an interface \r
+    using pure C functions only. \r
+  * mupInit() removed\r
+\r
+  Build system:\r
+   * MSVC7 Project files removed in favor of MSVC8\r
+\r
+  Bugfixes:\r
+   * The dynamic library did not build on other systems than linux due to a misplaced \r
+     preprocessor definition. This is fixed now.\r
+\r
+\r
+Rev 1.27:\r
+---------------------------\r
+\r
+  Build system:\r
+   * Modified build\ directory layout introducing some subfolders \r
+     for the various IDE supported\r
+   * Project files for BCB and MSVC7 added\r
+   * Switched to use bakefile 0.2.1 which now correctly creates the \r
+     "make uninstall" target for autoconf's Makefile.in\r
+   * Now the library debug builds are named "muparserd" instead of "muparser"\r
+     to allow multiple mixed release/debug builds to coexist; so e.g. on Windows\r
+     when building with DEBUG=1, you'll get "muparserd.lib" instead of "muparser.lib"\r
+\r
+  New Features:\r
+   * Factory functions can now take a user defined pointer\r
+   * String functions can now be used with up to two additional \r
+     double parameters\r
+   * Support for UNICODE character types added\r
+   * Infix operator priority can now be changed by the user\r
+\r
+  Bugfixes:\r
+   * An internal error was raised when evaluating an empty \r
+     expressions\r
+   * The error message raised in case of name collisions between \r
+     implicitely defined variables and postfix operators did contain\r
+     misleading data.\r
+\r
+\r
+Rev 1.26: (unofficial release)\r
+------------------------------\r
+\r
+  New Features:\r
+   * Unary operator precedence can now be changed by the user.\r
+\r
+\r
+Rev 1.25: 5. February, 2006\r
+---------------------------\r
+\r
+  Build system: (special thanks to Francesco Montorsi for implementing it!)\r
+    * created a bakefile-based build system which adds support for the following win32 compilers:\r
+      -> MS visual C++ (6 and .NET)\r
+      -> BorlandC++ (5 or greater)\r
+      -> Mingw32 (tested with gcc 3.2)\r
+      -> Watcom (not tested)\r
+      and for GCC on Unix (using a standard autoconf's configure script).\r
+\r
+  Compatibility improvements:\r
+    * fixed some small warnings when using -Wall with GCC on Unix\r
+    * added inclusion guards for win32-specific portions of code\r
+    * added fixes that remove compiler warnings on Intel C++ and the Solaris C++ compiler.\r
+\r
+\r
+Rev 1.24: 29. October, 2005\r
+---------------------------\r
+\r
+Changes:\r
+\r
+  Compatibility improvements:\r
+    * parser now works on 64 bit compilers\r
+    * (bytecode base datatype can now be changed freely)\r
+\r
+\r
+Rev 1.23: 19. October, 2005\r
+---------------------------\r
+\r
+Changes:\r
+\r
+  Bugfixes:\r
+    * Variable factory examples in Example1.cpp and Example3.cpp contained a subtle bug.\r
+\r
+  New features:\r
+    * Added a MSVC6 project file and introduced muParserFixes.h in order to make it compile with MSVC6\r
+\r
+\r
+Rev 1.22: October, 2005\r
+-----------------------\r
+\r
+Release notes:\r
+\r
+All features of Version 1.22 are similar to Version 1.21. Version 1.22 fixes a compilation issue with\r
+gcc 4.0. In order to fix this issue I rewrote part of the library to remove some unnecessary templates. \r
+This should make the code cleaner. The Borland Project files were removed. If you want to use it \r
+with Borland either use the dll version or create your own project files. I can't support it since I don't \r
+have this compiler at hand.\r
+\r
+Changes:\r
+\r
+  Project Changes:\r
+    * Borland project files removed\r
+      (The code should still compile with BCB but I cant provide you with project files)\r
+\r
+  Internal Changes:\r
+    * unnecessary template files have been removed:\r
+        - new files: muParserError.cpp, muParserTokenReader.cpp, muParserCallback.cpp\r
+        - removed Files: muIParserTypes.h\r
+\r
+\r
+Rev 1.2 / 1.21: April, 2005\r
+---------------------------\r
+\r
+Release Notes:\r
+First of all the interface has changed so this version is not backwards compatible.\r
+After receiving a couple of questions about it, this version features support for\r
+user defined binary operators. Consequently the built in operators can now be \r
+turned off, thus you can deactivate them and write complete customized parser\r
+subclasses that only contain the functionality you want. Another new feature is \r
+the introduction of callback functions taking string arguments, implicit \r
+generation of variables and the Assignement operator.\r
+\r
+  Functionality\r
+    * New built in operator: xor; Logical xor.\r
+    * New built in operator: Assignement operator; Defining variables in terms of \r
+                             other variables/constants\r
+    * New feature: Strings as arguments for callback functions\r
+    * New feature: User defined binary operators\r
+    * New feature: ParserInt a class with a sample implementation for\r
+                     integer numbers.\r
+    * New feature: Callbacks to value regognition functions.\r
+\r
+    * Removed:  all predefined postfix operators have been removed.\r
+    * New project file:  Now comes with a ready to use windows DLL.\r
+    * New project file:  Makefile for cygwin now included.\r
+    * New example:  Example3 shows usage of the DLL.\r
+\r
+  Interface changes\r
+    * New member function: DefineOprt For adding user defined binary operators.\r
+    * New member function: EnableBuiltInOprt(bool) Enables/Disables built in \r
+                           binary operators.\r
+    * New member function: AddValIdent(...) to add callbacks for custom value \r
+                           recognition functions.\r
+    * Removed: SetVar(), SetConst().\r
+    * Renamed: Most interface functions have been renamed\r
+    * Changed: The type for multiargument callbacks multfun_type has changed. \r
+               It no longer takes a std::vector as input.\r
+\r
+  Internal changes\r
+    * new class muParserTokenReader.h encapsulates the token identification \r
+      and token assignement.\r
+    * Internal handling of function callbacks unified as a result the performance \r
+      of the bytecode evaluation increased.\r
+\r
+\r
+Rev 1.10 : December 30, 2004\r
+----------------------------\r
+\r
+Release Notes:\r
+This version does not contain major new feature compared to V1.07 but its internal structure has\r
+changed significantly. The String parsing routine is slower than the one of V1.07 but bytecode\r
+parsing is equally fast. On the other hand the error messages of V1.09 are more flexible and you\r
+can change its value datatype. It should work on 64-bit systems. For this reason I supply both\r
+versions for download. If you use V1.07 and are happy with it there is no need for updating\r
+your version.\r
+\r
+    * New example program: Archive now contains two demo programs: One for standard C++ and one for\r
+                           managed C++.\r
+    * New member function: RemoveVar(...) can be used for removing a single variable from the internal \r
+                           storage.\r
+    * New member function: GetVar() can be used for querying the variable names and pointers of all\r
+                           variables defined in the parser.\r
+    * New member function: GetConst() can be used for querying all defined constants and their values.\r
+    * New member function: GetFunDef() can be used for querying all defined functions and the number of\r
+                           arguments they expect.\r
+    * Internal structure changed; hanging base datatype at compile time is now possible.\r
+    * Bugfix: Postfix operator parsing could fail in certain cases; This has been fixed now.\r
+    * Bugfix: Variable names must will now be tested if they conflict with constant or function names.\r
+    * Internal change:  Removed most dependencies from the C-string libraries.\r
+    * Internal change:  Bytecode is now stored in a separate class: ParserByteCode.h\r
+    * Internal change:  GetUsedVar() does no longer require that variables are defined at time of call.\r
+    * Internal change:  Error treatment changed. ParserException is no longer derived from\r
+                        std::runtime_error; Internal treatment of Error messages changed.\r
+    * New functions in Parser interface: ValidNameChars(), ValidOprtChars() and ValidPrefixOprtChars()\r
+                        they are used for defining the charset allowed for variable-, operator- and\r
+                        function names.\r
+\r
+\r
+Rev 1.09 : November 20, 2004\r
+----------------------------\r
+\r
+    * New member function:  RemoveVar(...) can be used for removing a single variable from the internal \r
+                            storage.\r
+    * Internal structure changed; changing base datatype at compile time is now possible.\r
+    * Bug fix: Postfix operator parsing could fail in certain cases; This has been fixed now.\r
+    * Internal change:  Removed most dependencies from the C-string libraries.\r
+    * Internal change:  Bytecode is now stored in a seperate class: ParserByteCode.h.\r
+    * Internal change:  GetUsedVar() does no longer require that variables are defined at time of call.\r
+    * Internal change:  Error treatment changed. ParserException is no longer derived from \r
+                        std::runtime_error; Internal treatment of Error messages changed.\r
+    * New functions in Parser interface; ValidNameChars(), ValidOprtChars() and ValidPrefixOprtChars()\r
+      they are used for defining the charset allowed for variable-, operator- and function names.\r
+\r
+\r
+Rev 1.08 : November, 2004 \r
+-------------------------\r
+\r
+    * unpublished; experimental template version with respect to data type and underlying string\r
+      type (string <-> widestring). The idea was dropped...\r
+\r
+\r
+Rev 1.07 : September 4 2004\r
+---------------------------\r
+\r
+    * Improved portability; Changes to make life for MSVC 6 user easier, there are probably still some\r
+      issues left.\r
+    * Improved portability; Changes in order to allow compiling on BCB.\r
+    * New function; value_type Diff(value_type *a_Var, value_type a_fPos) 4th order Differentiation with\r
+      respect to a certain variable; added in muParser.h.\r
+\r
+\r
+Rev 1.06 : August 20 2004\r
+-------------------------\r
+\r
+    * Volatile functions added; All overloaded AddFun(...) functions can now take a third parameter\r
+      indicating that the function can not be optimized.\r
+    * Internal changes: muParserStack.h simplified; refactorings\r
+    * Parser is now distributed under the MIT License; all comments changed accordingly.\r
+\r
+\r
+Rev 1.05 : August 20 2004\r
+-------------------------\r
+\r
+    * Variable/constant names will now be checked for invalid characters.\r
+    * Querying the names of all variables used in an expression is now possible; new function: GetUsedVar().\r
+    * Disabling bytecode parsing is now possible; new function: EnableByteCode(bool bStat).\r
+    * Predefined functions with variable number of arguments added: sum, avg, min, max.\r
+    * Unary prefix operators added; new functions: AddPrefixOp(...), ClearPrefixOp().\r
+    * Postfix operator interface names changed; new function names: AddPostfixOp(...), ClearPostfixOp().\r
+    * Hardcoded sign operators removed in favor of prefix operators; bytecode format changed accordingly.\r
+    * Internal changes: static array removed in Command code calculation routine; misc. changes.\r
+\r
+\r
+Rev 1.04 : August 16 2004\r
+-------------------------\r
+\r
+    * Support for functions with variable number of arguments added.\r
+    * Internal structure changed; new: ParserBase.h, ParserBase.cpp; removed: ParserException.h;\r
+      changed: Parser.h, Parser.cpp.\r
+    * Bug in the bytecode calculation function fixed (affected the unary minus operator).\r
+    * Optimizer can be deactivated; new function: EnableOptimizer(bool bStat).\r
+\r
+\r
+Rev 1.03 : August 10 2004\r
+-------------------------\r
+\r
+    * Support for user-defined unary postfix operators added; new functions: AddPostOp(), InitPostOp(),\r
+      ClearPostOp().\r
+    * Minor changes to the bytecode parsing routine.\r
+    * User defined functions can now have up to four parameters.\r
+    * Performance optimized: simple formula optimization added; (precalculation of constant parts of the\r
+      expression).\r
+    * Bug fixes: Multi-arg function parameters, constant name lookup and unary minus did not work properly.\r
+\r
+\r
+Rev 1.02 : July 30 2004\r
+-----------------------\r
+\r
+    * Support for user defined constants added; new functions: InitConst(), AddConst(), SetConst(),\r
+      ClearConst().\r
+    * Single variables can now be added using AddVar(); you have now the choice of adding them either\r
+      one by one or all at the same time using SetVar(const varmap_type &a_vVar).\r
+    * Internal handling of variables changed, is now similar to function handling.\r
+    * Virtual destructor added; InitFun(), InitConst() are now virtual too thus making it possible to\r
+      derive new parsers with a modified set of default functions and constants.\r
+    * Support for user defined functions with 2 or 3 parameters added; bytecode format changed to hold\r
+      function parameter count.\r
+\r
+\r
+Rev 1.01 : July 23 2004\r
+-----------------------\r
+\r
+    * Support for user defined functions has been added; new functions: AddFun(), ClearFun(),\r
+      InitFunctions().\r
+    * Built in constants have been removed; the parser contained undocumented built in\r
+      constants pi, e.\r
+      There was the possibility of name conflicts with user defined variables.\r
+    * Setting multiple variables with SetVar can now be done with a map of names and pointers as the only\r
+      argument. For this reason, a new type Parser::varmap_type was added. The old version that took 3\r
+      arguments (array of names, array of pointers, and array length) is now marked as deprecated.\r
+    * The names of logarithm functions have changed. The new names are: log2 for base 2, log10 or log for\r
+      base 10, and ln for base e.\r
+\r
+\r
+Rev 1.00 : July 21 2004\r
+-----------------------\r
+\r
+    * Initial release\r
diff --git a/deal.II/bundled/muparser_v2_2_3/License.txt b/deal.II/bundled/muparser_v2_2_3/License.txt
new file mode 100644 (file)
index 0000000..c4c0d2b
--- /dev/null
@@ -0,0 +1,35 @@
+#######################################################################\r
+#                                                                     #\r
+#                                                                     #\r
+#                 __________                                          #\r
+#    _____   __ __\______   \_____  _______  ______  ____ _______     #\r
+#   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \    #\r
+#  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/    #\r
+#  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|       #\r
+#        \/                       \/            \/      \/            #\r
+#                                        Fast math parser Library    #\r
+#                                                                     #\r
+#  Copyright (C) 2011 Ingo Berg                                       #\r
+#                                                                     #\r
+#  Web:     muparser.beltoforion.de                                   #\r
+#  e-mail:  muparser@beltoforion.de                                   #\r
+#                                                                     #\r
+#                                                                     #\r
+#######################################################################\r
+\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+  OR OTHER DEALINGS IN THE SOFTWARE.\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParser.h b/deal.II/bundled/muparser_v2_2_3/include/muParser.h
new file mode 100644 (file)
index 0000000..9e7bb6f
--- /dev/null
@@ -0,0 +1,114 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#ifndef MU_PARSER_H\r
+#define MU_PARSER_H\r
+\r
+//--- Standard includes ------------------------------------------------------------------------\r
+#include <vector>\r
+\r
+//--- Parser includes --------------------------------------------------------------------------\r
+#include "muParserBase.h"\r
+#include "muParserTemplateMagic.h"\r
+\r
+/** \file\r
+    \brief Definition of the standard floating point parser.\r
+*/\r
+\r
+namespace mu\r
+{\r
+  /** \brief Mathematical expressions parser.\r
+    \r
+    Standard implementation of the mathematical expressions parser. \r
+    Can be used as a reference implementation for subclassing the parser.\r
+\r
+    <small>\r
+    (C) 2011 Ingo Berg<br>\r
+    muparser(at)gmx.de\r
+    </small>\r
+  */\r
+  /* final */ class Parser : public ParserBase\r
+  {\r
+  public:\r
+\r
+    Parser();\r
+\r
+    virtual void InitCharSets();\r
+    virtual void InitFun();\r
+    virtual void InitConst();\r
+    virtual void InitOprt();\r
+    virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);\r
+\r
+    value_type Diff(value_type *a_Var, \r
+                    value_type a_fPos, \r
+                    value_type a_fEpsilon = 0) const;\r
+\r
+  protected:\r
+\r
+    // Trigonometric functions\r
+    static value_type  Sin(value_type);\r
+    static value_type  Cos(value_type);\r
+    static value_type  Tan(value_type);\r
+    static value_type  Tan2(value_type, value_type);\r
+    // arcus functions\r
+    static value_type  ASin(value_type);\r
+    static value_type  ACos(value_type);\r
+    static value_type  ATan(value_type);\r
+    static value_type  ATan2(value_type, value_type);\r
+\r
+    // hyperbolic functions\r
+    static value_type  Sinh(value_type);\r
+    static value_type  Cosh(value_type);\r
+    static value_type  Tanh(value_type);\r
+    // arcus hyperbolic functions\r
+    static value_type  ASinh(value_type);\r
+    static value_type  ACosh(value_type);\r
+    static value_type  ATanh(value_type);\r
+    // Logarithm functions\r
+    static value_type  Log2(value_type);  // Logarithm Base 2\r
+    static value_type  Log10(value_type); // Logarithm Base 10\r
+    static value_type  Ln(value_type);    // Logarithm Base e (natural logarithm)\r
+    // misc\r
+    static value_type  Exp(value_type);\r
+    static value_type  Abs(value_type);\r
+    static value_type  Sqrt(value_type);\r
+    static value_type  Rint(value_type);\r
+    static value_type  Sign(value_type);\r
+\r
+    // Prefix operators\r
+    // !!! Unary Minus is a MUST if you want to use negative signs !!!\r
+    static value_type  UnaryMinus(value_type);\r
+\r
+    // Functions with variable number of arguments\r
+    static value_type Sum(const value_type*, int);  // sum\r
+    static value_type Avg(const value_type*, int);  // mean value\r
+    static value_type Min(const value_type*, int);  // minimum\r
+    static value_type Max(const value_type*, int);  // maximum\r
+\r
+    static int IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal);\r
+  };\r
+} // namespace mu\r
+\r
+#endif\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserBase.h b/deal.II/bundled/muparser_v2_2_3/include/muParserBase.h
new file mode 100644 (file)
index 0000000..a189a26
--- /dev/null
@@ -0,0 +1,311 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#ifndef MU_PARSER_BASE_H\r
+#define MU_PARSER_BASE_H\r
+\r
+//--- Standard includes ------------------------------------------------------------------------\r
+#include <cmath>\r
+#include <string>\r
+#include <iostream>\r
+#include <map>\r
+#include <memory>\r
+#include <locale>\r
+\r
+//--- Parser includes --------------------------------------------------------------------------\r
+#include "muParserDef.h"\r
+#include "muParserStack.h"\r
+#include "muParserTokenReader.h"\r
+#include "muParserBytecode.h"\r
+#include "muParserError.h"\r
+\r
+\r
+namespace mu\r
+{\r
+/** \file\r
+    \brief This file contains the class definition of the muparser engine.\r
+*/\r
+\r
+//--------------------------------------------------------------------------------------------------\r
+/** \brief Mathematical expressions parser (base parser engine).\r
+    \author (C) 2013 Ingo Berg\r
+\r
+  This is the implementation of a bytecode based mathematical expressions parser. \r
+  The formula will be parsed from string and converted into a bytecode. \r
+  Future calculations will be done with the bytecode instead the formula string\r
+  resulting in a significant performance increase. \r
+  Complementary to a set of internally implemented functions the parser is able to handle \r
+  user defined functions and variables. \r
+*/\r
+class ParserBase \r
+{\r
+friend class ParserTokenReader;\r
+\r
+private:\r
+\r
+    /** \brief Typedef for the parse functions. \r
+    \r
+      The parse function do the actual work. The parser exchanges\r
+      the function pointer to the parser function depending on \r
+      which state it is in. (i.e. bytecode parser vs. string parser)\r
+    */\r
+    typedef value_type (ParserBase::*ParseFunction)() const;  \r
+\r
+    /** \brief Type used for storing an array of values. */\r
+    typedef std::vector<value_type> valbuf_type;\r
+\r
+    /** \brief Type for a vector of strings. */\r
+    typedef std::vector<string_type> stringbuf_type;\r
+\r
+    /** \brief Typedef for the token reader. */\r
+    typedef ParserTokenReader token_reader_type;\r
+    \r
+    /** \brief Type used for parser tokens. */\r
+    typedef ParserToken<value_type, string_type> token_type;\r
+\r
+    /** \brief Maximum number of threads spawned by OpenMP when using the bulk mode. */\r
+    static const int s_MaxNumOpenMPThreads = 4;\r
+\r
+ public:\r
+\r
+    /** \brief Type of the error class. \r
+    \r
+      Included for backwards compatibility.\r
+    */\r
+    typedef ParserError exception_type;\r
+\r
+    static void EnableDebugDump(bool bDumpCmd, bool bDumpStack);\r
+\r
+    ParserBase(); \r
+    ParserBase(const ParserBase &a_Parser);\r
+    ParserBase& operator=(const ParserBase &a_Parser);\r
+\r
+    virtual ~ParserBase();\r
+    \r
+         value_type  Eval() const;\r
+    value_type* Eval(int &nStackSize) const;\r
+    void Eval(value_type *results, int nBulkSize);\r
+\r
+    int GetNumResults() const;\r
+\r
+    void SetExpr(const string_type &a_sExpr);\r
+    void SetVarFactory(facfun_type a_pFactory, void *pUserData = NULL);\r
+\r
+    void SetDecSep(char_type cDecSep);\r
+    void SetThousandsSep(char_type cThousandsSep = 0);\r
+    void ResetLocale();\r
+\r
+    void EnableOptimizer(bool a_bIsOn=true);\r
+    void EnableBuiltInOprt(bool a_bIsOn=true);\r
+\r
+    bool HasBuiltInOprt() const;\r
+    void AddValIdent(identfun_type a_pCallback);\r
+\r
+    /** \fn void mu::ParserBase::DefineFun(const string_type &a_strName, fun_type0 a_pFun, bool a_bAllowOpt = true) \r
+        \brief Define a parser function without arguments.\r
+        \param a_strName Name of the function\r
+        \param a_pFun Pointer to the callback function\r
+        \param a_bAllowOpt A flag indicating this function may be optimized\r
+    */\r
+    template<typename T>\r
+    void DefineFun(const string_type &a_strName, T a_pFun, bool a_bAllowOpt = true)\r
+    {\r
+      AddCallback( a_strName, ParserCallback(a_pFun, a_bAllowOpt), m_FunDef, ValidNameChars() );\r
+    }\r
+\r
+    void DefineOprt(const string_type &a_strName, \r
+                    fun_type2 a_pFun, \r
+                    unsigned a_iPri=0, \r
+                    EOprtAssociativity a_eAssociativity = oaLEFT,\r
+                    bool a_bAllowOpt = false);\r
+    void DefineConst(const string_type &a_sName, value_type a_fVal);\r
+    void DefineStrConst(const string_type &a_sName, const string_type &a_strVal);\r
+    void DefineVar(const string_type &a_sName, value_type *a_fVar);\r
+    void DefinePostfixOprt(const string_type &a_strFun, fun_type1 a_pOprt, bool a_bAllowOpt=true);\r
+    void DefineInfixOprt(const string_type &a_strName, fun_type1 a_pOprt, int a_iPrec=prINFIX, bool a_bAllowOpt=true);\r
+\r
+    // Clear user defined variables, constants or functions\r
+    void ClearVar();\r
+    void ClearFun();\r
+    void ClearConst();\r
+    void ClearInfixOprt();\r
+    void ClearPostfixOprt();\r
+    void ClearOprt();\r
+    \r
+    void RemoveVar(const string_type &a_strVarName);\r
+    const varmap_type& GetUsedVar() const;\r
+    const varmap_type& GetVar() const;\r
+    const valmap_type& GetConst() const;\r
+    const string_type& GetExpr() const;\r
+    const funmap_type& GetFunDef() const;\r
+    string_type GetVersion(EParserVersionInfo eInfo = pviFULL) const;\r
+\r
+    const char_type ** GetOprtDef() const;\r
+    void DefineNameChars(const char_type *a_szCharset);\r
+    void DefineOprtChars(const char_type *a_szCharset);\r
+    void DefineInfixOprtChars(const char_type *a_szCharset);\r
+\r
+    const char_type* ValidNameChars() const;\r
+    const char_type* ValidOprtChars() const;\r
+    const char_type* ValidInfixOprtChars() const;\r
+\r
+    void SetArgSep(char_type cArgSep);\r
+    char_type GetArgSep() const;\r
+    \r
+    void  Error(EErrorCodes a_iErrc, \r
+                int a_iPos = (int)mu::string_type::npos, \r
+                const string_type &a_strTok = string_type() ) const;\r
+\r
+ protected:\r
+         \r
+    void Init();\r
+\r
+    virtual void InitCharSets() = 0;\r
+    virtual void InitFun() = 0;\r
+    virtual void InitConst() = 0;\r
+    virtual void InitOprt() = 0; \r
+\r
+    virtual void OnDetectVar(string_type *pExpr, int &nStart, int &nEnd);\r
+\r
+    static const char_type *c_DefaultOprt[]; \r
+    static std::locale s_locale;  ///< The locale used by the parser\r
+    static bool g_DbgDumpCmdCode;\r
+    static bool g_DbgDumpStack;\r
+\r
+    /** \brief A facet class used to change decimal and thousands separator. */\r
+    template<class TChar>\r
+    class change_dec_sep : public std::numpunct<TChar>\r
+    {\r
+    public:\r
+      \r
+      explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)\r
+        :std::numpunct<TChar>()\r
+        ,m_nGroup(nGroup)\r
+        ,m_cDecPoint(cDecSep)\r
+        ,m_cThousandsSep(cThousandsSep)\r
+      {}\r
+      \r
+    protected:\r
+      \r
+      virtual char_type do_decimal_point() const\r
+      {\r
+        return m_cDecPoint;\r
+      }\r
+\r
+      virtual char_type do_thousands_sep() const\r
+      {\r
+        return m_cThousandsSep;\r
+      }\r
+\r
+      virtual std::string do_grouping() const \r
+      { \r
+        return std::string(1, m_nGroup); \r
+      }\r
+\r
+    private:\r
+\r
+      int m_nGroup;\r
+      char_type m_cDecPoint;  \r
+      char_type m_cThousandsSep;\r
+    };\r
+\r
+ private:\r
+\r
+    void Assign(const ParserBase &a_Parser);\r
+    void InitTokenReader();\r
+    void ReInit() const;\r
+\r
+    void AddCallback( const string_type &a_strName, \r
+                      const ParserCallback &a_Callback, \r
+                      funmap_type &a_Storage,\r
+                      const char_type *a_szCharSet );\r
+\r
+    void ApplyRemainingOprt(ParserStack<token_type> &a_stOpt,\r
+                                ParserStack<token_type> &a_stVal) const;\r
+    void ApplyBinOprt(ParserStack<token_type> &a_stOpt,\r
+                      ParserStack<token_type> &a_stVal) const;\r
+\r
+    void ApplyIfElse(ParserStack<token_type> &a_stOpt,\r
+                     ParserStack<token_type> &a_stVal) const;\r
+\r
+    void ApplyFunc(ParserStack<token_type> &a_stOpt,\r
+                   ParserStack<token_type> &a_stVal, \r
+                   int iArgCount) const; \r
+\r
+    token_type ApplyStrFunc(const token_type &a_FunTok,\r
+                            const std::vector<token_type> &a_vArg) const;\r
+\r
+    int GetOprtPrecedence(const token_type &a_Tok) const;\r
+    EOprtAssociativity GetOprtAssociativity(const token_type &a_Tok) const;\r
+\r
+    void CreateRPN() const;\r
+\r
+    value_type ParseString() const; \r
+    value_type ParseCmdCode() const;\r
+    value_type ParseCmdCodeBulk(int nOffset, int nThreadID) const;\r
+\r
+    void  CheckName(const string_type &a_strName, const string_type &a_CharSet) const;\r
+    void  CheckOprt(const string_type &a_sName,\r
+                    const ParserCallback &a_Callback,\r
+                    const string_type &a_szCharSet) const;\r
+\r
+    void StackDump(const ParserStack<token_type > &a_stVal, \r
+                   const ParserStack<token_type > &a_stOprt) const;\r
+\r
+    /** \brief Pointer to the parser function. \r
+    \r
+      Eval() calls the function whose address is stored there.\r
+    */\r
+    mutable ParseFunction  m_pParseFormula;\r
+    mutable ParserByteCode m_vRPN;        ///< The Bytecode class.\r
+    mutable stringbuf_type  m_vStringBuf; ///< String buffer, used for storing string function arguments\r
+    stringbuf_type  m_vStringVarBuf;\r
+\r
+    std::auto_ptr<token_reader_type> m_pTokenReader; ///< Managed pointer to the token reader object.\r
+\r
+    funmap_type  m_FunDef;         ///< Map of function names and pointers.\r
+    funmap_type  m_PostOprtDef;    ///< Postfix operator callbacks\r
+    funmap_type  m_InfixOprtDef;   ///< unary infix operator.\r
+    funmap_type  m_OprtDef;        ///< Binary operator callbacks\r
+    valmap_type  m_ConstDef;       ///< user constants.\r
+    strmap_type  m_StrVarDef;      ///< user defined string constants\r
+    varmap_type  m_VarDef;         ///< user defind variables.\r
+\r
+    bool m_bBuiltInOp;             ///< Flag that can be used for switching built in operators on and off\r
+\r
+    string_type m_sNameChars;      ///< Charset for names\r
+    string_type m_sOprtChars;      ///< Charset for postfix/ binary operator tokens\r
+    string_type m_sInfixOprtChars; ///< Charset for infix operator tokens\r
+    \r
+    mutable int m_nIfElseCounter;  ///< Internal counter for keeping track of nested if-then-else clauses\r
+\r
+    // items merely used for caching state information\r
+    mutable valbuf_type m_vStackBuffer; ///< This is merely a buffer used for the stack in the cmd parsing routine\r
+    mutable int m_nFinalResultIdx;\r
+};\r
+\r
+} // namespace mu\r
+\r
+#endif\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserBytecode.h b/deal.II/bundled/muparser_v2_2_3/include/muParserBytecode.h
new file mode 100644 (file)
index 0000000..39ab39d
--- /dev/null
@@ -0,0 +1,141 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#ifndef MU_PARSER_BYTECODE_H\r
+#define MU_PARSER_BYTECODE_H\r
+\r
+#include <cassert>\r
+#include <string>\r
+#include <stack>\r
+#include <vector>\r
+\r
+#include "muParserDef.h"\r
+#include "muParserError.h"\r
+#include "muParserToken.h"\r
+\r
+/** \file\r
+    \brief Definition of the parser bytecode class.\r
+*/\r
+\r
+\r
+namespace mu\r
+{\r
+  struct SToken\r
+  {\r
+    ECmdCode Cmd;\r
+    int StackPos;\r
+\r
+    union\r
+    {\r
+      struct //SValData\r
+      {\r
+        value_type *ptr;\r
+        value_type  data;\r
+        value_type  data2;\r
+      } Val;\r
+\r
+      struct //SFunData\r
+      {\r
+        // Note: generic_fun_type is merely a placeholder. The real type could be \r
+        //       anything between gun_type1 and fun_type9. I can't use a void\r
+        //       pointer due to constraints in the ANSI standard which allows\r
+        //       data pointers and function pointers to differ in size.\r
+        generic_fun_type ptr;\r
+        int   argc;\r
+        int   idx;\r
+      } Fun;\r
+\r
+      struct //SOprtData\r
+      {\r
+        value_type *ptr;\r
+        int offset;\r
+      } Oprt;\r
+    };\r
+  };\r
+  \r
+  \r
+  /** \brief Bytecode implementation of the Math Parser.\r
+\r
+  The bytecode contains the formula converted to revers polish notation stored in a continious\r
+  memory area. Associated with this data are operator codes, variable pointers, constant \r
+  values and function pointers. Those are necessary in order to calculate the result.\r
+  All those data items will be casted to the underlying datatype of the bytecode.\r
+\r
+  \author (C) 2004-2013 Ingo Berg \r
+*/\r
+class ParserByteCode\r
+{\r
+private:\r
+\r
+    /** \brief Token type for internal use only. */\r
+    typedef ParserToken<value_type, string_type> token_type;\r
+\r
+    /** \brief Token vector for storing the RPN. */\r
+    typedef std::vector<SToken> rpn_type;\r
+\r
+    /** \brief Position in the Calculation array. */\r
+    unsigned m_iStackPos;\r
+\r
+    /** \brief Maximum size needed for the stack. */\r
+    std::size_t m_iMaxStackSize;\r
+    \r
+    /** \brief The actual rpn storage. */\r
+    rpn_type  m_vRPN;\r
+\r
+    bool m_bEnableOptimizer;\r
+\r
+    void ConstantFolding(ECmdCode a_Oprt);\r
+\r
+public:\r
+\r
+    ParserByteCode();\r
+    ParserByteCode(const ParserByteCode &a_ByteCode);\r
+    ParserByteCode& operator=(const ParserByteCode &a_ByteCode);\r
+    void Assign(const ParserByteCode &a_ByteCode);\r
+\r
+    void AddVar(value_type *a_pVar);\r
+    void AddVal(value_type a_fVal);\r
+    void AddOp(ECmdCode a_Oprt);\r
+    void AddIfElse(ECmdCode a_Oprt);\r
+    void AddAssignOp(value_type *a_pVar);\r
+    void AddFun(generic_fun_type a_pFun, int a_iArgc);\r
+    void AddBulkFun(generic_fun_type a_pFun, int a_iArgc);\r
+    void AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx);\r
+\r
+    void EnableOptimizer(bool bStat);\r
+\r
+    void Finalize();\r
+    void clear();\r
+    std::size_t GetMaxStackSize() const;\r
+    std::size_t GetSize() const;\r
+\r
+    const SToken* GetBase() const;\r
+    void AsciiDump();\r
+};\r
+\r
+} // namespace mu\r
+\r
+#endif\r
+\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserCallback.h b/deal.II/bundled/muparser_v2_2_3/include/muParserCallback.h
new file mode 100644 (file)
index 0000000..ef32b49
--- /dev/null
@@ -0,0 +1,118 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_CALLBACK_H\r
+#define MU_PARSER_CALLBACK_H\r
+\r
+#include "muParserDef.h"\r
+\r
+/** \file\r
+    \brief Definition of the parser callback class.\r
+*/\r
+\r
+namespace mu\r
+{\r
+\r
+/** \brief Encapsulation of prototypes for a numerical parser function.\r
+\r
+    Encapsulates the prototyp for numerical parser functions. The class\r
+    stores the number of arguments for parser functions as well\r
+    as additional flags indication the function is non optimizeable.\r
+    The pointer to the callback function pointer is stored as void* \r
+    and needs to be casted according to the argument count.\r
+    Negative argument counts indicate a parser function with a variable number\r
+    of arguments. \r
+\r
+    \author (C) 2004-2011 Ingo Berg\r
+*/\r
+class ParserCallback\r
+{\r
+public:\r
+    ParserCallback(fun_type0  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type1  a_pFun, bool a_bAllowOpti, int a_iPrec = -1, ECmdCode a_iCode=cmFUNC);\r
+    ParserCallback(fun_type2  a_pFun, bool a_bAllowOpti, int a_iPrec, EOprtAssociativity a_eAssociativity);\r
+    ParserCallback(fun_type2  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type3  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type4  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type5  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type6  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type7  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type8  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type9  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti);\r
+\r
+    ParserCallback(bulkfun_type0  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type1  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type2  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type3  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type4  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type5  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type6  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type7  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type8  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type9  a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti);\r
+\r
+    ParserCallback(multfun_type a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti);\r
+    ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti);\r
+    ParserCallback();\r
+    ParserCallback(const ParserCallback &a_Fun);\r
+    \r
+    ParserCallback* Clone() const;\r
+\r
+    bool  IsOptimizable() const;\r
+    void* GetAddr() const;\r
+    ECmdCode  GetCode() const;\r
+    ETypeCode GetType() const;\r
+    int GetPri()  const;\r
+    EOprtAssociativity GetAssociativity() const;\r
+    int GetArgc() const;\r
+\r
+private:\r
+    void *m_pFun;                   ///< Pointer to the callback function, casted to void\r
+    \r
+    /** \brief Number of numeric function arguments\r
+    \r
+        This number is negative for functions with variable number of arguments. in this cases\r
+        they represent the actual number of arguments found.\r
+    */\r
+    int   m_iArgc;      \r
+    int   m_iPri;                   ///< Valid only for binary and infix operators; Operator precedence.\r
+    EOprtAssociativity m_eOprtAsct; ///< Operator associativity; Valid only for binary operators \r
+    ECmdCode  m_iCode;\r
+    ETypeCode m_iType;\r
+    bool  m_bAllowOpti;             ///< Flag indication optimizeability \r
+};\r
+\r
+//------------------------------------------------------------------------------\r
+/** \brief Container for Callback objects. */\r
+typedef std::map<string_type, ParserCallback> funmap_type; \r
+\r
+} // namespace mu\r
+\r
+#endif\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserDLL.h b/deal.II/bundled/muparser_v2_2_3/include/muParserDLL.h
new file mode 100644 (file)
index 0000000..db11c8d
--- /dev/null
@@ -0,0 +1,235 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#ifndef MU_PARSER_DLL_H\r
+#define MU_PARSER_DLL_H\r
+\r
+#if defined(WIN32) || defined(_WIN32)\r
+    #ifdef MUPARSERLIB_EXPORTS\r
+        #define API_EXPORT(TYPE) __declspec(dllexport) TYPE __cdecl\r
+    #else\r
+        #define API_EXPORT(TYPE) __declspec(dllimport) TYPE __cdecl\r
+    #endif\r
+#else\r
+    #define API_EXPORT(TYPE) TYPE\r
+#endif\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+/** \file \r
+    \brief This file contains the DLL interface of muparser.\r
+*/\r
+\r
+// Basic types\r
+typedef void*  muParserHandle_t;    // parser handle\r
+typedef char   muChar_t;            // character type\r
+typedef int    muBool_t;            // boolean type\r
+typedef int    muInt_t;             // integer type \r
+typedef double muFloat_t;           // floating point type\r
+\r
+// function types for calculation\r
+typedef muFloat_t (*muFun0_t )(); \r
+typedef muFloat_t (*muFun1_t )(muFloat_t); \r
+typedef muFloat_t (*muFun2_t )(muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun3_t )(muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun4_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun5_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun6_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun7_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun8_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun9_t )(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muFun10_t)(muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+\r
+// Function prototypes for bulkmode functions\r
+typedef muFloat_t (*muBulkFun0_t )(int, int); \r
+typedef muFloat_t (*muBulkFun1_t )(int, int, muFloat_t); \r
+typedef muFloat_t (*muBulkFun2_t )(int, int, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun3_t )(int, int, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun4_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun5_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun6_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun7_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun8_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun9_t )(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+typedef muFloat_t (*muBulkFun10_t)(int, int, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t, muFloat_t); \r
+\r
+typedef muFloat_t (*muMultFun_t)(const muFloat_t*, muInt_t);\r
+typedef muFloat_t (*muStrFun1_t)(const muChar_t*);\r
+typedef muFloat_t (*muStrFun2_t)(const muChar_t*, muFloat_t);\r
+typedef muFloat_t (*muStrFun3_t)(const muChar_t*, muFloat_t, muFloat_t);\r
+\r
+// Functions for parser management\r
+typedef void (*muErrorHandler_t)(muParserHandle_t a_hParser);           // [optional] callback to an error handler\r
+typedef muFloat_t* (*muFacFun_t)(const muChar_t*, void*);               // [optional] callback for creating new variables\r
+typedef muInt_t (*muIdentFun_t)(const muChar_t*, muInt_t*, muFloat_t*); // [optional] value identification callbacks\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+// Constants\r
+static const int muOPRT_ASCT_LEFT  = 0;\r
+static const int muOPRT_ASCT_RIGHT = 1;\r
+\r
+static const int muBASETYPE_FLOAT  = 0;\r
+static const int muBASETYPE_INT    = 1;\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+//\r
+//\r
+// muParser C compatible bindings\r
+//\r
+//\r
+//-----------------------------------------------------------------------------------------------------\r
+\r
+\r
+// Basic operations / initialization  \r
+API_EXPORT(muParserHandle_t) mupCreate(int nBaseType);\r
+API_EXPORT(void) mupRelease(muParserHandle_t a_hParser);\r
+API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t *a_szExpr);\r
+API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void* pUserData);\r
+API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser);\r
+API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser);\r
+API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum);\r
+API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_fResult, int nSize);\r
+\r
+// Defining callbacks / variables / constants\r
+API_EXPORT(void) mupDefineFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun0_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun1_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun2_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun3_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun4_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun5_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun6_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun7_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun8_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun9_t a_pFun, muBool_t a_bOptimize);\r
+API_EXPORT(void) mupDefineFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muFun10_t a_pFun, muBool_t a_bOptimize);\r
+\r
+// Defining bulkmode functions\r
+API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun0_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun1_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun2_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun3_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun4_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun5_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun6_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun7_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun8_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun9_t a_pFun);\r
+API_EXPORT(void) mupDefineBulkFun10(muParserHandle_t a_hParser, const muChar_t *a_szName, muBulkFun10_t a_pFun);\r
+\r
+// string functions\r
+API_EXPORT(void) mupDefineStrFun1(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun1_t a_pFun);\r
+API_EXPORT(void) mupDefineStrFun2(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun2_t a_pFun);\r
+API_EXPORT(void) mupDefineStrFun3(muParserHandle_t a_hParser, const muChar_t *a_szName, muStrFun3_t a_pFun);\r
+\r
+API_EXPORT(void) mupDefineMultFun( muParserHandle_t a_hParser, \r
+                                   const muChar_t* a_szName, \r
+                                   muMultFun_t a_pFun, \r
+                                   muBool_t a_bOptimize);\r
+\r
+API_EXPORT(void) mupDefineOprt( muParserHandle_t a_hParser, \r
+                                const muChar_t* a_szName, \r
+                                muFun2_t a_pFun, \r
+                                muInt_t a_nPrec, \r
+                                muInt_t a_nOprtAsct,\r
+                                muBool_t a_bOptimize);\r
+\r
+API_EXPORT(void) mupDefineConst( muParserHandle_t a_hParser, \r
+                                 const muChar_t* a_szName, \r
+                                 muFloat_t a_fVal );\r
+\r
+API_EXPORT(void) mupDefineStrConst( muParserHandle_t a_hParser, \r
+                                    const muChar_t* a_szName, \r
+                                    const muChar_t *a_sVal );\r
+\r
+API_EXPORT(void) mupDefineVar( muParserHandle_t a_hParser, \r
+                               const muChar_t* a_szName, \r
+                               muFloat_t *a_fVar);\r
+\r
+API_EXPORT(void) mupDefineBulkVar( muParserHandle_t a_hParser, \r
+                               const muChar_t* a_szName, \r
+                               muFloat_t *a_fVar);\r
+\r
+API_EXPORT(void) mupDefinePostfixOprt( muParserHandle_t a_hParser, \r
+                                       const muChar_t* a_szName, \r
+                                       muFun1_t a_pOprt, \r
+                                       muBool_t a_bOptimize);\r
+\r
+\r
+API_EXPORT(void) mupDefineInfixOprt( muParserHandle_t a_hParser, \r
+                                     const muChar_t* a_szName, \r
+                                     muFun1_t a_pOprt, \r
+                                     muBool_t a_bOptimize);\r
+\r
+// Define character sets for identifiers\r
+API_EXPORT(void) mupDefineNameChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);\r
+API_EXPORT(void) mupDefineOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);\r
+API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, const muChar_t* a_szCharset);\r
+\r
+// Remove all / single variables\r
+API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName);\r
+API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser);\r
+\r
+// Querying variables / expression variables / constants\r
+API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser);\r
+API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser);\r
+API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);\r
+API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t** a_pVar);\r
+API_EXPORT(void) mupGetConst(muParserHandle_t a_hParser, unsigned a_iVar, const muChar_t** a_pszName, muFloat_t* a_pVar);\r
+API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep);\r
+API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cArgSep);\r
+API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cArgSep);\r
+API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser);\r
+\r
+// Add value recognition callbacks\r
+API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser, muIdentFun_t);\r
+\r
+// Error handling\r
+API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser);\r
+API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pErrHandler);\r
+API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser);\r
+API_EXPORT(muInt_t) mupGetErrorCode(muParserHandle_t a_hParser);\r
+API_EXPORT(muInt_t) mupGetErrorPos(muParserHandle_t a_hParser);\r
+API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser);\r
+//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser);\r
+\r
+// This is used for .NET only. It creates a new variable allowing the dll to\r
+// manage the variable rather than the .NET garbage collector.\r
+API_EXPORT(muFloat_t*) mupCreateVar();\r
+API_EXPORT(void) mupReleaseVar(muFloat_t*);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // include guard\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserDef.h b/deal.II/bundled/muparser_v2_2_3/include/muParserDef.h
new file mode 100644 (file)
index 0000000..54f4559
--- /dev/null
@@ -0,0 +1,368 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#ifndef MUP_DEF_H\r
+#define MUP_DEF_H\r
+\r
+#include <iostream>\r
+#include <string>\r
+#include <sstream>\r
+#include <map>\r
+\r
+#include "muParserFixes.h"\r
+\r
+/** \file\r
+    \brief This file contains standard definitions used by the parser.\r
+*/\r
+\r
+#define MUP_VERSION _T("2.2.3")\r
+#define MUP_VERSION_DATE _T("20121222; SF")\r
+\r
+#define MUP_CHARS _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")\r
+\r
+/** \brief If this macro is defined mathematical exceptions (div by zero) will be thrown as exceptions. */\r
+//#define MUP_MATH_EXCEPTIONS\r
+\r
+/** \brief Define the base datatype for values.\r
+\r
+  This datatype must be a built in value type. You can not use custom classes.\r
+  It should be working with all types except "int"!\r
+*/\r
+#define MUP_BASETYPE double\r
+\r
+/** \brief Activate this option in order to compile with OpenMP support. \r
+\r
+  OpenMP is used only in the bulk mode it may increase the performance a bit. \r
+*/\r
+//#define MUP_USE_OPENMP\r
+\r
+#if defined(_UNICODE)\r
+  /** \brief Definition of the basic parser string type. */\r
+  #define MUP_STRING_TYPE std::wstring\r
+\r
+  #if !defined(_T)\r
+    #define _T(x) L##x\r
+  #endif // not defined _T\r
+#else\r
+  #ifndef _T\r
+  #define _T(x) x\r
+  #endif\r
+  \r
+  /** \brief Definition of the basic parser string type. */\r
+  #define MUP_STRING_TYPE std::string\r
+#endif\r
+\r
+#if defined(_DEBUG)\r
+  /** \brief Debug macro to force an abortion of the programm with a certain message.\r
+  */\r
+  #define MUP_FAIL(MSG)     \\r
+          {                 \\r
+            bool MSG=false; \\r
+            assert(MSG);    \\r
+          }\r
+\r
+    /** \brief An assertion that does not kill the program.\r
+\r
+        This macro is neutralised in UNICODE builds. It's\r
+        too difficult to translate.\r
+    */\r
+    #define MUP_ASSERT(COND)                         \\r
+            if (!(COND))                             \\r
+            {                                        \\r
+              stringstream_type ss;                  \\r
+              ss << _T("Assertion \"") _T(#COND) _T("\" failed: ") \\r
+                 << __FILE__ << _T(" line ")         \\r
+                 << __LINE__ << _T(".");             \\r
+              throw ParserError( ss.str() );         \\r
+            }\r
+#else\r
+  #define MUP_FAIL(MSG)\r
+  #define MUP_ASSERT(COND)\r
+#endif\r
+\r
+\r
+namespace mu\r
+{\r
+#if defined(_UNICODE)\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Encapsulate wcout. */\r
+  inline std::wostream& console()\r
+  {\r
+    return std::wcout;\r
+  }\r
+\r
+  /** \brief Encapsulate cin. */\r
+  inline std::wistream& console_in()\r
+  {\r
+    return std::wcin;\r
+  }\r
+\r
+#else\r
+\r
+  /** \brief Encapsulate cout. \r
+  \r
+    Used for supporting UNICODE more easily.\r
+  */\r
+  inline std::ostream& console()\r
+  {\r
+    return std::cout;\r
+  }\r
+\r
+  /** \brief Encapsulate cin. \r
+\r
+    Used for supporting UNICODE more easily.\r
+  */\r
+  inline std::istream& console_in()\r
+  {\r
+    return std::cin;\r
+  }\r
+\r
+#endif\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Bytecode values.\r
+\r
+      \attention The order of the operator entries must match the order in ParserBase::c_DefaultOprt!\r
+  */\r
+  enum ECmdCode\r
+  {\r
+    // The following are codes for built in binary operators\r
+    // apart from built in operators the user has the opportunity to\r
+    // add user defined operators.\r
+    cmLE            = 0,   ///< Operator item:  less or equal\r
+    cmGE            = 1,   ///< Operator item:  greater or equal\r
+    cmNEQ           = 2,   ///< Operator item:  not equal\r
+    cmEQ            = 3,   ///< Operator item:  equals\r
+    cmLT            = 4,   ///< Operator item:  less than\r
+    cmGT            = 5,   ///< Operator item:  greater than\r
+    cmADD           = 6,   ///< Operator item:  add\r
+    cmSUB           = 7,   ///< Operator item:  subtract\r
+    cmMUL           = 8,   ///< Operator item:  multiply\r
+    cmDIV           = 9,   ///< Operator item:  division\r
+    cmPOW           = 10,  ///< Operator item:  y to the power of ...\r
+    cmLAND          = 11,\r
+    cmLOR           = 12,\r
+    cmASSIGN        = 13,  ///< Operator item:  Assignment operator\r
+    cmBO            = 14,  ///< Operator item:  opening bracket\r
+    cmBC            = 15,  ///< Operator item:  closing bracket\r
+    cmIF            = 16,  ///< For use in the ternary if-then-else operator\r
+    cmELSE          = 17,  ///< For use in the ternary if-then-else operator\r
+    cmENDIF         = 18,  ///< For use in the ternary if-then-else operator\r
+    cmARG_SEP       = 19,  ///< function argument separator\r
+    cmVAR           = 20,  ///< variable item\r
+    cmVAL           = 21,  ///< value item\r
+\r
+    // For optimization purposes\r
+    cmVARPOW2,\r
+    cmVARPOW3,\r
+    cmVARPOW4,\r
+    cmVARMUL,\r
+    cmPOW2,\r
+\r
+    // operators and functions\r
+    cmFUNC,                ///< Code for a generic function item\r
+    cmFUNC_STR,            ///< Code for a function with a string parameter\r
+    cmFUNC_BULK,           ///< Special callbacks for Bulk mode with an additional parameter for the bulk index \r
+    cmSTRING,              ///< Code for a string token\r
+    cmOPRT_BIN,            ///< user defined binary operator\r
+    cmOPRT_POSTFIX,        ///< code for postfix operators\r
+    cmOPRT_INFIX,          ///< code for infix operators\r
+    cmEND,                 ///< end of formula\r
+    cmUNKNOWN              ///< uninitialized item\r
+  };\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Types internally used by the parser.\r
+  */\r
+  enum ETypeCode\r
+  {\r
+    tpSTR  = 0,     ///< String type (Function arguments and constants only, no string variables)\r
+    tpDBL  = 1,     ///< Floating point variables\r
+    tpVOID = 2      ///< Undefined type.\r
+  };\r
+\r
+  //------------------------------------------------------------------------------\r
+  enum EParserVersionInfo\r
+  {\r
+    pviBRIEF,\r
+    pviFULL\r
+  };\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Parser operator precedence values. */\r
+  enum EOprtAssociativity\r
+  {\r
+    oaLEFT  = 0,\r
+    oaRIGHT = 1,\r
+    oaNONE  = 2\r
+  };\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Parser operator precedence values. */\r
+  enum EOprtPrecedence\r
+  {\r
+    // binary operators\r
+    prLOR     = 1,\r
+    prLAND    = 2,\r
+    prLOGIC   = 3,  ///< logic operators\r
+    prCMP     = 4,  ///< comparsion operators\r
+    prADD_SUB = 5,  ///< addition\r
+    prMUL_DIV = 6,  ///< multiplication/division\r
+    prPOW     = 7,  ///< power operator priority (highest)\r
+\r
+    // infix operators\r
+    prINFIX   = 6, ///< Signs have a higher priority than ADD_SUB, but lower than power operator\r
+    prPOSTFIX = 6  ///< Postfix operator priority (currently unused)\r
+  };\r
+\r
+  //------------------------------------------------------------------------------\r
+  // basic types\r
+\r
+  /** \brief The numeric datatype used by the parser. \r
+  \r
+    Normally this is a floating point type either single or double precision.\r
+  */\r
+  typedef MUP_BASETYPE value_type;\r
+\r
+  /** \brief The stringtype used by the parser. \r
+\r
+    Depends on wether UNICODE is used or not.\r
+  */\r
+  typedef MUP_STRING_TYPE string_type;\r
+\r
+  /** \brief The character type used by the parser. \r
+  \r
+    Depends on wether UNICODE is used or not.\r
+  */\r
+  typedef string_type::value_type char_type;\r
+\r
+  /** \brief Typedef for easily using stringstream that respect the parser stringtype. */\r
+  typedef std::basic_stringstream<char_type,\r
+                                  std::char_traits<char_type>,\r
+                                  std::allocator<char_type> > stringstream_type;\r
+\r
+  // Data container types\r
+\r
+  /** \brief Type used for storing variables. */\r
+  typedef std::map<string_type, value_type*> varmap_type;\r
+  \r
+  /** \brief Type used for storing constants. */\r
+  typedef std::map<string_type, value_type> valmap_type;\r
+  \r
+  /** \brief Type for assigning a string name to an index in the internal string table. */\r
+  typedef std::map<string_type, std::size_t> strmap_type;\r
+\r
+  // Parser callbacks\r
+  \r
+  /** \brief Callback type used for functions without arguments. */\r
+  typedef value_type (*generic_fun_type)();\r
+\r
+  /** \brief Callback type used for functions without arguments. */\r
+  typedef value_type (*fun_type0)();\r
+\r
+  /** \brief Callback type used for functions with a single arguments. */\r
+  typedef value_type (*fun_type1)(value_type);\r
+\r
+  /** \brief Callback type used for functions with two arguments. */\r
+  typedef value_type (*fun_type2)(value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with three arguments. */\r
+  typedef value_type (*fun_type3)(value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with four arguments. */\r
+  typedef value_type (*fun_type4)(value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*fun_type5)(value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*fun_type6)(value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*fun_type7)(value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*fun_type8)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*fun_type9)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*fun_type10)(value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions without arguments. */\r
+  typedef value_type (*bulkfun_type0)(int, int);\r
+\r
+  /** \brief Callback type used for functions with a single arguments. */\r
+  typedef value_type (*bulkfun_type1)(int, int, value_type);\r
+\r
+  /** \brief Callback type used for functions with two arguments. */\r
+  typedef value_type (*bulkfun_type2)(int, int, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with three arguments. */\r
+  typedef value_type (*bulkfun_type3)(int, int, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with four arguments. */\r
+  typedef value_type (*bulkfun_type4)(int, int, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*bulkfun_type5)(int, int, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*bulkfun_type6)(int, int, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*bulkfun_type7)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*bulkfun_type8)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*bulkfun_type9)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with five arguments. */\r
+  typedef value_type (*bulkfun_type10)(int, int, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type, value_type);\r
+\r
+  /** \brief Callback type used for functions with a variable argument list. */\r
+  typedef value_type (*multfun_type)(const value_type*, int);\r
+\r
+  /** \brief Callback type used for functions taking a string as an argument. */\r
+  typedef value_type (*strfun_type1)(const char_type*);\r
+\r
+  /** \brief Callback type used for functions taking a string and a value as arguments. */\r
+  typedef value_type (*strfun_type2)(const char_type*, value_type);\r
+\r
+  /** \brief Callback type used for functions taking a string and two values as arguments. */\r
+  typedef value_type (*strfun_type3)(const char_type*, value_type, value_type);\r
+\r
+  /** \brief Callback used for functions that identify values in a string. */\r
+  typedef int (*identfun_type)(const char_type *sExpr, int *nPos, value_type *fVal);\r
+\r
+  /** \brief Callback used for variable creation factory functions. */\r
+  typedef value_type* (*facfun_type)(const char_type*, void*);\r
+} // end of namespace\r
+\r
+#endif\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserError.h b/deal.II/bundled/muparser_v2_2_3/include/muParserError.h
new file mode 100644 (file)
index 0000000..60244ac
--- /dev/null
@@ -0,0 +1,174 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_ERROR_H\r
+#define MU_PARSER_ERROR_H\r
+\r
+#include <cassert>\r
+#include <stdexcept>\r
+#include <string>\r
+#include <sstream>\r
+#include <vector>\r
+#include <memory>\r
+\r
+#include "muParserDef.h"\r
+\r
+/** \file \r
+    \brief This file defines the error class used by the parser.\r
+*/\r
+\r
+namespace mu\r
+{\r
+\r
+/** \brief Error codes. */\r
+enum EErrorCodes\r
+{\r
+  // Formula syntax errors\r
+  ecUNEXPECTED_OPERATOR    = 0,  ///< Unexpected binary operator found\r
+  ecUNASSIGNABLE_TOKEN     = 1,  ///< Token cant be identified.\r
+  ecUNEXPECTED_EOF         = 2,  ///< Unexpected end of formula. (Example: "2+sin(")\r
+  ecUNEXPECTED_ARG_SEP     = 3,  ///< An unexpected comma has been found. (Example: "1,23")\r
+  ecUNEXPECTED_ARG         = 4,  ///< An unexpected argument has been found\r
+  ecUNEXPECTED_VAL         = 5,  ///< An unexpected value token has been found\r
+  ecUNEXPECTED_VAR         = 6,  ///< An unexpected variable token has been found\r
+  ecUNEXPECTED_PARENS      = 7,  ///< Unexpected Parenthesis, opening or closing\r
+  ecUNEXPECTED_STR         = 8,  ///< A string has been found at an inapropriate position\r
+  ecSTRING_EXPECTED        = 9,  ///< A string function has been called with a different type of argument\r
+  ecVAL_EXPECTED           = 10, ///< A numerical function has been called with a non value type of argument\r
+  ecMISSING_PARENS         = 11, ///< Missing parens. (Example: "3*sin(3")\r
+  ecUNEXPECTED_FUN         = 12, ///< Unexpected function found. (Example: "sin(8)cos(9)")\r
+  ecUNTERMINATED_STRING    = 13, ///< unterminated string constant. (Example: "3*valueof("hello)")\r
+  ecTOO_MANY_PARAMS        = 14, ///< Too many function parameters\r
+  ecTOO_FEW_PARAMS         = 15, ///< Too few function parameters. (Example: "ite(1<2,2)")\r
+  ecOPRT_TYPE_CONFLICT     = 16, ///< binary operators may only be applied to value items of the same type\r
+  ecSTR_RESULT             = 17, ///< result is a string\r
+\r
+  // Invalid Parser input Parameters\r
+  ecINVALID_NAME           = 18, ///< Invalid function, variable or constant name.\r
+  ecINVALID_BINOP_IDENT    = 19, ///< Invalid binary operator identifier\r
+  ecINVALID_INFIX_IDENT    = 20, ///< Invalid function, variable or constant name.\r
+  ecINVALID_POSTFIX_IDENT  = 21, ///< Invalid function, variable or constant name.\r
+\r
+  ecBUILTIN_OVERLOAD       = 22, ///< Trying to overload builtin operator\r
+  ecINVALID_FUN_PTR        = 23, ///< Invalid callback function pointer \r
+  ecINVALID_VAR_PTR        = 24, ///< Invalid variable pointer \r
+  ecEMPTY_EXPRESSION       = 25, ///< The Expression is empty\r
+  ecNAME_CONFLICT          = 26, ///< Name conflict\r
+  ecOPT_PRI                = 27, ///< Invalid operator priority\r
+  // \r
+  ecDOMAIN_ERROR           = 28, ///< catch division by zero, sqrt(-1), log(0) (currently unused)\r
+  ecDIV_BY_ZERO            = 29, ///< Division by zero (currently unused)\r
+  ecGENERIC                = 30, ///< Generic error\r
+  ecLOCALE                 = 31, ///< Conflict with current locale\r
+\r
+  ecUNEXPECTED_CONDITIONAL = 32,\r
+  ecMISSING_ELSE_CLAUSE    = 33, \r
+  ecMISPLACED_COLON        = 34,\r
+\r
+  // internal errors\r
+  ecINTERNAL_ERROR         = 35, ///< Internal error of any kind.\r
+  \r
+  // The last two are special entries \r
+  ecCOUNT,                      ///< This is no error code, It just stores just the total number of error codes\r
+  ecUNDEFINED              = -1  ///< Undefined message, placeholder to detect unassigned error messages\r
+};\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief A class that handles the error messages.\r
+*/\r
+class ParserErrorMsg\r
+{\r
+public:\r
+    typedef ParserErrorMsg self_type;\r
+\r
+    ParserErrorMsg& operator=(const ParserErrorMsg &);\r
+    ParserErrorMsg(const ParserErrorMsg&);\r
+    ParserErrorMsg();\r
+\r
+   ~ParserErrorMsg();\r
+\r
+    static const ParserErrorMsg& Instance();\r
+    string_type operator[](unsigned a_iIdx) const;\r
+\r
+private:\r
+    std::vector<string_type>  m_vErrMsg;  ///< A vector with the predefined error messages\r
+    static const self_type m_Instance;    ///< The instance pointer\r
+};\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Error class of the parser. \r
+    \author Ingo Berg\r
+\r
+  Part of the math parser package.\r
+*/\r
+class ParserError\r
+{\r
+private:\r
+\r
+    /** \brief Replace all ocuurences of a substring with another string. */\r
+    void ReplaceSubString( string_type &strSource, \r
+                           const string_type &strFind,\r
+                           const string_type &strReplaceWith);\r
+    void Reset();\r
+\r
+public:\r
+\r
+    ParserError();\r
+    explicit ParserError(EErrorCodes a_iErrc);\r
+    explicit ParserError(const string_type &sMsg);\r
+    ParserError( EErrorCodes a_iErrc,\r
+                 const string_type &sTok,\r
+                 const string_type &sFormula = string_type(),\r
+                 int a_iPos = -1);\r
+    ParserError( EErrorCodes a_iErrc, \r
+                 int a_iPos, \r
+                 const string_type &sTok);\r
+    ParserError( const char_type *a_szMsg, \r
+                 int a_iPos = -1, \r
+                 const string_type &sTok = string_type());\r
+    ParserError(const ParserError &a_Obj);\r
+    ParserError& operator=(const ParserError &a_Obj);\r
+   ~ParserError();\r
+\r
+    void SetFormula(const string_type &a_strFormula);\r
+    const string_type& GetExpr() const;\r
+    const string_type& GetMsg() const;\r
+    std::size_t GetPos() const;\r
+    const string_type& GetToken() const;\r
+    EErrorCodes GetCode() const;\r
+\r
+private:\r
+    string_type m_strMsg;     ///< The message string\r
+    string_type m_strFormula; ///< Formula string\r
+    string_type m_strTok;     ///< Token related with the error\r
+    int m_iPos;               ///< Formula position related to the error \r
+    EErrorCodes m_iErrc;      ///< Error code\r
+    const ParserErrorMsg &m_ErrMsg;\r
+};             \r
+\r
+} // namespace mu\r
+\r
+#endif\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserFixes.h b/deal.II/bundled/muparser_v2_2_3/include/muParserFixes.h
new file mode 100644 (file)
index 0000000..1cd15e0
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_FIXES_H\r
+#define MU_PARSER_FIXES_H\r
+\r
+/** \file\r
+    \brief This file contains compatibility fixes for some platforms.\r
+*/\r
+\r
+//\r
+// Compatibility fixes\r
+//\r
+\r
+//---------------------------------------------------------------------------\r
+//\r
+// Intel Compiler\r
+//\r
+//---------------------------------------------------------------------------\r
+\r
+#ifdef __INTEL_COMPILER\r
+\r
+// remark #981: operands are evaluated in unspecified order\r
+// disabled -> completely pointless if the functions do not have side effects\r
+//\r
+#pragma warning(disable:981)\r
+\r
+// remark #383: value copied to temporary, reference to temporary used\r
+#pragma warning(disable:383)\r
+\r
+// remark #1572: floating-point equality and inequality comparisons are unreliable\r
+// disabled -> everyone knows it, the parser passes this problem\r
+//             deliberately to the user\r
+#pragma warning(disable:1572)\r
+\r
+#endif\r
+\r
+#endif // include guard\r
+\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserInt.h b/deal.II/bundled/muparser_v2_2_3/include/muParserInt.h
new file mode 100644 (file)
index 0000000..4d11afb
--- /dev/null
@@ -0,0 +1,135 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_INT_H\r
+#define MU_PARSER_INT_H\r
+\r
+#include "muParserBase.h"\r
+#include <vector>\r
+\r
+\r
+/** \file\r
+    \brief Definition of a parser using integer value.\r
+*/\r
+\r
+\r
+namespace mu\r
+{\r
+\r
+/** \brief Mathematical expressions parser.\r
+  \r
+  This version of the parser handles only integer numbers. It disables the built in operators thus it is \r
+  slower than muParser. Integer values are stored in the double value_type and converted if needed.\r
+*/\r
+class ParserInt : public ParserBase\r
+{\r
+private:\r
+    static int  Round(value_type v) { return (int)(v + ((v>=0) ? 0.5 : -0.5) ); };\r
+  \r
+    static value_type  Abs(value_type);\r
+    static value_type  Sign(value_type);\r
+    static value_type  Ite(value_type, value_type, value_type);\r
+    // !! The unary Minus is a MUST, otherwise you cant use negative signs !!\r
+    static value_type  UnaryMinus(value_type);\r
+    // Functions with variable number of arguments\r
+    static value_type  Sum(const value_type* a_afArg, int a_iArgc);  // sum\r
+    static value_type  Min(const value_type* a_afArg, int a_iArgc);  // minimum\r
+    static value_type  Max(const value_type* a_afArg, int a_iArgc);  // maximum\r
+    // binary operator callbacks\r
+    static value_type  Add(value_type v1, value_type v2);\r
+    static value_type  Sub(value_type v1, value_type v2);\r
+    static value_type  Mul(value_type v1, value_type v2);\r
+    static value_type  Div(value_type v1, value_type v2);\r
+    static value_type  Mod(value_type v1, value_type v2);\r
+    static value_type  Pow(value_type v1, value_type v2);\r
+    static value_type  Shr(value_type v1, value_type v2);\r
+    static value_type  Shl(value_type v1, value_type v2);\r
+    static value_type  LogAnd(value_type v1, value_type v2);\r
+    static value_type  LogOr(value_type v1, value_type v2);\r
+    static value_type  And(value_type v1, value_type v2);\r
+    static value_type  Or(value_type v1, value_type v2);\r
+    static value_type  Xor(value_type v1, value_type v2);\r
+    static value_type  Less(value_type v1, value_type v2);\r
+    static value_type  Greater(value_type v1, value_type v2);\r
+    static value_type  LessEq(value_type v1, value_type v2);\r
+    static value_type  GreaterEq(value_type v1, value_type v2);\r
+    static value_type  Equal(value_type v1, value_type v2);\r
+    static value_type  NotEqual(value_type v1, value_type v2);\r
+    static value_type  Not(value_type v1);\r
+\r
+    static int IsHexVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);\r
+    static int IsBinVal(const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);\r
+    static int IsVal   (const char_type* a_szExpr, int *a_iPos, value_type *a_iVal);\r
+\r
+    /** \brief A facet class used to change decimal and thousands separator. */\r
+    template<class TChar>\r
+    class change_dec_sep : public std::numpunct<TChar>\r
+    {\r
+    public:\r
+      \r
+      explicit change_dec_sep(char_type cDecSep, char_type cThousandsSep = 0, int nGroup = 3)\r
+        :std::numpunct<TChar>()\r
+        ,m_cDecPoint(cDecSep)\r
+        ,m_cThousandsSep(cThousandsSep)\r
+        ,m_nGroup(nGroup)\r
+      {}\r
+      \r
+    protected:\r
+      \r
+      virtual char_type do_decimal_point() const\r
+      {\r
+        return m_cDecPoint;\r
+      }\r
+\r
+      virtual char_type do_thousands_sep() const\r
+      {\r
+        return m_cThousandsSep;\r
+      }\r
+\r
+      virtual std::string do_grouping() const \r
+      { \r
+        return std::string(1, m_nGroup); \r
+      }\r
+\r
+    private:\r
+\r
+      int m_nGroup;\r
+      char_type m_cDecPoint;  \r
+      char_type m_cThousandsSep;\r
+    };\r
+\r
+public:\r
+    ParserInt();\r
+\r
+    virtual void InitFun();\r
+         virtual void InitOprt();\r
+    virtual void InitConst();\r
+    virtual void InitCharSets();\r
+};\r
+\r
+} // namespace mu\r
+\r
+#endif\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserStack.h b/deal.II/bundled/muparser_v2_2_3/include/muParserStack.h
new file mode 100644 (file)
index 0000000..c97e092
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_STACK_H\r
+#define MU_PARSER_STACK_H\r
+\r
+#include <cassert>\r
+#include <string>\r
+#include <stack>\r
+#include <vector>\r
+\r
+#include "muParserError.h"\r
+#include "muParserToken.h"\r
+\r
+/** \file \r
+    \brief This file defines the stack used by muparser.\r
+*/\r
+\r
+namespace mu\r
+{\r
+\r
+  /** \brief Parser stack implementation. \r
+\r
+      Stack implementation based on a std::stack. The behaviour of pop() had been\r
+      slightly changed in order to get an error code if the stack is empty.\r
+      The stack is used within the Parser both as a value stack and as an operator stack.\r
+\r
+      \author (C) 2004-2011 Ingo Berg \r
+  */\r
+  template <typename TValueType>\r
+  class ParserStack \r
+  {\r
+    private:\r
+\r
+      /** \brief Type of the underlying stack implementation. */\r
+      typedef std::stack<TValueType, std::vector<TValueType> > impl_type;\r
+      \r
+      impl_type m_Stack;  ///< This is the actual stack.\r
+\r
+    public:    \r
+        \r
+      //---------------------------------------------------------------------------\r
+      ParserStack()\r
+        :m_Stack()\r
+      {}\r
+\r
+      //---------------------------------------------------------------------------\r
+      virtual ~ParserStack()\r
+      {}\r
+\r
+      //---------------------------------------------------------------------------\r
+      /** \brief Pop a value from the stack.\r
+       \r
+        Unlike the standard implementation this function will return the value that\r
+        is going to be taken from the stack.\r
+\r
+        \throw ParserException in case the stack is empty.\r
+        \sa pop(int &a_iErrc)\r
+      */\r
+           TValueType pop()\r
+      {\r
+        if (empty())\r
+          throw ParserError( _T("stack is empty.") );\r
+\r
+        TValueType el = top();\r
+        m_Stack.pop();\r
+        return el;\r
+      }\r
+\r
+      /** \brief Push an object into the stack. \r
+\r
+          \param a_Val object to push into the stack.\r
+          \throw nothrow\r
+      */\r
+      void push(const TValueType& a_Val) \r
+      { \r
+        m_Stack.push(a_Val); \r
+      }\r
+\r
+      /** \brief Return the number of stored elements. */\r
+      unsigned size() const\r
+      { \r
+        return (unsigned)m_Stack.size(); \r
+      }\r
+\r
+      /** \brief Returns true if stack is empty false otherwise. */\r
+      bool empty() const\r
+      {\r
+        return m_Stack.size()==0; \r
+      }\r
+       \r
+      /** \brief Return reference to the top object in the stack. \r
+       \r
+          The top object is the one pushed most recently.\r
+      */\r
+      TValueType& top() \r
+      { \r
+        return m_Stack.top(); \r
+      }\r
+  };\r
+} // namespace MathUtils\r
+\r
+#endif\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserTemplateMagic.h b/deal.II/bundled/muparser_v2_2_3/include/muParserTemplateMagic.h
new file mode 100644 (file)
index 0000000..8a9b7a6
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef MU_PARSER_TEMPLATE_MAGIC_H\r
+#define MU_PARSER_TEMPLATE_MAGIC_H\r
+\r
+#include <cmath>\r
+#include "muParserError.h"\r
+\r
+\r
+namespace mu\r
+{\r
+  //-----------------------------------------------------------------------------------------------\r
+  //\r
+  // Compile time type detection\r
+  //\r
+  //-----------------------------------------------------------------------------------------------\r
+\r
+  /** \brief A class singling out integer types at compile time using \r
+             template meta programming.\r
+  */\r
+  template<typename T>\r
+  struct TypeInfo\r
+  {\r
+    static bool IsInteger() { return false; }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<char>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<short>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<int>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<long>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<unsigned char>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<unsigned short>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<unsigned int>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+  template<>\r
+  struct TypeInfo<unsigned long>\r
+  {\r
+    static bool IsInteger() { return true;  }\r
+  };\r
+\r
+\r
+  //-----------------------------------------------------------------------------------------------\r
+  //\r
+  // Standard math functions with dummy overload for integer types\r
+  //\r
+  //-----------------------------------------------------------------------------------------------\r
+\r
+  /** \brief A template class for providing wrappers for essential math functions.\r
+\r
+    This template is spezialized for several types in order to provide a unified interface\r
+    for parser internal math function calls regardless of the data type.\r
+  */\r
+  template<typename T>\r
+  struct MathImpl\r
+  {\r
+    static T Sin(T v)   { return sin(v);  }\r
+    static T Cos(T v)   { return cos(v);  }\r
+    static T Tan(T v)   { return tan(v);  }\r
+    static T ASin(T v)  { return asin(v); }\r
+    static T ACos(T v)  { return acos(v); }\r
+    static T ATan(T v)  { return atan(v); }\r
+    static T ATan2(T v1, T v2) { return atan2(v1, v2); }\r
+    static T Sinh(T v)  { return sinh(v); }\r
+    static T Cosh(T v)  { return cosh(v); }\r
+    static T Tanh(T v)  { return tanh(v); }\r
+    static T ASinh(T v) { return log(v + sqrt(v * v + 1)); }\r
+    static T ACosh(T v) { return log(v + sqrt(v * v - 1)); }\r
+    static T ATanh(T v) { return ((T)0.5 * log((1 + v) / (1 - v))); }\r
+    static T Log(T v)   { return log(v); } \r
+    static T Log2(T v)  { return log(v)/log((T)2); } // Logarithm base 2\r
+    static T Log10(T v) { return log10(v); }         // Logarithm base 10\r
+    static T Exp(T v)   { return exp(v);   }\r
+    static T Abs(T v)   { return (v>=0) ? v : -v; }\r
+    static T Sqrt(T v)  { return sqrt(v); }\r
+    static T Rint(T v)  { return floor(v + (T)0.5); }\r
+    static T Sign(T v)  { return (T)((v<0) ? -1 : (v>0) ? 1 : 0); }\r
+    static T Pow(T v1, T v2) { return std::pow(v1, v2); }\r
+  };\r
+\r
+  // Create (mostly) dummy math function definitions for integer types. They are mostly\r
+  // empty since they are not applicable for integer values.\r
+#define MAKE_MATH_DUMMY(TYPE)                    \\r
+  template<>                                     \\r
+  struct MathImpl<TYPE>                          \\r
+  {                                              \\r
+    static TYPE Sin(TYPE)          { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Cos(TYPE)          { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Tan(TYPE)          { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ASin(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ACos(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ATan(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ATan2(TYPE, TYPE)  { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Sinh(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Cosh(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Tanh(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ASinh(TYPE)        { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ACosh(TYPE)        { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE ATanh(TYPE)        { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Log(TYPE)          { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Log2(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Log10(TYPE)        { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Exp(TYPE)          { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Abs(TYPE)          { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Sqrt(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Rint(TYPE)         { throw ParserError(_T("unimplemented function.")); } \\r
+    static TYPE Sign(TYPE v)          { return (TYPE)((v<0) ? -1 : (v>0) ? 1 : 0);     } \\r
+    static TYPE Pow(TYPE v1, TYPE v2) { return (TYPE)std::pow((double)v1, (double)v2); } \\r
+  };\r
+\r
+  MAKE_MATH_DUMMY(char)\r
+  MAKE_MATH_DUMMY(short)\r
+  MAKE_MATH_DUMMY(int)\r
+  MAKE_MATH_DUMMY(long)\r
+\r
+#undef MAKE_MATH_DUMMY\r
+}\r
+\r
+#endif\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserTest.h b/deal.II/bundled/muparser_v2_2_3/include/muParserTest.h
new file mode 100644 (file)
index 0000000..cd2b2b4
--- /dev/null
@@ -0,0 +1,210 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_TEST_H\r
+#define MU_PARSER_TEST_H\r
+\r
+#include <string>\r
+#include <cstdlib>\r
+#include <numeric> // for accumulate\r
+#include "muParser.h"\r
+#include "muParserInt.h"\r
+\r
+/** \file\r
+    \brief This file contains the parser test class.\r
+*/\r
+\r
+namespace mu\r
+{\r
+  /** \brief Namespace for test cases. */\r
+  namespace Test\r
+  {\r
+    //------------------------------------------------------------------------------\r
+    /** \brief Test cases for unit testing.\r
+\r
+      (C) 2004-2011 Ingo Berg\r
+    */\r
+    class ParserTester // final\r
+    {\r
+    private:\r
+        static int c_iCount;\r
+\r
+        // Multiarg callbacks\r
+        static value_type f1of1(value_type v) { return v;};\r
+       \r
+        static value_type f1of2(value_type v, value_type  ) {return v;};\r
+        static value_type f2of2(value_type  , value_type v) {return v;};\r
+\r
+        static value_type f1of3(value_type v, value_type  , value_type  ) {return v;};\r
+        static value_type f2of3(value_type  , value_type v, value_type  ) {return v;};\r
+        static value_type f3of3(value_type  , value_type  , value_type v) {return v;};\r
+       \r
+        static value_type f1of4(value_type v, value_type,   value_type  , value_type  ) {return v;}\r
+        static value_type f2of4(value_type  , value_type v, value_type  , value_type  ) {return v;}\r
+        static value_type f3of4(value_type  , value_type,   value_type v, value_type  ) {return v;}\r
+        static value_type f4of4(value_type  , value_type,   value_type  , value_type v) {return v;}\r
+\r
+             static value_type f1of5(value_type v, value_type,   value_type  , value_type  , value_type  ) { return v; }\r
+             static value_type f2of5(value_type  , value_type v, value_type  , value_type  , value_type  ) { return v; }\r
+             static value_type f3of5(value_type  , value_type,   value_type v, value_type  , value_type  ) { return v; }\r
+             static value_type f4of5(value_type  , value_type,   value_type  , value_type v, value_type  ) { return v; }\r
+             static value_type f5of5(value_type  , value_type,   value_type  , value_type  , value_type v) { return v; }\r
+\r
+        static value_type Min(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1<a_fVal2) ? a_fVal1 : a_fVal2; }\r
+           static value_type Max(value_type a_fVal1, value_type a_fVal2) { return (a_fVal1>a_fVal2) ? a_fVal1 : a_fVal2; }\r
+\r
+        static value_type plus2(value_type v1) { return v1+2; }\r
+        static value_type times3(value_type v1) { return v1*3; }\r
+        static value_type sqr(value_type v1) { return v1*v1; }\r
+        static value_type sign(value_type v) { return -v; }\r
+        static value_type add(value_type v1, value_type v2) { return v1+v2; }\r
+        static value_type land(value_type v1, value_type v2) { return (int)v1 & (int)v2; }\r
+        \r
+\r
+        static value_type FirstArg(const value_type* a_afArg, int a_iArgc)\r
+        {\r
+          if (!a_iArgc)        \r
+            throw mu::Parser::exception_type( _T("too few arguments for function FirstArg.") );\r
+\r
+          return  a_afArg[0];\r
+        }\r
+\r
+        static value_type LastArg(const value_type* a_afArg, int a_iArgc)\r
+        {\r
+          if (!a_iArgc)        \r
+            throw mu::Parser::exception_type( _T("too few arguments for function LastArg.") );\r
+\r
+          return  a_afArg[a_iArgc-1];\r
+        }\r
+\r
+        static value_type Sum(const value_type* a_afArg, int a_iArgc)\r
+        { \r
+          if (!a_iArgc)        \r
+            throw mu::Parser::exception_type( _T("too few arguments for function sum.") );\r
+\r
+          value_type fRes=0;\r
+          for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];\r
+          return fRes;\r
+        }\r
+\r
+        static value_type Rnd(value_type v)\r
+        {\r
+          return (value_type)(1+(v*std::rand()/(RAND_MAX+1.0)));\r
+        }\r
+\r
+        static value_type RndWithString(const char_type*)\r
+        {\r
+          return (value_type)( 1 + (1000.0f * std::rand() / (RAND_MAX + 1.0) ) );\r
+        }\r
+\r
+        static value_type Ping()\r
+        { \r
+          return 10; \r
+        }\r
+\r
+        static value_type ValueOf(const char_type*)      \r
+        { \r
+          return 123; \r
+        }\r
+\r
+        static value_type StrFun1(const char_type* v1)                               \r
+        { \r
+          int val(0);\r
+          stringstream_type(v1) >> val;\r
+          return (value_type)val;\r
+        }\r
+\r
+        static value_type StrFun2(const char_type* v1, value_type v2)                \r
+        { \r
+          int val(0);\r
+          stringstream_type(v1) >> val;\r
+          return (value_type)(val + v2);\r
+        }\r
+        \r
+        static value_type StrFun3(const char_type* v1, value_type v2, value_type v3) \r
+        { \r
+          int val(0);\r
+          stringstream_type(v1) >> val;\r
+          return val + v2 + v3;\r
+        }\r
+\r
+        static value_type StrToFloat(const char_type* a_szMsg)\r
+        {\r
+          value_type val(0);\r
+          stringstream_type(a_szMsg) >> val;\r
+          return val;\r
+        }\r
+\r
+        // postfix operator callback\r
+        static value_type Mega(value_type a_fVal)  { return a_fVal * (value_type)1e6; }\r
+        static value_type Micro(value_type a_fVal) { return a_fVal * (value_type)1e-6; }\r
+        static value_type Milli(value_type a_fVal) { return a_fVal / (value_type)1e3; }\r
+\r
+        // Custom value recognition\r
+        static int IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal);\r
+\r
+        int TestNames();\r
+             int TestSyntax();\r
+             int TestMultiArg();\r
+             int TestPostFix();\r
+             int TestExpression();\r
+             int TestInfixOprt();\r
+             int TestBinOprt();\r
+             int TestVarConst();\r
+             int TestInterface();\r
+             int TestException();\r
+        int TestStrArg();\r
+        int TestIfThenElse();\r
+\r
+        void Abort() const;\r
+\r
+    public:\r
+        typedef int (ParserTester::*testfun_type)();\r
+\r
+             ParserTester();\r
+             void Run();\r
+\r
+    private:\r
+        std::vector<testfun_type> m_vTestFun;\r
+             void AddTest(testfun_type a_pFun);\r
+\r
+        // Test Double Parser\r
+        int EqnTest(const string_type& a_str, double a_fRes, bool a_fPass);\r
+        int EqnTestWithVarChange(const string_type& a_str, \r
+                                 double a_fRes1, \r
+                                 double a_fVar1, \r
+                                 double a_fRes2, \r
+                                 double a_fVar2);\r
+        int ThrowTest(const string_type& a_str, int a_iErrc, bool a_bFail = true);\r
+\r
+        // Test Int Parser\r
+        int EqnTestInt(const string_type& a_str, double a_fRes, bool a_fPass);\r
+    };\r
+  } // namespace Test\r
+} // namespace mu\r
+\r
+#endif\r
+\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserToken.h b/deal.II/bundled/muparser_v2_2_3/include/muParserToken.h
new file mode 100644 (file)
index 0000000..326d717
--- /dev/null
@@ -0,0 +1,399 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_TOKEN_H\r
+#define MU_PARSER_TOKEN_H\r
+\r
+#include <cassert>\r
+#include <string>\r
+#include <stack>\r
+#include <vector>\r
+#include <memory>\r
+\r
+#include "muParserError.h"\r
+#include "muParserCallback.h"\r
+\r
+/** \file\r
+    \brief This file contains the parser token definition.\r
+*/\r
+\r
+namespace mu\r
+{\r
+  /** \brief Encapsulation of the data for a single formula token. \r
+\r
+    Formula token implementation. Part of the Math Parser Package.\r
+    Formula tokens can be either one of the following:\r
+    <ul>\r
+      <li>value</li>\r
+      <li>variable</li>\r
+      <li>function with numerical arguments</li>\r
+      <li>functions with a string as argument</li>\r
+      <li>prefix operators</li>\r
+      <li>infix operators</li>\r
+           <li>binary operator</li>\r
+    </ul>\r
+\r
+   \author (C) 2004-2013 Ingo Berg \r
+  */\r
+  template<typename TBase, typename TString>\r
+  class ParserToken\r
+  {\r
+  private:\r
+\r
+      ECmdCode  m_iCode;  ///< Type of the token; The token type is a constant of type #ECmdCode.\r
+      ETypeCode m_iType;\r
+      void  *m_pTok;      ///< Stores Token pointer; not applicable for all tokens\r
+      int  m_iIdx;        ///< An otional index to an external buffer storing the token data\r
+      TString m_strTok;   ///< Token string\r
+      TString m_strVal;   ///< Value for string variables\r
+      value_type m_fVal;  ///< the value \r
+      std::auto_ptr<ParserCallback> m_pCallback;\r
+\r
+  public:\r
+\r
+      //---------------------------------------------------------------------------\r
+      /** \brief Constructor (default).\r
+        \r
+          Sets token to an neutral state of type cmUNKNOWN.\r
+          \throw nothrow\r
+          \sa ECmdCode\r
+      */\r
+      ParserToken()\r
+        :m_iCode(cmUNKNOWN)\r
+        ,m_iType(tpVOID)\r
+        ,m_pTok(0)\r
+        ,m_iIdx(-1)\r
+        ,m_strTok()\r
+        ,m_pCallback()\r
+      {}\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Create token from another one.\r
+      \r
+          Implemented by calling Assign(...)\r
+          \throw nothrow\r
+          \post m_iType==cmUNKNOWN\r
+          \sa #Assign\r
+      */\r
+      ParserToken(const ParserToken &a_Tok)\r
+      {\r
+        Assign(a_Tok);\r
+      }\r
+      \r
+      //------------------------------------------------------------------------------\r
+      /** \brief Assignement operator. \r
+      \r
+          Copy token state from another token and return this.\r
+          Implemented by calling Assign(...).\r
+          \throw nothrow\r
+      */\r
+      ParserToken& operator=(const ParserToken &a_Tok)\r
+      {\r
+        Assign(a_Tok);\r
+        return *this;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Copy token information from argument.\r
+      \r
+          \throw nothrow\r
+      */\r
+      void Assign(const ParserToken &a_Tok)\r
+      {\r
+        m_iCode = a_Tok.m_iCode;\r
+        m_pTok = a_Tok.m_pTok;\r
+        m_strTok = a_Tok.m_strTok;\r
+        m_iIdx = a_Tok.m_iIdx;\r
+        m_strVal = a_Tok.m_strVal;\r
+        m_iType = a_Tok.m_iType;\r
+        m_fVal = a_Tok.m_fVal;\r
+        // create new callback object if a_Tok has one \r
+        m_pCallback.reset(a_Tok.m_pCallback.get() ? a_Tok.m_pCallback->Clone() : 0);\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Assign a token type. \r
+\r
+        Token may not be of type value, variable or function. Those have seperate set functions. \r
+\r
+        \pre [assert] a_iType!=cmVAR\r
+        \pre [assert] a_iType!=cmVAL\r
+        \pre [assert] a_iType!=cmFUNC\r
+        \post m_fVal = 0\r
+        \post m_pTok = 0\r
+      */\r
+      ParserToken& Set(ECmdCode a_iType, const TString &a_strTok=TString())\r
+      {\r
+        // The following types cant be set this way, they have special Set functions\r
+        assert(a_iType!=cmVAR);\r
+        assert(a_iType!=cmVAL);\r
+        assert(a_iType!=cmFUNC);\r
+\r
+        m_iCode = a_iType;\r
+        m_iType = tpVOID;\r
+        m_pTok = 0;\r
+        m_strTok = a_strTok;\r
+        m_iIdx = -1;\r
+\r
+        return *this;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Set Callback type. */\r
+      ParserToken& Set(const ParserCallback &a_pCallback, const TString &a_sTok)\r
+      {\r
+        assert(a_pCallback.GetAddr());\r
+\r
+        m_iCode = a_pCallback.GetCode();\r
+        m_iType = tpVOID;\r
+        m_strTok = a_sTok;\r
+        m_pCallback.reset(new ParserCallback(a_pCallback));\r
+\r
+        m_pTok = 0;\r
+        m_iIdx = -1;\r
+        \r
+        return *this;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Make this token a value token. \r
+      \r
+          Member variables not necessary for value tokens will be invalidated.\r
+          \throw nothrow\r
+      */\r
+      ParserToken& SetVal(TBase a_fVal, const TString &a_strTok=TString())\r
+      {\r
+        m_iCode = cmVAL;\r
+        m_iType = tpDBL;\r
+        m_fVal = a_fVal;\r
+        m_strTok = a_strTok;\r
+        m_iIdx = -1;\r
+        \r
+        m_pTok = 0;\r
+        m_pCallback.reset(0);\r
+\r
+        return *this;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief make this token a variable token. \r
+      \r
+          Member variables not necessary for variable tokens will be invalidated.\r
+          \throw nothrow\r
+      */\r
+      ParserToken& SetVar(TBase *a_pVar, const TString &a_strTok)\r
+      {\r
+        m_iCode = cmVAR;\r
+        m_iType = tpDBL;\r
+        m_strTok = a_strTok;\r
+        m_iIdx = -1;\r
+        m_pTok = (void*)a_pVar;\r
+        m_pCallback.reset(0);\r
+        return *this;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Make this token a variable token. \r
+      \r
+          Member variables not necessary for variable tokens will be invalidated.\r
+          \throw nothrow\r
+      */\r
+      ParserToken& SetString(const TString &a_strTok, std::size_t a_iSize)\r
+      {\r
+        m_iCode = cmSTRING;\r
+        m_iType = tpSTR;\r
+        m_strTok = a_strTok;\r
+        m_iIdx = static_cast<int>(a_iSize);\r
+\r
+        m_pTok = 0;\r
+        m_pCallback.reset(0);\r
+        return *this;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Set an index associated with the token related data. \r
+      \r
+          In cmSTRFUNC - This is the index to a string table in the main parser.\r
+          \param a_iIdx The index the string function result will take in the bytecode parser.\r
+          \throw exception_type if #a_iIdx<0 or #m_iType!=cmSTRING\r
+      */\r
+      void SetIdx(int a_iIdx)\r
+      {\r
+        if (m_iCode!=cmSTRING || a_iIdx<0)\r
+               throw ParserError(ecINTERNAL_ERROR);\r
+        \r
+        m_iIdx = a_iIdx;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Return Index associated with the token related data. \r
+      \r
+          In cmSTRFUNC - This is the index to a string table in the main parser.\r
+\r
+          \throw exception_type if #m_iIdx<0 or #m_iType!=cmSTRING\r
+          \return The index the result will take in the Bytecode calculatin array (#m_iIdx).\r
+      */\r
+      int GetIdx() const\r
+      {\r
+        if (m_iIdx<0 || m_iCode!=cmSTRING )\r
+          throw ParserError(ecINTERNAL_ERROR);\r
+\r
+        return m_iIdx;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Return the token type.\r
+      \r
+          \return #m_iType\r
+          \throw nothrow\r
+      */\r
+      ECmdCode GetCode() const\r
+      {\r
+        if (m_pCallback.get())\r
+        {\r
+          return m_pCallback->GetCode();\r
+        }\r
+        else\r
+        {\r
+          return m_iCode;\r
+        }\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      ETypeCode GetType() const\r
+      {\r
+        if (m_pCallback.get())\r
+        {\r
+          return m_pCallback->GetType();\r
+        }\r
+        else\r
+        {\r
+          return m_iType;\r
+        }\r
+      }\r
+      \r
+      //------------------------------------------------------------------------------\r
+      int GetPri() const\r
+      {\r
+        if ( !m_pCallback.get())\r
+               throw ParserError(ecINTERNAL_ERROR);\r
+            \r
+        if ( m_pCallback->GetCode()!=cmOPRT_BIN && m_pCallback->GetCode()!=cmOPRT_INFIX)\r
+               throw ParserError(ecINTERNAL_ERROR);\r
+\r
+        return m_pCallback->GetPri();\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      EOprtAssociativity GetAssociativity() const\r
+      {\r
+        if (m_pCallback.get()==NULL || m_pCallback->GetCode()!=cmOPRT_BIN)\r
+               throw ParserError(ecINTERNAL_ERROR);\r
+\r
+        return m_pCallback->GetAssociativity();\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Return the address of the callback function assoziated with\r
+                 function and operator tokens.\r
+\r
+          \return The pointer stored in #m_pTok.\r
+          \throw exception_type if token type is non of:\r
+                 <ul>\r
+                   <li>cmFUNC</li>\r
+                   <li>cmSTRFUNC</li>\r
+                   <li>cmPOSTOP</li>\r
+                   <li>cmINFIXOP</li>\r
+                   <li>cmOPRT_BIN</li>\r
+                 </ul>\r
+          \sa ECmdCode\r
+      */\r
+      generic_fun_type GetFuncAddr() const\r
+      {\r
+        return (m_pCallback.get()) ? (generic_fun_type)m_pCallback->GetAddr() : 0;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \biref Get value of the token.\r
+        \r
+          Only applicable to variable and value tokens.\r
+          \throw exception_type if token is no value/variable token.\r
+      */\r
+      TBase GetVal() const\r
+      {\r
+        switch (m_iCode)\r
+        {\r
+          case cmVAL:  return m_fVal;\r
+          case cmVAR:  return *((TBase*)m_pTok);\r
+          default:     throw ParserError(ecVAL_EXPECTED);\r
+        }\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Get address of a variable token.\r
+\r
+        Valid only if m_iType==CmdVar.\r
+        \throw exception_type if token is no variable token.\r
+      */\r
+      TBase* GetVar() const\r
+      {\r
+        if (m_iCode!=cmVAR)\r
+               throw ParserError(ecINTERNAL_ERROR);\r
+\r
+        return (TBase*)m_pTok;\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Return the number of function arguments. \r
+\r
+        Valid only if m_iType==CmdFUNC.\r
+      */\r
+      int GetArgCount() const\r
+      {\r
+        assert(m_pCallback.get());\r
+\r
+        if (!m_pCallback->GetAddr())\r
+               throw ParserError(ecINTERNAL_ERROR);\r
+\r
+        return m_pCallback->GetArgc();\r
+      }\r
+\r
+      //------------------------------------------------------------------------------\r
+      /** \brief Return the token identifier. \r
+          \r
+          If #m_iType is cmSTRING the token identifier is the value of the string argument\r
+          for a string function.\r
+          \return #m_strTok\r
+          \throw nothrow\r
+          \sa m_strTok\r
+      */\r
+      const TString& GetAsString() const\r
+      {\r
+        return m_strTok;\r
+      }\r
+  };\r
+} // namespace mu\r
+\r
+#endif\r
diff --git a/deal.II/bundled/muparser_v2_2_3/include/muParserTokenReader.h b/deal.II/bundled/muparser_v2_2_3/include/muParserTokenReader.h
new file mode 100644 (file)
index 0000000..9d96225
--- /dev/null
@@ -0,0 +1,161 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#ifndef MU_PARSER_TOKEN_READER_H\r
+#define MU_PARSER_TOKEN_READER_H\r
+\r
+#include <cassert>\r
+#include <cstdio>\r
+#include <cstring>\r
+#include <list>\r
+#include <map>\r
+#include <memory>\r
+#include <stack>\r
+#include <string>\r
+\r
+#include "muParserDef.h"\r
+#include "muParserToken.h"\r
+\r
+/** \file\r
+    \brief This file contains the parser token reader definition.\r
+*/\r
+\r
+\r
+namespace mu\r
+{\r
+  // Forward declaration\r
+  class ParserBase;\r
+\r
+  /** \brief Token reader for the ParserBase class.\r
+\r
+  */\r
+  class ParserTokenReader \r
+  {\r
+  private:\r
+\r
+      typedef ParserToken<value_type, string_type> token_type;\r
+\r
+  public:\r
+\r
+      ParserTokenReader(ParserBase *a_pParent);\r
+      ParserTokenReader* Clone(ParserBase *a_pParent) const;\r
+\r
+      void AddValIdent(identfun_type a_pCallback);\r
+      void SetVarCreator(facfun_type a_pFactory, void *pUserData);\r
+      void SetFormula(const string_type &a_strFormula);\r
+      void SetArgSep(char_type cArgSep);\r
+\r
+      int GetPos() const;\r
+      const string_type& GetExpr() const;\r
+      varmap_type& GetUsedVar();\r
+      char_type GetArgSep() const;\r
+\r
+      void IgnoreUndefVar(bool bIgnore);\r
+      void ReInit();\r
+      token_type ReadNextToken();\r
+\r
+  private:\r
+\r
+      /** \brief Syntax codes. \r
+       \r
+               The syntax codes control the syntax check done during the first time parsing of \r
+          the expression string. They are flags that indicate which tokens are allowed next\r
+          if certain tokens are identified.\r
+         */\r
+      enum ESynCodes\r
+      {\r
+        noBO      = 1 << 0,  ///< to avoid i.e. "cos(7)(" \r
+        noBC      = 1 << 1,  ///< to avoid i.e. "sin)" or "()"\r
+        noVAL     = 1 << 2,  ///< to avoid i.e. "tan 2" or "sin(8)3.14"\r
+        noVAR     = 1 << 3,  ///< to avoid i.e. "sin a" or "sin(8)a"\r
+        noARG_SEP = 1 << 4,  ///< to avoid i.e. ",," or "+," ...\r
+        noFUN     = 1 << 5,  ///< to avoid i.e. "sqrt cos" or "(1)sin" \r
+        noOPT     = 1 << 6,  ///< to avoid i.e. "(+)"\r
+        noPOSTOP  = 1 << 7,  ///< to avoid i.e. "(5!!)" "sin!"\r
+             noINFIXOP = 1 << 8,  ///< to avoid i.e. "++4" "!!4"\r
+        noEND     = 1 << 9,  ///< to avoid unexpected end of formula\r
+        noSTR     = 1 << 10, ///< to block numeric arguments on string functions\r
+        noASSIGN  = 1 << 11, ///< to block assignement to constant i.e. "4=7"\r
+        noIF      = 1 << 12,\r
+        noELSE    = 1 << 13,\r
+        sfSTART_OF_LINE = noOPT | noBC | noPOSTOP | noASSIGN | noIF | noELSE | noARG_SEP,\r
+        noANY     = ~0       ///< All of he above flags set\r
+      };       \r
+\r
+      ParserTokenReader(const ParserTokenReader &a_Reader);\r
+      ParserTokenReader& operator=(const ParserTokenReader &a_Reader);\r
+      void Assign(const ParserTokenReader &a_Reader);\r
+\r
+      void SetParent(ParserBase *a_pParent);\r
+      int ExtractToken(const char_type *a_szCharSet, \r
+                       string_type &a_strTok, \r
+                       int a_iPos) const;\r
+      int ExtractOperatorToken(string_type &a_sTok, int a_iPos) const;\r
+\r
+      bool IsBuiltIn(token_type &a_Tok);\r
+      bool IsArgSep(token_type &a_Tok);\r
+      bool IsEOF(token_type &a_Tok);\r
+      bool IsInfixOpTok(token_type &a_Tok);\r
+      bool IsFunTok(token_type &a_Tok);\r
+      bool IsPostOpTok(token_type &a_Tok);\r
+      bool IsOprt(token_type &a_Tok);\r
+      bool IsValTok(token_type &a_Tok);\r
+      bool IsVarTok(token_type &a_Tok);\r
+      bool IsStrVarTok(token_type &a_Tok);\r
+      bool IsUndefVarTok(token_type &a_Tok);\r
+      bool IsString(token_type &a_Tok);\r
+      void Error(EErrorCodes a_iErrc, \r
+                 int a_iPos = -1, \r
+                 const string_type &a_sTok = string_type() ) const;\r
+\r
+      token_type& SaveBeforeReturn(const token_type &tok);\r
+\r
+      ParserBase *m_pParser;\r
+      string_type m_strFormula;\r
+      int  m_iPos;\r
+      int  m_iSynFlags;\r
+      bool m_bIgnoreUndefVar;\r
+\r
+      const funmap_type *m_pFunDef;\r
+      const funmap_type *m_pPostOprtDef;\r
+      const funmap_type *m_pInfixOprtDef;\r
+      const funmap_type *m_pOprtDef;\r
+      const valmap_type *m_pConstDef;\r
+      const strmap_type *m_pStrVarDef;\r
+      varmap_type *m_pVarDef;  ///< The only non const pointer to parser internals\r
+      facfun_type m_pFactory;\r
+      void *m_pFactoryData;\r
+      std::list<identfun_type> m_vIdentFun; ///< Value token identification function\r
+      varmap_type m_UsedVar;\r
+      value_type m_fZero;      ///< Dummy value of zero, referenced by undefined variables\r
+      int m_iBrackets;\r
+      token_type m_lastTok;\r
+      char_type m_cArgSep;     ///< The character used for separating function arguments\r
+  };\r
+} // namespace mu\r
+\r
+#endif\r
+\r
+\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParser.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParser.cpp
new file mode 100644 (file)
index 0000000..0eecd98
--- /dev/null
@@ -0,0 +1,386 @@
+/* \r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+\r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#include "muParser.h"\r
+#include "muParserTemplateMagic.h"\r
+\r
+//--- Standard includes ------------------------------------------------------------------------\r
+#include <cmath>\r
+#include <algorithm>\r
+#include <numeric>\r
+\r
+/** \brief Pi (what else?). */\r
+#define PARSER_CONST_PI  3.141592653589793238462643\r
+\r
+/** \brief The eulerian number. */\r
+#define PARSER_CONST_E   2.718281828459045235360287\r
+\r
+using namespace std;\r
+\r
+/** \file\r
+    \brief Implementation of the standard floating point parser.\r
+*/\r
+\r
+\r
+\r
+/** \brief Namespace for mathematical applications. */\r
+namespace mu\r
+{\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  // Trigonometric function\r
+  value_type Parser::Sin(value_type v)   { return MathImpl<value_type>::Sin(v);  }\r
+  value_type Parser::Cos(value_type v)   { return MathImpl<value_type>::Cos(v);  }\r
+  value_type Parser::Tan(value_type v)   { return MathImpl<value_type>::Tan(v);  }\r
+  value_type Parser::ASin(value_type v)  { return MathImpl<value_type>::ASin(v); }\r
+  value_type Parser::ACos(value_type v)  { return MathImpl<value_type>::ACos(v); }\r
+  value_type Parser::ATan(value_type v)  { return MathImpl<value_type>::ATan(v); }\r
+  value_type Parser::ATan2(value_type v1, value_type v2) { return MathImpl<value_type>::ATan2(v1, v2); }\r
+  value_type Parser::Sinh(value_type v)  { return MathImpl<value_type>::Sinh(v); }\r
+  value_type Parser::Cosh(value_type v)  { return MathImpl<value_type>::Cosh(v); }\r
+  value_type Parser::Tanh(value_type v)  { return MathImpl<value_type>::Tanh(v); }\r
+  value_type Parser::ASinh(value_type v) { return MathImpl<value_type>::ASinh(v); }\r
+  value_type Parser::ACosh(value_type v) { return MathImpl<value_type>::ACosh(v); }\r
+  value_type Parser::ATanh(value_type v) { return MathImpl<value_type>::ATanh(v); }\r
+\r
+  //---------------------------------------------------------------------------\r
+  // Logarithm functions\r
+\r
+  // Logarithm base 2\r
+  value_type Parser::Log2(value_type v)  \r
+  { \r
+    #ifdef MUP_MATH_EXCEPTIONS\r
+        if (v<=0)\r
+          throw ParserError(ecDOMAIN_ERROR, _T("Log2"));\r
+    #endif\r
+\r
+    return MathImpl<value_type>::Log2(v);  \r
+  }  \r
+\r
+  // Logarithm base 10\r
+  value_type Parser::Log10(value_type v) \r
+  { \r
+    #ifdef MUP_MATH_EXCEPTIONS\r
+        if (v<=0)\r
+          throw ParserError(ecDOMAIN_ERROR, _T("Log10"));\r
+    #endif\r
+\r
+    return MathImpl<value_type>::Log10(v); \r
+  } \r
+\r
+// Logarithm base e (natural logarithm)\r
+  value_type Parser::Ln(value_type v)    \r
+  { \r
+    #ifdef MUP_MATH_EXCEPTIONS\r
+        if (v<=0)\r
+          throw ParserError(ecDOMAIN_ERROR, _T("Ln"));\r
+    #endif\r
+\r
+    return MathImpl<value_type>::Log(v);   \r
+  } \r
+\r
+  //---------------------------------------------------------------------------\r
+  //  misc\r
+  value_type Parser::Exp(value_type v)  { return MathImpl<value_type>::Exp(v);  }\r
+  value_type Parser::Abs(value_type v)  { return MathImpl<value_type>::Abs(v);  }\r
+  value_type Parser::Sqrt(value_type v) \r
+  { \r
+    #ifdef MUP_MATH_EXCEPTIONS\r
+        if (v<0)\r
+          throw ParserError(ecDOMAIN_ERROR, _T("sqrt"));\r
+    #endif\r
+\r
+    return MathImpl<value_type>::Sqrt(v); \r
+  }\r
+  value_type Parser::Rint(value_type v) { return MathImpl<value_type>::Rint(v); }\r
+  value_type Parser::Sign(value_type v) { return MathImpl<value_type>::Sign(v); }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Callback for the unary minus operator.\r
+      \param v The value to negate\r
+      \return -v\r
+  */\r
+  value_type Parser::UnaryMinus(value_type v) \r
+  { \r
+    return -v; \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Callback for adding multiple values. \r
+      \param [in] a_afArg Vector with the function arguments\r
+      \param [in] a_iArgc The size of a_afArg\r
+  */\r
+  value_type Parser::Sum(const value_type *a_afArg, int a_iArgc)\r
+  { \r
+    if (!a_iArgc)      \r
+      throw exception_type(_T("too few arguments for function sum."));\r
+\r
+    value_type fRes=0;\r
+    for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];\r
+    return fRes;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Callback for averaging multiple values. \r
+      \param [in] a_afArg Vector with the function arguments\r
+      \param [in] a_iArgc The size of a_afArg\r
+  */\r
+  value_type Parser::Avg(const value_type *a_afArg, int a_iArgc)\r
+  { \r
+    if (!a_iArgc)      \r
+      throw exception_type(_T("too few arguments for function sum."));\r
+\r
+    value_type fRes=0;\r
+    for (int i=0; i<a_iArgc; ++i) fRes += a_afArg[i];\r
+    return fRes/(value_type)a_iArgc;\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Callback for determining the minimum value out of a vector. \r
+      \param [in] a_afArg Vector with the function arguments\r
+      \param [in] a_iArgc The size of a_afArg\r
+  */\r
+  value_type Parser::Min(const value_type *a_afArg, int a_iArgc)\r
+  { \r
+    if (!a_iArgc)      \r
+      throw exception_type(_T("too few arguments for function min."));\r
+\r
+    value_type fRes=a_afArg[0];\r
+    for (int i=0; i<a_iArgc; ++i) \r
+      fRes = std::min(fRes, a_afArg[i]);\r
+\r
+    return fRes;\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Callback for determining the maximum value out of a vector. \r
+      \param [in] a_afArg Vector with the function arguments\r
+      \param [in] a_iArgc The size of a_afArg\r
+  */\r
+  value_type Parser::Max(const value_type *a_afArg, int a_iArgc)\r
+  { \r
+    if (!a_iArgc)      \r
+      throw exception_type(_T("too few arguments for function min."));\r
+\r
+    value_type fRes=a_afArg[0];\r
+    for (int i=0; i<a_iArgc; ++i) fRes = std::max(fRes, a_afArg[i]);\r
+\r
+    return fRes;\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Default value recognition callback. \r
+      \param [in] a_szExpr Pointer to the expression\r
+      \param [in, out] a_iPos Pointer to an index storing the current position within the expression\r
+      \param [out] a_fVal Pointer where the value should be stored in case one is found.\r
+      \return 1 if a value was found 0 otherwise.\r
+  */\r
+  int Parser::IsVal(const char_type* a_szExpr, int *a_iPos, value_type *a_fVal)\r
+  {\r
+    value_type fVal(0);\r
+\r
+    stringstream_type stream(a_szExpr);\r
+    stream.seekg(0);        // todo:  check if this really is necessary\r
+    stream.imbue(Parser::s_locale);\r
+    stream >> fVal;\r
+    stringstream_type::pos_type iEnd = stream.tellg(); // Position after reading\r
+\r
+    if (iEnd==(stringstream_type::pos_type)-1)\r
+      return 0;\r
+\r
+    *a_iPos += (int)iEnd;\r
+    *a_fVal = fVal;\r
+    return 1;\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Constructor. \r
+\r
+    Call ParserBase class constructor and trigger Function, Operator and Constant initialization.\r
+  */\r
+  Parser::Parser()\r
+    :ParserBase()\r
+  {\r
+    AddValIdent(IsVal);\r
+\r
+    InitCharSets();\r
+    InitFun();\r
+    InitConst();\r
+    InitOprt();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Define the character sets. \r
+      \sa DefineNameChars, DefineOprtChars, DefineInfixOprtChars\r
+    \r
+    This function is used for initializing the default character sets that define\r
+    the characters to be useable in function and variable names and operators.\r
+  */\r
+  void Parser::InitCharSets()\r
+  {\r
+    DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );\r
+    DefineOprtChars( _T("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*^/?<>=#!$%&|~'_{}") );\r
+    DefineInfixOprtChars( _T("/+-*^?<>=#!$%&|~'_") );\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Initialize the default functions. */\r
+  void Parser::InitFun()\r
+  {\r
+    if (mu::TypeInfo<mu::value_type>::IsInteger())\r
+    {\r
+      // When setting MUP_BASETYPE to an integer type\r
+      // Place functions for dealing with integer values here\r
+      // ...\r
+      // ...\r
+      // ...\r
+    }\r
+    else\r
+    {\r
+      // trigonometric functions\r
+      DefineFun(_T("sin"), Sin);\r
+      DefineFun(_T("cos"), Cos);\r
+      DefineFun(_T("tan"), Tan);\r
+      // arcus functions\r
+      DefineFun(_T("asin"), ASin);\r
+      DefineFun(_T("acos"), ACos);\r
+      DefineFun(_T("atan"), ATan);\r
+      DefineFun(_T("atan2"), ATan2);\r
+      // hyperbolic functions\r
+      DefineFun(_T("sinh"), Sinh);\r
+      DefineFun(_T("cosh"), Cosh);\r
+      DefineFun(_T("tanh"), Tanh);\r
+      // arcus hyperbolic functions\r
+      DefineFun(_T("asinh"), ASinh);\r
+      DefineFun(_T("acosh"), ACosh);\r
+      DefineFun(_T("atanh"), ATanh);\r
+      // Logarithm functions\r
+      DefineFun(_T("log2"), Log2);\r
+      DefineFun(_T("log10"), Log10);\r
+      DefineFun(_T("log"), Log10);\r
+      DefineFun(_T("ln"), Ln);\r
+      // misc\r
+      DefineFun(_T("exp"), Exp);\r
+      DefineFun(_T("sqrt"), Sqrt);\r
+      DefineFun(_T("sign"), Sign);\r
+      DefineFun(_T("rint"), Rint);\r
+      DefineFun(_T("abs"), Abs);\r
+      // Functions with variable number of arguments\r
+      DefineFun(_T("sum"), Sum);\r
+      DefineFun(_T("avg"), Avg);\r
+      DefineFun(_T("min"), Min);\r
+      DefineFun(_T("max"), Max);\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Initialize constants.\r
+  \r
+    By default the parser recognizes two constants. Pi ("pi") and the eulerian\r
+    number ("_e").\r
+  */\r
+  void Parser::InitConst()\r
+  {\r
+    DefineConst(_T("_pi"), (value_type)PARSER_CONST_PI);\r
+    DefineConst(_T("_e"), (value_type)PARSER_CONST_E);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Initialize operators. \r
+  \r
+    By default only the unary minus operator is added.\r
+  */\r
+  void Parser::InitOprt()\r
+  {\r
+    DefineInfixOprt(_T("-"), UnaryMinus);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void Parser::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)\r
+  {\r
+    // this is just sample code to illustrate modifying variable names on the fly.\r
+    // I'm not sure anyone really needs such a feature...\r
+    /*\r
+\r
+\r
+    string sVar(pExpr->begin()+nStart, pExpr->begin()+nEnd);\r
+    string sRepl = std::string("_") + sVar + "_";\r
+  \r
+    int nOrigVarEnd = nEnd;\r
+    cout << "variable detected!\n";\r
+    cout << "  Expr: " << *pExpr << "\n";\r
+    cout << "  Start: " << nStart << "\n";\r
+    cout << "  End: " << nEnd << "\n";\r
+    cout << "  Var: \"" << sVar << "\"\n";\r
+    cout << "  Repl: \"" << sRepl << "\"\n";\r
+    nEnd = nStart + sRepl.length();\r
+    cout << "  End: " << nEnd << "\n";\r
+    pExpr->replace(pExpr->begin()+nStart, pExpr->begin()+nOrigVarEnd, sRepl);\r
+    cout << "  New expr: " << *pExpr << "\n";\r
+    */\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Numerically differentiate with regard to a variable. \r
+      \param [in] a_Var Pointer to the differentiation variable.\r
+      \param [in] a_fPos Position at which the differentiation should take place.\r
+      \param [in] a_fEpsilon Epsilon used for the numerical differentiation.\r
+\r
+    Numerical differentiation uses a 5 point operator yielding a 4th order \r
+    formula. The default value for epsilon is 0.00074 which is\r
+    numeric_limits<double>::epsilon() ^ (1/5) as suggested in the muparser\r
+    forum:\r
+\r
+    http://sourceforge.net/forum/forum.php?thread_id=1994611&forum_id=462843\r
+  */\r
+  value_type Parser::Diff(value_type *a_Var, \r
+                          value_type  a_fPos, \r
+                          value_type  a_fEpsilon) const\r
+  {\r
+    value_type fRes(0), \r
+               fBuf(*a_Var),\r
+               f[4] = {0,0,0,0},\r
+               fEpsilon(a_fEpsilon);\r
+\r
+    // Backwards compatible calculation of epsilon inc case the user doesnt provide\r
+    // his own epsilon\r
+    if (fEpsilon==0)\r
+      fEpsilon = (a_fPos==0) ? (value_type)1e-10 : (value_type)1e-7 * a_fPos;\r
+\r
+    *a_Var = a_fPos+2 * fEpsilon;  f[0] = Eval();\r
+    *a_Var = a_fPos+1 * fEpsilon;  f[1] = Eval();\r
+    *a_Var = a_fPos-1 * fEpsilon;  f[2] = Eval();\r
+    *a_Var = a_fPos-2 * fEpsilon;  f[3] = Eval();\r
+    *a_Var = fBuf; // restore variable\r
+\r
+    fRes = (-f[0] + 8*f[1] - 8*f[2] + f[3]) / (12*fEpsilon);\r
+    return fRes;\r
+  }\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserBase.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserBase.cpp
new file mode 100644 (file)
index 0000000..fafca6f
--- /dev/null
@@ -0,0 +1,1775 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#include "muParserBase.h"\r
+#include "muParserTemplateMagic.h"\r
+\r
+//--- Standard includes ------------------------------------------------------------------------\r
+#include <cassert>\r
+#include <cmath>\r
+#include <memory>\r
+#include <vector>\r
+#include <deque>\r
+#include <sstream>\r
+#include <locale>\r
+\r
+#ifdef MUP_USE_OPENMP\r
+  #include <omp.h>\r
+#endif\r
+\r
+using namespace std;\r
+\r
+/** \file\r
+    \brief This file contains the basic implementation of the muparser engine.\r
+*/\r
+\r
+namespace mu\r
+{\r
+  std::locale ParserBase::s_locale = std::locale(std::locale::classic(), new change_dec_sep<char_type>('.'));\r
+\r
+  bool ParserBase::g_DbgDumpCmdCode = false;\r
+  bool ParserBase::g_DbgDumpStack = false;\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Identifiers for built in binary operators. \r
+\r
+      When defining custom binary operators with #AddOprt(...) make sure not to choose \r
+      names conflicting with these definitions. \r
+  */\r
+  const char_type* ParserBase::c_DefaultOprt[] = \r
+  { \r
+    _T("<="), _T(">="),  _T("!="), \r
+    _T("=="), _T("<"),   _T(">"), \r
+    _T("+"),  _T("-"),   _T("*"), \r
+    _T("/"),  _T("^"),   _T("&&"), \r
+    _T("||"), _T("="),   _T("("),  \r
+    _T(")"),   _T("?"),  _T(":"), 0 \r
+  };\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Constructor.\r
+      \param a_szFormula the formula to interpret.\r
+      \throw ParserException if a_szFormula is null.\r
+  */\r
+  ParserBase::ParserBase()\r
+    :m_pParseFormula(&ParserBase::ParseString)\r
+    ,m_vRPN()\r
+    ,m_vStringBuf()\r
+    ,m_pTokenReader()\r
+    ,m_FunDef()\r
+    ,m_PostOprtDef()\r
+    ,m_InfixOprtDef()\r
+    ,m_OprtDef()\r
+    ,m_ConstDef()\r
+    ,m_StrVarDef()\r
+    ,m_VarDef()\r
+    ,m_bBuiltInOp(true)\r
+    ,m_sNameChars()\r
+    ,m_sOprtChars()\r
+    ,m_sInfixOprtChars()\r
+    ,m_nIfElseCounter(0)\r
+    ,m_vStackBuffer()\r
+    ,m_nFinalResultIdx(0)\r
+  {\r
+    InitTokenReader();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Copy constructor. \r
+\r
+    Tha parser can be safely copy constructed but the bytecode is reset during\r
+    copy construction.\r
+  */\r
+  ParserBase::ParserBase(const ParserBase &a_Parser)\r
+    :m_pParseFormula(&ParserBase::ParseString)\r
+    ,m_vRPN()\r
+    ,m_vStringBuf()\r
+    ,m_pTokenReader()\r
+    ,m_FunDef()\r
+    ,m_PostOprtDef()\r
+    ,m_InfixOprtDef()\r
+    ,m_OprtDef()\r
+    ,m_ConstDef()\r
+    ,m_StrVarDef()\r
+    ,m_VarDef()\r
+    ,m_bBuiltInOp(true)\r
+    ,m_sNameChars()\r
+    ,m_sOprtChars()\r
+    ,m_sInfixOprtChars()\r
+    ,m_nIfElseCounter(0)\r
+  {\r
+    m_pTokenReader.reset(new token_reader_type(this));\r
+    Assign(a_Parser);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserBase::~ParserBase()\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Assignement operator. \r
+\r
+    Implemented by calling Assign(a_Parser). Self assignement is suppressed.\r
+    \param a_Parser Object to copy to this.\r
+    \return *this\r
+    \throw nothrow\r
+  */\r
+  ParserBase& ParserBase::operator=(const ParserBase &a_Parser)\r
+  {\r
+    Assign(a_Parser);\r
+    return *this;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Copy state of a parser object to this. \r
+\r
+    Clears Variables and Functions of this parser.\r
+    Copies the states of all internal variables.\r
+    Resets parse function to string parse mode.\r
+\r
+    \param a_Parser the source object.\r
+  */\r
+  void ParserBase::Assign(const ParserBase &a_Parser)\r
+  {\r
+    if (&a_Parser==this)\r
+      return;\r
+\r
+    // Don't copy bytecode instead cause the parser to create new bytecode\r
+    // by resetting the parse function.\r
+    ReInit();\r
+\r
+    m_ConstDef        = a_Parser.m_ConstDef;         // Copy user define constants\r
+    m_VarDef          = a_Parser.m_VarDef;           // Copy user defined variables\r
+    m_bBuiltInOp      = a_Parser.m_bBuiltInOp;\r
+    m_vStringBuf      = a_Parser.m_vStringBuf;\r
+    m_vStackBuffer    = a_Parser.m_vStackBuffer;\r
+    m_nFinalResultIdx = a_Parser.m_nFinalResultIdx;\r
+    m_StrVarDef       = a_Parser.m_StrVarDef;\r
+    m_vStringVarBuf   = a_Parser.m_vStringVarBuf;\r
+    m_nIfElseCounter  = a_Parser.m_nIfElseCounter;\r
+    m_pTokenReader.reset(a_Parser.m_pTokenReader->Clone(this));\r
+\r
+    // Copy function and operator callbacks\r
+    m_FunDef = a_Parser.m_FunDef;             // Copy function definitions\r
+    m_PostOprtDef = a_Parser.m_PostOprtDef;   // post value unary operators\r
+    m_InfixOprtDef = a_Parser.m_InfixOprtDef; // unary operators for infix notation\r
+    m_OprtDef = a_Parser.m_OprtDef;           // binary operators\r
+\r
+    m_sNameChars = a_Parser.m_sNameChars;\r
+    m_sOprtChars = a_Parser.m_sOprtChars;\r
+    m_sInfixOprtChars = a_Parser.m_sInfixOprtChars;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Set the decimal separator.\r
+      \param cDecSep Decimal separator as a character value.\r
+      \sa SetThousandsSep\r
+\r
+      By default muparser uses the "C" locale. The decimal separator of this\r
+      locale is overwritten by the one provided here.\r
+  */\r
+  void ParserBase::SetDecSep(char_type cDecSep)\r
+  {\r
+    char_type cThousandsSep = std::use_facet< change_dec_sep<char_type> >(s_locale).thousands_sep();\r
+    s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>(cDecSep, cThousandsSep));\r
+  }\r
+  \r
+  //---------------------------------------------------------------------------\r
+  /** \brief Sets the thousands operator. \r
+      \param cThousandsSep The thousands separator as a character\r
+      \sa SetDecSep\r
+\r
+      By default muparser uses the "C" locale. The thousands separator of this\r
+      locale is overwritten by the one provided here.\r
+  */\r
+  void ParserBase::SetThousandsSep(char_type cThousandsSep)\r
+  {\r
+    char_type cDecSep = std::use_facet< change_dec_sep<char_type> >(s_locale).decimal_point();\r
+    s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>(cDecSep, cThousandsSep));\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Resets the locale. \r
+\r
+    The default locale used "." as decimal separator, no thousands separator and\r
+    "," as function argument separator.\r
+  */\r
+  void ParserBase::ResetLocale()\r
+  {\r
+    s_locale = std::locale(std::locale("C"), new change_dec_sep<char_type>('.'));\r
+    SetArgSep(',');\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Initialize the token reader. \r
+\r
+    Create new token reader object and submit pointers to function, operator,\r
+    constant and variable definitions.\r
+\r
+    \post m_pTokenReader.get()!=0\r
+    \throw nothrow\r
+  */\r
+  void ParserBase::InitTokenReader()\r
+  {\r
+    m_pTokenReader.reset(new token_reader_type(this));\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Reset parser to string parsing mode and clear internal buffers.\r
+\r
+      Clear bytecode, reset the token reader.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::ReInit() const\r
+  {\r
+    m_pParseFormula = &ParserBase::ParseString;\r
+    m_vStringBuf.clear();\r
+    m_vRPN.clear();\r
+    m_pTokenReader->ReInit();\r
+    m_nIfElseCounter = 0;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserBase::OnDetectVar(string_type * /*pExpr*/, int & /*nStart*/, int & /*nEnd*/)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Returns the version of muparser. \r
+      \param eInfo A flag indicating whether the full version info should be \r
+                   returned or not.\r
+\r
+    Format is as follows: "MAJOR.MINOR (COMPILER_FLAGS)" The COMPILER_FLAGS\r
+    are returned only if eInfo==pviFULL.\r
+  */\r
+  string_type ParserBase::GetVersion(EParserVersionInfo eInfo) const\r
+  {\r
+    string_type sCompileTimeSettings;\r
+    \r
+    stringstream_type ss;\r
+\r
+    ss << MUP_VERSION;\r
+\r
+    if (eInfo==pviFULL)\r
+    {\r
+      ss << _T(" (") << MUP_VERSION_DATE;\r
+      ss << std::dec << _T("; ") << sizeof(void*)*8 << _T("BIT");\r
+\r
+#ifdef _DEBUG\r
+      ss << _T("; DEBUG");\r
+#else \r
+      ss << _T("; RELEASE");\r
+#endif\r
+\r
+#ifdef _UNICODE\r
+      ss << _T("; UNICODE");\r
+#else\r
+  #ifdef _MBCS\r
+      ss << _T("; MBCS");\r
+  #else\r
+      ss << _T("; ASCII");\r
+  #endif\r
+#endif\r
+\r
+#ifdef MUP_USE_OPENMP\r
+      ss << _T("; OPENMP");\r
+//#else\r
+//      ss << _T("; NO_OPENMP");\r
+#endif\r
+\r
+#if defined(MUP_MATH_EXCEPTIONS)\r
+      ss << _T("; MATHEXC");\r
+//#else\r
+//      ss << _T("; NO_MATHEXC");\r
+#endif\r
+\r
+      ss << _T(")");\r
+    }\r
+\r
+    return ss.str();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a value parsing function. \r
+      \r
+      When parsing an expression muParser tries to detect values in the expression\r
+      string using different valident callbacks. Thuis it's possible to parse\r
+      for hex values, binary values and floating point values. \r
+  */\r
+  void ParserBase::AddValIdent(identfun_type a_pCallback)\r
+  {\r
+    m_pTokenReader->AddValIdent(a_pCallback);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Set a function that can create variable pointer for unknown expression variables. \r
+      \param a_pFactory A pointer to the variable factory.\r
+      \param pUserData A user defined context pointer.\r
+  */\r
+  void ParserBase::SetVarFactory(facfun_type a_pFactory, void *pUserData)\r
+  {\r
+    m_pTokenReader->SetVarCreator(a_pFactory, pUserData);  \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a function or operator callback to the parser. */\r
+  void ParserBase::AddCallback( const string_type &a_strName,\r
+                                const ParserCallback &a_Callback, \r
+                                funmap_type &a_Storage,\r
+                                const char_type *a_szCharSet )\r
+  {\r
+    if (a_Callback.GetAddr()==0)\r
+        Error(ecINVALID_FUN_PTR);\r
+\r
+    const funmap_type *pFunMap = &a_Storage;\r
+\r
+    // Check for conflicting operator or function names\r
+    if ( pFunMap!=&m_FunDef && m_FunDef.find(a_strName)!=m_FunDef.end() )\r
+      Error(ecNAME_CONFLICT, -1, a_strName);\r
+\r
+    if ( pFunMap!=&m_PostOprtDef && m_PostOprtDef.find(a_strName)!=m_PostOprtDef.end() )\r
+      Error(ecNAME_CONFLICT, -1, a_strName);\r
+\r
+    if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_InfixOprtDef.find(a_strName)!=m_InfixOprtDef.end() )\r
+      Error(ecNAME_CONFLICT, -1, a_strName);\r
+\r
+    if ( pFunMap!=&m_InfixOprtDef && pFunMap!=&m_OprtDef && m_OprtDef.find(a_strName)!=m_OprtDef.end() )\r
+      Error(ecNAME_CONFLICT, -1, a_strName);\r
+\r
+    CheckOprt(a_strName, a_Callback, a_szCharSet);\r
+    a_Storage[a_strName] = a_Callback;\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check if a name contains invalid characters. \r
+\r
+      \throw ParserException if the name contains invalid charakters.\r
+  */\r
+  void ParserBase::CheckOprt(const string_type &a_sName,\r
+                             const ParserCallback &a_Callback,\r
+                             const string_type &a_szCharSet) const\r
+  {\r
+    if ( !a_sName.length() ||\r
+        (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||\r
+        (a_sName[0]>='0' && a_sName[0]<='9'))\r
+    {\r
+      switch(a_Callback.GetCode())\r
+      {\r
+      case cmOPRT_POSTFIX: Error(ecINVALID_POSTFIX_IDENT, -1, a_sName);\r
+      case cmOPRT_INFIX:   Error(ecINVALID_INFIX_IDENT, -1, a_sName);\r
+      default:             Error(ecINVALID_NAME, -1, a_sName);\r
+      }\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check if a name contains invalid characters. \r
+\r
+      \throw ParserException if the name contains invalid charakters.\r
+  */\r
+  void ParserBase::CheckName(const string_type &a_sName,\r
+                             const string_type &a_szCharSet) const\r
+  {\r
+    if ( !a_sName.length() ||\r
+        (a_sName.find_first_not_of(a_szCharSet)!=string_type::npos) ||\r
+        (a_sName[0]>='0' && a_sName[0]<='9'))\r
+    {\r
+      Error(ecINVALID_NAME);\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Set the formula. \r
+      \param a_strFormula Formula as string_type\r
+      \throw ParserException in case of syntax errors.\r
+\r
+      Triggers first time calculation thus the creation of the bytecode and\r
+      scanning of used variables.\r
+  */\r
+  void ParserBase::SetExpr(const string_type &a_sExpr)\r
+  {\r
+    // Check locale compatibility\r
+    std::locale loc;\r
+    if (m_pTokenReader->GetArgSep()==std::use_facet<numpunct<char_type> >(loc).decimal_point())\r
+      Error(ecLOCALE);\r
+\r
+    // <ibg> 20060222: Bugfix for Borland-Kylix:\r
+    // adding a space to the expression will keep Borlands KYLIX from going wild\r
+    // when calling tellg on a stringstream created from the expression after \r
+    // reading a value at the end of an expression. (mu::Parser::IsVal function)\r
+    // (tellg returns -1 otherwise causing the parser to ignore the value)\r
+    string_type sBuf(a_sExpr + _T(" ") );\r
+    m_pTokenReader->SetFormula(sBuf);\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Get the default symbols used for the built in operators. \r
+      \sa c_DefaultOprt\r
+  */\r
+  const char_type** ParserBase::GetOprtDef() const\r
+  {\r
+    return (const char_type **)(&c_DefaultOprt[0]);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Define the set of valid characters to be used in names of\r
+             functions, variables, constants.\r
+  */\r
+  void ParserBase::DefineNameChars(const char_type *a_szCharset)\r
+  {\r
+    m_sNameChars = a_szCharset;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Define the set of valid characters to be used in names of\r
+             binary operators and postfix operators.\r
+  */\r
+  void ParserBase::DefineOprtChars(const char_type *a_szCharset)\r
+  {\r
+    m_sOprtChars = a_szCharset;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Define the set of valid characters to be used in names of\r
+             infix operators.\r
+  */\r
+  void ParserBase::DefineInfixOprtChars(const char_type *a_szCharset)\r
+  {\r
+    m_sInfixOprtChars = a_szCharset;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Virtual function that defines the characters allowed in name identifiers. \r
+      \sa #ValidOprtChars, #ValidPrefixOprtChars\r
+  */ \r
+  const char_type* ParserBase::ValidNameChars() const\r
+  {\r
+    assert(m_sNameChars.size());\r
+    return m_sNameChars.c_str();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Virtual function that defines the characters allowed in operator definitions. \r
+      \sa #ValidNameChars, #ValidPrefixOprtChars\r
+  */\r
+  const char_type* ParserBase::ValidOprtChars() const\r
+  {\r
+    assert(m_sOprtChars.size());\r
+    return m_sOprtChars.c_str();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Virtual function that defines the characters allowed in infix operator definitions.\r
+      \sa #ValidNameChars, #ValidOprtChars\r
+  */\r
+  const char_type* ParserBase::ValidInfixOprtChars() const\r
+  {\r
+    assert(m_sInfixOprtChars.size());\r
+    return m_sInfixOprtChars.c_str();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a user defined operator. \r
+      \post Will reset the Parser to string parsing mode.\r
+  */\r
+  void ParserBase::DefinePostfixOprt(const string_type &a_sName, \r
+                                     fun_type1 a_pFun,\r
+                                     bool a_bAllowOpt)\r
+  {\r
+    AddCallback(a_sName, \r
+                ParserCallback(a_pFun, a_bAllowOpt, prPOSTFIX, cmOPRT_POSTFIX),\r
+                m_PostOprtDef, \r
+                ValidOprtChars() );\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Initialize user defined functions. \r
+   \r
+    Calls the virtual functions InitFun(), InitConst() and InitOprt().\r
+  */\r
+  void ParserBase::Init()\r
+  {\r
+    InitCharSets();\r
+    InitFun();\r
+    InitConst();\r
+    InitOprt();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a user defined operator. \r
+      \post Will reset the Parser to string parsing mode.\r
+      \param [in] a_sName  operator Identifier \r
+      \param [in] a_pFun  Operator callback function\r
+      \param [in] a_iPrec  Operator Precedence (default=prSIGN)\r
+      \param [in] a_bAllowOpt  True if operator is volatile (default=false)\r
+      \sa EPrec\r
+  */\r
+  void ParserBase::DefineInfixOprt(const string_type &a_sName, \r
+                                  fun_type1 a_pFun, \r
+                                  int a_iPrec, \r
+                                  bool a_bAllowOpt)\r
+  {\r
+    AddCallback(a_sName, \r
+                ParserCallback(a_pFun, a_bAllowOpt, a_iPrec, cmOPRT_INFIX), \r
+                m_InfixOprtDef, \r
+                ValidInfixOprtChars() );\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Define a binary operator. \r
+      \param [in] a_sName The identifier of the operator.\r
+      \param [in] a_pFun Pointer to the callback function.\r
+      \param [in] a_iPrec Precedence of the operator.\r
+      \param [in] a_eAssociativity The associativity of the operator.\r
+      \param [in] a_bAllowOpt If this is true the operator may be optimized away.\r
+      \r
+      Adds a new Binary operator the the parser instance. \r
+  */\r
+  void ParserBase::DefineOprt( const string_type &a_sName, \r
+                               fun_type2 a_pFun, \r
+                               unsigned a_iPrec, \r
+                               EOprtAssociativity a_eAssociativity,\r
+                               bool a_bAllowOpt )\r
+  {\r
+    // Check for conflicts with built in operator names\r
+    for (int i=0; m_bBuiltInOp && i<cmENDIF; ++i)\r
+      if (a_sName == string_type(c_DefaultOprt[i]))\r
+        Error(ecBUILTIN_OVERLOAD, -1, a_sName);\r
+\r
+    AddCallback(a_sName, \r
+                ParserCallback(a_pFun, a_bAllowOpt, a_iPrec, a_eAssociativity), \r
+                m_OprtDef, \r
+                ValidOprtChars() );\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Define a new string constant.\r
+      \param [in] a_strName The name of the constant.\r
+      \param [in] a_strVal the value of the constant. \r
+  */\r
+  void ParserBase::DefineStrConst(const string_type &a_strName, const string_type &a_strVal)\r
+  {\r
+    // Test if a constant with that names already exists\r
+    if (m_StrVarDef.find(a_strName)!=m_StrVarDef.end())\r
+      Error(ecNAME_CONFLICT);\r
+\r
+    CheckName(a_strName, ValidNameChars());\r
+    \r
+    m_vStringVarBuf.push_back(a_strVal);           // Store variable string in internal buffer\r
+    m_StrVarDef[a_strName] = m_vStringBuf.size();  // bind buffer index to variable name\r
+\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a user defined variable. \r
+      \param [in] a_sName the variable name\r
+      \param [in] a_pVar A pointer to the variable vaule.\r
+      \post Will reset the Parser to string parsing mode.\r
+      \throw ParserException in case the name contains invalid signs or a_pVar is NULL.\r
+  */\r
+  void ParserBase::DefineVar(const string_type &a_sName, value_type *a_pVar)\r
+  {\r
+    if (a_pVar==0)\r
+      Error(ecINVALID_VAR_PTR);\r
+\r
+    // Test if a constant with that names already exists\r
+    if (m_ConstDef.find(a_sName)!=m_ConstDef.end())\r
+      Error(ecNAME_CONFLICT);\r
+\r
+    CheckName(a_sName, ValidNameChars());\r
+    m_VarDef[a_sName] = a_pVar;\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a user defined constant. \r
+      \param [in] a_sName The name of the constant.\r
+      \param [in] a_fVal the value of the constant.\r
+      \post Will reset the Parser to string parsing mode.\r
+      \throw ParserException in case the name contains invalid signs.\r
+  */\r
+  void ParserBase::DefineConst(const string_type &a_sName, value_type a_fVal)\r
+  {\r
+    CheckName(a_sName, ValidNameChars());\r
+    m_ConstDef[a_sName] = a_fVal;\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Get operator priority.\r
+      \throw ParserException if a_Oprt is no operator code\r
+  */\r
+  int ParserBase::GetOprtPrecedence(const token_type &a_Tok) const\r
+  {\r
+    switch (a_Tok.GetCode())\r
+    {\r
+    // built in operators\r
+    case cmEND:      return -5;\r
+    case cmARG_SEP:  return -4;\r
+    case cmASSIGN:   return -1;               \r
+    case cmELSE:\r
+    case cmIF:       return  0;\r
+    case cmLAND:     return  prLAND;\r
+    case cmLOR:      return  prLOR;\r
+    case cmLT:\r
+    case cmGT:\r
+    case cmLE:\r
+    case cmGE:\r
+    case cmNEQ:\r
+    case cmEQ:       return  prCMP; \r
+    case cmADD:\r
+    case cmSUB:      return  prADD_SUB;\r
+    case cmMUL:\r
+    case cmDIV:      return  prMUL_DIV;\r
+    case cmPOW:      return  prPOW;\r
+\r
+    // user defined binary operators\r
+    case cmOPRT_INFIX: \r
+    case cmOPRT_BIN: return a_Tok.GetPri();\r
+    default:  Error(ecINTERNAL_ERROR, 5);\r
+              return 999;\r
+    }  \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Get operator priority.\r
+      \throw ParserException if a_Oprt is no operator code\r
+  */\r
+  EOprtAssociativity ParserBase::GetOprtAssociativity(const token_type &a_Tok) const\r
+  {\r
+    switch (a_Tok.GetCode())\r
+    {\r
+    case cmASSIGN:\r
+    case cmLAND:\r
+    case cmLOR:\r
+    case cmLT:\r
+    case cmGT:\r
+    case cmLE:\r
+    case cmGE:\r
+    case cmNEQ:\r
+    case cmEQ: \r
+    case cmADD:\r
+    case cmSUB:\r
+    case cmMUL:\r
+    case cmDIV:      return oaLEFT;\r
+    case cmPOW:      return oaRIGHT;\r
+    case cmOPRT_BIN: return a_Tok.GetAssociativity();\r
+    default:         return oaNONE;\r
+    }  \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return a map containing the used variables only. */\r
+  const varmap_type& ParserBase::GetUsedVar() const\r
+  {\r
+    try\r
+    {\r
+      m_pTokenReader->IgnoreUndefVar(true);\r
+      CreateRPN(); // try to create bytecode, but don't use it for any further calculations since it\r
+                   // may contain references to nonexisting variables.\r
+      m_pParseFormula = &ParserBase::ParseString;\r
+      m_pTokenReader->IgnoreUndefVar(false);\r
+    }\r
+    catch(exception_type &e)\r
+    {\r
+      // Make sure to stay in string parse mode, dont call ReInit()\r
+      // because it deletes the array with the used variables\r
+      m_pParseFormula = &ParserBase::ParseString;\r
+      m_pTokenReader->IgnoreUndefVar(false);\r
+      throw e;\r
+    }\r
+    \r
+    return m_pTokenReader->GetUsedVar();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return a map containing the used variables only. */\r
+  const varmap_type& ParserBase::GetVar() const\r
+  {\r
+    return m_VarDef;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return a map containing all parser constants. */\r
+  const valmap_type& ParserBase::GetConst() const\r
+  {\r
+    return m_ConstDef;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return prototypes of all parser functions.\r
+      \return #m_FunDef\r
+      \sa FunProt\r
+      \throw nothrow\r
+      \r
+      The return type is a map of the public type #funmap_type containing the prototype\r
+      definitions for all numerical parser functions. String functions are not part of \r
+      this map. The Prototype definition is encapsulated in objects of the class FunProt\r
+      one per parser function each associated with function names via a map construct.\r
+  */\r
+  const funmap_type& ParserBase::GetFunDef() const\r
+  {\r
+    return m_FunDef;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Retrieve the formula. */\r
+  const string_type& ParserBase::GetExpr() const\r
+  {\r
+    return m_pTokenReader->GetExpr();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Execute a function that takes a single string argument.\r
+      \param a_FunTok Function token.\r
+      \throw exception_type If the function token is not a string function\r
+  */\r
+  ParserBase::token_type ParserBase::ApplyStrFunc(const token_type &a_FunTok,\r
+                                                  const std::vector<token_type> &a_vArg) const\r
+  {\r
+    if (a_vArg.back().GetCode()!=cmSTRING)\r
+      Error(ecSTRING_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString());\r
+\r
+    token_type  valTok;\r
+    generic_fun_type pFunc = a_FunTok.GetFuncAddr();\r
+    assert(pFunc);\r
+\r
+    try\r
+    {\r
+      // Check function arguments; write dummy value into valtok to represent the result\r
+      switch(a_FunTok.GetArgCount())\r
+      {\r
+      case 0: valTok.SetVal(1); a_vArg[0].GetAsString();  break;\r
+      case 1: valTok.SetVal(1); a_vArg[1].GetAsString();  a_vArg[0].GetVal();  break;\r
+      case 2: valTok.SetVal(1); a_vArg[2].GetAsString();  a_vArg[1].GetVal();  a_vArg[0].GetVal();  break;\r
+      default: Error(ecINTERNAL_ERROR);\r
+      }\r
+    }\r
+    catch(ParserError& )\r
+    {\r
+      Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), a_FunTok.GetAsString());\r
+    }\r
+\r
+    // string functions won't be optimized\r
+    m_vRPN.AddStrFun(pFunc, a_FunTok.GetArgCount(), a_vArg.back().GetIdx());\r
+    \r
+    // Push dummy value representing the function result to the stack\r
+    return valTok;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Apply a function token. \r
+      \param iArgCount Number of Arguments actually gathered used only for multiarg functions.\r
+      \post The result is pushed to the value stack\r
+      \post The function token is removed from the stack\r
+      \throw exception_type if Argument count does not mach function requirements.\r
+  */\r
+  void ParserBase::ApplyFunc( ParserStack<token_type> &a_stOpt,\r
+                              ParserStack<token_type> &a_stVal, \r
+                              int a_iArgCount) const\r
+  { \r
+    assert(m_pTokenReader.get());\r
+\r
+    // Operator stack empty or does not contain tokens with callback functions\r
+    if (a_stOpt.empty() || a_stOpt.top().GetFuncAddr()==0 )\r
+      return;\r
+\r
+    token_type funTok = a_stOpt.pop();\r
+    assert(funTok.GetFuncAddr());\r
+\r
+    // Binary operators must rely on their internal operator number\r
+    // since counting of operators relies on commas for function arguments\r
+    // binary operators do not have commas in their expression\r
+    int iArgCount = (funTok.GetCode()==cmOPRT_BIN) ? funTok.GetArgCount() : a_iArgCount;\r
+\r
+    // determine how many parameters the function needs. To remember iArgCount includes the \r
+    // string parameter whilst GetArgCount() counts only numeric parameters.\r
+    int iArgRequired = funTok.GetArgCount() + ((funTok.GetType()==tpSTR) ? 1 : 0);\r
+\r
+    // Thats the number of numerical parameters\r
+    int iArgNumerical = iArgCount - ((funTok.GetType()==tpSTR) ? 1 : 0);\r
+\r
+    if (funTok.GetCode()==cmFUNC_STR && iArgCount-iArgNumerical>1)\r
+      Error(ecINTERNAL_ERROR);\r
+\r
+    if (funTok.GetArgCount()>=0 && iArgCount>iArgRequired) \r
+      Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());\r
+\r
+    if (funTok.GetCode()!=cmOPRT_BIN && iArgCount<iArgRequired )\r
+      Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());\r
+\r
+    if (funTok.GetCode()==cmFUNC_STR && iArgCount>iArgRequired )\r
+      Error(ecTOO_MANY_PARAMS, m_pTokenReader->GetPos()-1, funTok.GetAsString());\r
+\r
+    // Collect the numeric function arguments from the value stack and store them\r
+    // in a vector\r
+    std::vector<token_type> stArg;  \r
+    for (int i=0; i<iArgNumerical; ++i)\r
+    {\r
+      stArg.push_back( a_stVal.pop() );\r
+      if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )\r
+        Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());\r
+    }\r
+\r
+    switch(funTok.GetCode())\r
+    {\r
+    case  cmFUNC_STR:  \r
+          stArg.push_back(a_stVal.pop());\r
+          \r
+          if ( stArg.back().GetType()==tpSTR && funTok.GetType()!=tpSTR )\r
+            Error(ecVAL_EXPECTED, m_pTokenReader->GetPos(), funTok.GetAsString());\r
+\r
+          ApplyStrFunc(funTok, stArg); \r
+          break;\r
+\r
+    case  cmFUNC_BULK: \r
+          m_vRPN.AddBulkFun(funTok.GetFuncAddr(), (int)stArg.size()); \r
+          break;\r
+\r
+    case  cmOPRT_BIN:\r
+    case  cmOPRT_POSTFIX:\r
+    case  cmOPRT_INFIX:\r
+    case  cmFUNC:\r
+          if (funTok.GetArgCount()==-1 && iArgCount==0)\r
+            Error(ecTOO_FEW_PARAMS, m_pTokenReader->GetPos(), funTok.GetAsString());\r
+\r
+          m_vRPN.AddFun(funTok.GetFuncAddr(), (funTok.GetArgCount()==-1) ? -iArgNumerical : iArgNumerical);\r
+          break;\r
+    }\r
+\r
+    // Push dummy value representing the function result to the stack\r
+    token_type token;\r
+    token.SetVal(1);  \r
+    a_stVal.push(token);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserBase::ApplyIfElse(ParserStack<token_type> &a_stOpt,\r
+                               ParserStack<token_type> &a_stVal) const\r
+  {\r
+    // Check if there is an if Else clause to be calculated\r
+    while (a_stOpt.size() && a_stOpt.top().GetCode()==cmELSE)\r
+    {\r
+      token_type opElse = a_stOpt.pop();\r
+      MUP_ASSERT(a_stOpt.size()>0);\r
+\r
+      // Take the value associated with the else branch from the value stack\r
+      token_type vVal2 = a_stVal.pop();\r
+\r
+      MUP_ASSERT(a_stOpt.size()>0);\r
+      MUP_ASSERT(a_stVal.size()>=2);\r
+\r
+      // it then else is a ternary operator Pop all three values from the value s\r
+      // tack and just return the right value\r
+      token_type vVal1 = a_stVal.pop();\r
+      token_type vExpr = a_stVal.pop();\r
+\r
+      a_stVal.push( (vExpr.GetVal()!=0) ? vVal1 : vVal2);\r
+\r
+      token_type opIf = a_stOpt.pop();\r
+      MUP_ASSERT(opElse.GetCode()==cmELSE);\r
+      MUP_ASSERT(opIf.GetCode()==cmIF);\r
+\r
+      m_vRPN.AddIfElse(cmENDIF);\r
+    } // while pending if-else-clause found\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Performs the necessary steps to write code for\r
+             the execution of binary operators into the bytecode. \r
+  */\r
+  void ParserBase::ApplyBinOprt(ParserStack<token_type> &a_stOpt,\r
+                                ParserStack<token_type> &a_stVal) const\r
+  {\r
+    // is it a user defined binary operator?\r
+    if (a_stOpt.top().GetCode()==cmOPRT_BIN)\r
+    {\r
+      ApplyFunc(a_stOpt, a_stVal, 2);\r
+    }\r
+    else\r
+    {\r
+      MUP_ASSERT(a_stVal.size()>=2);\r
+      token_type valTok1 = a_stVal.pop(),\r
+                 valTok2 = a_stVal.pop(),\r
+                 optTok  = a_stOpt.pop(),\r
+                 resTok; \r
+\r
+      if ( valTok1.GetType()!=valTok2.GetType() || \r
+          (valTok1.GetType()==tpSTR && valTok2.GetType()==tpSTR) )\r
+        Error(ecOPRT_TYPE_CONFLICT, m_pTokenReader->GetPos(), optTok.GetAsString());\r
+\r
+      if (optTok.GetCode()==cmASSIGN)\r
+      {\r
+        if (valTok2.GetCode()!=cmVAR)\r
+          Error(ecUNEXPECTED_OPERATOR, -1, _T("="));\r
+                      \r
+        m_vRPN.AddAssignOp(valTok2.GetVar());\r
+      }\r
+      else\r
+        m_vRPN.AddOp(optTok.GetCode());\r
+\r
+      resTok.SetVal(1);\r
+      a_stVal.push(resTok);\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Apply a binary operator. \r
+      \param a_stOpt The operator stack\r
+      \param a_stVal The value stack\r
+  */\r
+  void ParserBase::ApplyRemainingOprt(ParserStack<token_type> &stOpt,\r
+                                      ParserStack<token_type> &stVal) const\r
+  {\r
+    while (stOpt.size() && \r
+           stOpt.top().GetCode() != cmBO &&\r
+           stOpt.top().GetCode() != cmIF)\r
+    {\r
+      token_type tok = stOpt.top();\r
+      switch (tok.GetCode())\r
+      {\r
+      case cmOPRT_INFIX:\r
+      case cmOPRT_BIN:\r
+      case cmLE:\r
+      case cmGE:\r
+      case cmNEQ:\r
+      case cmEQ:\r
+      case cmLT:\r
+      case cmGT:\r
+      case cmADD:\r
+      case cmSUB:\r
+      case cmMUL:\r
+      case cmDIV:\r
+      case cmPOW:\r
+      case cmLAND:\r
+      case cmLOR:\r
+      case cmASSIGN:\r
+          if (stOpt.top().GetCode()==cmOPRT_INFIX)\r
+            ApplyFunc(stOpt, stVal, 1);\r
+          else\r
+            ApplyBinOprt(stOpt, stVal);\r
+          break;\r
+\r
+      case cmELSE:\r
+          ApplyIfElse(stOpt, stVal);\r
+          break;\r
+\r
+      default:\r
+          Error(ecINTERNAL_ERROR);\r
+      }\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Parse the command code.\r
+      \sa ParseString(...)\r
+\r
+      Command code contains precalculated stack positions of the values and the\r
+      associated operators. The Stack is filled beginning from index one the \r
+      value at index zero is not used at all.\r
+  */\r
+  value_type ParserBase::ParseCmdCode() const\r
+  {\r
+    return ParseCmdCodeBulk(0, 0);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Evaluate the RPN. \r
+      \param nOffset The offset added to variable addresses (for bulk mode)\r
+      \param nThreadID OpenMP Thread id of the calling thread\r
+  */\r
+  value_type ParserBase::ParseCmdCodeBulk(int nOffset, int nThreadID) const\r
+  {\r
+    assert(nThreadID<=s_MaxNumOpenMPThreads);\r
+\r
+    // Note: The check for nOffset==0 and nThreadID here is not necessary but \r
+    //       brings a minor performance gain when not in bulk mode.\r
+    value_type *Stack = ((nOffset==0) && (nThreadID==0)) ? &m_vStackBuffer[0] : &m_vStackBuffer[nThreadID * (m_vStackBuffer.size() / s_MaxNumOpenMPThreads)];\r
+    value_type buf;\r
+    int sidx(0);\r
+    for (const SToken *pTok = m_vRPN.GetBase(); pTok->Cmd!=cmEND ; ++pTok)\r
+    {\r
+      switch (pTok->Cmd)\r
+      {\r
+      // built in binary operators\r
+      case  cmLE:   --sidx; Stack[sidx]  = Stack[sidx] <= Stack[sidx+1]; continue;\r
+      case  cmGE:   --sidx; Stack[sidx]  = Stack[sidx] >= Stack[sidx+1]; continue;\r
+      case  cmNEQ:  --sidx; Stack[sidx]  = Stack[sidx] != Stack[sidx+1]; continue;\r
+      case  cmEQ:   --sidx; Stack[sidx]  = Stack[sidx] == Stack[sidx+1]; continue;\r
+      case  cmLT:   --sidx; Stack[sidx]  = Stack[sidx] < Stack[sidx+1];  continue;\r
+      case  cmGT:   --sidx; Stack[sidx]  = Stack[sidx] > Stack[sidx+1];  continue;\r
+      case  cmADD:  --sidx; Stack[sidx] += Stack[1+sidx]; continue;\r
+      case  cmSUB:  --sidx; Stack[sidx] -= Stack[1+sidx]; continue;\r
+      case  cmMUL:  --sidx; Stack[sidx] *= Stack[1+sidx]; continue;\r
+      case  cmDIV:  --sidx;\r
+\r
+  #if defined(MUP_MATH_EXCEPTIONS)\r
+                  if (Stack[1+sidx]==0)\r
+                    Error(ecDIV_BY_ZERO);\r
+  #endif\r
+                  Stack[sidx] /= Stack[1+sidx]; \r
+                  continue;\r
+\r
+      case  cmPOW: \r
+              --sidx; Stack[sidx] = MathImpl<value_type>::Pow(Stack[sidx], Stack[1+sidx]);\r
+              continue;\r
+\r
+      case  cmLAND: --sidx; Stack[sidx]  = Stack[sidx] && Stack[sidx+1]; continue;\r
+      case  cmLOR:  --sidx; Stack[sidx]  = Stack[sidx] || Stack[sidx+1]; continue;\r
+\r
+      case  cmASSIGN: \r
+            --sidx; Stack[sidx] = *pTok->Oprt.ptr = Stack[sidx+1]; continue;\r
+\r
+      //case  cmBO:  // unused, listed for compiler optimization purposes\r
+      //case  cmBC:\r
+      //      MUP_FAIL(INVALID_CODE_IN_BYTECODE);\r
+      //      continue;\r
+\r
+      case  cmIF:\r
+            if (Stack[sidx--]==0)\r
+              pTok += pTok->Oprt.offset;\r
+            continue;\r
+\r
+      case  cmELSE:\r
+            pTok += pTok->Oprt.offset;\r
+            continue;\r
+\r
+      case  cmENDIF:\r
+            continue;\r
+\r
+      //case  cmARG_SEP:\r
+      //      MUP_FAIL(INVALID_CODE_IN_BYTECODE);\r
+      //      continue;\r
+\r
+      // value and variable tokens\r
+      case  cmVAR:    Stack[++sidx] = *(pTok->Val.ptr + nOffset);  continue;\r
+      case  cmVAL:    Stack[++sidx] =  pTok->Val.data2;  continue;\r
+      \r
+      case  cmVARPOW2: buf = *(pTok->Val.ptr + nOffset);\r
+                       Stack[++sidx] = buf*buf;\r
+                       continue;\r
+\r
+      case  cmVARPOW3: buf = *(pTok->Val.ptr + nOffset);\r
+                       Stack[++sidx] = buf*buf*buf;\r
+                       continue;\r
+\r
+      case  cmVARPOW4: buf = *(pTok->Val.ptr + nOffset);\r
+                       Stack[++sidx] = buf*buf*buf*buf;\r
+                       continue;\r
+      \r
+      case  cmVARMUL:  Stack[++sidx] = *(pTok->Val.ptr + nOffset) * pTok->Val.data + pTok->Val.data2;\r
+                       continue;\r
+\r
+      // Next is treatment of numeric functions\r
+      case  cmFUNC:\r
+            {\r
+              int iArgCount = pTok->Fun.argc;\r
+\r
+              // switch according to argument count\r
+              switch(iArgCount)  \r
+              {\r
+              case 0: sidx += 1; Stack[sidx] = (*(fun_type0)pTok->Fun.ptr)(); continue;\r
+              case 1:            Stack[sidx] = (*(fun_type1)pTok->Fun.ptr)(Stack[sidx]);   continue;\r
+              case 2: sidx -= 1; Stack[sidx] = (*(fun_type2)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1]); continue;\r
+              case 3: sidx -= 2; Stack[sidx] = (*(fun_type3)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;\r
+              case 4: sidx -= 3; Stack[sidx] = (*(fun_type4)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;\r
+              case 5: sidx -= 4; Stack[sidx] = (*(fun_type5)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;\r
+              case 6: sidx -= 5; Stack[sidx] = (*(fun_type6)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;\r
+              case 7: sidx -= 6; Stack[sidx] = (*(fun_type7)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;\r
+              case 8: sidx -= 7; Stack[sidx] = (*(fun_type8)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;\r
+              case 9: sidx -= 8; Stack[sidx] = (*(fun_type9)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;\r
+              case 10:sidx -= 9; Stack[sidx] = (*(fun_type10)pTok->Fun.ptr)(Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;\r
+              default:\r
+                if (iArgCount>0) // function with variable arguments store the number as a negative value\r
+                  Error(ecINTERNAL_ERROR, 1);\r
+\r
+                sidx -= -iArgCount - 1;\r
+                Stack[sidx] =(*(multfun_type)pTok->Fun.ptr)(&Stack[sidx], -iArgCount);\r
+                continue;\r
+              }\r
+            }\r
+\r
+      // Next is treatment of string functions\r
+      case  cmFUNC_STR:\r
+            {\r
+              sidx -= pTok->Fun.argc -1;\r
+\r
+              // The index of the string argument in the string table\r
+              int iIdxStack = pTok->Fun.idx;  \r
+              MUP_ASSERT( iIdxStack>=0 && iIdxStack<(int)m_vStringBuf.size() );\r
+\r
+              switch(pTok->Fun.argc)  // switch according to argument count\r
+              {\r
+              case 0: Stack[sidx] = (*(strfun_type1)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str()); continue;\r
+              case 1: Stack[sidx] = (*(strfun_type2)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx]); continue;\r
+              case 2: Stack[sidx] = (*(strfun_type3)pTok->Fun.ptr)(m_vStringBuf[iIdxStack].c_str(), Stack[sidx], Stack[sidx+1]); continue;\r
+              }\r
+\r
+              continue;\r
+            }\r
+\r
+        case  cmFUNC_BULK:\r
+              {\r
+                int iArgCount = pTok->Fun.argc;\r
+\r
+                // switch according to argument count\r
+                switch(iArgCount)  \r
+                {\r
+                case 0: sidx += 1; Stack[sidx] = (*(bulkfun_type0 )pTok->Fun.ptr)(nOffset, nThreadID); continue;\r
+                case 1:            Stack[sidx] = (*(bulkfun_type1 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx]); continue;\r
+                case 2: sidx -= 1; Stack[sidx] = (*(bulkfun_type2 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1]); continue;\r
+                case 3: sidx -= 2; Stack[sidx] = (*(bulkfun_type3 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2]); continue;\r
+                case 4: sidx -= 3; Stack[sidx] = (*(bulkfun_type4 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3]); continue;\r
+                case 5: sidx -= 4; Stack[sidx] = (*(bulkfun_type5 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4]); continue;\r
+                case 6: sidx -= 5; Stack[sidx] = (*(bulkfun_type6 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5]); continue;\r
+                case 7: sidx -= 6; Stack[sidx] = (*(bulkfun_type7 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6]); continue;\r
+                case 8: sidx -= 7; Stack[sidx] = (*(bulkfun_type8 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7]); continue;\r
+                case 9: sidx -= 8; Stack[sidx] = (*(bulkfun_type9 )pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8]); continue;\r
+                case 10:sidx -= 9; Stack[sidx] = (*(bulkfun_type10)pTok->Fun.ptr)(nOffset, nThreadID, Stack[sidx], Stack[sidx+1], Stack[sidx+2], Stack[sidx+3], Stack[sidx+4], Stack[sidx+5], Stack[sidx+6], Stack[sidx+7], Stack[sidx+8], Stack[sidx+9]); continue;\r
+                default:\r
+                  Error(ecINTERNAL_ERROR, 2);\r
+                  continue;\r
+                }\r
+              }\r
+\r
+        //case  cmSTRING:\r
+        //case  cmOPRT_BIN:\r
+        //case  cmOPRT_POSTFIX:\r
+        //case  cmOPRT_INFIX:\r
+        //      MUP_FAIL(INVALID_CODE_IN_BYTECODE);\r
+        //      continue;\r
+\r
+        //case  cmEND:\r
+              //     return Stack[m_nFinalResultIdx];  \r
+\r
+        default:\r
+              Error(ecINTERNAL_ERROR, 3);\r
+              return 0;\r
+      } // switch CmdCode\r
+    } // for all bytecode tokens\r
+\r
+    return Stack[m_nFinalResultIdx];  \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserBase::CreateRPN() const\r
+  {\r
+    if (!m_pTokenReader->GetExpr().length())\r
+      Error(ecUNEXPECTED_EOF, 0);\r
+\r
+    ParserStack<token_type> stOpt, stVal;\r
+    ParserStack<int> stArgCount;\r
+    token_type opta, opt;  // for storing operators\r
+    token_type val, tval;  // for storing value\r
+    string_type strBuf;    // buffer for string function arguments\r
+\r
+    ReInit();\r
+    \r
+    // The outermost counter counts the number of seperated items\r
+    // such as in "a=10,b=20,c=c+a"\r
+    stArgCount.push(1);\r
+    \r
+    for(;;)\r
+    {\r
+      opt = m_pTokenReader->ReadNextToken();\r
+\r
+      switch (opt.GetCode())\r
+      {\r
+        //\r
+        // Next three are different kind of value entries\r
+        //\r
+        case cmSTRING:\r
+                opt.SetIdx((int)m_vStringBuf.size());      // Assign buffer index to token \r
+                stVal.push(opt);\r
+                           m_vStringBuf.push_back(opt.GetAsString()); // Store string in internal buffer\r
+                break;\r
+   \r
+        case cmVAR:\r
+                stVal.push(opt);\r
+                m_vRPN.AddVar( static_cast<value_type*>(opt.GetVar()) );\r
+                break;\r
+\r
+        case cmVAL:\r
+                           stVal.push(opt);\r
+                m_vRPN.AddVal( opt.GetVal() );\r
+                break;\r
+\r
+        case cmELSE:\r
+                m_nIfElseCounter--;\r
+                if (m_nIfElseCounter<0)\r
+                  Error(ecMISPLACED_COLON, m_pTokenReader->GetPos());\r
+\r
+                ApplyRemainingOprt(stOpt, stVal);\r
+                m_vRPN.AddIfElse(cmELSE);\r
+                stOpt.push(opt);\r
+                break;\r
+\r
+\r
+        case cmARG_SEP:\r
+                if (stArgCount.empty())\r
+                  Error(ecUNEXPECTED_ARG_SEP, m_pTokenReader->GetPos());\r
+\r
+                ++stArgCount.top();\r
+                // fallthrough intentional (no break!)\r
+\r
+        case cmEND:\r
+                ApplyRemainingOprt(stOpt, stVal);\r
+                break;\r
+\r
+       case cmBC:\r
+                {\r
+                  // The argument count for parameterless functions is zero\r
+                  // by default an opening bracket sets parameter count to 1\r
+                  // in preparation of arguments to come. If the last token\r
+                  // was an opening bracket we know better...\r
+                  if (opta.GetCode()==cmBO)\r
+                    --stArgCount.top();\r
+                  \r
+                  ApplyRemainingOprt(stOpt, stVal);\r
+\r
+                  // Check if the bracket content has been evaluated completely\r
+                  if (stOpt.size() && stOpt.top().GetCode()==cmBO)\r
+                  {\r
+                    // if opt is ")" and opta is "(" the bracket has been evaluated, now its time to check\r
+                    // if there is either a function or a sign pending\r
+                    // neither the opening nor the closing bracket will be pushed back to\r
+                    // the operator stack\r
+                    // Check if a function is standing in front of the opening bracket, \r
+                    // if yes evaluate it afterwards check for infix operators\r
+                    assert(stArgCount.size());\r
+                    int iArgCount = stArgCount.pop();\r
+                    \r
+                    stOpt.pop(); // Take opening bracket from stack\r
+\r
+                    if (iArgCount>1 && ( stOpt.size()==0 || \r
+                                        (stOpt.top().GetCode()!=cmFUNC && \r
+                                         stOpt.top().GetCode()!=cmFUNC_BULK && \r
+                                         stOpt.top().GetCode()!=cmFUNC_STR) ) )\r
+                      Error(ecUNEXPECTED_ARG, m_pTokenReader->GetPos());\r
+                    \r
+                    // The opening bracket was popped from the stack now check if there\r
+                    // was a function before this bracket\r
+                    if (stOpt.size() && \r
+                        stOpt.top().GetCode()!=cmOPRT_INFIX && \r
+                        stOpt.top().GetCode()!=cmOPRT_BIN && \r
+                        stOpt.top().GetFuncAddr()!=0)\r
+                    {\r
+                      ApplyFunc(stOpt, stVal, iArgCount);\r
+                    }\r
+                  }\r
+                } // if bracket content is evaluated\r
+                break;\r
+\r
+        //\r
+        // Next are the binary operator entries\r
+        //\r
+        //case cmAND:   // built in binary operators\r
+        //case cmOR:\r
+        //case cmXOR:\r
+        case cmIF:\r
+                m_nIfElseCounter++;\r
+                // fallthrough intentional (no break!)\r
+\r
+        case cmLAND:\r
+        case cmLOR:\r
+        case cmLT:\r
+        case cmGT:\r
+        case cmLE:\r
+        case cmGE:\r
+        case cmNEQ:\r
+        case cmEQ:\r
+        case cmADD:\r
+        case cmSUB:\r
+        case cmMUL:\r
+        case cmDIV:\r
+        case cmPOW:\r
+        case cmASSIGN:\r
+        case cmOPRT_BIN:\r
+\r
+                // A binary operator (user defined or built in) has been found. \r
+                while ( stOpt.size() && \r
+                        stOpt.top().GetCode() != cmBO &&\r
+                        stOpt.top().GetCode() != cmELSE &&\r
+                        stOpt.top().GetCode() != cmIF)\r
+                {\r
+                  int nPrec1 = GetOprtPrecedence(stOpt.top()),\r
+                      nPrec2 = GetOprtPrecedence(opt);\r
+\r
+                  if (stOpt.top().GetCode()==opt.GetCode())\r
+                  {\r
+\r
+                    // Deal with operator associativity\r
+                    EOprtAssociativity eOprtAsct = GetOprtAssociativity(opt);\r
+                    if ( (eOprtAsct==oaRIGHT && (nPrec1 <= nPrec2)) || \r
+                         (eOprtAsct==oaLEFT  && (nPrec1 <  nPrec2)) )\r
+                    {\r
+                      break;\r
+                    }\r
+                  }\r
+                  else if (nPrec1 < nPrec2)\r
+                  {\r
+                    // In case the operators are not equal the precedence decides alone...\r
+                    break;\r
+                  }\r
+                  \r
+                  if (stOpt.top().GetCode()==cmOPRT_INFIX)\r
+                    ApplyFunc(stOpt, stVal, 1);\r
+                  else\r
+                    ApplyBinOprt(stOpt, stVal);\r
+                } // while ( ... )\r
+\r
+                if (opt.GetCode()==cmIF)\r
+                  m_vRPN.AddIfElse(opt.GetCode());\r
+\r
+                             // The operator can't be evaluated right now, push back to the operator stack\r
+                stOpt.push(opt);\r
+                break;\r
+\r
+        //\r
+        // Last section contains functions and operators implicitely mapped to functions\r
+        //\r
+        case cmBO:\r
+                stArgCount.push(1);\r
+                stOpt.push(opt);\r
+                break;\r
+\r
+        case cmOPRT_INFIX:\r
+        case cmFUNC:\r
+        case cmFUNC_BULK:\r
+        case cmFUNC_STR:  \r
+                stOpt.push(opt);\r
+                break;\r
+\r
+        case cmOPRT_POSTFIX:\r
+                stOpt.push(opt);\r
+                ApplyFunc(stOpt, stVal, 1);  // this is the postfix operator\r
+                break;\r
+\r
+        default:  Error(ecINTERNAL_ERROR, 3);\r
+      } // end of switch operator-token\r
+\r
+      opta = opt;\r
+\r
+      if ( opt.GetCode() == cmEND )\r
+      {\r
+        m_vRPN.Finalize();\r
+        break;\r
+      }\r
+\r
+      if (ParserBase::g_DbgDumpStack)\r
+      {\r
+        StackDump(stVal, stOpt);\r
+        m_vRPN.AsciiDump();\r
+      }\r
+    } // while (true)\r
+\r
+    if (ParserBase::g_DbgDumpCmdCode)\r
+      m_vRPN.AsciiDump();\r
+\r
+    if (m_nIfElseCounter>0)\r
+      Error(ecMISSING_ELSE_CLAUSE);\r
+\r
+    // get the last value (= final result) from the stack\r
+    MUP_ASSERT(stArgCount.size()==1);\r
+    m_nFinalResultIdx = stArgCount.top();\r
+    if (m_nFinalResultIdx==0)\r
+      Error(ecINTERNAL_ERROR, 9);\r
+\r
+    if (stVal.size()==0)\r
+      Error(ecEMPTY_EXPRESSION);\r
+\r
+    if (stVal.top().GetType()!=tpDBL)\r
+      Error(ecSTR_RESULT);\r
+\r
+    m_vStackBuffer.resize(m_vRPN.GetMaxStackSize() * s_MaxNumOpenMPThreads);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief One of the two main parse functions.\r
+      \sa ParseCmdCode(...)\r
+\r
+    Parse expression from input string. Perform syntax checking and create \r
+    bytecode. After parsing the string and creating the bytecode the function \r
+    pointer #m_pParseFormula will be changed to the second parse routine the \r
+    uses bytecode instead of string parsing.\r
+  */\r
+  value_type ParserBase::ParseString() const\r
+  {\r
+    try\r
+    {\r
+      CreateRPN();\r
+      m_pParseFormula = &ParserBase::ParseCmdCode;\r
+      return (this->*m_pParseFormula)(); \r
+    }\r
+    catch(ParserError &exc)\r
+    {\r
+      exc.SetFormula(m_pTokenReader->GetExpr());\r
+      throw;\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Create an error containing the parse error position.\r
+\r
+    This function will create an Parser Exception object containing the error text and\r
+    its position.\r
+\r
+    \param a_iErrc [in] The error code of type #EErrorCodes.\r
+    \param a_iPos [in] The position where the error was detected.\r
+    \param a_strTok [in] The token string representation associated with the error.\r
+    \throw ParserException always throws thats the only purpose of this function.\r
+  */\r
+  void  ParserBase::Error(EErrorCodes a_iErrc, int a_iPos, const string_type &a_sTok) const\r
+  {\r
+    throw exception_type(a_iErrc, a_sTok, m_pTokenReader->GetExpr(), a_iPos);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Clear all user defined variables.\r
+      \throw nothrow\r
+\r
+      Resets the parser to string parsing mode by calling #ReInit.\r
+  */\r
+  void ParserBase::ClearVar()\r
+  {\r
+    m_VarDef.clear();\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Remove a variable from internal storage.\r
+      \throw nothrow\r
+\r
+      Removes a variable if it exists. If the Variable does not exist nothing will be done.\r
+  */\r
+  void ParserBase::RemoveVar(const string_type &a_strVarName)\r
+  {\r
+    varmap_type::iterator item = m_VarDef.find(a_strVarName);\r
+    if (item!=m_VarDef.end())\r
+    {\r
+      m_VarDef.erase(item);\r
+      ReInit();\r
+    }\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Clear all functions.\r
+      \post Resets the parser to string parsing mode.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::ClearFun()\r
+  {\r
+    m_FunDef.clear();\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Clear all user defined constants.\r
+\r
+      Both numeric and string constants will be removed from the internal storage.\r
+      \post Resets the parser to string parsing mode.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::ClearConst()\r
+  {\r
+    m_ConstDef.clear();\r
+    m_StrVarDef.clear();\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Clear all user defined postfix operators.\r
+      \post Resets the parser to string parsing mode.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::ClearPostfixOprt()\r
+  {\r
+    m_PostOprtDef.clear();\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Clear all user defined binary operators.\r
+      \post Resets the parser to string parsing mode.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::ClearOprt()\r
+  {\r
+    m_OprtDef.clear();\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Clear the user defined Prefix operators. \r
+      \post Resets the parser to string parser mode.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::ClearInfixOprt()\r
+  {\r
+    m_InfixOprtDef.clear();\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Enable or disable the formula optimization feature. \r
+      \post Resets the parser to string parser mode.\r
+      \throw nothrow\r
+  */\r
+  void ParserBase::EnableOptimizer(bool a_bIsOn)\r
+  {\r
+    m_vRPN.EnableOptimizer(a_bIsOn);\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Enable the dumping of bytecode amd stack content on the console. \r
+      \param bDumpCmd Flag to enable dumping of the current bytecode to the console.\r
+      \param bDumpStack Flag to enable dumping of the stack content is written to the console.\r
+\r
+     This function is for debug purposes only!\r
+  */\r
+  void ParserBase::EnableDebugDump(bool bDumpCmd, bool bDumpStack)\r
+  {\r
+    ParserBase::g_DbgDumpCmdCode = bDumpCmd;\r
+    ParserBase::g_DbgDumpStack   = bDumpStack;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Enable or disable the built in binary operators.\r
+      \throw nothrow\r
+      \sa m_bBuiltInOp, ReInit()\r
+\r
+    If you disable the built in binary operators there will be no binary operators\r
+    defined. Thus you must add them manually one by one. It is not possible to\r
+    disable built in operators selectively. This function will Reinitialize the\r
+    parser by calling ReInit().\r
+  */\r
+  void ParserBase::EnableBuiltInOprt(bool a_bIsOn)\r
+  {\r
+    m_bBuiltInOp = a_bIsOn;\r
+    ReInit();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Query status of built in variables.\r
+      \return #m_bBuiltInOp; true if built in operators are enabled.\r
+      \throw nothrow\r
+  */\r
+  bool ParserBase::HasBuiltInOprt() const\r
+  {\r
+    return m_bBuiltInOp;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Get the argument separator character. \r
+  */\r
+  char_type ParserBase::GetArgSep() const\r
+  {\r
+    return m_pTokenReader->GetArgSep();\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Set argument separator. \r
+      \param cArgSep the argument separator character.\r
+  */\r
+  void ParserBase::SetArgSep(char_type cArgSep)\r
+  {\r
+    m_pTokenReader->SetArgSep(cArgSep);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Dump stack content. \r
+\r
+      This function is used for debugging only.\r
+  */\r
+  void ParserBase::StackDump(const ParserStack<token_type> &a_stVal, \r
+                             const ParserStack<token_type> &a_stOprt) const\r
+  {\r
+    ParserStack<token_type> stOprt(a_stOprt), \r
+                            stVal(a_stVal);\r
+\r
+    mu::console() << _T("\nValue stack:\n");\r
+    while ( !stVal.empty() ) \r
+    {\r
+      token_type val = stVal.pop();\r
+      if (val.GetType()==tpSTR)\r
+        mu::console() << _T(" \"") << val.GetAsString() << _T("\" ");\r
+      else\r
+        mu::console() << _T(" ") << val.GetVal() << _T(" ");\r
+    }\r
+    mu::console() << "\nOperator stack:\n";\r
+\r
+    while ( !stOprt.empty() )\r
+    {\r
+      if (stOprt.top().GetCode()<=cmASSIGN) \r
+      {\r
+        mu::console() << _T("OPRT_INTRNL \"")\r
+                      << ParserBase::c_DefaultOprt[stOprt.top().GetCode()] \r
+                      << _T("\" \n");\r
+      }\r
+      else\r
+      {\r
+        switch(stOprt.top().GetCode())\r
+        {\r
+        case cmVAR:   mu::console() << _T("VAR\n");  break;\r
+        case cmVAL:   mu::console() << _T("VAL\n");  break;\r
+        case cmFUNC:  mu::console() << _T("FUNC \"") \r
+                                    << stOprt.top().GetAsString() \r
+                                    << _T("\"\n");   break;\r
+        case cmFUNC_BULK:  mu::console() << _T("FUNC_BULK \"") \r
+                                         << stOprt.top().GetAsString() \r
+                                         << _T("\"\n");   break;\r
+        case cmOPRT_INFIX: mu::console() << _T("OPRT_INFIX \"")\r
+                                         << stOprt.top().GetAsString() \r
+                                         << _T("\"\n");      break;\r
+        case cmOPRT_BIN:   mu::console() << _T("OPRT_BIN \"") \r
+                                         << stOprt.top().GetAsString() \r
+                                         << _T("\"\n");           break;\r
+        case cmFUNC_STR: mu::console() << _T("FUNC_STR\n");       break;\r
+        case cmEND:      mu::console() << _T("END\n");            break;\r
+        case cmUNKNOWN:  mu::console() << _T("UNKNOWN\n");        break;\r
+        case cmBO:       mu::console() << _T("BRACKET \"(\"\n");  break;\r
+        case cmBC:       mu::console() << _T("BRACKET \")\"\n");  break;\r
+        case cmIF:       mu::console() << _T("IF\n");  break;\r
+        case cmELSE:     mu::console() << _T("ELSE\n");  break;\r
+        case cmENDIF:    mu::console() << _T("ENDIF\n");  break;\r
+        default:         mu::console() << stOprt.top().GetCode() << _T(" ");  break;\r
+        }\r
+      }        \r
+      stOprt.pop();\r
+    }\r
+\r
+    mu::console() << dec << endl;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Evaluate an expression containing comma seperated subexpressions \r
+      \param [out] nStackSize The total number of results available\r
+      \return Pointer to the array containing all expression results\r
+\r
+      This member function can be used to retriev all results of an expression\r
+      made up of multiple comma seperated subexpressions (i.e. "x+y,sin(x),cos(y)")\r
+  */\r
+  value_type* ParserBase::Eval(int &nStackSize) const\r
+  {\r
+    (this->*m_pParseFormula)(); \r
+    nStackSize = m_nFinalResultIdx;\r
+\r
+    // (for historic reasons the stack starts at position 1)\r
+    return &m_vStackBuffer[1];\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return the number of results on the calculation stack. \r
+  \r
+    If the expression contains comma seperated subexpressions (i.e. "sin(y), x+y"). \r
+    There mey be more than one return value. This function returns the number of \r
+    available results.\r
+  */\r
+  int ParserBase::GetNumResults() const\r
+  {\r
+    return m_nFinalResultIdx;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Calculate the result.\r
+\r
+    A note on const correctness: \r
+    I consider it important that Calc is a const function.\r
+    Due to caching operations Calc changes only the state of internal variables with one exception\r
+    m_UsedVar this is reset during string parsing and accessible from the outside. Instead of making\r
+    Calc non const GetUsedVar is non const because it explicitely calls Eval() forcing this update. \r
+\r
+    \pre A formula must be set.\r
+    \pre Variables must have been set (if needed)\r
+\r
+    \sa #m_pParseFormula\r
+    \return The evaluation result\r
+    \throw ParseException if no Formula is set or in case of any other error related to the formula.\r
+  */\r
+  value_type ParserBase::Eval() const\r
+  {\r
+    return (this->*m_pParseFormula)(); \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserBase::Eval(value_type *results, int nBulkSize)\r
+  {\r
+    CreateRPN();\r
+\r
+    int i = 0;\r
+\r
+#ifdef MUP_USE_OPENMP\r
+//#define DEBUG_OMP_STUFF\r
+    #ifdef DEBUG_OMP_STUFF\r
+    int *pThread = new int[nBulkSize];\r
+    int *pIdx = new int[nBulkSize];\r
+    #endif\r
+\r
+    int nMaxThreads = std::min(omp_get_max_threads(), s_MaxNumOpenMPThreads);\r
+    int nThreadID, ct=0;\r
+    omp_set_num_threads(nMaxThreads);\r
+\r
+    #pragma omp parallel for schedule(static, nBulkSize/nMaxThreads) private(nThreadID)\r
+    for (i=0; i<nBulkSize; ++i)\r
+    {\r
+      nThreadID = omp_get_thread_num();\r
+      results[i] = ParseCmdCodeBulk(i, nThreadID);\r
+\r
+      #ifdef DEBUG_OMP_STUFF\r
+      #pragma omp critical\r
+      {\r
+        pThread[ct] = nThreadID;  \r
+        pIdx[ct] = i; \r
+        ct++;\r
+      }\r
+      #endif\r
+    }\r
+\r
+#ifdef DEBUG_OMP_STUFF\r
+    FILE *pFile = fopen("bulk_dbg.txt", "w");\r
+    for (i=0; i<nBulkSize; ++i)\r
+    {\r
+      fprintf(pFile, "idx: %d  thread: %d \n", pIdx[i], pThread[i]);\r
+    }\r
+    \r
+    delete [] pIdx;\r
+    delete [] pThread;\r
+\r
+    fclose(pFile);\r
+#endif\r
+\r
+#else\r
+    for (i=0; i<nBulkSize; ++i)\r
+    {\r
+      results[i] = ParseCmdCodeBulk(i, 0);\r
+    }\r
+#endif\r
+\r
+  }\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserBytecode.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserBytecode.cpp
new file mode 100644 (file)
index 0000000..c6d277b
--- /dev/null
@@ -0,0 +1,586 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#include "muParserBytecode.h"\r
+\r
+#include <cassert>\r
+#include <string>\r
+#include <stack>\r
+#include <vector>\r
+#include <iostream>\r
+\r
+#include "muParserDef.h"\r
+#include "muParserError.h"\r
+#include "muParserToken.h"\r
+#include "muParserStack.h"\r
+#include "muParserTemplateMagic.h"\r
+\r
+\r
+namespace mu\r
+{\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Bytecode default constructor. */\r
+  ParserByteCode::ParserByteCode()\r
+    :m_iStackPos(0)\r
+    ,m_iMaxStackSize(0)\r
+    ,m_vRPN()\r
+    ,m_bEnableOptimizer(true)\r
+  {\r
+    m_vRPN.reserve(50);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Copy constructor. \r
+    \r
+      Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)\r
+  */\r
+  ParserByteCode::ParserByteCode(const ParserByteCode &a_ByteCode)\r
+  {\r
+    Assign(a_ByteCode);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Assignment operator.\r
+    \r
+      Implemented in Terms of Assign(const ParserByteCode &a_ByteCode)\r
+  */\r
+  ParserByteCode& ParserByteCode::operator=(const ParserByteCode &a_ByteCode)\r
+  {\r
+    Assign(a_ByteCode);\r
+    return *this;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserByteCode::EnableOptimizer(bool bStat)\r
+  {\r
+    m_bEnableOptimizer = bStat;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Copy state of another object to this. \r
+    \r
+      \throw nowthrow\r
+  */\r
+  void ParserByteCode::Assign(const ParserByteCode &a_ByteCode)\r
+  {\r
+    if (this==&a_ByteCode)    \r
+      return;\r
+\r
+    m_iStackPos = a_ByteCode.m_iStackPos;\r
+    m_vRPN = a_ByteCode.m_vRPN;\r
+    m_iMaxStackSize = a_ByteCode.m_iMaxStackSize;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a Variable pointer to bytecode. \r
+      \param a_pVar Pointer to be added.\r
+      \throw nothrow\r
+  */\r
+  void ParserByteCode::AddVar(value_type *a_pVar)\r
+  {\r
+    ++m_iStackPos;\r
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);\r
+\r
+    // optimization does not apply\r
+    SToken tok;\r
+    tok.Cmd       = cmVAR;\r
+    tok.Val.ptr   = a_pVar;\r
+    tok.Val.data  = 1;\r
+    tok.Val.data2 = 0;\r
+    m_vRPN.push_back(tok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a Variable pointer to bytecode. \r
+\r
+      Value entries in byte code consist of:\r
+      <ul>\r
+        <li>value array position of the value</li>\r
+        <li>the operator code according to ParserToken::cmVAL</li>\r
+        <li>the value stored in #mc_iSizeVal number of bytecode entries.</li>\r
+      </ul>\r
+\r
+      \param a_pVal Value to be added.\r
+      \throw nothrow\r
+  */\r
+  void ParserByteCode::AddVal(value_type a_fVal)\r
+  {\r
+    ++m_iStackPos;\r
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);\r
+\r
+    // If optimization does not apply\r
+    SToken tok;\r
+    tok.Cmd = cmVAL;\r
+    tok.Val.ptr   = NULL;\r
+    tok.Val.data  = 0;\r
+    tok.Val.data2 = a_fVal;\r
+    m_vRPN.push_back(tok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserByteCode::ConstantFolding(ECmdCode a_Oprt)\r
+  {\r
+    std::size_t sz = m_vRPN.size();\r
+    value_type &x = m_vRPN[sz-2].Val.data2,\r
+               &y = m_vRPN[sz-1].Val.data2;\r
+    switch (a_Oprt)\r
+    {\r
+    case cmLAND: x = (int)x && (int)y; m_vRPN.pop_back(); break;\r
+    case cmLOR:  x = (int)x || (int)y; m_vRPN.pop_back(); break;\r
+    case cmLT:   x = x < y;  m_vRPN.pop_back();  break;\r
+    case cmGT:   x = x > y;  m_vRPN.pop_back();  break;\r
+    case cmLE:   x = x <= y; m_vRPN.pop_back();  break;\r
+    case cmGE:   x = x >= y; m_vRPN.pop_back();  break;\r
+    case cmNEQ:  x = x != y; m_vRPN.pop_back();  break;\r
+    case cmEQ:   x = x == y; m_vRPN.pop_back();  break;\r
+    case cmADD:  x = x + y;  m_vRPN.pop_back();  break;\r
+    case cmSUB:  x = x - y;  m_vRPN.pop_back();  break;\r
+    case cmMUL:  x = x * y;  m_vRPN.pop_back();  break;\r
+    case cmDIV: \r
+\r
+#if defined(MUP_MATH_EXCEPTIONS)\r
+        if (y==0)\r
+          throw ParserError(ecDIV_BY_ZERO, _T("0"));\r
+#endif\r
+\r
+        x = x / y;   \r
+        m_vRPN.pop_back();\r
+        break;\r
+\r
+    case cmPOW: x = MathImpl<value_type>::Pow(x, y); \r
+                m_vRPN.pop_back();\r
+                break;\r
+\r
+    default:\r
+        break;\r
+    } // switch opcode\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add an operator identifier to bytecode. \r
+    \r
+      Operator entries in byte code consist of:\r
+      <ul>\r
+        <li>value array position of the result</li>\r
+        <li>the operator code according to ParserToken::ECmdCode</li>\r
+      </ul>\r
+\r
+      \sa  ParserToken::ECmdCode\r
+  */\r
+  void ParserByteCode::AddOp(ECmdCode a_Oprt)\r
+  {\r
+    bool bOptimized = false;\r
+\r
+    if (m_bEnableOptimizer)\r
+    {\r
+      std::size_t sz = m_vRPN.size();\r
+\r
+      // Check for foldable constants like:\r
+      //   cmVAL cmVAL cmADD \r
+      // where cmADD can stand fopr any binary operator applied to\r
+      // two constant values.\r
+      if (sz>=2 && m_vRPN[sz-2].Cmd == cmVAL && m_vRPN[sz-1].Cmd == cmVAL)\r
+      {\r
+        ConstantFolding(a_Oprt);\r
+        bOptimized = true;\r
+      }\r
+      else\r
+      {\r
+        switch(a_Oprt)\r
+        {\r
+        case  cmPOW:\r
+              // Optimization for ploynomials of low order\r
+              if (m_vRPN[sz-2].Cmd == cmVAR && m_vRPN[sz-1].Cmd == cmVAL)\r
+              {\r
+                if (m_vRPN[sz-1].Val.data2==2)\r
+                  m_vRPN[sz-2].Cmd = cmVARPOW2;\r
+                else if (m_vRPN[sz-1].Val.data2==3)\r
+                  m_vRPN[sz-2].Cmd = cmVARPOW3;\r
+                else if (m_vRPN[sz-1].Val.data2==4)\r
+                  m_vRPN[sz-2].Cmd = cmVARPOW4;\r
+                else\r
+                  break;\r
+\r
+                m_vRPN.pop_back();\r
+                bOptimized = true;\r
+              }\r
+              break;\r
+\r
+        case  cmSUB:\r
+        case  cmADD:\r
+              // Simple optimization based on pattern recognition for a shitload of different\r
+              // bytecode combinations of addition/subtraction\r
+              if ( (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVAL)    ||\r
+                   (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVAR)    || \r
+                   (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVARMUL) ||\r
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL)    ||\r
+                   (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVAR    && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||\r
+                   (m_vRPN[sz-1].Cmd == cmVAR    && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||\r
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAR    && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) ||\r
+                   (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) )\r
+              {\r
+                assert( (m_vRPN[sz-2].Val.ptr==NULL && m_vRPN[sz-1].Val.ptr!=NULL) ||\r
+                        (m_vRPN[sz-2].Val.ptr!=NULL && m_vRPN[sz-1].Val.ptr==NULL) || \r
+                        (m_vRPN[sz-2].Val.ptr == m_vRPN[sz-1].Val.ptr) );\r
+\r
+                m_vRPN[sz-2].Cmd = cmVARMUL;\r
+                m_vRPN[sz-2].Val.ptr    = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));    // variable\r
+                m_vRPN[sz-2].Val.data2 += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data2;  // offset\r
+                m_vRPN[sz-2].Val.data  += ((a_Oprt==cmSUB) ? -1 : 1) * m_vRPN[sz-1].Val.data;   // multiplikatior\r
+                m_vRPN.pop_back();\r
+                bOptimized = true;\r
+              } \r
+              break;\r
+\r
+        case  cmMUL:\r
+              if ( (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAL) ||\r
+                   (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVAR) ) \r
+              {\r
+                m_vRPN[sz-2].Cmd        = cmVARMUL;\r
+                m_vRPN[sz-2].Val.ptr    = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));\r
+                m_vRPN[sz-2].Val.data   = m_vRPN[sz-2].Val.data2 + m_vRPN[sz-1].Val.data2;\r
+                m_vRPN[sz-2].Val.data2  = 0;\r
+                m_vRPN.pop_back();\r
+                bOptimized = true;\r
+              } \r
+              else if ( (m_vRPN[sz-1].Cmd == cmVAL    && m_vRPN[sz-2].Cmd == cmVARMUL) ||\r
+                        (m_vRPN[sz-1].Cmd == cmVARMUL && m_vRPN[sz-2].Cmd == cmVAL) )\r
+              {\r
+                // Optimization: 2*(3*b+1) or (3*b+1)*2 -> 6*b+2\r
+                m_vRPN[sz-2].Cmd     = cmVARMUL;\r
+                m_vRPN[sz-2].Val.ptr = (value_type*)((long long)(m_vRPN[sz-2].Val.ptr) | (long long)(m_vRPN[sz-1].Val.ptr));\r
+                if (m_vRPN[sz-1].Cmd == cmVAL)\r
+                {\r
+                  m_vRPN[sz-2].Val.data  *= m_vRPN[sz-1].Val.data2;\r
+                  m_vRPN[sz-2].Val.data2 *= m_vRPN[sz-1].Val.data2;\r
+                }\r
+                else\r
+                {\r
+                  m_vRPN[sz-2].Val.data  = m_vRPN[sz-1].Val.data  * m_vRPN[sz-2].Val.data2;\r
+                  m_vRPN[sz-2].Val.data2 = m_vRPN[sz-1].Val.data2 * m_vRPN[sz-2].Val.data2;\r
+                }\r
+                m_vRPN.pop_back();\r
+                bOptimized = true;\r
+              }\r
+              else if (m_vRPN[sz-1].Cmd == cmVAR && m_vRPN[sz-2].Cmd == cmVAR &&\r
+                       m_vRPN[sz-1].Val.ptr == m_vRPN[sz-2].Val.ptr)\r
+              {\r
+                // Optimization: a*a -> a^2\r
+                m_vRPN[sz-2].Cmd = cmVARPOW2;\r
+                m_vRPN.pop_back();\r
+                bOptimized = true;\r
+              }\r
+              break;\r
+\r
+        case cmDIV:\r
+              if (m_vRPN[sz-1].Cmd == cmVAL && m_vRPN[sz-2].Cmd == cmVARMUL && m_vRPN[sz-1].Val.data2!=0)\r
+              {\r
+                // Optimization: 4*a/2 -> 2*a\r
+                m_vRPN[sz-2].Val.data  /= m_vRPN[sz-1].Val.data2;\r
+                m_vRPN[sz-2].Val.data2 /= m_vRPN[sz-1].Val.data2;\r
+                m_vRPN.pop_back();\r
+                bOptimized = true;\r
+              }\r
+              break;\r
+              \r
+        } // switch a_Oprt\r
+      }\r
+    }\r
+\r
+    // If optimization can't be applied just write the value\r
+    if (!bOptimized)\r
+    {\r
+      --m_iStackPos;\r
+      SToken tok;\r
+      tok.Cmd = a_Oprt;\r
+      m_vRPN.push_back(tok);\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserByteCode::AddIfElse(ECmdCode a_Oprt)\r
+  {\r
+    SToken tok;\r
+    tok.Cmd = a_Oprt;\r
+    m_vRPN.push_back(tok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add an assignement operator\r
+    \r
+      Operator entries in byte code consist of:\r
+      <ul>\r
+        <li>cmASSIGN code</li>\r
+        <li>the pointer of the destination variable</li>\r
+      </ul>\r
+\r
+      \sa  ParserToken::ECmdCode\r
+  */\r
+  void ParserByteCode::AddAssignOp(value_type *a_pVar)\r
+  {\r
+    --m_iStackPos;\r
+\r
+    SToken tok;\r
+    tok.Cmd = cmASSIGN;\r
+    tok.Val.ptr = a_pVar;\r
+    m_vRPN.push_back(tok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add function to bytecode. \r
+\r
+      \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.\r
+      \param a_pFun Pointer to function callback.\r
+  */\r
+  void ParserByteCode::AddFun(generic_fun_type a_pFun, int a_iArgc)\r
+  {\r
+    if (a_iArgc>=0)\r
+    {\r
+      m_iStackPos = m_iStackPos - a_iArgc + 1; \r
+    }\r
+    else\r
+    {\r
+      // function with unlimited number of arguments\r
+      m_iStackPos = m_iStackPos + a_iArgc + 1; \r
+    }\r
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);\r
+\r
+    SToken tok;\r
+    tok.Cmd = cmFUNC;\r
+    tok.Fun.argc = a_iArgc;\r
+    tok.Fun.ptr = a_pFun;\r
+    m_vRPN.push_back(tok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add a bulk function to bytecode. \r
+\r
+      \param a_iArgc Number of arguments, negative numbers indicate multiarg functions.\r
+      \param a_pFun Pointer to function callback.\r
+  */\r
+  void ParserByteCode::AddBulkFun(generic_fun_type a_pFun, int a_iArgc)\r
+  {\r
+    m_iStackPos = m_iStackPos - a_iArgc + 1; \r
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);\r
+\r
+    SToken tok;\r
+    tok.Cmd = cmFUNC_BULK;\r
+    tok.Fun.argc = a_iArgc;\r
+    tok.Fun.ptr = a_pFun;\r
+    m_vRPN.push_back(tok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add Strung function entry to the parser bytecode. \r
+      \throw nothrow\r
+\r
+      A string function entry consists of the stack position of the return value,\r
+      followed by a cmSTRFUNC code, the function pointer and an index into the \r
+      string buffer maintained by the parser.\r
+  */\r
+  void ParserByteCode::AddStrFun(generic_fun_type a_pFun, int a_iArgc, int a_iIdx)\r
+  {\r
+    m_iStackPos = m_iStackPos - a_iArgc + 1;\r
+\r
+    SToken tok;\r
+    tok.Cmd = cmFUNC_STR;\r
+    tok.Fun.argc = a_iArgc;\r
+    tok.Fun.idx = a_iIdx;\r
+    tok.Fun.ptr = a_pFun;\r
+    m_vRPN.push_back(tok);\r
+\r
+    m_iMaxStackSize = std::max(m_iMaxStackSize, (size_t)m_iStackPos);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Add end marker to bytecode.\r
+      \r
+      \throw nothrow \r
+  */\r
+  void ParserByteCode::Finalize()\r
+  {\r
+    SToken tok;\r
+    tok.Cmd = cmEND;\r
+    m_vRPN.push_back(tok);\r
+    rpn_type(m_vRPN).swap(m_vRPN);     // shrink bytecode vector to fit\r
+\r
+    // Determine the if-then-else jump offsets\r
+    ParserStack<int> stIf, stElse;\r
+    int idx;\r
+    for (int i=0; i<(int)m_vRPN.size(); ++i)\r
+    {\r
+      switch(m_vRPN[i].Cmd)\r
+      {\r
+      case cmIF:\r
+            stIf.push(i);\r
+            break;\r
+\r
+      case  cmELSE:\r
+            stElse.push(i);\r
+            idx = stIf.pop();\r
+            m_vRPN[idx].Oprt.offset = i - idx;\r
+            break;\r
+      \r
+      case cmENDIF:\r
+            idx = stElse.pop();\r
+            m_vRPN[idx].Oprt.offset = i - idx;\r
+            break;\r
+\r
+      default:\r
+            break;\r
+      }\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  const SToken* ParserByteCode::GetBase() const\r
+  {\r
+    if (m_vRPN.size()==0)\r
+      throw ParserError(ecINTERNAL_ERROR);\r
+    else\r
+      return &m_vRPN[0];\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  std::size_t ParserByteCode::GetMaxStackSize() const\r
+  {\r
+    return m_iMaxStackSize+1;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Returns the number of entries in the bytecode. */\r
+  std::size_t ParserByteCode::GetSize() const\r
+  {\r
+    return m_vRPN.size();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Delete the bytecode. \r
+  \r
+      \throw nothrow\r
+\r
+      The name of this function is a violation of my own coding guidelines\r
+      but this way it's more in line with the STL functions thus more \r
+      intuitive.\r
+  */\r
+  void ParserByteCode::clear()\r
+  {\r
+    m_vRPN.clear();\r
+    m_iStackPos = 0;\r
+    m_iMaxStackSize = 0;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Dump bytecode (for debugging only!). */\r
+  void ParserByteCode::AsciiDump()\r
+  {\r
+    if (!m_vRPN.size()) \r
+    {\r
+      mu::console() << _T("No bytecode available\n");\r
+      return;\r
+    }\r
+\r
+    mu::console() << _T("Number of RPN tokens:") << (int)m_vRPN.size() << _T("\n");\r
+    for (std::size_t i=0; i<m_vRPN.size() && m_vRPN[i].Cmd!=cmEND; ++i)\r
+    {\r
+      mu::console() << std::dec << i << _T(" : \t");\r
+      switch (m_vRPN[i].Cmd)\r
+      {\r
+      case cmVAL:   mu::console() << _T("VAL \t");\r
+                    mu::console() << _T("[") << m_vRPN[i].Val.data2 << _T("]\n");\r
+                    break;\r
+\r
+      case cmVAR:   mu::console() << _T("VAR \t");\r
+                         mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
+                    break;\r
+\r
+      case cmVARPOW2: mu::console() << _T("VARPOW2 \t");\r
+                           mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
+                      break;\r
+\r
+      case cmVARPOW3: mu::console() << _T("VARPOW3 \t");\r
+                           mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
+                      break;\r
+\r
+      case cmVARPOW4: mu::console() << _T("VARPOW4 \t");\r
+                           mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]\n"); \r
+                      break;\r
+\r
+      case cmVARMUL:  mu::console() << _T("VARMUL \t");\r
+                           mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Val.ptr << _T("]"); \r
+                      mu::console() << _T(" * [") << m_vRPN[i].Val.data << _T("]");\r
+                      mu::console() << _T(" + [") << m_vRPN[i].Val.data2 << _T("]\n");\r
+                      break;\r
+\r
+      case cmFUNC:  mu::console() << _T("CALL\t");\r
+                    mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]"); \r
+                    mu::console() << _T("[ADDR: 0x") << std::hex << m_vRPN[i].Fun.ptr << _T("]"); \r
+                    mu::console() << _T("\n");\r
+                    break;\r
+\r
+      case cmFUNC_STR:\r
+                    mu::console() << _T("CALL STRFUNC\t");\r
+                    mu::console() << _T("[ARG:") << std::dec << m_vRPN[i].Fun.argc << _T("]");\r
+                    mu::console() << _T("[IDX:") << std::dec << m_vRPN[i].Fun.idx << _T("]");\r
+                    mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Fun.ptr << _T("]\n"); \r
+                    break;\r
+\r
+      case cmLT:    mu::console() << _T("LT\n");  break;\r
+      case cmGT:    mu::console() << _T("GT\n");  break;\r
+      case cmLE:    mu::console() << _T("LE\n");  break;\r
+      case cmGE:    mu::console() << _T("GE\n");  break;\r
+      case cmEQ:    mu::console() << _T("EQ\n");  break;\r
+      case cmNEQ:   mu::console() << _T("NEQ\n"); break;\r
+      case cmADD:   mu::console() << _T("ADD\n"); break;\r
+      case cmLAND:  mu::console() << _T("&&\n"); break;\r
+      case cmLOR:   mu::console() << _T("||\n"); break;\r
+      case cmSUB:   mu::console() << _T("SUB\n"); break;\r
+      case cmMUL:   mu::console() << _T("MUL\n"); break;\r
+      case cmDIV:   mu::console() << _T("DIV\n"); break;\r
+      case cmPOW:   mu::console() << _T("POW\n"); break;\r
+\r
+      case cmIF:    mu::console() << _T("IF\t");\r
+                    mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");\r
+                    break;\r
+\r
+      case cmELSE:  mu::console() << _T("ELSE\t");\r
+                    mu::console() << _T("[OFFSET:") << std::dec << m_vRPN[i].Oprt.offset << _T("]\n");\r
+                    break;\r
+\r
+      case cmENDIF: mu::console() << _T("ENDIF\n"); break;\r
+\r
+      case cmASSIGN: \r
+                    mu::console() << _T("ASSIGN\t");\r
+                    mu::console() << _T("[ADDR: 0x") << m_vRPN[i].Oprt.ptr << _T("]\n"); \r
+                    break; \r
+\r
+      default:      mu::console() << _T("(unknown code: ") << m_vRPN[i].Cmd << _T(")\n"); \r
+                    break;\r
+      } // switch cmdCode\r
+    } // while bytecode\r
+\r
+    mu::console() << _T("END") << std::endl;\r
+  }\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserCallback.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserCallback.cpp
new file mode 100644 (file)
index 0000000..9baa91d
--- /dev/null
@@ -0,0 +1,463 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#include "muParserCallback.h"\r
+\r
+/** \file\r
+    \brief Implementation of the parser callback class.\r
+*/\r
+\r
+\r
+namespace mu\r
+{\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type0 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(0)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type1 a_pFun, bool a_bAllowOpti, int a_iPrec, ECmdCode a_iCode)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(1)\r
+    ,m_iPri(a_iPrec)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(a_iCode)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Constructor for constructing funcstion callbacks taking two arguments. \r
+      \throw nothrow\r
+  */\r
+  ParserCallback::ParserCallback(fun_type2 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(2)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Constructor for constructing binary operator callbacks. \r
+      \param a_pFun Pointer to a static function taking two arguments\r
+      \param a_bAllowOpti A flag indicating this funcation can be optimized\r
+      \param a_iPrec The operator precedence\r
+      \param a_eOprtAsct The operators associativity\r
+      \throw nothrow\r
+  */\r
+  ParserCallback::ParserCallback(fun_type2 a_pFun, \r
+                                 bool a_bAllowOpti, \r
+                                 int a_iPrec, \r
+                                 EOprtAssociativity a_eOprtAsct)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(2)\r
+    ,m_iPri(a_iPrec)\r
+    ,m_eOprtAsct(a_eOprtAsct)\r
+    ,m_iCode(cmOPRT_BIN)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type3 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(3)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type4 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(4)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type5 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(5)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type6 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(6)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type7 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(7)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type8 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(8)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type9 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(9)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(fun_type10 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(10)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type0 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(0)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type1 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(1)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Constructor for constructing funcstion callbacks taking two arguments. \r
+      \throw nothrow\r
+  */\r
+  ParserCallback::ParserCallback(bulkfun_type2 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(2)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type3 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(3)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type4 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(4)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type5 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(5)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type6 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(6)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type7 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(7)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type8 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(8)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type9 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(9)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(bulkfun_type10 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(10)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_BULK)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(multfun_type a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(-1)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC)\r
+    ,m_iType(tpDBL)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(strfun_type1 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(0)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_STR)\r
+    ,m_iType(tpSTR)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(strfun_type2 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(1)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_STR)\r
+    ,m_iType(tpSTR)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserCallback::ParserCallback(strfun_type3 a_pFun, bool a_bAllowOpti)\r
+    :m_pFun((void*)a_pFun)\r
+    ,m_iArgc(2)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmFUNC_STR)\r
+    ,m_iType(tpSTR)\r
+    ,m_bAllowOpti(a_bAllowOpti)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Default constructor. \r
+      \throw nothrow\r
+  */\r
+  ParserCallback::ParserCallback()\r
+    :m_pFun(0)\r
+    ,m_iArgc(0)\r
+    ,m_iPri(-1)\r
+    ,m_eOprtAsct(oaNONE)\r
+    ,m_iCode(cmUNKNOWN)\r
+    ,m_iType(tpVOID)\r
+    ,m_bAllowOpti(0)\r
+  {}\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Copy constructor. \r
+      \throw nothrow\r
+  */\r
+  ParserCallback::ParserCallback(const ParserCallback &ref)\r
+  {\r
+    m_pFun       = ref.m_pFun;\r
+    m_iArgc      = ref.m_iArgc;\r
+    m_bAllowOpti = ref.m_bAllowOpti;\r
+    m_iCode      = ref.m_iCode;\r
+    m_iType      = ref.m_iType;\r
+    m_iPri       = ref.m_iPri;\r
+    m_eOprtAsct  = ref.m_eOprtAsct;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Clone this instance and return a pointer to the new instance. */\r
+  ParserCallback* ParserCallback::Clone() const\r
+  {\r
+    return new ParserCallback(*this);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return tru if the function is conservative.\r
+\r
+      Conservative functions return always the same result for the same argument.\r
+      \throw nothrow\r
+  */\r
+  bool ParserCallback::IsOptimizable() const  \r
+  { \r
+    return m_bAllowOpti; \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Get the callback address for the parser function. \r
+  \r
+      The type of the address is void. It needs to be recasted according to the\r
+      argument number to the right type.\r
+\r
+      \throw nothrow\r
+      \return #pFun\r
+  */\r
+  void* ParserCallback::GetAddr() const \r
+  { \r
+    return m_pFun;  \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return the callback code. */\r
+  ECmdCode  ParserCallback::GetCode() const \r
+  { \r
+    return m_iCode; \r
+  }\r
+  \r
+  //---------------------------------------------------------------------------\r
+  ETypeCode ParserCallback::GetType() const \r
+  { \r
+    return m_iType; \r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return the operator precedence. \r
+      \throw nothrown\r
+\r
+     Only valid if the callback token is an operator token (binary or infix).\r
+  */\r
+  int ParserCallback::GetPri()  const \r
+  { \r
+    return m_iPri;  \r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return the operators associativity. \r
+      \throw nothrown\r
+\r
+     Only valid if the callback token is a binary operator token.\r
+  */\r
+  EOprtAssociativity ParserCallback::GetAssociativity() const\r
+  {\r
+    return m_eOprtAsct;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Returns the number of function Arguments. */\r
+  int ParserCallback::GetArgc() const \r
+  { \r
+    return m_iArgc; \r
+  }\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserDLL.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserDLL.cpp
new file mode 100644 (file)
index 0000000..619ed3e
--- /dev/null
@@ -0,0 +1,1060 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2004-2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#if defined(MUPARSER_DLL) \r
+\r
+#if defined(_WIN32)\r
+  #define WIN32_LEAN_AND_MEAN\r
+  #include <windows.h>\r
+#endif\r
+\r
+#include "muParserDLL.h"\r
+#include "muParser.h"\r
+#include "muParserInt.h"\r
+#include "muParserError.h"\r
+\r
+\r
+#define MU_TRY  \\r
+        try     \\r
+        {\r
+\r
+#define MU_CATCH                                                 \\r
+        }                                                        \\r
+        catch(muError_t &e)                                      \\r
+        {                                                        \\r
+          ParserTag *pTag = static_cast<ParserTag*>(a_hParser);  \\r
+          pTag->exc = e;                                         \\r
+          pTag->bError = true;                                   \\r
+          if (pTag->errHandler)                                  \\r
+            (pTag->errHandler)(a_hParser);                       \\r
+        }                                                        \\r
+        catch(...)                                               \\r
+        {                                                        \\r
+          ParserTag *pTag = static_cast<ParserTag*>(a_hParser);  \\r
+          pTag->exc = muError_t(mu::ecINTERNAL_ERROR);           \\r
+          pTag->bError = true;                                   \\r
+          if (pTag->errHandler)                                  \\r
+            (pTag->errHandler)(a_hParser);                       \\r
+        }\r
+\r
+/** \file \r
+    \brief This file contains the implementation of the DLL interface of muparser.\r
+*/\r
+\r
+//---------------------------------------------------------------------------\r
+// private types\r
+typedef mu::ParserBase::exception_type muError_t;\r
+typedef mu::ParserBase muParser_t;\r
+\r
+int g_nBulkSize;\r
+\r
+//---------------------------------------------------------------------------\r
+class ParserTag\r
+{\r
+public:\r
+  ParserTag(int nType)\r
+    :pParser( (nType==muBASETYPE_FLOAT)   ? (mu::ParserBase*)new mu::Parser()    : \r
+              (nType==muBASETYPE_INT)     ? (mu::ParserBase*)new mu::ParserInt() : NULL)\r
+    ,exc()\r
+    ,errHandler(NULL)\r
+    ,bError(false)\r
+    ,m_nParserType(nType)\r
+  {}\r
\r
+ ~ParserTag()\r
+  {\r
+    delete pParser;\r
+  }\r
+\r
+  mu::ParserBase *pParser;\r
+  mu::ParserBase::exception_type exc;\r
+  muErrorHandler_t errHandler;\r
+  bool bError;\r
+\r
+private:\r
+  ParserTag(const ParserTag &ref);\r
+  ParserTag& operator=(const ParserTag &ref);\r
+\r
+  int m_nParserType;\r
+};\r
+\r
+static muChar_t s_tmpOutBuf[2048];\r
+\r
+//---------------------------------------------------------------------------\r
+//\r
+//\r
+//  unexported functions\r
+//\r
+//\r
+//---------------------------------------------------------------------------\r
+\r
+//---------------------------------------------------------------------------\r
+muParser_t* AsParser(muParserHandle_t a_hParser)\r
+{\r
+  return static_cast<ParserTag*>(a_hParser)->pParser;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+ParserTag* AsParserTag(muParserHandle_t a_hParser)\r
+{\r
+  return static_cast<ParserTag*>(a_hParser);\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+#if defined(_WIN32)\r
+  #define _CRT_SECURE_NO_DEPRECATE\r
+\r
+  BOOL APIENTRY DllMain( HANDLE /*hModule*/, \r
+                         DWORD ul_reason_for_call, \r
+                         LPVOID /*lpReserved*/ )\r
+  {\r
+         switch (ul_reason_for_call)\r
+         {\r
+         case  DLL_PROCESS_ATTACH:\r
+          break;\r
+\r
+    case  DLL_THREAD_ATTACH:\r
+    case  DLL_THREAD_DETACH:\r
+    case  DLL_PROCESS_DETACH:\r
+                 break;\r
+         }\r
+\r
+    return TRUE;\r
+  }\r
+\r
+#endif\r
+\r
+//---------------------------------------------------------------------------\r
+//\r
+//\r
+//  exported functions\r
+//\r
+//\r
+//---------------------------------------------------------------------------\r
+\r
+API_EXPORT(void) mupSetVarFactory(muParserHandle_t a_hParser, muFacFun_t a_pFactory, void *pUserData)\r
+{\r
+  MU_TRY\r
+    muParser_t* p(AsParser(a_hParser));\r
+    p->SetVarFactory(a_pFactory, pUserData);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Create a new Parser instance and return its handle.\r
+*/\r
+API_EXPORT(muParserHandle_t) mupCreate(int nBaseType)\r
+{\r
+  switch(nBaseType)\r
+  {\r
+  case  muBASETYPE_FLOAT:   return (void*)(new ParserTag(muBASETYPE_FLOAT));\r
+  case  muBASETYPE_INT:     return (void*)(new ParserTag(muBASETYPE_INT));\r
+  default:                  return NULL;\r
+  }\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Release the parser instance related with a parser handle.\r
+*/\r
+API_EXPORT(void) mupRelease(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    ParserTag* p = static_cast<ParserTag*>(a_hParser);\r
+    delete p;\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(const muChar_t*) mupGetVersion(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    sprintf(s_tmpOutBuf, "%s", p->GetVersion().c_str());\r
+    return s_tmpOutBuf;\r
+  MU_CATCH\r
+\r
+  return "";\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Evaluate the expression.\r
+*/\r
+API_EXPORT(muFloat_t) mupEval(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    return p->Eval();\r
+  MU_CATCH\r
+\r
+  return 0;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(muFloat_t*) mupEvalMulti(muParserHandle_t a_hParser, int *nNum)\r
+{\r
+  MU_TRY\r
+    assert(nNum!=NULL);\r
+\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    return p->Eval(*nNum);\r
+  MU_CATCH\r
+\r
+  return 0;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupEvalBulk(muParserHandle_t a_hParser, muFloat_t *a_res, int nSize)\r
+{\r
+  MU_TRY\r
+    muParser_t* p(AsParser(a_hParser));\r
+    p->Eval(a_res, nSize);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupSetExpr(muParserHandle_t a_hParser, const muChar_t* a_szExpr)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->SetExpr(a_szExpr);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupRemoveVar(muParserHandle_t a_hParser, const muChar_t* a_szName)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->RemoveVar( a_szName );\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Release all parser variables.\r
+    \param a_hParser Handle to the parser instance.\r
+*/\r
+API_EXPORT(void) mupClearVar(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->ClearVar();\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Release all parser variables.\r
+    \param a_hParser Handle to the parser instance.\r
+*/\r
+API_EXPORT(void) mupClearConst(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->ClearConst();\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Clear all user defined operators.\r
+    \param a_hParser Handle to the parser instance.\r
+*/\r
+API_EXPORT(void) mupClearOprt(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->ClearOprt();\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupClearFun(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->ClearFun();\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun0( muParserHandle_t a_hParser, \r
+                                const muChar_t* a_szName, \r
+                                muFun0_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun1( muParserHandle_t a_hParser, \r
+                                const muChar_t* a_szName, \r
+                                muFun1_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun2( muParserHandle_t a_hParser, \r
+                                const muChar_t* a_szName, \r
+                                muFun2_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun3( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun3_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun4( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun4_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun5( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun5_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun6( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun6_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun7( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun7_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun8( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun8_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun9( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun9_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineFun10( muParserHandle_t a_hParser, \r
+                                const muChar_t *a_szName, \r
+                                muFun10_t a_pFun, \r
+                                muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun0(muParserHandle_t a_hParser, \r
+                                   const muChar_t* a_szName, \r
+                                   muBulkFun0_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun1(muParserHandle_t a_hParser, \r
+                                   const muChar_t* a_szName, \r
+                                   muBulkFun1_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun2(muParserHandle_t a_hParser, \r
+                                   const muChar_t* a_szName, \r
+                                   muBulkFun2_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun3(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun3_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun4(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun4_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun5(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun5_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun6(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun6_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun7(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun7_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun8(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun8_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun9(muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muBulkFun9_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkFun10( muParserHandle_t a_hParser, \r
+                                     const muChar_t *a_szName, \r
+                                     muBulkFun10_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineStrFun1( muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muStrFun1_t a_pFun )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineStrFun2( muParserHandle_t a_hParser, \r
+                                   const muChar_t* a_szName, \r
+                                   muStrFun2_t a_pFun )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineStrFun3( muParserHandle_t a_hParser, \r
+                                   const muChar_t* a_szName, \r
+                                   muStrFun3_t a_pFun )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, false);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineMultFun( muParserHandle_t a_hParser, \r
+                                   const muChar_t *a_szName, \r
+                                   muMultFun_t a_pFun, \r
+                                   muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineFun(a_szName, a_pFun, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineOprt( muParserHandle_t a_hParser, \r
+                                const muChar_t* a_szName, \r
+                                muFun2_t a_pFun, \r
+                                muInt_t a_nPrec, \r
+                                muInt_t a_nOprtAsct,\r
+                                muBool_t a_bAllowOpt)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineOprt(a_szName, \r
+                  a_pFun, \r
+                  a_nPrec, \r
+                  (mu::EOprtAssociativity)a_nOprtAsct, \r
+                  a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineVar(muParserHandle_t a_hParser, \r
+                              const muChar_t *a_szName, \r
+                              muFloat_t *a_pVar)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineVar(a_szName, a_pVar);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineBulkVar(muParserHandle_t a_hParser, \r
+                                  const muChar_t *a_szName, \r
+                                  muFloat_t *a_pVar)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineVar(a_szName, a_pVar);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineConst(muParserHandle_t a_hParser, \r
+                                                               const muChar_t *a_szName, \r
+                                                               muFloat_t a_fVal)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineConst(a_szName, a_fVal);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineStrConst(muParserHandle_t a_hParser, \r
+                                                                  const muChar_t *a_szName, \r
+                                                                  const muChar_t *a_szVal)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineStrConst(a_szName, a_szVal);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(const muChar_t*) mupGetExpr(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+\r
+    // C# explodes when pMsg is returned directly. For some reason it can't access\r
+    // the memory where the message lies directly.\r
+    sprintf(s_tmpOutBuf, "%s", p->GetExpr().c_str());\r
+    return s_tmpOutBuf;\r
+  \r
+  MU_CATCH\r
+\r
+  return "";\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefinePostfixOprt( muParserHandle_t a_hParser,\r
+                                       const muChar_t* a_szName,\r
+                                       muFun1_t a_pOprt,\r
+                                       muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefinePostfixOprt(a_szName, a_pOprt, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineInfixOprt( muParserHandle_t a_hParser,\r
+                                     const muChar_t* a_szName,\r
+                                     muFun1_t a_pOprt,\r
+                                     muBool_t a_bAllowOpt )\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->DefineInfixOprt(a_szName, a_pOprt, a_bAllowOpt!=0);\r
+  MU_CATCH\r
+}\r
+\r
+// Define character sets for identifiers\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineNameChars( muParserHandle_t a_hParser, \r
+                                     const muChar_t* a_szCharset )\r
+{\r
+    muParser_t* const p(AsParser(a_hParser));\r
+  p->DefineNameChars(a_szCharset);\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineOprtChars( muParserHandle_t a_hParser, \r
+                                     const muChar_t* a_szCharset )\r
+{\r
+  muParser_t* const p(AsParser(a_hParser));\r
+  p->DefineOprtChars(a_szCharset);\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupDefineInfixOprtChars(muParserHandle_t a_hParser, \r
+                                                                                const muChar_t *a_szCharset)\r
+{\r
+  muParser_t* const p(AsParser(a_hParser));\r
+  p->DefineInfixOprtChars(a_szCharset);\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Get the number of variables defined in the parser.\r
+    \param a_hParser [in] Must be a valid parser handle.\r
+    \return The number of used variables.\r
+    \sa mupGetExprVar\r
+*/\r
+API_EXPORT(int) mupGetVarNum(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    const mu::varmap_type VarMap = p->GetVar();\r
+    return (int)VarMap.size();\r
+  MU_CATCH\r
+\r
+  return 0; // never reached\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return a variable that is used in an expression.\r
+    \param a_hParser [in] A valid parser handle.\r
+    \param a_iVar [in] The index of the variable to return.\r
+    \param a_szName [out] Pointer to the variable name.\r
+    \param a_pVar [out] Pointer to the variable.\r
+    \throw nothrow\r
+\r
+    Prior to calling this function call mupGetExprVarNum in order to get the\r
+    number of variables in the expression. If the parameter a_iVar is greater\r
+    than the number of variables both a_szName and a_pVar will be set to zero.\r
+    As a side effect this function will trigger an internal calculation of the\r
+    expression undefined variables will be set to zero during this calculation.\r
+    During the calculation user defined callback functions present in the expression\r
+    will be called, this is unavoidable.\r
+*/\r
+API_EXPORT(void) mupGetVar(muParserHandle_t a_hParser, \r
+                                                  unsigned a_iVar, \r
+                                                  const muChar_t **a_szName, \r
+                                                  muFloat_t **a_pVar)\r
+{\r
+  // A static buffer is needed for the name since i cant return the\r
+  // pointer from the map.\r
+  static muChar_t  szName[1024];\r
+\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    const mu::varmap_type VarMap = p->GetVar();\r
+\r
+    if (a_iVar>=VarMap.size())\r
+    {\r
+     *a_szName = 0;\r
+     *a_pVar = 0;\r
+      return;\r
+    }\r
+    mu::varmap_type::const_iterator item;\r
+\r
+    item = VarMap.begin();\r
+    for (unsigned i=0; i<a_iVar; ++i)\r
+      item++;\r
+\r
+     strncpy(szName, item->first.c_str(), sizeof(szName));\r
+     szName[sizeof(szName)-1] = 0;\r
+\r
+    *a_szName = &szName[0];\r
+    *a_pVar = item->second;\r
+     return;\r
+\r
+  MU_CATCH\r
+\r
+  *a_szName = 0;\r
+  *a_pVar = 0;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Get the number of variables used in the expression currently set in the parser.\r
+    \param a_hParser [in] Must be a valid parser handle.\r
+    \return The number of used variables.\r
+    \sa mupGetExprVar\r
+*/\r
+API_EXPORT(int) mupGetExprVarNum(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    const mu::varmap_type VarMap = p->GetUsedVar();\r
+    return (int)VarMap.size();\r
+  MU_CATCH\r
+\r
+  return 0; // never reached\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return a variable that is used in an expression.\r
+\r
+    Prior to calling this function call mupGetExprVarNum in order to get the\r
+    number of variables in the expression. If the parameter a_iVar is greater\r
+    than the number of variables both a_szName and a_pVar will be set to zero.\r
+    As a side effect this function will trigger an internal calculation of the\r
+    expression undefined variables will be set to zero during this calculation.\r
+    During the calculation user defined callback functions present in the expression\r
+    will be called, this is unavoidable.\r
+\r
+    \param a_hParser [in] A valid parser handle.\r
+    \param a_iVar [in] The index of the variable to return.\r
+    \param a_szName [out] Pointer to the variable name.\r
+    \param a_pVar [out] Pointer to the variable.\r
+    \throw nothrow\r
+*/\r
+API_EXPORT(void) mupGetExprVar(muParserHandle_t a_hParser, \r
+                                                          unsigned a_iVar, \r
+                                                          const muChar_t **a_szName, \r
+                                                          muFloat_t **a_pVar)\r
+{\r
+  // A static buffer is needed for the name since i cant return the\r
+  // pointer from the map.\r
+  static muChar_t  szName[1024];\r
+\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    const mu::varmap_type VarMap = p->GetUsedVar();\r
+\r
+    if (a_iVar>=VarMap.size())\r
+    {\r
+     *a_szName = 0;\r
+     *a_pVar = 0;\r
+      return;\r
+    }\r
+    mu::varmap_type::const_iterator item;\r
+\r
+    item = VarMap.begin();\r
+    for (unsigned i=0; i<a_iVar; ++i)\r
+      item++;\r
+\r
+     strncpy(szName, item->first.c_str(), sizeof(szName));\r
+     szName[sizeof(szName)-1] = 0;\r
+\r
+    *a_szName = &szName[0];\r
+    *a_pVar = item->second;\r
+     return;\r
+\r
+  MU_CATCH\r
+\r
+  *a_szName = 0;\r
+  *a_pVar = 0;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return the number of constants defined in a parser. */\r
+API_EXPORT(int) mupGetConstNum(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    const mu::valmap_type ValMap = p->GetConst();\r
+    return (int)ValMap.size();\r
+  MU_CATCH\r
+\r
+  return 0; // never reached\r
+}\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+API_EXPORT(void) mupSetArgSep(muParserHandle_t a_hParser, const muChar_t cArgSep)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->SetArgSep(cArgSep);\r
+  MU_CATCH\r
+}\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+API_EXPORT(void) mupResetLocale(muParserHandle_t a_hParser)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->ResetLocale();\r
+  MU_CATCH\r
+}\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+API_EXPORT(void) mupSetDecSep(muParserHandle_t a_hParser, const muChar_t cDecSep)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->SetDecSep(cDecSep);\r
+  MU_CATCH\r
+}\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+API_EXPORT(void) mupSetThousandsSep(muParserHandle_t a_hParser, const muChar_t cThousandsSep)\r
+{\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    p->SetThousandsSep(cThousandsSep);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Retrieve name and value of a single parser constant.\r
+    \param a_hParser [in] a valid parser handle\r
+    \param a_iVar [in] Index of the constant to query\r
+    \param a_pszName [out] pointer to a null terminated string with the constant name\r
+    \param [out] The constant value\r
+*/\r
+API_EXPORT(void) mupGetConst( muParserHandle_t a_hParser, \r
+                              unsigned a_iVar,\r
+                              const muChar_t **a_pszName, \r
+                              muFloat_t *a_fVal)\r
+{\r
+  // A static buffer is needed for the name since i cant return the\r
+  // pointer from the map.\r
+  static muChar_t szName[1024];\r
+\r
+  MU_TRY\r
+    muParser_t* const p(AsParser(a_hParser));\r
+    const mu::valmap_type ValMap = p->GetConst();\r
+\r
+    if (a_iVar>=ValMap.size())\r
+    {\r
+     *a_pszName = 0;\r
+     *a_fVal = 0;\r
+      return;\r
+    }\r
+\r
+    mu::valmap_type::const_iterator item;\r
+    item = ValMap.begin();\r
+    for (unsigned i=0; i<a_iVar; ++i)\r
+      item++;\r
+\r
+    strncpy(szName, item->first.c_str(), sizeof(szName));\r
+    szName[sizeof(szName)-1] = 0;\r
+\r
+    *a_pszName = &szName[0];\r
+    *a_fVal = item->second;\r
+     return;\r
+\r
+  MU_CATCH\r
+\r
+  *a_pszName = 0;\r
+  *a_fVal = 0;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Add a custom value regognition function.\r
+*/\r
+API_EXPORT(void) mupAddValIdent(muParserHandle_t a_hParser, \r
+                                muIdentFun_t a_pFun)\r
+{\r
+  MU_TRY\r
+    muParser_t* p(AsParser(a_hParser));\r
+    p->AddValIdent(a_pFun);\r
+  MU_CATCH\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Query if an error occured.\r
+\r
+    After querying the internal error bit will be reset. So a consecutive call\r
+    will return false.\r
+*/\r
+API_EXPORT(muBool_t) mupError(muParserHandle_t a_hParser)\r
+{\r
+  bool bError( AsParserTag(a_hParser)->bError );\r
+  AsParserTag(a_hParser)->bError = false;\r
+  return bError;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Reset the internal error flag.\r
+*/\r
+API_EXPORT(void) mupErrorReset(muParserHandle_t a_hParser)\r
+{\r
+  AsParserTag(a_hParser)->bError = false;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+API_EXPORT(void) mupSetErrorHandler(muParserHandle_t a_hParser, muErrorHandler_t a_pHandler)\r
+{\r
+  AsParserTag(a_hParser)->errHandler = a_pHandler;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return the message associated with the last error.\r
+*/\r
+API_EXPORT(const muChar_t*) mupGetErrorMsg(muParserHandle_t a_hParser)\r
+{\r
+  ParserTag* const p(AsParserTag(a_hParser));\r
+  const muChar_t *pMsg = p->exc.GetMsg().c_str();\r
+\r
+  // C# explodes when pMsg is returned directly. For some reason it can't access\r
+  // the memory where the message lies directly.\r
+  sprintf(s_tmpOutBuf, "%s", pMsg);\r
+  return s_tmpOutBuf;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return the message associated with the last error.\r
+*/\r
+API_EXPORT(const muChar_t*) mupGetErrorToken(muParserHandle_t a_hParser)\r
+{\r
+  ParserTag* const p(AsParserTag(a_hParser));\r
+  const muChar_t *pToken = p->exc.GetToken().c_str();\r
+\r
+  // C# explodes when pMsg is returned directly. For some reason it can't access\r
+  // the memory where the message lies directly.\r
+  sprintf(s_tmpOutBuf, "%s", pToken);\r
+  return s_tmpOutBuf;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return the code associated with the last error.\r
+*/\r
+API_EXPORT(int) mupGetErrorCode(muParserHandle_t a_hParser)\r
+{\r
+  return AsParserTag(a_hParser)->exc.GetCode();\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Return the postion associated with the last error. */\r
+API_EXPORT(int) mupGetErrorPos(muParserHandle_t a_hParser)\r
+{\r
+  return (int)AsParserTag(a_hParser)->exc.GetPos();\r
+}\r
+\r
+////-----------------------------------------------------------------------------------------------------\r
+//API_EXPORT(const muChar_t*) mupGetErrorExpr(muParserHandle_t a_hParser)\r
+//{\r
+//  return AsParserTag(a_hParser)->exc.GetExpr().c_str();\r
+//}\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+API_EXPORT(muFloat_t*) mupCreateVar()\r
+{\r
+  return new muFloat_t(0);\r
+}\r
+\r
+//-----------------------------------------------------------------------------------------------------\r
+API_EXPORT(void) mupReleaseVar(muFloat_t *ptr)\r
+{\r
+  delete ptr;\r
+}\r
+\r
+#endif      // MUPARSER_DLL\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserError.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserError.cpp
new file mode 100644 (file)
index 0000000..e3d334b
--- /dev/null
@@ -0,0 +1,336 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#include "muParserError.h"\r
+\r
+\r
+namespace mu\r
+{\r
+  const ParserErrorMsg ParserErrorMsg::m_Instance;\r
+\r
+  //------------------------------------------------------------------------------\r
+  const ParserErrorMsg& ParserErrorMsg::Instance()\r
+  {\r
+    return m_Instance;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  string_type ParserErrorMsg::operator[](unsigned a_iIdx) const\r
+  {\r
+    return (a_iIdx<m_vErrMsg.size()) ? m_vErrMsg[a_iIdx] : string_type();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserErrorMsg::~ParserErrorMsg()\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Assignement operator is deactivated.\r
+  */\r
+  ParserErrorMsg& ParserErrorMsg::operator=(const ParserErrorMsg& )\r
+  {\r
+    assert(false);\r
+    return *this;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserErrorMsg::ParserErrorMsg(const ParserErrorMsg&)\r
+  {}\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserErrorMsg::ParserErrorMsg()\r
+    :m_vErrMsg(0)\r
+  {\r
+    m_vErrMsg.resize(ecCOUNT);\r
+\r
+    m_vErrMsg[ecUNASSIGNABLE_TOKEN]     = _T("Unexpected token \"$TOK$\" found at position $POS$.");\r
+    m_vErrMsg[ecINTERNAL_ERROR]         = _T("Internal error");\r
+    m_vErrMsg[ecINVALID_NAME]           = _T("Invalid function-, variable- or constant name: \"$TOK$\".");\r
+    m_vErrMsg[ecINVALID_BINOP_IDENT]    = _T("Invalid binary operator identifier: \"$TOK$\".");\r
+    m_vErrMsg[ecINVALID_INFIX_IDENT]    = _T("Invalid infix operator identifier: \"$TOK$\".");\r
+    m_vErrMsg[ecINVALID_POSTFIX_IDENT]  = _T("Invalid postfix operator identifier: \"$TOK$\".");\r
+    m_vErrMsg[ecINVALID_FUN_PTR]        = _T("Invalid pointer to callback function.");\r
+    m_vErrMsg[ecEMPTY_EXPRESSION]       = _T("Expression is empty.");\r
+    m_vErrMsg[ecINVALID_VAR_PTR]        = _T("Invalid pointer to variable.");\r
+    m_vErrMsg[ecUNEXPECTED_OPERATOR]    = _T("Unexpected operator \"$TOK$\" found at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_EOF]         = _T("Unexpected end of expression at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_ARG_SEP]     = _T("Unexpected argument separator at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_PARENS]      = _T("Unexpected parenthesis \"$TOK$\" at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_FUN]         = _T("Unexpected function \"$TOK$\" at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_VAL]         = _T("Unexpected value \"$TOK$\" found at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_VAR]         = _T("Unexpected variable \"$TOK$\" found at position $POS$");\r
+    m_vErrMsg[ecUNEXPECTED_ARG]         = _T("Function arguments used without a function (position: $POS$)");\r
+    m_vErrMsg[ecMISSING_PARENS]         = _T("Missing parenthesis");\r
+    m_vErrMsg[ecTOO_MANY_PARAMS]        = _T("Too many parameters for function \"$TOK$\" at expression position $POS$");\r
+    m_vErrMsg[ecTOO_FEW_PARAMS]         = _T("Too few parameters for function \"$TOK$\" at expression position $POS$");\r
+    m_vErrMsg[ecDIV_BY_ZERO]            = _T("Divide by zero");\r
+    m_vErrMsg[ecDOMAIN_ERROR]           = _T("Domain error");\r
+    m_vErrMsg[ecNAME_CONFLICT]          = _T("Name conflict");\r
+    m_vErrMsg[ecOPT_PRI]                = _T("Invalid value for operator priority (must be greater or equal to zero).");\r
+    m_vErrMsg[ecBUILTIN_OVERLOAD]       = _T("user defined binary operator \"$TOK$\" conflicts with a built in operator.");\r
+    m_vErrMsg[ecUNEXPECTED_STR]         = _T("Unexpected string token found at position $POS$.");\r
+    m_vErrMsg[ecUNTERMINATED_STRING]    = _T("Unterminated string starting at position $POS$.");\r
+    m_vErrMsg[ecSTRING_EXPECTED]        = _T("String function called with a non string type of argument.");\r
+    m_vErrMsg[ecVAL_EXPECTED]           = _T("String value used where a numerical argument is expected.");\r
+    m_vErrMsg[ecOPRT_TYPE_CONFLICT]     = _T("No suitable overload for operator \"$TOK$\" at position $POS$.");\r
+    m_vErrMsg[ecSTR_RESULT]             = _T("Function result is a string.");\r
+    m_vErrMsg[ecGENERIC]                = _T("Parser error.");\r
+    m_vErrMsg[ecLOCALE]                 = _T("Decimal separator is identic to function argument separator.");\r
+    m_vErrMsg[ecUNEXPECTED_CONDITIONAL] = _T("The \"$TOK$\" operator must be preceeded by a closing bracket.");\r
+    m_vErrMsg[ecMISSING_ELSE_CLAUSE]    = _T("If-then-else operator is missing an else clause");\r
+    m_vErrMsg[ecMISPLACED_COLON]        = _T("Misplaced colon at position $POS$");\r
+\r
+    #if defined(_DEBUG)\r
+      for (int i=0; i<ecCOUNT; ++i)\r
+        if (!m_vErrMsg[i].length())\r
+          assert(false);\r
+    #endif\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  //\r
+  //  ParserError class\r
+  //\r
+  //---------------------------------------------------------------------------\r
+\r
+  /** \brief Default constructor. */\r
+  ParserError::ParserError()\r
+    :m_strMsg()\r
+    ,m_strFormula()\r
+    ,m_strTok()\r
+    ,m_iPos(-1)\r
+    ,m_iErrc(ecUNDEFINED)\r
+    ,m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief This Constructor is used for internal exceptions only. \r
+      \r
+    It does not contain any information but the error code.\r
+  */\r
+  ParserError::ParserError(EErrorCodes a_iErrc) \r
+    :m_strMsg()\r
+    ,m_strFormula()\r
+    ,m_strTok()\r
+    ,m_iPos(-1)\r
+    ,m_iErrc(a_iErrc)\r
+    ,m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+    m_strMsg = m_ErrMsg[m_iErrc];\r
+    stringstream_type stream;\r
+    stream << (int)m_iPos;\r
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());\r
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Construct an error from a message text. */\r
+  ParserError::ParserError(const string_type &sMsg) \r
+    :m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+    Reset();\r
+    m_strMsg = sMsg;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Construct an error object. \r
+      \param [in] a_iErrc the error code.\r
+      \param [in] sTok The token string related to this error.\r
+      \param [in] sExpr The expression related to the error.\r
+      \param [in] a_iPos the position in the expression where the error occured. \r
+  */\r
+  ParserError::ParserError( EErrorCodes iErrc,\r
+                            const string_type &sTok,\r
+                            const string_type &sExpr,\r
+                            int iPos )\r
+    :m_strMsg()\r
+    ,m_strFormula(sExpr)\r
+    ,m_strTok(sTok)\r
+    ,m_iPos(iPos)\r
+    ,m_iErrc(iErrc)\r
+    ,m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+    m_strMsg = m_ErrMsg[m_iErrc];\r
+    stringstream_type stream;\r
+    stream << (int)m_iPos;\r
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());\r
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Construct an error object. \r
+      \param [in] iErrc the error code.\r
+      \param [in] iPos the position in the expression where the error occured. \r
+      \param [in] sTok The token string related to this error.\r
+  */\r
+  ParserError::ParserError(EErrorCodes iErrc, int iPos, const string_type &sTok) \r
+    :m_strMsg()\r
+    ,m_strFormula()\r
+    ,m_strTok(sTok)\r
+    ,m_iPos(iPos)\r
+    ,m_iErrc(iErrc)\r
+    ,m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+    m_strMsg = m_ErrMsg[m_iErrc];\r
+    stringstream_type stream;\r
+    stream << (int)m_iPos;\r
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());\r
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Construct an error object. \r
+      \param [in] szMsg The error message text.\r
+      \param [in] iPos the position related to the error.\r
+      \param [in] sTok The token string related to this error.\r
+  */\r
+  ParserError::ParserError(const char_type *szMsg, int iPos, const string_type &sTok) \r
+    :m_strMsg(szMsg)\r
+    ,m_strFormula()\r
+    ,m_strTok(sTok)\r
+    ,m_iPos(iPos)\r
+    ,m_iErrc(ecGENERIC)\r
+    ,m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+    stringstream_type stream;\r
+    stream << (int)m_iPos;\r
+    ReplaceSubString(m_strMsg, _T("$POS$"), stream.str());\r
+    ReplaceSubString(m_strMsg, _T("$TOK$"), m_strTok);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Copy constructor. */\r
+  ParserError::ParserError(const ParserError &a_Obj)\r
+    :m_strMsg(a_Obj.m_strMsg)\r
+    ,m_strFormula(a_Obj.m_strFormula)\r
+    ,m_strTok(a_Obj.m_strTok)\r
+    ,m_iPos(a_Obj.m_iPos)\r
+    ,m_iErrc(a_Obj.m_iErrc)\r
+    ,m_ErrMsg(ParserErrorMsg::Instance())\r
+  {\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Assignment operator. */\r
+  ParserError& ParserError::operator=(const ParserError &a_Obj)\r
+  {\r
+    if (this==&a_Obj)\r
+      return *this;\r
+\r
+    m_strMsg = a_Obj.m_strMsg;\r
+    m_strFormula = a_Obj.m_strFormula;\r
+    m_strTok = a_Obj.m_strTok;\r
+    m_iPos = a_Obj.m_iPos;\r
+    m_iErrc = a_Obj.m_iErrc;\r
+    return *this;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  ParserError::~ParserError()\r
+  {}\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Replace all ocuurences of a substring with another string. \r
+      \param strFind The string that shall be replaced.\r
+      \param strReplaceWith The string that should be inserted instead of strFind\r
+  */\r
+  void ParserError::ReplaceSubString( string_type &strSource,\r
+                                      const string_type &strFind,\r
+                                      const string_type &strReplaceWith)\r
+  {\r
+    string_type strResult;\r
+    string_type::size_type iPos(0), iNext(0);\r
+\r
+    for(;;)\r
+    {\r
+      iNext = strSource.find(strFind, iPos);\r
+      strResult.append(strSource, iPos, iNext-iPos);\r
+\r
+      if( iNext==string_type::npos )\r
+        break;\r
+\r
+      strResult.append(strReplaceWith);\r
+      iPos = iNext + strFind.length();\r
+    } \r
+\r
+    strSource.swap(strResult);\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Reset the erro object. */\r
+  void ParserError::Reset()\r
+  {\r
+    m_strMsg = _T("");\r
+    m_strFormula = _T("");\r
+    m_strTok = _T("");\r
+    m_iPos = -1;\r
+    m_iErrc = ecUNDEFINED;\r
+  }\r
+      \r
+  //------------------------------------------------------------------------------\r
+  /** \brief Set the expression related to this error. */\r
+  void ParserError::SetFormula(const string_type &a_strFormula)\r
+  {\r
+    m_strFormula = a_strFormula;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief gets the expression related tp this error.*/\r
+  const string_type& ParserError::GetExpr() const \r
+  {\r
+    return m_strFormula;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Returns the message string for this error. */\r
+  const string_type& ParserError::GetMsg() const\r
+  {\r
+    return m_strMsg;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Return the formula position related to the error. \r
+\r
+    If the error is not related to a distinct position this will return -1\r
+  */\r
+  std::size_t ParserError::GetPos() const\r
+  {\r
+    return m_iPos;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Return string related with this token (if available). */\r
+  const string_type& ParserError::GetToken() const\r
+  {\r
+    return m_strTok;\r
+  }\r
+\r
+  //------------------------------------------------------------------------------\r
+  /** \brief Return the error code. */\r
+  EErrorCodes ParserError::GetCode() const\r
+  {\r
+    return m_iErrc;\r
+  }\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserInt.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserInt.cpp
new file mode 100644 (file)
index 0000000..fd377a8
--- /dev/null
@@ -0,0 +1,280 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2011 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#include "muParserInt.h"\r
+\r
+#include <cmath>\r
+#include <algorithm>\r
+#include <numeric>\r
+\r
+using namespace std;\r
+\r
+/** \file\r
+    \brief Implementation of a parser using integer value.\r
+*/\r
+\r
+/** \brief Namespace for mathematical applications. */\r
+namespace mu\r
+{\r
+value_type ParserInt::Abs(value_type v)  { return (value_type)Round(fabs((double)v)); }\r
+value_type ParserInt::Sign(value_type v) { return (Round(v)<0) ? -1 : (Round(v)>0) ? 1 : 0; }\r
+value_type ParserInt::Ite(value_type v1, \r
+                          value_type v2, \r
+                          value_type v3) { return (Round(v1)==1) ? Round(v2) : Round(v3); }\r
+value_type ParserInt::Add(value_type v1, value_type v2) { return Round(v1)  + Round(v2); }\r
+value_type ParserInt::Sub(value_type v1, value_type v2) { return Round(v1)  - Round(v2); }\r
+value_type ParserInt::Mul(value_type v1, value_type v2) { return Round(v1)  * Round(v2); }\r
+value_type ParserInt::Div(value_type v1, value_type v2) { return Round(v1)  / Round(v2); }\r
+value_type ParserInt::Mod(value_type v1, value_type v2) { return Round(v1)  % Round(v2); }\r
+value_type ParserInt::Shr(value_type v1, value_type v2) { return Round(v1) >> Round(v2); }\r
+value_type ParserInt::Shl(value_type v1, value_type v2) { return Round(v1) << Round(v2); }\r
+value_type ParserInt::LogAnd(value_type v1, value_type v2) { return Round(v1) & Round(v2); }\r
+value_type ParserInt::LogOr(value_type v1, value_type v2)  { return Round(v1) | Round(v2); }\r
+value_type ParserInt::And(value_type v1, value_type v2) { return Round(v1) && Round(v2); }\r
+value_type ParserInt::Or(value_type v1, value_type v2)  { return Round(v1) || Round(v2); }\r
+value_type ParserInt::Less(value_type v1, value_type v2)      { return Round(v1)  < Round(v2); }\r
+value_type ParserInt::Greater(value_type v1, value_type v2)   { return Round(v1)  > Round(v2); }\r
+value_type ParserInt::LessEq(value_type v1, value_type v2)    { return Round(v1) <= Round(v2); }\r
+value_type ParserInt::GreaterEq(value_type v1, value_type v2) { return Round(v1) >= Round(v2); }\r
+value_type ParserInt::Equal(value_type v1, value_type v2)     { return Round(v1) == Round(v2); }\r
+value_type ParserInt::NotEqual(value_type v1, value_type v2)  { return Round(v1) != Round(v2); }\r
+value_type ParserInt::Not(value_type v) { return !Round(v); }\r
+\r
+value_type ParserInt::Pow(value_type v1, value_type v2) \r
+{ \r
+  return std::pow((double)Round(v1), (double)Round(v2)); \r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+// Unary operator Callbacks: Infix operators\r
+value_type ParserInt::UnaryMinus(value_type v) \r
+{ \r
+  return -Round(v); \r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+value_type ParserInt::Sum(const value_type* a_afArg, int a_iArgc)\r
+{ \r
+  if (!a_iArgc)        \r
+    throw ParserError(_T("too few arguments for function sum."));\r
+\r
+  value_type fRes=0;\r
+  for (int i=0; i<a_iArgc; ++i) \r
+    fRes += a_afArg[i];\r
+\r
+  return fRes;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+value_type ParserInt::Min(const value_type* a_afArg, int a_iArgc)\r
+{ \r
+  if (!a_iArgc)        \r
+    throw ParserError( _T("too few arguments for function min.") );\r
+\r
+  value_type fRes=a_afArg[0];\r
+  for (int i=0; i<a_iArgc; ++i) \r
+    fRes = std::min(fRes, a_afArg[i]);\r
+\r
+  return fRes;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+value_type ParserInt::Max(const value_type* a_afArg, int a_iArgc)\r
+{ \r
+  if (!a_iArgc)        \r
+    throw ParserError(_T("too few arguments for function min."));\r
+\r
+  value_type fRes=a_afArg[0];\r
+  for (int i=0; i<a_iArgc; ++i) \r
+    fRes = std::max(fRes, a_afArg[i]);\r
+\r
+  return fRes;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+// Default value recognition callback\r
+int ParserInt::IsVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)\r
+{\r
+  string_type buf(a_szExpr);\r
+  std::size_t pos = buf.find_first_not_of(_T("0123456789"));\r
+\r
+  if (pos==std::string::npos)\r
+    return 0;\r
+\r
+  stringstream_type stream( buf.substr(0, pos ) );\r
+  int iVal(0);\r
+\r
+  stream >> iVal;\r
+  if (stream.fail())\r
+    return 0;\r
+      \r
+  stringstream_type::pos_type iEnd = stream.tellg();   // Position after reading\r
+  if (stream.fail())\r
+    iEnd = stream.str().length();  \r
+\r
+  if (iEnd==(stringstream_type::pos_type)-1)\r
+    return 0;\r
+\r
+  *a_iPos += (int)iEnd;\r
+  *a_fVal = (value_type)iVal;\r
+  return 1;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Check a given position in the expression for the presence of \r
+           a hex value. \r
+    \param a_szExpr Pointer to the expression string\r
+    \param [in/out] a_iPos Pointer to an interger value holding the current parsing \r
+           position in the expression.\r
+    \param [out] a_fVal Pointer to the position where the detected value shall be stored.\r
+\r
+  Hey values must be prefixed with "0x" in order to be detected properly.\r
+*/\r
+int ParserInt::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)\r
+{\r
+  if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) \r
+    return 0;\r
+\r
+  unsigned iVal(0);\r
+\r
+  // New code based on streams for UNICODE compliance:\r
+  stringstream_type::pos_type nPos(0);\r
+  stringstream_type ss(a_szExpr + 2);\r
+  ss >> std::hex >> iVal;\r
+  nPos = ss.tellg();\r
+\r
+  if (nPos==(stringstream_type::pos_type)0)\r
+    return 1;\r
+\r
+  *a_iPos += (int)(2 + nPos);\r
+  *a_fVal = (value_type)iVal;\r
+  return 1;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+int ParserInt::IsBinVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)\r
+{\r
+  if (a_szExpr[0]!='#') \r
+    return 0;\r
+\r
+  unsigned iVal(0), \r
+           iBits(sizeof(iVal)*8),\r
+           i(0);\r
+\r
+  for (i=0; (a_szExpr[i+1]=='0' || a_szExpr[i+1]=='1') && i<iBits; ++i)\r
+    iVal |= (int)(a_szExpr[i+1]=='1') << ((iBits-1)-i);\r
+\r
+  if (i==0) \r
+    return 0;\r
+\r
+  if (i==iBits)\r
+    throw exception_type(_T("Binary to integer conversion error (overflow)."));\r
+\r
+  *a_fVal = (unsigned)(iVal >> (iBits-i) );\r
+  *a_iPos += i+1;\r
+\r
+  return 1;\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Constructor. \r
+\r
+  Call ParserBase class constructor and trigger Function, Operator and Constant initialization.\r
+*/\r
+ParserInt::ParserInt()\r
+  :ParserBase()\r
+{\r
+  AddValIdent(IsVal);    // lowest priority\r
+  AddValIdent(IsBinVal);\r
+  AddValIdent(IsHexVal); // highest priority\r
+\r
+  InitCharSets();\r
+  InitFun();\r
+  InitOprt();\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+void ParserInt::InitConst()\r
+{\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+void ParserInt::InitCharSets()\r
+{\r
+  DefineNameChars( _T("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") );\r
+  DefineOprtChars( _T("+-*^/?<>=!%&|~'_") );\r
+  DefineInfixOprtChars( _T("/+-*^?<>=!%&|~'_") );\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Initialize the default functions. */\r
+void ParserInt::InitFun()\r
+{\r
+  DefineFun( _T("sign"), Sign);\r
+  DefineFun( _T("abs"), Abs);\r
+  DefineFun( _T("if"), Ite);\r
+  DefineFun( _T("sum"), Sum);\r
+  DefineFun( _T("min"), Min);\r
+  DefineFun( _T("max"), Max);\r
+}\r
+\r
+//---------------------------------------------------------------------------\r
+/** \brief Initialize operators. */\r
+void ParserInt::InitOprt()\r
+{\r
+  // disable all built in operators, not all of them usefull for integer numbers\r
+  // (they don't do rounding of values)\r
+  EnableBuiltInOprt(false);\r
+\r
+  // Disable all built in operators, they wont work with integer numbers\r
+  // since they are designed for floating point numbers\r
+  DefineInfixOprt( _T("-"), UnaryMinus);\r
+  DefineInfixOprt( _T("!"), Not);\r
+\r
+  DefineOprt( _T("&"), LogAnd, prLOGIC);\r
+  DefineOprt( _T("|"), LogOr, prLOGIC);\r
+  DefineOprt( _T("&&"), And, prLOGIC);\r
+  DefineOprt( _T("||"), Or, prLOGIC);\r
+\r
+  DefineOprt( _T("<"), Less, prCMP);\r
+  DefineOprt( _T(">"), Greater, prCMP);\r
+  DefineOprt( _T("<="), LessEq, prCMP);\r
+  DefineOprt( _T(">="), GreaterEq, prCMP);\r
+  DefineOprt( _T("=="), Equal, prCMP);\r
+  DefineOprt( _T("!="), NotEqual, prCMP);\r
+\r
+  DefineOprt( _T("+"), Add, prADD_SUB);\r
+  DefineOprt( _T("-"), Sub, prADD_SUB);\r
+\r
+  DefineOprt( _T("*"), Mul, prMUL_DIV);\r
+  DefineOprt( _T("/"), Div, prMUL_DIV);\r
+  DefineOprt( _T("%"), Mod, prMUL_DIV);\r
+\r
+  DefineOprt( _T("^"), Pow, prPOW, oaRIGHT);\r
+  DefineOprt( _T(">>"), Shr, prMUL_DIV+1);\r
+  DefineOprt( _T("<<"), Shl, prMUL_DIV+1);\r
+}\r
+\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserTest.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserTest.cpp
new file mode 100644 (file)
index 0000000..b9818b6
--- /dev/null
@@ -0,0 +1,1450 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+\r
+#include "muParserTest.h"\r
+\r
+#include <cstdio>\r
+#include <cmath>\r
+#include <iostream>\r
+#include <limits>\r
+\r
+#define PARSER_CONST_PI  3.141592653589793238462643\r
+#define PARSER_CONST_E   2.718281828459045235360287\r
+\r
+using namespace std;\r
+\r
+/** \file\r
+    \brief This file contains the implementation of parser test cases.\r
+*/\r
+\r
+namespace mu\r
+{\r
+  namespace Test\r
+  {\r
+    int ParserTester::c_iCount = 0;\r
+\r
+    //---------------------------------------------------------------------------------------------\r
+    ParserTester::ParserTester()\r
+      :m_vTestFun()\r
+    {\r
+      AddTest(&ParserTester::TestNames);\r
+      AddTest(&ParserTester::TestSyntax);\r
+      AddTest(&ParserTester::TestPostFix);\r
+      AddTest(&ParserTester::TestInfixOprt);\r
+      AddTest(&ParserTester::TestVarConst);\r
+      AddTest(&ParserTester::TestMultiArg);\r
+      AddTest(&ParserTester::TestExpression);\r
+      AddTest(&ParserTester::TestIfThenElse);\r
+      AddTest(&ParserTester::TestInterface);\r
+      AddTest(&ParserTester::TestBinOprt);\r
+      AddTest(&ParserTester::TestException);\r
+      AddTest(&ParserTester::TestStrArg);\r
+\r
+      ParserTester::c_iCount = 0;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------------------------\r
+    int ParserTester::IsHexVal(const char_type *a_szExpr, int *a_iPos, value_type *a_fVal)\r
+    {\r
+      if (a_szExpr[1]==0 || (a_szExpr[0]!='0' || a_szExpr[1]!='x') ) \r
+        return 0;\r
+\r
+      unsigned iVal(0);\r
+\r
+      // New code based on streams for UNICODE compliance:\r
+      stringstream_type::pos_type nPos(0);\r
+      stringstream_type ss(a_szExpr + 2);\r
+      ss >> std::hex >> iVal;\r
+      nPos = ss.tellg();\r
+\r
+      if (nPos==(stringstream_type::pos_type)0)\r
+        return 1;\r
+\r
+      *a_iPos += (int)(2 + nPos);\r
+      *a_fVal = (value_type)iVal;\r
+      return 1;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------------------------\r
+    int ParserTester::TestInterface()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing member functions...");\r
+   \r
+      // Test RemoveVar\r
+      value_type afVal[3] = {1,2,3};\r
+      Parser p;\r
+  \r
+      try\r
+      {\r
+        p.DefineVar( _T("a"), &afVal[0]);\r
+        p.DefineVar( _T("b"), &afVal[1]);\r
+        p.DefineVar( _T("c"), &afVal[2]);\r
+        p.SetExpr( _T("a+b+c") );\r
+        p.Eval();\r
+      }\r
+      catch(...)\r
+      {\r
+        iStat += 1;  // this is not supposed to happen \r
+      }\r
+\r
+      try\r
+      {\r
+        p.RemoveVar( _T("c") );\r
+        p.Eval();\r
+        iStat += 1;  // not supposed to reach this, nonexisting variable "c" deleted...\r
+      }\r
+      catch(...)\r
+      {\r
+        // failure is expected...\r
+      }\r
+\r
+      if (iStat==0) \r
+        mu::console() << _T("passed") << endl;\r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------------------------\r
+    int ParserTester::TestStrArg()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing string arguments...");\r
\r
+      iStat += EqnTest(_T("valueof(\"\")"), 123, true);   // empty string arguments caused a crash\r
+      iStat += EqnTest(_T("valueof(\"aaa\")+valueof(\"bbb\")  "), 246, true);\r
+      iStat += EqnTest(_T("2*(valueof(\"aaa\")-23)+valueof(\"bbb\")"), 323, true);\r
+      // use in expressions with variables\r
+      iStat += EqnTest(_T("a*(atof(\"10\")-b)"), 8, true);\r
+      iStat += EqnTest(_T("a-(atof(\"10\")*b)"), -19, true);\r
+      // string + numeric arguments\r
+      iStat += EqnTest(_T("strfun1(\"100\")"), 100, true);\r
+      iStat += EqnTest(_T("strfun2(\"100\",1)"), 101, true);\r
+      iStat += EqnTest(_T("strfun3(\"99\",1,2)"), 102, true);\r
+\r
+      if (iStat==0)\r
+        mu::console() << _T("passed") << endl;\r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------------------------\r
+    int ParserTester::TestBinOprt()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing binary operators...");\r
+   \r
+      // built in operators\r
+      // xor operator\r
+      //iStat += EqnTest(_T("1 xor 2"), 3, true); \r
+      //iStat += EqnTest(_T("a xor b"), 3, true);            // with a=1 and b=2\r
+      //iStat += EqnTest(_T("1 xor 2 xor 3"), 0, true); \r
+      //iStat += EqnTest(_T("a xor b xor 3"), 0, true);      // with a=1 and b=2\r
+      //iStat += EqnTest(_T("a xor b xor c"), 0, true);      // with a=1 and b=2\r
+      //iStat += EqnTest(_T("(1 xor 2) xor 3"), 0, true); \r
+      //iStat += EqnTest(_T("(a xor b) xor c"), 0, true);    // with a=1 and b=2\r
+      //iStat += EqnTest(_T("(a) xor (b) xor c"), 0, true);  // with a=1 and b=2\r
+      //iStat += EqnTest(_T("1 or 2"), 3, true); \r
+      //iStat += EqnTest(_T("a or b"), 3, true);             // with a=1 and b=2\r
+      iStat += EqnTest(_T("a++b"), 3, true);\r
+      iStat += EqnTest(_T("a ++ b"), 3, true);\r
+      iStat += EqnTest(_T("1++2"), 3, true);\r
+      iStat += EqnTest(_T("1 ++ 2"), 3, true);\r
+      iStat += EqnTest(_T("a add b"), 3, true);\r
+      iStat += EqnTest(_T("1 add 2"), 3, true);\r
+      iStat += EqnTest(_T("a<b"), 1, true);\r
+      iStat += EqnTest(_T("b>a"), 1, true);\r
+      iStat += EqnTest(_T("a>a"), 0, true);\r
+      iStat += EqnTest(_T("a<a"), 0, true);\r
+      iStat += EqnTest(_T("a>a"), 0, true);\r
+      iStat += EqnTest(_T("a<=a"), 1, true);\r
+      iStat += EqnTest(_T("a<=b"), 1, true);\r
+      iStat += EqnTest(_T("b<=a"), 0, true);\r
+      iStat += EqnTest(_T("a>=a"), 1, true);\r
+      iStat += EqnTest(_T("b>=a"), 1, true);\r
+      iStat += EqnTest(_T("a>=b"), 0, true);\r
+\r
+      // Test logical operators, expecially if user defined "&" and the internal "&&" collide\r
+      iStat += EqnTest(_T("1 && 1"), 1, true); \r
+      iStat += EqnTest(_T("1 && 0"), 0, true); \r
+      iStat += EqnTest(_T("(a<b) && (b>a)"), 1, true); \r
+      iStat += EqnTest(_T("(a<b) && (a>b)"), 0, true); \r
+      //iStat += EqnTest(_T("12 and 255"), 12, true); \r
+      //iStat += EqnTest(_T("12 and 0"), 0, true); \r
+      iStat += EqnTest(_T("12 & 255"), 12, true); \r
+      iStat += EqnTest(_T("12 & 0"), 0, true); \r
+      iStat += EqnTest(_T("12&255"), 12, true); \r
+      iStat += EqnTest(_T("12&0"), 0, true); \r
+\r
+      // Assignement operator\r
+      iStat += EqnTest(_T("a = b"), 2, true); \r
+      iStat += EqnTest(_T("a = sin(b)"), 0.909297, true); \r
+      iStat += EqnTest(_T("a = 1+sin(b)"), 1.909297, true);\r
+      iStat += EqnTest(_T("(a=b)*2"), 4, true);\r
+      iStat += EqnTest(_T("2*(a=b)"), 4, true);\r
+      iStat += EqnTest(_T("2*(a=b+1)"), 6, true);\r
+      iStat += EqnTest(_T("(a=b+1)*2"), 6, true);\r
+\r
+      iStat += EqnTest(_T("2^2^3"), 256, true); \r
+      iStat += EqnTest(_T("1/2/3"), 1.0/6.0, true); \r
+\r
+      // reference: http://www.wolframalpha.com/input/?i=3%2B4*2%2F%281-5%29^2^3\r
+      iStat += EqnTest(_T("3+4*2/(1-5)^2^3"), 3.0001220703125, true); \r
+\r
+      // Test user defined binary operators\r
+      iStat += EqnTestInt(_T("1 | 2"), 3, true);          \r
+      iStat += EqnTestInt(_T("1 || 2"), 1, true);          \r
+      iStat += EqnTestInt(_T("123 & 456"), 72, true);          \r
+      iStat += EqnTestInt(_T("(123 & 456) % 10"), 2, true);\r
+      iStat += EqnTestInt(_T("1 && 0"), 0, true);          \r
+      iStat += EqnTestInt(_T("123 && 456"), 1, true);          \r
+      iStat += EqnTestInt(_T("1 << 3"), 8, true);          \r
+      iStat += EqnTestInt(_T("8 >> 3"), 1, true);          \r
+      iStat += EqnTestInt(_T("9 / 4"), 2, true);  \r
+      iStat += EqnTestInt(_T("9 % 4"), 1, true);  \r
+      iStat += EqnTestInt(_T("if(5%2,1,0)"), 1, true);\r
+      iStat += EqnTestInt(_T("if(4%2,1,0)"), 0, true);\r
+      iStat += EqnTestInt(_T("-10+1"), -9, true);\r
+      iStat += EqnTestInt(_T("1+2*3"), 7, true);\r
+      iStat += EqnTestInt(_T("const1 != const2"), 1, true);\r
+      iStat += EqnTestInt(_T("const1 != const2"), 0, false);\r
+      iStat += EqnTestInt(_T("const1 == const2"), 0, true);\r
+      iStat += EqnTestInt(_T("const1 == 1"), 1, true);\r
+      iStat += EqnTestInt(_T("10*(const1 == 1)"), 10, true);\r
+      iStat += EqnTestInt(_T("2*(const1 | const2)"), 6, true);\r
+      iStat += EqnTestInt(_T("2*(const1 | const2)"), 7, false);\r
+      iStat += EqnTestInt(_T("const1 < const2"), 1, true);\r
+      iStat += EqnTestInt(_T("const2 > const1"), 1, true);\r
+      iStat += EqnTestInt(_T("const1 <= 1"), 1, true);\r
+      iStat += EqnTestInt(_T("const2 >= 2"), 1, true);\r
+      iStat += EqnTestInt(_T("2*(const1 + const2)"), 6, true);\r
+      iStat += EqnTestInt(_T("2*(const1 - const2)"), -2, true);\r
+      iStat += EqnTestInt(_T("a != b"), 1, true);\r
+      iStat += EqnTestInt(_T("a != b"), 0, false);\r
+      iStat += EqnTestInt(_T("a == b"), 0, true);\r
+      iStat += EqnTestInt(_T("a == 1"), 1, true);\r
+      iStat += EqnTestInt(_T("10*(a == 1)"), 10, true);\r
+      iStat += EqnTestInt(_T("2*(a | b)"), 6, true);\r
+      iStat += EqnTestInt(_T("2*(a | b)"), 7, false);\r
+      iStat += EqnTestInt(_T("a < b"), 1, true);\r
+      iStat += EqnTestInt(_T("b > a"), 1, true);\r
+      iStat += EqnTestInt(_T("a <= 1"), 1, true);\r
+      iStat += EqnTestInt(_T("b >= 2"), 1, true);\r
+      iStat += EqnTestInt(_T("2*(a + b)"), 6, true);\r
+      iStat += EqnTestInt(_T("2*(a - b)"), -2, true);\r
+      iStat += EqnTestInt(_T("a + (a << b)"), 5, true);\r
+      iStat += EqnTestInt(_T("-2^2"), -4, true);\r
+      iStat += EqnTestInt(_T("3--a"), 4, true);\r
+      iStat += EqnTestInt(_T("3+-3^2"), -6, true);\r
+\r
+      // Test reading of hex values:\r
+      iStat += EqnTestInt(_T("0xff"), 255, true);\r
+      iStat += EqnTestInt(_T("10+0xff"), 265, true);\r
+      iStat += EqnTestInt(_T("0xff+10"), 265, true);\r
+      iStat += EqnTestInt(_T("10*0xff"), 2550, true);\r
+      iStat += EqnTestInt(_T("0xff*10"), 2550, true);\r
+      iStat += EqnTestInt(_T("10+0xff+1"), 266, true);\r
+      iStat += EqnTestInt(_T("1+0xff+10"), 266, true);\r
+\r
+// incorrect: '^' is yor here, not power\r
+//    iStat += EqnTestInt("-(1+2)^2", -9, true);\r
+//    iStat += EqnTestInt("-1^3", -1, true);          \r
+\r
+      // Test precedence\r
+      // a=1, b=2, c=3\r
+      iStat += EqnTestInt(_T("a + b * c"), 7, true);\r
+      iStat += EqnTestInt(_T("a * b + c"), 5, true);\r
+      iStat += EqnTestInt(_T("a<b && b>10"), 0, true);\r
+      iStat += EqnTestInt(_T("a<b && b<10"), 1, true);\r
+\r
+      iStat += EqnTestInt(_T("a + b << c"), 17, true);\r
+      iStat += EqnTestInt(_T("a << b + c"), 7, true);\r
+      iStat += EqnTestInt(_T("c * b < a"), 0, true);\r
+      iStat += EqnTestInt(_T("c * b == 6 * a"), 1, true);\r
+      iStat += EqnTestInt(_T("2^2^3"), 256, true); \r
+\r
+\r
+      if (iStat==0)\r
+        mu::console() << _T("passed") << endl;\r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------------------------\r
+    /** \brief Check muParser name restriction enforcement. */\r
+    int ParserTester::TestNames()\r
+    {\r
+      int  iStat= 0,\r
+           iErr = 0;\r
+\r
+      mu::console() << "testing name restriction enforcement...";\r
+    \r
+      Parser p;\r
+\r
+  #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \\r
+      iErr = 0;                                      \\r
+      ParserTester::c_iCount++;                      \\r
+      try                                            \\r
+      {                                              \\r
+        p.Define##DOMAIN(EXPR, ARG);                 \\r
+      }                                              \\r
+      catch(Parser::exception_type&)                 \\r
+      {                                              \\r
+        iErr = (FAIL==false) ? 0 : 1;                \\r
+      }                                              \\r
+      iStat += iErr;      \r
+      \r
+      // constant names\r
+      PARSER_THROWCHECK(Const, false, _T("0a"), 1)\r
+      PARSER_THROWCHECK(Const, false, _T("9a"), 1)\r
+      PARSER_THROWCHECK(Const, false, _T("+a"), 1)\r
+      PARSER_THROWCHECK(Const, false, _T("-a"), 1)\r
+      PARSER_THROWCHECK(Const, false, _T("a-"), 1)\r
+      PARSER_THROWCHECK(Const, false, _T("a*"), 1)\r
+      PARSER_THROWCHECK(Const, false, _T("a?"), 1)\r
+      PARSER_THROWCHECK(Const, true, _T("a"), 1)\r
+      PARSER_THROWCHECK(Const, true, _T("a_min"), 1)\r
+      PARSER_THROWCHECK(Const, true, _T("a_min0"), 1)\r
+      PARSER_THROWCHECK(Const, true, _T("a_min9"), 1)\r
+      // variable names\r
+      value_type a;\r
+      p.ClearConst();\r
+      PARSER_THROWCHECK(Var, false, _T("123abc"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("9a"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("0a"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("+a"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("-a"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("?a"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("!a"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("a+"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("a-"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("a*"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("a?"), &a)\r
+      PARSER_THROWCHECK(Var, true, _T("a"), &a)\r
+      PARSER_THROWCHECK(Var, true, _T("a_min"), &a)\r
+      PARSER_THROWCHECK(Var, true, _T("a_min0"), &a)\r
+      PARSER_THROWCHECK(Var, true, _T("a_min9"), &a)\r
+      PARSER_THROWCHECK(Var, false, _T("a_min9"), 0)\r
+      // Postfix operators\r
+      // fail\r
+      PARSER_THROWCHECK(PostfixOprt, false, _T("(k"), f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, false, _T("9+"), f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, false, _T("+"), 0)\r
+      // pass\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("-a"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("?a"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("_"),   f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("#"),   f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("&&"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("||"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("&"),   f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("|"),   f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("++"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("--"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("?>"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("?<"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("**"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("xor"), f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("and"), f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("or"),  f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("not"), f1of1)\r
+      PARSER_THROWCHECK(PostfixOprt, true, _T("!"),   f1of1)\r
+      // Binary operator\r
+      // The following must fail with builtin operators activated\r
+      // p.EnableBuiltInOp(true); -> this is the default\r
+      p.ClearPostfixOprt();\r
+      PARSER_THROWCHECK(Oprt, false, _T("+"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, false, _T("-"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, false, _T("*"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, false, _T("/"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, false, _T("^"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, false, _T("&&"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, false, _T("||"),  f1of2)\r
+      // without activated built in operators it should work\r
+      p.EnableBuiltInOprt(false);\r
+      PARSER_THROWCHECK(Oprt, true, _T("+"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, true, _T("-"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, true, _T("*"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, true, _T("/"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, true, _T("^"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, true, _T("&&"),  f1of2)\r
+      PARSER_THROWCHECK(Oprt, true, _T("||"),  f1of2)\r
+  #undef PARSER_THROWCHECK\r
+\r
+      if (iStat==0) \r
+        mu::console() << _T("passed") << endl;\r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestSyntax()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing syntax engine...");\r
+\r
+      iStat += ThrowTest(_T("1,"), ecUNEXPECTED_EOF);  // incomplete hex definition\r
+      iStat += ThrowTest(_T("a,"), ecUNEXPECTED_EOF);  // incomplete hex definition\r
+      iStat += ThrowTest(_T("sin(8),"), ecUNEXPECTED_EOF);  // incomplete hex definition\r
+      iStat += ThrowTest(_T("(sin(8)),"), ecUNEXPECTED_EOF);  // incomplete hex definition\r
+      iStat += ThrowTest(_T("a{m},"), ecUNEXPECTED_EOF);  // incomplete hex definition\r
+\r
+      iStat += EqnTest(_T("(1+ 2*a)"), 3, true);   // Spaces within formula\r
+      iStat += EqnTest(_T("sqrt((4))"), 2, true);  // Multiple brackets\r
+      iStat += EqnTest(_T("sqrt((2)+2)"), 2, true);// Multiple brackets\r
+      iStat += EqnTest(_T("sqrt(2+(2))"), 2, true);// Multiple brackets\r
+      iStat += EqnTest(_T("sqrt(a+(3))"), 2, true);// Multiple brackets\r
+      iStat += EqnTest(_T("sqrt((3)+a)"), 2, true);// Multiple brackets\r
+      iStat += EqnTest(_T("order(1,2)"), 1, true); // May not cause name collision with operator "or"\r
+      iStat += EqnTest(_T("(2+"), 0, false);       // missing closing bracket \r
+      iStat += EqnTest(_T("2++4"), 0, false);      // unexpected operator\r
+      iStat += EqnTest(_T("2+-4"), 0, false);      // unexpected operator\r
+      iStat += EqnTest(_T("(2+)"), 0, false);      // unexpected closing bracket\r
+      iStat += EqnTest(_T("--2"), 0, false);       // double sign\r
+      iStat += EqnTest(_T("ksdfj"), 0, false);     // unknown token\r
+      iStat += EqnTest(_T("()"), 0, false);        // empty bracket without a function\r
+      iStat += EqnTest(_T("5+()"), 0, false);      // empty bracket without a function\r
+      iStat += EqnTest(_T("sin(cos)"), 0, false);  // unexpected function\r
+      iStat += EqnTest(_T("5t6"), 0, false);       // unknown token\r
+      iStat += EqnTest(_T("5 t 6"), 0, false);     // unknown token\r
+      iStat += EqnTest(_T("8*"), 0, false);        // unexpected end of formula\r
+      iStat += EqnTest(_T(",3"), 0, false);        // unexpected comma\r
+      iStat += EqnTest(_T("3,5"), 0, false);       // unexpected comma\r
+      iStat += EqnTest(_T("sin(8,8)"), 0, false);  // too many function args\r
+      iStat += EqnTest(_T("(7,8)"), 0, false);     // too many function args\r
+      iStat += EqnTest(_T("sin)"), 0, false);      // unexpected closing bracket\r
+      iStat += EqnTest(_T("a)"), 0, false);        // unexpected closing bracket\r
+      iStat += EqnTest(_T("pi)"), 0, false);       // unexpected closing bracket\r
+      iStat += EqnTest(_T("sin(())"), 0, false);   // unexpected closing bracket\r
+      iStat += EqnTest(_T("sin()"), 0, false);     // unexpected closing bracket\r
+\r
+      if (iStat==0)\r
+        mu::console() << _T("passed") << endl;\r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestVarConst()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing variable/constant detection...");\r
+\r
+      // Test if the result changes when a variable changes\r
+      iStat += EqnTestWithVarChange( _T("a"), 1, 1, 2, 2 );\r
+      iStat += EqnTestWithVarChange( _T("2*a"), 2, 4, 3, 6 );\r
+\r
+      // distinguish constants with same basename\r
+      iStat += EqnTest( _T("const"), 1, true);\r
+      iStat += EqnTest( _T("const1"), 2, true);\r
+      iStat += EqnTest( _T("const2"), 3, true);\r
+      iStat += EqnTest( _T("2*const"), 2, true);\r
+      iStat += EqnTest( _T("2*const1"), 4, true);\r
+      iStat += EqnTest( _T("2*const2"), 6, true);\r
+      iStat += EqnTest( _T("2*const+1"), 3, true);\r
+      iStat += EqnTest( _T("2*const1+1"), 5, true);\r
+      iStat += EqnTest( _T("2*const2+1"), 7, true);\r
+      iStat += EqnTest( _T("const"), 0, false);\r
+      iStat += EqnTest( _T("const1"), 0, false);\r
+      iStat += EqnTest( _T("const2"), 0, false);\r
+\r
+      // distinguish variables with same basename\r
+      iStat += EqnTest( _T("a"), 1, true);\r
+      iStat += EqnTest( _T("aa"), 2, true);\r
+      iStat += EqnTest( _T("2*a"), 2, true);\r
+      iStat += EqnTest( _T("2*aa"), 4, true);\r
+      iStat += EqnTest( _T("2*a-1"), 1, true);\r
+      iStat += EqnTest( _T("2*aa-1"), 3, true);\r
+\r
+      // custom value recognition\r
+      iStat += EqnTest( _T("0xff"), 255, true);\r
+      iStat += EqnTest( _T("0x97 + 0xff"), 406, true);\r
+\r
+      // Finally test querying of used variables\r
+      try\r
+      {\r
+        int idx;\r
+        mu::Parser p;\r
+        mu::value_type vVarVal[] = { 1, 2, 3, 4, 5};\r
+        p.DefineVar( _T("a"), &vVarVal[0]);\r
+        p.DefineVar( _T("b"), &vVarVal[1]);\r
+        p.DefineVar( _T("c"), &vVarVal[2]);\r
+        p.DefineVar( _T("d"), &vVarVal[3]);\r
+        p.DefineVar( _T("e"), &vVarVal[4]);\r
+\r
+        // Test lookup of defined variables\r
+        // 4 used variables\r
+        p.SetExpr( _T("a+b+c+d") );\r
+        mu::varmap_type UsedVar = p.GetUsedVar();\r
+        int iCount = (int)UsedVar.size();\r
+        if (iCount!=4) \r
+          throw false;\r
+        \r
+        // the next check will fail if the parser \r
+        // erroneousely creates new variables internally\r
+        if (p.GetVar().size()!=5)\r
+          throw false;\r
+\r
+        mu::varmap_type::const_iterator item = UsedVar.begin();\r
+        for (idx=0; item!=UsedVar.end(); ++item)\r
+        {\r
+          if (&vVarVal[idx++]!=item->second) \r
+            throw false;\r
+        }\r
+\r
+        // Test lookup of undefined variables\r
+        p.SetExpr( _T("undef1+undef2+undef3") );\r
+        UsedVar = p.GetUsedVar();\r
+        iCount = (int)UsedVar.size();\r
+        if (iCount!=3) \r
+          throw false;\r
+\r
+        // the next check will fail if the parser \r
+        // erroneousely creates new variables internally\r
+        if (p.GetVar().size()!=5)\r
+          throw false;\r
+\r
+        for (item = UsedVar.begin(); item!=UsedVar.end(); ++item)\r
+        {\r
+          if (item->second!=0) \r
+            throw false; // all pointers to undefined variables must be null\r
+        }\r
+\r
+        // 1 used variables\r
+        p.SetExpr( _T("a+b") );\r
+        UsedVar = p.GetUsedVar();\r
+        iCount = (int)UsedVar.size();\r
+        if (iCount!=2) throw false;\r
+        item = UsedVar.begin();\r
+        for (idx=0; item!=UsedVar.end(); ++item)\r
+          if (&vVarVal[idx++]!=item->second) throw false;\r
+\r
+      }\r
+      catch(...)\r
+      {\r
+        iStat += 1;\r
+      }\r
+\r
+      if (iStat==0)  \r
+        mu::console() << _T("passed") << endl;\r
+      else\r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestMultiArg()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing multiarg functions...");\r
+    \r
+      // Compound expressions\r
+      iStat += EqnTest( _T("1,2,3"), 3, true);\r
+      iStat += EqnTest( _T("a,b,c"), 3, true);\r
+      iStat += EqnTest( _T("a=10,b=20,c=a*b"), 200, true);\r
+      iStat += EqnTest( _T("1,\n2,\n3"), 3, true);\r
+      iStat += EqnTest( _T("a,\nb,\nc"), 3, true);\r
+      iStat += EqnTest( _T("a=10,\nb=20,\nc=a*b"), 200, true);\r
+      iStat += EqnTest( _T("1,\r\n2,\r\n3"), 3, true);\r
+      iStat += EqnTest( _T("a,\r\nb,\r\nc"), 3, true);\r
+      iStat += EqnTest( _T("a=10,\r\nb=20,\r\nc=a*b"), 200, true);\r
+\r
+      // picking the right argument\r
+      iStat += EqnTest( _T("f1of1(1)"), 1, true);\r
+      iStat += EqnTest( _T("f1of2(1, 2)"), 1, true);\r
+      iStat += EqnTest( _T("f2of2(1, 2)"), 2, true);\r
+      iStat += EqnTest( _T("f1of3(1, 2, 3)"), 1, true);\r
+      iStat += EqnTest( _T("f2of3(1, 2, 3)"), 2, true);\r
+      iStat += EqnTest( _T("f3of3(1, 2, 3)"), 3, true);\r
+      iStat += EqnTest( _T("f1of4(1, 2, 3, 4)"), 1, true);\r
+      iStat += EqnTest( _T("f2of4(1, 2, 3, 4)"), 2, true);\r
+      iStat += EqnTest( _T("f3of4(1, 2, 3, 4)"), 3, true);\r
+      iStat += EqnTest( _T("f4of4(1, 2, 3, 4)"), 4, true);\r
+      iStat += EqnTest( _T("f1of5(1, 2, 3, 4, 5)"), 1, true);\r
+      iStat += EqnTest( _T("f2of5(1, 2, 3, 4, 5)"), 2, true);\r
+      iStat += EqnTest( _T("f3of5(1, 2, 3, 4, 5)"), 3, true);\r
+      iStat += EqnTest( _T("f4of5(1, 2, 3, 4, 5)"), 4, true);\r
+      iStat += EqnTest( _T("f5of5(1, 2, 3, 4, 5)"), 5, true);\r
+      // Too few arguments / Too many arguments\r
+      iStat += EqnTest( _T("1+ping()"), 11, true);\r
+      iStat += EqnTest( _T("ping()+1"), 11, true);\r
+      iStat += EqnTest( _T("2*ping()"), 20, true);\r
+      iStat += EqnTest( _T("ping()*2"), 20, true);\r
+      iStat += EqnTest( _T("ping(1,2)"), 0, false);\r
+      iStat += EqnTest( _T("1+ping(1,2)"), 0, false);\r
+      iStat += EqnTest( _T("f1of1(1,2)"), 0, false);\r
+      iStat += EqnTest( _T("f1of1()"), 0, false);\r
+      iStat += EqnTest( _T("f1of2(1, 2, 3)"), 0, false);\r
+      iStat += EqnTest( _T("f1of2(1)"), 0, false);\r
+      iStat += EqnTest( _T("f1of3(1, 2, 3, 4)"), 0, false);\r
+      iStat += EqnTest( _T("f1of3(1)"), 0, false);\r
+      iStat += EqnTest( _T("f1of4(1, 2, 3, 4, 5)"), 0, false);\r
+      iStat += EqnTest( _T("f1of4(1)"), 0, false);\r
+      iStat += EqnTest( _T("(1,2,3)"), 0, false);\r
+      iStat += EqnTest( _T("1,2,3"), 0, false);\r
+      iStat += EqnTest( _T("(1*a,2,3)"), 0, false);\r
+      iStat += EqnTest( _T("1,2*a,3"), 0, false);\r
+     \r
+      // correct calculation of arguments\r
+      iStat += EqnTest( _T("min(a, 1)"),  1, true);\r
+      iStat += EqnTest( _T("min(3*2, 1)"),  1, true);\r
+      iStat += EqnTest( _T("min(3*2, 1)"),  6, false);\r
+      iStat += EqnTest( _T("firstArg(2,3,4)"), 2, true);\r
+      iStat += EqnTest( _T("lastArg(2,3,4)"), 4, true);\r
+      iStat += EqnTest( _T("min(3*a+1, 1)"),  1, true);\r
+      iStat += EqnTest( _T("max(3*a+1, 1)"),  4, true);\r
+      iStat += EqnTest( _T("max(3*a+1, 1)*2"),  8, true);\r
+      iStat += EqnTest( _T("2*max(3*a+1, 1)+2"),  10, true);\r
+\r
+      // functions with Variable argument count\r
+      iStat += EqnTest( _T("sum(a)"), 1, true);\r
+      iStat += EqnTest( _T("sum(1,2,3)"),  6, true);\r
+      iStat += EqnTest( _T("sum(a,b,c)"),  6, true);\r
+      iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"),  4, true);\r
+      iStat += EqnTest( _T("2*sum(1,2,3)"),  12, true);\r
+      iStat += EqnTest( _T("2*sum(1,2,3)+2"),  14, true);\r
+      iStat += EqnTest( _T("2*sum(-1,2,3)+2"),  10, true);\r
+      iStat += EqnTest( _T("2*sum(-1,2,-(-a))+2"),  6, true);\r
+      iStat += EqnTest( _T("2*sum(-1,10,-a)+2"),  18, true);\r
+      iStat += EqnTest( _T("2*sum(1,2,3)*2"),  24, true);\r
+      iStat += EqnTest( _T("sum(1,-max(1,2),3)*2"),  4, true);\r
+      iStat += EqnTest( _T("sum(1*3, 4, a+2)"),  10, true);\r
+      iStat += EqnTest( _T("sum(1*3, 2*sum(1,2,2), a+2)"),  16, true);\r
+      iStat += EqnTest( _T("sum(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2)"), 24, true);\r
+\r
+      // some failures\r
+      iStat += EqnTest( _T("sum()"),  0, false);\r
+      iStat += EqnTest( _T("sum(,)"),  0, false);\r
+      iStat += EqnTest( _T("sum(1,2,)"),  0, false);\r
+      iStat += EqnTest( _T("sum(,1,2)"),  0, false);\r
+\r
+      if (iStat==0) \r
+        mu::console() << _T("passed") << endl;\r
+      else\r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+  \r
+      return iStat;\r
+    }\r
+\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestInfixOprt()\r
+    {\r
+      int iStat(0);\r
+      mu::console() << "testing infix operators...";\r
+\r
+      iStat += EqnTest( _T("-1"),    -1, true);\r
+      iStat += EqnTest( _T("-(-1)"),  1, true);\r
+      iStat += EqnTest( _T("-(-1)*2"),  2, true);\r
+      iStat += EqnTest( _T("-(-2)*sqrt(4)"),  4, true);\r
+      iStat += EqnTest( _T("-_pi"), -PARSER_CONST_PI, true);\r
+      iStat += EqnTest( _T("-a"),  -1, true);\r
+      iStat += EqnTest( _T("-(a)"),  -1, true);\r
+      iStat += EqnTest( _T("-(-a)"),  1, true);\r
+      iStat += EqnTest( _T("-(-a)*2"),  2, true);\r
+      iStat += EqnTest( _T("-(8)"), -8, true);\r
+      iStat += EqnTest( _T("-8"), -8, true);\r
+      iStat += EqnTest( _T("-(2+1)"), -3, true);\r
+      iStat += EqnTest( _T("-(f1of1(1+2*3)+1*2)"), -9, true);\r
+      iStat += EqnTest( _T("-(-f1of1(1+2*3)+1*2)"), 5, true);\r
+      iStat += EqnTest( _T("-sin(8)"), -0.989358, true);\r
+      iStat += EqnTest( _T("3-(-a)"), 4, true);\r
+      iStat += EqnTest( _T("3--a"), 4, true);\r
+      iStat += EqnTest( _T("-1*3"),  -3, true);\r
+\r
+      // Postfix / infix priorities\r
+      iStat += EqnTest( _T("~2#"), 8, true);\r
+      iStat += EqnTest( _T("~f1of1(2)#"), 8, true);\r
+      iStat += EqnTest( _T("~(b)#"), 8, true);\r
+      iStat += EqnTest( _T("(~b)#"), 12, true);\r
+      iStat += EqnTest( _T("~(2#)"), 8, true);\r
+      iStat += EqnTest( _T("~(f1of1(2)#)"), 8, true);\r
+      //\r
+      iStat += EqnTest( _T("-2^2"),-4, true);\r
+      iStat += EqnTest( _T("-(a+b)^2"),-9, true);\r
+      iStat += EqnTest( _T("(-3)^2"),9, true);\r
+      iStat += EqnTest( _T("-(-2^2)"),4, true);\r
+      iStat += EqnTest( _T("3+-3^2"),-6, true);\r
+      // The following assumes use of sqr as postfix operator ("§") together\r
+      // with a sign operator of low priority:\r
+      iStat += EqnTest( _T("-2'"), -4, true);\r
+      iStat += EqnTest( _T("-(1+1)'"),-4, true);\r
+      iStat += EqnTest( _T("2+-(1+1)'"),-2, true);\r
+      iStat += EqnTest( _T("2+-2'"), -2, true);\r
+      // This is the classic behaviour of the infix sign operator (here: "$") which is\r
+      // now deprecated:\r
+      iStat += EqnTest( _T("$2^2"),4, true);\r
+      iStat += EqnTest( _T("$(a+b)^2"),9, true);\r
+      iStat += EqnTest( _T("($3)^2"),9, true);\r
+      iStat += EqnTest( _T("$($2^2)"),-4, true);\r
+      iStat += EqnTest( _T("3+$3^2"),12, true);\r
+\r
+      // infix operators sharing the first few characters\r
+      iStat += EqnTest( _T("~ 123"),  123+2, true);\r
+      iStat += EqnTest( _T("~~ 123"),  123+2, true);\r
+\r
+      if (iStat==0)\r
+        mu::console() << _T("passed") << endl;\r
+      else\r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestPostFix()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing postfix operators...");\r
+\r
+      // application\r
+      iStat += EqnTest( _T("3{m}+5"), 5.003, true);\r
+      iStat += EqnTest( _T("1000{m}"), 1, true);\r
+      iStat += EqnTest( _T("1000 {m}"), 1, true);\r
+      iStat += EqnTest( _T("(a){m}"), 1e-3, true);\r
+      iStat += EqnTest( _T("a{m}"), 1e-3, true);\r
+      iStat += EqnTest( _T("a {m}"), 1e-3, true);\r
+      iStat += EqnTest( _T("-(a){m}"), -1e-3, true);\r
+      iStat += EqnTest( _T("-2{m}"), -2e-3, true);\r
+      iStat += EqnTest( _T("-2 {m}"), -2e-3, true);\r
+      iStat += EqnTest( _T("f1of1(1000){m}"), 1, true);\r
+      iStat += EqnTest( _T("-f1of1(1000){m}"), -1, true);\r
+      iStat += EqnTest( _T("-f1of1(-1000){m}"), 1, true);\r
+      iStat += EqnTest( _T("f4of4(0,0,0,1000){m}"), 1, true);\r
+      iStat += EqnTest( _T("2+(a*1000){m}"), 3, true);\r
+\r
+      // can postfix operators "m" und "meg" be told apart properly?\r
+      iStat += EqnTest( _T("2*3000meg+2"), 2*3e9+2, true);   \r
+\r
+      // some incorrect results\r
+      iStat += EqnTest( _T("1000{m}"), 0.1, false);\r
+      iStat += EqnTest( _T("(a){m}"), 2, false);\r
+      // failure due to syntax checking\r
+      iStat += ThrowTest(_T("0x"), ecUNASSIGNABLE_TOKEN);  // incomplete hex definition\r
+      iStat += ThrowTest(_T("3+"), ecUNEXPECTED_EOF);\r
+      iStat += ThrowTest( _T("4 + {m}"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("{m}4"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("sin({m})"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("{m} {m}"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("{m}(8)"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("4,{m}"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("-{m}"), ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest( _T("2(-{m})"), ecUNEXPECTED_PARENS);\r
+      iStat += ThrowTest( _T("2({m})"), ecUNEXPECTED_PARENS);\r
\r
+      iStat += ThrowTest( _T("multi*1.0"), ecUNASSIGNABLE_TOKEN);\r
+\r
+      if (iStat==0)\r
+        mu::console() << _T("passed") << endl;\r
+      else\r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestExpression()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing expression samples...");\r
+\r
+      value_type b = 2;\r
+\r
+      // Optimization\r
+      iStat += EqnTest( _T("2*b*5"), 20, true);\r
+      iStat += EqnTest( _T("2*b*5 + 4*b"), 28, true);\r
+      iStat += EqnTest( _T("2*a/3"), 2.0/3.0, true);\r
+\r
+      // Addition auf cmVARMUL \r
+      iStat += EqnTest( _T("3+b"), b+3, true);\r
+      iStat += EqnTest( _T("b+3"), b+3, true);\r
+      iStat += EqnTest( _T("b*3+2"), b*3+2, true);\r
+      iStat += EqnTest( _T("3*b+2"), b*3+2, true);\r
+      iStat += EqnTest( _T("2+b*3"), b*3+2, true);\r
+      iStat += EqnTest( _T("2+3*b"), b*3+2, true);\r
+      iStat += EqnTest( _T("b+3*b"), b+3*b, true);\r
+      iStat += EqnTest( _T("3*b+b"), b+3*b, true);\r
+\r
+      iStat += EqnTest( _T("2+b*3+b"), 2+b*3+b, true);\r
+      iStat += EqnTest( _T("b+2+b*3"), b+2+b*3, true);\r
+\r
+      iStat += EqnTest( _T("(2*b+1)*4"), (2*b+1)*4, true);\r
+      iStat += EqnTest( _T("4*(2*b+1)"), (2*b+1)*4, true);\r
+\r
+      // operator precedencs\r
+      iStat += EqnTest( _T("1+2-3*4/5^6"), 2.99923, true);\r
+      iStat += EqnTest( _T("1^2/3*4-5+6"), 2.33333333, true);\r
+      iStat += EqnTest( _T("1+2*3"), 7, true);\r
+      iStat += EqnTest( _T("1+2*3"), 7, true);\r
+      iStat += EqnTest( _T("(1+2)*3"), 9, true);\r
+      iStat += EqnTest( _T("(1+2)*(-3)"), -9, true);\r
+      iStat += EqnTest( _T("2/4"), 0.5, true);\r
+\r
+      iStat += EqnTest( _T("exp(ln(7))"), 7, true);\r
+      iStat += EqnTest( _T("e^ln(7)"), 7, true);\r
+      iStat += EqnTest( _T("e^(ln(7))"), 7, true);\r
+      iStat += EqnTest( _T("(e^(ln(7)))"), 7, true);\r
+      iStat += EqnTest( _T("1-(e^(ln(7)))"), -6, true);\r
+      iStat += EqnTest( _T("2*(e^(ln(7)))"), 14, true);\r
+      iStat += EqnTest( _T("10^log(5)"), 5, true);\r
+      iStat += EqnTest( _T("10^log10(5)"), 5, true);\r
+      iStat += EqnTest( _T("2^log2(4)"), 4, true);\r
+      iStat += EqnTest( _T("-(sin(0)+1)"), -1, true);\r
+      iStat += EqnTest( _T("-(2^1.1)"), -2.14354692, true);\r
+\r
+      iStat += EqnTest( _T("(cos(2.41)/b)"), -0.372056, true);\r
+      iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(a+b)))))))"), 2160, true);\r
+      iStat += EqnTest( _T("(1*(2*(3*(4*(5*(6*(7*(a+b))))))))"), 15120, true);\r
+      iStat += EqnTest( _T("(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))"), 0.00377999, true);\r
+\r
+      // long formula (Reference: Matlab)\r
+      iStat += EqnTest(\r
+        _T("(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))")\r
+        _T("/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/")\r
+        _T("((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-")\r
+        _T("e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6")\r
+        _T("+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e")\r
+        _T("*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)"), -12.23016549, true);\r
+\r
+      // long formula (Reference: Matlab)\r
+      iStat += EqnTest(\r
+          _T("(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e")\r
+          _T(")+a)))*2.77)"), -2.16995656, true);\r
+\r
+      // long formula (Reference: Matlab)\r
+      iStat += EqnTest( _T("1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12"), -7995810.09926, true);\r
+         \r
+      if (iStat==0) \r
+        mu::console() << _T("passed") << endl;  \r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestIfThenElse()\r
+    {\r
+      int iStat = 0;\r
+      mu::console() << _T("testing if-then-else operator...");\r
+\r
+      // Test error detection\r
+      iStat += ThrowTest(_T(":3"), ecUNEXPECTED_CONDITIONAL); \r
+      iStat += ThrowTest(_T("? 1 : 2"), ecUNEXPECTED_CONDITIONAL); \r
+      iStat += ThrowTest(_T("(a<b) ? (b<c) ? 1 : 2"), ecMISSING_ELSE_CLAUSE); \r
+      iStat += ThrowTest(_T("(a<b) ? 1"), ecMISSING_ELSE_CLAUSE); \r
+      iStat += ThrowTest(_T("(a<b) ? a"), ecMISSING_ELSE_CLAUSE); \r
+      iStat += ThrowTest(_T("(a<b) ? a+b"), ecMISSING_ELSE_CLAUSE); \r
+      iStat += ThrowTest(_T("a : b"), ecMISPLACED_COLON); \r
+      iStat += ThrowTest(_T("1 : 2"), ecMISPLACED_COLON); \r
+      iStat += ThrowTest(_T("(1) ? 1 : 2 : 3"), ecMISPLACED_COLON); \r
+      iStat += ThrowTest(_T("(true) ? 1 : 2 : 3"), ecUNASSIGNABLE_TOKEN); \r
+\r
+      iStat += EqnTest(_T("1 ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("1<2 ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("a<b ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("(a<b) ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("(1) ? 10 : 11"), 10, true);\r
+      iStat += EqnTest(_T("(0) ? 10 : 11"), 11, true);\r
+      iStat += EqnTest(_T("(1) ? a+b : c+d"), 3, true);\r
+      iStat += EqnTest(_T("(0) ? a+b : c+d"), 1, true);\r
+      iStat += EqnTest(_T("(1) ? 0 : 1"), 0, true);\r
+      iStat += EqnTest(_T("(0) ? 0 : 1"), 1, true);\r
+      iStat += EqnTest(_T("(a<b) ? 10 : 11"), 10, true);\r
+      iStat += EqnTest(_T("(a>b) ? 10 : 11"), 11, true);\r
+      iStat += EqnTest(_T("(a<b) ? c : d"), 3, true);\r
+      iStat += EqnTest(_T("(a>b) ? c : d"), -2, true);\r
+\r
+      iStat += EqnTest(_T("(a>b) ? 1 : 0"), 0, true);\r
+      iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : 2"), 2, true);\r
+      iStat += EqnTest(_T("((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)"), 2, true);\r
+      iStat += EqnTest(_T("((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)"), 1, true);\r
+\r
+      iStat += EqnTest(_T("sum((a>b) ? 1 : 2)"), 2, true);\r
+      iStat += EqnTest(_T("sum((1) ? 1 : 2)"), 1, true);\r
+      iStat += EqnTest(_T("sum((a>b) ? 1 : 2, 100)"), 102, true);\r
+      iStat += EqnTest(_T("sum((1) ? 1 : 2, 100)"), 101, true);\r
+      iStat += EqnTest(_T("sum(3, (a>b) ? 3 : 10)"), 13, true);\r
+      iStat += EqnTest(_T("sum(3, (a<b) ? 3 : 10)"), 6, true);\r
+      iStat += EqnTest(_T("10*sum(3, (a>b) ? 3 : 10)"), 130, true);\r
+      iStat += EqnTest(_T("10*sum(3, (a<b) ? 3 : 10)"), 60, true);\r
+      iStat += EqnTest(_T("sum(3, (a>b) ? 3 : 10)*10"), 130, true);\r
+      iStat += EqnTest(_T("sum(3, (a<b) ? 3 : 10)*10"), 60, true);\r
+      iStat += EqnTest(_T("(a<b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 60, true);\r
+      iStat += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10)*10 : 99"), 99, true);\r
+      iStat += EqnTest(_T("(a<b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 360, true);\r
+      iStat += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : 99"), 99, true);\r
+      iStat += EqnTest(_T("(a>b) ? sum(3, (a<b) ? 3 : 10,10,20)*10 : sum(3, (a<b) ? 3 : 10)*10"), 60, true);\r
+\r
+      // todo: auch für muParserX hinzufügen!\r
+      iStat += EqnTest(_T("(a<b)&&(a<b) ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("(a>b)&&(a<b) ? 128 : 255"), 255, true);\r
+      iStat += EqnTest(_T("(1<2)&&(1<2) ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("(1>2)&&(1<2) ? 128 : 255"), 255, true);\r
+      iStat += EqnTest(_T("((1<2)&&(1<2)) ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("((1>2)&&(1<2)) ? 128 : 255"), 255, true);\r
+      iStat += EqnTest(_T("((a<b)&&(a<b)) ? 128 : 255"), 128, true);\r
+      iStat += EqnTest(_T("((a>b)&&(a<b)) ? 128 : 255"), 255, true);\r
+\r
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 255, true);\r
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)"), 255, true);\r
+      iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 128, true);\r
+      iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)"), 128, true);\r
+      iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64"), 32, true);\r
+      iStat += EqnTest(_T("1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64"), 64, true);\r
+      iStat += EqnTest(_T("1>0 ? 50 :  1>0 ? 128 : 255"), 50, true);\r
+      iStat += EqnTest(_T("1>0 ? 50 : (1>0 ? 128 : 255)"), 50, true);\r
+      iStat += EqnTest(_T("1>0 ? 1>0 ? 128 : 255 : 50"), 128, true);\r
+      iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16"), 32, true);\r
+      iStat += EqnTest(_T("1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)"), 32, true);\r
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 :  1>0 ? 32 :1>2 ? 64 : 16"), 255, true);\r
+      iStat += EqnTest(_T("1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)"), 255, true);\r
+      iStat += EqnTest(_T("1 ? 0 ? 128 : 255 : 1 ? 32 : 64"), 255, true);\r
+\r
+      // assignment operators\r
+      iStat += EqnTest(_T("a= 0 ? 128 : 255, a"), 255, true);\r
+      iStat += EqnTest(_T("a=((a>b)&&(a<b)) ? 128 : 255, a"), 255, true);\r
+      iStat += EqnTest(_T("c=(a<b)&&(a<b) ? 128 : 255, c"), 128, true);\r
+      iStat += EqnTest(_T("0 ? a=a+1 : 666, a"), 1, true);\r
+      iStat += EqnTest(_T("1?a=10:a=20, a"), 10, true);\r
+      iStat += EqnTest(_T("0?a=10:a=20, a"), 20, true);\r
+      iStat += EqnTest(_T("0?a=sum(3,4):10, a"), 1, true);  // a should not change its value due to lazy calculation\r
+      \r
+      iStat += EqnTest(_T("a=1?b=1?3:4:5, a"), 3, true);\r
+      iStat += EqnTest(_T("a=1?b=1?3:4:5, b"), 3, true);\r
+      iStat += EqnTest(_T("a=0?b=1?3:4:5, a"), 5, true);\r
+      iStat += EqnTest(_T("a=0?b=1?3:4:5, b"), 2, true);\r
+\r
+      iStat += EqnTest(_T("a=1?5:b=1?3:4, a"), 5, true);\r
+      iStat += EqnTest(_T("a=1?5:b=1?3:4, b"), 2, true);\r
+      iStat += EqnTest(_T("a=0?5:b=1?3:4, a"), 3, true);\r
+      iStat += EqnTest(_T("a=0?5:b=1?3:4, b"), 3, true);\r
+\r
+      if (iStat==0) \r
+        mu::console() << _T("passed") << endl;  \r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::TestException()\r
+    {\r
+      int  iStat = 0;\r
+      mu::console() << _T("testing error codes...");\r
+\r
+      iStat += ThrowTest(_T("3+"),           ecUNEXPECTED_EOF);\r
+      iStat += ThrowTest(_T("3+)"),          ecUNEXPECTED_PARENS);\r
+      iStat += ThrowTest(_T("()"),           ecUNEXPECTED_PARENS);\r
+      iStat += ThrowTest(_T("3+()"),         ecUNEXPECTED_PARENS);\r
+      iStat += ThrowTest(_T("sin(3,4)"),     ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest(_T("sin()"),        ecTOO_FEW_PARAMS);\r
+      iStat += ThrowTest(_T("(1+2"),         ecMISSING_PARENS);\r
+      iStat += ThrowTest(_T("sin(3)3"),      ecUNEXPECTED_VAL);\r
+      iStat += ThrowTest(_T("sin(3)xyz"),    ecUNASSIGNABLE_TOKEN);\r
+      iStat += ThrowTest(_T("sin(3)cos(3)"), ecUNEXPECTED_FUN);\r
+      iStat += ThrowTest(_T("a+b+c=10"),     ecUNEXPECTED_OPERATOR);\r
+      iStat += ThrowTest(_T("a=b=3"),        ecUNEXPECTED_OPERATOR);\r
+\r
+#if defined(MUP_MATH_EXCEPTIONS)\r
+      // divide by zero whilst constant folding\r
+      iStat += ThrowTest(_T("1/0"),          ecDIV_BY_ZERO);\r
+      // square root of a negative number\r
+      iStat += ThrowTest(_T("sqrt(-1)"),     ecDOMAIN_ERROR);\r
+      // logarithms of zero\r
+      iStat += ThrowTest(_T("ln(0)"),        ecDOMAIN_ERROR);\r
+      iStat += ThrowTest(_T("log2(0)"),      ecDOMAIN_ERROR);\r
+      iStat += ThrowTest(_T("log10(0)"),     ecDOMAIN_ERROR);\r
+      iStat += ThrowTest(_T("log(0)"),       ecDOMAIN_ERROR);\r
+      // logarithms of negative values\r
+      iStat += ThrowTest(_T("ln(-1)"),       ecDOMAIN_ERROR);\r
+      iStat += ThrowTest(_T("log2(-1)"),     ecDOMAIN_ERROR);\r
+      iStat += ThrowTest(_T("log10(-1)"),    ecDOMAIN_ERROR);\r
+      iStat += ThrowTest(_T("log(-1)"),      ecDOMAIN_ERROR);\r
+#endif\r
+\r
+      // functions without parameter\r
+      iStat += ThrowTest( _T("3+ping(2)"),    ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("3+ping(a+2)"),  ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("3+ping(sin(a)+2)"),  ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("3+ping(1+sin(a))"),  ecTOO_MANY_PARAMS);\r
+\r
+      // String function related\r
+      iStat += ThrowTest( _T("valueof(\"xxx\")"),  999, false);\r
+      iStat += ThrowTest( _T("valueof()"),          ecUNEXPECTED_PARENS);\r
+      iStat += ThrowTest( _T("1+valueof(\"abc\""),  ecMISSING_PARENS);\r
+      iStat += ThrowTest( _T("valueof(\"abc\""),    ecMISSING_PARENS);\r
+      iStat += ThrowTest( _T("valueof(\"abc"),      ecUNTERMINATED_STRING);\r
+      iStat += ThrowTest( _T("valueof(\"abc\",3)"), ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("valueof(3)"),         ecSTRING_EXPECTED);\r
+      iStat += ThrowTest( _T("sin(\"abc\")"),       ecVAL_EXPECTED);\r
+      iStat += ThrowTest( _T("valueof(\"\\\"abc\\\"\")"),  999, false);\r
+      iStat += ThrowTest( _T("\"hello world\""),    ecSTR_RESULT);\r
+      iStat += ThrowTest( _T("(\"hello world\")"),  ecSTR_RESULT);\r
+      iStat += ThrowTest( _T("\"abcd\"+100"),       ecOPRT_TYPE_CONFLICT);\r
+      iStat += ThrowTest( _T("\"a\"+\"b\""),        ecOPRT_TYPE_CONFLICT);\r
+      iStat += ThrowTest( _T("strfun1(\"100\",3)"),     ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("strfun2(\"100\",3,5)"),   ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("strfun3(\"100\",3,5,6)"), ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("strfun2(\"100\")"),       ecTOO_FEW_PARAMS);\r
+      iStat += ThrowTest( _T("strfun3(\"100\",6)"),   ecTOO_FEW_PARAMS);\r
+      iStat += ThrowTest( _T("strfun2(1,1)"),         ecSTRING_EXPECTED);\r
+      iStat += ThrowTest( _T("strfun2(a,1)"),         ecSTRING_EXPECTED);\r
+      iStat += ThrowTest( _T("strfun2(1,1,1)"),       ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("strfun2(a,1,1)"),       ecTOO_MANY_PARAMS);\r
+      iStat += ThrowTest( _T("strfun3(1,2,3)"),         ecSTRING_EXPECTED);\r
+      iStat += ThrowTest( _T("strfun3(1, \"100\",3)"),  ecSTRING_EXPECTED);\r
+      iStat += ThrowTest( _T("strfun3(\"1\", \"100\",3)"),  ecVAL_EXPECTED);\r
+      iStat += ThrowTest( _T("strfun3(\"1\", 3, \"100\")"),  ecVAL_EXPECTED);\r
+      iStat += ThrowTest( _T("strfun3(\"1\", \"100\", \"100\", \"100\")"),  ecTOO_MANY_PARAMS);\r
+\r
+      // assignement operator\r
+      iStat += ThrowTest( _T("3=4"), ecUNEXPECTED_OPERATOR);\r
+      iStat += ThrowTest( _T("sin(8)=4"), ecUNEXPECTED_OPERATOR);\r
+      iStat += ThrowTest( _T("\"test\"=a"), ecUNEXPECTED_OPERATOR);\r
+\r
+      // <ibg 20090529>\r
+      // this is now legal, for reference see:\r
+      // https://sourceforge.net/forum/message.php?msg_id=7411373\r
+      //      iStat += ThrowTest( _T("sin=9"), ecUNEXPECTED_OPERATOR);    \r
+      // </ibg>\r
+\r
+      iStat += ThrowTest( _T("(8)=5"), ecUNEXPECTED_OPERATOR);\r
+      iStat += ThrowTest( _T("(a)=5"), ecUNEXPECTED_OPERATOR);\r
+      iStat += ThrowTest( _T("a=\"tttt\""), ecOPRT_TYPE_CONFLICT);\r
+\r
+      if (iStat==0) \r
+        mu::console() << _T("passed") << endl;\r
+      else \r
+        mu::console() << _T("\n  failed with ") << iStat << _T(" errors") << endl;\r
+\r
+      return iStat;\r
+    }\r
+\r
+\r
+    //---------------------------------------------------------------------------\r
+    void ParserTester::AddTest(testfun_type a_pFun)\r
+    {\r
+      m_vTestFun.push_back(a_pFun);\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    void ParserTester::Run()\r
+    {\r
+      int iStat = 0;\r
+      try\r
+      {\r
+        for (int i=0; i<(int)m_vTestFun.size(); ++i)\r
+          iStat += (this->*m_vTestFun[i])();\r
+      }\r
+      catch(Parser::exception_type &e)\r
+      {\r
+        mu::console() << "\n" << e.GetMsg() << endl;\r
+        mu::console() << e.GetToken() << endl;\r
+        Abort();\r
+      }\r
+      catch(std::exception &e)\r
+      {\r
+        mu::console() << e.what() << endl;\r
+        Abort();\r
+      }\r
+      catch(...)\r
+      {\r
+        mu::console() << "Internal error";\r
+        Abort();\r
+      }\r
+\r
+      if (iStat==0) \r
+      {\r
+        mu::console() << "Test passed (" <<  ParserTester::c_iCount << " expressions)" << endl;\r
+      }\r
+      else \r
+      {\r
+        mu::console() << "Test failed with " << iStat \r
+                  << " errors (" <<  ParserTester::c_iCount \r
+                  << " expressions)" << endl;\r
+      }\r
+      ParserTester::c_iCount = 0;\r
+    }\r
+\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::ThrowTest(const string_type &a_str, int a_iErrc, bool a_bFail)\r
+    {\r
+      ParserTester::c_iCount++;\r
+\r
+      try\r
+      {\r
+        value_type fVal[] = {1,1,1};\r
+        Parser p;\r
+\r
+        p.DefineVar( _T("a"), &fVal[0]);\r
+        p.DefineVar( _T("b"), &fVal[1]);\r
+        p.DefineVar( _T("c"), &fVal[2]);\r
+        p.DefinePostfixOprt( _T("{m}"), Milli);\r
+        p.DefinePostfixOprt( _T("m"), Milli);\r
+        p.DefineFun( _T("ping"), Ping);\r
+        p.DefineFun( _T("valueof"), ValueOf);\r
+        p.DefineFun( _T("strfun1"), StrFun1);\r
+        p.DefineFun( _T("strfun2"), StrFun2);\r
+        p.DefineFun( _T("strfun3"), StrFun3);\r
+        p.SetExpr(a_str);\r
+        p.Eval();\r
+      }\r
+      catch(ParserError &e)\r
+      {\r
+        // output the formula in case of an failed test\r
+        if (a_bFail==false || (a_bFail==true && a_iErrc!=e.GetCode()) )\r
+        {\r
+          mu::console() << _T("\n  ") \r
+                        << _T("Expression: ") << a_str \r
+                        << _T("  Code:") << e.GetCode() << _T("(") << e.GetMsg() << _T(")")\r
+                        << _T("  Expected:") << a_iErrc;\r
+        }\r
+\r
+        return (a_iErrc==e.GetCode()) ? 0 : 1;\r
+      }\r
+\r
+      // if a_bFail==false no exception is expected\r
+      bool bRet((a_bFail==false) ? 0 : 1);\r
+      if (bRet==1)\r
+      {\r
+        mu::console() << _T("\n  ") \r
+                      << _T("Expression: ") << a_str \r
+                      << _T("  did evaluate; Expected error:") << a_iErrc;\r
+      }\r
+\r
+      return bRet; \r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    /** \brief Evaluate a tet expression. \r
+\r
+        \return 1 in case of a failure, 0 otherwise.\r
+    */\r
+    int ParserTester::EqnTestWithVarChange(const string_type &a_str, \r
+                                           double a_fVar1, \r
+                                           double a_fRes1, \r
+                                           double a_fVar2, \r
+                                           double a_fRes2)\r
+    {\r
+      ParserTester::c_iCount++;\r
+      value_type fVal[2] = {-999, -999 }; // should be equalinitially\r
+\r
+      try\r
+      {\r
+        Parser  p;\r
+\r
+        // variable\r
+        value_type var = 0;\r
+        p.DefineVar( _T("a"), &var);\r
+        p.SetExpr(a_str);\r
+\r
+        var = a_fVar1;\r
+        fVal[0] = p.Eval();\r
+\r
+        var = a_fVar2;\r
+        fVal[1] = p.Eval();\r
+        \r
+        if ( fabs(a_fRes1-fVal[0]) > 0.0000000001)\r
+          throw std::runtime_error("incorrect result (first pass)");\r
+\r
+        if ( fabs(a_fRes2-fVal[1]) > 0.0000000001)\r
+          throw std::runtime_error("incorrect result (second pass)");\r
+      }\r
+      catch(Parser::exception_type &e)\r
+      {\r
+        mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")");\r
+        return 1;\r
+      }\r
+      catch(std::exception &e)\r
+      {\r
+        mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")");\r
+        return 1;  // always return a failure since this exception is not expected\r
+      }\r
+      catch(...)\r
+      {\r
+        mu::console() << _T("\n  fail: ") << a_str.c_str() <<  _T(" (unexpected exception)");\r
+        return 1;  // exceptions other than ParserException are not allowed\r
+      }\r
+\r
+      return 0;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    /** \brief Evaluate a tet expression. \r
+\r
+        \return 1 in case of a failure, 0 otherwise.\r
+    */\r
+    int ParserTester::EqnTest(const string_type &a_str, double a_fRes, bool a_fPass)\r
+    {\r
+      ParserTester::c_iCount++;\r
+      int iRet(0);\r
+      value_type fVal[5] = {-999, -998, -997, -996, -995}; // initially should be different\r
+\r
+      try\r
+      {\r
+        std::auto_ptr<Parser> p1;\r
+        Parser  p2, p3;   // three parser objects\r
+                          // they will be used for testing copy and assihnment operators\r
+        // p1 is a pointer since i'm going to delete it in order to test if\r
+        // parsers after copy construction still refer to members of it.\r
+        // !! If this is the case this function will crash !!\r
+      \r
+        p1.reset(new mu::Parser()); \r
+        // Add constants\r
+        p1->DefineConst( _T("pi"), (value_type)PARSER_CONST_PI);\r
+        p1->DefineConst( _T("e"), (value_type)PARSER_CONST_E);\r
+        p1->DefineConst( _T("const"), 1);\r
+        p1->DefineConst( _T("const1"), 2);\r
+        p1->DefineConst( _T("const2"), 3);\r
+        // variables\r
+        value_type vVarVal[] = { 1, 2, 3, -2};\r
+        p1->DefineVar( _T("a"), &vVarVal[0]);\r
+        p1->DefineVar( _T("aa"), &vVarVal[1]);\r
+        p1->DefineVar( _T("b"), &vVarVal[1]);\r
+        p1->DefineVar( _T("c"), &vVarVal[2]);\r
+        p1->DefineVar( _T("d"), &vVarVal[3]);\r
+        \r
+        // custom value ident functions\r
+        p1->AddValIdent(&ParserTester::IsHexVal);        \r
+\r
+        // functions\r
+        p1->DefineFun( _T("ping"), Ping);\r
+        p1->DefineFun( _T("f1of1"), f1of1);  // one parameter\r
+        p1->DefineFun( _T("f1of2"), f1of2);  // two parameter\r
+        p1->DefineFun( _T("f2of2"), f2of2);\r
+        p1->DefineFun( _T("f1of3"), f1of3);  // three parameter\r
+        p1->DefineFun( _T("f2of3"), f2of3);\r
+        p1->DefineFun( _T("f3of3"), f3of3);\r
+        p1->DefineFun( _T("f1of4"), f1of4);  // four parameter\r
+        p1->DefineFun( _T("f2of4"), f2of4);\r
+        p1->DefineFun( _T("f3of4"), f3of4);\r
+        p1->DefineFun( _T("f4of4"), f4of4);\r
+        p1->DefineFun( _T("f1of5"), f1of5);  // five parameter\r
+        p1->DefineFun( _T("f2of5"), f2of5);\r
+        p1->DefineFun( _T("f3of5"), f3of5);\r
+        p1->DefineFun( _T("f4of5"), f4of5);\r
+        p1->DefineFun( _T("f5of5"), f5of5);\r
+\r
+        // binary operators\r
+        p1->DefineOprt( _T("add"), add, 0);\r
+        p1->DefineOprt( _T("++"), add, 0);\r
+        p1->DefineOprt( _T("&"), land, prLAND);\r
+\r
+        // sample functions\r
+        p1->DefineFun( _T("min"), Min);\r
+        p1->DefineFun( _T("max"), Max);\r
+        p1->DefineFun( _T("sum"), Sum);\r
+        p1->DefineFun( _T("valueof"), ValueOf);\r
+        p1->DefineFun( _T("atof"), StrToFloat);\r
+        p1->DefineFun( _T("strfun1"), StrFun1);\r
+        p1->DefineFun( _T("strfun2"), StrFun2);\r
+        p1->DefineFun( _T("strfun3"), StrFun3);\r
+        p1->DefineFun( _T("lastArg"), LastArg);\r
+        p1->DefineFun( _T("firstArg"), FirstArg);\r
+        p1->DefineFun( _T("order"), FirstArg);\r
+\r
+        // infix / postfix operator\r
+        // Note: Identifiers used here do not have any meaning \r
+        //       they are mere placeholders to test certain features.\r
+        p1->DefineInfixOprt( _T("$"), sign, prPOW+1);  // sign with high priority\r
+        p1->DefineInfixOprt( _T("~"), plus2);          // high priority\r
+        p1->DefineInfixOprt( _T("~~"), plus2);\r
+        p1->DefinePostfixOprt( _T("{m}"), Milli);\r
+        p1->DefinePostfixOprt( _T("{M}"), Mega);\r
+        p1->DefinePostfixOprt( _T("m"), Milli);\r
+        p1->DefinePostfixOprt( _T("meg"), Mega);\r
+        p1->DefinePostfixOprt( _T("#"), times3);\r
+        p1->DefinePostfixOprt( _T("'"), sqr); \r
+        p1->SetExpr(a_str);\r
+\r
+        // Test bytecode integrity\r
+        // String parsing and bytecode parsing must yield the same result\r
+        fVal[0] = p1->Eval(); // result from stringparsing\r
+        fVal[1] = p1->Eval(); // result from bytecode\r
+        if (fVal[0]!=fVal[1])\r
+          throw Parser::exception_type( _T("Bytecode / string parsing mismatch.") );\r
+\r
+        // Test copy and assignement operators\r
+        try\r
+        {\r
+          // Test copy constructor\r
+          std::vector<mu::Parser> vParser;\r
+          vParser.push_back(*(p1.get()));\r
+          mu::Parser p2 = vParser[0];   // take parser from vector\r
+        \r
+          // destroy the originals from p2\r
+          vParser.clear();              // delete the vector\r
+          p1.reset(0);\r
+\r
+          fVal[2] = p2.Eval();\r
+\r
+          // Test assignement operator\r
+          // additionally  disable Optimizer this time\r
+          mu::Parser p3;\r
+          p3 = p2;\r
+          p3.EnableOptimizer(false);\r
+          fVal[3] = p3.Eval();\r
+\r
+          // Test Eval function for multiple return values\r
+          // use p2 since it has the optimizer enabled!\r
+          int nNum;\r
+          value_type *v = p2.Eval(nNum);\r
+          fVal[4] = v[nNum-1];\r
+        }\r
+        catch(std::exception &e)\r
+        {\r
+          mu::console() << _T("\n  ") << e.what() << _T("\n");\r
+        }\r
+\r
+        // limited floating point accuracy requires the following test\r
+        bool bCloseEnough(true);\r
+        for (unsigned i=0; i<sizeof(fVal)/sizeof(value_type); ++i)\r
+        {\r
+          bCloseEnough &= (fabs(a_fRes-fVal[i]) <= fabs(fVal[i]*0.00001));\r
+\r
+          // The tests equations never result in infinity, if they do thats a bug.\r
+          // reference:\r
+          // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/5037825\r
+          if (numeric_limits<value_type>::has_infinity)\r
+            bCloseEnough &= (fabs(fVal[i]) != numeric_limits<value_type>::infinity());\r
+        }\r
+\r
+        iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;\r
+        \r
+        \r
+        if (iRet==1)\r
+        {\r
+          mu::console() << _T("\n  fail: ") << a_str.c_str() \r
+                        << _T(" (incorrect result; expected: ") << a_fRes\r
+                        << _T(" ;calculated: ") << fVal[0] << _T(",") \r
+                                                << fVal[1] << _T(",")\r
+                                                << fVal[2] << _T(",")\r
+                                                << fVal[3] << _T(",")\r
+                                                << fVal[4] << _T(").");\r
+        }\r
+      }\r
+      catch(Parser::exception_type &e)\r
+      {\r
+        if (a_fPass)\r
+        {\r
+          if (fVal[0]!=fVal[2] && fVal[0]!=-999 && fVal[1]!=-998)\r
+            mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (copy construction)");\r
+          else\r
+            mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.GetMsg() << _T(")");\r
+          return 1;\r
+        }\r
+      }\r
+      catch(std::exception &e)\r
+      {\r
+        mu::console() << _T("\n  fail: ") << a_str.c_str() << _T(" (") << e.what() << _T(")");\r
+        return 1;  // always return a failure since this exception is not expected\r
+      }\r
+      catch(...)\r
+      {\r
+        mu::console() << _T("\n  fail: ") << a_str.c_str() <<  _T(" (unexpected exception)");\r
+        return 1;  // exceptions other than ParserException are not allowed\r
+      }\r
+\r
+      return iRet;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    int ParserTester::EqnTestInt(const string_type &a_str, double a_fRes, bool a_fPass)\r
+    {\r
+      ParserTester::c_iCount++;\r
+\r
+      value_type vVarVal[] = {1, 2, 3};   // variable values\r
+      value_type fVal[2] = {-99, -999};   // results: initially should be different\r
+      int iRet(0);\r
+\r
+      try\r
+      {\r
+        ParserInt p;\r
+        p.DefineConst( _T("const1"), 1);\r
+        p.DefineConst( _T("const2"), 2);\r
+        p.DefineVar( _T("a"), &vVarVal[0]);\r
+        p.DefineVar( _T("b"), &vVarVal[1]);\r
+        p.DefineVar( _T("c"), &vVarVal[2]);\r
+\r
+        p.SetExpr(a_str);\r
+        fVal[0] = p.Eval(); // result from stringparsing\r
+        fVal[1] = p.Eval(); // result from bytecode\r
+\r
+        if (fVal[0]!=fVal[1])\r
+          throw Parser::exception_type( _T("Bytecode corrupt.") );\r
+\r
+        iRet =  ( (a_fRes==fVal[0] &&  a_fPass) || \r
+                  (a_fRes!=fVal[0] && !a_fPass) ) ? 0 : 1;\r
+        if (iRet==1)\r
+        {\r
+          mu::console() << _T("\n  fail: ") << a_str.c_str() \r
+                        << _T(" (incorrect result; expected: ") << a_fRes \r
+                        << _T(" ;calculated: ") << fVal[0]<< _T(").");\r
+        }\r
+      }\r
+      catch(Parser::exception_type &e)\r
+      {\r
+        if (a_fPass)\r
+        {\r
+          mu::console() << _T("\n  fail: ") << e.GetExpr() << _T(" : ") << e.GetMsg();\r
+          iRet = 1;\r
+        }\r
+      }\r
+      catch(...)\r
+      {\r
+        mu::console() << _T("\n  fail: ") << a_str.c_str() <<  _T(" (unexpected exception)");\r
+        iRet = 1;  // exceptions other than ParserException are not allowed\r
+      }\r
+\r
+      return iRet;\r
+    }\r
+\r
+    //---------------------------------------------------------------------------\r
+    /** \brief Internal error in test class Test is going to be aborted. */\r
+    void ParserTester::Abort() const\r
+    {\r
+      mu::console() << _T("Test failed (internal error in test class)") << endl;\r
+      while (!getchar());\r
+      exit(-1);\r
+    }\r
+  } // namespace test\r
+} // namespace mu\r
diff --git a/deal.II/bundled/muparser_v2_2_3/src/muParserTokenReader.cpp b/deal.II/bundled/muparser_v2_2_3/src/muParserTokenReader.cpp
new file mode 100644 (file)
index 0000000..0719ea0
--- /dev/null
@@ -0,0 +1,955 @@
+/*\r
+                 __________                                      \r
+    _____   __ __\______   \_____  _______  ______  ____ _______ \r
+   /     \ |  |  \|     ___/\__  \ \_  __ \/  ___/_/ __ \\_  __ \\r
+  |  Y Y  \|  |  /|    |     / __ \_|  | \/\___ \ \  ___/ |  | \/\r
+  |__|_|  /|____/ |____|    (____  /|__|  /____  > \___  >|__|   \r
+        \/                       \/            \/      \/        \r
+  Copyright (C) 2013 Ingo Berg\r
+\r
+  Permission is hereby granted, free of charge, to any person obtaining a copy of this \r
+  software and associated documentation files (the "Software"), to deal in the Software\r
+  without restriction, including without limitation the rights to use, copy, modify, \r
+  merge, publish, distribute, sublicense, and/or sell copies of the Software, and to \r
+  permit persons to whom the Software is furnished to do so, subject to the following conditions:\r
+\r
+  The above copyright notice and this permission notice shall be included in all copies or \r
+  substantial portions of the Software.\r
+\r
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT\r
+  NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND \r
+  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, \r
+  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, \r
+  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \r
+*/\r
+#include <cassert>\r
+#include <cstdio>\r
+#include <cstring>\r
+#include <map>\r
+#include <stack>\r
+#include <string>\r
+\r
+#include "muParserTokenReader.h"\r
+#include "muParserBase.h"\r
+\r
+/** \file\r
+    \brief This file contains the parser token reader implementation.\r
+*/\r
+\r
+\r
+namespace mu\r
+{\r
+\r
+  // Forward declaration\r
+  class ParserBase;\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Copy constructor.\r
+\r
+      \sa Assign\r
+      \throw nothrow\r
+  */\r
+  ParserTokenReader::ParserTokenReader(const ParserTokenReader &a_Reader) \r
+  { \r
+    Assign(a_Reader);\r
+  }\r
+    \r
+  //---------------------------------------------------------------------------\r
+  /** \brief Assignement operator.\r
+\r
+      Self assignement will be suppressed otherwise #Assign is called.\r
+\r
+      \param a_Reader Object to copy to this token reader.\r
+      \throw nothrow\r
+  */\r
+  ParserTokenReader& ParserTokenReader::operator=(const ParserTokenReader &a_Reader) \r
+  {\r
+    if (&a_Reader!=this)\r
+      Assign(a_Reader);\r
+\r
+    return *this;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Assign state of a token reader to this token reader. \r
+      \r
+      \param a_Reader Object from which the state should be copied.\r
+      \throw nothrow\r
+  */\r
+  void ParserTokenReader::Assign(const ParserTokenReader &a_Reader)\r
+  {\r
+    m_pParser = a_Reader.m_pParser;\r
+    m_strFormula = a_Reader.m_strFormula;\r
+    m_iPos = a_Reader.m_iPos;\r
+    m_iSynFlags = a_Reader.m_iSynFlags;\r
+    \r
+    m_UsedVar         = a_Reader.m_UsedVar;\r
+    m_pFunDef         = a_Reader.m_pFunDef;\r
+    m_pConstDef       = a_Reader.m_pConstDef;\r
+    m_pVarDef         = a_Reader.m_pVarDef;\r
+    m_pStrVarDef      = a_Reader.m_pStrVarDef;\r
+    m_pPostOprtDef    = a_Reader.m_pPostOprtDef;\r
+    m_pInfixOprtDef   = a_Reader.m_pInfixOprtDef;\r
+    m_pOprtDef        = a_Reader.m_pOprtDef;\r
+    m_bIgnoreUndefVar = a_Reader.m_bIgnoreUndefVar;\r
+    m_vIdentFun       = a_Reader.m_vIdentFun;\r
+    m_pFactory        = a_Reader.m_pFactory;\r
+    m_pFactoryData    = a_Reader.m_pFactoryData;\r
+    m_iBrackets       = a_Reader.m_iBrackets;\r
+    m_cArgSep         = a_Reader.m_cArgSep;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Constructor. \r
+      \r
+      Create a Token reader and bind it to a parser object. \r
+\r
+      \pre [assert] a_pParser may not be NULL\r
+      \post #m_pParser==a_pParser\r
+      \param a_pParent Parent parser object of the token reader.\r
+  */\r
+  ParserTokenReader::ParserTokenReader(ParserBase *a_pParent)\r
+    :m_pParser(a_pParent)\r
+    ,m_strFormula()\r
+    ,m_iPos(0)\r
+    ,m_iSynFlags(0)\r
+    ,m_bIgnoreUndefVar(false)\r
+    ,m_pFunDef(NULL)\r
+    ,m_pPostOprtDef(NULL)\r
+    ,m_pInfixOprtDef(NULL)\r
+    ,m_pOprtDef(NULL)\r
+    ,m_pConstDef(NULL)\r
+    ,m_pStrVarDef(NULL)\r
+    ,m_pVarDef(NULL)\r
+    ,m_pFactory(NULL)\r
+    ,m_pFactoryData(NULL)\r
+    ,m_vIdentFun()\r
+    ,m_UsedVar()\r
+    ,m_fZero(0)\r
+    ,m_iBrackets(0)\r
+    ,m_lastTok()\r
+    ,m_cArgSep(',')\r
+  {\r
+    assert(m_pParser);\r
+    SetParent(m_pParser);\r
+  }\r
+    \r
+  //---------------------------------------------------------------------------\r
+  /** \brief Create instance of a ParserTokenReader identical with this \r
+              and return its pointer. \r
+\r
+      This is a factory method the calling function must take care of the object destruction.\r
+\r
+      \return A new ParserTokenReader object.\r
+      \throw nothrow\r
+  */\r
+  ParserTokenReader* ParserTokenReader::Clone(ParserBase *a_pParent) const\r
+  {\r
+    std::auto_ptr<ParserTokenReader> ptr(new ParserTokenReader(*this));\r
+    ptr->SetParent(a_pParent);\r
+    return ptr.release();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  ParserTokenReader::token_type& ParserTokenReader::SaveBeforeReturn(const token_type &tok)\r
+  {\r
+    m_lastTok = tok;\r
+    return m_lastTok;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserTokenReader::AddValIdent(identfun_type a_pCallback)\r
+  {\r
+    // Use push_front is used to give user defined callbacks a higher priority than\r
+    // the built in ones. Otherwise reading hex numbers would not work\r
+    // since the "0" in "0xff" would always be read first making parsing of \r
+    // the rest impossible.\r
+    // reference:\r
+    // http://sourceforge.net/projects/muparser/forums/forum/462843/topic/4824956\r
+    m_vIdentFun.push_front(a_pCallback);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserTokenReader::SetVarCreator(facfun_type a_pFactory, void *pUserData)\r
+  {\r
+    m_pFactory = a_pFactory;\r
+    m_pFactoryData = pUserData;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return the current position of the token reader in the formula string. \r
+\r
+      \return #m_iPos\r
+      \throw nothrow\r
+  */\r
+  int ParserTokenReader::GetPos() const\r
+  {\r
+    return m_iPos;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return a reference to the formula. \r
+\r
+      \return #m_strFormula\r
+      \throw nothrow\r
+  */\r
+  const string_type& ParserTokenReader::GetExpr() const\r
+  {\r
+    return m_strFormula;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Return a map containing the used variables only. */\r
+  varmap_type& ParserTokenReader::GetUsedVar() \r
+  {\r
+    return m_UsedVar;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Initialize the token Reader. \r
+  \r
+      Sets the formula position index to zero and set Syntax flags to default for initial formula parsing.\r
+      \pre [assert] triggered if a_szFormula==0\r
+  */\r
+  void ParserTokenReader::SetFormula(const string_type &a_strFormula)\r
+  {\r
+    m_strFormula = a_strFormula;\r
+    ReInit();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Set Flag that contronls behaviour in case of undefined variables beeing found. \r
+  \r
+    If true, the parser does not throw an exception if an undefined variable is found. \r
+    otherwise it does. This variable is used internally only!\r
+    It supresses a "undefined variable" exception in GetUsedVar().  \r
+    Those function should return a complete list of variables including \r
+    those the are not defined by the time of it's call.\r
+  */\r
+  void ParserTokenReader::IgnoreUndefVar(bool bIgnore)\r
+  {\r
+    m_bIgnoreUndefVar = bIgnore;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Reset the token reader to the start of the formula. \r
+\r
+      The syntax flags will be reset to a value appropriate for the \r
+      start of a formula.\r
+      \post #m_iPos==0, #m_iSynFlags = noOPT | noBC | noPOSTOP | noSTR\r
+      \throw nothrow\r
+      \sa ESynCodes\r
+  */\r
+  void ParserTokenReader::ReInit()\r
+  {\r
+    m_iPos = 0;\r
+    m_iSynFlags = sfSTART_OF_LINE;\r
+    m_iBrackets = 0;\r
+    m_UsedVar.clear();\r
+    m_lastTok = token_type();\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Read the next token from the string. */ \r
+  ParserTokenReader::token_type ParserTokenReader::ReadNextToken()\r
+  {\r
+    assert(m_pParser);\r
+\r
+    std::stack<int> FunArgs;\r
+    const char_type *szFormula = m_strFormula.c_str();\r
+    token_type tok;\r
+\r
+    // Ignore all non printable characters when reading the expression\r
+    while (szFormula[m_iPos]>0 && szFormula[m_iPos]<=0x20) \r
+      ++m_iPos;\r
+\r
+    if ( IsEOF(tok) )        return SaveBeforeReturn(tok); // Check for end of formula\r
+    if ( IsOprt(tok) )       return SaveBeforeReturn(tok); // Check for user defined binary operator\r
+    if ( IsFunTok(tok) )     return SaveBeforeReturn(tok); // Check for function token\r
+    if ( IsBuiltIn(tok) )    return SaveBeforeReturn(tok); // Check built in operators / tokens\r
+    if ( IsArgSep(tok) )     return SaveBeforeReturn(tok); // Check for function argument separators\r
+    if ( IsValTok(tok) )     return SaveBeforeReturn(tok); // Check for values / constant tokens\r
+    if ( IsVarTok(tok) )     return SaveBeforeReturn(tok); // Check for variable tokens\r
+    if ( IsStrVarTok(tok) )  return SaveBeforeReturn(tok); // Check for string variables\r
+    if ( IsString(tok) )     return SaveBeforeReturn(tok); // Check for String tokens\r
+    if ( IsInfixOpTok(tok) ) return SaveBeforeReturn(tok); // Check for unary operators\r
+    if ( IsPostOpTok(tok) )  return SaveBeforeReturn(tok); // Check for unary operators\r
+\r
+    // Check String for undefined variable token. Done only if a \r
+    // flag is set indicating to ignore undefined variables.\r
+    // This is a way to conditionally avoid an error if \r
+    // undefined variables occur. \r
+    // (The GetUsedVar function must suppress the error for\r
+    // undefined variables in order to collect all variable \r
+    // names including the undefined ones.)\r
+    if ( (m_bIgnoreUndefVar || m_pFactory) && IsUndefVarTok(tok) )  \r
+      return SaveBeforeReturn(tok);\r
+\r
+    // Check for unknown token\r
+    // \r
+    // !!! From this point on there is no exit without an exception possible...\r
+    // \r
+    string_type strTok;\r
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);\r
+    if (iEnd!=m_iPos)\r
+      Error(ecUNASSIGNABLE_TOKEN, m_iPos, strTok);\r
+\r
+    Error(ecUNASSIGNABLE_TOKEN, m_iPos, m_strFormula.substr(m_iPos));\r
+    return token_type(); // never reached\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserTokenReader::SetParent(ParserBase *a_pParent)\r
+  {\r
+    m_pParser       = a_pParent; \r
+    m_pFunDef       = &a_pParent->m_FunDef;\r
+    m_pOprtDef      = &a_pParent->m_OprtDef;\r
+    m_pInfixOprtDef = &a_pParent->m_InfixOprtDef;\r
+    m_pPostOprtDef  = &a_pParent->m_PostOprtDef;\r
+    m_pVarDef       = &a_pParent->m_VarDef;\r
+    m_pStrVarDef    = &a_pParent->m_StrVarDef;\r
+    m_pConstDef     = &a_pParent->m_ConstDef;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Extract all characters that belong to a certain charset.\r
+\r
+    \param a_szCharSet [in] Const char array of the characters allowed in the token. \r
+    \param a_strTok [out]  The string that consists entirely of characters listed in a_szCharSet.\r
+    \param a_iPos [in] Position in the string from where to start reading.\r
+    \return The Position of the first character not listed in a_szCharSet.\r
+    \throw nothrow\r
+  */\r
+  int ParserTokenReader::ExtractToken(const char_type *a_szCharSet, \r
+                                      string_type &a_sTok, \r
+                                      int a_iPos) const\r
+  {\r
+    int iEnd = (int)m_strFormula.find_first_not_of(a_szCharSet, a_iPos);\r
+\r
+    if (iEnd==(int)string_type::npos)\r
+        iEnd = (int)m_strFormula.length();\r
+    \r
+    // Assign token string if there was something found\r
+    if (a_iPos!=iEnd)\r
+      a_sTok = string_type( m_strFormula.begin()+a_iPos, m_strFormula.begin()+iEnd);\r
+\r
+    return iEnd;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check Expression for the presence of a binary operator token.\r
+  \r
+    Userdefined binary operator "++" gives inconsistent parsing result for\r
+    the equations "a++b" and "a ++ b" if alphabetic characters are allowed\r
+    in operator tokens. To avoid this this function checks specifically\r
+    for operator tokens.\r
+  */\r
+  int ParserTokenReader::ExtractOperatorToken(string_type &a_sTok, \r
+                                              int a_iPos) const\r
+  {\r
+    int iEnd = (int)m_strFormula.find_first_not_of(m_pParser->ValidInfixOprtChars(), a_iPos);\r
+    if (iEnd==(int)string_type::npos)\r
+      iEnd = (int)m_strFormula.length();\r
+\r
+    // Assign token string if there was something found\r
+    if (a_iPos!=iEnd)\r
+    {\r
+      a_sTok = string_type( m_strFormula.begin() + a_iPos, m_strFormula.begin() + iEnd);\r
+      return iEnd;\r
+    }\r
+    else\r
+    {\r
+      // There is still the chance of having to deal with an operator consisting exclusively\r
+      // of alphabetic characters.\r
+      return ExtractToken(MUP_CHARS, a_sTok, a_iPos);\r
+    }\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check if a built in operator or other token can be found\r
+      \param a_Tok  [out] Operator token if one is found. This can either be a binary operator or an infix operator token.\r
+      \return true if an operator token has been found.\r
+  */\r
+  bool ParserTokenReader::IsBuiltIn(token_type &a_Tok)\r
+  {\r
+    const char_type **const pOprtDef = m_pParser->GetOprtDef(),\r
+                     *const szFormula = m_strFormula.c_str();\r
+\r
+    // Compare token with function and operator strings\r
+    // check string for operator/function\r
+    for (int i=0; pOprtDef[i]; i++)\r
+    {\r
+      std::size_t len( std::char_traits<char_type>::length(pOprtDef[i]) );\r
+      if ( string_type(pOprtDef[i]) == string_type(szFormula + m_iPos, szFormula + m_iPos + len) )\r
+      {\r
+        switch(i)\r
+        {\r
+        //case cmAND:\r
+        //case cmOR:\r
+        //case cmXOR:\r
+        case cmLAND:\r
+        case cmLOR:\r
+        case cmLT:\r
+        case cmGT:\r
+        case cmLE:\r
+        case cmGE:\r
+        case cmNEQ:  \r
+        case cmEQ:\r
+        case cmADD:\r
+        case cmSUB:\r
+        case cmMUL:\r
+        case cmDIV:\r
+        case cmPOW:\r
+        case cmASSIGN:\r
+              //if (len!=sTok.length())\r
+              //  continue;\r
+\r
+              // The assignement operator need special treatment\r
+              if (i==cmASSIGN && m_iSynFlags & noASSIGN)\r
+                Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);\r
+\r
+              if (!m_pParser->HasBuiltInOprt()) continue;\r
+              if (m_iSynFlags & noOPT) \r
+              {\r
+                // Maybe its an infix operator not an operator\r
+                // Both operator types can share characters in \r
+                // their identifiers\r
+                if ( IsInfixOpTok(a_Tok) ) \r
+                  return true;\r
+\r
+                Error(ecUNEXPECTED_OPERATOR, m_iPos, pOprtDef[i]);\r
+              }\r
+\r
+              m_iSynFlags  = noBC | noOPT | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;\r
+              m_iSynFlags |= ( (i != cmEND) && ( i != cmBC) ) ? noEND : 0;\r
+              break;\r
+\r
+                   case cmBO:\r
+              if (m_iSynFlags & noBO)\r
+                     Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);\r
+              \r
+              if (m_lastTok.GetCode()==cmFUNC)\r
+                m_iSynFlags = noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN | noIF | noELSE;\r
+              else\r
+                m_iSynFlags = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN| noIF | noELSE;\r
+\r
+              ++m_iBrackets;\r
+              break;\r
+\r
+                   case cmBC:\r
+              if (m_iSynFlags & noBC)\r
+                Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);\r
+\r
+              m_iSynFlags  = noBO | noVAR | noVAL | noFUN | noINFIXOP | noSTR | noASSIGN;\r
+\r
+              if (--m_iBrackets<0)\r
+                Error(ecUNEXPECTED_PARENS, m_iPos, pOprtDef[i]);\r
+              break;\r
+\r
+        case cmELSE:\r
+              if (m_iSynFlags & noELSE)\r
+                Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);\r
+\r
+              m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;\r
+              break;\r
+\r
+        case cmIF:\r
+              if (m_iSynFlags & noIF)\r
+                Error(ecUNEXPECTED_CONDITIONAL, m_iPos, pOprtDef[i]);\r
+\r
+              m_iSynFlags = noBC | noPOSTOP | noEND | noOPT | noIF | noELSE;\r
+              break;\r
+\r
+                   default:      // The operator is listed in c_DefaultOprt, but not here. This is a bad thing...\r
+              Error(ecINTERNAL_ERROR);\r
+        } // switch operator id\r
+\r
+        m_iPos += (int)len;\r
+        a_Tok.Set( (ECmdCode)i, pOprtDef[i] );\r
+        return true;\r
+           } // if operator string found\r
+    } // end of for all operator strings\r
+  \r
+    return false;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  bool ParserTokenReader::IsArgSep(token_type &a_Tok)\r
+  {\r
+    const char_type* szFormula = m_strFormula.c_str();\r
+\r
+    if (szFormula[m_iPos]==m_cArgSep)\r
+    {\r
+      // copy the separator into null terminated string\r
+      char_type szSep[2];\r
+      szSep[0] = m_cArgSep;\r
+      szSep[1] = 0;\r
+\r
+      if (m_iSynFlags & noARG_SEP)\r
+        Error(ecUNEXPECTED_ARG_SEP, m_iPos, szSep);\r
+\r
+      m_iSynFlags  = noBC | noOPT | noEND | noARG_SEP | noPOSTOP | noASSIGN;\r
+      m_iPos++;\r
+      a_Tok.Set(cmARG_SEP, szSep);\r
+      return true;\r
+    }\r
+\r
+    return false;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check for End of Formula.\r
+\r
+      \return true if an end of formula is found false otherwise.\r
+      \param a_Tok [out] If an eof is found the corresponding token will be stored there.\r
+      \throw nothrow\r
+      \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsString, IsInfixOpTok, IsPostOpTok\r
+  */\r
+  bool ParserTokenReader::IsEOF(token_type &a_Tok)\r
+  {\r
+    const char_type* szFormula = m_strFormula.c_str();\r
+\r
+    // check for EOF\r
+    if ( !szFormula[m_iPos] /*|| szFormula[m_iPos] == '\n'*/)\r
+    {\r
+      if ( m_iSynFlags & noEND )\r
+        Error(ecUNEXPECTED_EOF, m_iPos);\r
+\r
+      if (m_iBrackets>0)\r
+        Error(ecMISSING_PARENS, m_iPos, _T(")"));\r
+\r
+      m_iSynFlags = 0;\r
+      a_Tok.Set(cmEND);\r
+      return true;\r
+    }\r
+\r
+    return false;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check if a string position contains a unary infix operator. \r
+      \return true if a function token has been found false otherwise.\r
+  */\r
+  bool ParserTokenReader::IsInfixOpTok(token_type &a_Tok)\r
+  {\r
+    string_type sTok;\r
+    int iEnd = ExtractToken(m_pParser->ValidInfixOprtChars(), sTok, m_iPos);\r
+    if (iEnd==m_iPos)\r
+      return false;\r
+\r
+    // iteraterate over all postfix operator strings\r
+    funmap_type::const_reverse_iterator it = m_pInfixOprtDef->rbegin();\r
+    for ( ; it!=m_pInfixOprtDef->rend(); ++it)\r
+    {\r
+      if (sTok.find(it->first)!=0)\r
+        continue;\r
+\r
+      a_Tok.Set(it->second, it->first);\r
+      m_iPos += (int)it->first.length();\r
+\r
+      if (m_iSynFlags & noINFIXOP) \r
+        Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());\r
+\r
+      m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN;\r
+      return true;\r
+    }\r
+\r
+    return false;\r
+\r
+/*\r
+    a_Tok.Set(item->second, sTok);\r
+    m_iPos = (int)iEnd;\r
+\r
+    if (m_iSynFlags & noINFIXOP) \r
+      Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString());\r
+\r
+    m_iSynFlags = noPOSTOP | noINFIXOP | noOPT | noBC | noSTR | noASSIGN; \r
+    return true;\r
+*/\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check whether the token at a given position is a function token.\r
+      \param a_Tok [out] If a value token is found it will be placed here.\r
+      \throw ParserException if Syntaxflags do not allow a function at a_iPos\r
+      \return true if a function token has been found false otherwise.\r
+      \pre [assert] m_pParser!=0\r
+  */\r
+  bool ParserTokenReader::IsFunTok(token_type &a_Tok)\r
+  {\r
+    string_type strTok;\r
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);\r
+    if (iEnd==m_iPos)\r
+      return false;\r
+\r
+    funmap_type::const_iterator item = m_pFunDef->find(strTok);\r
+    if (item==m_pFunDef->end())\r
+      return false;\r
+\r
+    // Check if the next sign is an opening bracket\r
+    const char_type *szFormula = m_strFormula.c_str();\r
+    if (szFormula[iEnd]!='(')\r
+      return false;\r
+\r
+    a_Tok.Set(item->second, strTok);\r
+\r
+    m_iPos = (int)iEnd;\r
+    if (m_iSynFlags & noFUN)\r
+      Error(ecUNEXPECTED_FUN, m_iPos-(int)a_Tok.GetAsString().length(), a_Tok.GetAsString());\r
+\r
+    m_iSynFlags = noANY ^ noBO;\r
+    return true;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check if a string position contains a binary operator.\r
+      \param a_Tok  [out] Operator token if one is found. This can either be a binary operator or an infix operator token.\r
+      \return true if an operator token has been found.\r
+  */\r
+  bool ParserTokenReader::IsOprt(token_type &a_Tok)\r
+  {\r
+    const char_type *const szExpr = m_strFormula.c_str();\r
+    string_type strTok;\r
+\r
+    int iEnd = ExtractOperatorToken(strTok, m_iPos);\r
+    if (iEnd==m_iPos)\r
+      return false;\r
+\r
+    // Check if the operator is a built in operator, if so ignore it here\r
+    const char_type **const pOprtDef = m_pParser->GetOprtDef();\r
+    for (int i=0; m_pParser->HasBuiltInOprt() && pOprtDef[i]; ++i)\r
+    {\r
+      if (string_type(pOprtDef[i])==strTok)\r
+        return false;\r
+    }\r
+\r
+    // Note:\r
+    // All tokens in oprt_bin_maptype are have been sorted by their length\r
+    // Long operators must come first! Otherwise short names (like: "add") that\r
+    // are part of long token names (like: "add123") will be found instead \r
+    // of the long ones.\r
+    // Length sorting is done with ascending length so we use a reverse iterator here.\r
+    funmap_type::const_reverse_iterator it = m_pOprtDef->rbegin();\r
+    for ( ; it!=m_pOprtDef->rend(); ++it)\r
+    {\r
+      const string_type &sID = it->first;\r
+      if ( sID == string_type(szExpr + m_iPos, szExpr + m_iPos + sID.length()) )\r
+      {\r
+        a_Tok.Set(it->second, strTok);\r
+\r
+        // operator was found\r
+        if (m_iSynFlags & noOPT) \r
+        {\r
+          // An operator was found but is not expected to occur at\r
+          // this position of the formula, maybe it is an infix \r
+          // operator, not a binary operator. Both operator types\r
+          // can share characters in their identifiers.\r
+          if ( IsInfixOpTok(a_Tok) ) \r
+            return true;\r
+          else\r
+          {\r
+            // nope, no infix operator\r
+            return false;\r
+            //Error(ecUNEXPECTED_OPERATOR, m_iPos, a_Tok.GetAsString()); \r
+          }\r
+\r
+        }\r
+\r
+        m_iPos += (int)sID.length();\r
+        m_iSynFlags  = noBC | noOPT | noARG_SEP | noPOSTOP | noEND | noBC | noASSIGN;\r
+        return true;\r
+      }\r
+    }\r
+\r
+    return false;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check if a string position contains a unary post value operator. */\r
+  bool ParserTokenReader::IsPostOpTok(token_type &a_Tok)\r
+  {\r
+    // <ibg 20110629> Do not check for postfix operators if they are not allowed at\r
+    //                the current expression index.\r
+    //\r
+    //  This will fix the bug reported here:  \r
+    //\r
+    //  http://sourceforge.net/tracker/index.php?func=detail&aid=3343891&group_id=137191&atid=737979\r
+    //\r
+    if (m_iSynFlags & noPOSTOP)\r
+      return false;\r
+    // </ibg>\r
+\r
+    // Tricky problem with equations like "3m+5":\r
+    //     m is a postfix operator, + is a valid sign for postfix operators and \r
+    //     for binary operators parser detects "m+" as operator string and \r
+    //     finds no matching postfix operator.\r
+    // \r
+    // This is a special case so this routine slightly differs from the other\r
+    // token readers.\r
+    \r
+    // Test if there could be a postfix operator\r
+    string_type sTok;\r
+    int iEnd = ExtractToken(m_pParser->ValidOprtChars(), sTok, m_iPos);\r
+    if (iEnd==m_iPos)\r
+      return false;\r
+\r
+    // iteraterate over all postfix operator strings\r
+    funmap_type::const_reverse_iterator it = m_pPostOprtDef->rbegin();\r
+    for ( ; it!=m_pPostOprtDef->rend(); ++it)\r
+    {\r
+      if (sTok.find(it->first)!=0)\r
+        continue;\r
+\r
+      a_Tok.Set(it->second, sTok);\r
+         m_iPos += (int)it->first.length();\r
+\r
+      m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noSTR | noASSIGN;\r
+      return true;\r
+    }\r
+\r
+    return false;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check whether the token at a given position is a value token.\r
+\r
+    Value tokens are either values or constants.\r
+\r
+    \param a_Tok [out] If a value token is found it will be placed here.\r
+    \return true if a value token has been found.\r
+  */\r
+  bool ParserTokenReader::IsValTok(token_type &a_Tok)\r
+  {\r
+    assert(m_pConstDef);\r
+    assert(m_pParser);\r
+\r
+    string_type strTok;\r
+    value_type fVal(0);\r
+    int iEnd(0);\r
+    \r
+    // 2.) Check for user defined constant\r
+    // Read everything that could be a constant name\r
+    iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);\r
+    if (iEnd!=m_iPos)\r
+    {\r
+      valmap_type::const_iterator item = m_pConstDef->find(strTok);\r
+      if (item!=m_pConstDef->end())\r
+      {\r
+        m_iPos = iEnd;\r
+        a_Tok.SetVal(item->second, strTok);\r
+\r
+        if (m_iSynFlags & noVAL)\r
+          Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);\r
+\r
+        m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; \r
+        return true;\r
+      }\r
+    }\r
+\r
+    // 3.call the value recognition functions provided by the user\r
+    // Call user defined value recognition functions\r
+    std::list<identfun_type>::const_iterator item = m_vIdentFun.begin();\r
+    for (item = m_vIdentFun.begin(); item!=m_vIdentFun.end(); ++item)\r
+    {\r
+      int iStart = m_iPos;\r
+      if ( (*item)(m_strFormula.c_str() + m_iPos, &m_iPos, &fVal)==1 )\r
+      {\r
+        strTok.assign(m_strFormula.c_str(), iStart, m_iPos);\r
+        if (m_iSynFlags & noVAL)\r
+          Error(ecUNEXPECTED_VAL, m_iPos - (int)strTok.length(), strTok);\r
+\r
+        a_Tok.SetVal(fVal, strTok);\r
+        m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN;\r
+        return true;\r
+      }\r
+    }\r
+\r
+    return false;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check wheter a token at a given position is a variable token. \r
+      \param a_Tok [out] If a variable token has been found it will be placed here.\r
+           \return true if a variable token has been found.\r
+  */\r
+  bool ParserTokenReader::IsVarTok(token_type &a_Tok)\r
+  {\r
+    if (!m_pVarDef->size())\r
+      return false;\r
+\r
+    string_type strTok;\r
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);\r
+    if (iEnd==m_iPos)\r
+      return false;\r
+\r
+    varmap_type::const_iterator item =  m_pVarDef->find(strTok);\r
+    if (item==m_pVarDef->end())\r
+      return false;\r
+\r
+    if (m_iSynFlags & noVAR)\r
+      Error(ecUNEXPECTED_VAR, m_iPos, strTok);\r
+\r
+    m_pParser->OnDetectVar(&m_strFormula, m_iPos, iEnd);\r
+\r
+    m_iPos = iEnd;\r
+    a_Tok.SetVar(item->second, strTok);\r
+    m_UsedVar[item->first] = item->second;  // Add variable to used-var-list\r
+\r
+    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR;\r
+\r
+//  Zur Info hier die SynFlags von IsVal():\r
+//    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noINFIXOP | noSTR | noASSIGN; \r
+    return true;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  bool ParserTokenReader::IsStrVarTok(token_type &a_Tok)\r
+  {\r
+    if (!m_pStrVarDef || !m_pStrVarDef->size())\r
+      return false;\r
+\r
+    string_type strTok;\r
+    int iEnd = ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos);\r
+    if (iEnd==m_iPos)\r
+      return false;\r
+\r
+    strmap_type::const_iterator item =  m_pStrVarDef->find(strTok);\r
+    if (item==m_pStrVarDef->end())\r
+      return false;\r
+\r
+    if (m_iSynFlags & noSTR)\r
+      Error(ecUNEXPECTED_VAR, m_iPos, strTok);\r
+\r
+    m_iPos = iEnd;\r
+    if (!m_pParser->m_vStringVarBuf.size())\r
+      Error(ecINTERNAL_ERROR);\r
+\r
+    a_Tok.SetString(m_pParser->m_vStringVarBuf[item->second], m_pParser->m_vStringVarBuf.size() );\r
+\r
+    m_iSynFlags = noANY ^ ( noBC | noOPT | noEND | noARG_SEP);\r
+    return true;\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check wheter a token at a given position is an undefined variable. \r
+\r
+      \param a_Tok [out] If a variable tom_pParser->m_vStringBufken has been found it will be placed here.\r
+           \return true if a variable token has been found.\r
+      \throw nothrow\r
+  */\r
+  bool ParserTokenReader::IsUndefVarTok(token_type &a_Tok)\r
+  {\r
+    string_type strTok;\r
+    int iEnd( ExtractToken(m_pParser->ValidNameChars(), strTok, m_iPos) );\r
+    if ( iEnd==m_iPos )\r
+      return false;\r
+\r
+    if (m_iSynFlags & noVAR)\r
+    {\r
+      // <ibg/> 20061021 added token string strTok instead of a_Tok.GetAsString() as the \r
+      //                 token identifier. \r
+      // related bug report:\r
+      // http://sourceforge.net/tracker/index.php?func=detail&aid=1578779&group_id=137191&atid=737979\r
+      Error(ecUNEXPECTED_VAR, m_iPos - (int)a_Tok.GetAsString().length(), strTok);\r
+    }\r
+\r
+    // If a factory is available implicitely create new variables\r
+    if (m_pFactory)\r
+    {\r
+      value_type *fVar = m_pFactory(strTok.c_str(), m_pFactoryData);\r
+      a_Tok.SetVar(fVar, strTok );\r
+\r
+      // Do not use m_pParser->DefineVar( strTok, fVar );\r
+      // in order to define the new variable, it will clear the\r
+      // m_UsedVar array which will kill previousely defined variables\r
+      // from the list\r
+      // This is safe because the new variable can never override an existing one\r
+      // because they are checked first!\r
+      (*m_pVarDef)[strTok] = fVar;\r
+      m_UsedVar[strTok] = fVar;  // Add variable to used-var-list\r
+    }\r
+    else\r
+    {\r
+      a_Tok.SetVar((value_type*)&m_fZero, strTok);\r
+      m_UsedVar[strTok] = 0;  // Add variable to used-var-list\r
+    }\r
+\r
+    m_iPos = iEnd;\r
+\r
+    // Call the variable factory in order to let it define a new parser variable\r
+    m_iSynFlags = noVAL | noVAR | noFUN | noBO | noPOSTOP | noINFIXOP | noSTR;\r
+    return true;\r
+  }\r
+\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Check wheter a token at a given position is a string.\r
+      \param a_Tok [out] If a variable token has been found it will be placed here.\r
+         \return true if a string token has been found.\r
+      \sa IsOprt, IsFunTok, IsStrFunTok, IsValTok, IsVarTok, IsEOF, IsInfixOpTok, IsPostOpTok\r
+      \throw nothrow\r
+  */\r
+  bool ParserTokenReader::IsString(token_type &a_Tok)\r
+  {\r
+    if (m_strFormula[m_iPos]!='"') \r
+      return false;\r
+\r
+    string_type strBuf(&m_strFormula[m_iPos+1]);\r
+    std::size_t iEnd(0), iSkip(0);\r
+\r
+    // parser over escaped '\"' end replace them with '"'\r
+    for(iEnd=(int)strBuf.find( _T("\"") ); iEnd!=0 && iEnd!=string_type::npos; iEnd=(int)strBuf.find( _T("\""), iEnd))\r
+    {\r
+      if (strBuf[iEnd-1]!='\\') break;\r
+      strBuf.replace(iEnd-1, 2, _T("\"") );\r
+      iSkip++;\r
+    }\r
+\r
+    if (iEnd==string_type::npos)\r
+      Error(ecUNTERMINATED_STRING, m_iPos, _T("\"") );\r
+\r
+    string_type strTok(strBuf.begin(), strBuf.begin()+iEnd);\r
+\r
+    if (m_iSynFlags & noSTR)\r
+      Error(ecUNEXPECTED_STR, m_iPos, strTok);\r
+\r
+               m_pParser->m_vStringBuf.push_back(strTok); // Store string in internal buffer\r
+    a_Tok.SetString(strTok, m_pParser->m_vStringBuf.size());\r
+\r
+    m_iPos += (int)strTok.length() + 2 + (int)iSkip;  // +2 wg Anführungszeichen; +iSkip für entfernte escape zeichen\r
+    m_iSynFlags = noANY ^ ( noARG_SEP | noBC | noOPT | noEND );\r
+\r
+    return true;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  /** \brief Create an error containing the parse error position.\r
+\r
+    This function will create an Parser Exception object containing the error text and its position.\r
+\r
+    \param a_iErrc [in] The error code of type #EErrorCodes.\r
+    \param a_iPos [in] The position where the error was detected.\r
+    \param a_strTok [in] The token string representation associated with the error.\r
+    \throw ParserException always throws thats the only purpose of this function.\r
+  */\r
+  void  ParserTokenReader::Error( EErrorCodes a_iErrc, \r
+                                  int a_iPos, \r
+                                  const string_type &a_sTok) const\r
+  {\r
+    m_pParser->Error(a_iErrc, a_iPos, a_sTok);\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  void ParserTokenReader::SetArgSep(char_type cArgSep)\r
+  {\r
+    m_cArgSep = cArgSep;\r
+  }\r
+\r
+  //---------------------------------------------------------------------------\r
+  char_type ParserTokenReader::GetArgSep() const\r
+  {\r
+    return m_cArgSep;\r
+  }\r
+} // namespace mu\r
+\r
index b1de850df9319d9dd7aadaf950eaaef8f345a58a..5a5206cdf50169806851eaaea06100625ad19d53 100644 (file)
@@ -73,3 +73,15 @@ OPTION(DEAL_II_FORCE_BUNDLED_UMFPACK
   OFF)
 
 SET(UMFPACK_FOLDER "${CMAKE_SOURCE_DIR}/bundled/umfpack")
+
+
+#
+# muparser
+#
+SET(FEATURE_MUPARSER_HAVE_BUNDLED TRUE)
+
+OPTION(DEAL_II_FORCE_BUNDLED_MUPARSER
+  "Always use the bundled functionparser library instead of an external one."
+  OFF)
+
+SET(MUPARSER_FOLDER "${CMAKE_SOURCE_DIR}/bundled/muparser_v2_2_3/")
index 93dcbc7294fb540f267fb9d0e2933dd921b54429..2580c6a5e43c4c1bb685acfb75f5ea2a59c18ff6 100644 (file)
 # Configuration for the MUPARSER library:
 #
 
+MACRO(FEATURE_MUPARSER_FIND_EXTERNAL var)
+  MESSAGE(STATUS
+    "No module available for finding functionparser externally."
+    )
+ENDMACRO()
+
+
+MACRO(FEATURE_MUPARSER_CONFIGURE_BUNDLED)
+  SET(MUPARSER_BUNDLED_INCLUDE_DIRS ${MUPARSER_FOLDER}/include)
+ENDMACRO()
+
+
+MACRO(FEATURE_MUPARSER_ERROR_MESSAGE)
+  MESSAGE(FATAL_ERROR "\n"
+    "No module available for finding functionparser externally.\n"
+    "Disable DEAL_II_WITH_MUPARSER, or enable DEAL_II_ALLOW_BUNDLED.\n\n"
+    )
+ENDMACRO()
+
+
 CONFIGURE_FEATURE(MUPARSER)

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.