• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // ------------------------------------------------------------------------------
2 // format_test_exceptions.cpp : exception handling
3 // ------------------------------------------------------------------------------
4 
5 //  Copyright 2017 James E. King, III - Use, modification, and distribution are
6 //  subject to the Boost Software License, Version 1.0. (See accompanying
7 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
8 
9 // see http://www.boost.org/libs/format for library home page
10 
11 // ------------------------------------------------------------------------------
12 
13 #include <boost/algorithm/string.hpp>
14 #include <boost/detail/lightweight_test.hpp>
15 #include <boost/format.hpp>
16 #include <iomanip>
17 #include <iostream>
18 
19 #define CHECK_INVALID_0(FMT, EX) { BOOST_TEST_THROWS((boost::format(FMT)).str(), EX); \
20     boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe).str(); }
21 #define CHECK_INVALID_1(FMT, _1, EX) { BOOST_TEST_THROWS((boost::format(FMT) % _1).str(), EX); \
22     boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe % _1).str(); }
23 #define CHECK_INVALID_2(FMT, _1, _2, EX) { BOOST_TEST_THROWS((boost::format(FMT) % _1 % _2).str(), EX); \
24     boost::format safe; safe.exceptions(boost::io::no_error_bits); safe.parse(FMT); (safe % _1 % _2).str(); }
25 
main(int,char * [])26 int main(int, char* [])
27 {
28     using namespace boost::io;
29 
30     // https://svn.boost.org/trac10/ticket/8735
31 
32     CHECK_INVALID_0("%", bad_format_string);          // no conversion specifier
33     CHECK_INVALID_0("%|", bad_format_string);         // truncated
34     CHECK_INVALID_0("%|%", bad_format_string);        // mismatched bars
35     CHECK_INVALID_0("%|2%", bad_format_string);       // mismatched bars
36     CHECK_INVALID_0("%'", bad_format_string);         // flag ' is ignored, no conversion specifier
37     CHECK_INVALID_0("%2", bad_format_string);         // no terminating percent
38     CHECK_INVALID_0("%*", bad_format_string);         // truncated
39     CHECK_INVALID_1("%$2", 1, bad_format_string);     // no conversion specifier
40     CHECK_INVALID_1("%$2.*", 1, bad_format_string);   // no conversion specifier
41     CHECK_INVALID_0("%0%", bad_format_string);        // positional arguments start at 1
42     CHECK_INVALID_2("%1%", 1, 2, too_many_args);
43     CHECK_INVALID_1("%1% %2%", 1, too_few_args);
44 
45     CHECK_INVALID_0("%I", bad_format_string);
46     CHECK_INVALID_0("%I2", bad_format_string);
47     CHECK_INVALID_0("%I2d", bad_format_string);
48     CHECK_INVALID_0("%I3", bad_format_string);
49     CHECK_INVALID_0("%I3d", bad_format_string);
50     CHECK_INVALID_0("%I32", bad_format_string);
51     CHECK_INVALID_0("%I33", bad_format_string);
52     CHECK_INVALID_0("%I6", bad_format_string);
53     CHECK_INVALID_0("%I62", bad_format_string);
54     CHECK_INVALID_0("%I63", bad_format_string);
55     CHECK_INVALID_0("%I63d", bad_format_string);
56     CHECK_INVALID_0("%I64", bad_format_string);
57     CHECK_INVALID_0("%I128d", bad_format_string);
58     CHECK_INVALID_0("%3.*4d", bad_format_string);
59 
60     // mixing positional and non-positional
61     CHECK_INVALID_2("%1% %2d", 1, 2, bad_format_string);
62     CHECK_INVALID_2("%2d %2%", 1, 2, bad_format_string);
63 
64     // found while improving coverage - a number following the * for width
65     // or precision was being eaten instead of being treated as an error
66     CHECK_INVALID_0("%1$*4d", bad_format_string);
67     CHECK_INVALID_0("%1$05.*32d", bad_format_string);
68     CHECK_INVALID_0("%1$05.*6", bad_format_string);
69 
70     // found while improving coverage, this caused an unhandled exception
71     // the "T" conversion specifier didn't handle the exception flags properly
72     CHECK_INVALID_0("%1$T", bad_format_string);       // missing fill character
73 
74     // test what() on exceptions
75     format_error base_err;
76     BOOST_TEST_GT(strlen(base_err.what()), 0u);
77 
78     bad_format_string bfs(2, 3);
79     BOOST_TEST(boost::contains(bfs.what(), "bad_format_string"));
80 
81     too_few_args tfa(5, 4);
82     BOOST_TEST(boost::contains(tfa.what(), "format-string"));
83 
84     too_many_args tma(4, 5);
85     BOOST_TEST(boost::contains(tma.what(), "format-string"));
86 
87     boost::io::out_of_range oor(1, 2, 3);
88     BOOST_TEST(boost::contains(oor.what(), "out_of_range"));
89 
90     // bind and unbind
91     boost::format two("%1%, %2%");
92     two.bind_arg(1, 1);
93     two.bind_arg(2, 2);
94     BOOST_TEST_EQ(two.str(), "1, 2");
95 
96     two.clear_bind(1);
97     BOOST_TEST_THROWS(two.str(), too_few_args);
98     BOOST_TEST_THROWS(two.clear_bind(1), boost::io::out_of_range);
99     two.exceptions(no_error_bits);
100     two.clear_bind(1);
101     two.str();
102 
103     return boost::report_errors();
104 }
105 
106