File: format_test_exceptions.cpp

package info (click to toggle)
boost1.83 1.83.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 545,632 kB
  • sloc: cpp: 3,857,086; xml: 125,552; ansic: 34,414; python: 25,887; asm: 5,276; sh: 4,799; ada: 1,681; makefile: 1,629; perl: 1,212; pascal: 1,139; sql: 810; yacc: 478; ruby: 102; lisp: 24; csh: 6
file content (105 lines) | stat: -rw-r--r-- 4,609 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// ------------------------------------------------------------------------------
// format_test_exceptions.cpp : exception handling
// ------------------------------------------------------------------------------

//  Copyright 2017 James E. King, III - Use, modification, and distribution are
//  subject to the Boost Software License, Version 1.0. (See accompanying
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

// see http://www.boost.org/libs/format for library home page

// ------------------------------------------------------------------------------

#include <boost/algorithm/string.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <boost/format.hpp>
#include <iomanip>
#include <iostream>

#define CHECK_INVALID_0(FMT, EX) { BOOST_TEST_THROWS((boost::format(FMT)).str(), EX); \
    boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe).str(); }
#define CHECK_INVALID_1(FMT, _1, EX) { BOOST_TEST_THROWS((boost::format(FMT) % _1).str(), EX); \
    boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe % _1).str(); }
#define CHECK_INVALID_2(FMT, _1, _2, EX) { BOOST_TEST_THROWS((boost::format(FMT) % _1 % _2).str(), EX); \
    boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe % _1 % _2).str(); }

int main(int, char* [])
{
    using namespace boost::io;

    // https://svn.boost.org/trac10/ticket/8735

    CHECK_INVALID_0("%", bad_format_string);          // no conversion specifier
    CHECK_INVALID_0("%|", bad_format_string);         // truncated
    CHECK_INVALID_0("%|%", bad_format_string);        // mismatched bars
    CHECK_INVALID_0("%|2%", bad_format_string);       // mismatched bars
    CHECK_INVALID_0("%'", bad_format_string);         // flag ' is ignored, no conversion specifier
    CHECK_INVALID_0("%2", bad_format_string);         // no terminating percent
    CHECK_INVALID_0("%*", bad_format_string);         // truncated
    CHECK_INVALID_1("%$2", 1, bad_format_string);     // no conversion specifier
    CHECK_INVALID_1("%$2.*", 1, bad_format_string);   // no conversion specifier
    CHECK_INVALID_0("%0%", bad_format_string);        // positional arguments start at 1
    CHECK_INVALID_2("%1%", 1, 2, too_many_args);
    CHECK_INVALID_1("%1% %2%", 1, too_few_args);

    CHECK_INVALID_0("%I", bad_format_string);
    CHECK_INVALID_0("%I2", bad_format_string);
    CHECK_INVALID_0("%I2d", bad_format_string);
    CHECK_INVALID_0("%I3", bad_format_string);
    CHECK_INVALID_0("%I3d", bad_format_string);
    CHECK_INVALID_0("%I32", bad_format_string);
    CHECK_INVALID_0("%I33", bad_format_string);
    CHECK_INVALID_0("%I6", bad_format_string);
    CHECK_INVALID_0("%I62", bad_format_string);
    CHECK_INVALID_0("%I63", bad_format_string);
    CHECK_INVALID_0("%I63d", bad_format_string);
    CHECK_INVALID_0("%I64", bad_format_string);
    CHECK_INVALID_0("%I128d", bad_format_string);
    CHECK_INVALID_0("%3.*4d", bad_format_string);

    // mixing positional and non-positional
    CHECK_INVALID_2("%1% %2d", 1, 2, bad_format_string);
    CHECK_INVALID_2("%2d %2%", 1, 2, bad_format_string);

    // found while improving coverage - a number following the * for width
    // or precision was being eaten instead of being treated as an error
    CHECK_INVALID_0("%1$*4d", bad_format_string);
    CHECK_INVALID_0("%1$05.*32d", bad_format_string);
    CHECK_INVALID_0("%1$05.*6", bad_format_string);

    // found while improving coverage, this caused an unhandled exception
    // the "T" conversion specifier didn't handle the exception flags properly
    CHECK_INVALID_0("%1$T", bad_format_string);       // missing fill character

    // test what() on exceptions
    format_error base_err;
    BOOST_TEST_GT(strlen(base_err.what()), 0u);

    bad_format_string bfs(2, 3);
    BOOST_TEST(boost::contains(bfs.what(), "bad_format_string"));

    too_few_args tfa(5, 4);
    BOOST_TEST(boost::contains(tfa.what(), "format-string"));

    too_many_args tma(4, 5);
    BOOST_TEST(boost::contains(tma.what(), "format-string"));

    boost::io::out_of_range oor(1, 2, 3);
    BOOST_TEST(boost::contains(oor.what(), "out_of_range"));

    // bind and unbind
    boost::format two("%1%, %2%");
    two.bind_arg(1, 1);
    two.bind_arg(2, 2);
    BOOST_TEST_EQ(two.str(), "1, 2");

    two.clear_bind(1);
    BOOST_TEST_THROWS(two.str(), too_few_args);
    BOOST_TEST_THROWS(two.clear_bind(1), boost::io::out_of_range);
    two.exceptions(no_error_bits);
    two.clear_bind(1);
    two.str();

    return boost::report_errors();
}