wpkg test coverage results

Coverage test results of the Windows Packager by Made to Order Software Corporation.

LCOV - code coverage report
Current view: top level - tests/unittests - unittest_expr.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 558 558 100.0 %
Date: 2013-06-17 Functions: 18 18 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*    unittest_expr.cpp
       2             :  *    Copyright (C) 2013  Made to Order Software Corporation
       3             :  *
       4             :  *    This program is free software; you can redistribute it and/or modify
       5             :  *    it under the terms of the GNU General Public License as published by
       6             :  *    the Free Software Foundation; either version 2 of the License, or
       7             :  *    (at your option) any later version.
       8             :  *
       9             :  *    This program is distributed in the hope that it will be useful,
      10             :  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  *    GNU General Public License for more details.
      13             :  *
      14             :  *    You should have received a copy of the GNU General Public License along
      15             :  *    with this program; if not, write to the Free Software Foundation, Inc.,
      16             :  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  *
      18             :  *    Authors
      19             :  *    Alexis Wilke   alexis@m2osw.com
      20             :  */
      21             : 
      22             : #include "unittest_expr.h"
      23             : #include "libexpr/expr.h"
      24             : 
      25             : #include <cppunit/config/SourcePrefix.h>
      26             : #include <string.h>
      27             : #include <math.h>
      28             : #include <time.h>
      29             : 
      30             : // warning C4554: '<<' : check operator precedence for possible error; use parentheses to clarify precedence
      31             : #pragma warning(disable: 4554)
      32             : // warning C4805: '==' : unsafe mix of type 'long' and type 'bool' in operation
      33             : #pragma warning(disable: 4805)
      34             : 
      35           1 : CPPUNIT_TEST_SUITE_REGISTRATION( ExprUnitTests );
      36             : 
      37             : #ifdef _MSC_VER
      38             : namespace
      39             : {
      40             : long lrint(double f)
      41             : {
      42             :     // XXX at some point libexpr may check for over/under-flow...
      43             :     return static_cast<long>(f < 0.0 ? ceil(f - 0.5) : floor(f + 0.5));
      44             : }
      45             : 
      46             : double acosh(double flt)
      47             : {
      48             :         return log(flt + sqrt(flt * flt - 1.0));
      49             : }
      50             : 
      51             : double asinh(double flt)
      52             : {
      53             :         return log(flt + sqrt(flt * flt + 1.0));
      54             : }
      55             : 
      56             : double atanh(double flt)
      57             : {
      58             :         return log((1.0 + flt) / (1.0 - flt)) / 2.0;
      59             : }
      60             : 
      61             : double rint(double flt)
      62             : {
      63             :         if(flt < 0.0)
      64             :         {
      65             :                 return ceil(flt - 0.5);
      66             :         }
      67             :         else
      68             :         {
      69             :                 return floor(flt + 0.5);
      70             :         }
      71             : }
      72             : 
      73             : } // noname namespace
      74             : #endif
      75             : 
      76             : 
      77          12 : void ExprUnitTests::setUp()
      78             : {
      79          12 : }
      80             : 
      81         315 : long compute_long(const char *op)
      82             : {
      83             : //printf("compute long [%s]\n", op);
      84         315 :     libexpr::expr_evaluator e;
      85         315 :     libexpr::variable result;
      86         315 :     e.eval(op, result);
      87             :     long value;
      88         209 :     result.get(value);
      89         315 :     return value;
      90             : }
      91             : 
      92         130 : double compute_double(const char *op, double flt)
      93             : {
      94         130 :     libexpr::expr_evaluator e;
      95         130 :     libexpr::variable result;
      96         130 :     e.eval(op, result);
      97             :     double value;
      98         112 :     result.get(value);
      99         130 :     return abs(value - flt) < 0.00001;
     100             : }
     101             : 
     102          13 : bool compute_string(const char *op, const char *expected)
     103             : {
     104          13 :     libexpr::expr_evaluator e;
     105          13 :     libexpr::variable result;
     106             : //printf("compute [%s]\n", op);
     107          13 :     e.eval(op, result);
     108          13 :     std::string value;
     109          13 :     result.get(value);
     110             : //printf("\nvalue = [");
     111             : //for(const char *s(value.c_str()); *s != '\0'; ++s) static_cast<unsigned char>(*s) < ' ' ? printf("^%c", *s + '@') : (static_cast<unsigned char>(*s) > 0x7E ? printf("/0x%02X/", static_cast<unsigned char>(*s)) : printf("%c", *s));
     112             : //printf("] [");
     113             : //for(const char *s(expected); *s != '\0'; ++s) static_cast<unsigned char>(*s) < ' ' ? printf("^%c", *s + '@') : (static_cast<unsigned char>(*s) > 0x7E ? printf("/0x%02X/", static_cast<unsigned char>(*s)) : printf("%c", *s));
     114             : //printf("]\n");
     115          13 :     return value == expected;
     116             : }
     117             : 
     118             : #define ASSERT_LONG_OPERATION(operation) \
     119             :     CPPUNIT_ASSERT(compute_long(#operation) == (operation))
     120             : 
     121             : #define ASSERT_DOUBLE_OPERATION(operation) \
     122             :     CPPUNIT_ASSERT(compute_double(#operation, (operation)))
     123             : 
     124             : 
     125           1 : void ExprUnitTests::bad_literals()
     126             : {
     127             :     // bad hex
     128           1 :     CPPUNIT_ASSERT_THROW(compute_long("(0x) * 2"), libexpr::syntax_error);
     129             : 
     130             :     // bad octal
     131           1 :     CPPUNIT_ASSERT_THROW(compute_long("03 + 08"), libexpr::syntax_error);
     132           1 :     CPPUNIT_ASSERT_THROW(compute_long("033 + 09"), libexpr::syntax_error);
     133             : 
     134             :     // bad float
     135           1 :     CPPUNIT_ASSERT_THROW(compute_long("0.3e++"), libexpr::syntax_error);
     136           1 :     CPPUNIT_ASSERT_THROW(compute_long("0.3ee3"), libexpr::syntax_error);
     137           1 :     CPPUNIT_ASSERT_THROW(compute_long("0.3e-a"), libexpr::syntax_error);
     138             : 
     139             :     // bad character
     140           1 :     CPPUNIT_ASSERT_THROW(compute_long("'h + 3"), libexpr::syntax_error);
     141           1 :     CPPUNIT_ASSERT_THROW(compute_long("'h"), libexpr::syntax_error);
     142           1 :     CPPUNIT_ASSERT_THROW(compute_long("'\\x74 + 3"), libexpr::syntax_error);
     143           1 :     CPPUNIT_ASSERT_THROW(compute_long("'\\x74"), libexpr::syntax_error);
     144             : 
     145             :     // bad string
     146           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"hello world"), libexpr::syntax_error);
     147           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"hello\\xqaworld\""), libexpr::syntax_error);
     148             : 
     149             :     // bad conditional
     150           1 :     CPPUNIT_ASSERT_THROW(compute_long("(a = 3, b = 55, 3 > 0 ? a b)"), libexpr::syntax_error);
     151           1 : }
     152             : 
     153           1 : void ExprUnitTests::bad_variables()
     154             : {
     155           1 :     CPPUNIT_ASSERT_THROW(compute_long("a"), libexpr::undefined_variable);
     156             : 
     157           1 :     CPPUNIT_ASSERT_THROW(compute_long("a++"), libexpr::undefined_variable);
     158           1 :     CPPUNIT_ASSERT_THROW(compute_long("++a"), libexpr::undefined_variable);
     159           1 :     CPPUNIT_ASSERT_THROW(compute_long("a--"), libexpr::undefined_variable);
     160           1 :     CPPUNIT_ASSERT_THROW(compute_long("--a"), libexpr::undefined_variable);
     161             : 
     162           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = b;"), libexpr::undefined_variable); // cannot get an undefined variable
     163           1 :     CPPUNIT_ASSERT_THROW(compute_long("a *= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     164           1 :     CPPUNIT_ASSERT_THROW(compute_long("a /= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     165           1 :     CPPUNIT_ASSERT_THROW(compute_long("a %= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     166           1 :     CPPUNIT_ASSERT_THROW(compute_long("a += 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     167           1 :     CPPUNIT_ASSERT_THROW(compute_long("a -= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     168           1 :     CPPUNIT_ASSERT_THROW(compute_long("a >>= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     169           1 :     CPPUNIT_ASSERT_THROW(compute_long("a <<= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     170           1 :     CPPUNIT_ASSERT_THROW(compute_long("a &= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     171           1 :     CPPUNIT_ASSERT_THROW(compute_long("a ^= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     172           1 :     CPPUNIT_ASSERT_THROW(compute_long("a |= 5;"), libexpr::undefined_variable); // cannot get an undefined variable
     173           1 : }
     174             : 
     175           1 : void ExprUnitTests::bad_expressions()
     176             : {
     177             :     // misc.
     178           1 :     CPPUNIT_ASSERT_THROW(compute_long("(a = 3, b = \"abc\", a->b = 5)"), libexpr::syntax_error); // arrow not supported
     179           1 :     CPPUNIT_ASSERT_THROW(compute_long("(a = 5, a++"), libexpr::syntax_error); // ')' missing
     180           1 :     CPPUNIT_ASSERT_THROW(compute_long("(a = 5 a)"), libexpr::syntax_error); // comma missing
     181           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = 5, a)"), libexpr::syntax_error); // '(' missing
     182           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = 5 a"), libexpr::syntax_error); // ',' missing
     183           1 :     CPPUNIT_ASSERT_THROW(compute_long(")a)"), libexpr::syntax_error); // ')' instead of '('
     184           1 :     CPPUNIT_ASSERT_THROW(compute_long("lrint("), libexpr::syntax_error); // missing argument
     185           1 :     CPPUNIT_ASSERT_THROW(compute_long("lrint(3.4"), libexpr::syntax_error); // ')' missing
     186           1 :     CPPUNIT_ASSERT_THROW(compute_long("lrint(3.4,"), libexpr::syntax_error); // expect only one parameter, missing ')'
     187           1 :     CPPUNIT_ASSERT_THROW(compute_long("lrint(3.4, 5)"), libexpr::function_args); // expects only one parameter
     188           1 :     CPPUNIT_ASSERT_THROW(compute_long("3(75)"), libexpr::syntax_error); // not a function name
     189           1 :     CPPUNIT_ASSERT_THROW(compute_long("unknown_function_name(1, 2, 3)"), libexpr::undefined_function); // function not defined
     190             : #if !defined(WINDOWS) && !defined(_WINDOWS)
     191             :     // shell true and false are inverted!
     192           1 :     CPPUNIT_ASSERT_THROW(compute_long("shell( \"true\" , \"magic\" )"), libexpr::function_args);
     193           1 :     CPPUNIT_ASSERT_THROW(compute_long("shell( \"totally-unknown-command\" )"), libexpr::libexpr_runtime_error);
     194             : #endif
     195           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = 5, a++++"), libexpr::syntax_error); // ++ only applicable to lvalue
     196           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = 5, a----"), libexpr::syntax_error); // -- only applicable to lvalue
     197           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = 5, a++--"), libexpr::syntax_error); // -- only applicable to lvalue
     198           1 :     CPPUNIT_ASSERT_THROW(compute_long("a = 5, a--++"), libexpr::syntax_error); // ++ only applicable to lvalue
     199           1 :     CPPUNIT_ASSERT_THROW(compute_long("5--"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     200           1 :     CPPUNIT_ASSERT_THROW(compute_long("5++"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     201           1 :     CPPUNIT_ASSERT_THROW(compute_long("++5"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     202           1 :     CPPUNIT_ASSERT_THROW(compute_long("--5"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     203           1 :     CPPUNIT_ASSERT_THROW(compute_long("5.3--"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     204           1 :     CPPUNIT_ASSERT_THROW(compute_long("5.2++"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     205           1 :     CPPUNIT_ASSERT_THROW(compute_long("++5.1"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     206           1 :     CPPUNIT_ASSERT_THROW(compute_long("--7.9"), libexpr::expected_a_variable); // ++ only applicable to lvalue
     207           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 = 5;"), libexpr::expected_a_variable); // cannot set a number
     208           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 *= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     209           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 /= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     210           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 %= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     211           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 += 5;"), libexpr::expected_a_variable); // cannot get/set a number
     212           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 -= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     213           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 >>= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     214           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 <<= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     215           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 &= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     216           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 ^= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     217           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 |= 5;"), libexpr::expected_a_variable); // cannot get/set a number
     218             : 
     219             :     // string problems
     220           1 :     CPPUNIT_ASSERT_THROW(compute_long("-\"neg\""), libexpr::incompatible_type); // -"string" not valid
     221           1 :     CPPUNIT_ASSERT_THROW(compute_long("+\"neg\""), libexpr::incompatible_type); // +"string" not valid
     222           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 * \"mul\""), libexpr::incompatible_type); // "string" operation not valid
     223           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 % \"mod\""), libexpr::incompatible_type); // "string" operation not valid
     224           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 / \"div\""), libexpr::incompatible_type); // "string" operation not valid
     225           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 - \"div\""), libexpr::incompatible_type); // "string" operation not valid
     226           1 :     CPPUNIT_ASSERT_THROW(compute_double("3.5 * \"mul\"", 0.0), libexpr::incompatible_type); // "string" operation not valid
     227           1 :     CPPUNIT_ASSERT_THROW(compute_double("17.3 / \"div\"", 0.0), libexpr::incompatible_type); // "string" operation not valid
     228           1 :     CPPUNIT_ASSERT_THROW(compute_double("3.9 % \"mod\"", 0.0), libexpr::incompatible_type); // "string" operation not valid
     229           1 :     CPPUNIT_ASSERT_THROW(compute_double("3.9 - \"mod\"", 0.0), libexpr::incompatible_type); // "string" operation not valid
     230           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"mul\" * 3"), libexpr::incompatible_type); // "string" operation not valid
     231           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"div\" / 3"), libexpr::incompatible_type); // "string" operation not valid
     232           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"min\" - 3"), libexpr::incompatible_type); // "string" operation not valid
     233           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"min\" & 3"), libexpr::incompatible_type); // "string" operation not valid
     234           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"min\" ^ 3"), libexpr::incompatible_type); // "string" operation not valid
     235           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"min\" | 3"), libexpr::incompatible_type); // "string" operation not valid
     236           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 & \"min\""), libexpr::incompatible_type); // "string" operation not valid
     237           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 ^ \"min\""), libexpr::incompatible_type); // "string" operation not valid
     238           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 | \"min\""), libexpr::incompatible_type); // "string" operation not valid
     239           1 :     CPPUNIT_ASSERT_THROW(compute_long("~\"min\""), libexpr::incompatible_type); // "string" operation not valid
     240           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 == \"str\""), libexpr::incompatible_type); // "string" operation not valid
     241           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.5 == \"str\""), libexpr::incompatible_type); // "string" operation not valid
     242           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 != \"str\""), libexpr::incompatible_type); // "string" operation not valid
     243           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.5 != \"str\""), libexpr::incompatible_type); // "string" operation not valid
     244           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 < \"str\""), libexpr::incompatible_type); // "string" operation not valid
     245           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.5 < \"str\""), libexpr::incompatible_type); // "string" operation not valid
     246           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 <= \"str\""), libexpr::incompatible_type); // "string" operation not valid
     247           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.5 <= \"str\""), libexpr::incompatible_type); // "string" operation not valid
     248           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 > \"str\""), libexpr::incompatible_type); // "string" operation not valid
     249           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.5 > \"str\""), libexpr::incompatible_type); // "string" operation not valid
     250           1 :     CPPUNIT_ASSERT_THROW(compute_long("3 >= \"str\""), libexpr::incompatible_type); // "string" operation not valid
     251           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.5 >= \"str\""), libexpr::incompatible_type); // "string" operation not valid
     252           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" == 56"), libexpr::incompatible_type); // "string" operation not valid
     253           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" == 895.3"), libexpr::incompatible_type); // "string" operation not valid
     254           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" != 56"), libexpr::incompatible_type); // "string" operation not valid
     255           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" != 895.3"), libexpr::incompatible_type); // "string" operation not valid
     256           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" < 56"), libexpr::incompatible_type); // "string" operation not valid
     257           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" < 895.3"), libexpr::incompatible_type); // "string" operation not valid
     258           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" <= 56"), libexpr::incompatible_type); // "string" operation not valid
     259           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" <= 895.3"), libexpr::incompatible_type); // "string" operation not valid
     260           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" > 56"), libexpr::incompatible_type); // "string" operation not valid
     261           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" > 895.3"), libexpr::incompatible_type); // "string" operation not valid
     262           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" >= 56"), libexpr::incompatible_type); // "string" operation not valid
     263           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"str\" >= 895.3"), libexpr::incompatible_type); // "string" operation not valid
     264             : 
     265             :     // floating point problems
     266           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 % 2.4", 0.0), libexpr::incompatible_type); // % not valid with float
     267           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3 % 2.4", 0.0), libexpr::incompatible_type); // % not valid with float
     268           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 % 2", 0.0), libexpr::incompatible_type); // % not valid with float
     269           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 << 2.4", 0.0), libexpr::incompatible_type); // << not valid with float
     270           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3 << 2.4", 0.0), libexpr::incompatible_type); // << not valid with float
     271           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 << 2", 0.0), libexpr::incompatible_type); // << not valid with float
     272           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 >> 2.4", 0.0), libexpr::incompatible_type); // >> not valid with float
     273           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3 >> 2.4", 0.0), libexpr::incompatible_type); // >> not valid with float
     274           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 >> 2", 0.0), libexpr::incompatible_type); // >> not valid with float
     275           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 & 2", 0.0), libexpr::incompatible_type); // & not valid with float
     276           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 ^ 2", 0.0), libexpr::incompatible_type); // ^ not valid with float
     277           1 :     CPPUNIT_ASSERT_THROW(compute_double("-3.5 | 2", 0.0), libexpr::incompatible_type); // | not valid with float
     278           1 :     CPPUNIT_ASSERT_THROW(compute_double("~3.5", 0.0), libexpr::incompatible_type); // ~ not valid with float
     279           1 :     CPPUNIT_ASSERT_THROW(compute_double("~-9.3", 0.0), libexpr::incompatible_type); // ~ not valid with float
     280             : 
     281             :     // incompatible data type for our get
     282           1 :     CPPUNIT_ASSERT_THROW(compute_double("3", 0.0), libexpr::invalid_type); // 3 is a long, not a float
     283           1 :     CPPUNIT_ASSERT_THROW(compute_double("\"hello\"", 0.0), libexpr::invalid_type); // "hello" is a string, not a float
     284           1 :     CPPUNIT_ASSERT_THROW(compute_long("3.3"), libexpr::invalid_type); // 3.3 is a float, not a long
     285           1 :     CPPUNIT_ASSERT_THROW(compute_long("\"hello\""), libexpr::invalid_type); // "hello" is a string, not a long
     286           1 :     CPPUNIT_ASSERT_THROW(compute_string("3", "3"), libexpr::invalid_type); // 3 is a long, not a string
     287           1 :     CPPUNIT_ASSERT_THROW(compute_string("4.5", "4.5"), libexpr::invalid_type); // 4.5 is a float, not a string
     288           1 : }
     289             : 
     290           1 : void ExprUnitTests::additions()
     291             : {
     292             : #if defined( __GNUC__ )
     293             : #   pragma GCC diagnostic push
     294             : #   pragma GCC diagnostic ignored "-Wsign-compare"
     295             : #endif
     296             :     // integers
     297           1 :     ASSERT_LONG_OPERATION(3 + 7 + 2 + 0X8f);
     298           1 :     ASSERT_LONG_OPERATION(90 - 45 + 33 + 0xC1);
     299           1 :     ASSERT_LONG_OPERATION(-45 + 33 - 193 + 34 + 1000 + 3276 - 9);
     300           1 :     ASSERT_LONG_OPERATION(3 + 7 - +0 + 2 + 0XFABCD899);
     301           1 :     ASSERT_LONG_OPERATION(-3 + +7 - +0 + -2 + +0XFABCD899);
     302             : 
     303             :     // characters (same as integers, just not the same value)
     304           1 :     ASSERT_LONG_OPERATION(3 + '7' - 0 + 2 + 0XFABCD899 - 'a');
     305             : #if defined( __GNUC__ )
     306             : #   pragma GCC diagnostic pop
     307             : #endif
     308             : 
     309             :     // floating points
     310           1 :     ASSERT_DOUBLE_OPERATION(3.3 + 7.1 - 0.9 + 2.2 + 123.001);
     311           1 :     ASSERT_DOUBLE_OPERATION(.33e1 + .71e+1 - 9.E-1 + .22E1 + 123001.0e-3 );
     312           1 :     ASSERT_DOUBLE_OPERATION(+.33e1 + -.71e+1 - -9.E-1 + +.22E1 + -123001.0e-3 );
     313           1 :     ASSERT_DOUBLE_OPERATION(-3.99 - +43 - +0.0 + -2 + +0XD899);
     314             : 
     315             :     // test newlines and carriage returns
     316             :     // although at this point we cannot check the f_line (not accessible)
     317           1 :     CPPUNIT_ASSERT(compute_double("3.5\n*\r\n7.2", 3.5 * 7.2));
     318           1 :     CPPUNIT_ASSERT(compute_double("13.5 // this is an approximation\n+\r\n /* multiplye is * but we use + here and luckily we found this number: */ 7.05", 13.5 + 7.05));
     319             : 
     320             :     // string concatenation
     321           1 :     CPPUNIT_ASSERT(compute_string("\"this\" + \"that\"", "thisthat"));
     322           1 :     CPPUNIT_ASSERT(compute_string("\"\\x74hi\\163\\7\" + \".\\40.\" + \"that\\x07\"", "this\a. .that\a"));
     323           1 :     CPPUNIT_ASSERT(compute_string("\"escapes: \\a\\b\\e\\f\" + \"\\n\\r\\t\\v\\?\"", "escapes: \a\b\33\f\n\r\t\v\?"));
     324           1 :     CPPUNIT_ASSERT(compute_string("\"\\xaa\\XFF\\XFQ\" + \"\\xBe\\xDc\" \"auto-concat\";;;", "\xaa\xff\xfQ\xbe\xdc" "auto-concat"));
     325           1 :     CPPUNIT_ASSERT(compute_string("\"this\" + 3", "this3"));
     326           1 :     CPPUNIT_ASSERT(compute_string("3 + \"this\"", "3this"));
     327           1 :     CPPUNIT_ASSERT(compute_string("3 + \"this\" + 3", "3this3"));
     328           1 :     CPPUNIT_ASSERT(compute_string("3.35 + \"this\" + 3.35", "3.35this3.35"));
     329           1 : }
     330             : 
     331           1 : void ExprUnitTests::shifts()
     332             : {
     333           1 :     ASSERT_LONG_OPERATION(1 << 0xD);
     334           1 :     ASSERT_LONG_OPERATION(0x8000 >> 05);
     335           1 :     ASSERT_LONG_OPERATION(1 << 2 << 3 << 4);
     336             : 
     337           1 :     ASSERT_LONG_OPERATION(0x3000 << 7 + 2 >> 1);
     338           1 :     ASSERT_LONG_OPERATION(0x3000 << 7 - 2 >> 1);
     339           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 * 3 << 1);
     340           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 % 3 << 1);
     341           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 / 3 << 1);
     342             : 
     343           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 == 3 << 1);
     344           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 != 3 << 1);
     345           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 > 3 << 1);
     346           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 >= 3 << 1);
     347           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 < 3 << 1);
     348           1 :     ASSERT_LONG_OPERATION(0x3000 >> 7 <= 3 << 1);
     349             : 
     350           1 :     ASSERT_LONG_OPERATION(((0x3000 >> 7) | (0x3000 << 7)) & 0xFFFF);
     351           1 : }
     352             : 
     353           1 : void ExprUnitTests::increments() // postfix/prefix
     354             : {
     355             :     // note that we support multiple ++ and -- in a row, but that
     356             :     // is not valid C++ (i.e. a++++ is not valid because the second
     357             :     // ++ would otherwise be applied to the result of a++ which is
     358             :     // not an lvalue.)
     359             :     long a, _a;
     360           1 :     ASSERT_LONG_OPERATION((a = 3, a++));
     361           1 :     ASSERT_LONG_OPERATION((a = 3, a++, a));
     362           1 :     ASSERT_LONG_OPERATION((a = 78, a--));
     363           1 :     ASSERT_LONG_OPERATION((a = 78, a--, a));
     364           1 :     ASSERT_LONG_OPERATION((a = 234, ++a));
     365           1 :     ASSERT_LONG_OPERATION((a = 234, ++a, a));
     366           1 :     ASSERT_LONG_OPERATION((a = 934, --a));
     367           1 :     ASSERT_LONG_OPERATION((_a = 934, --_a, _a));
     368           1 : }
     369             : 
     370           1 : void ExprUnitTests::multiplications()
     371             : {
     372             :     // integer operations
     373           1 :     ASSERT_LONG_OPERATION(3 + 7 + 2 * 143);
     374           1 :     ASSERT_LONG_OPERATION(-90 * 45 + 33 + 193);
     375           1 :     ASSERT_LONG_OPERATION(0x3002 + 1 + 45 + 33 * 193);
     376           1 :     ASSERT_LONG_OPERATION(3702 / 9 + 45 * 7 + 33 / 193 + 30491 / 129 / 2);
     377           1 :     ASSERT_LONG_OPERATION(7 + 3 + 5 + 9 / 0x2);
     378           1 :     ASSERT_LONG_OPERATION(111 + 7 + 3 + 5 + 0x09 * 2 - 003);
     379           1 :     ASSERT_LONG_OPERATION(56 + 7 + 3 + 05 + 9 % 2 + 34);
     380           1 :     ASSERT_LONG_OPERATION(3 + 7 + 3804 % 5 + 9 % 2 * 13 % 27);
     381             : 
     382             :     // some floating point operations
     383           1 :     ASSERT_DOUBLE_OPERATION(3 * 1.34e0 + 1);
     384           1 :     ASSERT_DOUBLE_OPERATION(3.34 * 34 + 24);
     385           1 :     ASSERT_DOUBLE_OPERATION(3.34e-0 * 34 + 24);
     386           1 :     ASSERT_DOUBLE_OPERATION(3 / 1.34e0 + 1);
     387           1 :     ASSERT_DOUBLE_OPERATION(3.34 / 34 + 24);
     388           1 :     ASSERT_DOUBLE_OPERATION(3.34e-0 / 34 + 24);
     389           1 :     ASSERT_DOUBLE_OPERATION(3 * 34 / 2.4);
     390           1 :     ASSERT_DOUBLE_OPERATION(3 * 34 + 2.4);
     391           1 :     ASSERT_DOUBLE_OPERATION(3 * 34 - 2.4);
     392           1 : }
     393             : 
     394           1 : void ExprUnitTests::bitwise()
     395             : {
     396           1 :     ASSERT_LONG_OPERATION(3 | +4);
     397           1 :     ASSERT_LONG_OPERATION(255 & -4);
     398           1 :     ASSERT_LONG_OPERATION(0xAA^0x55);
     399             : 
     400           1 :     ASSERT_LONG_OPERATION(~3 | +4);
     401           1 :     ASSERT_LONG_OPERATION(255 & ~-4);
     402           1 :     ASSERT_LONG_OPERATION(0xAA^~0x55);
     403             : 
     404           1 :     ASSERT_LONG_OPERATION(3 | ~4);
     405           1 :     ASSERT_LONG_OPERATION(~255 & -4);
     406           1 :     ASSERT_LONG_OPERATION(~0xAA^0x55);
     407             : 
     408           1 :     ASSERT_LONG_OPERATION(~3 | ~4);
     409           1 :     ASSERT_LONG_OPERATION(~255 & ~-4);
     410           1 :     ASSERT_LONG_OPERATION(~0xAA^~0x55);
     411             : 
     412             :     // priority stuff
     413           1 :     ASSERT_LONG_OPERATION('a' ^ 0x55 | 071 & 0xEF);
     414           1 :     ASSERT_LONG_OPERATION('a' ^ 0x55 & 071 | 0xEF);
     415           1 :     ASSERT_LONG_OPERATION('a' | 0x55 & 071 ^ 0xEF);
     416           1 :     ASSERT_LONG_OPERATION('a' | 0x55 ^ 071 & 0xEF);
     417           1 :     ASSERT_LONG_OPERATION('a' & 0x55 ^ 071 | 0xEF);
     418           1 :     ASSERT_LONG_OPERATION('a' & 0x55 | 071 ^ 0xEF);
     419           1 : }
     420             : 
     421           1 : void ExprUnitTests::comparisons()
     422             : {
     423             :     // integers
     424           1 :     ASSERT_LONG_OPERATION(7 != 9);
     425           1 :     ASSERT_LONG_OPERATION(132817291 == 132817291);
     426           1 :     ASSERT_LONG_OPERATION(!(132817291 == 13281729));
     427           1 :     ASSERT_LONG_OPERATION(3 * 7 < 9 * 47);
     428           1 :     ASSERT_LONG_OPERATION(3 * 7 < 9 * 47 < true);
     429           1 :     ASSERT_LONG_OPERATION(9 * 47 < 3 * 7);
     430           1 :     ASSERT_LONG_OPERATION(3 * 7 <= 9 * 47);
     431           1 :     ASSERT_LONG_OPERATION(9 * 47 <= 3 * 7);
     432           1 :     ASSERT_LONG_OPERATION(3 * 7 < 9 * 47 <= false);
     433           1 :     ASSERT_LONG_OPERATION(3 * 7 > 9 * 47);
     434           1 :     ASSERT_LONG_OPERATION(9 * 47 > 3 * 7);
     435           1 :     ASSERT_LONG_OPERATION(3 * 7 >= 9 * 47);
     436           1 :     ASSERT_LONG_OPERATION(9 * 47 >= 3 * 7);
     437           1 :     ASSERT_LONG_OPERATION(9 * 47 >= 3 * 7 < true);
     438           1 :     ASSERT_LONG_OPERATION(9 * 47 >= 3 * 7 <= true);
     439           1 :     ASSERT_LONG_OPERATION(9 * 47 >= 3 * 7 < false);
     440           1 :     ASSERT_LONG_OPERATION(9 * 47 >= 3 * 7 <= false);
     441             : 
     442             :     // floating point
     443           1 :     ASSERT_LONG_OPERATION(9.01 * 47 == 3.1 * 7);
     444           1 :     ASSERT_LONG_OPERATION(9 * 47.1 == 3 * 7.2222);
     445           1 :     ASSERT_LONG_OPERATION(9.2 * 47 != 3.1 * 7);
     446           1 :     ASSERT_LONG_OPERATION(9 * 47.1 != 3 * 7.111);
     447           1 :     ASSERT_LONG_OPERATION(9.01 * 47 > 3.1 * 7);
     448           1 :     ASSERT_LONG_OPERATION(9 * 47.1 > 3 * 7.2222);
     449           1 :     ASSERT_LONG_OPERATION(9.2 * 47 >= 3.1 * 7);
     450           1 :     ASSERT_LONG_OPERATION(9 * 47.1 >= 3 * 7.111);
     451           1 :     ASSERT_LONG_OPERATION(9.3 * 47 < 3.1 * 7);
     452           1 :     ASSERT_LONG_OPERATION(9 * 47.1 < 3 * 7);
     453           1 :     ASSERT_LONG_OPERATION(9.3 * 47 <= 3.1 * 7.0102);
     454           1 :     ASSERT_LONG_OPERATION(9 * 47.1 <= 3 * 7);
     455             : 
     456           1 :     ASSERT_LONG_OPERATION(9 * 47 == 3.1 * 7);
     457           1 :     ASSERT_LONG_OPERATION(9 * 47.1 == 3 * 7);
     458           1 :     ASSERT_LONG_OPERATION(9 * 47 != 3.1 * 7);
     459           1 :     ASSERT_LONG_OPERATION(9 * 47.1 != 3 * 7);
     460           1 :     ASSERT_LONG_OPERATION(9 * 47 > 3.1 * 7);
     461           1 :     ASSERT_LONG_OPERATION(9 * 47.1 > 3 * 7);
     462           1 :     ASSERT_LONG_OPERATION(9 * 47 >= 3.1 * 7);
     463           1 :     ASSERT_LONG_OPERATION(9 * 47.1 >= 3 * 7);
     464           1 :     ASSERT_LONG_OPERATION(9 * 47 < 3.1 * 7);
     465           1 :     ASSERT_LONG_OPERATION(9 * 47.1 < 3 * 7);
     466           1 :     ASSERT_LONG_OPERATION(9 * 47 <= 3.1 * 7);
     467           1 :     ASSERT_LONG_OPERATION(9 * 47.1 <= 3 * 7);
     468             : 
     469             :     // string
     470           1 :     CPPUNIT_ASSERT(compute_long("\"this\" == \"th\" \"is\"") == true);
     471           1 :     CPPUNIT_ASSERT(compute_long("\"th\" + \"is\" == \"th\" \"is\"") == true);
     472           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47\" == \"3.1 * 7\"") == false);
     473           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47.1\" == \"3 * 7\"") == false);
     474           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47\" != \"3.1 * 7\"") == true);
     475           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47.1\" != \"3 * 7\"") == true);
     476           1 :     CPPUNIT_ASSERT(compute_long("\"th\" + \"is\" != \"th\" \"is\"") == false);
     477           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47\" > \"3.1 * 7\"") == true);
     478           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47.1\" > \"3 * 7\"") == true);
     479           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47\" >= \"3.1 * 7\"") == true);
     480           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47.1\" >= \"3 * 7\"") == true);
     481           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47\" < \"3.1 * 7\"") == false);
     482           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47.1\" < \"3 * 7\"") == false);
     483           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47\" <= \"3.1 * 7\"") == false);
     484           1 :     CPPUNIT_ASSERT(compute_long("\"9 * 47.1\" <= \"3 * 7\"") == false);
     485             : 
     486             :     {
     487             :     // proves we can redefine e along the way
     488             :     long a, b, c, d, e, f;
     489           1 :     ASSERT_LONG_OPERATION((a = 9, b = 47, c = 3, d = 7, e = 33, f = 45, a * b >= c * d && e > f));
     490           1 :     ASSERT_LONG_OPERATION((a = 888, a = 333, b = 123, c = 00003, d = 0x7AFE, ++b, e = '\33', e++, f = 9945, c -= 32, a * b >= c * d || e > f));
     491             :     }
     492             : 
     493             :     // check the not
     494           1 :     ASSERT_LONG_OPERATION(!0);
     495           1 :     ASSERT_LONG_OPERATION(!7);
     496           1 :     ASSERT_LONG_OPERATION(!-7);
     497           1 :     CPPUNIT_ASSERT(compute_long("!\"\"") == true);  // we return true but C++ says false here!
     498           1 :     ASSERT_LONG_OPERATION(!"not empty");
     499           1 :     ASSERT_LONG_OPERATION(!3.5);
     500           1 :     ASSERT_LONG_OPERATION(!-3.5);
     501           1 :     ASSERT_LONG_OPERATION(!0.0);
     502             : 
     503             :     // test our addition (^^)
     504           1 :     CPPUNIT_ASSERT(compute_long("true ^^ true") == false);
     505           1 :     CPPUNIT_ASSERT(compute_long("true ^^ false") == true);
     506           1 :     CPPUNIT_ASSERT(compute_long("false ^^ true") == true);
     507           1 :     CPPUNIT_ASSERT(compute_long("false ^^ false") == false);
     508           1 :     CPPUNIT_ASSERT(compute_long("3 ^^ 3.3") == false);
     509           1 :     CPPUNIT_ASSERT(compute_long("3 ^^ \"\"") == true);
     510           1 :     CPPUNIT_ASSERT(compute_long("3.3 ^^ 3") == false);
     511           1 :     CPPUNIT_ASSERT(compute_long("3.3 ^^ \"\"") == true);
     512           1 :     CPPUNIT_ASSERT(compute_long("\"\" ^^ 3") == true);
     513           1 :     CPPUNIT_ASSERT(compute_long("\"\" ^^ 5.4") == true);
     514             : 
     515           1 :     CPPUNIT_ASSERT(compute_long("true && true ^^ true && true") == false);
     516           1 :     CPPUNIT_ASSERT(compute_long("true && true ^^ true && false") == true);
     517           1 :     CPPUNIT_ASSERT(compute_long("true && false ^^ true && true") == true);
     518           1 :     CPPUNIT_ASSERT(compute_long("true && true ^^ false && true") == true);
     519           1 :     CPPUNIT_ASSERT(compute_long("false && true ^^ true && true") == true);
     520           1 :     CPPUNIT_ASSERT(compute_long("true && false ^^ true && false") == false);
     521           1 :     CPPUNIT_ASSERT(compute_long("false && false ^^ true && false") == false);
     522             : 
     523             :     // some priority checks
     524           1 :     ASSERT_LONG_OPERATION(true && true || true);
     525           1 :     ASSERT_LONG_OPERATION(true && true || false);
     526           1 :     ASSERT_LONG_OPERATION(false && true || false);
     527           1 :     ASSERT_LONG_OPERATION(false && false || false);
     528           1 :     ASSERT_LONG_OPERATION(false && true || true);
     529           1 :     ASSERT_LONG_OPERATION(false && false || true);
     530             : 
     531           1 :     ASSERT_LONG_OPERATION(true && true == true || true);
     532           1 :     ASSERT_LONG_OPERATION(true && false == true || false);
     533           1 :     ASSERT_LONG_OPERATION(false && true == false || true);
     534           1 :     ASSERT_LONG_OPERATION(false && false == false || false);
     535             : 
     536           1 :     ASSERT_LONG_OPERATION(true && true != true || true);
     537           1 :     ASSERT_LONG_OPERATION(true && false != true || false);
     538           1 :     ASSERT_LONG_OPERATION(false && true != false || true);
     539           1 :     ASSERT_LONG_OPERATION(false && false != false || false);
     540             : 
     541             :     // operations on other types
     542           1 :     ASSERT_LONG_OPERATION(33 && 35);
     543           1 :     ASSERT_LONG_OPERATION(33 && 3.5);
     544           1 :     ASSERT_LONG_OPERATION(5.5 && 35);
     545           1 :     ASSERT_LONG_OPERATION(5.5 && "35");
     546           1 :     ASSERT_LONG_OPERATION("35" && 5.5);
     547           1 :     CPPUNIT_ASSERT(compute_long("\"\" && 5.4") == false);
     548           1 :     CPPUNIT_ASSERT(compute_long("5.4 && \"\"") == false);
     549           1 :     ASSERT_LONG_OPERATION(33 || 35);
     550           1 :     ASSERT_LONG_OPERATION(33 || 3.5);
     551           1 :     ASSERT_LONG_OPERATION(5.5 || 35);
     552           1 :     ASSERT_LONG_OPERATION(5.5 || "35");
     553           1 :     ASSERT_LONG_OPERATION("35" || 5.5);
     554           1 :     CPPUNIT_ASSERT(compute_long("\"\" || 5.4") == true);
     555           1 :     CPPUNIT_ASSERT(compute_long("5.4 || \"\"") == true);
     556             : 
     557             :     // conditional
     558             :     {
     559             :     long a, b, c, d;
     560           1 :     ASSERT_LONG_OPERATION((a = 34, b = 123, 3 > 9 ? a : b));
     561           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 23, c = -33, d = 55, c < d ? a : b));
     562             :     }
     563           1 : }
     564             : 
     565           1 : void ExprUnitTests::assignments()
     566             : {
     567             :     long a, b;
     568           1 :     ASSERT_LONG_OPERATION((a = 9444, b = a, b + 3));
     569           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a *= b));
     570           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a *= b, a));
     571           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a *= b, b));
     572           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a /= b));
     573           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a /= b, a));
     574           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a /= b, b));
     575           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a %= b));
     576           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a %= b, a));
     577           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a %= b, b));
     578           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a += b));
     579           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a += b, a));
     580           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a += b, b));
     581           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a -= b));
     582           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a -= b, a));
     583           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a -= b, b));
     584             :     // WARNING: large shifts do not give us the same results under Linux & Windows...
     585             :     //          (it looks like MS-Windows, even in 64 bits, may apply an AND 0x1F?)
     586           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 29, a <<= b));
     587           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 29, a <<= b, a));
     588           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 29, a <<= b, b));
     589           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4, a >>= b));
     590           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4, a >>= b, a));
     591           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4, a >>= b, b));
     592           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a &= b));
     593           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a &= b, a));
     594           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a &= b, b));
     595           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a ^= b));
     596           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a ^= b, a));
     597           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a ^= b, b));
     598           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a |= b));
     599           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a |= b, a));
     600           1 :     ASSERT_LONG_OPERATION((a = 9444, b = 4531, a |= b, b));
     601           1 : }
     602             : 
     603           1 : void ExprUnitTests::functions()
     604             : {
     605           1 :     double a, b, pi(3.14159265358979323846), e(2.7182818284590452354);
     606             :     const char *s;
     607             : 
     608             :     // acos
     609           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, acos(a)));
     610           1 :     ASSERT_DOUBLE_OPERATION((a = 0.03, acos(a)));
     611           1 :     ASSERT_DOUBLE_OPERATION((a = 0.123, acos(a)));
     612           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, acos(a)));
     613             : 
     614             :     // acosh
     615           1 :     ASSERT_DOUBLE_OPERATION((a = 1.0, acosh(a)));
     616           1 :     ASSERT_DOUBLE_OPERATION((a = pi, acosh(a)));
     617           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, acosh(a)));
     618           1 :     ASSERT_DOUBLE_OPERATION((a = 2.45, acosh(a)));
     619             : 
     620             :     // asin
     621           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, asin(a)));
     622           1 :     ASSERT_DOUBLE_OPERATION((a = 0.03, asin(a)));
     623           1 :     ASSERT_DOUBLE_OPERATION((a = 0.123, asin(a)));
     624           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, asin(a)));
     625             : 
     626             :     // asinh
     627           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, asinh(a)));
     628           1 :     ASSERT_DOUBLE_OPERATION((a = pi, asinh(a)));
     629           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, asinh(a)));
     630           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, asinh(a)));
     631             : 
     632             :     // atan
     633           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, atan(a)));
     634           1 :     ASSERT_DOUBLE_OPERATION((a = pi, atan(a)));
     635           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, atan(a)));
     636           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, atan(a)));
     637             : 
     638             :     // atan2
     639           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, b = 0.0, atan2(a, b)));
     640           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, b = 0.0, atan2(a, b)));
     641           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, b = 10.0, atan2(a, b)));
     642           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, b = 10.0, atan2(a, b)));
     643             : 
     644             :     // atanh
     645           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, atanh(a)));
     646           1 :     ASSERT_DOUBLE_OPERATION((a = 0.999, atanh(a)));
     647           1 :     ASSERT_DOUBLE_OPERATION((a = 0.5, atanh(a)));
     648           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, atanh(a)));
     649             : 
     650             :     // ceil
     651           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, ceil(a)));
     652           1 :     ASSERT_DOUBLE_OPERATION((a = 3.245, ceil(a)));
     653           1 :     ASSERT_DOUBLE_OPERATION((a = -3.245, ceil(a)));
     654           1 :     ASSERT_DOUBLE_OPERATION((a = 3.6245, ceil(a)));
     655           1 :     ASSERT_DOUBLE_OPERATION((a = -3.6245, ceil(a)));
     656           1 :     ASSERT_DOUBLE_OPERATION((a = 3.5, ceil(a)));
     657           1 :     ASSERT_DOUBLE_OPERATION((a = -3.5, ceil(a)));
     658             : 
     659             :     // cos
     660           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, cos(a)));
     661           1 :     ASSERT_DOUBLE_OPERATION((a = pi, cos(a)));
     662           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, cos(a)));
     663           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, cos(a)));
     664             : 
     665             :     // cosh
     666           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, cosh(a)));
     667           1 :     ASSERT_DOUBLE_OPERATION((a = pi, cosh(a)));
     668           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, cosh(a)));
     669           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, cosh(a)));
     670             : 
     671             :     // ctime
     672           1 :         time_t the_time(1234123412);
     673           1 :     std::string the_ctime(ctime(&the_time));
     674           1 :     std::string::size_type p(the_ctime.find_first_of("\r\n"));
     675           1 :     if(p != std::string::npos)
     676             :     {
     677           1 :         the_ctime = the_ctime.substr(0, p);
     678             :     }
     679           1 :     CPPUNIT_ASSERT(compute_string("a = 1234123412, ctime(a)", the_ctime.c_str()));
     680             : 
     681             :     // exp
     682           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, exp(a)));
     683           1 :     ASSERT_DOUBLE_OPERATION((a = e, exp(a)));
     684           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, exp(a)));
     685             : 
     686             :     // fabs
     687           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, fabs(a)));
     688           1 :     ASSERT_DOUBLE_OPERATION((a = -0.0, fabs(a)));
     689           1 :     ASSERT_DOUBLE_OPERATION((a = e, fabs(a)));
     690           1 :     ASSERT_DOUBLE_OPERATION((a = -pi, fabs(a)));
     691             : 
     692             :     // floor
     693           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, floor(a)));
     694           1 :     ASSERT_DOUBLE_OPERATION((a = 3.245, floor(a)));
     695           1 :     ASSERT_DOUBLE_OPERATION((a = -3.245, floor(a)));
     696           1 :     ASSERT_DOUBLE_OPERATION((a = 3.6245, floor(a)));
     697           1 :     ASSERT_DOUBLE_OPERATION((a = -3.6245, floor(a)));
     698           1 :     ASSERT_DOUBLE_OPERATION((a = 3.5, floor(a)));
     699           1 :     ASSERT_DOUBLE_OPERATION((a = -3.5, floor(a)));
     700             : 
     701             :     // fmod
     702           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, b = 3.0, fmod(a, b)));
     703           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, b = 3.0, fmod(a, b)));
     704           1 :     ASSERT_DOUBLE_OPERATION((a = e * 45, b = 3.0, fmod(a, b)));
     705           1 :     ASSERT_DOUBLE_OPERATION((a = pi * 143.4, b = 3.0, fmod(a, b)));
     706             : 
     707             :     // log
     708           1 :     ASSERT_DOUBLE_OPERATION((a = 0.00001, log(a)));
     709           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, log(a)));
     710           1 :     ASSERT_DOUBLE_OPERATION((a = e * 45, log(a)));
     711           1 :     ASSERT_DOUBLE_OPERATION((a = pi * 143.4, log(a)));
     712             : 
     713             :     // log10
     714           1 :     ASSERT_DOUBLE_OPERATION((a = 0.00005, log10(a)));
     715           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, log10(a)));
     716           1 :     ASSERT_DOUBLE_OPERATION((a = e * 45, log10(a)));
     717           1 :     ASSERT_DOUBLE_OPERATION((a = pi * 143.4, log10(a)));
     718             : 
     719             :     // lrint
     720           1 :     ASSERT_LONG_OPERATION((a = 9444.32, lrint(a)));
     721           1 :     ASSERT_LONG_OPERATION((a = -744.66, lrint(a)));
     722             : 
     723             :     // pow
     724           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, b = 3.0, pow(a, b)));
     725           1 :     ASSERT_DOUBLE_OPERATION((a = 10.0, b = 0.0, pow(a, b)));
     726           1 :     ASSERT_DOUBLE_OPERATION((a = e * 45, b = 7.0, pow(a, b)));
     727           1 :     ASSERT_DOUBLE_OPERATION((a = pi * 143.4, b = 23.0, pow(a, b)));
     728             : 
     729             :     // rint
     730           1 :     ASSERT_DOUBLE_OPERATION((a = 9444.32, rint(a)));
     731           1 :     ASSERT_DOUBLE_OPERATION((a = -744.66, rint(a)));
     732             : 
     733             : #if !defined(WINDOWS) && !defined(_WINDOWS)
     734             :     // shell true and false are inverted!
     735           1 :     CPPUNIT_ASSERT(compute_long("shell( \"true\" , \"exitcode\" )") == 0);
     736           1 :     CPPUNIT_ASSERT(compute_long("shell(\"false\", \"exitcode\")") == 256);
     737           1 :     CPPUNIT_ASSERT(compute_string("shell(\"echo true\", \"output\")", "true\n"));
     738           1 :     CPPUNIT_ASSERT(compute_string("shell(\"echo true\")", "true\n"));
     739             : #endif
     740             : 
     741             :     // sin
     742           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, sin(a)));
     743           1 :     ASSERT_DOUBLE_OPERATION((a = pi, sin(a)));
     744           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, sin(a)));
     745           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, sin(a)));
     746             : 
     747             :     // sinh
     748           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, sinh(a)));
     749           1 :     ASSERT_DOUBLE_OPERATION((a = pi, sinh(a)));
     750           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, sinh(a)));
     751           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, sinh(a)));
     752             : 
     753             :     // sqrt
     754           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, sqrt(a)));
     755           1 :     ASSERT_DOUBLE_OPERATION((a = pi, sqrt(a)));
     756           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, sqrt(a)));
     757           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, sqrt(a)));
     758             : 
     759             : #if defined( __GNUC__ )
     760             : #   pragma GCC diagnostic push
     761             : #   pragma GCC diagnostic ignored "-Wsign-compare"
     762             : #endif
     763             :     // strlen
     764             :     // DO NOT USE static_cast<>() for the strlen(), add -W... on the command line in CMakeLists.txt to turn off those warnings
     765           1 :     ASSERT_LONG_OPERATION((s = "9444.32", strlen(s)));
     766           1 :     ASSERT_LONG_OPERATION((s = "", strlen(s)));
     767           1 :     ASSERT_LONG_OPERATION((s = "con" "cat", (strlen(s))));
     768             : #if defined( __GNUC__ )
     769             : #   pragma GCC diagnostic pop
     770             : #endif
     771             : 
     772             :     // tan
     773           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, tan(a)));
     774           1 :     ASSERT_DOUBLE_OPERATION((a = pi, tan(a)));
     775           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, tan(a)));
     776           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, tan(a)));
     777             : 
     778             :     // tanh
     779           1 :     ASSERT_DOUBLE_OPERATION((a = 0.0, tanh(a)));
     780           1 :     ASSERT_DOUBLE_OPERATION((a = pi, tanh(a)));
     781           1 :     ASSERT_DOUBLE_OPERATION((a = pi / 2.0, tanh(a)));
     782           1 :     ASSERT_DOUBLE_OPERATION((a = 0.245, tanh(a)));
     783             : 
     784             :     // time
     785           1 :     time_t now(time(NULL));
     786           1 :     time_t expr_now(compute_long("time()"));
     787           1 :     CPPUNIT_ASSERT((expr_now - now) <= 1);
     788           1 : }
     789             : 
     790           1 : void ExprUnitTests::misc()
     791             : {
     792           1 :     libexpr::variable v, undefined, result;
     793           1 :     std::string str;
     794           1 :     undefined.to_string(str);
     795           1 :     CPPUNIT_ASSERT(str == "undefined");
     796             : 
     797           1 :     v.set(128394L);
     798           1 :     CPPUNIT_ASSERT_THROW(result.add(v, undefined), libexpr::incompatible_type);
     799           1 :     v.set(128.394);
     800           1 :     CPPUNIT_ASSERT_THROW(result.add(v, undefined), libexpr::incompatible_type);
     801           1 :     v.set("128394");
     802           1 :     CPPUNIT_ASSERT_THROW(result.add(v, undefined), libexpr::incompatible_type);
     803           1 :     CPPUNIT_ASSERT_THROW(result.add(undefined, v), libexpr::incompatible_type);
     804           1 :     CPPUNIT_ASSERT_THROW(result.lt(undefined, v), libexpr::incompatible_type);
     805           1 :     CPPUNIT_ASSERT_THROW(result.lt(v, undefined), libexpr::incompatible_type);
     806           1 :     CPPUNIT_ASSERT_THROW(result.le(undefined, v), libexpr::incompatible_type);
     807           1 :     CPPUNIT_ASSERT_THROW(result.le(v, undefined), libexpr::incompatible_type);
     808           1 :     CPPUNIT_ASSERT_THROW(result.gt(undefined, v), libexpr::incompatible_type);
     809           1 :     CPPUNIT_ASSERT_THROW(result.gt(v, undefined), libexpr::incompatible_type);
     810           1 :     CPPUNIT_ASSERT_THROW(result.ge(undefined, v), libexpr::incompatible_type);
     811           1 :     CPPUNIT_ASSERT_THROW(result.ge(v, undefined), libexpr::incompatible_type);
     812           1 :     CPPUNIT_ASSERT_THROW(result.eq(undefined, v), libexpr::incompatible_type);
     813           1 :     CPPUNIT_ASSERT_THROW(result.eq(v, undefined), libexpr::incompatible_type);
     814           1 :     CPPUNIT_ASSERT_THROW(result.ne(undefined, v), libexpr::incompatible_type);
     815           1 :     CPPUNIT_ASSERT_THROW(result.ne(v, undefined), libexpr::incompatible_type);
     816           1 :     CPPUNIT_ASSERT_THROW(result.logic_and(undefined, v), libexpr::incompatible_type);
     817           1 :     CPPUNIT_ASSERT_THROW(result.logic_and(v, undefined), libexpr::incompatible_type);
     818           1 :     CPPUNIT_ASSERT_THROW(result.logic_or(undefined, v), libexpr::incompatible_type);
     819           1 :     CPPUNIT_ASSERT_THROW(result.logic_or(v, undefined), libexpr::incompatible_type);
     820           1 :     CPPUNIT_ASSERT_THROW(result.logic_xor(undefined, v), libexpr::incompatible_type);
     821           1 :     CPPUNIT_ASSERT_THROW(result.logic_xor(v, undefined), libexpr::incompatible_type);
     822           1 :     CPPUNIT_ASSERT_THROW(result.logic_not(undefined), libexpr::incompatible_type);
     823             : 
     824           1 :     v.set(std::string("string"));
     825           1 :     v.to_string(str);
     826           1 :     CPPUNIT_ASSERT(str == "string");
     827           1 :     v.set(5.509);
     828           1 :     v.to_string(str);
     829           1 :     CPPUNIT_ASSERT(str == "5.509");
     830           1 :     v.set("string");
     831           1 :     v.to_string(str);
     832           1 :     CPPUNIT_ASSERT(str == "string");
     833           1 :     std::wstring wstr(L"wide-string");
     834           1 :     v.set(wstr);
     835           1 :     v.to_string(str);
     836           1 :     CPPUNIT_ASSERT(str == "wide-string");
     837           1 :     v.set(L"wc-string");
     838           1 :     v.to_string(str);
     839           1 :     CPPUNIT_ASSERT(str == "wc-string");
     840             : 
     841           4 : }
     842             : 
     843             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.9

The wpkg tool is an open source tool created by Made to Order Software Corporation.