summary refs log blame commit diff stats
path: root/test/stuff/test1.py
blob: 97505c41555512c6a64e02944de530515ee09756 (plain) (tree)
1
2
3
4
5
6
7
8
                  






                                             


                              


























































                                                          
#!/usr/bin/python3
# coding=utf-8
# some tests with curses, threads and unicode
import os
import curses
import time
import threading
import locale
import _thread

lock = _thread.allocate_lock()

locale.setlocale(locale.LC_ALL, 'en_US.utf8')

blocked = False
stringy = 'るでか'
stdscr = curses.initscr()

curses.noecho()
curses.cbreak()
curses.halfdelay(3)
stdscr.keypad(1)
#curses.curs_set(0)

stdscr.addstr(4, 0, stringy)
stdscr.refresh()

class ThreadTest(threading.Thread):
	def __init__(self, *a, **b):
		threading.Thread.__init__(self, *a, **b)
		self.killed = False

	def run(self):
		global stdscr
		global blocked
		for i in range(1,50):
			while blocked: time.sleep(0.1)
			blocked = True
			stdscr.addstr(1, 0, str(i))
			stdscr.refresh()
			blocked = False
			time.sleep(0.1)
			if self.killed: raise SystemExit()

	def kill(self):
		self.killed = True

thr = ThreadTest()
thr.start()

try:
	while 1:
		c = stdscr.getch()
		if c == ord('q'): raise
		while blocked: time.sleep(0.1)
		blocked = True
		stdscr.addstr(0, 0, str(c))
		stdscr.refresh()
		blocked = False

except Exception:
	thr.kill()
	raise
finally:
	curses.nocbreak()
	stdscr.keypad(1)
	curses.echo()
	curses.endwin()
#	curses.curs_set(1)
background-color: #080808; } body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; } * { font-size: 12pt; font-size: 1em; } .Constant { color: #00a0a0; } .Comment { color: #9090ff; } .Delimiter { color: #800080; } .cSpecial { color: #008000; } .Identifier { color: #fcb165; } .Normal { color: #eeeeee; background-color: #080808; padding-bottom: 1px; } --> </style> <script type='text/javascript'> <!-- --> </script> </head> <body> <pre id='vimCodeElement'> <span class="Comment">//: A debugging helper that lets you zoom in/out on a trace.</span> <span class="Comment">//: browse the trace we just created</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span> _BROWSE_TRACE<span class="Delimiter">,</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span> put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;$browse-trace&quot;</span><span class="Delimiter">,</span> _BROWSE_TRACE<span class="Delimiter">);</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span> <span class="Normal">case</span> _BROWSE_TRACE: <span class="Delimiter">{</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span> <span class="Normal">case</span> _BROWSE_TRACE: <span class="Delimiter">{</span> start_trace_browser<span class="Delimiter">();</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Comment">//: browse a trace loaded from a file</span> <span class="Delimiter">:(after &quot;Commandline Parsing&quot;)</span> <span class="Normal">if</span> <span class="Delimiter">(</span>argc == <span class="Constant">3</span> &amp;&amp; is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">&quot;browse-trace&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span> load_trace<span class="Delimiter">(</span>argv[<span class="Constant">2</span>]<span class="Delimiter">);</span> start_trace_browser<span class="Delimiter">();</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Delimiter">:(before &quot;End Globals&quot;)</span> set&lt;<span class="Normal">int</span>&gt; Visible<span class="Delimiter">;</span> <span class="Normal">int</span> Top_of_screen = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">int</span> Last_printed_row = <span class="Constant">0</span><span class="Delimiter">;</span> map&lt;<span class="Normal">int</span><span class="Delimiter">,</span> <span class="Normal">int</span>&gt; Trace_index<span class="Delimiter">;</span> <span class="Comment">// screen row -&gt; trace index</span> <span class="Delimiter">:(code)</span> <span class="Normal">void</span> start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span> cerr &lt;&lt; <span class="Constant">&quot;computing min depth to display</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span> <span class="Normal">int</span> min_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &lt; min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span> <span class="Delimiter">}</span> cerr &lt;&lt; <span class="Constant">&quot;min depth is &quot;</span> &lt;&lt; min_depth &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> cerr &lt;&lt; <span class="Constant">&quot;computing lines to display</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>depth == min_depth<span class="Delimiter">)</span> Visible<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>i<span class="Delimiter">);</span> <span class="Delimiter">}</span> tb_init<span class="Delimiter">();</span> Display_row = Display_column = <span class="Constant">0</span><span class="Delimiter">;</span> tb_event event<span class="Delimiter">;</span> Top_of_screen = <span class="Constant">0</span><span class="Delimiter">;</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Normal">while</span> <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> render<span class="Delimiter">();</span> <span class="Normal">do</span> <span class="Delimiter">{</span> tb_poll_event<span class="Delimiter">(</span>&amp;event<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">while</span> <span class="Delimiter">(</span>event<span class="Delimiter">.</span>type != TB_EVENT_KEY<span class="Delimiter">);</span> <span class="Normal">int</span> key = event<span class="Delimiter">.</span>key ? event<span class="Delimiter">.</span>key : event<span class="Delimiter">.</span>ch<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'q'</span> || key == <span class="Constant">'Q'</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'j'</span> || key == TB_KEY_ARROW_DOWN<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor one line down</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row &lt; Last_printed_row<span class="Delimiter">)</span> ++Display_row<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'k'</span> || key == TB_KEY_ARROW_UP<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor one line up</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Display_row &gt; <span class="Constant">0</span><span class="Delimiter">)</span> --Display_row<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'H'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor to top of screen</span> Display_row = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'M'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor to center of screen</span> Display_row = tb_height<span class="Delimiter">()</span>/<span class="Constant">2</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'L'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// move cursor to bottom of screen</span> Display_row = tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'J'</span> || key == TB_KEY_PGDN<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// page-down</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Trace_index<span class="Delimiter">.</span>find<span class="Delimiter">(</span>tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> != Trace_index<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span> Top_of_screen = get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> + <span class="Constant">1</span><span class="Delimiter">;</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'K'</span> || key == TB_KEY_PGUP<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// page-up is more convoluted</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> screen_row = tb_height<span class="Delimiter">();</span> screen_row &gt; <span class="Constant">0</span> &amp;&amp; Top_of_screen &gt; <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> --Top_of_screen<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Top_of_screen &lt;= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Normal">while</span> <span class="Delimiter">(</span>Top_of_screen &gt; <span class="Constant">0</span> &amp;&amp; !contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> Top_of_screen<span class="Delimiter">))</span> --Top_of_screen<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Top_of_screen &gt;= <span class="Constant">0</span><span class="Delimiter">)</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == <span class="Constant">'G'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// go to bottom of screen; largely like page-up, interestingly</span> Top_of_screen = SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span><span class="Normal">int</span> screen_row = tb_height<span class="Delimiter">();</span> screen_row &gt; <span class="Constant">0</span> &amp;&amp; Top_of_screen &gt; <span class="Constant">0</span><span class="Delimiter">;</span> --screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> --Top_of_screen<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>Top_of_screen &lt;= <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Normal">while</span> <span class="Delimiter">(</span>Top_of_screen &gt; <span class="Constant">0</span> &amp;&amp; !contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> Top_of_screen<span class="Delimiter">))</span> --Top_of_screen<span class="Delimiter">;</span> <span class="Delimiter">}</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Comment">// move cursor to bottom</span> Display_row = Last_printed_row<span class="Delimiter">;</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// expand lines under current by one level</span> assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> Display_row<span class="Delimiter">));</span> <span class="Normal">int</span> start_index = get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// simultaneously compute end_index and min_depth</span> <span class="Normal">int</span> min_depth = <span class="Constant">9999</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span> trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> assert<span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &gt; Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &lt; min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> end_index = index<span class="Delimiter">;</span> <span class="Comment">// mark as visible all intervening indices at min_depth</span> <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index<span class="Delimiter">;</span> index &lt; end_index<span class="Delimiter">;</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == min_depth<span class="Delimiter">)</span> <span class="Delimiter">{</span> Visible<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>key == TB_KEY_BACKSPACE || key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// collapse all lines under current</span> assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> Display_row<span class="Delimiter">));</span> <span class="Normal">int</span> start_index = get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> <span class="Normal">int</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Comment">// end_index is the next line at a depth same as or lower than start_index</span> <span class="Normal">int</span> initial_depth = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &lt;= initial_depth<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">int</span> end_index = index<span class="Delimiter">;</span> <span class="Comment">// mark as visible all intervening indices at min_depth</span> <span class="Normal">for</span> <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index &lt; end_index<span class="Delimiter">;</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> Visible<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>index<span class="Delimiter">);</span> <span class="Delimiter">}</span> refresh_screen_rows<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> tb_shutdown<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Comment">// update Trace_indices for each screen_row on the basis of Top_of_screen and Visible</span> <span class="Normal">void</span> refresh_screen_rows<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Normal">int</span> screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = <span class="Constant">0</span><span class="Delimiter">;</span> Trace_index<span class="Delimiter">.</span>clear<span class="Delimiter">();</span> <span class="Normal">for</span> <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">,</span> index = Top_of_screen<span class="Delimiter">;</span> screen_row &lt; tb_height<span class="Delimiter">()</span> &amp;&amp; index &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++screen_row<span class="Delimiter">,</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Comment">// skip lines without depth for now</span> <span class="Normal">while</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Delimiter">{</span> ++index<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>index &gt;= SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">))</span> <span class="Identifier">goto</span> done<span class="Delimiter">;</span> <span class="Delimiter">}</span> assert<span class="Delimiter">(</span>index &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">));</span> put<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">,</span> index<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">done</span>:<span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">void</span> render<span class="Delimiter">()</span> <span class="Delimiter">{</span> <span class="Normal">int</span> screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span>screen_row = <span class="Constant">0</span><span class="Delimiter">;</span> screen_row &lt; tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span> trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">));</span> ostringstream out<span class="Delimiter">;</span> out &lt;&lt; std::setw<span class="Delimiter">(</span><span class="Constant">4</span><span class="Delimiter">)</span> &lt;&lt; curr_line<span class="Delimiter">.</span>depth &lt;&lt; <span class="Constant">' '</span> &lt;&lt; curr_line<span class="Delimiter">.</span>label &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; curr_line<span class="Delimiter">.</span>contents<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>screen_row &lt; tb_height<span class="Delimiter">()</span>-<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">int</span> delta = lines_hidden<span class="Delimiter">(</span>screen_row<span class="Delimiter">);</span> <span class="Comment">// home-brew escape sequence for red</span> <span class="Normal">if</span> <span class="Delimiter">(</span>delta &gt; <span class="Constant">999</span><span class="Delimiter">)</span> out &lt;&lt; <span class="Constant">&quot;{&quot;</span><span class="Delimiter">;</span> out &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; delta &lt;&lt; <span class="Constant">&quot;)&quot;</span><span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>delta &gt; <span class="Constant">999</span><span class="Delimiter">)</span> out &lt;&lt; <span class="Constant">&quot;}&quot;</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> render_line<span class="Delimiter">(</span>screen_row<span class="Delimiter">,</span> out<span class="Delimiter">.</span>str<span class="Delimiter">());</span> <span class="Delimiter">}</span> <span class="Comment">// clear rest of screen</span> Last_printed_row = screen_row-<span class="Constant">1</span><span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(;</span> screen_row &lt; tb_height<span class="Delimiter">();</span> ++screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> render_line<span class="Delimiter">(</span>screen_row<span class="Delimiter">,</span> <span class="Constant">&quot;~&quot;</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Comment">// move cursor back to display row at the end</span> tb_set_cursor<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">,</span> Display_row<span class="Delimiter">);</span> tb_present<span class="Delimiter">();</span> <span class="Delimiter">}</span> <span class="Normal">int</span> lines_hidden<span class="Delimiter">(</span><span class="Normal">int</span> screen_row<span class="Delimiter">)</span> <span class="Delimiter">{</span> assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">));</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row+<span class="Constant">1</span><span class="Delimiter">))</span> <span class="Identifier">return</span> SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">)</span> - get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">);</span> <span class="Normal">else</span> <span class="Identifier">return</span> get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row+<span class="Constant">1</span><span class="Delimiter">)</span> - get<span class="Delimiter">(</span>Trace_index<span class="Delimiter">,</span> screen_row<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">void</span> render_line<span class="Delimiter">(</span><span class="Normal">int</span> screen_row<span class="Delimiter">,</span> <span class="Normal">const</span> string&amp; s<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">int</span> col = <span class="Constant">0</span><span class="Delimiter">;</span> <span class="Normal">int</span> color = TB_WHITE<span class="Delimiter">;</span> <span class="Normal">for</span> <span class="Delimiter">(</span>col = <span class="Constant">0</span><span class="Delimiter">;</span> col &lt; tb_width<span class="Delimiter">()</span> &amp;&amp; col &lt; SIZE<span class="Delimiter">(</span>s<span class="Delimiter">);</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> <span class="Normal">char</span> c = s<span class="Delimiter">.</span>at<span class="Delimiter">(</span>col<span class="Delimiter">);</span> <span class="Comment">// todo: unicode</span> <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> c = <span class="Constant">';'</span><span class="Delimiter">;</span> <span class="Comment">// replace newlines with semi-colons</span> <span class="Comment">// escapes. hack: can't start a line with them.</span> <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'{'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> color = <span class="Comment">/*</span><span class="Comment">red</span><span class="Comment">*/</span><span class="Constant">1</span><span class="Delimiter">;</span> c = <span class="Constant">' '</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> <span class="Normal">if</span> <span class="Delimiter">(</span>c == <span class="Constant">'}'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span> color = TB_WHITE<span class="Delimiter">;</span> c = <span class="Constant">' '</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> tb_change_cell<span class="Delimiter">(</span>col<span class="Delimiter">,</span> screen_row<span class="Delimiter">,</span> c<span class="Delimiter">,</span> color<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Normal">for</span> <span class="Delimiter">(;</span> col &lt; tb_width<span class="Delimiter">();</span> ++col<span class="Delimiter">)</span> <span class="Delimiter">{</span> tb_change_cell<span class="Delimiter">(</span>col<span class="Delimiter">,</span> screen_row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> TB_WHITE<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span> <span class="Delimiter">}</span> <span class="Delimiter">}</span> <span class="Normal">void</span> load_trace<span class="Delimiter">(</span><span class="Normal">const</span> <span class="Normal">char</span>* filename<span class="Delimiter">)</span> <span class="Delimiter">{</span> ifstream tin<span class="Delimiter">(</span>filename<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!tin<span class="Delimiter">)</span> <span class="Delimiter">{</span> cerr &lt;&lt; <span class="Constant">&quot;no such file: &quot;</span> &lt;&lt; filename &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span> <span class="Delimiter">}</span> Trace_stream = <span class="Normal">new</span> trace_stream<span class="Delimiter">;</span> <span class="Normal">while</span> <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>tin<span class="Delimiter">))</span> <span class="Delimiter">{</span> tin &gt;&gt; std::noskipws<span class="Delimiter">;</span> skip_whitespace_but_not_newline<span class="Delimiter">(</span>tin<span class="Delimiter">);</span> <span class="Normal">if</span> <span class="Delimiter">(</span>!isdigit<span class="Delimiter">(</span>tin<span class="Delimiter">.</span>peek<span class="Delimiter">()))</span> <span class="Delimiter">{</span> string dummy<span class="Delimiter">;</span> getline<span class="Delimiter">(</span>tin<span class="Delimiter">,</span> dummy<span class="Delimiter">);</span> <span class="Identifier">continue</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> tin &gt;&gt; std::skipws<span class="Delimiter">;</span> <span class="Normal">int</span> depth<span class="Delimiter">;</span> tin &gt;&gt; depth<span class="Delimiter">;</span> string label<span class="Delimiter">;</span> tin &gt;&gt; label<span class="Delimiter">;</span> <span class="Normal">if</span> <span class="Delimiter">(</span>*--label<span class="Delimiter">.</span>end<span class="Delimiter">()</span> == <span class="Constant">':'</span><span class="Delimiter">)</span> label<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>--label<span class="Delimiter">.</span>end<span class="Delimiter">());</span> string line<span class="Delimiter">;</span> getline<span class="Delimiter">(</span>tin<span class="Delimiter">,</span> line<span class="Delimiter">);</span> Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>depth<span class="Delimiter">,</span> label<span class="Delimiter">,</span> line<span class="Delimiter">));</span> <span class="Delimiter">}</span> cerr &lt;&lt; <span class="Constant">&quot;lines read: &quot;</span> &lt;&lt; Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>size<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span> <span class="Delimiter">}</span> </pre> </body> </html> <!-- vim: set foldmethod=manual : -->