From 0668b1b222bd25e6d1dcb4e2188aaa2422e5886f Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 8 Mar 2017 23:16:48 -0800 Subject: 3769 --- html/100trace_browser.cc.html | 552 +++++++++++++++++++++--------------------- 1 file changed, 280 insertions(+), 272 deletions(-) (limited to 'html/100trace_browser.cc.html') diff --git a/html/100trace_browser.cc.html b/html/100trace_browser.cc.html index c76aa4ac..152bec77 100644 --- a/html/100trace_browser.cc.html +++ b/html/100trace_browser.cc.html @@ -91,281 +91,289 @@ if ('onhashchange' in window) { 31 //: `k` or `up-arrow`: Move/scroll cursor up one line. 32 //: `J` or `ctrl-f` or `page-down`: Scroll cursor down one page. 33 //: `K` or `ctrl-b` or `page-up`: Scroll cursor up one page. - 34 //: `H`: Scroll cursor left one screen-width. - 35 //: `L`: Scroll cursor right one screen-width. - 36 //: - 37 //: `g` or `home`: Move cursor to start of trace. - 38 //: `G` or `end`: Move cursor to end of trace. - 39 //: - 40 //: `t`: Move cursor to top line on screen. - 41 //: `c`: Move cursor to center line on screen. - 42 //: `b`: Move cursor to bottom line on screen. - 43 //: `T`: Scroll line at cursor to top of screen. - 44 - 45 :(before "End Primitive Recipe Declarations") - 46 _BROWSE_TRACE, - 47 :(before "End Primitive Recipe Numbers") - 48 put(Recipe_ordinal, "$browse-trace", _BROWSE_TRACE); - 49 :(before "End Primitive Recipe Checks") - 50 case _BROWSE_TRACE: { - 51 break; - 52 } - 53 :(before "End Primitive Recipe Implementations") - 54 case _BROWSE_TRACE: { - 55 start_trace_browser(); - 56 break; - 57 } - 58 - 59 //: browse a trace loaded from a file - 60 :(after "Commandline Parsing") - 61 if (argc == 3 && is_equal(argv[1], "browse-trace")) { - 62 load_trace(argv[2]); - 63 start_trace_browser(); - 64 return 0; - 65 } - 66 - 67 :(before "End Globals") - 68 set<int> Visible; - 69 int Top_of_screen = 0; - 70 int Left_of_screen = 0; - 71 int Last_printed_row = 0; - 72 map<int, int> Trace_index; // screen row -> trace index - 73 - 74 :(code) - 75 void start_trace_browser() { - 76 if (!Trace_stream) return; - 77 cerr << "computing min depth to display\n"; - 78 int min_depth = 9999; - 79 for (int i = 0; i < SIZE(Trace_stream->past_lines); ++i) { - 80 ¦ trace_line& curr_line = Trace_stream->past_lines.at(i); - 81 ¦ if (curr_line.depth < min_depth) min_depth = curr_line.depth; - 82 } - 83 cerr << "min depth is " << min_depth << '\n'; - 84 cerr << "computing lines to display\n"; - 85 for (int i = 0; i < SIZE(Trace_stream->past_lines); ++i) { - 86 ¦ if (Trace_stream->past_lines.at(i).depth == min_depth) - 87 ¦ ¦ Visible.insert(i); - 88 } - 89 tb_init(); - 90 Display_row = Display_column = 0; - 91 tb_event event; - 92 Top_of_screen = 0; - 93 refresh_screen_rows(); - 94 while (true) { - 95 ¦ render(); - 96 ¦ do { - 97 ¦ ¦ tb_poll_event(&event); - 98 ¦ } while (event.type != TB_EVENT_KEY); - 99 ¦ int key = event.key ? event.key : event.ch; -100 ¦ if (key == 'q' || key == 'Q' || key == TB_KEY_CTRL_C) break; -101 ¦ if (key == 'j' || key == TB_KEY_ARROW_DOWN) { -102 ¦ ¦ // move cursor one line down -103 ¦ ¦ if (Display_row < Last_printed_row) ++Display_row; -104 ¦ } -105 ¦ if (key == 'k' || key == TB_KEY_ARROW_UP) { -106 ¦ ¦ // move cursor one line up -107 ¦ ¦ if (Display_row > 0) --Display_row; -108 ¦ } -109 ¦ if (key == 't') { -110 ¦ ¦ // move cursor to top of screen -111 ¦ ¦ Display_row = 0; -112 ¦ } -113 ¦ if (key == 'c') { -114 ¦ ¦ // move cursor to center of screen -115 ¦ ¦ Display_row = tb_height()/2; -116 ¦ } -117 ¦ if (key == 'b') { -118 ¦ ¦ // move cursor to bottom of screen -119 ¦ ¦ Display_row = tb_height()-1; -120 ¦ } -121 ¦ if (key == 'T') { -122 ¦ ¦ Top_of_screen = get(Trace_index, Display_row); -123 ¦ ¦ Display_row = 0; -124 ¦ ¦ refresh_screen_rows(); -125 ¦ } -126 ¦ if (key == 'H') { -127 ¦ ¦ Left_of_screen -= (tb_width() - 5); -128 ¦ ¦ if (Left_of_screen < 0) Left_of_screen = 0; -129 ¦ } -130 ¦ if (key == 'L') { -131 ¦ ¦ Left_of_screen += (tb_width() - 5); -132 ¦ } -133 ¦ if (key == 'J' || key == TB_KEY_PGDN || key == TB_KEY_CTRL_F) { -134 ¦ ¦ // page-down -135 ¦ ¦ if (Trace_index.find(tb_height()-1) != Trace_index.end()) { -136 ¦ ¦ ¦ Top_of_screen = get(Trace_index, tb_height()-1) + 1; -137 ¦ ¦ ¦ refresh_screen_rows(); -138 ¦ ¦ } -139 ¦ } -140 ¦ if (key == 'K' || key == TB_KEY_PGUP || key == TB_KEY_CTRL_B) { -141 ¦ ¦ // page-up is more convoluted -142 ¦ ¦ for (int screen_row = tb_height(); screen_row > 0 && Top_of_screen > 0; --screen_row) { -143 ¦ ¦ ¦ --Top_of_screen; -144 ¦ ¦ ¦ if (Top_of_screen <= 0) break; -145 ¦ ¦ ¦ while (Top_of_screen > 0 && !contains_key(Visible, Top_of_screen)) -146 ¦ ¦ ¦ ¦ --Top_of_screen; -147 ¦ ¦ } -148 ¦ ¦ if (Top_of_screen >= 0) -149 ¦ ¦ ¦ refresh_screen_rows(); -150 ¦ } -151 ¦ if (key == 'g' || key == TB_KEY_HOME) { -152 ¦ ¦ ¦ Top_of_screen = 0; -153 ¦ ¦ ¦ Last_printed_row = 0; -154 ¦ ¦ ¦ Display_row = 0; -155 ¦ ¦ ¦ refresh_screen_rows(); -156 ¦ } -157 ¦ if (key == 'G' || key == TB_KEY_END) { -158 ¦ ¦ // go to bottom of screen; largely like page-up, interestingly -159 ¦ ¦ Top_of_screen = SIZE(Trace_stream->past_lines)-1; -160 ¦ ¦ for (int screen_row = tb_height(); screen_row > 0 && Top_of_screen > 0; --screen_row) { -161 ¦ ¦ ¦ --Top_of_screen; -162 ¦ ¦ ¦ if (Top_of_screen <= 0) break; -163 ¦ ¦ ¦ while (Top_of_screen > 0 && !contains_key(Visible, Top_of_screen)) -164 ¦ ¦ ¦ ¦ --Top_of_screen; -165 ¦ ¦ } -166 ¦ ¦ refresh_screen_rows(); -167 ¦ ¦ // move cursor to bottom -168 ¦ ¦ Display_row = Last_printed_row; -169 ¦ ¦ refresh_screen_rows(); -170 ¦ } -171 ¦ if (key == TB_KEY_CARRIAGE_RETURN) { -172 ¦ ¦ // expand lines under current by one level -173 ¦ ¦ assert(contains_key(Trace_index, Display_row)); -174 ¦ ¦ int start_index = get(Trace_index, Display_row); -175 ¦ ¦ int index = 0; -176 ¦ ¦ // simultaneously compute end_index and min_depth -177 ¦ ¦ int min_depth = 9999; -178 ¦ ¦ for (index = start_index+1; index < SIZE(Trace_stream->past_lines); ++index) { -179 ¦ ¦ ¦ if (contains_key(Visible, index)) break; -180 ¦ ¦ ¦ trace_line& curr_line = Trace_stream->past_lines.at(index); -181 ¦ ¦ ¦ assert(curr_line.depth > Trace_stream->past_lines.at(start_index).depth); -182 ¦ ¦ ¦ if (curr_line.depth < min_depth) min_depth = curr_line.depth; -183 ¦ ¦ } -184 ¦ ¦ int end_index = index; -185 ¦ ¦ // mark as visible all intervening indices at min_depth -186 ¦ ¦ for (index = start_index; index < end_index; ++index) { -187 ¦ ¦ ¦ trace_line& curr_line = Trace_stream->past_lines.at(index); -188 ¦ ¦ ¦ if (curr_line.depth == min_depth) { -189 ¦ ¦ ¦ ¦ Visible.insert(index); -190 ¦ ¦ ¦ } + 34 //: `h` or `left-arrow`: Scroll cursor left one character. + 35 //: `l` or `right-arrow`: Scroll cursor right one character. + 36 //: `H`: Scroll cursor left one screen-width. + 37 //: `L`: Scroll cursor right one screen-width. + 38 //: + 39 //: `g` or `home`: Move cursor to start of trace. + 40 //: `G` or `end`: Move cursor to end of trace. + 41 //: + 42 //: `t`: Move cursor to top line on screen. + 43 //: `c`: Move cursor to center line on screen. + 44 //: `b`: Move cursor to bottom line on screen. + 45 //: `T`: Scroll line at cursor to top of screen. + 46 + 47 :(before "End Primitive Recipe Declarations") + 48 _BROWSE_TRACE, + 49 :(before "End Primitive Recipe Numbers") + 50 put(Recipe_ordinal, "$browse-trace", _BROWSE_TRACE); + 51 :(before "End Primitive Recipe Checks") + 52 case _BROWSE_TRACE: { + 53 break; + 54 } + 55 :(before "End Primitive Recipe Implementations") + 56 case _BROWSE_TRACE: { + 57 start_trace_browser(); + 58 break; + 59 } + 60 + 61 //: browse a trace loaded from a file + 62 :(after "Commandline Parsing") + 63 if (argc == 3 && is_equal(argv[1], "browse-trace")) { + 64 load_trace(argv[2]); + 65 start_trace_browser(); + 66 return 0; + 67 } + 68 + 69 :(before "End Globals") + 70 set<int> Visible; + 71 int Top_of_screen = 0; + 72 int Left_of_screen = 0; + 73 int Last_printed_row = 0; + 74 map<int, int> Trace_index; // screen row -> trace index + 75 + 76 :(code) + 77 void start_trace_browser() { + 78 if (!Trace_stream) return; + 79 cerr << "computing min depth to display\n"; + 80 int min_depth = 9999; + 81 for (int i = 0; i < SIZE(Trace_stream->past_lines); ++i) { + 82 ¦ trace_line& curr_line = Trace_stream->past_lines.at(i); + 83 ¦ if (curr_line.depth < min_depth) min_depth = curr_line.depth; + 84 } + 85 cerr << "min depth is " << min_depth << '\n'; + 86 cerr << "computing lines to display\n"; + 87 for (int i = 0; i < SIZE(Trace_stream->past_lines); ++i) { + 88 ¦ if (Trace_stream->past_lines.at(i).depth == min_depth) + 89 ¦ ¦ Visible.insert(i); + 90 } + 91 tb_init(); + 92 Display_row = Display_column = 0; + 93 tb_event event; + 94 Top_of_screen = 0; + 95 refresh_screen_rows(); + 96 while (true) { + 97 ¦ render(); + 98 ¦ do { + 99 ¦ ¦ tb_poll_event(&event); +100 ¦ } while (event.type != TB_EVENT_KEY); +101 ¦ int key = event.key ? event.key : event.ch; +102 ¦ if (key == 'q' || key == 'Q' || key == TB_KEY_CTRL_C) break; +103 ¦ if (key == 'j' || key == TB_KEY_ARROW_DOWN) { +104 ¦ ¦ // move cursor one line down +105 ¦ ¦ if (Display_row < Last_printed_row) ++Display_row; +106 ¦ } +107 ¦ if (key == 'k' || key == TB_KEY_ARROW_UP) { +108 ¦ ¦ // move cursor one line up +109 ¦ ¦ if (Display_row > 0) --Display_row; +110 ¦ } +111 ¦ if (key == 't') { +112 ¦ ¦ // move cursor to top of screen +113 ¦ ¦ Display_row = 0; +114 ¦ } +115 ¦ if (key == 'c') { +116 ¦ ¦ // move cursor to center of screen +117 ¦ ¦ Display_row = tb_height()/2; +118 ¦ } +119 ¦ if (key == 'b') { +120 ¦ ¦ // move cursor to bottom of screen +121 ¦ ¦ Display_row = tb_height()-1; +122 ¦ } +123 ¦ if (key == 'T') { +124 ¦ ¦ Top_of_screen = get(Trace_index, Display_row); +125 ¦ ¦ Display_row = 0; +126 ¦ ¦ refresh_screen_rows(); +127 ¦ } +128 ¦ if (key == 'h' || key == TB_KEY_ARROW_LEFT) { +129 ¦ ¦ --Left_of_screen; +130 ¦ } +131 ¦ if (key == 'l' || key == TB_KEY_ARROW_RIGHT) { +132 ¦ ¦ ++Left_of_screen; +133 ¦ } +134 ¦ if (key == 'H') { +135 ¦ ¦ Left_of_screen -= (tb_width() - 5); +136 ¦ ¦ if (Left_of_screen < 0) Left_of_screen = 0; +137 ¦ } +138 ¦ if (key == 'L') { +139 ¦ ¦ Left_of_screen += (tb_width() - 5); +140 ¦ } +141 ¦ if (key == 'J' || key == TB_KEY_PGDN || key == TB_KEY_CTRL_F) { +142 ¦ ¦ // page-down +143 ¦ ¦ if (Trace_index.find(tb_height()-1) != Trace_index.end()) { +144 ¦ ¦ ¦ Top_of_screen = get(Trace_index, tb_height()-1) + 1; +145 ¦ ¦ ¦ refresh_screen_rows(); +146 ¦ ¦ } +147 ¦ } +148 ¦ if (key == 'K' || key == TB_KEY_PGUP || key == TB_KEY_CTRL_B) { +149 ¦ ¦ // page-up is more convoluted +150 ¦ ¦ for (int screen_row = tb_height(); screen_row > 0 && Top_of_screen > 0; --screen_row) { +151 ¦ ¦ ¦ --Top_of_screen; +152 ¦ ¦ ¦ if (Top_of_screen <= 0) break; +153 ¦ ¦ ¦ while (Top_of_screen > 0 && !contains_key(Visible, Top_of_screen)) +154 ¦ ¦ ¦ ¦ --Top_of_screen; +155 ¦ ¦ } +156 ¦ ¦ if (Top_of_screen >= 0) +157 ¦ ¦ ¦ refresh_screen_rows(); +158 ¦ } +159 ¦ if (key == 'g' || key == TB_KEY_HOME) { +160 ¦ ¦ ¦ Top_of_screen = 0; +161 ¦ ¦ ¦ Last_printed_row = 0; +162 ¦ ¦ ¦ Display_row = 0; +163 ¦ ¦ ¦ refresh_screen_rows(); +164 ¦ } +165 ¦ if (key == 'G' || key == TB_KEY_END) { +166 ¦ ¦ // go to bottom of screen; largely like page-up, interestingly +167 ¦ ¦ Top_of_screen = SIZE(Trace_stream->past_lines)-1; +168 ¦ ¦ for (int screen_row = tb_height(); screen_row > 0 && Top_of_screen > 0; --screen_row) { +169 ¦ ¦ ¦ --Top_of_screen; +170 ¦ ¦ ¦ if (Top_of_screen <= 0) break; +171 ¦ ¦ ¦ while (Top_of_screen > 0 && !contains_key(Visible, Top_of_screen)) +172 ¦ ¦ ¦ ¦ --Top_of_screen; +173 ¦ ¦ } +174 ¦ ¦ refresh_screen_rows(); +175 ¦ ¦ // move cursor to bottom +176 ¦ ¦ Display_row = Last_printed_row; +177 ¦ ¦ refresh_screen_rows(); +178 ¦ } +179 ¦ if (key == TB_KEY_CARRIAGE_RETURN) { +180 ¦ ¦ // expand lines under current by one level +181 ¦ ¦ assert(contains_key(Trace_index, Display_row)); +182 ¦ ¦ int start_index = get(Trace_index, Display_row); +183 ¦ ¦ int index = 0; +184 ¦ ¦ // simultaneously compute end_index and min_depth +185 ¦ ¦ int min_depth = 9999; +186 ¦ ¦ for (index = start_index+1; index < SIZE(Trace_stream->past_lines); ++index) { +187 ¦ ¦ ¦ if (contains_key(Visible, index)) break; +188 ¦ ¦ ¦ trace_line& curr_line = Trace_stream->past_lines.at(index); +189 ¦ ¦ ¦ assert(curr_line.depth > Trace_stream->past_lines.at(start_index).depth); +190 ¦ ¦ ¦ if (curr_line.depth < min_depth) min_depth = curr_line.depth; 191 ¦ ¦ } -192 ¦ ¦ refresh_screen_rows(); -193 ¦ } -194 ¦ if (key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2) { -195 ¦ ¦ // collapse all lines under current -196 ¦ ¦ assert(contains_key(Trace_index, Display_row)); -197 ¦ ¦ int start_index = get(Trace_index, Display_row); -198 ¦ ¦ int index = 0; -199 ¦ ¦ // end_index is the next line at a depth same as or lower than start_index -200 ¦ ¦ int initial_depth = Trace_stream->past_lines.at(start_index).depth; -201 ¦ ¦ for (index = start_index+1; index < SIZE(Trace_stream->past_lines); ++index) { -202 ¦ ¦ ¦ if (!contains_key(Visible, index)) continue; -203 ¦ ¦ ¦ trace_line& curr_line = Trace_stream->past_lines.at(index); -204 ¦ ¦ ¦ if (curr_line.depth <= initial_depth) break; -205 ¦ ¦ } -206 ¦ ¦ int end_index = index; -207 ¦ ¦ // mark as visible all intervening indices at min_depth -208 ¦ ¦ for (index = start_index+1; index < end_index; ++index) { -209 ¦ ¦ ¦ Visible.erase(index); -210 ¦ ¦ } -211 ¦ ¦ refresh_screen_rows(); -212 ¦ } -213 } -214 tb_shutdown(); -215 } -216 -217 // update Trace_indices for each screen_row on the basis of Top_of_screen and Visible -218 void refresh_screen_rows() { -219 int screen_row = 0, index = 0; -220 Trace_index.clear(); -221 for (screen_row = 0, index = Top_of_screen; screen_row < tb_height() && index < SIZE(Trace_stream->past_lines); ++screen_row, ++index) { -222 ¦ // skip lines without depth for now -223 ¦ while (!contains_key(Visible, index)) { -224 ¦ ¦ ++index; -225 ¦ ¦ if (index >= SIZE(Trace_stream->past_lines)) goto done; -226 ¦ } -227 ¦ assert(index < SIZE(Trace_stream->past_lines)); -228 ¦ put(Trace_index, screen_row, index); -229 } -230 done:; -231 } -232 -233 void render() { -234 int screen_row = 0; -235 for (screen_row = 0; screen_row < tb_height(); ++screen_row) { -236 ¦ if (!contains_key(Trace_index, screen_row)) break; -237 ¦ trace_line& curr_line = Trace_stream->past_lines.at(get(Trace_index, screen_row)); -238 ¦ ostringstream out; -239 ¦ out << std::setw(4) << curr_line.depth << ' ' << curr_line.label << ": " << curr_line.contents; -240 ¦ if (screen_row < tb_height()-1) { -241 ¦ ¦ int delta = lines_hidden(screen_row); -242 ¦ ¦ // home-brew escape sequence for red -243 ¦ ¦ if (delta > 999) out << static_cast<char>(1); -244 ¦ ¦ out << " (" << delta << ")"; -245 ¦ ¦ if (delta > 999) out << static_cast<char>(2); -246 ¦ } -247 ¦ render_line(screen_row, out.str(), screen_row == Display_row); -248 } -249 // clear rest of screen -250 Last_printed_row = screen_row-1; -251 for (; screen_row < tb_height(); ++screen_row) { -252 ¦ render_line(screen_row, "~", /*highlight?*/false); -253 } -254 // move cursor back to display row at the end -255 tb_set_cursor(0, Display_row); -256 tb_present(); -257 } -258 -259 int lines_hidden(int screen_row) { -260 assert(contains_key(Trace_index, screen_row)); -261 if (!contains_key(Trace_index, screen_row+1)) -262 ¦ return SIZE(Trace_stream->past_lines) - get(Trace_index, screen_row); -263 else -264 ¦ return get(Trace_index, screen_row+1) - get(Trace_index, screen_row); +192 ¦ ¦ int end_index = index; +193 ¦ ¦ // mark as visible all intervening indices at min_depth +194 ¦ ¦ for (index = start_index; index < end_index; ++index) { +195 ¦ ¦ ¦ trace_line& curr_line = Trace_stream->past_lines.at(index); +196 ¦ ¦ ¦ if (curr_line.depth == min_depth) { +197 ¦ ¦ ¦ ¦ Visible.insert(index); +198 ¦ ¦ ¦ } +199 ¦ ¦ } +200 ¦ ¦ refresh_screen_rows(); +201 ¦ } +202 ¦ if (key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2) { +203 ¦ ¦ // collapse all lines under current +204 ¦ ¦ assert(contains_key(Trace_index, Display_row)); +205 ¦ ¦ int start_index = get(Trace_index, Display_row); +206 ¦ ¦ int index = 0; +207 ¦ ¦ // end_index is the next line at a depth same as or lower than start_index +208 ¦ ¦ int initial_depth = Trace_stream->past_lines.at(start_index).depth; +209 ¦ ¦ for (index = start_index+1; index < SIZE(Trace_stream->past_lines); ++index) { +210 ¦ ¦ ¦ if (!contains_key(Visible, index)) continue; +211 ¦ ¦ ¦ trace_line& curr_line = Trace_stream->past_lines.at(index); +212 ¦ ¦ ¦ if (curr_line.depth <= initial_depth) break; +213 ¦ ¦ } +214 ¦ ¦ int end_index = index; +215 ¦ ¦ // mark as visible all intervening indices at min_depth +216 ¦ ¦ for (index = start_index+1; index < end_index; ++index) { +217 ¦ ¦ ¦ Visible.erase(index); +218 ¦ ¦ } +219 ¦ ¦ refresh_screen_rows(); +220 ¦ } +221 } +222 tb_shutdown(); +223 } +224 +225 // update Trace_indices for each screen_row on the basis of Top_of_screen and Visible +226 void refresh_screen_rows() { +227 int screen_row = 0, index = 0; +228 Trace_index.clear(); +229 for (screen_row = 0, index = Top_of_screen; screen_row < tb_height() && index < SIZE(Trace_stream->past_lines); ++screen_row, ++index) { +230 ¦ // skip lines without depth for now +231 ¦ while (!contains_key(Visible, index)) { +232 ¦ ¦ ++index; +233 ¦ ¦ if (index >= SIZE(Trace_stream->past_lines)) goto done; +234 ¦ } +235 ¦ assert(index < SIZE(Trace_stream->past_lines)); +236 ¦ put(Trace_index, screen_row, index); +237 } +238 done:; +239 } +240 +241 void render() { +242 int screen_row = 0; +243 for (screen_row = 0; screen_row < tb_height(); ++screen_row) { +244 ¦ if (!contains_key(Trace_index, screen_row)) break; +245 ¦ trace_line& curr_line = Trace_stream->past_lines.at(get(Trace_index, screen_row)); +246 ¦ ostringstream out; +247 ¦ out << std::setw(4) << curr_line.depth << ' ' << curr_line.label << ": " << curr_line.contents; +248 ¦ if (screen_row < tb_height()-1) { +249 ¦ ¦ int delta = lines_hidden(screen_row); +250 ¦ ¦ // home-brew escape sequence for red +251 ¦ ¦ if (delta > 999) out << static_cast<char>(1); +252 ¦ ¦ out << " (" << delta << ")"; +253 ¦ ¦ if (delta > 999) out << static_cast<char>(2); +254 ¦ } +255 ¦ render_line(screen_row, out.str(), screen_row == Display_row); +256 } +257 // clear rest of screen +258 Last_printed_row = screen_row-1; +259 for (; screen_row < tb_height(); ++screen_row) { +260 ¦ render_line(screen_row, "~", /*highlight?*/false); +261 } +262 // move cursor back to display row at the end +263 tb_set_cursor(0, Display_row); +264 tb_present(); 265 } 266 -267 void render_line(int screen_row, const string& s, bool highlight) { -268 int col = 0; -269 int color = TB_WHITE; -270 for (col = 0; col < tb_width() && col+Left_of_screen < SIZE(s); ++col) { -271 ¦ char c = s.at(col+Left_of_screen); // todo: unicode -272 ¦ if (c == '\n') c = ';'; // replace newlines with semi-colons -273 ¦ // escapes. hack: can't start a line with them. -274 ¦ if (c == '\1') { color = /*red*/1; c = ' '; } -275 ¦ if (c == '\2') { color = TB_WHITE; c = ' '; } -276 ¦ tb_change_cell(col, screen_row, c, color, highlight ? /*subtle grey*/240 : TB_BLACK); -277 } -278 for (; col < tb_width(); ++col) -279 ¦ tb_change_cell(col, screen_row, ' ', TB_WHITE, highlight ? /*subtle grey*/240 : TB_BLACK); -280 } -281 -282 void load_trace(const char* filename) { -283 ifstream tin(filename); -284 if (!tin) { -285 ¦ cerr << "no such file: " << filename << '\n'; -286 ¦ exit(1); -287 } -288 Trace_stream = new trace_stream; -289 while (has_data(tin)) { -290 ¦ tin >> std::noskipws; -291 ¦ ¦ skip_whitespace_but_not_newline(tin); -292 ¦ ¦ if (!isdigit(tin.peek())) { -293 ¦ ¦ ¦ string dummy; -294 ¦ ¦ ¦ getline(tin, dummy); -295 ¦ ¦ ¦ continue; -296 ¦ ¦ } -297 ¦ tin >> std::skipws; -298 ¦ int depth; -299 ¦ tin >> depth; -300 ¦ string label; -301 ¦ tin >> label; -302 ¦ if (*--label.end() == ':') label.erase(--label.end()); -303 ¦ string line; -304 ¦ getline(tin, line); -305 ¦ Trace_stream->past_lines.push_back(trace_line(depth, label, line)); -306 } -307 cerr << "lines read: " << Trace_stream->past_lines.size() << '\n'; -308 } +267 int lines_hidden(int screen_row) { +268 assert(contains_key(Trace_index, screen_row)); +269 if (!contains_key(Trace_index, screen_row+1)) +270 ¦ return SIZE(Trace_stream->past_lines) - get(Trace_index, screen_row); +271 else +272 ¦ return get(Trace_index, screen_row+1) - get(Trace_index, screen_row); +273 } +274 +275 void render_line(int screen_row, const string& s, bool highlight) { +276 int col = 0; +277 int color = TB_WHITE; +278 for (col = 0; col < tb_width() && col+Left_of_screen < SIZE(s); ++col) { +279 ¦ char c = s.at(col+Left_of_screen); // todo: unicode +280 ¦ if (c == '\n') c = ';'; // replace newlines with semi-colons +281 ¦ // escapes. hack: can't start a line with them. +282 ¦ if (c == '\1') { color = /*red*/1; c = ' '; } +283 ¦ if (c == '\2') { color = TB_WHITE; c = ' '; } +284 ¦ tb_change_cell(col, screen_row, c, color, highlight ? /*subtle grey*/240 : TB_BLACK); +285 } +286 for (; col < tb_width(); ++col) +287 ¦ tb_change_cell(col, screen_row, ' ', TB_WHITE, highlight ? /*subtle grey*/240 : TB_BLACK); +288 } +289 +290 void load_trace(const char* filename) { +291 ifstream tin(filename); +292 if (!tin) { +293 ¦ cerr << "no such file: " << filename << '\n'; +294 ¦ exit(1); +295 } +296 Trace_stream = new trace_stream; +297 while (has_data(tin)) { +298 ¦ tin >> std::noskipws; +299 ¦ ¦ skip_whitespace_but_not_newline(tin); +300 ¦ ¦ if (!isdigit(tin.peek())) { +301 ¦ ¦ ¦ string dummy; +302 ¦ ¦ ¦ getline(tin, dummy); +303 ¦ ¦ ¦ continue; +304 ¦ ¦ } +305 ¦ tin >> std::skipws; +306 ¦ int depth; +307 ¦ tin >> depth; +308 ¦ string label; +309 ¦ tin >> label; +310 ¦ if (*--label.end() == ':') label.erase(--label.end()); +311 ¦ string line; +312 ¦ getline(tin, line); +313 ¦ Trace_stream->past_lines.push_back(trace_line(depth, label, line)); +314 } +315 cerr << "lines read: " << Trace_stream->past_lines.size() << '\n'; +316 } -- cgit 1.4.1-2-gfad0