LCOV - code coverage report
Current view: top level - tests - catch_tokenize_format.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 292 301 97.0 %
Date: 2023-05-29 16:11:08 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2023  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/snapdev
       4             : // contact@m2osw.com
       5             : //
       6             : // This program is free software: you can redistribute it and/or modify
       7             : // it under the terms of the GNU General Public License as published by
       8             : // the Free Software Foundation, either version 3 of the License, or
       9             : // (at your option) any later version.
      10             : //
      11             : // This program is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : //
      16             : // You should have received a copy of the GNU General Public License
      17             : // along with this program.  If not, see <https://www.gnu.org/licenses/>.
      18             : 
      19             : /** \file
      20             :  * \brief Verify that the tokenize_format functions & traits work.
      21             :  *
      22             :  * This file implements tests for the tokenize_format functions and
      23             :  * traits for printf(3) and strftime(3).
      24             :  */
      25             : 
      26             : // self
      27             : //
      28             : #include    <snapdev/tokenize_format.h>
      29             : 
      30             : #include    "catch_main.h"
      31             : 
      32             : 
      33             : // last include
      34             : //
      35             : #include    <snapdev/poison.h>
      36             : 
      37             : 
      38             : namespace
      39             : {
      40             : 
      41             : 
      42             : 
      43             : constexpr char const * const g_printf_letters = "diouxXeEfFgGaAcsCSpnm";
      44             : 
      45             : 
      46             : struct printf_size_t
      47             : {
      48             :     char const * const              f_flag = nullptr;
      49             :     snapdev::format_flag_t const    f_length = snapdev::FORMAT_FLAG_NONE;
      50             : };
      51             : 
      52             : constexpr printf_size_t const g_printf_sizes[] = {
      53             :     {
      54             :         "",
      55             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_INT,
      56             :     },
      57             :     {
      58             :         "hh",
      59             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR,
      60             :     },
      61             :     {
      62             :         "h",
      63             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT,
      64             :     },
      65             :     {
      66             :         "l",
      67             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG,
      68             :     },
      69             :     {
      70             :         "ll",
      71             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG,
      72             :     },
      73             :     {
      74             :         "q",
      75             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG,
      76             :     },
      77             :     {
      78             :         "L",
      79             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_DOUBLE,
      80             :     },
      81             :     {
      82             :         "j",
      83             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_INTMAX_T,
      84             :     },
      85             :     {
      86             :         "z",
      87             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T,
      88             :     },
      89             :     {
      90             :         "Z",
      91             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T,
      92             :     },
      93             :     {
      94             :         "t",
      95             :         snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_PTRDFF_T,
      96             :     },
      97             : };
      98             : 
      99             : 
     100             : 
     101             : struct printf_result_t
     102             : {
     103             :     snapdev::format_error_set_t     f_errors = {};
     104             :     char const * const              f_string = nullptr;
     105             :     snapdev::format_flag_t const    f_flags = snapdev::FORMAT_FLAG_NONE;
     106             :     int                             f_width = snapdev::format_item<char>::NUMBER_UNDEFINED;
     107             :     int                             f_precision = snapdev::format_item<char>::NUMBER_UNDEFINED;
     108             :     int                             f_position = snapdev::format_item<char>::NUMBER_UNDEFINED;
     109             :     char                            f_format = '\0';
     110             : };
     111             : 
     112             : struct printf_formats_t
     113             : {
     114             :     char const * const              f_format_string = nullptr;
     115             :     std::list<printf_result_t>      f_results = {};
     116             : };
     117             : 
     118             : printf_formats_t const g_printf_formats[] =
     119             : {
     120             :     {
     121             :         .f_format_string = "Data Driven %% Tests",
     122             :         .f_results = {
     123             :             {
     124             :                 .f_string = "Data Driven ",
     125             :             },
     126             :             {
     127             :                 .f_string = "%",
     128             :             },
     129             :             {
     130             :                 .f_string = " Tests",
     131             :             },
     132             :         },
     133             :     },
     134             :     {
     135             :         .f_format_string = "Position %32$i Only",
     136             :         .f_results = {
     137             :             {
     138             :                 .f_string = "Position ",
     139             :             },
     140             :             {
     141             :                 .f_string = "%32$i",  // for now this keeps the original...
     142             :                 .f_position = 32,
     143             :                 .f_format = 'd',
     144             :             },
     145             :             {
     146             :                 .f_string = " Only",
     147             :             },
     148             :         },
     149             :     },
     150             :     {
     151             :         .f_format_string = "Width %72d Only",
     152             :         .f_results = {
     153             :             {
     154             :                 .f_string = "Width ",
     155             :             },
     156             :             {
     157             :                 .f_string = "%72d",
     158             :                 .f_width = 72,
     159             :                 .f_format = 'd',
     160             :             },
     161             :             {
     162             :                 .f_string = " Only",
     163             :             },
     164             :         },
     165             :     },
     166             :     {
     167             :         .f_format_string = "Precision %l.l23x Only",
     168             :         .f_results = {
     169             :             {
     170             :                 .f_string = "Precision ",
     171             :             },
     172             :             {
     173             :                 .f_string = "%l.l23x",
     174             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG,
     175             :                 .f_precision = 23,
     176             :                 .f_format = 'x',
     177             :             },
     178             :             {
     179             :                 .f_string = " Only",
     180             :             },
     181             :         },
     182             :     },
     183             :     {
     184             :         .f_format_string = "Width/Precision/Position %4$72.41lX Mix",
     185             :         .f_results = {
     186             :             {
     187             :                 .f_string = "Width/Precision/Position ",
     188             :             },
     189             :             {
     190             :                 .f_string = "%4$72.41lX",
     191             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG,
     192             :                 .f_width = 72,
     193             :                 .f_precision = 41,
     194             :                 .f_position = 4,
     195             :                 .f_format = 'X',
     196             :             },
     197             :             {
     198             :                 .f_string = " Mix",
     199             :             },
     200             :         },
     201             :     },
     202             :     {
     203             :         .f_format_string = "Width/Precision %*.h*u Dynamic",
     204             :         .f_results = {
     205             :             {
     206             :                 .f_string = "Width/Precision ",
     207             :             },
     208             :             {
     209             :                 .f_string = "%*.h*u",
     210             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT,
     211             :                 .f_width = 0,
     212             :                 .f_precision = 0,
     213             :                 .f_format = 'u',
     214             :             },
     215             :             {
     216             :                 .f_string = " Dynamic",
     217             :             },
     218             :         },
     219             :     },
     220             :     {
     221             :         .f_format_string = "Position/Width/Precision %h*3$.*5$h1$o Ultra Dynamic",
     222             :         .f_results = {
     223             :             {
     224             :                 .f_string = "Position/Width/Precision ",
     225             :             },
     226             :             {
     227             :                 .f_string = "%h*3$.*5$h1$o",
     228             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR,
     229             :                 .f_width = -3,
     230             :                 .f_precision = -5,
     231             :                 .f_position = 1,
     232             :                 .f_format = 'o',
     233             :             },
     234             :             {
     235             :                 .f_string = " Ultra Dynamic",
     236             :             },
     237             :         },
     238             :     },
     239             :     {
     240             :         .f_format_string = "Space Sign %7$ q*8$.*2$f Flag",
     241             :         .f_results = {
     242             :             {
     243             :                 .f_string = "Space Sign ",
     244             :             },
     245             :             {
     246             :                 .f_string = "%7$ q*8$.*2$f",
     247             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG
     248             :                          | snapdev::printf_flag_traits<char>::FORMAT_FLAG_SPACE_SIGN,
     249             :                 .f_width = -8,
     250             :                 .f_precision = -2,
     251             :                 .f_position = 7,
     252             :                 .f_format = 'f',
     253             :             },
     254             :             {
     255             :                 .f_string = " Flag",
     256             :             },
     257             :         },
     258             :     },
     259             :     {
     260             :         .f_format_string = "Left Adjusted %10000$-q*8$.*2$f Flag",
     261             :         .f_results = {
     262             :             {
     263             :                 .f_string = "Left Adjusted ",
     264             :             },
     265             :             {
     266             :                 .f_string = "%10000$-q*8$.*2$f",
     267             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG
     268             :                          | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LEFT_ADJUSTED,
     269             :                 .f_width = -8,
     270             :                 .f_precision = -2,
     271             :                 .f_position = 10000,
     272             :                 .f_format = 'f',
     273             :             },
     274             :             {
     275             :                 .f_string = " Flag",
     276             :             },
     277             :         },
     278             :     },
     279             :     {
     280             :         .f_format_string = "Alternate Form %1$#*10000$.*5$C Flag",
     281             :         .f_results = {
     282             :             {
     283             :                 .f_string = "Alternate Form ",
     284             :             },
     285             :             {
     286             :                 .f_string = "%1$#*10000$.*5$C",
     287             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG
     288             :                          | snapdev::printf_flag_traits<char>::FORMAT_FLAG_ALTERNATE_FORM,
     289             :                 .f_width = -10000,
     290             :                 .f_precision = -5,
     291             :                 .f_position = 1,
     292             :                 .f_format = 'c',
     293             :             },
     294             :             {
     295             :                 .f_string = " Flag",
     296             :             },
     297             :         },
     298             :     },
     299             :     {
     300             :         .f_format_string = "Show Sign %1$301.*10000$+S Flag",
     301             :         .f_results = {
     302             :             {
     303             :                 .f_string = "Show Sign ",
     304             :             },
     305             :             {
     306             :                 .f_string = "%1$301.*10000$+S",
     307             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG
     308             :                          | snapdev::printf_flag_traits<char>::FORMAT_FLAG_SHOW_SIGN,
     309             :                 .f_width = 301,
     310             :                 .f_precision = -10000,
     311             :                 .f_position = 1,
     312             :                 .f_format = 's',
     313             :             },
     314             :             {
     315             :                 .f_string = " Flag",
     316             :             },
     317             :         },
     318             :     },
     319             :     {
     320             :         .f_format_string = "Grouping %'1$301.*31$S Flag",
     321             :         .f_results = {
     322             :             {
     323             :                 .f_string = "Grouping ",
     324             :             },
     325             :             {
     326             :                 .f_string = "%'1$301.*31$S",
     327             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG
     328             :                          | snapdev::printf_flag_traits<char>::FORMAT_FLAG_GROUPING,
     329             :                 .f_width = 301,
     330             :                 .f_precision = -31,
     331             :                 .f_position = 1,
     332             :                 .f_format = 's',
     333             :             },
     334             :             {
     335             :                 .f_string = " Flag",
     336             :             },
     337             :         },
     338             :     },
     339             :     {
     340             :         .f_format_string = "Alternate Digits %2$307.I*41$zG Flag",
     341             :         .f_results = {
     342             :             {
     343             :                 .f_string = "Alternate Digits ",
     344             :             },
     345             :             {
     346             :                 .f_string = "%2$307.I*41$zG",
     347             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T
     348             :                          | snapdev::printf_flag_traits<char>::FORMAT_FLAG_ALTERNATE_DIGITS,
     349             :                 .f_width = 307,
     350             :                 .f_precision = -41,
     351             :                 .f_position = 2,
     352             :                 .f_format = 'G',
     353             :             },
     354             :             {
     355             :                 .f_string = " Flag",
     356             :             },
     357             :         },
     358             :     },
     359             :     {
     360             :         .f_format_string = "Error %--e Duplicate",
     361             :         .f_results = {
     362             :             {
     363             :                 .f_string = "Error ",
     364             :             },
     365             :             {
     366             :                 .f_errors = {
     367             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     368             :                 },
     369             :                 .f_string = "%--e",
     370             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LEFT_ADJUSTED,
     371             :                 .f_format = 'e',
     372             :             },
     373             :             {
     374             :                 .f_string = " Duplicate",
     375             :             },
     376             :         },
     377             :     },
     378             :     {
     379             :         .f_format_string = "Error %  E Duplicate",
     380             :         .f_results = {
     381             :             {
     382             :                 .f_string = "Error ",
     383             :             },
     384             :             {
     385             :                 .f_errors = {
     386             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     387             :                 },
     388             :                 .f_string = "%  E",
     389             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_SPACE_SIGN,
     390             :                 .f_format = 'E',
     391             :             },
     392             :             {
     393             :                 .f_string = " Duplicate",
     394             :             },
     395             :         },
     396             :     },
     397             :     {
     398             :         .f_format_string = "Error %##G Duplicate",
     399             :         .f_results = {
     400             :             {
     401             :                 .f_string = "Error ",
     402             :             },
     403             :             {
     404             :                 .f_errors = {
     405             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     406             :                 },
     407             :                 .f_string = "%##G",
     408             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_ALTERNATE_FORM,
     409             :                 .f_format = 'G',
     410             :             },
     411             :             {
     412             :                 .f_string = " Duplicate",
     413             :             },
     414             :         },
     415             :     },
     416             :     {
     417             :         .f_format_string = "Error %++f Duplicate",
     418             :         .f_results = {
     419             :             {
     420             :                 .f_string = "Error ",
     421             :             },
     422             :             {
     423             :                 .f_errors = {
     424             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     425             :                 },
     426             :                 .f_string = "%++f",
     427             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_SHOW_SIGN,
     428             :                 .f_format = 'f',
     429             :             },
     430             :             {
     431             :                 .f_string = " Duplicate",
     432             :             },
     433             :         },
     434             :     },
     435             :     {
     436             :         .f_format_string = "Error %''F Duplicate",
     437             :         .f_results = {
     438             :             {
     439             :                 .f_string = "Error ",
     440             :             },
     441             :             {
     442             :                 .f_errors = {
     443             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     444             :                 },
     445             :                 .f_string = "%''F",
     446             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_GROUPING,
     447             :                 .f_format = 'F',
     448             :             },
     449             :             {
     450             :                 .f_string = " Duplicate",
     451             :             },
     452             :         },
     453             :     },
     454             :     {
     455             :         .f_format_string = "Error %IIA Duplicate",
     456             :         .f_results = {
     457             :             {
     458             :                 .f_string = "Error ",
     459             :             },
     460             :             {
     461             :                 .f_errors = {
     462             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     463             :                 },
     464             :                 .f_string = "%IIA",
     465             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_ALTERNATE_DIGITS,
     466             :                 .f_format = 'A',
     467             :             },
     468             :             {
     469             :                 .f_string = " Duplicate",
     470             :             },
     471             :         },
     472             :     },
     473             :     {
     474             :         .f_format_string = "Unknown Format %h*Y Error",
     475             :         .f_results = {
     476             :             {
     477             :                 .f_string = "Unknown Format ",
     478             :             },
     479             :             {
     480             :                 .f_errors = {
     481             :                     snapdev::format_error_t::FORMAT_ERROR_UNKNOWN,
     482             :                 },
     483             :                 .f_string = "%",
     484             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT,
     485             :                 .f_width = 0,
     486             :             },
     487             :             {
     488             :                 .f_string = "h*Y Error",
     489             :             },
     490             :         },
     491             :     },
     492             :     {
     493             :         .f_format_string = "Duplicated Width %h*h4p Error",
     494             :         .f_results = {
     495             :             {
     496             :                 .f_string = "Duplicated Width ",
     497             :             },
     498             :             {
     499             :                 .f_errors = {
     500             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     501             :                 },
     502             :                 .f_string = "%h*h4p",
     503             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR,
     504             :                 .f_width = 4,
     505             :                 .f_format = 'p',
     506             :             },
     507             :             {
     508             :                 .f_string = " Error",
     509             :             },
     510             :         },
     511             :     },
     512             :     {
     513             :         .f_format_string = "Duplicated Width %l4l*n Error",
     514             :         .f_results = {
     515             :             {
     516             :                 .f_string = "Duplicated Width ",
     517             :             },
     518             :             {
     519             :                 .f_errors = {
     520             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     521             :                 },
     522             :                 .f_string = "%l4l*n",
     523             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG,
     524             :                 .f_width = 0,
     525             :                 .f_format = 'n',
     526             :             },
     527             :             {
     528             :                 .f_string = " Error",
     529             :             },
     530             :         },
     531             :     },
     532             :     {
     533             :         .f_format_string = "Mismatch Widths %*4hhp Error",
     534             :         .f_results = {
     535             :             {
     536             :                 .f_string = "Mismatch Widths ",
     537             :             },
     538             :             {
     539             :                 .f_errors = {
     540             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
     541             :                 },
     542             :                 .f_string = "%*4hhp",
     543             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR,
     544             :                 .f_width = 4,
     545             :                 .f_format = 'p',
     546             :             },
     547             :             {
     548             :                 .f_string = " Error",
     549             :             },
     550             :         },
     551             :     },
     552             :     {
     553             :         .f_format_string = "Lone $ %L$m Error",
     554             :         .f_results = {
     555             :             {
     556             :                 .f_string = "Lone $ ",
     557             :             },
     558             :             {
     559             :                 .f_errors = {
     560             :                     snapdev::format_error_t::FORMAT_ERROR_SYNTAX,
     561             :                 },
     562             :                 .f_string = "%",
     563             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_DOUBLE,
     564             :             },
     565             :             {
     566             :                 .f_string = "L$m Error",
     567             :             },
     568             :         },
     569             :     },
     570             :     {
     571             :         .f_format_string = "Duplicated Width %.h*h4p Error",
     572             :         .f_results = {
     573             :             {
     574             :                 .f_string = "Duplicated Width ",
     575             :             },
     576             :             {
     577             :                 .f_errors = {
     578             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     579             :                 },
     580             :                 .f_string = "%.h*h4p",
     581             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR,
     582             :                 .f_precision = 4,
     583             :                 .f_format = 'p',
     584             :             },
     585             :             {
     586             :                 .f_string = " Error",
     587             :             },
     588             :         },
     589             :     },
     590             :     {
     591             :         .f_format_string = "Duplicated Width %.l4l*n Error",
     592             :         .f_results = {
     593             :             {
     594             :                 .f_string = "Duplicated Width ",
     595             :             },
     596             :             {
     597             :                 .f_errors = {
     598             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     599             :                 },
     600             :                 .f_string = "%.l4l*n",
     601             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG,
     602             :                 .f_precision = 0,
     603             :                 .f_format = 'n',
     604             :             },
     605             :             {
     606             :                 .f_string = " Error",
     607             :             },
     608             :         },
     609             :     },
     610             :     {
     611             :         .f_format_string = "Mismatch Widths %.*4hhp Error",
     612             :         .f_results = {
     613             :             {
     614             :                 .f_string = "Mismatch Widths ",
     615             :             },
     616             :             {
     617             :                 .f_errors = {
     618             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
     619             :                 },
     620             :                 .f_string = "%.*4hhp",
     621             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR,
     622             :                 .f_precision = 4,
     623             :                 .f_format = 'p',
     624             :             },
     625             :             {
     626             :                 .f_string = " Error",
     627             :             },
     628             :         },
     629             :     },
     630             :     {
     631             :         .f_format_string = "Two Positions %4$1$Zp Error",
     632             :         .f_results = {
     633             :             {
     634             :                 .f_string = "Two Positions ",
     635             :             },
     636             :             {
     637             :                 .f_errors = {
     638             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     639             :                 },
     640             :                 .f_string = "%4$1$Zp",
     641             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T,
     642             :                 .f_position = 1,
     643             :                 .f_format = 'p',
     644             :             },
     645             :             {
     646             :                 .f_string = " Error",
     647             :             },
     648             :         },
     649             :     },
     650             :     {
     651             :         .f_format_string = "End Of String %z*",
     652             :         .f_results = {
     653             :             {
     654             :                 .f_string = "End Of String ",
     655             :             },
     656             :             {
     657             :                 .f_errors = {
     658             :                     snapdev::format_error_t::FORMAT_ERROR_EOS,
     659             :                 },
     660             :                 .f_string = "%z*",
     661             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T,
     662             :                 .f_width = 0,
     663             :             },
     664             :         },
     665             :     },
     666             :     {
     667             :         .f_format_string = "End Of String %.z*",
     668             :         .f_results = {
     669             :             {
     670             :                 .f_string = "End Of String ",
     671             :             },
     672             :             {
     673             :                 .f_errors = {
     674             :                     snapdev::format_error_t::FORMAT_ERROR_EOS,
     675             :                 },
     676             :                 .f_string = "%.z*",
     677             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T,
     678             :                 .f_precision = 0,
     679             :             },
     680             :         },
     681             :     },
     682             :     {
     683             :         .f_format_string = "End Of String %1..5zp",
     684             :         .f_results = {
     685             :             {
     686             :                 .f_string = "End Of String ",
     687             :             },
     688             :             {
     689             :                 .f_errors = {
     690             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     691             :                 },
     692             :                 .f_string = "%1..5zp",
     693             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SIZE_T,
     694             :                 .f_width = 1,
     695             :                 .f_precision = 5,
     696             :                 .f_format = 'p',
     697             :             },
     698             :         },
     699             :     },
     700             :     {
     701             :         .f_format_string = "End Of String %10001Lp",
     702             :         .f_results = {
     703             :             {
     704             :                 .f_string = "End Of String ",
     705             :             },
     706             :             {
     707             :                 .f_errors = {
     708             :                     snapdev::format_error_t::FORMAT_ERROR_OVERFLOW,
     709             :                 },
     710             :                 .f_string = "%10001Lp",
     711             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_DOUBLE,
     712             :                 .f_width = 10000,
     713             :                 .f_format = 'p',
     714             :             },
     715             :         },
     716             :     },
     717             :     {
     718             :         .f_format_string = "End Of String %1j*a",
     719             :         .f_results = {
     720             :             {
     721             :                 .f_string = "End Of String ",
     722             :             },
     723             :             {
     724             :                 .f_errors = {
     725             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     726             :                 },
     727             :                 .f_string = "%1j*a",
     728             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_INTMAX_T,
     729             :                 .f_width = 0,
     730             :                 .f_format = 'a',
     731             :             },
     732             :         },
     733             :     },
     734             :     {
     735             :         .f_format_string = "End Of String %.1j*a",
     736             :         .f_results = {
     737             :             {
     738             :                 .f_string = "End Of String ",
     739             :             },
     740             :             {
     741             :                 .f_errors = {
     742             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     743             :                 },
     744             :                 .f_string = "%.1j*a",
     745             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_INTMAX_T,
     746             :                 .f_precision = 0,
     747             :                 .f_format = 'a',
     748             :             },
     749             :         },
     750             :     },
     751             :     {
     752             :         .f_format_string = "End Of String %1j*3$A",
     753             :         .f_results = {
     754             :             {
     755             :                 .f_string = "End Of String ",
     756             :             },
     757             :             {
     758             :                 .f_errors = {
     759             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     760             :                 },
     761             :                 .f_string = "%1j*3$A",
     762             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_INTMAX_T,
     763             :                 .f_width = -3,
     764             :                 .f_format = 'A',
     765             :             },
     766             :         },
     767             :     },
     768             :     {
     769             :         .f_format_string = "End Of String %.1j*3$A",
     770             :         .f_results = {
     771             :             {
     772             :                 .f_string = "End Of String ",
     773             :             },
     774             :             {
     775             :                 .f_errors = {
     776             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
     777             :                 },
     778             :                 .f_string = "%.1j*3$A",
     779             :                 .f_flags = snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_INTMAX_T,
     780             :                 .f_precision = -3,
     781             :                 .f_format = 'A',
     782             :             },
     783             :         },
     784             :     },
     785             : };
     786             : 
     787             : 
     788             : printf_formats_t const g_strftime_formats[] =
     789             : {
     790             :     {
     791             :         .f_format_string = "Data Driven %% Tests",
     792             :         .f_results = {
     793             :             {
     794             :                 .f_string = "Data Driven ",
     795             :             },
     796             :             {
     797             :                 .f_string = "%",
     798             :             },
     799             :             {
     800             :                 .f_string = " Tests",
     801             :             },
     802             :         },
     803             :     },
     804             :     {
     805             :         .f_format_string = "Simple %a Code",
     806             :         .f_results = {
     807             :             {
     808             :                 .f_string = "Simple ",
     809             :             },
     810             :             {
     811             :                 .f_string = "%a",
     812             :                 .f_format = 'a',
     813             :             },
     814             :             {
     815             :                 .f_string = " Code",
     816             :             },
     817             :         },
     818             :     },
     819             :     {
     820             :         .f_format_string = "Week Day %_A and Space Pad",
     821             :         .f_results = {
     822             :             {
     823             :                 .f_string = "Week Day ",
     824             :             },
     825             :             {
     826             :                 .f_string = "%_A",
     827             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES,
     828             :                 .f_format = 'A',
     829             :             },
     830             :             {
     831             :                 .f_string = " and Space Pad",
     832             :             },
     833             :         },
     834             :     },
     835             :     {
     836             :         .f_format_string = "Abbr Month %-b without pad",
     837             :         .f_results = {
     838             :             {
     839             :                 .f_string = "Abbr Month ",
     840             :             },
     841             :             {
     842             :                 .f_string = "%-b",
     843             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD,
     844             :                 .f_format = 'b',
     845             :             },
     846             :             {
     847             :                 .f_string = " without pad",
     848             :             },
     849             :         },
     850             :     },
     851             :     {
     852             :         .f_format_string = "Month %0B Zero Pad",
     853             :         .f_results = {
     854             :             {
     855             :                 .f_string = "Month ",
     856             :             },
     857             :             {
     858             :                 .f_string = "%0B",
     859             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
     860             :                 .f_format = 'B',
     861             :             },
     862             :             {
     863             :                 .f_string = " Zero Pad",
     864             :             },
     865             :         },
     866             :     },
     867             :     {
     868             :         .f_format_string = "Default Date %^c Uppercase",
     869             :         .f_results = {
     870             :             {
     871             :                 .f_string = "Default Date ",
     872             :             },
     873             :             {
     874             :                 .f_string = "%^c",
     875             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE,
     876             :                 .f_format = 'c',
     877             :             },
     878             :             {
     879             :                 .f_string = " Uppercase",
     880             :             },
     881             :         },
     882             :     },
     883             :     {
     884             :         .f_format_string = "Century %#C Swap Case",
     885             :         .f_results = {
     886             :             {
     887             :                 .f_string = "Century ",
     888             :             },
     889             :             {
     890             :                 .f_string = "%#C",
     891             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_SWAP_CASE,
     892             :                 .f_format = 'C',
     893             :             },
     894             :             {
     895             :                 .f_string = " Swap Case",
     896             :             },
     897             :         },
     898             :     },
     899             :     {
     900             :         .f_format_string = "Day %Od Alternate",
     901             :         .f_results = {
     902             :             {
     903             :                 .f_string = "Day ",
     904             :             },
     905             :             {
     906             :                 .f_string = "%Od",
     907             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
     908             :                 .f_format = 'd',
     909             :             },
     910             :             {
     911             :                 .f_string = " Alternate",
     912             :             },
     913             :         },
     914             :     },
     915             :     {
     916             :         .f_format_string = "Date %_^D Pad/Upper",
     917             :         .f_results = {
     918             :             {
     919             :                 .f_string = "Date ",
     920             :             },
     921             :             {
     922             :                 .f_string = "%_^D",
     923             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES
     924             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE,
     925             :                 .f_format = 'D',
     926             :             },
     927             :             {
     928             :                 .f_string = " Pad/Upper",
     929             :             },
     930             :         },
     931             :     },
     932             :     {
     933             :         .f_format_string = "Alternate Form %-#Oe Flag",
     934             :         .f_results = {
     935             :             {
     936             :                 .f_string = "Alternate Form ",
     937             :             },
     938             :             {
     939             :                 .f_string = "%-#Oe",
     940             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD
     941             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_SWAP_CASE
     942             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
     943             :                 .f_format = 'e',
     944             :             },
     945             :             {
     946             :                 .f_string = " Flag",
     947             :             },
     948             :         },
     949             :     },
     950             :     {
     951             :         .f_format_string = "ISO 8601 %^0F Date",
     952             :         .f_results = {
     953             :             {
     954             :                 .f_string = "ISO 8601 ",
     955             :             },
     956             :             {
     957             :                 .f_string = "%^0F",
     958             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES
     959             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE,
     960             :                 .f_format = 'F',
     961             :             },
     962             :             {
     963             :                 .f_string = " Date",
     964             :             },
     965             :         },
     966             :     },
     967             :     {
     968             :         .f_format_string = "Year %G Based on Week",
     969             :         .f_results = {
     970             :             {
     971             :                 .f_string = "Year ",
     972             :             },
     973             :             {
     974             :                 .f_string = "%G",
     975             :                 .f_format = 'G',
     976             :             },
     977             :             {
     978             :                 .f_string = " Based on Week",
     979             :             },
     980             :         },
     981             :     },
     982             :     {
     983             :         .f_format_string = "Small %g Year",
     984             :         .f_results = {
     985             :             {
     986             :                 .f_string = "Small ",
     987             :             },
     988             :             {
     989             :                 .f_string = "%g",
     990             :                 .f_format = 'g',
     991             :             },
     992             :             {
     993             :                 .f_string = " Year",
     994             :             },
     995             :         },
     996             :     },
     997             :     {
     998             :         .f_format_string = "Switch to b %--h and Duplicate",
     999             :         .f_results = {
    1000             :             {
    1001             :                 .f_string = "Switch to b ",
    1002             :             },
    1003             :             {
    1004             :                 .f_errors = {
    1005             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
    1006             :                 },
    1007             :                 .f_string = "%--h",
    1008             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD,
    1009             :                 .f_format = 'b',
    1010             :             },
    1011             :             {
    1012             :                 .f_string = " and Duplicate",
    1013             :             },
    1014             :         },
    1015             :     },
    1016             :     {
    1017             :         .f_format_string = "Hour %__H and Duplicate",
    1018             :         .f_results = {
    1019             :             {
    1020             :                 .f_string = "Hour ",
    1021             :             },
    1022             :             {
    1023             :                 .f_errors = {
    1024             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
    1025             :                 },
    1026             :                 .f_string = "%__H",
    1027             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES,
    1028             :                 .f_format = 'H',
    1029             :             },
    1030             :             {
    1031             :                 .f_string = " and Duplicate",
    1032             :             },
    1033             :         },
    1034             :     },
    1035             :     {
    1036             :         .f_format_string = "12h %##I and Duplicate",
    1037             :         .f_results = {
    1038             :             {
    1039             :                 .f_string = "12h ",
    1040             :             },
    1041             :             {
    1042             :                 .f_errors = {
    1043             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
    1044             :                 },
    1045             :                 .f_string = "%##I",
    1046             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_SWAP_CASE,
    1047             :                 .f_format = 'I',
    1048             :             },
    1049             :             {
    1050             :                 .f_string = " and Duplicate",
    1051             :             },
    1052             :         },
    1053             :     },
    1054             :     {
    1055             :         .f_format_string = "Year Day %00j and Duplicate",
    1056             :         .f_results = {
    1057             :             {
    1058             :                 .f_string = "Year Day ",
    1059             :             },
    1060             :             {
    1061             :                 .f_errors = {
    1062             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
    1063             :                 },
    1064             :                 .f_string = "%00j",
    1065             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1066             :                 .f_format = 'j',
    1067             :             },
    1068             :             {
    1069             :                 .f_string = " and Duplicate",
    1070             :             },
    1071             :         },
    1072             :     },
    1073             :     {
    1074             :         .f_format_string = "24h %^^k and Duplicate",
    1075             :         .f_results = {
    1076             :             {
    1077             :                 .f_string = "24h ",
    1078             :             },
    1079             :             {
    1080             :                 .f_errors = {
    1081             :                     snapdev::format_error_t::FORMAT_ERROR_DUPLICATE,
    1082             :                 },
    1083             :                 .f_string = "%^^k",
    1084             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE,
    1085             :                 .f_format = 'k',
    1086             :             },
    1087             :             {
    1088             :                 .f_string = " and Duplicate",
    1089             :             },
    1090             :         },
    1091             :     },
    1092             :     {
    1093             :         .f_format_string = "12h %_0l and Mismatch",
    1094             :         .f_results = {
    1095             :             {
    1096             :                 .f_string = "12h ",
    1097             :             },
    1098             :             {
    1099             :                 .f_errors = {
    1100             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
    1101             :                 },
    1102             :                 .f_string = "%_0l",
    1103             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES
    1104             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1105             :                 .f_format = 'l',
    1106             :             },
    1107             :             {
    1108             :                 .f_string = " and Mismatch",
    1109             :             },
    1110             :         },
    1111             :     },
    1112             :     {
    1113             :         .f_format_string = "Month %0_m Mismatch",
    1114             :         .f_results = {
    1115             :             {
    1116             :                 .f_string = "Month ",
    1117             :             },
    1118             :             {
    1119             :                 .f_errors = {
    1120             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
    1121             :                 },
    1122             :                 .f_string = "%0_m",
    1123             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES
    1124             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1125             :                 .f_format = 'm',
    1126             :             },
    1127             :             {
    1128             :                 .f_string = " Mismatch",
    1129             :             },
    1130             :         },
    1131             :     },
    1132             :     {
    1133             :         .f_format_string = "Minutes %_-M and Mismatch",
    1134             :         .f_results = {
    1135             :             {
    1136             :                 .f_string = "Minutes ",
    1137             :             },
    1138             :             {
    1139             :                 .f_errors = {
    1140             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
    1141             :                 },
    1142             :                 .f_string = "%_-M",
    1143             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD
    1144             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES,
    1145             :                 .f_format = 'M',
    1146             :             },
    1147             :             {
    1148             :                 .f_string = " and Mismatch",
    1149             :             },
    1150             :         },
    1151             :     },
    1152             :     {
    1153             :         .f_format_string = "Newline %-_n and Mismatch",
    1154             :         .f_results = {
    1155             :             {
    1156             :                 .f_string = "Newline ",
    1157             :             },
    1158             :             {
    1159             :                 .f_errors = {
    1160             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
    1161             :                 },
    1162             :                 .f_string = "%-_n",
    1163             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD
    1164             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES,
    1165             :                 .f_format = 'n',
    1166             :             },
    1167             :             {
    1168             :                 .f_string = " and Mismatch",
    1169             :             },
    1170             :         },
    1171             :     },
    1172             :     {
    1173             :         .f_format_string = "Nanoseconds %-N (for us)",
    1174             :         .f_results = {
    1175             :             {
    1176             :                 .f_string = "Nanoseconds ",
    1177             :             },
    1178             :             {
    1179             :                 .f_string = "%-N",
    1180             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD,
    1181             :                 .f_format = 'N',
    1182             :             },
    1183             :             {
    1184             :                 .f_string = " (for us)",
    1185             :             },
    1186             :         },
    1187             :     },
    1188             :     {
    1189             :         .f_format_string = "AM/PM %-0p Mismatch",
    1190             :         .f_results = {
    1191             :             {
    1192             :                 .f_string = "AM/PM ",
    1193             :             },
    1194             :             {
    1195             :                 .f_errors = {
    1196             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
    1197             :                 },
    1198             :                 .f_string = "%-0p",
    1199             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD
    1200             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1201             :                 .f_format = 'p',
    1202             :             },
    1203             :             {
    1204             :                 .f_string = " Mismatch",
    1205             :             },
    1206             :         },
    1207             :     },
    1208             :     {
    1209             :         .f_format_string = "am/pm %0-P and Mismatch",
    1210             :         .f_results = {
    1211             :             {
    1212             :                 .f_string = "am/pm ",
    1213             :             },
    1214             :             {
    1215             :                 .f_errors = {
    1216             :                     snapdev::format_error_t::FORMAT_ERROR_MISMATCH,
    1217             :                 },
    1218             :                 .f_string = "%0-P",
    1219             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_NO_PAD
    1220             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1221             :                 .f_format = 'P',
    1222             :             },
    1223             :             {
    1224             :                 .f_string = " and Mismatch",
    1225             :             },
    1226             :         },
    1227             :     },
    1228             :     {
    1229             :         .f_format_string = "Time %^#r Upper/Flip",
    1230             :         .f_results = {
    1231             :             {
    1232             :                 .f_string = "Time ",
    1233             :             },
    1234             :             {
    1235             :                 .f_string = "%^#r",
    1236             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE
    1237             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_SWAP_CASE,
    1238             :                 .f_format = 'r',
    1239             :             },
    1240             :             {
    1241             :                 .f_string = " Upper/Flip",
    1242             :             },
    1243             :         },
    1244             :     },
    1245             :     {
    1246             :         .f_format_string = "Time %#^r Flip/Upper",
    1247             :         .f_results = {
    1248             :             {
    1249             :                 .f_string = "Time ",
    1250             :             },
    1251             :             {
    1252             :                 .f_string = "%#^r",
    1253             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE
    1254             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_SWAP_CASE,
    1255             :                 .f_format = 'r',
    1256             :             },
    1257             :             {
    1258             :                 .f_string = " Flip/Upper",
    1259             :             },
    1260             :         },
    1261             :     },
    1262             :     {
    1263             :         .f_format_string = "Basic Time %R",
    1264             :         .f_results = {
    1265             :             {
    1266             :                 .f_string = "Basic Time ",
    1267             :             },
    1268             :             {
    1269             :                 .f_string = "%R",
    1270             :                 .f_format = 'R',
    1271             :             },
    1272             :         },
    1273             :     },
    1274             :     {
    1275             :         .f_format_string = "Seconds %s.%EN Nanoseconds",
    1276             :         .f_results = {
    1277             :             {
    1278             :                 .f_string = "Seconds ",
    1279             :             },
    1280             :             {
    1281             :                 .f_string = "%s",
    1282             :                 .f_format = 's',
    1283             :             },
    1284             :             {
    1285             :                 .f_string = ".",
    1286             :             },
    1287             :             {
    1288             :                 .f_string = "%EN",
    1289             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1290             :                 .f_format = 'N',
    1291             :             },
    1292             :             {
    1293             :                 .f_string = " Nanoseconds",
    1294             :             },
    1295             :         },
    1296             :     },
    1297             :     {
    1298             :         .f_format_string = "2-digit seconds %02S no error",
    1299             :         .f_results = {
    1300             :             {
    1301             :                 .f_string = "2-digit seconds ",
    1302             :             },
    1303             :             {
    1304             :                 .f_string = "%02S",
    1305             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1306             :                 .f_width = 2,
    1307             :                 .f_format = 'S',
    1308             :             },
    1309             :             {
    1310             :                 .f_string = " no error",
    1311             :             },
    1312             :         },
    1313             :     },
    1314             :     {
    1315             :         .f_format_string = "Tab %t Char",
    1316             :         .f_results = {
    1317             :             {
    1318             :                 .f_string = "Tab ",
    1319             :             },
    1320             :             {
    1321             :                 .f_string = "%t",
    1322             :                 .f_format = 't',
    1323             :             },
    1324             :             {
    1325             :                 .f_string = " Char",
    1326             :             },
    1327             :         },
    1328             :     },
    1329             :     {
    1330             :         .f_format_string = "End Of String %_#^",
    1331             :         .f_results = {
    1332             :             {
    1333             :                 .f_string = "End Of String ",
    1334             :             },
    1335             :             {
    1336             :                 .f_errors = {
    1337             :                     snapdev::format_error_t::FORMAT_ERROR_EOS,
    1338             :                 },
    1339             :                 .f_string = "%_#^",
    1340             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_SPACES
    1341             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE
    1342             :                          | snapdev::strftime_flag_traits<char>::FORMAT_FLAG_SWAP_CASE,
    1343             :             },
    1344             :         },
    1345             :     },
    1346             :     {
    1347             :         .f_format_string = "Time %^5T and EOS %",
    1348             :         .f_results = {
    1349             :             {
    1350             :                 .f_string = "Time ",
    1351             :             },
    1352             :             {
    1353             :                 .f_string = "%^5T",
    1354             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_UPPERCASE,
    1355             :                 .f_width = 5,
    1356             :                 .f_format = 'T',
    1357             :             },
    1358             :             {
    1359             :                 .f_string = " and EOS ",
    1360             :             },
    1361             :             {
    1362             :                 .f_errors = {
    1363             :                     snapdev::format_error_t::FORMAT_ERROR_EOS,
    1364             :                 },
    1365             :                 .f_string = "%",
    1366             :             },
    1367             :         },
    1368             :     },
    1369             :     {
    1370             :         .f_format_string = "%0u Start Of String",
    1371             :         .f_results = {
    1372             :             {
    1373             :                 .f_string = "%0u",
    1374             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_PAD_WITH_ZEROES,
    1375             :                 .f_format = 'u',
    1376             :             },
    1377             :             {
    1378             :                 .f_string = " Start Of String",
    1379             :             },
    1380             :         },
    1381             :     },
    1382             :     {
    1383             :         .f_format_string = "%U%10V%w",
    1384             :         .f_results = {
    1385             :             {
    1386             :                 .f_string = "%U",
    1387             :                 .f_format = 'U',
    1388             :             },
    1389             :             {
    1390             :                 .f_string = "%10V",
    1391             :                 .f_width = 10,
    1392             :                 .f_format = 'V',
    1393             :             },
    1394             :             {
    1395             :                 .f_string = "%w",
    1396             :                 .f_format = 'w',
    1397             :             },
    1398             :         },
    1399             :     },
    1400             :     {
    1401             :         .f_format_string = "without%Wspaces",
    1402             :         .f_results = {
    1403             :             {
    1404             :                 .f_string = "without",
    1405             :             },
    1406             :             {
    1407             :                 .f_string = "%W",
    1408             :                 .f_format = 'W',
    1409             :             },
    1410             :             {
    1411             :                 .f_string = "spaces",
    1412             :             },
    1413             :         },
    1414             :     },
    1415             :     {
    1416             :         .f_format_string = "Unknown %q Error",
    1417             :         .f_results = {
    1418             :             {
    1419             :                 .f_string = "Unknown ",
    1420             :             },
    1421             :             {
    1422             :                 .f_errors = {
    1423             :                     snapdev::format_error_t::FORMAT_ERROR_UNKNOWN,
    1424             :                 },
    1425             :                 .f_string = "%",
    1426             :             },
    1427             :             {
    1428             :                 .f_string = "q Error",
    1429             :             },
    1430             :         },
    1431             :     },
    1432             :     {
    1433             :         .f_format_string = "No %3.4z Separator",
    1434             :         .f_results = {
    1435             :             {
    1436             :                 .f_string = "No ",
    1437             :             },
    1438             :             {
    1439             :                 .f_errors = {
    1440             :                     snapdev::format_error_t::FORMAT_ERROR_UNKNOWN,
    1441             :                 },
    1442             :                 .f_string = "%",
    1443             :                 .f_width = 3,
    1444             :             },
    1445             :             {
    1446             :                 .f_string = "3.4z Separator",
    1447             :             },
    1448             :         },
    1449             :     },
    1450             :     {
    1451             :         .f_format_string = "Date %x Only",
    1452             :         .f_results = {
    1453             :             {
    1454             :                 .f_string = "Date ",
    1455             :             },
    1456             :             {
    1457             :                 .f_string = "%x",
    1458             :                 .f_format = 'x',
    1459             :             },
    1460             :             {
    1461             :                 .f_string = " Only",
    1462             :             },
    1463             :         },
    1464             :     },
    1465             :     {
    1466             :         .f_format_string = "Time %X Only",
    1467             :         .f_results = {
    1468             :             {
    1469             :                 .f_string = "Time ",
    1470             :             },
    1471             :             {
    1472             :                 .f_string = "%X",
    1473             :                 .f_format = 'X',
    1474             :             },
    1475             :             {
    1476             :                 .f_string = " Only",
    1477             :             },
    1478             :         },
    1479             :     },
    1480             :     {
    1481             :         .f_format_string = "Year %y without century",
    1482             :         .f_results = {
    1483             :             {
    1484             :                 .f_string = "Year ",
    1485             :             },
    1486             :             {
    1487             :                 .f_string = "%y",
    1488             :                 .f_format = 'y',
    1489             :             },
    1490             :             {
    1491             :                 .f_string = " without century",
    1492             :             },
    1493             :         },
    1494             :     },
    1495             :     {
    1496             :         .f_format_string = "Full %Y year",
    1497             :         .f_results = {
    1498             :             {
    1499             :                 .f_string = "Full ",
    1500             :             },
    1501             :             {
    1502             :                 .f_string = "%Y",
    1503             :                 .f_format = 'Y',
    1504             :             },
    1505             :             {
    1506             :                 .f_string = " year",
    1507             :             },
    1508             :         },
    1509             :     },
    1510             :     {
    1511             :         .f_format_string = "Zone %z (numeric)",
    1512             :         .f_results = {
    1513             :             {
    1514             :                 .f_string = "Zone ",
    1515             :             },
    1516             :             {
    1517             :                 .f_string = "%z",
    1518             :                 .f_format = 'z',
    1519             :             },
    1520             :             {
    1521             :                 .f_string = " (numeric)",
    1522             :             },
    1523             :         },
    1524             :     },
    1525             :     {
    1526             :         .f_format_string = "Zone %Z (abbr)",
    1527             :         .f_results = {
    1528             :             {
    1529             :                 .f_string = "Zone ",
    1530             :             },
    1531             :             {
    1532             :                 .f_string = "%Z",
    1533             :                 .f_format = 'Z',
    1534             :             },
    1535             :             {
    1536             :                 .f_string = " (abbr)",
    1537             :             },
    1538             :         },
    1539             :     },
    1540             :     {
    1541             :         .f_format_string = "date(1) %+ format",
    1542             :         .f_results = {
    1543             :             {
    1544             :                 .f_string = "date(1) ",
    1545             :             },
    1546             :             {
    1547             :                 .f_string = "%+",
    1548             :                 .f_format = '+',
    1549             :             },
    1550             :             {
    1551             :                 .f_string = " format",
    1552             :             },
    1553             :         },
    1554             :     },
    1555             :     {
    1556             :         .f_format_string = "extended %Ec format",
    1557             :         .f_results = {
    1558             :             {
    1559             :                 .f_string = "extended ",
    1560             :             },
    1561             :             {
    1562             :                 .f_string = "%Ec",
    1563             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1564             :                 .f_format = 'c',
    1565             :             },
    1566             :             {
    1567             :                 .f_string = " format",
    1568             :             },
    1569             :         },
    1570             :     },
    1571             :     {
    1572             :         .f_format_string = "extended %EC format",
    1573             :         .f_results = {
    1574             :             {
    1575             :                 .f_string = "extended ",
    1576             :             },
    1577             :             {
    1578             :                 .f_string = "%EC",
    1579             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1580             :                 .f_format = 'C',
    1581             :             },
    1582             :             {
    1583             :                 .f_string = " format",
    1584             :             },
    1585             :         },
    1586             :     },
    1587             :     {
    1588             :         .f_format_string = "extended %Ex format",
    1589             :         .f_results = {
    1590             :             {
    1591             :                 .f_string = "extended ",
    1592             :             },
    1593             :             {
    1594             :                 .f_string = "%Ex",
    1595             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1596             :                 .f_format = 'x',
    1597             :             },
    1598             :             {
    1599             :                 .f_string = " format",
    1600             :             },
    1601             :         },
    1602             :     },
    1603             :     {
    1604             :         .f_format_string = "extended %EX format",
    1605             :         .f_results = {
    1606             :             {
    1607             :                 .f_string = "extended ",
    1608             :             },
    1609             :             {
    1610             :                 .f_string = "%EX",
    1611             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1612             :                 .f_format = 'X',
    1613             :             },
    1614             :             {
    1615             :                 .f_string = " format",
    1616             :             },
    1617             :         },
    1618             :     },
    1619             :     {
    1620             :         .f_format_string = "extended %Ey format",
    1621             :         .f_results = {
    1622             :             {
    1623             :                 .f_string = "extended ",
    1624             :             },
    1625             :             {
    1626             :                 .f_string = "%Ey",
    1627             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1628             :                 .f_format = 'y',
    1629             :             },
    1630             :             {
    1631             :                 .f_string = " format",
    1632             :             },
    1633             :         },
    1634             :     },
    1635             :     {
    1636             :         .f_format_string = "extended %EY format",
    1637             :         .f_results = {
    1638             :             {
    1639             :                 .f_string = "extended ",
    1640             :             },
    1641             :             {
    1642             :                 .f_string = "%EY",
    1643             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1644             :                 .f_format = 'Y',
    1645             :             },
    1646             :             {
    1647             :                 .f_string = " format",
    1648             :             },
    1649             :         },
    1650             :     },
    1651             :     {
    1652             :         .f_format_string = "modified %Od format",
    1653             :         .f_results = {
    1654             :             {
    1655             :                 .f_string = "modified ",
    1656             :             },
    1657             :             {
    1658             :                 .f_string = "%Od",
    1659             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1660             :                 .f_format = 'd',
    1661             :             },
    1662             :             {
    1663             :                 .f_string = " format",
    1664             :             },
    1665             :         },
    1666             :     },
    1667             :     {
    1668             :         .f_format_string = "modified %Oe format",
    1669             :         .f_results = {
    1670             :             {
    1671             :                 .f_string = "modified ",
    1672             :             },
    1673             :             {
    1674             :                 .f_string = "%Oe",
    1675             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1676             :                 .f_format = 'e',
    1677             :             },
    1678             :             {
    1679             :                 .f_string = " format",
    1680             :             },
    1681             :         },
    1682             :     },
    1683             :     {
    1684             :         .f_format_string = "modified %OH format",
    1685             :         .f_results = {
    1686             :             {
    1687             :                 .f_string = "modified ",
    1688             :             },
    1689             :             {
    1690             :                 .f_string = "%OH",
    1691             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1692             :                 .f_format = 'H',
    1693             :             },
    1694             :             {
    1695             :                 .f_string = " format",
    1696             :             },
    1697             :         },
    1698             :     },
    1699             :     {
    1700             :         .f_format_string = "modified %OI format",
    1701             :         .f_results = {
    1702             :             {
    1703             :                 .f_string = "modified ",
    1704             :             },
    1705             :             {
    1706             :                 .f_string = "%OI",
    1707             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1708             :                 .f_format = 'I',
    1709             :             },
    1710             :             {
    1711             :                 .f_string = " format",
    1712             :             },
    1713             :         },
    1714             :     },
    1715             :     {
    1716             :         .f_format_string = "modified %Om format",
    1717             :         .f_results = {
    1718             :             {
    1719             :                 .f_string = "modified ",
    1720             :             },
    1721             :             {
    1722             :                 .f_string = "%Om",
    1723             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1724             :                 .f_format = 'm',
    1725             :             },
    1726             :             {
    1727             :                 .f_string = " format",
    1728             :             },
    1729             :         },
    1730             :     },
    1731             :     {
    1732             :         .f_format_string = "modified %OM format",
    1733             :         .f_results = {
    1734             :             {
    1735             :                 .f_string = "modified ",
    1736             :             },
    1737             :             {
    1738             :                 .f_string = "%OM",
    1739             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1740             :                 .f_format = 'M',
    1741             :             },
    1742             :             {
    1743             :                 .f_string = " format",
    1744             :             },
    1745             :         },
    1746             :     },
    1747             :     {
    1748             :         .f_format_string = "modified %OS format",
    1749             :         .f_results = {
    1750             :             {
    1751             :                 .f_string = "modified ",
    1752             :             },
    1753             :             {
    1754             :                 .f_string = "%OS",
    1755             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1756             :                 .f_format = 'S',
    1757             :             },
    1758             :             {
    1759             :                 .f_string = " format",
    1760             :             },
    1761             :         },
    1762             :     },
    1763             :     {
    1764             :         .f_format_string = "modified %Ou format",
    1765             :         .f_results = {
    1766             :             {
    1767             :                 .f_string = "modified ",
    1768             :             },
    1769             :             {
    1770             :                 .f_string = "%Ou",
    1771             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1772             :                 .f_format = 'u',
    1773             :             },
    1774             :             {
    1775             :                 .f_string = " format",
    1776             :             },
    1777             :         },
    1778             :     },
    1779             :     {
    1780             :         .f_format_string = "modified %OU format",
    1781             :         .f_results = {
    1782             :             {
    1783             :                 .f_string = "modified ",
    1784             :             },
    1785             :             {
    1786             :                 .f_string = "%OU",
    1787             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1788             :                 .f_format = 'U',
    1789             :             },
    1790             :             {
    1791             :                 .f_string = " format",
    1792             :             },
    1793             :         },
    1794             :     },
    1795             :     {
    1796             :         .f_format_string = "modified %OV format",
    1797             :         .f_results = {
    1798             :             {
    1799             :                 .f_string = "modified ",
    1800             :             },
    1801             :             {
    1802             :                 .f_string = "%OV",
    1803             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1804             :                 .f_format = 'V',
    1805             :             },
    1806             :             {
    1807             :                 .f_string = " format",
    1808             :             },
    1809             :         },
    1810             :     },
    1811             :     {
    1812             :         .f_format_string = "modified %Ow format",
    1813             :         .f_results = {
    1814             :             {
    1815             :                 .f_string = "modified ",
    1816             :             },
    1817             :             {
    1818             :                 .f_string = "%Ow",
    1819             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1820             :                 .f_format = 'w',
    1821             :             },
    1822             :             {
    1823             :                 .f_string = " format",
    1824             :             },
    1825             :         },
    1826             :     },
    1827             :     {
    1828             :         .f_format_string = "modified %OW format",
    1829             :         .f_results = {
    1830             :             {
    1831             :                 .f_string = "modified ",
    1832             :             },
    1833             :             {
    1834             :                 .f_string = "%OW",
    1835             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1836             :                 .f_format = 'W',
    1837             :             },
    1838             :             {
    1839             :                 .f_string = " format",
    1840             :             },
    1841             :         },
    1842             :     },
    1843             :     {
    1844             :         .f_format_string = "modified %Oy format",
    1845             :         .f_results = {
    1846             :             {
    1847             :                 .f_string = "modified ",
    1848             :             },
    1849             :             {
    1850             :                 .f_string = "%Oy",
    1851             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_MODIFIER,
    1852             :                 .f_format = 'y',
    1853             :             },
    1854             :             {
    1855             :                 .f_string = " format",
    1856             :             },
    1857             :         },
    1858             :     },
    1859             :     {
    1860             :         .f_format_string = "extended %Ef unknown",
    1861             :         .f_results = {
    1862             :             {
    1863             :                 .f_string = "extended ",
    1864             :             },
    1865             :             {
    1866             :                 .f_errors = {
    1867             :                     snapdev::format_error_t::FORMAT_ERROR_UNKNOWN,
    1868             :                 },
    1869             :                 .f_string = "%",
    1870             :             },
    1871             :             {
    1872             :                 .f_string = "Ef unknown",
    1873             :             },
    1874             :         },
    1875             :     },
    1876             :     {
    1877             :         .f_format_string = "modified %Of unknown",
    1878             :         .f_results = {
    1879             :             {
    1880             :                 .f_string = "modified ",
    1881             :             },
    1882             :             {
    1883             :                 .f_errors = {
    1884             :                     snapdev::format_error_t::FORMAT_ERROR_UNKNOWN,
    1885             :                 },
    1886             :                 .f_string = "%",
    1887             :             },
    1888             :             {
    1889             :                 .f_string = "Of unknown",
    1890             :             },
    1891             :         },
    1892             :     },
    1893             :     {
    1894             :         .f_format_string = "Overflow at end %10001Ey",
    1895             :         .f_results = {
    1896             :             {
    1897             :                 .f_string = "Overflow at end ",
    1898             :             },
    1899             :             {
    1900             :                 .f_errors = {
    1901             :                     snapdev::format_error_t::FORMAT_ERROR_OVERFLOW,
    1902             :                 },
    1903             :                 .f_string = "%10001Ey",
    1904             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1905             :                 .f_width = 10000,
    1906             :                 .f_format = 'y',
    1907             :             },
    1908             :         },
    1909             :     },
    1910             :     {
    1911             :         .f_format_string = "Overflow at end %99999Ey",
    1912             :         .f_results = {
    1913             :             {
    1914             :                 .f_string = "Overflow at end ",
    1915             :             },
    1916             :             {
    1917             :                 .f_errors = {
    1918             :                     snapdev::format_error_t::FORMAT_ERROR_OVERFLOW,
    1919             :                 },
    1920             :                 .f_string = "%99999Ey",
    1921             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1922             :                 .f_width = 10000,
    1923             :                 .f_format = 'y',
    1924             :             },
    1925             :         },
    1926             :     },
    1927             :     {
    1928             :         .f_format_string = "Overflow at end %3472830Ey",
    1929             :         .f_results = {
    1930             :             {
    1931             :                 .f_string = "Overflow at end ",
    1932             :             },
    1933             :             {
    1934             :                 .f_errors = {
    1935             :                     snapdev::format_error_t::FORMAT_ERROR_OVERFLOW,
    1936             :                 },
    1937             :                 .f_string = "%3472830Ey",
    1938             :                 .f_flags = snapdev::strftime_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    1939             :                 .f_width = 10000,
    1940             :                 .f_format = 'y',
    1941             :             },
    1942             :         },
    1943             :     },
    1944             : };
    1945             : 
    1946             : 
    1947             : 
    1948             : // the full implementation is found in the advgetopt library
    1949             : //
    1950             : template<typename _CharT>
    1951             : class usage_flag_traits
    1952             : {
    1953             : public:
    1954             :     typedef _CharT  char_t;
    1955             : 
    1956             :     static constexpr snapdev::format_flag_t const       FORMAT_FLAG_EXTENDED = 0x0001; // '*'
    1957             : 
    1958           3 :     static bool is_flag(char_t c, snapdev::format_item<_CharT> & f)
    1959             :     {
    1960           3 :         if(c == '*')
    1961             :         {
    1962           1 :             if(f.has_flags(FORMAT_FLAG_EXTENDED))
    1963             :             {
    1964           0 :                 f.add_error(snapdev::format_error_t::FORMAT_ERROR_DUPLICATE);
    1965             :             }
    1966           1 :             f.add_flags(FORMAT_FLAG_EXTENDED);
    1967           1 :             return true;
    1968             :         }
    1969           2 :         return false;
    1970             :     }
    1971             : };
    1972             : 
    1973             : template<typename _CharT>
    1974             : class usage_letter_traits
    1975             : {
    1976             : public:
    1977           2 :     static std::basic_string<_CharT>::size_type is_format(char const * s, snapdev::format_item<_CharT> & f)
    1978             :     {
    1979           2 :         if(s[0] == 'a'
    1980           1 :         || s[0] == 'd')
    1981             :         {
    1982           2 :             f.format(s[0]);
    1983           2 :             return 1UL;
    1984             :         }
    1985           0 :         f.add_error(snapdev::format_error_t::FORMAT_ERROR_UNKNOWN);
    1986           0 :         return 0;
    1987             :     }
    1988             : };
    1989             : 
    1990             : 
    1991             : printf_formats_t const g_usage_formats[] =
    1992             : {
    1993             :     {
    1994             :         .f_format_string = "Data Driven %% Tests",
    1995             :         .f_results = {
    1996             :             {
    1997             :                 .f_string = "Data Driven ",
    1998             :             },
    1999             :             {
    2000             :                 .f_string = "%",
    2001             :             },
    2002             :             {
    2003             :                 .f_string = " Tests",
    2004             :             },
    2005             :         },
    2006             :     },
    2007             :     {
    2008             :         .f_format_string = "Simple %a Code",
    2009             :         .f_results = {
    2010             :             {
    2011             :                 .f_string = "Simple ",
    2012             :             },
    2013             :             {
    2014             :                 .f_string = "%a",
    2015             :                 .f_format = 'a',
    2016             :             },
    2017             :             {
    2018             :                 .f_string = " Code",
    2019             :             },
    2020             :         },
    2021             :     },
    2022             :     {
    2023             :         .f_format_string = "Extended %*d Format",
    2024             :         .f_results = {
    2025             :             {
    2026             :                 .f_string = "Extended ",
    2027             :             },
    2028             :             {
    2029             :                 .f_string = "%*d",
    2030             :                 .f_flags = usage_flag_traits<char>::FORMAT_FLAG_EXTENDED,
    2031             :                 .f_format = 'd',
    2032             :             },
    2033             :             {
    2034             :                 .f_string = " Format",
    2035             :             },
    2036             :         },
    2037             :     },
    2038             : };
    2039             : 
    2040             : 
    2041             : 
    2042             : }
    2043             : // no name namespace
    2044             : 
    2045             : 
    2046             : 
    2047           5 : CATCH_TEST_CASE("tokenize_format_printf", "[string]")
    2048             : {
    2049           5 :     CATCH_START_SECTION("tokenize_format_printf: escape %")
    2050             :     {
    2051           1 :         snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2052             :                   char
    2053             :                 , snapdev::printf_letter_traits<char>
    2054             :                 , snapdev::printf_flag_traits<char>
    2055           3 :                 , snapdev::printf_number_traits<char>>("Test %% by itself"));
    2056             : 
    2057           1 :         CATCH_REQUIRE(items.size() == 3);
    2058             : 
    2059           1 :         auto it(items.begin());
    2060             : 
    2061           1 :         CATCH_REQUIRE(it->errors().empty());
    2062           1 :         CATCH_REQUIRE_FALSE(it->has_errors());
    2063           1 :         CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_DUPLICATE));
    2064           1 :         CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_EOS));
    2065           1 :         CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_MISMATCH));
    2066           1 :         CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_OVERFLOW));
    2067           1 :         CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_SYNTAX));
    2068           1 :         CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_UNKNOWN));
    2069           1 :         CATCH_REQUIRE(it->string() == "Test ");
    2070           1 :         CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2071          33 :         for(std::size_t flag(0); flag < sizeof(snapdev::format_flag_t) * CHAR_BIT; ++flag)
    2072             :         {
    2073          32 :             CATCH_REQUIRE_FALSE(it->has_flags(static_cast<snapdev::format_flag_t>(1LL << flag)));
    2074             :         }
    2075           1 :         CATCH_REQUIRE_FALSE(it->has_width());
    2076           1 :         CATCH_REQUIRE_FALSE(it->has_precision());
    2077           1 :         CATCH_REQUIRE_FALSE(it->has_position());
    2078           1 :         CATCH_REQUIRE_FALSE(it->is_format());
    2079             : 
    2080           1 :         ++it;
    2081           1 :         CATCH_REQUIRE_FALSE(it->has_errors());
    2082           1 :         CATCH_REQUIRE(it->string() == "%");
    2083           1 :         CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2084           1 :         CATCH_REQUIRE_FALSE(it->has_width());
    2085           1 :         CATCH_REQUIRE_FALSE(it->has_precision());
    2086           1 :         CATCH_REQUIRE_FALSE(it->has_position());
    2087           1 :         CATCH_REQUIRE_FALSE(it->is_format());
    2088             : 
    2089           1 :         ++it;
    2090           1 :         CATCH_REQUIRE_FALSE(it->has_errors());
    2091           1 :         CATCH_REQUIRE(it->string() == " by itself");
    2092           1 :         CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2093           1 :         CATCH_REQUIRE_FALSE(it->has_width());
    2094           1 :         CATCH_REQUIRE_FALSE(it->has_precision());
    2095           1 :         CATCH_REQUIRE_FALSE(it->has_position());
    2096           1 :         CATCH_REQUIRE_FALSE(it->is_format());
    2097           1 :     }
    2098           5 :     CATCH_END_SECTION()
    2099             : 
    2100           5 :     CATCH_START_SECTION("tokenize_format_printf: letters only")
    2101             :     {
    2102          22 :         for(char const * s(g_printf_letters); *s != '\0'; ++s)
    2103             :         {
    2104          21 :             snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2105             :                       char
    2106             :                     , snapdev::printf_letter_traits<char>
    2107             :                     , snapdev::printf_flag_traits<char>
    2108         105 :                     , snapdev::printf_number_traits<char>>(std::string("Letter %") + *s + " by itself"));
    2109             : 
    2110          21 :             CATCH_REQUIRE(items.size() == 3);
    2111             : 
    2112          21 :             auto it(items.begin());
    2113             : 
    2114          21 :             CATCH_REQUIRE(it->errors().empty());
    2115          21 :             CATCH_REQUIRE_FALSE(it->has_errors());
    2116          21 :             CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_DUPLICATE));
    2117          21 :             CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_EOS));
    2118          21 :             CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_MISMATCH));
    2119          21 :             CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_OVERFLOW));
    2120          21 :             CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_SYNTAX));
    2121          21 :             CATCH_REQUIRE_FALSE(it->has_error(snapdev::format_error_t::FORMAT_ERROR_UNKNOWN));
    2122          21 :             CATCH_REQUIRE(it->string() == "Letter ");
    2123          21 :             CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2124         693 :             for(std::size_t flag(0); flag < sizeof(snapdev::format_flag_t) * CHAR_BIT; ++flag)
    2125             :             {
    2126         672 :                 CATCH_REQUIRE_FALSE(it->has_flags(static_cast<snapdev::format_flag_t>(1LL << flag)));
    2127             :             }
    2128          21 :             CATCH_REQUIRE_FALSE(it->has_width());
    2129          21 :             CATCH_REQUIRE_FALSE(it->has_precision());
    2130          21 :             CATCH_REQUIRE_FALSE(it->has_position());
    2131          21 :             CATCH_REQUIRE_FALSE(it->is_format());
    2132             : 
    2133          21 :             ++it;
    2134          21 :             CATCH_REQUIRE_FALSE(it->has_errors());
    2135          21 :             CATCH_REQUIRE(it->string() == std::string("%") + *s);
    2136          21 :             char letter(*s);
    2137          21 :             switch(letter)
    2138             :             {
    2139           1 :             case 'i':
    2140           1 :                 letter = 'd';
    2141           1 :                 break;
    2142             : 
    2143           2 :             case 'S':
    2144             :             case 'C':
    2145           2 :                 CATCH_REQUIRE(it->flags() == snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG);
    2146           2 :                 letter = letter | 0x20;
    2147           2 :                 break;
    2148             : 
    2149          18 :             default:
    2150          18 :                 CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2151          18 :                 break;
    2152             : 
    2153             :             }
    2154          21 :             CATCH_REQUIRE_FALSE(it->has_width());
    2155          21 :             CATCH_REQUIRE_FALSE(it->has_precision());
    2156          21 :             CATCH_REQUIRE_FALSE(it->has_position());
    2157          21 :             CATCH_REQUIRE(it->is_format());
    2158          21 :             CATCH_REQUIRE(it->format() == letter);
    2159             : 
    2160          21 :             ++it;
    2161          21 :             CATCH_REQUIRE_FALSE(it->has_errors());
    2162          21 :             CATCH_REQUIRE(it->string() == " by itself");
    2163          21 :             CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2164          21 :             CATCH_REQUIRE_FALSE(it->has_width());
    2165          21 :             CATCH_REQUIRE_FALSE(it->has_precision());
    2166          21 :             CATCH_REQUIRE_FALSE(it->has_position());
    2167          21 :             CATCH_REQUIRE_FALSE(it->is_format());
    2168          21 :         }
    2169             :     }
    2170           5 :     CATCH_END_SECTION()
    2171             : 
    2172           5 :     CATCH_START_SECTION("tokenize_format_printf: size + format")
    2173             :     {
    2174          12 :         for(std::size_t idx(0); idx < std::size(g_printf_sizes); ++idx)
    2175             :         {
    2176          11 :             snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2177             :                       char
    2178             :                     , snapdev::printf_letter_traits<char>
    2179             :                     , snapdev::printf_flag_traits<char>
    2180          55 :                     , snapdev::printf_number_traits<char>>(std::string("Sized %") + g_printf_sizes[idx].f_flag + "d format"));
    2181             : 
    2182          11 :             CATCH_REQUIRE(items.size() == 3);
    2183             : 
    2184          11 :             auto it(items.begin());
    2185             : 
    2186          11 :             CATCH_REQUIRE(it->errors().empty());
    2187          11 :             CATCH_REQUIRE_FALSE(it->has_errors());
    2188          11 :             CATCH_REQUIRE(it->string() == "Sized ");
    2189          11 :             CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2190          11 :             CATCH_REQUIRE_FALSE(it->has_width());
    2191          11 :             CATCH_REQUIRE_FALSE(it->has_precision());
    2192          11 :             CATCH_REQUIRE_FALSE(it->has_position());
    2193          11 :             CATCH_REQUIRE_FALSE(it->is_format());
    2194             : 
    2195          11 :             ++it;
    2196          11 :             CATCH_REQUIRE_FALSE(it->has_errors());
    2197          11 :             CATCH_REQUIRE(it->string() == std::string("%") + g_printf_sizes[idx].f_flag + "d");
    2198          11 :             CATCH_REQUIRE(it->flags() == g_printf_sizes[idx].f_length);
    2199          11 :             CATCH_REQUIRE_FALSE(it->has_width());
    2200          11 :             CATCH_REQUIRE_FALSE(it->has_precision());
    2201          11 :             CATCH_REQUIRE_FALSE(it->has_position());
    2202          11 :             CATCH_REQUIRE(it->is_format());
    2203          11 :             CATCH_REQUIRE(it->format() == 'd');
    2204             : 
    2205          11 :             ++it;
    2206          11 :             CATCH_REQUIRE_FALSE(it->has_errors());
    2207          11 :             CATCH_REQUIRE(it->string() == " format");
    2208          11 :             CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2209          11 :             CATCH_REQUIRE_FALSE(it->has_width());
    2210          11 :             CATCH_REQUIRE_FALSE(it->has_precision());
    2211          11 :             CATCH_REQUIRE_FALSE(it->has_position());
    2212          11 :             CATCH_REQUIRE_FALSE(it->is_format());
    2213          11 :         }
    2214             :     }
    2215           5 :     CATCH_END_SECTION()
    2216             : 
    2217           5 :     CATCH_START_SECTION("tokenize_format_printf: size defined twice")
    2218             :     {
    2219           2 :         snapdev::format_error_set_t duplicate{ snapdev::format_error_t::FORMAT_ERROR_DUPLICATE };
    2220           1 :         int format(rand() % (sizeof(g_printf_letters) - 1));
    2221          12 :         for(std::size_t i(0); i < std::size(g_printf_sizes); ++i)
    2222             :         {
    2223         132 :             for(std::size_t j(0); j < std::size(g_printf_sizes); ++j)
    2224             :             {
    2225         121 :                 if(strcmp(g_printf_sizes[i].f_flag, "") == 0
    2226         110 :                 || strcmp(g_printf_sizes[j].f_flag, "") == 0
    2227         100 :                 || (strcmp(g_printf_sizes[i].f_flag, "h") == 0 && strcmp(g_printf_sizes[j].f_flag, "h") == 0)
    2228          99 :                 || (strcmp(g_printf_sizes[i].f_flag, "l") == 0 && strcmp(g_printf_sizes[j].f_flag, "l") == 0))
    2229             :                 {
    2230             :                     // doubling these won't generate an error
    2231             :                     // and here we are verifying duplicates
    2232             :                     //
    2233          23 :                     continue;
    2234             :                 }
    2235             : 
    2236         196 :                 std::string pattern("%");
    2237          98 :                 pattern += g_printf_sizes[i].f_flag;
    2238          98 :                 pattern += g_printf_sizes[j].f_flag;
    2239          98 :                 pattern += g_printf_letters[format];
    2240             : //std::cerr << "  --- pattern [" << pattern << "]\n";
    2241             : 
    2242          98 :                 snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2243             :                           char
    2244             :                         , snapdev::printf_letter_traits<char>
    2245             :                         , snapdev::printf_flag_traits<char>
    2246         490 :                         , snapdev::printf_number_traits<char>>(std::string("Double sized ") + pattern + " format"));
    2247             : 
    2248          98 :                 CATCH_REQUIRE(items.size() == 3);
    2249             : 
    2250          98 :                 auto it(items.begin());
    2251             : 
    2252          98 :                 CATCH_REQUIRE_FALSE(it->has_errors());
    2253          98 :                 CATCH_REQUIRE(it->string() == "Double sized ");
    2254          98 :                 CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2255          98 :                 CATCH_REQUIRE_FALSE(it->has_width());
    2256          98 :                 CATCH_REQUIRE_FALSE(it->has_precision());
    2257          98 :                 CATCH_REQUIRE_FALSE(it->has_position());
    2258          98 :                 CATCH_REQUIRE_FALSE(it->is_format());
    2259             : 
    2260          98 :                 ++it;
    2261          98 :                 CATCH_REQUIRE(it->has_errors());
    2262          98 :                 CATCH_REQUIRE(it->errors() == duplicate);
    2263          98 :                 CATCH_REQUIRE(it->string() == pattern);
    2264          98 :                 switch((g_printf_sizes[i].f_length << 16) | g_printf_sizes[j].f_length)
    2265             :                 {
    2266           3 :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR:
    2267             :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR:
    2268             :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT:
    2269             :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_SHORT:
    2270           3 :                     CATCH_REQUIRE(it->flags() == snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_CHAR);
    2271           3 :                     break;
    2272             : 
    2273           6 :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG:
    2274             :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG:
    2275             :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG:
    2276           6 :                     CATCH_REQUIRE(it->flags() == snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG);
    2277           6 :                     break;
    2278             : 
    2279           2 :                 case (snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG << 16) | snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG:
    2280             :                     // "q" does not overwrite by "l"
    2281             :                     //
    2282           2 :                     if(strcmp(g_printf_sizes[j].f_flag, "q") == 0)
    2283             :                     {
    2284           1 :                         CATCH_REQUIRE(it->flags() == snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG);
    2285             :                     }
    2286             :                     else
    2287             :                     {
    2288           1 :                         CATCH_REQUIRE(it->flags() == snapdev::printf_flag_traits<char>::FORMAT_FLAG_LENGTH_LONG_LONG);
    2289             :                     }
    2290           2 :                     break;
    2291             : 
    2292          87 :                 default:
    2293          87 :                     CATCH_REQUIRE(it->flags() == g_printf_sizes[i].f_length);
    2294          87 :                     break;
    2295             : 
    2296             :                 }
    2297          98 :                 CATCH_REQUIRE_FALSE(it->has_width());
    2298          98 :                 CATCH_REQUIRE_FALSE(it->has_precision());
    2299          98 :                 CATCH_REQUIRE_FALSE(it->has_position());
    2300          98 :                 CATCH_REQUIRE(it->is_format());
    2301          98 :                 switch(g_printf_letters[format])
    2302             :                 {
    2303          14 :                 case 'i':
    2304          14 :                     CATCH_REQUIRE(it->format() == 'd');
    2305          14 :                     break;
    2306             : 
    2307           0 :                 case 'S':
    2308           0 :                     CATCH_REQUIRE(it->format() == 's');
    2309           0 :                     break;
    2310             : 
    2311           0 :                 case 'C':
    2312           0 :                     CATCH_REQUIRE(it->format() == 'c');
    2313           0 :                     break;
    2314             : 
    2315          84 :                 default:
    2316          84 :                     CATCH_REQUIRE(it->format() == g_printf_letters[format]);
    2317             : 
    2318             :                 }
    2319          98 :                 ++it;
    2320          98 :                 CATCH_REQUIRE_FALSE(it->has_errors());
    2321          98 :                 CATCH_REQUIRE(it->string() == " format");
    2322          98 :                 CATCH_REQUIRE(it->flags() == snapdev::FORMAT_FLAG_NONE);
    2323          98 :                 CATCH_REQUIRE_FALSE(it->has_width());
    2324          98 :                 CATCH_REQUIRE_FALSE(it->has_precision());
    2325          98 :                 CATCH_REQUIRE_FALSE(it->has_position());
    2326          98 :                 CATCH_REQUIRE_FALSE(it->is_format());
    2327             : 
    2328          98 :                 format = (format + 1) % (sizeof(g_printf_letters) - 1);
    2329          98 :             }
    2330             :         }
    2331           1 :     }
    2332           5 :     CATCH_END_SECTION()
    2333             : 
    2334           5 :     CATCH_START_SECTION("tokenize_format_printf: data driven tests")
    2335             :     {
    2336          37 :         for(std::size_t idx(0); idx < std::size(g_printf_formats); ++idx)
    2337             :         {
    2338          36 :             snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2339             :                       char
    2340             :                     , snapdev::printf_letter_traits<char>
    2341             :                     , snapdev::printf_flag_traits<char>
    2342         108 :                     , snapdev::printf_number_traits<char>>(g_printf_formats[idx].f_format_string));
    2343             : 
    2344          36 :             CATCH_REQUIRE(items.size() == g_printf_formats[idx].f_results.size());
    2345             : 
    2346          36 :             auto r(g_printf_formats[idx].f_results.begin());
    2347         136 :             for(auto it(items.begin()); it != items.end(); ++it, ++r)
    2348             :             {
    2349             : //std::cerr << "   +++ parsed [" << g_printf_formats[idx].f_format_string << "] compare item [" << it->string() << "]\n";
    2350             : //if(it->has_errors())
    2351             : //{
    2352             : //for(auto const & e : it->errors())
    2353             : //{
    2354             : //std::cerr << "     >>> error: " << static_cast<int>(e) << "\n";
    2355             : //}
    2356             : //}
    2357             :                 // verify that test data match in size (we already verified
    2358             :                 // the size, but this is better than a SEGV)
    2359             :                 //
    2360         100 :                 CATCH_REQUIRE(r != g_printf_formats[idx].f_results.end());
    2361             : 
    2362         100 :                 CATCH_REQUIRE(it->errors() == r->f_errors);
    2363         100 :                 CATCH_REQUIRE(it->string() == r->f_string);
    2364         100 :                 CATCH_REQUIRE(it->flags() == r->f_flags);
    2365         100 :                 CATCH_REQUIRE(it->width() == r->f_width);
    2366         100 :                 CATCH_REQUIRE(it->precision() == r->f_precision);
    2367         100 :                 CATCH_REQUIRE(it->position() == r->f_position);
    2368         100 :                 CATCH_REQUIRE(it->format() == r->f_format);
    2369             :             }
    2370          36 :         }
    2371             :     }
    2372           5 :     CATCH_END_SECTION()
    2373           5 : }
    2374             : 
    2375             : 
    2376           3 : CATCH_TEST_CASE("tokenize_format_strftime", "[string]")
    2377             : {
    2378           3 :     CATCH_START_SECTION("tokenize_format_strftime: no nanoseconds support")
    2379             :     {
    2380           1 :         snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2381             :                   char
    2382             :                 , snapdev::strftime_letter_traits<char>
    2383             :                 , snapdev::strftime_flag_traits<char>
    2384           3 :                 , snapdev::strftime_number_traits<char>>("%s.%N"));
    2385             : 
    2386           1 :         CATCH_REQUIRE(items.size() == 4);
    2387             : 
    2388           1 :         auto it(items.begin());
    2389             : 
    2390           1 :         CATCH_REQUIRE(it->string() == "%s");
    2391             : 
    2392           1 :         ++it;
    2393           1 :         CATCH_REQUIRE(it->string() == ".");
    2394             : 
    2395           1 :         ++it;
    2396           1 :         CATCH_REQUIRE(it->string() == "%");
    2397           1 :         CATCH_REQUIRE(it->has_errors());
    2398           1 :         CATCH_REQUIRE(it->errors() == snapdev::format_error_set_t{ snapdev::format_error_t::FORMAT_ERROR_UNKNOWN });
    2399           1 :         CATCH_REQUIRE(it->format() == '\0');
    2400             : 
    2401           1 :         ++it;
    2402           1 :         CATCH_REQUIRE(it->string() == "N");
    2403           1 :     }
    2404           3 :     CATCH_END_SECTION()
    2405             : 
    2406           3 :     CATCH_START_SECTION("tokenize_format_strftime: no nanoseconds support (extended)")
    2407             :     {
    2408           1 :         snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2409             :                   char
    2410             :                 , snapdev::strftime_letter_traits<char>
    2411             :                 , snapdev::strftime_flag_traits<char>
    2412           3 :                 , snapdev::strftime_number_traits<char>>("%s.%EN"));
    2413             : 
    2414           1 :         CATCH_REQUIRE(items.size() == 4);
    2415             : 
    2416           1 :         auto it(items.begin());
    2417             : 
    2418           1 :         CATCH_REQUIRE(it->string() == "%s");
    2419             : 
    2420           1 :         ++it;
    2421           1 :         CATCH_REQUIRE(it->string() == ".");
    2422             : 
    2423           1 :         ++it;
    2424           1 :         CATCH_REQUIRE(it->string() == "%");
    2425           1 :         CATCH_REQUIRE(it->has_errors());
    2426           1 :         CATCH_REQUIRE(it->errors() == snapdev::format_error_set_t{ snapdev::format_error_t::FORMAT_ERROR_UNKNOWN });
    2427           1 :         CATCH_REQUIRE(it->format() == '\0');
    2428             : 
    2429           1 :         ++it;
    2430           1 :         CATCH_REQUIRE(it->string() == "EN");
    2431           1 :     }
    2432           3 :     CATCH_END_SECTION()
    2433             : 
    2434           3 :     CATCH_START_SECTION("tokenize_format_strftime: data driven tests")
    2435             :     {
    2436          70 :         for(std::size_t idx(0); idx < std::size(g_strftime_formats); ++idx)
    2437             :         {
    2438          69 :             snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2439             :                       char
    2440             :                     , snapdev::strftime_letter_traits<char, true>
    2441             :                     , snapdev::strftime_flag_traits<char>
    2442         207 :                     , snapdev::strftime_number_traits<char>>(g_strftime_formats[idx].f_format_string));
    2443             : 
    2444          69 :             CATCH_REQUIRE(items.size() == g_strftime_formats[idx].f_results.size());
    2445             : 
    2446          69 :             auto r(g_strftime_formats[idx].f_results.begin());
    2447         273 :             for(auto it(items.begin()); it != items.end(); ++it, ++r)
    2448             :             {
    2449             : //std::cerr << "   +++ parsed [" << g_strftime_formats[idx].f_format_string << "] compare item [" << it->string() << "]\n";
    2450             : //if(it->has_errors())
    2451             : //{
    2452             : //for(auto const & e : it->errors())
    2453             : //{
    2454             : //std::cerr << "     >>> error: " << static_cast<int>(e) << "\n";
    2455             : //}
    2456             : //}
    2457             :                 // verify that test data match in size (we already verified
    2458             :                 // the size, but this is better than a SEGV)
    2459             :                 //
    2460         204 :                 CATCH_REQUIRE(r != g_strftime_formats[idx].f_results.end());
    2461             : 
    2462         204 :                 CATCH_REQUIRE(it->errors() == r->f_errors);
    2463         204 :                 CATCH_REQUIRE(it->string() == r->f_string);
    2464         204 :                 CATCH_REQUIRE(it->flags() == r->f_flags);
    2465         204 :                 CATCH_REQUIRE(it->width() == r->f_width);
    2466         204 :                 CATCH_REQUIRE(it->precision() == r->f_precision);
    2467         204 :                 CATCH_REQUIRE(it->position() == r->f_position);
    2468         204 :                 CATCH_REQUIRE(it->format() == r->f_format);
    2469             :             }
    2470          69 :         }
    2471             :     }
    2472           3 :     CATCH_END_SECTION()
    2473           3 : }
    2474             : 
    2475             : 
    2476             : // the following tests a small subset of the advgetopt Usage: ... format
    2477             : // support to verify the "no number" implementation
    2478             : //
    2479           1 : CATCH_TEST_CASE("tokenize_format_advgetopt", "[string]")
    2480             : {
    2481           1 :     CATCH_START_SECTION("tokenize_format_advgetopt: data driven tests")
    2482             :     {
    2483           4 :         for(std::size_t idx(0); idx < std::size(g_usage_formats); ++idx)
    2484             :         {
    2485           3 :             snapdev::format_item<char>::list_t items(snapdev::tokenize_format<
    2486             :                       char
    2487             :                     , usage_letter_traits<char>
    2488           9 :                     , usage_flag_traits<char>>(g_usage_formats[idx].f_format_string));
    2489             : 
    2490           3 :             CATCH_REQUIRE(items.size() == g_usage_formats[idx].f_results.size());
    2491             : 
    2492           3 :             auto r(g_usage_formats[idx].f_results.begin());
    2493          12 :             for(auto it(items.begin()); it != items.end(); ++it, ++r)
    2494             :             {
    2495             : //std::cerr << "   +++ parsed [" << g_usage_formats[idx].f_format_string << "] compare item [" << it->string() << "]\n";
    2496             : //if(it->has_errors())
    2497             : //{
    2498             : //for(auto const & e : it->errors())
    2499             : //{
    2500             : //std::cerr << "     >>> error: " << static_cast<int>(e) << "\n";
    2501             : //}
    2502             : //}
    2503             :                 // verify that test data match in size (we already verified
    2504             :                 // the size, but this is better than a SEGV)
    2505             :                 //
    2506           9 :                 CATCH_REQUIRE(r != g_usage_formats[idx].f_results.end());
    2507             : 
    2508           9 :                 CATCH_REQUIRE(it->errors() == r->f_errors);
    2509           9 :                 CATCH_REQUIRE(it->string() == r->f_string);
    2510           9 :                 CATCH_REQUIRE(it->flags() == r->f_flags);
    2511           9 :                 CATCH_REQUIRE(it->width() == r->f_width);
    2512           9 :                 CATCH_REQUIRE(it->precision() == r->f_precision);
    2513           9 :                 CATCH_REQUIRE(it->position() == r->f_position);
    2514           9 :                 CATCH_REQUIRE(it->format() == r->f_format);
    2515             :             }
    2516           3 :         }
    2517             :     }
    2518           1 :     CATCH_END_SECTION()
    2519           1 : }
    2520             : 
    2521             : 
    2522             : 
    2523             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.14