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 - libexpr - variable.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 456 456 100.0 %
Date: 2013-06-17 Functions: 44 44 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*    variable -- a variable implementation
       2             :  *    Copyright (C) 2007-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             : #include        "libexpr/variable.h"
      22             : #include        "libutf8/libutf8.h"
      23             : #include        <cmath>
      24             : #include        <sstream>
      25             : #include        <iostream>
      26             : 
      27             : #ifndef M_PI
      28             : #define M_PI            3.14159265358979323846
      29             : #endif
      30             : #ifndef M_E
      31             : #define M_E             2.7182818284590452354
      32             : #endif
      33             : 
      34             : namespace libexpr
      35             : {
      36             : 
      37             : 
      38             : /** \brief Initializes a variable as undefined.
      39             :  *
      40             :  * This function initializes a variable and sets it to undefined.
      41             :  *
      42             :  * Use one of the set functions to change the value of a variable.
      43             :  * The variable::reset() functions resets the variable to undefined.
      44             :  */
      45        9142 : variable::variable()
      46             :         : f_type(TYPE_UNDEFINED),
      47             :           f_int(int()),
      48             :           f_flt(double()),
      49        9142 :           f_str(std::string())
      50             : {
      51        9142 : }
      52             : 
      53             : /** \brief Get the variable name.
      54             :  *
      55             :  * Variables that are given a name (i.e. an identifier) are given a
      56             :  * name using the set_name() function and the different expressions
      57             :  * that can handle a variable (++a, a = 5, etc.) can make use of
      58             :  * this name as appropriate.
      59             :  *
      60             :  * The main value is the content of the variable so in an expression
      61             :  * such as: a = b + c; the b and c variable values are used and their
      62             :  * names are ignored. The a variable is used and set as expected.
      63             :  *
      64             :  * \param[in] name  The name of this variable.
      65             :  *
      66             :  * \sa set_name()
      67             :  */
      68        1284 : std::string variable::get_name() const
      69             : {
      70        1284 :         return f_name;
      71             : }
      72             : 
      73             : /** \brief Set the variable name.
      74             :  *
      75             :  * This entry is used when encountering an identifier referencing
      76             :  * a variable. It's nmae is saved with the set_name() and can be
      77             :  * retrieved with the get_name() function.
      78             :  *
      79             :  * Values (direct integers, strings, floating point values) do not
      80             :  * receive a name.
      81             :  *
      82             :  * \return The name of this variable, may be empty.
      83             :  *
      84             :  * \sa get_name()
      85             :  */
      86        1507 : void variable::set_name(const std::string& name)
      87             : {
      88        1507 :         f_name = name;
      89        1507 : }
      90             : 
      91             : /** \brief Get the variable type.
      92             :  *
      93             :  * This function is used to determine the type of a variable.
      94             :  *
      95             :  * \return one of the variable::TYPE_... enumerations
      96             :  */
      97          40 : variable::type_t variable::type() const
      98             : {
      99          40 :         return f_type;
     100             : }
     101             : 
     102             : /** \brief Reset the variable to undefined.
     103             :  *
     104             :  * This function resets the variable type to variable::TYPE_UNDEFINED.
     105             :  */
     106        1599 : void variable::reset()
     107             : {
     108        1599 :         f_type = TYPE_UNDEFINED;
     109        1599 : }
     110             : 
     111             : /** \brief Set the variable to an integer value from a boolean value.
     112             :  *
     113             :  * This function changes the value of the variable and sets it to
     114             :  * a long value.
     115             :  *
     116             :  * This function as the side effect of changing the type of the
     117             :  * variable to variable::TYPE_INT.
     118             :  *
     119             :  * \param[in] value  The new boolean value of the variable.
     120             :  */
     121         224 : void variable::set(bool value)
     122             : {
     123         224 :         f_type = TYPE_INT;
     124         224 :         f_int = value ? 1L : 0L;
     125         224 : }
     126             : 
     127             : /** \brief Set the variable to an integer value.
     128             :  *
     129             :  * This function changes the value of the variable and sets it to
     130             :  * a long value.
     131             :  *
     132             :  * This function as the side effect of changing the type of the
     133             :  * variable to variable::TYPE_INT.
     134             :  *
     135             :  * \param[in] value  The new integer value of the variable.
     136             :  */
     137         996 : void variable::set(long value)
     138             : {
     139         996 :         f_type = TYPE_INT;
     140         996 :         f_int = value;
     141         996 : }
     142             : 
     143             : /** \brief Set the variable to a floating point value.
     144             :  *
     145             :  * This function changes the value of the variable and sets it to
     146             :  * a floating point value.
     147             :  *
     148             :  * This function as the side effect of changing the type of the
     149             :  * variable to variable::TYPE_FLT.
     150             :  *
     151             :  * \param[in] value  The new floating point value of the variable.
     152             :  */
     153         461 : void variable::set(double value)
     154             : {
     155         461 :         f_type = TYPE_FLT;
     156         461 :         f_flt = value;
     157         461 : }
     158             : 
     159             : /** \brief Set the variable to a string value.
     160             :  *
     161             :  * This function changes the value of the variable and sets it to
     162             :  * a string value.
     163             :  *
     164             :  * This function as the side effect of changing the type of the
     165             :  * variable to variable::TYPE_STR.
     166             :  *
     167             :  * \param[in] str  The new string value of the variable.
     168             :  */
     169         569 : void variable::set(const std::string& str)
     170             : {
     171         569 :         f_type = TYPE_STR;
     172         569 :         f_str = str;
     173         569 : }
     174             : 
     175             : /** \brief Set the variable to a string value.
     176             :  *
     177             :  * This function changes the value of the variable and sets it to
     178             :  * a string value.
     179             :  *
     180             :  * This function as the side effect of changing the type of the
     181             :  * variable to variable::TYPE_STR.
     182             :  *
     183             :  * \param[in] str  The new string value of the variable.
     184             :  */
     185           1 : void variable::set(const std::wstring& str)
     186             : {
     187           1 :         f_type = TYPE_STR;
     188           1 :         f_str = libutf8::wcstombs(str);
     189           1 : }
     190             : 
     191             : /** \brief Set the variable to a string value.
     192             :  *
     193             :  * This function changes the value of the variable and sets it to
     194             :  * a null terminated string value.
     195             :  *
     196             :  * This function as the side effect of changing the type of the
     197             :  * variable to variable::TYPE_STR.
     198             :  *
     199             :  * \param[in] str  The new string value of the variable.
     200             :  */
     201           2 : void variable::set(const char *str)
     202             : {
     203           2 :         f_type = TYPE_STR;
     204           2 :         f_str = str;
     205           2 : }
     206             : 
     207             : /** \brief Set the variable to a string value.
     208             :  *
     209             :  * This function changes the value of the variable and sets it to
     210             :  * a null terminated string value.
     211             :  *
     212             :  * This function as the side effect of changing the type of the
     213             :  * variable to variable::TYPE_STR.
     214             :  *
     215             :  * \param[in] str  The new string value of the variable.
     216             :  */
     217           1 : void variable::set(const wchar_t *str)
     218             : {
     219           1 :         f_type = TYPE_STR;
     220           1 :         f_str = libutf8::wcstombs(str);
     221           1 : }
     222             : 
     223             : /** \brief Get the integer value of the variable.
     224             :  *
     225             :  * This function is used to retrieve the integer value of the
     226             :  * variable.
     227             :  *
     228             :  * \bug
     229             :  * This function throws an error of type libexpr::invalid_type
     230             :  * if the variable is not current an integer.
     231             :  *
     232             :  * \param[out] value  The current value of the integer variable.
     233             :  */
     234         353 : void variable::get(long& value) const
     235             : {
     236         353 :         validate_type(TYPE_INT);
     237         351 :         value = f_int;
     238         351 : }
     239             : 
     240             : /** \brief Get the floating point value of the variable.
     241             :  *
     242             :  * This function is used to retrieve the floating point value of
     243             :  * the variable.
     244             :  *
     245             :  * \bug
     246             :  * This function throws an error of type libexpr::invalid_type
     247             :  * if the variable is not current a floating point.
     248             :  *
     249             :  * \param[out] value  The current value of the floating point variable.
     250             :  */
     251         221 : void variable::get(double& value) const
     252             : {
     253         221 :         validate_type(TYPE_FLT);
     254         219 :         value = f_flt;
     255         219 : }
     256             : 
     257             : /** \brief Get the string of the variable.
     258             :  *
     259             :  * This function is used to retrieve the string of
     260             :  * the variable.
     261             :  *
     262             :  * \bug
     263             :  * This function throws an error of type libexpr::invalid_type
     264             :  * if the variable is not current a string.
     265             :  *
     266             :  * \param[out] str  The current string of the variable.
     267             :  */
     268         167 : void variable::get(std::string& str) const
     269             : {
     270         167 :         validate_type(TYPE_STR);
     271         165 :         str = f_str;
     272         165 : }
     273             : 
     274             : /** \brief Get the content of the variable as a string.
     275             :  *
     276             :  * This function transforms the current content of the
     277             :  * variable into a string and returns that string.
     278             :  *
     279             :  * An undefined variable returns the word "undefined".
     280             :  * (which is indeed undistinguishable from the string
     281             :  * "undefined".)
     282             :  *
     283             :  * \param[out] str  The string representing the content of the variable.
     284             :  */
     285          12 : void variable::to_string(std::string& str) const
     286             : {
     287          12 :         std::stringstream out;
     288             : 
     289          12 :         switch(f_type) {
     290             :         case TYPE_UNDEFINED:
     291           1 :                 str = "undefined";
     292           1 :                 break;
     293             : 
     294             :         case TYPE_INT:
     295           4 :                 out << f_int;
     296           4 :                 str = out.str();
     297           4 :                 break;
     298             : 
     299             :         case TYPE_FLT:
     300           3 :                 out << f_flt;
     301           3 :                 str = out.str();
     302           3 :                 break;
     303             : 
     304             :         case TYPE_STR:
     305           4 :                 str = f_str;
     306           4 :                 break;
     307             : 
     308          12 :         }
     309          12 : }
     310             : 
     311             : /** \brief Internal function used to validate a typed request.
     312             :  *
     313             :  * This function checks that the type equals its parameter type.
     314             :  * If not, it throws a libexpr::invalid_type exception.
     315             :  *
     316             :  * \param[in] t        The type the variable needs to be defined as
     317             :  */
     318         741 : void variable::validate_type(type_t t) const
     319             : {
     320         741 :         if(f_type != t) {
     321           6 :                 throw invalid_type("type mismatch");
     322             :         }
     323         735 : }
     324             : 
     325             : /** \brief Negate the integer or floating point.
     326             :  *
     327             :  * This function negates the input integer or floating point
     328             :  * and saves the result in this variable.
     329             :  *
     330             :  * \bug
     331             :  * This function throws an incompatible_type exception
     332             :  * whenever this function is called with a value of
     333             :  * incompatible type.
     334             :  *
     335             :  * \param[in] v1        The value to negate
     336             :  */
     337          40 : void variable::neg(const variable& v1)
     338             : {
     339          40 :         switch(v1.type()) {
     340             :         case TYPE_INT:
     341          14 :                 set(-v1.f_int);
     342          14 :                 break;
     343             : 
     344             :         case TYPE_FLT:
     345          25 :                 set(-v1.f_flt);
     346          25 :                 break;
     347             : 
     348             :         default:
     349           1 :                 throw incompatible_type("type not supported by unary - operator");
     350             : 
     351             :         }
     352          39 : }
     353             : 
     354             : /** \brief Apply the unary + operator on an integer or floating point.
     355             :  *
     356             :  * This function "pluses" the input integer or floating point
     357             :  * and saves the result in this variable.
     358             :  *
     359             :  * \bug
     360             :  * This function throws an incompatible_type exception
     361             :  * whenever this function is called with a value of
     362             :  * incompatible type.
     363             :  *
     364             :  * \param[in] v1        The value to "pluses"
     365             :  */
     366          12 : void variable::pls(const variable& v1)
     367             : {
     368          12 :         switch(v1.f_type) {
     369             :         case TYPE_INT:
     370           8 :                 set(+v1.f_int);
     371           8 :                 break;
     372             : 
     373             :         case TYPE_FLT:
     374           3 :                 set(+v1.f_flt);
     375           3 :                 break;
     376             : 
     377             :         default:
     378           1 :                 throw incompatible_type("type not supported by unary + operator");
     379             : 
     380             :         }
     381          11 : }
     382             : 
     383             : /** \brief Multiply v1 by v2.
     384             :  *
     385             :  * This function multiplies the input integer or floating point
     386             :  * values and saves the result in this variable.
     387             :  *
     388             :  * \bug
     389             :  * This function throws an incompatible_type exception
     390             :  * whenever this function is called with a value of
     391             :  * incompatible type.
     392             :  *
     393             :  * \param[in] v1        The left handside
     394             :  * \param[in] v2        The right handside
     395             :  */
     396         108 : void variable::mul(const variable& v1, const variable& v2)
     397             : {
     398         108 :         switch(v1.f_type) {
     399             :         case TYPE_INT:
     400          77 :                 switch(v2.f_type) {
     401             :                 case TYPE_INT:
     402          59 :                         set(v1.f_int * v2.f_int);
     403          59 :                         break;
     404             : 
     405             :                 case TYPE_FLT:
     406          17 :                         set(v1.f_int * v2.f_flt);
     407          17 :                         break;
     408             : 
     409             :                 default:
     410           1 :                         throw incompatible_type("type not supported by * operator");
     411             : 
     412             :                 }
     413          76 :                 break;
     414             : 
     415             :         case TYPE_FLT:
     416          30 :                 switch(v2.f_type) {
     417             :                 case TYPE_INT:
     418          23 :                         set(v1.f_flt * v2.f_int);
     419          23 :                         break;
     420             : 
     421             :                 case TYPE_FLT:
     422           6 :                         set(v1.f_flt * v2.f_flt);
     423           6 :                         break;
     424             : 
     425             :                 default:
     426           1 :                         throw incompatible_type("type not supported by * operator");
     427             : 
     428             :                 }
     429          29 :                 break;
     430             : 
     431             :         default:
     432           1 :                 throw incompatible_type("type not supported by * operator");
     433             : 
     434             :         }
     435         105 : }
     436             : 
     437             : /** \brief Divide v1 by v2.
     438             :  *
     439             :  * This function divides the input integer or floating point
     440             :  * values and saves the result in this variable.
     441             :  *
     442             :  * \bug
     443             :  * This function throws an incompatible_type exception
     444             :  * whenever this function is called with a value of
     445             :  * incompatible type.
     446             :  *
     447             :  * \param[in] v1        The left handside
     448             :  * \param[in] v2        The right handside
     449             :  */
     450          26 : void variable::div(const variable& v1, const variable& v2)
     451             : {
     452          26 :         switch(v1.f_type) {
     453             :         case TYPE_INT:
     454          12 :                 switch(v2.f_type) {
     455             :                 case TYPE_INT:
     456           9 :                         set(v1.f_int / v2.f_int);
     457           9 :                         break;
     458             : 
     459             :                 case TYPE_FLT:
     460           2 :                         set(v1.f_int / v2.f_flt);
     461           2 :                         break;
     462             : 
     463             :                 default:
     464           1 :                         throw incompatible_type("type not supported by / operator");
     465             : 
     466             :                 }
     467          11 :                 break;
     468             : 
     469             :         case TYPE_FLT:
     470          13 :                 switch(v2.f_type) {
     471             :                 case TYPE_INT:
     472           2 :                         set(v1.f_flt / v2.f_int);
     473           2 :                         break;
     474             : 
     475             :                 case TYPE_FLT:
     476          10 :                         set(v1.f_flt / v2.f_flt);
     477          10 :                         break;
     478             : 
     479             :                 default:
     480           1 :                         throw incompatible_type("type not supported by / operator");
     481             : 
     482             :                 }
     483          12 :                 break;
     484             : 
     485             :         default:
     486           1 :                 throw incompatible_type("type not supported by / operator");
     487             : 
     488             :         }
     489          23 : }
     490             : 
     491             : /** \brief Computes v1 modulo v2.
     492             :  *
     493             :  * This function computes the module between the input integer or
     494             :  * floating point values and saves the result in this variable.
     495             :  *
     496             :  * \bug
     497             :  * This function throws an incompatible_type exception
     498             :  * whenever this function is called with a value of
     499             :  * incompatible type.
     500             :  *
     501             :  * \param[in] v1        The left handside
     502             :  * \param[in] v2        The right handside
     503             :  */
     504          13 : void variable::mod(const variable& v1, const variable& v2)
     505             : {
     506          13 :         switch(v1.f_type) {
     507             :         case TYPE_INT:
     508          10 :                 switch(v2.f_type) {
     509             :                 case TYPE_INT:
     510           8 :                         set(v1.f_int % v2.f_int);
     511           8 :                         break;
     512             : 
     513             :                 default:
     514           2 :                         throw incompatible_type("type not supported by %% operator");
     515             : 
     516             :                 }
     517           8 :                 break;
     518             : 
     519             :         default:
     520           3 :                 throw incompatible_type("type not supported by %% operator");
     521             : 
     522             :         }
     523           8 : }
     524             : 
     525             : /** \brief Add v1 to v2.
     526             :  *
     527             :  * This function adds the input integer or floating point values
     528             :  * and saves the result in this variable.
     529             :  *
     530             :  * This function concatenates the input if at least one of them
     531             :  * is a string then the other is converted to a string.
     532             :  *
     533             :  * \bug
     534             :  * This function throws an incompatible_type exception
     535             :  * whenever this function is called with a value of
     536             :  * incompatible type.
     537             :  *
     538             :  * \param[in] v1        The left handside
     539             :  * \param[in] v2        The right handside
     540             :  */
     541         104 : void variable::add(const variable& v1, const variable& v2)
     542             : {
     543         104 :         std::string str;
     544             : 
     545         104 :         switch(v1.f_type) {
     546             :         case TYPE_INT:
     547          67 :                 switch(v2.f_type) {
     548             :                 case TYPE_INT:
     549          63 :                         set(v1.f_int + v2.f_int);
     550          63 :                         break;
     551             : 
     552             :                 case TYPE_FLT:
     553           1 :                         set(v1.f_int + v2.f_flt);
     554           1 :                         break;
     555             : 
     556             :                 case TYPE_STR:
     557           2 :                         v1.to_string(str);
     558           2 :                         set(str + v2.f_str);
     559           2 :                         break;
     560             : 
     561             :                 default:
     562           1 :                         throw incompatible_type("type not supported by the + operator");
     563             : 
     564             :                 }
     565          66 :                 break;
     566             : 
     567             :         case TYPE_FLT:
     568          20 :                 switch(v2.f_type) {
     569             :                 case TYPE_INT:
     570           8 :                         set(v1.f_flt + v2.f_int);
     571           8 :                         break;
     572             : 
     573             :                 case TYPE_FLT:
     574          10 :                         set(v1.f_flt + v2.f_flt);
     575          10 :                         break;
     576             : 
     577             :                 case TYPE_STR:
     578           1 :                         v1.to_string(str);
     579           1 :                         set(str + v2.f_str);
     580           1 :                         break;
     581             : 
     582             :                 default:
     583           1 :                         throw incompatible_type("type not supported by the + operator");
     584             : 
     585             :                 }
     586          19 :                 break;
     587             : 
     588             :         case TYPE_STR:
     589          16 :                 switch(v2.f_type) {
     590             :                 case TYPE_INT:
     591             :                 case TYPE_FLT:
     592           3 :                         v2.to_string(str);
     593           3 :                         set(v1.f_str + str);
     594           3 :                         break;
     595             : 
     596             :                 case TYPE_STR:
     597          12 :                         set(v1.f_str + v2.f_str);
     598          12 :                         break;
     599             : 
     600             :                 default:
     601           1 :                         throw incompatible_type("type not supported by the + operator");
     602             : 
     603             :                 }
     604          15 :                 break;
     605             : 
     606             :         default:
     607           1 :                 throw incompatible_type("type not supported by + operator");
     608             : 
     609         104 :         }
     610         100 : }
     611             : 
     612             : /** \brief Subtract v2 from v1.
     613             :  *
     614             :  * This function subtract the input integer or floating point values
     615             :  * and saves the result in this variable.
     616             :  *
     617             :  * \bug
     618             :  * This function throws an incompatible_type exception
     619             :  * whenever this function is called with a value of
     620             :  * incompatible type.
     621             :  *
     622             :  * \param[in] v1        The left handside
     623             :  * \param[in] v2        The right handside
     624             :  */
     625          22 : void variable::sub(const variable& v1, const variable& v2)
     626             : {
     627          22 :         switch(v1.f_type) {
     628             :         case TYPE_INT:
     629          15 :                 switch(v2.f_type) {
     630             :                 case TYPE_INT:
     631          13 :                         set(v1.f_int - v2.f_int);
     632          13 :                         break;
     633             : 
     634             :                 case TYPE_FLT:
     635           1 :                         set(v1.f_int - v2.f_flt);
     636           1 :                         break;
     637             : 
     638             :                 default:
     639           1 :                         throw incompatible_type("type not supported by the - operator");
     640             : 
     641             :                 }
     642          14 :                 break;
     643             : 
     644             :         case TYPE_FLT:
     645           6 :                 switch(v2.f_type) {
     646             :                 case TYPE_INT:
     647           1 :                         set(v1.f_flt - v2.f_int);
     648           1 :                         break;
     649             : 
     650             :                 case TYPE_FLT:
     651           4 :                         set(v1.f_flt - v2.f_flt);
     652           4 :                         break;
     653             : 
     654             :                 default:
     655           1 :                         throw incompatible_type("type not supported by the - operator");
     656             : 
     657             :                 }
     658           5 :                 break;
     659             : 
     660             :         default:
     661           1 :                 throw incompatible_type("type not supported by - operator");
     662             : 
     663             :         }
     664          19 : }
     665             : 
     666             : /** \brief Bitwise AND between v1 and v2.
     667             :  *
     668             :  * This function computes the bitwise AND of the input integer values
     669             :  * and saves the result in this variable.
     670             :  *
     671             :  * \bug
     672             :  * This function throws an incompatible_type exception
     673             :  * whenever this function is called with a value of
     674             :  * incompatible type.
     675             :  *
     676             :  * \param[in] v1        The left handside
     677             :  * \param[in] v2        The right handside
     678             :  */
     679          17 : void variable::bitwise_and(const variable& v1, const variable& v2)
     680             : {
     681          17 :         switch(v1.f_type) {
     682             :         case TYPE_INT:
     683          15 :                 switch(v2.f_type) {
     684             :                 case TYPE_INT:
     685          14 :                         set(v1.f_int & v2.f_int);
     686          14 :                         break;
     687             : 
     688             :                 default:
     689           1 :                         throw incompatible_type("type not supported by the & operator");
     690             : 
     691             :                 }
     692          14 :                 break;
     693             : 
     694             :         default:
     695           2 :                 throw incompatible_type("type not supported by & operator");
     696             : 
     697             :         }
     698          14 : }
     699             : 
     700             : /** \brief Bitwise OR between v1 and v2.
     701             :  *
     702             :  * This function computes the bitwise OR of the input integer values
     703             :  * and saves the result in this variable.
     704             :  *
     705             :  * \bug
     706             :  * This function throws an incompatible_type exception
     707             :  * whenever this function is called with a value of
     708             :  * incompatible type.
     709             :  *
     710             :  * \param[in] v1        The left handside
     711             :  * \param[in] v2        The right handside
     712             :  */
     713          17 : void variable::bitwise_or(const variable& v1, const variable& v2)
     714             : {
     715          17 :         switch(v1.f_type) {
     716             :         case TYPE_INT:
     717          15 :                 switch(v2.f_type) {
     718             :                 case TYPE_INT:
     719          14 :                         set(v1.f_int | v2.f_int);
     720          14 :                         break;
     721             : 
     722             :                 default:
     723           1 :                         throw incompatible_type("type not supported by the | operator");
     724             : 
     725             :                 }
     726          14 :                 break;
     727             : 
     728             :         default:
     729           2 :                 throw incompatible_type("type not supported by | operator");
     730             : 
     731             :         }
     732          14 : }
     733             : 
     734             : /** \brief Bitwise XOR between v1 and v2.
     735             :  *
     736             :  * This function computes the bitwise XOR of the input integer values
     737             :  * and saves the result in this variable.
     738             :  *
     739             :  * \bug
     740             :  * This function throws an incompatible_type exception
     741             :  * whenever this function is called with a value of
     742             :  * incompatible type.
     743             :  *
     744             :  * \param[in] v1        The left handside
     745             :  * \param[in] v2        The right handside
     746             :  */
     747          16 : void variable::bitwise_xor(const variable& v1, const variable& v2)
     748             : {
     749          16 :         switch(v1.f_type) {
     750             :         case TYPE_INT:
     751          14 :                 switch(v2.f_type) {
     752             :                 case TYPE_INT:
     753          13 :                         set(v1.f_int ^ v2.f_int);
     754          13 :                         break;
     755             : 
     756             :                 default:
     757           1 :                         throw incompatible_type("type not supported by the ^ operator");
     758             : 
     759             :                 }
     760          13 :                 break;
     761             : 
     762             :         default:
     763           2 :                 throw incompatible_type("type not supported by ^ operator");
     764             : 
     765             :         }
     766          13 : }
     767             : 
     768             : /** \brief Bitwise NOT of v1.
     769             :  *
     770             :  * This function computes the bitwise XOR of the input integer values
     771             :  * and saves the result in this variable.
     772             :  *
     773             :  * \bug
     774             :  * This function throws an incompatible_type exception
     775             :  * whenever this function is called with a value of
     776             :  * incompatible type.
     777             :  *
     778             :  * \param[in] v1        The left handside
     779             :  * \param[in] v2        The right handside
     780             :  */
     781          15 : void variable::bitwise_not(const variable& v1)
     782             : {
     783          15 :         switch(v1.f_type) {
     784             :         case TYPE_INT:
     785          12 :                 set(~v1.f_int);
     786          12 :                 break;
     787             : 
     788             :         default:
     789           3 :                 throw incompatible_type("type not supported by ~ operator");
     790             : 
     791             :         }
     792          12 : }
     793             : 
     794             : /** \brief Left shift of v1 by v2.
     795             :  *
     796             :  * This function computes the left shift of the input integer values
     797             :  * and saves the result in this variable.
     798             :  *
     799             :  * \bug
     800             :  * This function throws an incompatible_type exception
     801             :  * whenever this function is called with a value of
     802             :  * incompatible type.
     803             :  *
     804             :  * \param[in] v1        The left handside
     805             :  * \param[in] v2        The right handside
     806             :  */
     807          22 : void variable::shl(const variable& v1, const variable& v2)
     808             : {
     809          22 :         switch(v1.f_type) {
     810             :         case TYPE_INT:
     811          20 :                 switch(v2.f_type) {
     812             :                 case TYPE_INT:
     813          19 :                         set(v1.f_int << v2.f_int);
     814          19 :                         break;
     815             : 
     816             :                 default:
     817           1 :                         throw incompatible_type("type not supported by the << operator");
     818             : 
     819             :                 }
     820          19 :                 break;
     821             : 
     822             :         default:
     823           2 :                 throw incompatible_type("type not supported by << operator");
     824             : 
     825             :         }
     826          19 : }
     827             : 
     828             : /** \brief Signed right shift of v1 by v2.
     829             :  *
     830             :  * This function computes the right shift of the input integer values
     831             :  * and saves the result in this variable.
     832             :  *
     833             :  * \bug
     834             :  * This function throws an incompatible_type exception
     835             :  * whenever this function is called with a value of
     836             :  * incompatible type.
     837             :  *
     838             :  * \param[in] v1        The left handside
     839             :  * \param[in] v2        The right handside
     840             :  */
     841          19 : void variable::shr(const variable& v1, const variable& v2)
     842             : {
     843          19 :         switch(v1.f_type) {
     844             :         case TYPE_INT:
     845          17 :                 switch(v2.f_type) {
     846             :                 case TYPE_INT:
     847          16 :                         set(v1.f_int >> v2.f_int);
     848          16 :                         break;
     849             : 
     850             :                 default:
     851           1 :                         throw incompatible_type("type not supported by the >> operator");
     852             : 
     853             :                 }
     854          16 :                 break;
     855             : 
     856             :         default:
     857           2 :                 throw incompatible_type("type not supported by >> operator");
     858             : 
     859             :         }
     860          16 : }
     861             : 
     862             : /** \brief Compare whether v1 is smaller than v2.
     863             :  *
     864             :  * This function compares the input values and saves true in
     865             :  * this variable if v1 is smaller than v2.
     866             :  *
     867             :  * Integers and floating points can be compared between each
     868             :  * others. Strings can be compared between each others.
     869             :  *
     870             :  * \bug
     871             :  * This function throws an incompatible_type exception
     872             :  * whenever this function is called with a value of
     873             :  * incompatible type.
     874             :  *
     875             :  * \param[in] v1        The left handside
     876             :  * \param[in] v2        The right handside
     877             :  */
     878          21 : void variable::lt(const variable& v1, const variable& v2)
     879             : {
     880          21 :         switch(v1.f_type) {
     881             :         case TYPE_INT:
     882          11 :                 switch(v2.f_type) {
     883             :                 case TYPE_INT:
     884           9 :                         set(v1.f_int < v2.f_int);
     885           9 :                         break;
     886             : 
     887             :                 case TYPE_FLT:
     888           1 :                         set(v1.f_int < v2.f_flt);
     889           1 :                         break;
     890             : 
     891             :                 default:
     892           1 :                         throw incompatible_type("type not supported by the < operator");
     893             : 
     894             :                 }
     895          10 :                 break;
     896             : 
     897             :         case TYPE_FLT:
     898           4 :                 switch(v2.f_type) {
     899             :                 case TYPE_INT:
     900           2 :                         set(v1.f_flt < v2.f_int);
     901           2 :                         break;
     902             : 
     903             :                 case TYPE_FLT:
     904           1 :                         set(v1.f_flt < v2.f_flt);
     905           1 :                         break;
     906             : 
     907             :                 default:
     908           1 :                         throw incompatible_type("type not supported by the < operator");
     909             : 
     910             :                 }
     911           3 :                 break;
     912             : 
     913             :         case TYPE_STR:
     914           5 :                 switch(v2.f_type) {
     915             :                 case TYPE_STR:
     916           2 :                         set(v1.f_str < v2.f_str);
     917           2 :                         break;
     918             : 
     919             :                 default:
     920           3 :                         throw incompatible_type("type not supported by the < operator");
     921             : 
     922             :                 }
     923           2 :                 break;
     924             : 
     925             :         default:
     926           1 :                 throw incompatible_type("type not supported by < operator");
     927             : 
     928             :         }
     929          15 : }
     930             : 
     931             : /** \brief Compare whether v1 is smaller or equal to v2.
     932             :  *
     933             :  * This function compares the input values and saves true in
     934             :  * this variable if v1 is smaller or equal to v2.
     935             :  *
     936             :  * Integers and floating points can be compared between each
     937             :  * others. Strings can be compared between each others.
     938             :  *
     939             :  * \bug
     940             :  * This function throws an incompatible_type exception
     941             :  * whenever this function is called with a value of
     942             :  * incompatible type.
     943             :  *
     944             :  * \param[in] v1        The left handside
     945             :  * \param[in] v2        The right handside
     946             :  */
     947          18 : void variable::le(const variable& v1, const variable& v2)
     948             : {
     949          18 :         switch(v1.f_type) {
     950             :         case TYPE_INT:
     951           8 :                 switch(v2.f_type) {
     952             :                 case TYPE_INT:
     953           6 :                         set(v1.f_int <= v2.f_int);
     954           6 :                         break;
     955             : 
     956             :                 case TYPE_FLT:
     957           1 :                         set(v1.f_int <= v2.f_flt);
     958           1 :                         break;
     959             : 
     960             :                 default:
     961           1 :                         throw incompatible_type("type not supported by the <= operator");
     962             : 
     963             :                 }
     964           7 :                 break;
     965             : 
     966             :         case TYPE_FLT:
     967           4 :                 switch(v2.f_type) {
     968             :                 case TYPE_INT:
     969           2 :                         set(v1.f_flt <= v2.f_int);
     970           2 :                         break;
     971             : 
     972             :                 case TYPE_FLT:
     973           1 :                         set(v1.f_flt <= v2.f_flt);
     974           1 :                         break;
     975             : 
     976             :                 default:
     977           1 :                         throw incompatible_type("type not supported by the <= operator");
     978             : 
     979             :                 }
     980           3 :                 break;
     981             : 
     982             :         case TYPE_STR:
     983           5 :                 switch(v2.f_type) {
     984             :                 case TYPE_STR:
     985           2 :                         set(v1.f_str <= v2.f_str);
     986           2 :                         break;
     987             : 
     988             :                 default:
     989           3 :                         throw incompatible_type("type not supported by the <= operator");
     990             : 
     991             :                 }
     992           2 :                 break;
     993             : 
     994             :         default:
     995           1 :                 throw incompatible_type("type not supported by <= operator");
     996             : 
     997             :         }
     998          12 : }
     999             : 
    1000             : /** \brief Compare whether v1 is equal to v2.
    1001             :  *
    1002             :  * This function compares the input values and saves true in
    1003             :  * this variable if v1 equals v2.
    1004             :  *
    1005             :  * Integers and floating points can be compared between each
    1006             :  * others. Strings can be compared between each others.
    1007             :  *
    1008             :  * \bug
    1009             :  * This function throws an incompatible_type exception
    1010             :  * whenever this function is called with a value of
    1011             :  * incompatible type.
    1012             :  *
    1013             :  * \param[in] v1        The left handside
    1014             :  * \param[in] v2        The right handside
    1015             :  */
    1016          23 : void variable::eq(const variable& v1, const variable& v2)
    1017             : {
    1018          23 :         switch(v1.f_type) {
    1019             :         case TYPE_INT:
    1020           9 :                 switch(v2.f_type) {
    1021             :                 case TYPE_INT:
    1022           7 :                         set(v1.f_int == v2.f_int);
    1023           7 :                         break;
    1024             : 
    1025             :                 case TYPE_FLT:
    1026           1 :                         set(v1.f_int == v2.f_flt);
    1027           1 :                         break;
    1028             : 
    1029             :                 default:
    1030           1 :                         throw incompatible_type("type not supported by the == operator");
    1031             : 
    1032             :                 }
    1033           8 :                 break;
    1034             : 
    1035             :         case TYPE_FLT:
    1036           4 :                 switch(v2.f_type) {
    1037             :                 case TYPE_INT:
    1038           1 :                         set(v1.f_flt == v2.f_int);
    1039           1 :                         break;
    1040             : 
    1041             :                 case TYPE_FLT:
    1042           2 :                         set(v1.f_flt == v2.f_flt);
    1043           2 :                         break;
    1044             : 
    1045             :                 default:
    1046           1 :                         throw incompatible_type("type not supported by the == operator");
    1047             : 
    1048             :                 }
    1049           3 :                 break;
    1050             : 
    1051             :         case TYPE_STR:
    1052           9 :                 switch(v2.f_type) {
    1053             :                 case TYPE_STR:
    1054           6 :                         set(v1.f_str == v2.f_str);
    1055           6 :                         break;
    1056             : 
    1057             :                 default:
    1058           3 :                         throw incompatible_type("type not supported by the == operator");
    1059             : 
    1060             :                 }
    1061           6 :                 break;
    1062             : 
    1063             :         default:
    1064           1 :                 throw incompatible_type("type not supported by == operator");
    1065             : 
    1066             :         }
    1067          17 : }
    1068             : 
    1069             : /** \brief Compare whether v1 is not equal to v2.
    1070             :  *
    1071             :  * This function compares the input values and saves true in
    1072             :  * this variable if v1 is not equal to v2.
    1073             :  *
    1074             :  * Integers and floating points can be compared between each
    1075             :  * others. Strings can be compared between each others.
    1076             :  *
    1077             :  * \bug
    1078             :  * This function throws an incompatible_type exception
    1079             :  * whenever this function is called with a value of
    1080             :  * incompatible type.
    1081             :  *
    1082             :  * \param[in] v1        The left handside
    1083             :  * \param[in] v2        The right handside
    1084             :  */
    1085          19 : void variable::ne(const variable& v1, const variable& v2)
    1086             : {
    1087          19 :         switch(v1.f_type) {
    1088             :         case TYPE_INT:
    1089           8 :                 switch(v2.f_type) {
    1090             :                 case TYPE_INT:
    1091           6 :                         set(v1.f_int != v2.f_int);
    1092           6 :                         break;
    1093             : 
    1094             :                 case TYPE_FLT:
    1095           1 :                         set(v1.f_int != v2.f_flt);
    1096           1 :                         break;
    1097             : 
    1098             :                 default:
    1099           1 :                         throw incompatible_type("type not supported by the != operator");
    1100             : 
    1101             :                 }
    1102           7 :                 break;
    1103             : 
    1104             :         case TYPE_FLT:
    1105           4 :                 switch(v2.f_type) {
    1106             :                 case TYPE_INT:
    1107           1 :                         set(v1.f_flt != v2.f_int);
    1108           1 :                         break;
    1109             : 
    1110             :                 case TYPE_FLT:
    1111           2 :                         set(v1.f_flt != v2.f_flt);
    1112           2 :                         break;
    1113             : 
    1114             :                 default:
    1115           1 :                         throw incompatible_type("type not supported by the != operator");
    1116             : 
    1117             :                 }
    1118           3 :                 break;
    1119             : 
    1120             :         case TYPE_STR:
    1121           6 :                 switch(v2.f_type) {
    1122             :                 case TYPE_STR:
    1123           3 :                         set(v1.f_str != v2.f_str);
    1124           3 :                         break;
    1125             : 
    1126             :                 default:
    1127           3 :                         throw incompatible_type("type not supported by the != operator");
    1128             : 
    1129             :                 }
    1130           3 :                 break;
    1131             : 
    1132             :         default:
    1133           1 :                 throw incompatible_type("type not supported by != operator");
    1134             : 
    1135             :         }
    1136          13 : }
    1137             : 
    1138             : /** \brief Compare whether v1 is greater or equal to v2.
    1139             :  *
    1140             :  * This function compares the input values and saves true in
    1141             :  * this variable if v1 is greater or equal to v2.
    1142             :  *
    1143             :  * Integers and floating points can be compared between each
    1144             :  * others. Strings can be compared between each others.
    1145             :  *
    1146             :  * \bug
    1147             :  * This function throws an incompatible_type exception
    1148             :  * whenever this function is called with a value of
    1149             :  * incompatible type.
    1150             :  *
    1151             :  * \param[in] v1        The left handside
    1152             :  * \param[in] v2        The right handside
    1153             :  */
    1154         158 : void variable::ge(const variable& v1, const variable& v2)
    1155             : {
    1156         158 :         switch(v1.f_type) {
    1157             :         case TYPE_INT:
    1158          11 :                 switch(v2.f_type) {
    1159             :                 case TYPE_INT:
    1160           9 :                         set(v1.f_int >= v2.f_int);
    1161           9 :                         break;
    1162             : 
    1163             :                 case TYPE_FLT:
    1164           1 :                         set(v1.f_int >= v2.f_flt);
    1165           1 :                         break;
    1166             : 
    1167             :                 default:
    1168           1 :                         throw incompatible_type("type not supported by the >= operator");
    1169             : 
    1170             :                 }
    1171          10 :                 break;
    1172             : 
    1173             :         case TYPE_FLT:
    1174           4 :                 switch(v2.f_type) {
    1175             :                 case TYPE_INT:
    1176           1 :                         set(v1.f_flt >= v2.f_int);
    1177           1 :                         break;
    1178             : 
    1179             :                 case TYPE_FLT:
    1180           2 :                         set(v1.f_flt >= v2.f_flt);
    1181           2 :                         break;
    1182             : 
    1183             :                 default:
    1184           1 :                         throw incompatible_type("type not supported by the >= operator");
    1185             : 
    1186             :                 }
    1187           3 :                 break;
    1188             : 
    1189             :         case TYPE_STR:
    1190         142 :                 switch(v2.f_type) {
    1191             :                 case TYPE_STR:
    1192         139 :                         set(v1.f_str >= v2.f_str);
    1193         139 :                         break;
    1194             : 
    1195             :                 default:
    1196           3 :                         throw incompatible_type("type not supported by the >= operator");
    1197             : 
    1198             :                 }
    1199         139 :                 break;
    1200             : 
    1201             :         default:
    1202           1 :                 throw incompatible_type("type not supported by >= operator");
    1203             : 
    1204             :         }
    1205         152 : }
    1206             : 
    1207             : /** \brief Compare whether v1 is greater than v2.
    1208             :  *
    1209             :  * This function compares the input values and saves true in
    1210             :  * this variable if v1 is greater than v2.
    1211             :  *
    1212             :  * Integers and floating points can be compared between each
    1213             :  * others. Strings can be compared between each others.
    1214             :  *
    1215             :  * \bug
    1216             :  * This function throws an incompatible_type exception
    1217             :  * whenever this function is called with a value of
    1218             :  * incompatible type.
    1219             :  *
    1220             :  * \param[in] v1        The left handside
    1221             :  * \param[in] v2        The right handside
    1222             :  */
    1223          21 : void variable::gt(const variable& v1, const variable& v2)
    1224             : {
    1225          21 :         switch(v1.f_type) {
    1226             :         case TYPE_INT:
    1227           9 :                 switch(v2.f_type) {
    1228             :                 case TYPE_INT:
    1229           7 :                         set(v1.f_int > v2.f_int);
    1230           7 :                         break;
    1231             : 
    1232             :                 case TYPE_FLT:
    1233           1 :                         set(v1.f_int > v2.f_flt);
    1234           1 :                         break;
    1235             : 
    1236             :                 default:
    1237           1 :                         throw incompatible_type("type not supported by the > operator");
    1238             : 
    1239             :                 }
    1240           8 :                 break;
    1241             : 
    1242             :         case TYPE_FLT:
    1243           4 :                 switch(v2.f_type) {
    1244             :                 case TYPE_INT:
    1245           1 :                         set(v1.f_flt > v2.f_int);
    1246           1 :                         break;
    1247             : 
    1248             :                 case TYPE_FLT:
    1249           2 :                         set(v1.f_flt > v2.f_flt);
    1250           2 :                         break;
    1251             : 
    1252             :                 default:
    1253           1 :                         throw incompatible_type("type not supported by the > operator");
    1254             : 
    1255             :                 }
    1256           3 :                 break;
    1257             : 
    1258             :         case TYPE_STR:
    1259           7 :                 switch(v2.f_type) {
    1260             :                 case TYPE_STR:
    1261           4 :                         set(v1.f_str > v2.f_str);
    1262           4 :                         break;
    1263             : 
    1264             :                 default:
    1265           3 :                         throw incompatible_type("type not supported by the > operator");
    1266             : 
    1267             :                 }
    1268           4 :                 break;
    1269             : 
    1270             :         default:
    1271           1 :                 throw incompatible_type("type not supported by > operator");
    1272             : 
    1273             :         }
    1274          15 : }
    1275             : 
    1276             : /** \brief Apply the logical AND between v1 and v2.
    1277             :  *
    1278             :  * This function applies the logical AND between v1 and v2.
    1279             :  *
    1280             :  * Integers and floating points are considered true when not
    1281             :  * zero. Strings are considered true when not empty.
    1282             :  *
    1283             :  * The function returns an integer set to 0 (false) or 1 (true).
    1284             :  *
    1285             :  * \bug
    1286             :  * This function throws an incompatible_type exception
    1287             :  * whenever this function is called with a value of
    1288             :  * incompatible type.
    1289             :  *
    1290             :  * \param[in] v1        The left handside
    1291             :  * \param[in] v2        The right handside
    1292             :  */
    1293          38 : void variable::logic_and(const variable& v1, const variable& v2)
    1294             : {
    1295             :         bool l1, l2;
    1296             : 
    1297          38 :         switch(v1.f_type) {
    1298             :         case TYPE_INT:
    1299          31 :                 l1 = v1.f_int != 0;
    1300          31 :                 break;
    1301             : 
    1302             :         case TYPE_FLT:
    1303           3 :                 l1 = v1.f_flt != 0;
    1304           3 :                 break;
    1305             : 
    1306             :         case TYPE_STR:
    1307           3 :                 l1 = !v1.f_str.empty();
    1308           3 :                 break;
    1309             : 
    1310             :         default:
    1311           1 :                 throw incompatible_type("type not supported by the && operator");
    1312             : 
    1313             :         }
    1314          37 :         switch(v2.f_type) {
    1315             :         case TYPE_INT:
    1316          31 :                 l2 = v2.f_int != 0;
    1317          31 :                 break;
    1318             : 
    1319             :         case TYPE_FLT:
    1320           3 :                 l2 = v2.f_flt != 0;
    1321           3 :                 break;
    1322             : 
    1323             :         case TYPE_STR:
    1324           2 :                 l2 = !v2.f_str.empty();
    1325           2 :                 break;
    1326             : 
    1327             :         default:
    1328           1 :                 throw incompatible_type("type not supported by the && operator");
    1329             : 
    1330             :         }
    1331             : 
    1332          36 :         set(l1 && l2 ? 1L : 0L);
    1333          36 : }
    1334             : 
    1335             : /** \brief Apply the logical OR between v1 and v2.
    1336             :  *
    1337             :  * This function applies the logical OR between v1 and v2.
    1338             :  *
    1339             :  * Integers and floating points are considered true when not
    1340             :  * zero. Strings are considered true when not empty.
    1341             :  *
    1342             :  * The function returns an integer set to 0 (false) or 1 (true).
    1343             :  *
    1344             :  * \bug
    1345             :  * This function throws an incompatible_type exception
    1346             :  * whenever this function is called with a value of
    1347             :  * incompatible type.
    1348             :  *
    1349             :  * \param[in] v1        The left handside
    1350             :  * \param[in] v2        The right handside
    1351             :  */
    1352          24 : void variable::logic_or(const variable& v1, const variable& v2)
    1353             : {
    1354             :         bool l1, l2;
    1355             : 
    1356          24 :         switch(v1.f_type) {
    1357             :         case TYPE_INT:
    1358          17 :                 l1 = v1.f_int != 0;
    1359          17 :                 break;
    1360             : 
    1361             :         case TYPE_FLT:
    1362           3 :                 l1 = v1.f_flt != 0;
    1363           3 :                 break;
    1364             : 
    1365             :         case TYPE_STR:
    1366           3 :                 l1 = !v1.f_str.empty();
    1367           3 :                 break;
    1368             : 
    1369             :         default:
    1370           1 :                 throw incompatible_type("type not supported by the || operator");
    1371             : 
    1372             :         }
    1373          23 :         switch(v2.f_type) {
    1374             :         case TYPE_INT:
    1375          17 :                 l2 = v2.f_int != 0;
    1376          17 :                 break;
    1377             : 
    1378             :         case TYPE_FLT:
    1379           3 :                 l2 = v2.f_flt != 0;
    1380           3 :                 break;
    1381             : 
    1382             :         case TYPE_STR:
    1383           2 :                 l2 = !v2.f_str.empty();
    1384           2 :                 break;
    1385             : 
    1386             :         default:
    1387           1 :                 throw incompatible_type("type not supported by the || operator");
    1388             : 
    1389             :         }
    1390             : 
    1391          22 :         set(l1 || l2 ? 1L : 0L);
    1392          22 : }
    1393             : 
    1394             : /** \brief Apply the logical XOR between v1 and v2.
    1395             :  *
    1396             :  * This function applies the logical XOR between v1 and v2.
    1397             :  *
    1398             :  * Integers and floating points are considered true when not
    1399             :  * zero. Strings are considered true when not empty.
    1400             :  *
    1401             :  * The function returns an integer set to 0 (false) or 1 (true).
    1402             :  *
    1403             :  * \bug
    1404             :  * This function throws an incompatible_type exception
    1405             :  * whenever this function is called with a value of
    1406             :  * incompatible type.
    1407             :  *
    1408             :  * \param[in] v1        The left handside
    1409             :  * \param[in] v2        The right handside
    1410             :  */
    1411          19 : void variable::logic_xor(const variable& v1, const variable& v2)
    1412             : {
    1413             :         bool l1, l2;
    1414             : 
    1415          19 :         switch(v1.f_type) {
    1416             :         case TYPE_INT:
    1417          13 :                 l1 = v1.f_int != 0;
    1418          13 :                 break;
    1419             : 
    1420             :         case TYPE_FLT:
    1421           2 :                 l1 = v1.f_flt != 0;
    1422           2 :                 break;
    1423             : 
    1424             :         case TYPE_STR:
    1425           3 :                 l1 = !v1.f_str.empty();
    1426           3 :                 break;
    1427             : 
    1428             :         default:
    1429           1 :                 throw incompatible_type("type not supported by the ^^ operator");
    1430             : 
    1431             :         }
    1432          18 :         switch(v2.f_type) {
    1433             :         case TYPE_INT:
    1434          13 :                 l2 = v2.f_int != 0;
    1435          13 :                 break;
    1436             : 
    1437             :         case TYPE_FLT:
    1438           2 :                 l2 = v2.f_flt != 0;
    1439           2 :                 break;
    1440             : 
    1441             :         case TYPE_STR:
    1442           2 :                 l2 = !v2.f_str.empty();
    1443           2 :                 break;
    1444             : 
    1445             :         default:
    1446           1 :                 throw incompatible_type("type not supported by the ^^ operator");
    1447             : 
    1448             :         }
    1449             : 
    1450          17 :         set(l1 ^ l2 ? 1L : 0L);
    1451          17 : }
    1452             : 
    1453             : /** \brief Apply the logical NOT to v1.
    1454             :  *
    1455             :  * This function applies the logical NOT to v1.
    1456             :  *
    1457             :  * Integers and floating points are considered true when not
    1458             :  * zero. Strings are considered true when not empty.
    1459             :  *
    1460             :  * The function returns an integer set to 0 (false) or 1 (true).
    1461             :  *
    1462             :  * \bug
    1463             :  * This function throws an incompatible_type exception
    1464             :  * whenever this function is called with a value of
    1465             :  * incompatible type.
    1466             :  *
    1467             :  * \param[in] v1        The left handside
    1468             :  * \param[in] v2        The right handside
    1469             :  */
    1470          12 : void variable::logic_not(const variable& v1)
    1471             : {
    1472          12 :         switch(v1.f_type) {
    1473             :         case TYPE_INT:
    1474           6 :                 set(v1.f_int == 0 ? 1L : 0L);
    1475           6 :                 break;
    1476             : 
    1477             :         case TYPE_FLT:
    1478           3 :                 set(v1.f_flt == 0 ? 1L : 0L);
    1479           3 :                 break;
    1480             : 
    1481             :         case TYPE_STR:
    1482           2 :                 set(v1.f_str.empty() ? 1L : 0L);
    1483           2 :                 break;
    1484             : 
    1485             :         default:
    1486           1 :                 throw incompatible_type("type not supported by the ^^ operator");
    1487             : 
    1488             :         }
    1489          11 : }
    1490             : 
    1491             : 
    1492             : 
    1493             : /** \brief Get a copy of the named variable
    1494             :  *
    1495             :  * This function searches for the named variable and if found
    1496             :  * it copies the current value to the user supplied variable.
    1497             :  * If not found, the function returns false and the user
    1498             :  * supplied variable is variable::reset().
    1499             :  *
    1500             :  * This function knows of the "e" and "pi" variables internally.
    1501             :  * You do not have to define those two variables, they will
    1502             :  * always be defined.
    1503             :  *
    1504             :  * \param[in]  name       The name of the variable to search
    1505             :  * \param[out] var        The user variable to set with the value of the variable found in the list
    1506             :  *
    1507             :  * \return true if the variable is found; false otherwise
    1508             :  */
    1509         329 : bool variable_list::get(const std::string& name, variable& var) const
    1510             : {
    1511         329 :         list_t::const_iterator v = f_list.find(name);
    1512         329 :         if(v == f_list.end())
    1513             :         {
    1514          47 :                 if(name == "e")
    1515             :                 {
    1516           6 :                         var.set(M_E);
    1517             :                 }
    1518          41 :                 else if(name == "pi")
    1519             :                 {
    1520          25 :                         var.set(M_PI);
    1521             :                 }
    1522             :                 else
    1523             :                 {
    1524          16 :                         var.reset();
    1525          16 :                         return false;
    1526             :                 }
    1527             :         }
    1528             :         else
    1529             :         {
    1530         282 :                 var = v->second;
    1531             :         }
    1532             : 
    1533         329 :         return true;
    1534             : }
    1535             : 
    1536             : /** \brief Set a variable in the variable list.
    1537             :  *
    1538             :  * This function sets the named variable to the value of
    1539             :  * the specified variable.
    1540             :  *
    1541             :  * If the variable does not exist yet, it is created.
    1542             :  *
    1543             :  * If the variable already exists, its current value is
    1544             :  * overwritten. If you want to simulate constants, try
    1545             :  * first to get() the variable. If you succeed, then
    1546             :  * do not set.
    1547             :  *
    1548             :  * \param[in] name        The name of the variable
    1549             :  * \param[in] var         The variable value
    1550             :  */
    1551         260 : void variable_list::set(const std::string& name, const variable& var)
    1552             : {
    1553         260 :         f_list[name] = var;
    1554         260 : }
    1555             : 
    1556             : 
    1557             : 
    1558             : 
    1559        4170 : }               // namespace expr
    1560             : 

Generated by: LCOV version 1.9

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