# # # patch "cmd_automate.cc" # from [509e178776ec2e15eebda4476afef9ff0b77b367] # to [ef47d7f7bea31484180956bf9a75802d8cb09175] # # patch "ui.cc" # from [31589a9e86d23d92cb4f87b310c6eb920d026db6] # to [921e346b84547304ea37662924a70c35e0194a44] # # patch "ui.hh" # from [2e63f2165702aa2904d7169b5ae68a28a0eb5b3d] # to [3c761127d8c6b1f709a7ee8ccc51db4a0d473256] # ============================================================ --- cmd_automate.cc 509e178776ec2e15eebda4476afef9ff0b77b367 +++ cmd_automate.cc ef47d7f7bea31484180956bf9a75802d8cb09175 @@ -329,20 +329,6 @@ struct automate_ostream : public std::os { _M_autobuf.end_cmd(); } }; - -struct user_interface_stdio : public user_interface -{ -public: - user_interface_stdio(automate_ostream * ostr) - : user_interface(), ostream(ostr) - { initialize(); } - ~user_interface_stdio() {} - void inform(std::string const & line) - { *ostream << "[" << line << "]"; } -private: - automate_ostream * ostream; -}; - CMD_AUTOMATE(stdio, "", N_("Automates several commands in one run"), "", @@ -358,8 +344,7 @@ CMD_AUTOMATE(stdio, "", automate_ostream os(output, app.opts.automate_stdio_size); automate_reader ar(std::cin); - user_interface old_ui = ui; - ui = user_interface_stdio(&os); + ui.set_print_impl(new user_interface::print_impl(&os)); vector > params; vector cmdline; @@ -426,8 +411,6 @@ CMD_AUTOMATE(stdio, "", } os.end_cmd(); } - - ui = old_ui; } LUAEXT(mtn_automate, ) ============================================================ --- ui.cc 31589a9e86d23d92cb4f87b310c6eb920d026db6 +++ ui.cc 921e346b84547304ea37662924a70c35e0194a44 @@ -50,7 +50,7 @@ struct user_interface ui; struct user_interface ui; -struct user_interface::impl +struct user_interface::ticker_impl { std::set issued_warnings; @@ -60,10 +60,25 @@ struct user_interface::impl tick_writer * t_writer; string tick_trailer; - impl() : some_tick_is_dirty(false), last_write_was_a_tick(false), + ticker_impl() : some_tick_is_dirty(false), last_write_was_a_tick(false), t_writer(0) {} }; +struct user_interface::print_impl +{ + std::ostream ostr; + void flush() { ostr.flush(); } + print_impl & operator<<(print_impl & pimpl, char const ch) + { + return (pimpl.ostr << ch); + } + print_impl & operator<<(print_impl & pimpl, std::string const & str) + { + return (pimpl.ostr << str); + } + print_impl() : ostr(clog) {} +}; + ticker::ticker(string const & tickname, string const & s, size_t mod, bool kilocount) : ticks(0), @@ -77,16 +92,16 @@ ticker::ticker(string const & tickname, shortname(s), count_size(0) { - I(ui.imp); - safe_insert(ui.imp->tickers, make_pair(keyname, this)); + I(ui.ticker_imp); + safe_insert(ui.ticker_imp->tickers, make_pair(keyname, this)); } ticker::~ticker() { - I(ui.imp); - safe_erase(ui.imp->tickers, keyname); + I(ui.ticker_imp); + safe_erase(ui.ticker_imp->tickers, keyname); - if (ui.imp->some_tick_is_dirty) + if (ui.ticker_imp->some_tick_is_dirty) ui.write_ticks(); ui.finish_ticking(); } @@ -94,10 +109,10 @@ ticker::operator++() void ticker::operator++() { - I(ui.imp); - I(ui.imp->tickers.find(keyname) != ui.imp->tickers.end()); + I(ui.ticker_imp); + I(ui.ticker_imp->tickers.find(keyname) != ui.ticker_imp->tickers.end()); ticks++; - ui.imp->some_tick_is_dirty = true; + ui.ticker_imp->some_tick_is_dirty = true; if (ticks % mod == 0) ui.write_ticks(); } @@ -105,14 +120,14 @@ ticker::operator+=(size_t t) void ticker::operator+=(size_t t) { - I(ui.imp); - I(ui.imp->tickers.find(keyname) != ui.imp->tickers.end()); + I(ui.ticker_imp); + I(ui.ticker_imp->tickers.find(keyname) != ui.ticker_imp->tickers.end()); size_t old = ticks; ticks += t; if (t != 0) { - ui.imp->some_tick_is_dirty = true; + ui.ticker_imp->some_tick_is_dirty = true; if (ticks % mod == 0 || (ticks / mod) > (old / mod)) ui.write_ticks(); } @@ -229,9 +244,11 @@ void tick_write_count::write_ticks() vector tick_title_strings; vector tick_count_strings; - I(ui.imp); - for (map::const_iterator i = ui.imp->tickers.begin(); - i != ui.imp->tickers.end(); ++i) + I(ui.ticker_imp); + I(ui.print_imp); + + for (map::const_iterator i = ui.ticker_imp->tickers.begin(); + i != ui.ticker_imp->tickers.end(); ++i) { ticker * tick = i->second; @@ -288,7 +305,7 @@ void tick_write_count::write_ticks() } string tickline1; - bool write_tickline1 = !(ui.imp->last_write_was_a_tick + bool write_tickline1 = !(ui.ticker_imp->last_write_was_a_tick && (tick_widths == last_tick_widths)); if (write_tickline1) { @@ -313,10 +330,10 @@ void tick_write_count::write_ticks() tickline2.append(idx(tick_count_strings, i)); } - if (!ui.imp->tick_trailer.empty()) + if (!ui.ticker_imp->tick_trailer.empty()) { tickline2 += " "; - tickline2 += ui.imp->tick_trailer; + tickline2 += ui.ticker_imp->tick_trailer; } size_t curr_sz = display_width(utf8(tickline2)); @@ -327,8 +344,8 @@ void tick_write_count::write_ticks() unsigned int tw = terminal_width(); if(write_tickline1) { - if (ui.imp->last_write_was_a_tick) - clog << '\n'; + if (ui.ticker_imp->last_write_was_a_tick) + ui.print_imp << '\n'; if (tw && display_width(utf8(tickline1)) > tw) { @@ -336,7 +353,7 @@ void tick_write_count::write_ticks() // bytes, not by characters) tickline1.resize(tw); } - clog << tickline1 << '\n'; + ui.print_imp << tickline1 << '\n'; } if (tw && display_width(utf8(tickline2)) > tw) { @@ -344,13 +361,14 @@ void tick_write_count::write_ticks() // bytes, not by characters) tickline2.resize(tw); } - clog << '\r' << tickline2; - clog.flush(); + ui.print_imp << '\r' << tickline2; + ui.print_imp.flush(); } void tick_write_count::clear_line() { - clog << endl; + I(ui.print_imp); + ui.print_imp << endl; } @@ -364,12 +382,14 @@ void tick_write_dot::write_ticks() void tick_write_dot::write_ticks() { - I(ui.imp); + I(ui.ticker_imp); + I(ui.print_imp); + static const string tickline_prefix = ui.output_prefix(); string tickline1, tickline2; bool first_tick = true; - if (ui.imp->last_write_was_a_tick) + if (ui.ticker_imp->last_write_was_a_tick) { tickline1 = ""; tickline2 = ""; @@ -381,12 +401,12 @@ void tick_write_dot::write_ticks() chars_on_line = tickline_prefix.size(); } - for (map::const_iterator i = ui.imp->tickers.begin(); - i != ui.imp->tickers.end(); ++i) + for (map::const_iterator i = ui.ticker_imp->tickers.begin(); + i != ui.ticker_imp->tickers.end(); ++i) { map::const_iterator old = last_ticks.find(i->first); - if (!ui.imp->last_write_was_a_tick) + if (!ui.ticker_imp->last_write_was_a_tick) { if (!first_tick) tickline1 += ", "; @@ -416,13 +436,14 @@ void tick_write_dot::write_ticks() } } - clog << tickline1 << tickline2; - clog.flush(); + ui.print_imp << tickline1 << tickline2; + ui.print_imp.flush(); } void tick_write_dot::clear_line() { - clog << endl; + I(ui.print_imp); + ui.print_imp << endl; } // user_interface has both constructor/destructor and initialize/ @@ -430,17 +451,20 @@ 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("?"), imp(0) {} +user_interface::user_interface() : prog_name("?"), ticker_imp(0), print_imp(0) {} void user_interface::initialize() { - imp = new user_interface::impl; - + ticker_imp = new user_interface::ticker_impl; + cout.exceptions(ios_base::badbit); #ifdef SYNC_WITH_STDIO_WORKS clog.sync_with_stdio(false); #endif clog.unsetf(ios_base::unitbuf); + + print_imp = new user_interface::print_impl(clog); + if (have_smart_terminal()) set_tick_write_count(); else @@ -452,78 +476,80 @@ void user_interface::deinitialize() void user_interface::deinitialize() { - I(imp); - delete imp->t_writer; - delete imp; + I(ticker_imp); + delete ticker_imp->t_writer; + delete ticker_imp; + I(print_imp); + delete print_imp; } void user_interface::finish_ticking() { - I(imp); - if (imp->tickers.size() == 0 && imp->last_write_was_a_tick) + I(ticker_imp); + if (ticker_imp->tickers.size() == 0 && ticker_imp->last_write_was_a_tick) { - imp->tick_trailer = ""; - imp->t_writer->clear_line(); - imp->last_write_was_a_tick = false; + ticker_imp->tick_trailer = ""; + ticker_imp->t_writer->clear_line(); + ticker_imp->last_write_was_a_tick = false; } } void user_interface::set_tick_trailer(string const & t) { - I(imp); - imp->tick_trailer = t; + I(ticker_imp); + ticker_imp->tick_trailer = t; } void user_interface::set_tick_write_dot() { - I(imp); - if (imp->t_writer != 0) - delete imp->t_writer; - imp->t_writer = new tick_write_dot; + I(ticker_imp); + if (ticker_imp->t_writer != 0) + delete ticker_imp->t_writer; + ticker_imp->t_writer = new tick_write_dot; } void user_interface::set_tick_write_count() { - I(imp); - if (imp->t_writer != 0) - delete imp->t_writer; - imp->t_writer = new tick_write_count; + I(ticker_imp); + if (ticker_imp->t_writer != 0) + delete ticker_imp->t_writer; + ticker_imp->t_writer = new tick_write_count; } void user_interface::set_tick_write_nothing() { - I(imp); - if (imp->t_writer != 0) - delete imp->t_writer; - imp->t_writer = new tick_write_nothing; + I(ticker_imp); + if (ticker_imp->t_writer != 0) + delete ticker_imp->t_writer; + ticker_imp->t_writer = new tick_write_nothing; } void user_interface::write_ticks() { - I(imp); - imp->t_writer->write_ticks(); - imp->last_write_was_a_tick = true; - imp->some_tick_is_dirty = false; + I(ticker_imp); + ticker_imp->t_writer->write_ticks(); + ticker_imp->last_write_was_a_tick = true; + ticker_imp->some_tick_is_dirty = false; } void user_interface::warn(string const & warning) { - I(imp); - if (imp->issued_warnings.find(warning) == imp->issued_warnings.end()) + I(ticker_imp); + if (ticker_imp->issued_warnings.find(warning) == ticker_imp->issued_warnings.end()) { string message; prefix_lines_with(_("warning: "), warning, message); inform(message); } - imp->issued_warnings.insert(warning); + ticker_imp->issued_warnings.insert(warning); } // this message should be kept consistent with unix/main.cc and @@ -620,13 +646,13 @@ user_interface::ensure_clean_line() void user_interface::ensure_clean_line() { - I(imp); - if (imp->last_write_was_a_tick) + I(ticker_imp); + if (ticker_imp->last_write_was_a_tick) { write_ticks(); - imp->t_writer->clear_line(); + ticker_imp->t_writer->clear_line(); } - imp->last_write_was_a_tick = false; + ticker_imp->last_write_was_a_tick = false; } void @@ -641,12 +667,22 @@ void } void +user_interface::set_print_impl(print_impl * pimpl) +{ + I(pimpl); + if (print_imp) + delete print_imp; + print_imp = pimpl; +} + +void user_interface::inform(string const & line) { + I(ui.print_imp); string prefixedLine; prefix_lines_with(output_prefix(), line, prefixedLine); ensure_clean_line(); - clog << sanitize(prefixedLine) << endl; // flushes + ui.print_imp << sanitize(prefixedLine) << endl; // flushes } unsigned int ============================================================ --- ui.hh 2e63f2165702aa2904d7169b5ae68a28a0eb5b3d +++ ui.hh 3c761127d8c6b1f709a7ee8ccc51db4a0d473256 @@ -45,15 +45,18 @@ public: struct user_interface { public: + struct ticker_impl; + struct print_impl; + user_interface(); - virtual ~user_interface(); + ~user_interface(); void initialize(); void deinitialize(); void warn(std::string const & warning); void warn(format_base const & fmt) { warn(fmt.str()); } void fatal(std::string const & fatal); void fatal(format_base const & fmt) { fatal(fmt.str()); } - virtual void inform(std::string const & line); + void inform(std::string const & line); void inform(format_base const & fmt) { inform(fmt.str()); } void fatal_exception(std::exception const & ex); void fatal_exception(); @@ -63,6 +66,7 @@ public: void set_tick_write_nothing(); void ensure_clean_line(); void redirect_log_to(system_path const & filename); + void set_print_impl(print_impl * pimpl); std::string output_prefix(); std::string prog_name; @@ -71,8 +75,8 @@ private: void finish_ticking(); void write_ticks(); - struct impl; - impl * imp; + ticker_impl * ticker_imp; + print_impl * print_imp; friend struct ticker; friend struct tick_write_count;