# # # patch "restrictions.cc" # from [0ed28c124d4af8fbaab01d6d8445980ca7d0bdc9] # to [9a37177b1a374c1973c01da3d4729e3a5d854453] # # patch "ui.cc" # from [989194f7bb73d7cc55e7197508b9203dde9d164f] # to [31589a9e86d23d92cb4f87b310c6eb920d026db6] # # patch "ui.hh" # from [e2c82fd7f5fb014e3cacf951bb4a5c165c16d13b] # to [13c682946de40aa1900a0b756c86062f95078147] # # patch "unit_tests.cc" # from [6c18091f527b9b38ae589bf9b6dede0896abdcd7] # to [45a81af10ac5ffd8be8d0bf9c4c8ee03f63bf16d] # ============================================================ --- restrictions.cc 0ed28c124d4af8fbaab01d6d8445980ca7d0bdc9 +++ restrictions.cc 9a37177b1a374c1973c01da3d4729e3a5d854453 @@ -403,29 +403,29 @@ using std::string; // x's and y's are directories // and this is rather painful -file_path fp_root = file_path_internal(""); -file_path fp_f = file_path_internal("f"); -file_path fp_g = file_path_internal("g"); +#define fp_root file_path_internal("") +#define fp_f file_path_internal("f") +#define fp_g file_path_internal("g") -file_path fp_x = file_path_internal("x"); -file_path fp_xf = file_path_internal("x/f"); -file_path fp_xg = file_path_internal("x/g"); -file_path fp_xx = file_path_internal("x/x"); -file_path fp_xxf = file_path_internal("x/x/f"); -file_path fp_xxg = file_path_internal("x/x/g"); -file_path fp_xy = file_path_internal("x/y"); -file_path fp_xyf = file_path_internal("x/y/f"); -file_path fp_xyg = file_path_internal("x/y/g"); +#define fp_x file_path_internal("x") +#define fp_xf file_path_internal("x/f") +#define fp_xg file_path_internal("x/g") +#define fp_xx file_path_internal("x/x") +#define fp_xxf file_path_internal("x/x/f") +#define fp_xxg file_path_internal("x/x/g") +#define fp_xy file_path_internal("x/y") +#define fp_xyf file_path_internal("x/y/f") +#define fp_xyg file_path_internal("x/y/g") -file_path fp_y = file_path_internal("y"); -file_path fp_yf = file_path_internal("y/f"); -file_path fp_yg = file_path_internal("y/g"); -file_path fp_yx = file_path_internal("y/x"); -file_path fp_yxf = file_path_internal("y/x/f"); -file_path fp_yxg = file_path_internal("y/x/g"); -file_path fp_yy = file_path_internal("y/y"); -file_path fp_yyf = file_path_internal("y/y/f"); -file_path fp_yyg = file_path_internal("y/y/g"); +#define fp_y file_path_internal("y") +#define fp_yf file_path_internal("y/f") +#define fp_yg file_path_internal("y/g") +#define fp_yx file_path_internal("y/x") +#define fp_yxf file_path_internal("y/x/f") +#define fp_yxg file_path_internal("y/x/g") +#define fp_yy file_path_internal("y/y") +#define fp_yyf file_path_internal("y/y/f") +#define fp_yyg file_path_internal("y/y/g") node_id nid_root; node_id nid_f; ============================================================ --- ui.cc 989194f7bb73d7cc55e7197508b9203dde9d164f +++ ui.cc 31589a9e86d23d92cb4f87b310c6eb920d026db6 @@ -14,6 +14,7 @@ #include "base.hh" #include "platform.hh" +#include "paths.hh" #include "sanity.hh" #include "ui.hh" #include "charset.hh" @@ -24,7 +25,10 @@ #include #include #include +#include +#include #include "lexical_cast.hh" +#include "safe_map.hh" #include @@ -46,6 +50,20 @@ struct user_interface ui; struct user_interface ui; +struct user_interface::impl +{ + std::set issued_warnings; + + bool some_tick_is_dirty; // At least one tick needs being printed + bool last_write_was_a_tick; + map tickers; + tick_writer * t_writer; + string tick_trailer; + + impl() : some_tick_is_dirty(false), last_write_was_a_tick(false), + t_writer(0) {} +}; + ticker::ticker(string const & tickname, string const & s, size_t mod, bool kilocount) : ticks(0), @@ -59,27 +77,27 @@ ticker::ticker(string const & tickname, shortname(s), count_size(0) { - I(ui.tickers.find(keyname) == ui.tickers.end()); - ui.tickers.insert(make_pair(keyname, this)); + I(ui.imp); + safe_insert(ui.imp->tickers, make_pair(keyname, this)); } ticker::~ticker() { - I(ui.tickers.find(keyname) != ui.tickers.end()); - if (ui.some_tick_is_dirty) - { - ui.write_ticks(); - } - ui.tickers.erase(keyname); + I(ui.imp); + safe_erase(ui.imp->tickers, keyname); + + if (ui.imp->some_tick_is_dirty) + ui.write_ticks(); ui.finish_ticking(); } void ticker::operator++() { - I(ui.tickers.find(keyname) != ui.tickers.end()); + I(ui.imp); + I(ui.imp->tickers.find(keyname) != ui.imp->tickers.end()); ticks++; - ui.some_tick_is_dirty = true; + ui.imp->some_tick_is_dirty = true; if (ticks % mod == 0) ui.write_ticks(); } @@ -87,13 +105,14 @@ ticker::operator+=(size_t t) void ticker::operator+=(size_t t) { - I(ui.tickers.find(keyname) != ui.tickers.end()); + I(ui.imp); + I(ui.imp->tickers.find(keyname) != ui.imp->tickers.end()); size_t old = ticks; ticks += t; if (t != 0) { - ui.some_tick_is_dirty = true; + ui.imp->some_tick_is_dirty = true; if (ticks % mod == 0 || (ticks / mod) > (old / mod)) ui.write_ticks(); } @@ -210,8 +229,9 @@ void tick_write_count::write_ticks() vector tick_title_strings; vector tick_count_strings; - for (map::const_iterator i = ui.tickers.begin(); - i != ui.tickers.end(); ++i) + I(ui.imp); + for (map::const_iterator i = ui.imp->tickers.begin(); + i != ui.imp->tickers.end(); ++i) { ticker * tick = i->second; @@ -268,7 +288,7 @@ void tick_write_count::write_ticks() } string tickline1; - bool write_tickline1 = !(ui.last_write_was_a_tick + bool write_tickline1 = !(ui.imp->last_write_was_a_tick && (tick_widths == last_tick_widths)); if (write_tickline1) { @@ -293,10 +313,10 @@ void tick_write_count::write_ticks() tickline2.append(idx(tick_count_strings, i)); } - if (!ui.tick_trailer.empty()) + if (!ui.imp->tick_trailer.empty()) { tickline2 += " "; - tickline2 += ui.tick_trailer; + tickline2 += ui.imp->tick_trailer; } size_t curr_sz = display_width(utf8(tickline2)); @@ -307,7 +327,7 @@ void tick_write_count::write_ticks() unsigned int tw = terminal_width(); if(write_tickline1) { - if (ui.last_write_was_a_tick) + if (ui.imp->last_write_was_a_tick) clog << '\n'; if (tw && display_width(utf8(tickline1)) > tw) @@ -344,11 +364,12 @@ void tick_write_dot::write_ticks() void tick_write_dot::write_ticks() { + I(ui.imp); static const string tickline_prefix = ui.output_prefix(); string tickline1, tickline2; bool first_tick = true; - if (ui.last_write_was_a_tick) + if (ui.imp->last_write_was_a_tick) { tickline1 = ""; tickline2 = ""; @@ -360,12 +381,12 @@ void tick_write_dot::write_ticks() chars_on_line = tickline_prefix.size(); } - for (map::const_iterator i = ui.tickers.begin(); - i != ui.tickers.end(); ++i) + for (map::const_iterator i = ui.imp->tickers.begin(); + i != ui.imp->tickers.end(); ++i) { map::const_iterator old = last_ticks.find(i->first); - if (!ui.last_write_was_a_tick) + if (!ui.imp->last_write_was_a_tick) { if (!first_tick) tickline1 += ", "; @@ -409,14 +430,12 @@ void tick_write_dot::clear_line() // global, and we don't want global constructors/destructors doing // any real work. see monotone.cc for how this is handled. -user_interface::user_interface() : - prog_name("?"), - last_write_was_a_tick(false), - t_writer(0) -{} +user_interface::user_interface() : prog_name("?"), imp(0) {} void user_interface::initialize() { + imp = new user_interface::impl; + cout.exceptions(ios_base::badbit); #ifdef SYNC_WITH_STDIO_WORKS clog.sync_with_stdio(false); @@ -433,70 +452,78 @@ void user_interface::deinitialize() void user_interface::deinitialize() { - delete t_writer; + I(imp); + delete imp->t_writer; + delete imp; } void user_interface::finish_ticking() { - if (tickers.size() == 0 && - last_write_was_a_tick) + I(imp); + if (imp->tickers.size() == 0 && imp->last_write_was_a_tick) { - tick_trailer = ""; - t_writer->clear_line(); - last_write_was_a_tick = false; + imp->tick_trailer = ""; + imp->t_writer->clear_line(); + imp->last_write_was_a_tick = false; } } void user_interface::set_tick_trailer(string const & t) { - tick_trailer = t; + I(imp); + imp->tick_trailer = t; } void user_interface::set_tick_write_dot() { - if (t_writer != 0) - delete t_writer; - t_writer = new tick_write_dot; + I(imp); + if (imp->t_writer != 0) + delete imp->t_writer; + imp->t_writer = new tick_write_dot; } void user_interface::set_tick_write_count() { - if (t_writer != 0) - delete t_writer; - t_writer = new tick_write_count; + I(imp); + if (imp->t_writer != 0) + delete imp->t_writer; + imp->t_writer = new tick_write_count; } void user_interface::set_tick_write_nothing() { - if (t_writer != 0) - delete t_writer; - t_writer = new tick_write_nothing; + I(imp); + if (imp->t_writer != 0) + delete imp->t_writer; + imp->t_writer = new tick_write_nothing; } void user_interface::write_ticks() { - t_writer->write_ticks(); - last_write_was_a_tick = true; - some_tick_is_dirty = false; + I(imp); + imp->t_writer->write_ticks(); + imp->last_write_was_a_tick = true; + imp->some_tick_is_dirty = false; } void user_interface::warn(string const & warning) { - if (issued_warnings.find(warning) == issued_warnings.end()) + I(imp); + if (imp->issued_warnings.find(warning) == imp->issued_warnings.end()) { string message; prefix_lines_with(_("warning: "), warning, message); inform(message); } - issued_warnings.insert(warning); + imp->issued_warnings.insert(warning); } // this message should be kept consistent with unix/main.cc and @@ -593,12 +620,13 @@ user_interface::ensure_clean_line() void user_interface::ensure_clean_line() { - if (last_write_was_a_tick) + I(imp); + if (imp->last_write_was_a_tick) { write_ticks(); - t_writer->clear_line(); + imp->t_writer->clear_line(); } - last_write_was_a_tick = false; + imp->last_write_was_a_tick = false; } void ============================================================ --- ui.hh e2c82fd7f5fb014e3cacf951bb4a5c165c16d13b +++ ui.hh 13c682946de40aa1900a0b756c86062f95078147 @@ -14,12 +14,9 @@ // interface. the global user_interface object 'ui' owns cerr, so // no writing to it directly! -#include -#include +struct i18n_format; +struct system_path; -#include "paths.hh" -#include "sanity.hh" - struct ticker { size_t ticks; @@ -71,16 +68,12 @@ private: std::string prog_name; private: - std::set issued_warnings; - - bool some_tick_is_dirty; // At least one tick needs being printed - bool last_write_was_a_tick; - std::map tickers; - tick_writer * t_writer; void finish_ticking(); void write_ticks(); - std::string tick_trailer; + struct impl; + impl * imp; + friend struct ticker; friend struct tick_write_count; friend struct tick_write_dot; ============================================================ --- unit_tests.cc 6c18091f527b9b38ae589bf9b6dede0896abdcd7 +++ unit_tests.cc 45a81af10ac5ffd8be8d0bf9c4c8ee03f63bf16d @@ -158,6 +158,10 @@ int main(int argc, char * argv[]) bool help(false); string test_to_run; + ui.initialize(); + ui.prog_name = argv[0]; + global_sanity.initialize(argc, argv, "C"); // we didn't call setlocale + try { option::concrete_option_set os; @@ -194,9 +198,6 @@ int main(int argc, char * argv[]) // set up some global state before running the tests - ui.initialize(); - ui.prog_name = argv[0]; - global_sanity.initialize(argc, argv, "C"); // we didn't call setlocale Botan::LibraryInitializer::initialize(); // Make clog and cout use the same streambuf as cerr; this ensures