2 # $Id: tracemunch,v 1.41 2021/09/04 10:31:03 tom Exp $
3 ##############################################################################
4 # Copyright 2018-2020,2021 Thomas E. Dickey #
5 # Copyright 1998-2005,2017 Free Software Foundation, Inc. #
7 # Permission is hereby granted, free of charge, to any person obtaining a #
8 # copy of this software and associated documentation files (the "Software"), #
9 # to deal in the Software without restriction, including without limitation #
10 # the rights to use, copy, modify, merge, publish, distribute, distribute #
11 # with modifications, sublicense, and/or sell copies of the Software, and to #
12 # permit persons to whom the Software is furnished to do so, subject to the #
13 # following conditions: #
15 # The above copyright notice and this permission notice shall be included in #
16 # all copies or substantial portions of the Software. #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
21 # THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
22 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
23 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
24 # DEALINGS IN THE SOFTWARE. #
26 # Except as contained in this notice, the name(s) of the above copyright #
27 # holders shall not be used in advertising or otherwise to promote the sale, #
28 # use or other dealings in this Software without prior written #
30 ##############################################################################
31 # tracemunch -- compactify ncurses trace logs
33 # The error logs produced by ncurses with tracing enabled can be very tedious
34 # to wade through. This script helps by compacting runs of log lines that
35 # can be conveniently expressed as higher-level operations.
43 'PutAttrChar\(\{\{ ' . "'(.)'"
44 . ' = 0[0-7]+ \}\}\) at \(([0-9]+), ([0-9]+)\)';
46 '^called \{waddnstr\((0x[[:xdigit:]]+|window\d+),"((\\.|[^\"]*))",[-]?[0-9]+\)';
68 our $tSCREEN = 1; # SCREEN*
69 our $tWINDOW = 2; # WINDOW*
70 our $tTERMINAL = 3; # TERMINAL*
71 our $tPANEL = 4; # PANEL*
72 our $tFIELD = 5; # FIELD*
73 our $tFORM = 5; # FORM*
74 our $tMENU = 6; # MENU*
75 our $tITEM = 7; # ITEM*
77 our %known_p1_types = (
78 $tSCREEN => "SCREEN*",
79 $tWINDOW => "WINDOW*",
80 $tTERMINAL => "TERMINAL*",
88 # If the trace is complete, we can infer addresses using the return value from
89 # newwin, etc. But if it is incomplete, we can still check for special cases
90 # such as SCREEN* and WINDOW* parameters. In this table, the type for the
91 # first parameter is encoded, relying upon an ncurses programming convention:
93 TransformLine => $tSCREEN,
94 _nc_console_read => $tSCREEN,
95 _nc_freewin => $tWINDOW,
96 _nc_initscr => $tSCREEN,
97 _nc_makenew => $tSCREEN,
98 _nc_mingw_console_read => $tSCREEN,
99 _nc_reset_colors => $tSCREEN,
100 _nc_scroll_optimize => $tSCREEN,
101 _nc_tinfo => $tSCREEN,
102 _nc_tinfo_mvcur => $tSCREEN,
103 _nc_wgetch => $tWINDOW,
104 adjust_window => $tWINDOW,
105 assume_default_colors => $tSCREEN,
106 attr_get => $tWINDOW,
107 baudrate => $tSCREEN,
109 border_set => $tWINDOW,
110 bottom_panel => $tPANEL,
111 bottom_panel => $tPANEL,
114 can_change_color => $tSCREEN,
116 ceiling_panel => $tSCREEN,
118 color_content => $tSCREEN,
120 current_item => $tMENU,
121 curs_set => $tSCREEN,
122 decrease_size => $tSCREEN,
123 def_prog_mode => $tSCREEN,
124 def_shell_mode => $tSCREEN,
125 define_key => $tSCREEN,
126 del_curterm => $tSCREEN,
127 del_panel => $tPANEL,
128 del_panel => $tPANEL,
129 delay_output => $tSCREEN,
130 delscreen => $tSCREEN,
133 doupdate => $tSCREEN,
134 dup_field => $tFIELD,
138 erasechar => $tSCREEN,
139 field_opts_off => $tFIELD,
140 field_opts_on => $tFIELD,
143 flushinp => $tSCREEN,
144 form_driver => $tFORM,
145 form_driver_w => $tFORM,
146 form_opts_off => $tFORM,
147 form_opts_on => $tFORM,
148 free_field => $tFIELD,
152 getattrs => $tWINDOW,
160 getmouse => $tSCREEN,
163 ground_panel => $tSCREEN,
164 halfdelay => $tSCREEN,
168 hide_panel => $tPANEL,
169 hide_panel => $tPANEL,
173 increase_size => $tSCREEN,
174 init_color => $tSCREEN,
175 init_pair => $tSCREEN,
176 intrflush => $tSCREEN,
177 is_cleared => $tWINDOW,
178 is_idcok => $tWINDOW,
179 is_idlok => $tWINDOW,
180 is_immedok => $tWINDOW,
181 is_keypad => $tWINDOW,
182 is_leaveok => $tWINDOW,
183 is_linetouched => $tWINDOW,
184 is_nodelay => $tWINDOW,
185 is_notimeout => $tWINDOW,
187 is_scrollok => $tWINDOW,
188 is_subwin => $tWINDOW,
189 is_syncok => $tWINDOW,
190 is_term_resized => $tSCREEN,
191 is_wintouched => $tWINDOW,
192 item_count => $tMENU,
193 item_description => $tITEM,
194 item_index => $tITEM,
198 item_opts_off => $tITEM,
199 item_opts_on => $tITEM,
201 item_userptr => $tITEM,
202 item_value => $tITEM,
203 item_visible => $tITEM,
204 key_defined => $tSCREEN,
205 keybound => $tSCREEN,
208 killchar => $tSCREEN,
210 link_field => $tFIELD,
211 longname => $tSCREEN,
213 menu_driver => $tMENU,
215 menu_format => $tMENU,
218 menu_items => $tMENU,
221 menu_opts_off => $tMENU,
222 menu_opts_on => $tMENU,
224 menu_pattern => $tMENU,
225 menu_spacing => $tMENU,
228 menu_userptr => $tMENU,
231 mouseinterval => $tSCREEN,
232 mousemask => $tSCREEN,
233 move_field => $tFIELD,
234 move_panel => $tPANEL,
235 move_panel => $tPANEL,
237 mvderwin => $tWINDOW,
238 mvwadd_wch => $tWINDOW,
239 mvwadd_wchnstr => $tWINDOW,
240 mvwadd_wchstr => $tWINDOW,
241 mvwaddch => $tWINDOW,
242 mvwaddchnstr => $tWINDOW,
243 mvwaddchstr => $tWINDOW,
244 mvwaddnstr => $tWINDOW,
245 mvwaddnwstr => $tWINDOW,
246 mvwaddstr => $tWINDOW,
247 mvwaddwstr => $tWINDOW,
248 mvwchgat => $tWINDOW,
249 mvwdelch => $tWINDOW,
250 mvwget_wch => $tWINDOW,
251 mvwget_wstr => $tWINDOW,
252 mvwgetch => $tWINDOW,
253 mvwgetn_wstr => $tWINDOW,
254 mvwgetnstr => $tWINDOW,
255 mvwgetstr => $tWINDOW,
256 mvwhline => $tWINDOW,
257 mvwhline_set => $tWINDOW,
259 mvwin_wch => $tWINDOW,
260 mvwin_wchnstr => $tWINDOW,
261 mvwin_wchstr => $tWINDOW,
263 mvwinchnstr => $tWINDOW,
264 mvwinchstr => $tWINDOW,
265 mvwins_nwstr => $tWINDOW,
266 mvwins_wch => $tWINDOW,
267 mvwins_wstr => $tWINDOW,
268 mvwinsch => $tWINDOW,
269 mvwinsnstr => $tWINDOW,
270 mvwinsstr => $tWINDOW,
271 mvwinstr => $tWINDOW,
272 mvwinwstr => $tWINDOW,
273 mvwvline => $tWINDOW,
274 mvwvline_set => $tWINDOW,
275 new_panel => $tWINDOW,
276 new_panel => $tWINDOW,
281 nocbreak => $tSCREEN,
284 nofilter => $tSCREEN,
286 noqiflush => $tSCREEN,
288 notimeout => $tWINDOW,
291 overwrite => $tWINDOW,
292 pair_content => $tSCREEN,
293 panel_above => $tPANEL,
294 panel_above => $tPANEL,
295 panel_below => $tPANEL,
296 panel_below => $tPANEL,
297 panel_hidden => $tPANEL,
298 panel_hidden => $tPANEL,
299 panel_userptr => $tPANEL,
300 panel_userptr => $tPANEL,
301 panel_window => $tPANEL,
302 panel_window => $tPANEL,
303 pecho_wchar => $tWINDOW,
304 pechochar => $tWINDOW,
305 pnoutrefresh => $tWINDOW,
306 pos_form_cursor => $tFORM,
307 pos_menu_cursor => $tMENU,
313 redrawwin => $tWINDOW,
314 replace_panel => $tPANEL,
315 replace_panel => $tPANEL,
316 reset_prog_mode => $tSCREEN,
317 reset_shell_mode => $tSCREEN,
319 resize_term => $tSCREEN,
320 resizeterm => $tSCREEN,
321 restartterm => $tSCREEN,
322 ripoffline => $tSCREEN,
324 scale_menu => $tMENU,
325 scr_init => $tSCREEN,
326 scr_restore => $tSCREEN,
329 scrollok => $tWINDOW,
330 set_current_field => $tFORM,
331 set_current_item => $tMENU,
332 set_curterm => $tTERMINAL,
333 set_field_back => $tFIELD,
334 set_field_buffer => $tFIELD,
335 set_field_fore => $tFIELD,
336 set_field_init => $tFORM,
337 set_field_just => $tFIELD,
338 set_field_opts => $tFIELD,
339 set_field_pad => $tFIELD,
340 set_field_status => $tFIELD,
341 set_field_term => $tFORM,
342 set_field_type => $tFIELD,
343 set_field_userptr => $tFIELD,
344 set_form_fields => $tFORM,
345 set_form_init => $tFORM,
346 set_form_opts => $tFORM,
347 set_form_page => $tFORM,
348 set_form_sub => $tFORM,
349 set_form_term => $tFORM,
350 set_form_userptr => $tFORM,
351 set_form_win => $tFORM,
352 set_item_init => $tMENU,
353 set_item_opts => $tITEM,
354 set_item_term => $tMENU,
355 set_item_userptr => $tITEM,
356 set_item_value => $tITEM,
357 set_menu_back => $tMENU,
358 set_menu_fore => $tMENU,
359 set_menu_format => $tMENU,
360 set_menu_grey => $tMENU,
361 set_menu_init => $tMENU,
362 set_menu_items => $tMENU,
363 set_menu_mark => $tMENU,
364 set_menu_opts => $tMENU,
365 set_menu_pad => $tMENU,
366 set_menu_pattern => $tMENU,
367 set_menu_spacing => $tMENU,
368 set_menu_sub => $tMENU,
369 set_menu_term => $tMENU,
370 set_menu_userptr => $tMENU,
371 set_menu_win => $tMENU,
372 set_new_page => $tFIELD,
373 set_panel_userptr => $tPANEL,
374 set_panel_userptr => $tPANEL,
375 set_term => $tSCREEN,
376 set_top_row => $tMENU,
377 show_panel => $tPANEL,
378 show_panel => $tPANEL,
379 slk_attr => $tSCREEN,
380 slk_attr_set => $tSCREEN,
381 slk_attroff => $tSCREEN,
382 slk_attron => $tSCREEN,
383 slk_attrset => $tSCREEN,
384 slk_clear => $tSCREEN,
385 slk_color => $tSCREEN,
386 slk_init => $tSCREEN,
387 slk_label => $tSCREEN,
388 slk_noutrefresh => $tSCREEN,
389 slk_refresh => $tSCREEN,
390 slk_restore => $tSCREEN,
392 slk_touch => $tSCREEN,
393 start_color => $tSCREEN,
396 termattrs => $tSCREEN,
397 termname => $tSCREEN,
398 tgetflag => $tSCREEN,
400 tigetflag => $tSCREEN,
401 tigetnum => $tSCREEN,
402 tigetstr => $tSCREEN,
404 top_panel => $tPANEL,
405 top_panel => $tPANEL,
407 touchline => $tWINDOW,
408 touchwin => $tWINDOW,
409 typeahead => $tSCREEN,
410 unfocus_current_field => $tFORM,
411 unget_wch => $tSCREEN,
413 ungetmouse => $tSCREEN,
414 unpost_form => $tFORM,
415 unpost_menu => $tMENU,
416 untouchwin => $tWINDOW,
417 update_panels_sp => $tSCREEN,
418 use_default_colors => $tSCREEN,
420 use_legacy_coding => $tSCREEN,
421 use_screen => $tSCREEN,
422 use_tioctl => $tSCREEN,
423 use_window => $tWINDOW,
426 vw_printw => $tWINDOW,
427 vwprintw => $tWINDOW,
428 wadd_wch => $tWINDOW,
429 wadd_wchnstr => $tWINDOW,
430 wadd_wchstr => $tWINDOW,
432 waddchnstr => $tWINDOW,
433 waddchstr => $tWINDOW,
434 waddnstr => $tWINDOW,
435 waddnwstr => $tWINDOW,
437 waddwstr => $tWINDOW,
438 wattr_get => $tWINDOW,
439 wattr_off => $tWINDOW,
440 wattr_on => $tWINDOW,
441 wattr_set => $tWINDOW,
442 wattroff => $tWINDOW,
444 wattrset => $tWINDOW,
446 wbkgdset => $tWINDOW,
448 wborder_set => $tWINDOW,
451 wclrtobot => $tWINDOW,
452 wclrtoeol => $tWINDOW,
453 wcolor_set => $tWINDOW,
454 wcursyncup => $tWINDOW,
456 wdeleteln => $tWINDOW,
457 wechochar => $tWINDOW,
458 wenclose => $tWINDOW,
460 wget_wch => $tWINDOW,
461 wget_wstr => $tWINDOW,
462 wgetbkgrnd => $tWINDOW,
464 wgetch_events => $tWINDOW,
465 wgetdelay => $tWINDOW,
466 wgetn_wstr => $tWINDOW,
467 wgetnstr => $tWINDOW,
468 wgetparent => $tWINDOW,
469 wgetscrreg => $tWINDOW,
472 whline_set => $tWINDOW,
474 win_wchnstr => $tWINDOW,
475 win_wchstr => $tWINDOW,
477 winchnstr => $tWINDOW,
478 winchstr => $tWINDOW,
480 winnwstr => $tWINDOW,
481 wins_nwstr => $tWINDOW,
482 wins_wch => $tWINDOW,
483 wins_wstr => $tWINDOW,
485 winsdelln => $tWINDOW,
486 winsertln => $tWINDOW,
487 winsnstr => $tWINDOW,
491 wmouse_trafo => $tWINDOW,
493 wnoutrefresh => $tWINDOW,
495 wredrawln => $tWINDOW,
496 wrefresh => $tWINDOW,
499 wsetscrreg => $tWINDOW,
500 wstandend => $tWINDOW,
501 wstandout => $tWINDOW,
502 wsyncdown => $tWINDOW,
504 wtimeout => $tWINDOW,
505 wtouchln => $tWINDOW,
525 our %fld_addr; # FIELD*
526 our %frm_addr; # FORM*
527 our %itm_addr; # ITEM*
528 our %mnu_addr; # MENU*
529 our %pan_addr; # PANEL*
530 our %scr_addr; # SCREEN*
531 our %thr_addr; # thread-id
532 our %trm_addr; # TERMINAL*
533 our %try_addr; # tries-number
534 our %usr_addr; # user-pointer
535 our %win_addr; # WINDOW*
540 $result = 1 if ( $value =~ /\b0x[[:xdigit:]]+\b/i );
548 $arg =~ s/\b$curscr\b/curscr/g if ($curscr);
549 $arg =~ s/\b$newscr\b/newscr/g if ($newscr);
550 $arg =~ s/\b$stdscr\b/stdscr/g if ($stdscr);
551 if ( &has_addr($arg) ) {
552 foreach my $addr ( keys %fld_addr ) {
553 $n = $fld_addr{$addr};
554 $arg =~ s/\b$addr\b/field$n/g if ( defined $n );
557 if ( &has_addr($arg) ) {
558 foreach my $addr ( keys %frm_addr ) {
559 $n = $frm_addr{$addr};
560 $arg =~ s/\b$addr\b/form$n/g if ( defined $n );
563 if ( &has_addr($arg) ) {
564 foreach my $addr ( keys %itm_addr ) {
565 $n = $itm_addr{$addr};
566 $arg =~ s/\b$addr\b/item$n/g if ( defined $n );
569 if ( &has_addr($arg) ) {
570 foreach my $addr ( keys %mnu_addr ) {
571 $n = $mnu_addr{$addr};
572 $arg =~ s/\b$addr\b/menu$n/g if ( defined $n );
575 if ( &has_addr($arg) ) {
576 foreach my $addr ( keys %pan_addr ) {
577 $n = $pan_addr{$addr};
578 $arg =~ s/\b$addr\b/panel$n/g if ( defined $n );
581 if ( &has_addr($arg) ) {
582 foreach my $addr ( keys %scr_addr ) {
583 $n = $scr_addr{$addr};
584 $arg =~ s/\b$addr\b/screen$n/g if ( defined $n );
587 if ( &has_addr($arg) ) {
588 foreach my $addr ( keys %thr_addr ) {
589 $n = $thr_addr{$addr};
590 $arg =~ s/\b$addr\b/thread$n/g if ( defined $n );
593 if ( &has_addr($arg) ) {
594 foreach my $addr ( keys %trm_addr ) {
595 $n = $trm_addr{$addr};
596 $arg =~ s/\b$addr\b/terminal$n/g if ( defined $n );
599 if ( &has_addr($arg) ) {
600 foreach my $addr ( keys %try_addr ) {
601 $n = $try_addr{$addr};
602 $arg =~ s/\b$addr\b/tries_$n/g if ( defined $n );
605 if ( &has_addr($arg) ) {
606 foreach my $addr ( keys %usr_addr ) {
607 $n = $usr_addr{$addr};
608 $arg =~ s/\b$addr\b/user_ptr$n/g if ( defined $n );
611 if ( &has_addr($arg) ) {
612 foreach my $addr ( keys %win_addr ) {
613 $n = $win_addr{$addr};
614 $arg =~ s/\b$addr\b/window$n/g if ( defined $n );
617 if ( &has_addr($arg) ) {
618 if ( $arg =~ /add_wch\((window\d+,)?0x[[:xdigit:]]+\)/i ) {
619 $arg =~ s/(0x[[:xdigit:]]+)[)]/\&wch)/i;
622 $arg =~ /color_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){3}/i )
624 $arg =~ s/(,0x[[:xdigit:]]+){3}[)]/,\&r,\&g,\&b)/i;
626 elsif ( $arg =~ /pair_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){2}/i )
628 $arg =~ s/(,0x[[:xdigit:]]+){2}[)]/,\&fg,\&bg)/i;
631 if ( &has_addr($arg) and $arg =~ /called\s+\{/ ) {
634 $func =~ s/^.*called\s+\{([[:alnum:]_]+)\(.*$/$1/;
635 if ( defined $known_p1{$func} ) {
637 my $type = $known_p1{$func};
639 $addr =~ s/^[^(]+\((0x[[:xdigit:]]+).*$/$1/i;
640 if ( $addr !~ /^0x[[:xdigit:]]+$/i ) {
641 if ( $type == $tSCREEN and $addr =~ /^[^(]+\(screen\d+[,)]/ ) {
645 elsif ( $type == $tWINDOW
647 /^[^(]+\((stdscr|newscr|curscr|window\d+)[,)]/ )
652 elsif ( $type == $tTERMINAL
653 and $addr =~ /^[^(]+\(terminal\d+[,)]/ )
657 elsif ( $type == $tPANEL and $addr =~ /^[^(]+\(panel\d+[,)]/ ) {
661 elsif ( $type == $tFIELD and $addr =~ /^[^(]+\(field\d+[,)]/ ) {
665 elsif ( $type == $tMENU and $addr =~ /^[^(]+\(menu\d+[,)]/ ) {
669 elsif ( $type == $tITEM and $addr =~ /^[^(]+\(item\d+[,)]/ ) {
674 printf "OOPS - expected type \"%s\", skipping\n>>$addr\n",
675 $known_p1_types{$type};
678 elsif ( $type == $tSCREEN ) {
679 $scr_addr{$addr} = ++$scr_nums;
680 $arg = &transaddr($arg);
682 elsif ( $type == $tWINDOW ) {
683 $win_addr{$addr} = ++$win_nums;
684 $arg = &transaddr($arg);
686 elsif ( $type == $tTERMINAL ) {
687 $trm_addr{$addr} = ++$trm_nums;
688 $arg = &transaddr($arg);
690 elsif ( $type == $tPANEL ) {
691 $pan_addr{$addr} = ++$pan_nums;
692 $arg = &transaddr($arg);
694 elsif ( $type == $tFIELD ) {
695 $fld_addr{$addr} = ++$fld_nums;
696 $arg = &transaddr($arg);
698 elsif ( $type == $tFORM ) {
699 $frm_addr{$addr} = ++$frm_nums;
700 $arg = &transaddr($arg);
702 elsif ( $type == $tMENU ) {
703 $mnu_addr{$addr} = ++$mnu_nums;
704 $arg = &transaddr($arg);
706 elsif ( $type == $tITEM ) {
707 $itm_addr{$addr} = ++$itm_nums;
708 $arg = &transaddr($arg);
728 # just in case someone tries a file with cr/lf line-endings:
733 /^TRACING NCURSES version.*\(tracelevel=(0x[[:xdigit:]]+)\)/ )
735 $tracelevel = hex $1;
741 if ( $_ =~ /^(0x[[:xdigit:]]+):/ ) {
742 $thr_addr{$1} = ++$thr_nums unless defined $thr_addr{$1};
743 $thread = "thread" . $thr_addr{$1} . ":";
747 # Transform window pointer addresses to make it easier to compare logs
748 $awaiting = "curscr" if ( $_ =~ /creating curscr/ );
749 $awaiting = "newscr" if ( $_ =~ /creating newscr/ );
750 $awaiting = "stdscr" if ( $_ =~ /creating stdscr/ );
751 $awaiting = "screen" if ( $_ =~ /^(\+ )*called \{new_prescr\(\)/ );
752 if ( $_ =~ /^create :window 0x([[:xdigit:]]+)/ ) {
754 if ( $awaiting eq "curscr" ) {
757 elsif ( $awaiting eq "newscr" ) {
760 elsif ( $awaiting eq "stdscr" ) {
764 $win_addr{$addr} = $win_nums++;
768 elsif ( $_ =~ /^create :(root|new)_panel 0x([[:xdigit:]]+)/ ) {
770 $pan_addr{$addr} = $pan_nums++;
773 elsif ( $_ =~ /^create :user_ptr 0x([[:xdigit:]]+)/ ) {
775 $usr_addr{$addr} = $usr_nums++;
778 elsif ( $_ =~ /^create :field 0x([[:xdigit:]]+)/ ) {
780 $fld_addr{$addr} = $fld_nums++;
783 elsif ( $_ =~ /^create :form 0x([[:xdigit:]]+)/ ) {
785 $frm_addr{$addr} = $frm_nums++;
788 elsif ( $_ =~ /^create :menu 0x([[:xdigit:]]+)/ ) {
790 $mnu_addr{$addr} = $mnu_nums++;
793 elsif ( $_ =~ /^create :item 0x([[:xdigit:]]+)/ ) {
795 $itm_addr{$addr} = $itm_nums++;
798 elsif ( $_ =~ /^(\+ )*called \{set_curterm\((0x[[:xdigit:]]+)\)/ ) {
799 $trm_addr{$2} = ++$trm_nums unless defined $trm_addr{$2};
801 elsif ( $_ =~ /^(\+ )*called \{_nc_add_to_try\((0x[[:xdigit:]]+),/ )
803 $try_addr{$2} = ++$try_nums unless defined $try_addr{$2};
805 elsif ( $_ =~ /^(\+ )*_nc_alloc_screen_sp 0x([[:xdigit:]]+)/ ) {
807 $scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
810 elsif ( $_ =~ /^(\+ )*return }0x([[:xdigit:]]+)/ ) {
812 if ( $awaiting eq "screen" ) {
813 $scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
816 elsif ( $_ =~ /^\.\.\.deleted win=0x([[:xdigit:]]+)/ ) {
819 if ( $addr eq $curscr ) {
822 elsif ( $addr eq $newscr ) {
825 elsif ( $addr eq $stdscr ) {
829 undef $win_addr{$addr};
832 elsif ( $_ =~ /^\.\.\.deleted pan=\"0x([[:xdigit:]]+)\"/ ) {
835 undef $pan_addr{$addr};
837 elsif ( $_ =~ /^([+ ])*called \{free_field\(0x([[:xdigit:]]+)\)/ ) {
840 undef $fld_addr{$addr};
842 elsif ( $_ =~ /^([+ ])*called \{free_form\(0x([[:xdigit:]]+)\)/ ) {
845 undef $frm_addr{$addr};
847 elsif ( $_ =~ /^([+ ])*called \{free_menu\(0x([[:xdigit:]]+)\)/ ) {
850 undef $mnu_addr{$addr};
852 elsif ( $_ =~ /^([+ ])*called \{free_item\(0x([[:xdigit:]]+)\)/ ) {
855 undef $itm_addr{$addr};
858 # Compactify runs of PutAttrChar
859 if ( ( ( $tracelevel & $TR{CHARPUT} ) != 0 ) and $_ =~ /$putattr/ )
861 my $putattr_chars = $1;
865 if ( $_ =~ /$putattr/ ) {
866 $putattr_chars .= $1;
869 next if ( $_ =~ /^PUTC 0x[[:xdigit:]]+.*/ );
870 next if ( $_ =~ /^\.\.\.skip.*/ );
871 next if ( $_ =~ /^forced to blank.*/ );
875 print "RUN of PutAttrChar()s:"
876 . " \"$putattr_chars\" from ${starty}, ${startx}\n";
880 # Compactify runs of waddnstr calls
881 if ( ( ( $tracelevel & $TR{CALLS} ) != 0 ) and $_ =~ /$waddnstr/ ) {
882 my $waddnstr_chars = $2;
885 next if ( $_ =~ /^return \}0/ );
886 if ( $_ =~ /$waddnstr/ && $1 eq $winaddr ) {
887 $waddnstr_chars .= $2;
893 my $winaddstr = &transaddr($winaddr);
894 print "RUN of waddnstr()s:"
895 . " $winaddstr, \"$waddnstr_chars\"\n";
899 # More transformations can go here
901 # Repeated runs of anything
902 my $anyline = &transaddr($_);
905 if ( &transaddr($_) eq $anyline ) {
912 if ( $repeatcount > 1 ) {
913 print "${repeatcount} REPEATS OF $anyline";
916 print $thread . $anyline;
924 for my $tr ( keys %TR ) {
925 $TR{$tr} = hex $TR{$tr};
929 while ( $#ARGV >= 0 ) {
930 my $file = shift @ARGV;
931 open my $ifh, "<", $file or die $!;
939 # tracemunch ends here