differential code coverage report with master
Current view: top level - source/styles - number_format.cpp (source / functions) Coverage Total Hit UBC CBC
Current: coverage.info Lines: 79.3 % 164 130 34 130
Current Date: 2025-12-07 02:01:22 Functions: 97.7 % 44 43 1 43
Baseline: coverage_master.info Branches: 79.5 % 190 151 78 302
Baseline Date: 2025-12-07 02:01:21

             Branch data    TLA  Line data    Source code
       1                 :                : // Copyright (c) 2014-2022 Thomas Fussell
       2                 :                : // Copyright (c) 2010-2015 openpyxl
       3                 :                : // Copyright (c) 2024-2025 xlnt-community
       4                 :                : //
       5                 :                : // Permission is hereby granted, free of charge, to any person obtaining a copy
       6                 :                : // of this software and associated documentation files (the "Software"), to deal
       7                 :                : // in the Software without restriction, including without limitation the rights
       8                 :                : // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9                 :                : // copies of the Software, and to permit persons to whom the Software is
      10                 :                : // furnished to do so, subject to the following conditions:
      11                 :                : //
      12                 :                : // The above copyright notice and this permission notice shall be included in
      13                 :                : // all copies or substantial portions of the Software.
      14                 :                : //
      15                 :                : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16                 :                : // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17                 :                : // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18                 :                : // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19                 :                : // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20                 :                : // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21                 :                : // THE SOFTWARE
      22                 :                : //
      23                 :                : // @license: http://www.opensource.org/licenses/mit-license.php
      24                 :                : // @author: see AUTHORS file
      25                 :                : 
      26                 :                : #include <cctype>
      27                 :                : #include <unordered_map>
      28                 :                : #include <vector>
      29                 :                : 
      30                 :                : #include <xlnt/styles/number_format.hpp>
      31                 :                : #include <xlnt/utils/datetime.hpp>
      32                 :                : #include <xlnt/utils/exceptions.hpp>
      33                 :                : #include <detail/number_format/number_formatter.hpp>
      34                 :                : 
      35                 :                : namespace {
      36                 :                : 
      37                 :CBC         736 : const std::unordered_map<std::size_t, xlnt::number_format> &builtin_formats()
      38                 :                : {
      39   [ +  +  +  - ]:            736 :     static std::unordered_map<std::size_t, xlnt::number_format> formats;
      40                 :                : 
      41         [ +  + ]:            736 :     if (formats.size() == 0)
      42                 :                :     {
      43                 :                :         const std::unordered_map<std::size_t, std::string> format_strings{
      44                 :UBC           0 :             {0, "General"},
      45                 :              0 :             {1, "0"},
      46                 :              0 :             {2, "0.00"},
      47                 :              0 :             {3, "#,##0"},
      48                 :              0 :             {4, "#,##0.00"},
      49                 :              0 :             {9, "0%"},
      50                 :              0 :             {10, "0.00%"},
      51                 :              0 :             {11, "0.00E+00"},
      52                 :              0 :             {12, "# ?/?"},
      53                 :              0 :             {13, "# \?\?/??"}, // escape trigraph
      54                 :              0 :             {14, "mm-dd-yy"},
      55                 :              0 :             {15, "d-mmm-yy"},
      56                 :              0 :             {16, "d-mmm"},
      57                 :              0 :             {17, "mmm-yy"},
      58                 :              0 :             {18, "h:mm AM/PM"},
      59                 :              0 :             {19, "h:mm:ss AM/PM"},
      60                 :              0 :             {20, "h:mm"},
      61                 :              0 :             {21, "h:mm:ss"},
      62                 :              0 :             {22, "m/d/yy h:mm"},
      63                 :              0 :             {37, "#,##0 ;(#,##0)"},
      64                 :              0 :             {38, "#,##0 ;[Red](#,##0)"},
      65                 :              0 :             {39, "#,##0.00;(#,##0.00)"},
      66                 :              0 :             {40, "#,##0.00;[Red](#,##0.00)"},
      67                 :                : 
      68                 :                :             // 41-44 aren't in the ECMA 376 v4 standard, but Libre Office uses them
      69                 :              0 :             {41, "_(* #,##0_);_(* \\(#,##0\\);_(* \"-\"_);_(@_)"},
      70                 :              0 :             {42, "_(\"$\"* #,##0_);_(\"$\"* \\(#,##0\\);_(\"$\"* \"-\"_);_(@_)"},
      71                 :              0 :             {43, "_(* #,##0.00_);_(* \\(#,##0.00\\);_(* \"-\"??_);_(@_)"},
      72                 :              0 :             {44, "_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)"},
      73                 :                : 
      74                 :              0 :             {45, "mm:ss"},
      75                 :              0 :             {46, "[h]:mm:ss"},
      76                 :              0 :             {47, "mmss.0"},
      77                 :              0 :             {48, "##0.0E+0"},
      78   [ +  +  +  -  :CBC          34 :             {49, "@"}};
                      - ]
      79                 :                : 
      80      [ +  +  + ]:             33 :         for (auto format_string_pair : format_strings)
      81                 :                :         {
      82            [ + ]:             32 :             formats[format_string_pair.first] =
      83            [ + ]:             64 :                 xlnt::number_format(format_string_pair.second, format_string_pair.first);
      84                 :             32 :         }
      85                 :              1 :     }
      86                 :                : 
      87                 :            736 :     return formats;
      88   [ +  +  +  +  :              1 : }
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  -  -  
                   -  - ]
      89                 :                : 
      90                 :                : } // namespace
      91                 :                : 
      92                 :                : namespace xlnt {
      93                 :                : 
      94                 :            515 : const number_format number_format::general()
      95                 :                : {
      96         [ +  + ]:            515 :     return builtin_formats().at(0);
      97                 :                : }
      98                 :                : 
      99                 :              1 : const number_format number_format::text()
     100                 :                : {
     101         [ +  + ]:              1 :     return builtin_formats().at(49);
     102                 :                : }
     103                 :                : 
     104                 :              1 : const number_format number_format::number()
     105                 :                : {
     106         [ +  + ]:              1 :     return builtin_formats().at(1);
     107                 :                : }
     108                 :                : 
     109                 :              1 : const number_format number_format::number_00()
     110                 :                : {
     111         [ +  + ]:              1 :     return builtin_formats().at(2);
     112                 :                : }
     113                 :                : 
     114                 :              1 : const number_format number_format::number_comma_separated1()
     115                 :                : {
     116         [ +  + ]:              1 :     return builtin_formats().at(4);
     117                 :                : }
     118                 :                : 
     119                 :              4 : const number_format number_format::percentage()
     120                 :                : {
     121         [ +  + ]:              4 :     return builtin_formats().at(9);
     122                 :                : }
     123                 :                : 
     124                 :              1 : const number_format number_format::percentage_00()
     125                 :                : {
     126         [ +  + ]:              1 :     return builtin_formats().at(10);
     127                 :                : }
     128                 :                : 
     129                 :              3 : const number_format number_format::date_yyyymmdd2()
     130                 :                : {
     131   [ +  +  +  -  :              5 :     static const number_format format = number_format("yyyy-mm-dd");
             +  +  -  - ]
     132                 :              3 :     return format;
     133                 :                : }
     134                 :                : 
     135                 :              1 : const number_format number_format::date_yymmdd()
     136                 :                : {
     137   [ +  -  +  -  :              3 :     static const number_format format = number_format("yy-mm-dd");
             +  +  -  - ]
     138                 :              1 :     return format;
     139                 :                : }
     140                 :                : 
     141                 :              6 : const number_format number_format::date_ddmmyyyy()
     142                 :                : {
     143   [ +  +  +  -  :              8 :     static const number_format format = number_format("dd/mm/yy");
             +  +  -  - ]
     144                 :              6 :     return format;
     145                 :                : }
     146                 :                : 
     147                 :              1 : const number_format number_format::date_dmyslash()
     148                 :                : {
     149   [ +  -  +  -  :              3 :     static const number_format format = number_format("d/m/yy");
             +  +  -  - ]
     150                 :              1 :     return format;
     151                 :                : }
     152                 :                : 
     153                 :              1 : const number_format number_format::date_dmyminus()
     154                 :                : {
     155   [ +  -  +  -  :              3 :     static const number_format format = number_format("d-m-yy");
             +  +  -  - ]
     156                 :              1 :     return format;
     157                 :                : }
     158                 :                : 
     159                 :              3 : const number_format number_format::date_dmminus()
     160                 :                : {
     161   [ +  +  +  -  :              5 :     static const number_format format = number_format("d-m");
             +  +  -  - ]
     162                 :              3 :     return format;
     163                 :                : }
     164                 :                : 
     165                 :              1 : const number_format number_format::date_myminus()
     166                 :                : {
     167   [ +  -  +  -  :              3 :     static const number_format format = number_format("m-yy");
             +  +  -  - ]
     168                 :              1 :     return format;
     169                 :                : }
     170                 :                : 
     171                 :              1 : const number_format number_format::date_xlsx14()
     172                 :                : {
     173         [ +  + ]:              1 :     return builtin_formats().at(14);
     174                 :                : }
     175                 :                : 
     176                 :              1 : const number_format number_format::date_xlsx15()
     177                 :                : {
     178         [ +  + ]:              1 :     return builtin_formats().at(15);
     179                 :                : }
     180                 :                : 
     181                 :              1 : const number_format number_format::date_xlsx16()
     182                 :                : {
     183         [ +  + ]:              1 :     return builtin_formats().at(16);
     184                 :                : }
     185                 :                : 
     186                 :              1 : const number_format number_format::date_xlsx17()
     187                 :                : {
     188         [ +  + ]:              1 :     return builtin_formats().at(17);
     189                 :                : }
     190                 :                : 
     191                 :              1 : const number_format number_format::date_xlsx22()
     192                 :                : {
     193         [ +  + ]:              1 :     return builtin_formats().at(22);
     194                 :                : }
     195                 :                : 
     196                 :              7 : const number_format number_format::date_datetime()
     197                 :                : {
     198   [ +  +  +  -  :              9 :     static const number_format format = number_format("yyyy-mm-dd h:mm:ss");
             +  +  -  - ]
     199                 :              7 :     return format;
     200                 :                : }
     201                 :                : 
     202                 :              1 : const number_format number_format::date_time1()
     203                 :                : {
     204         [ +  + ]:              1 :     return builtin_formats().at(18);
     205                 :                : }
     206                 :                : 
     207                 :              5 : const number_format number_format::date_time2()
     208                 :                : {
     209         [ +  + ]:              5 :     return builtin_formats().at(19);
     210                 :                : }
     211                 :                : 
     212                 :              1 : const number_format number_format::date_time3()
     213                 :                : {
     214         [ +  + ]:              1 :     return builtin_formats().at(20);
     215                 :                : }
     216                 :                : 
     217                 :              2 : const number_format number_format::date_time4()
     218                 :                : {
     219         [ +  + ]:              2 :     return builtin_formats().at(21);
     220                 :                : }
     221                 :                : 
     222                 :              1 : const number_format number_format::date_time5()
     223                 :                : {
     224         [ +  + ]:              1 :     return builtin_formats().at(45);
     225                 :                : }
     226                 :                : 
     227                 :              5 : const number_format number_format::date_time6()
     228                 :                : {
     229         [ +  + ]:              5 :     return builtin_formats().at(21);
     230                 :                : }
     231                 :                : 
     232                 :            147 : number_format::number_format()
     233         [ +  + ]:            147 :     : number_format("General", 0)
     234                 :                : {
     235                 :            147 : }
     236                 :                : 
     237                 :              2 : number_format::number_format(std::size_t id)
     238                 :              2 :     : number_format(from_builtin_id(id))
     239                 :                : {
     240                 :              2 : }
     241                 :                : 
     242                 :             22 : number_format::number_format(const std::string &format_string)
     243            [ + ]:             22 :     : format_string_(format_string)
     244                 :                : {
     245                 :             22 : }
     246                 :                : 
     247                 :            181 : number_format::number_format(const std::string &format, std::size_t id)
     248                 :                : {
     249            [ + ]:            181 :     format_string(format, id);
     250                 :            181 : }
     251                 :                : 
     252                 :             32 : bool number_format::is_builtin_format(std::size_t builtin_id)
     253                 :                : {
     254      [ +  +  + ]:             32 :     return builtin_formats().find(builtin_id) != builtin_formats().end();
     255                 :                : }
     256                 :                : 
     257                 :             15 : const number_format &number_format::from_builtin_id(std::size_t builtin_id)
     258                 :                : {
     259         [ -  + ]:             15 :     if (!is_builtin_format(builtin_id))
     260                 :                :     {
     261            [ # ]:UBC           0 :         throw invalid_parameter();
     262                 :                :     }
     263                 :                : 
     264                 :CBC          15 :     return builtin_formats().at(builtin_id);
     265                 :                : }
     266                 :                : 
     267                 :           3589 : std::string number_format::format_string() const
     268                 :                : {
     269                 :           3589 :     return format_string_;
     270                 :                : }
     271                 :                : 
     272                 :            113 : void number_format::format_string(const std::string &format_string)
     273                 :                : {
     274                 :            113 :     format_string_ = format_string;
     275                 :            113 :     id_ = 0;
     276                 :                : 
     277      [ +  +  + ]:           3674 :     for (const auto &pair : builtin_formats())
     278                 :                :     {
     279      [ +  +  + ]:           3576 :         if (pair.second.format_string() == format_string)
     280                 :                :         {
     281            [ + ]:             15 :             id_ = pair.first;
     282                 :             15 :             break;
     283                 :                :         }
     284                 :                :     }
     285                 :            113 : }
     286                 :                : 
     287                 :            181 : void number_format::format_string(const std::string &format_string, std::size_t id)
     288                 :                : {
     289                 :            181 :     format_string_ = format_string;
     290                 :            181 :     id_ = id;
     291                 :            181 : }
     292                 :                : 
     293                 :           1758 : bool number_format::has_id() const
     294                 :                : {
     295                 :           1758 :     return id_.is_set();
     296                 :                : }
     297                 :                : 
     298                 :             49 : void number_format::id(std::size_t id)
     299                 :                : {
     300                 :             49 :     id_ = id;
     301                 :             49 : }
     302                 :                : 
     303                 :           1213 : std::size_t number_format::id() const
     304                 :                : {
     305         [ +  + ]:           1213 :     if (!has_id())
     306                 :                :     {
     307            [ + ]:              2 :         throw invalid_attribute();
     308                 :                :     }
     309                 :                : 
     310                 :           1211 :     return id_.get();
     311                 :                : }
     312                 :                : 
     313                 :              4 : bool number_format::is_date_format() const
     314                 :                : {
     315            [ + ]:              4 :     detail::number_format_parser p(format_string_);
     316            [ + ]:              4 :     p.parse();
     317         [ +  + ]:              4 :     auto parsed = p.result();
     318                 :                : 
     319                 :              4 :     bool any_datetime = false;
     320                 :              4 :     bool any_timedelta = false;
     321                 :                : 
     322         [ +  + ]:              8 :     for (const auto &section : parsed)
     323                 :                :     {
     324         [ +  - ]:              4 :         if (section.is_datetime)
     325                 :                :         {
     326                 :              4 :             any_datetime = true;
     327                 :                :         }
     328                 :                : 
     329         [ +  + ]:              4 :         if (section.is_timedelta)
     330                 :                :         {
     331                 :              1 :             any_timedelta = true;
     332                 :                :         }
     333                 :                :     }
     334                 :                : 
     335   [ +  -  +  + ]:              8 :     return any_datetime && !any_timedelta;
     336                 :              4 : }
     337                 :                : 
     338                 :             72 : std::string number_format::format(const std::string &text) const
     339                 :                : {
     340         [ +  + ]:             72 :     return detail::number_formatter(format_string_, calendar::windows_1900).format_text(text);
     341                 :                : }
     342                 :                : 
     343                 :            218 : std::string number_format::format(double number, calendar base_date) const
     344                 :                : {
     345         [ +  + ]:            218 :     return detail::number_formatter(format_string_, base_date).format_number(number);
     346                 :                : }
     347                 :                : 
     348                 :             40 : bool number_format::operator==(const number_format &other) const
     349                 :                : {
     350                 :             40 :     return format_string_ == other.format_string_;
     351                 :                : }
     352                 :                : 
     353                 :UBC           0 : bool number_format::operator!=(const number_format &other) const
     354                 :                : {
     355                 :              0 :     return !(*this == other);
     356                 :                : }
     357                 :                : 
     358                 :                : } // namespace xlnt
        

Generated by: LCOV version 2.3.1-beta