LCOV - code coverage report
Current view: top level - lib - csspp.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 40 40 100.0 %
Date: 2017-03-23 22:48:20 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // CSS Preprocessor
       2             : // Copyright (C) 2015-2017  Made to Order Software Corp.
       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
      15             : // along with this program; if not, write to the Free Software
      16             : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
      17             : 
      18             : /** \file
      19             :  * \brief Implementation of the CSS Preprocessor library.
      20             :  *
      21             :  * This file represents the main implementation of the CSS Preprocessor
      22             :  * library. It has only a few functions handling code that's common
      23             :  * to all the other classes. It also has the library version information.
      24             :  *
      25             :  * \sa \ref lexer_rules
      26             :  */
      27             : 
      28             : #include "csspp/csspp.h"
      29             : 
      30             : #include "csspp/exceptions.h"
      31             : 
      32             : #include <cmath>
      33             : #include <cfloat>
      34             : #include <iomanip>
      35             : #include <sstream>
      36             : #include <iostream>
      37             : 
      38             : /** \brief The namespace of all the classes in the CSS Preprocessor.
      39             :  *
      40             :  * All the classes and many definitions appear under 'csspp'. It
      41             :  * is strongly advised that you do not do a 'using csspp;' because
      42             :  * some of the definitions are likely to spoil your namespace in
      43             :  * a way you do not want it to.
      44             :  */
      45             : namespace csspp
      46             : {
      47             : 
      48             : namespace
      49             : {
      50             : 
      51             : int g_precision = 3;
      52             : 
      53             : } // no name namespace
      54             : 
      55           1 : char const * csspp_library_version()
      56             : {
      57           1 :     return CSSPP_VERSION;
      58             : }
      59             : 
      60      134033 : int get_precision()
      61             : {
      62      134033 :     return g_precision;
      63             : }
      64             : 
      65      268085 : void set_precision(int precision)
      66             : {
      67      268085 :     if(precision < 0 || precision > 10)
      68             :     {
      69          20 :         throw csspp_exception_overflow("precision must be between 0 and 10, " + std::to_string(precision) + " is out of bounds.");
      70             :     }
      71             : 
      72      268065 :     g_precision = precision;
      73      268065 : }
      74             : 
      75      302413 : std::string decimal_number_to_string(decimal_number_t d, bool remove_leading_zero)
      76             : {
      77             :     // the std::setprecision() is a total number of digits when we
      78             :     // want a specific number of digits after the decimal point so
      79             :     // we use the following algorithm for it:
      80      604826 :     std::stringstream ss;
      81             : 
      82             :     // use the maximum precision so we do not get any surprises
      83             :     // see the following for the "3 + DBL_MANT_DIG - DBL_MIN_EXP":
      84             :     // http://stackoverflow.com/questions/1701055/what-is-the-maximum-length-in-chars-needed-to-represent-any-double-value
      85      302413 :     ss << std::setprecision(3 + DBL_MANT_DIG - DBL_MIN_EXP);
      86             : 
      87             :     // make sure to round the value up first
      88      302413 :     if(d >= 0.0)
      89             :     {
      90      299032 :         ss << d + 0.5 / pow(10.0, g_precision);
      91             :     }
      92             :     else
      93             :     {
      94        3381 :         ss << d - 0.5 / pow(10.0, g_precision);
      95             :     }
      96             : 
      97      604826 :     std::string out(ss.str());
      98             : 
      99             :     // check wether the number of digits after the decimal point is too large
     100      302413 :     std::string::size_type end(out.find('.'));
     101      302413 :     if(end != std::string::npos
     102      302413 :     && out.length() > end + g_precision + 1)
     103             :     {
     104             :         // remove anything extra
     105      302405 :         out = out.substr(0, end + g_precision + 1);
     106             :     }
     107      604826 :     if(out.find('.') != std::string::npos
     108      302413 :     && end != std::string::npos)
     109             :     {
     110      770569 :         while(out.back() == '0')
     111             :         {
     112      234082 :             out.erase(out.end() - 1);
     113             :         }
     114      302405 :         if(out.back() == '.')
     115             :         {
     116       63506 :             out.erase(out.end() - 1);
     117             :         }
     118             :     }
     119             : 
     120             :     // remove the leading zero when possible
     121      302413 :     if(remove_leading_zero)
     122             :     {
     123      334952 :         if(out.length() >= 3
     124      150994 :         && out[0] == '0'
     125      311037 :         && out[1] == '.')
     126             :         {
     127      143561 :             out.erase(out.begin());
     128             :             // .33 is valid and equivalent to 0.33
     129             :         }
     130       47830 :         else if(out.length() >= 4
     131        2763 :              && out[0] == '-'
     132        1127 :              && out[1] == '0'
     133       24671 :              && out[2] == '.')
     134             :         {
     135         756 :             out.erase(out.begin() + 1);
     136             :             // -.33 is valid and equivalent to -0.33
     137             :         }
     138             :     }
     139             : 
     140      302413 :     if(out == "-0")
     141             :     {
     142             :         // this happens with really small numbers because we lose
     143             :         // the precision and thus end up with zero even if the number
     144             :         // was not really zero
     145          25 :         return "0";
     146             :     }
     147             : 
     148      302388 :     return out;
     149             : }
     150             : 
     151           9 : } // namespace csspp
     152             : 
     153             : // Local Variables:
     154             : // mode: cpp
     155             : // indent-tabs-mode: nil
     156             : // c-basic-offset: 4
     157             : // tab-width: 4
     158             : // End:
     159             : 
     160             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.12