blob: b2d3b03b216ca73e820f0e4b981a5a9b3cd5fb5f [file] [log] [blame]
micky3879b9f5e72025-07-08 18:04:53 -04001#!/usr/bin/env perl
2# $Id: tracemunch,v 1.41 2021/09/04 10:31:03 tom Exp $
Steve Kondikae271bc2015-11-15 02:50:53 +01003##############################################################################
micky3879b9f5e72025-07-08 18:04:53 -04004# Copyright 2018-2020,2021 Thomas E. Dickey #
5# Copyright 1998-2005,2017 Free Software Foundation, Inc. #
Steve Kondikae271bc2015-11-15 02:50:53 +01006# #
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: #
14# #
15# The above copyright notice and this permission notice shall be included in #
16# all copies or substantial portions of the Software. #
17# #
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. #
25# #
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 #
29# authorization. #
30##############################################################################
31# tracemunch -- compactify ncurses trace logs
32#
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.
micky3879b9f5e72025-07-08 18:04:53 -040036
Steve Kondikae271bc2015-11-15 02:50:53 +010037use strict;
micky3879b9f5e72025-07-08 18:04:53 -040038use warnings;
Steve Kondikae271bc2015-11-15 02:50:53 +010039
micky3879b9f5e72025-07-08 18:04:53 -040040$| = 1;
Steve Kondikae271bc2015-11-15 02:50:53 +010041
micky3879b9f5e72025-07-08 18:04:53 -040042our $putattr =
43 'PutAttrChar\(\{\{ ' . "'(.)'"
44 . ' = 0[0-7]+ \}\}\) at \(([0-9]+), ([0-9]+)\)';
45our $waddnstr =
46'^called \{waddnstr\((0x[[:xdigit:]]+|window\d+),"((\\.|[^\"]*))",[-]?[0-9]+\)';
Steve Kondikae271bc2015-11-15 02:50:53 +010047
micky3879b9f5e72025-07-08 18:04:53 -040048our %TR = qw(
49 DISABLE 0x0000
50 TIMES 0x0001
51 TPUTS 0x0002
52 UPDATE 0x0004
53 MOVE 0x0008
54 CHARPUT 0x0010
55 ORDINARY 0x001F
56 CALLS 0x0020
57 VIRTPUT 0x0040
58 IEVENT 0x0080
59 BITS 0x0100
60 ICALLS 0x0200
61 CCALLS 0x0400
62 DATABASE 0x0800
63 ATTRS 0x1000
64);
65
66our $tracelevel = 0;
67
68our $tSCREEN = 1; # SCREEN*
69our $tWINDOW = 2; # WINDOW*
70our $tTERMINAL = 3; # TERMINAL*
71our $tPANEL = 4; # PANEL*
72our $tFIELD = 5; # FIELD*
73our $tFORM = 5; # FORM*
74our $tMENU = 6; # MENU*
75our $tITEM = 7; # ITEM*
76
77our %known_p1_types = (
78 $tSCREEN => "SCREEN*",
79 $tWINDOW => "WINDOW*",
80 $tTERMINAL => "TERMINAL*",
81 $tPANEL => "PANEL*",
82 $tFORM => "FORM*",
83 $tFIELD => "FIELD*",
84 $tMENU => "MENU*",
85 $tITEM => "ITEM*",
86);
87
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:
92our %known_p1 = (
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,
108 beep => $tSCREEN,
109 border_set => $tWINDOW,
110 bottom_panel => $tPANEL,
111 bottom_panel => $tPANEL,
112 box => $tWINDOW,
113 box_set => $tWINDOW,
114 can_change_color => $tSCREEN,
115 cbreak => $tSCREEN,
116 ceiling_panel => $tSCREEN,
117 clearok => $tWINDOW,
118 color_content => $tSCREEN,
119 copywin => $tWINDOW,
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,
131 delwin => $tWINDOW,
132 derwin => $tWINDOW,
133 doupdate => $tSCREEN,
134 dup_field => $tFIELD,
135 dupwin => $tWINDOW,
136 echo => $tSCREEN,
137 endwin => $tSCREEN,
138 erasechar => $tSCREEN,
139 field_opts_off => $tFIELD,
140 field_opts_on => $tFIELD,
141 filter => $tSCREEN,
142 flash => $tSCREEN,
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,
149 free_form => $tFORM,
150 free_item => $tITEM,
151 free_menu => $tMENU,
152 getattrs => $tWINDOW,
153 getbegx => $tWINDOW,
154 getbegy => $tWINDOW,
155 getbkgd => $tWINDOW,
156 getcurx => $tWINDOW,
157 getcury => $tWINDOW,
158 getmaxx => $tWINDOW,
159 getmaxy => $tWINDOW,
160 getmouse => $tSCREEN,
161 getparx => $tWINDOW,
162 getpary => $tWINDOW,
163 ground_panel => $tSCREEN,
164 halfdelay => $tSCREEN,
165 has_ic => $tSCREEN,
166 has_il => $tSCREEN,
167 has_key => $tSCREEN,
168 hide_panel => $tPANEL,
169 hide_panel => $tPANEL,
170 idcok => $tWINDOW,
171 idlok => $tWINDOW,
172 immedok => $tWINDOW,
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,
186 is_pad => $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,
195 item_init => $tMENU,
196 item_name => $tITEM,
197 item_opts => $tITEM,
198 item_opts_off => $tITEM,
199 item_opts_on => $tITEM,
200 item_term => $tMENU,
201 item_userptr => $tITEM,
202 item_value => $tITEM,
203 item_visible => $tITEM,
204 key_defined => $tSCREEN,
205 keybound => $tSCREEN,
206 keyok => $tSCREEN,
207 keypad => $tWINDOW,
208 killchar => $tSCREEN,
209 leaveok => $tWINDOW,
210 link_field => $tFIELD,
211 longname => $tSCREEN,
212 menu_back => $tMENU,
213 menu_driver => $tMENU,
214 menu_fore => $tMENU,
215 menu_format => $tMENU,
216 menu_grey => $tMENU,
217 menu_init => $tMENU,
218 menu_items => $tMENU,
219 menu_mark => $tMENU,
220 menu_opts => $tMENU,
221 menu_opts_off => $tMENU,
222 menu_opts_on => $tMENU,
223 menu_pad => $tMENU,
224 menu_pattern => $tMENU,
225 menu_spacing => $tMENU,
226 menu_sub => $tMENU,
227 menu_term => $tMENU,
228 menu_userptr => $tMENU,
229 menu_win => $tMENU,
230 meta => $tWINDOW,
231 mouseinterval => $tSCREEN,
232 mousemask => $tSCREEN,
233 move_field => $tFIELD,
234 move_panel => $tPANEL,
235 move_panel => $tPANEL,
236 mvcur => $tSCREEN,
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,
258 mvwin => $tWINDOW,
259 mvwin_wch => $tWINDOW,
260 mvwin_wchnstr => $tWINDOW,
261 mvwin_wchstr => $tWINDOW,
262 mvwinch => $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,
277 newpad => $tSCREEN,
278 newterm => $tSCREEN,
279 newwin => $tSCREEN,
280 nl => $tSCREEN,
281 nocbreak => $tSCREEN,
282 nodelay => $tWINDOW,
283 noecho => $tSCREEN,
284 nofilter => $tSCREEN,
285 nonl => $tSCREEN,
286 noqiflush => $tSCREEN,
287 noraw => $tSCREEN,
288 notimeout => $tWINDOW,
289 overlap => $tWINDOW,
290 overlay => $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,
308 post_form => $tFORM,
309 post_menu => $tMENU,
310 putwin => $tWINDOW,
311 qiflush => $tSCREEN,
312 raw => $tSCREEN,
313 redrawwin => $tWINDOW,
314 replace_panel => $tPANEL,
315 replace_panel => $tPANEL,
316 reset_prog_mode => $tSCREEN,
317 reset_shell_mode => $tSCREEN,
318 resetty => $tSCREEN,
319 resize_term => $tSCREEN,
320 resizeterm => $tSCREEN,
321 restartterm => $tSCREEN,
322 ripoffline => $tSCREEN,
323 savetty => $tSCREEN,
324 scale_menu => $tMENU,
325 scr_init => $tSCREEN,
326 scr_restore => $tSCREEN,
327 scr_set => $tSCREEN,
328 scroll => $tWINDOW,
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,
391 slk_set => $tSCREEN,
392 slk_touch => $tSCREEN,
393 start_color => $tSCREEN,
394 subwin => $tWINDOW,
395 syncok => $tWINDOW,
396 termattrs => $tSCREEN,
397 termname => $tSCREEN,
398 tgetflag => $tSCREEN,
399 tgetnum => $tSCREEN,
400 tigetflag => $tSCREEN,
401 tigetnum => $tSCREEN,
402 tigetstr => $tSCREEN,
403 tinfo => $tSCREEN,
404 top_panel => $tPANEL,
405 top_panel => $tPANEL,
406 top_row => $tMENU,
407 touchline => $tWINDOW,
408 touchwin => $tWINDOW,
409 typeahead => $tSCREEN,
410 unfocus_current_field => $tFORM,
411 unget_wch => $tSCREEN,
412 ungetch => $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,
419 use_env => $tSCREEN,
420 use_legacy_coding => $tSCREEN,
421 use_screen => $tSCREEN,
422 use_tioctl => $tSCREEN,
423 use_window => $tWINDOW,
424 vidattr => $tSCREEN,
425 vidputs => $tSCREEN,
426 vw_printw => $tWINDOW,
427 vwprintw => $tWINDOW,
428 wadd_wch => $tWINDOW,
429 wadd_wchnstr => $tWINDOW,
430 wadd_wchstr => $tWINDOW,
431 waddch => $tWINDOW,
432 waddchnstr => $tWINDOW,
433 waddchstr => $tWINDOW,
434 waddnstr => $tWINDOW,
435 waddnwstr => $tWINDOW,
436 waddstr => $tWINDOW,
437 waddwstr => $tWINDOW,
438 wattr_get => $tWINDOW,
439 wattr_off => $tWINDOW,
440 wattr_on => $tWINDOW,
441 wattr_set => $tWINDOW,
442 wattroff => $tWINDOW,
443 wattron => $tWINDOW,
444 wattrset => $tWINDOW,
445 wbkgd => $tWINDOW,
446 wbkgdset => $tWINDOW,
447 wborder => $tWINDOW,
448 wborder_set => $tWINDOW,
449 wchgat => $tWINDOW,
450 wclear => $tWINDOW,
451 wclrtobot => $tWINDOW,
452 wclrtoeol => $tWINDOW,
453 wcolor_set => $tWINDOW,
454 wcursyncup => $tWINDOW,
455 wdelch => $tWINDOW,
456 wdeleteln => $tWINDOW,
457 wechochar => $tWINDOW,
458 wenclose => $tWINDOW,
459 werase => $tWINDOW,
460 wget_wch => $tWINDOW,
461 wget_wstr => $tWINDOW,
462 wgetbkgrnd => $tWINDOW,
463 wgetch => $tWINDOW,
464 wgetch_events => $tWINDOW,
465 wgetdelay => $tWINDOW,
466 wgetn_wstr => $tWINDOW,
467 wgetnstr => $tWINDOW,
468 wgetparent => $tWINDOW,
469 wgetscrreg => $tWINDOW,
470 wgetstr => $tWINDOW,
471 whline => $tWINDOW,
472 whline_set => $tWINDOW,
473 win_wch => $tWINDOW,
474 win_wchnstr => $tWINDOW,
475 win_wchstr => $tWINDOW,
476 winch => $tWINDOW,
477 winchnstr => $tWINDOW,
478 winchstr => $tWINDOW,
479 winnstr => $tWINDOW,
480 winnwstr => $tWINDOW,
481 wins_nwstr => $tWINDOW,
482 wins_wch => $tWINDOW,
483 wins_wstr => $tWINDOW,
484 winsch => $tWINDOW,
485 winsdelln => $tWINDOW,
486 winsertln => $tWINDOW,
487 winsnstr => $tWINDOW,
488 winsstr => $tWINDOW,
489 winstr => $tWINDOW,
490 winwstr => $tWINDOW,
491 wmouse_trafo => $tWINDOW,
492 wmove => $tWINDOW,
493 wnoutrefresh => $tWINDOW,
494 wprintw => $tWINDOW,
495 wredrawln => $tWINDOW,
496 wrefresh => $tWINDOW,
497 wresize => $tWINDOW,
498 wscrl => $tWINDOW,
499 wsetscrreg => $tWINDOW,
500 wstandend => $tWINDOW,
501 wstandout => $tWINDOW,
502 wsyncdown => $tWINDOW,
503 wsyncup => $tWINDOW,
504 wtimeout => $tWINDOW,
505 wtouchln => $tWINDOW,
506 wvline => $tWINDOW,
507);
508
509our $fld_nums = 0;
510our $frm_nums = 0;
511our $itm_nums = 0;
512our $mnu_nums = 0;
513our $pan_nums = 0;
514our $scr_nums = 0;
515our $thr_nums = 0;
516our $trm_nums = 0;
517our $try_nums = 0;
518our $usr_nums = 0;
519our $win_nums = 0;
520
521our $curscr = "";
522our $newscr = "";
523our $stdscr = "";
524
525our %fld_addr; # FIELD*
526our %frm_addr; # FORM*
527our %itm_addr; # ITEM*
528our %mnu_addr; # MENU*
529our %pan_addr; # PANEL*
530our %scr_addr; # SCREEN*
531our %thr_addr; # thread-id
532our %trm_addr; # TERMINAL*
533our %try_addr; # tries-number
534our %usr_addr; # user-pointer
535our %win_addr; # WINDOW*
536
537sub has_addr($) {
538 my $value = shift;
539 my $result = 0;
540 $result = 1 if ( $value =~ /\b0x[[:xdigit:]]+\b/i );
541 return $result;
542}
543
544sub transaddr($) {
545 my $arg = shift;
Steve Kondikae271bc2015-11-15 02:50:53 +0100546 my $n;
Steve Kondikae271bc2015-11-15 02:50:53 +0100547
micky3879b9f5e72025-07-08 18:04:53 -0400548 $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 );
555 }
556 }
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 );
561 }
562 }
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 );
567 }
568 }
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 );
573 }
574 }
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 );
579 }
580 }
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 );
585 }
586 }
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 );
591 }
592 }
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 );
597 }
598 }
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 );
603 }
604 }
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 );
609 }
610 }
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 );
615 }
616 }
617 if ( &has_addr($arg) ) {
618 if ( $arg =~ /add_wch\((window\d+,)?0x[[:xdigit:]]+\)/i ) {
619 $arg =~ s/(0x[[:xdigit:]]+)[)]/\&wch)/i;
620 }
621 elsif (
622 $arg =~ /color_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){3}/i )
623 {
624 $arg =~ s/(,0x[[:xdigit:]]+){3}[)]/,\&r,\&g,\&b)/i;
625 }
626 elsif ( $arg =~ /pair_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){2}/i )
627 {
628 $arg =~ s/(,0x[[:xdigit:]]+){2}[)]/,\&fg,\&bg)/i;
629 }
630 }
631 if ( &has_addr($arg) and $arg =~ /called\s+\{/ ) {
632 my $func = $arg;
633 chomp $func;
634 $func =~ s/^.*called\s+\{([[:alnum:]_]+)\(.*$/$1/;
635 if ( defined $known_p1{$func} ) {
636 my $addr = $arg;
637 my $type = $known_p1{$func};
638 chomp $addr;
639 $addr =~ s/^[^(]+\((0x[[:xdigit:]]+).*$/$1/i;
640 if ( $addr !~ /^0x[[:xdigit:]]+$/i ) {
641 if ( $type == $tSCREEN and $addr =~ /^[^(]+\(screen\d+[,)]/ ) {
642
643 # ignore
644 }
645 elsif ( $type == $tWINDOW
646 and $addr =~
647 /^[^(]+\((stdscr|newscr|curscr|window\d+)[,)]/ )
648 {
649
650 # ignore
651 }
652 elsif ( $type == $tTERMINAL
653 and $addr =~ /^[^(]+\(terminal\d+[,)]/ )
654 {
655 # ignore
656 }
657 elsif ( $type == $tPANEL and $addr =~ /^[^(]+\(panel\d+[,)]/ ) {
658
659 # ignore
660 }
661 elsif ( $type == $tFIELD and $addr =~ /^[^(]+\(field\d+[,)]/ ) {
662
663 # ignore
664 }
665 elsif ( $type == $tMENU and $addr =~ /^[^(]+\(menu\d+[,)]/ ) {
666
667 # ignore
668 }
669 elsif ( $type == $tITEM and $addr =~ /^[^(]+\(item\d+[,)]/ ) {
670
671 # ignore
672 }
673 else {
674 printf "OOPS - expected type \"%s\", skipping\n>>$addr\n",
675 $known_p1_types{$type};
676 }
677 }
678 elsif ( $type == $tSCREEN ) {
679 $scr_addr{$addr} = ++$scr_nums;
680 $arg = &transaddr($arg);
681 }
682 elsif ( $type == $tWINDOW ) {
683 $win_addr{$addr} = ++$win_nums;
684 $arg = &transaddr($arg);
685 }
686 elsif ( $type == $tTERMINAL ) {
687 $trm_addr{$addr} = ++$trm_nums;
688 $arg = &transaddr($arg);
689 }
690 elsif ( $type == $tPANEL ) {
691 $pan_addr{$addr} = ++$pan_nums;
692 $arg = &transaddr($arg);
693 }
694 elsif ( $type == $tFIELD ) {
695 $fld_addr{$addr} = ++$fld_nums;
696 $arg = &transaddr($arg);
697 }
698 elsif ( $type == $tFORM ) {
699 $frm_addr{$addr} = ++$frm_nums;
700 $arg = &transaddr($arg);
701 }
702 elsif ( $type == $tMENU ) {
703 $mnu_addr{$addr} = ++$mnu_nums;
704 $arg = &transaddr($arg);
705 }
706 elsif ( $type == $tITEM ) {
707 $itm_addr{$addr} = ++$itm_nums;
708 $arg = &transaddr($arg);
709 }
710 }
Steve Kondikae271bc2015-11-15 02:50:53 +0100711 }
712
713 return $arg;
714}
715
micky3879b9f5e72025-07-08 18:04:53 -0400716sub muncher($) {
717 my $STDIN = shift;
Steve Kondikae271bc2015-11-15 02:50:53 +0100718
micky3879b9f5e72025-07-08 18:04:53 -0400719 while (<$STDIN>) {
720 my $addr;
721 my $n;
722 my $awaiting = "";
Steve Kondikae271bc2015-11-15 02:50:53 +0100723
micky3879b9f5e72025-07-08 18:04:53 -0400724 CLASSIFY: {
Steve Kondikae271bc2015-11-15 02:50:53 +0100725
micky3879b9f5e72025-07-08 18:04:53 -0400726 next unless $_;
Steve Kondikae271bc2015-11-15 02:50:53 +0100727
micky3879b9f5e72025-07-08 18:04:53 -0400728 # just in case someone tries a file with cr/lf line-endings:
729 $_ =~ s/\r\n/\n/g;
730 $_ =~ s/\r/\n/g;
Steve Kondikae271bc2015-11-15 02:50:53 +0100731
micky3879b9f5e72025-07-08 18:04:53 -0400732 if ( $_ =~
733 /^TRACING NCURSES version.*\(tracelevel=(0x[[:xdigit:]]+)\)/ )
734 {
735 $tracelevel = hex $1;
736 print;
737 next;
738 }
Steve Kondikae271bc2015-11-15 02:50:53 +0100739
micky3879b9f5e72025-07-08 18:04:53 -0400740 my $thread = "";
741 if ( $_ =~ /^(0x[[:xdigit:]]+):/ ) {
742 $thr_addr{$1} = ++$thr_nums unless defined $thr_addr{$1};
743 $thread = "thread" . $thr_addr{$1} . ":";
744 $_ =~ s/^[^:]*://;
745 }
746
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:]]+)/ ) {
753 $addr = "0x$1";
754 if ( $awaiting eq "curscr" ) {
755 $curscr = $addr;
756 }
757 elsif ( $awaiting eq "newscr" ) {
758 $newscr = $addr;
759 }
760 elsif ( $awaiting eq "stdscr" ) {
761 $stdscr = $addr;
762 }
763 else {
764 $win_addr{$addr} = $win_nums++;
765 }
766 $awaiting = "";
767 }
768 elsif ( $_ =~ /^create :(root|new)_panel 0x([[:xdigit:]]+)/ ) {
769 $addr = "0x$2";
770 $pan_addr{$addr} = $pan_nums++;
771 $_ = &transaddr($_);
772 }
773 elsif ( $_ =~ /^create :user_ptr 0x([[:xdigit:]]+)/ ) {
774 $addr = "0x$1";
775 $usr_addr{$addr} = $usr_nums++;
776 $_ = &transaddr($_);
777 }
778 elsif ( $_ =~ /^create :field 0x([[:xdigit:]]+)/ ) {
779 $addr = "0x$1";
780 $fld_addr{$addr} = $fld_nums++;
781 $_ = &transaddr($_);
782 }
783 elsif ( $_ =~ /^create :form 0x([[:xdigit:]]+)/ ) {
784 $addr = "0x$1";
785 $frm_addr{$addr} = $frm_nums++;
786 $_ = &transaddr($_);
787 }
788 elsif ( $_ =~ /^create :menu 0x([[:xdigit:]]+)/ ) {
789 $addr = "0x$1";
790 $mnu_addr{$addr} = $mnu_nums++;
791 $_ = &transaddr($_);
792 }
793 elsif ( $_ =~ /^create :item 0x([[:xdigit:]]+)/ ) {
794 $addr = "0x$1";
795 $itm_addr{$addr} = $itm_nums++;
796 $_ = &transaddr($_);
797 }
798 elsif ( $_ =~ /^(\+ )*called \{set_curterm\((0x[[:xdigit:]]+)\)/ ) {
799 $trm_addr{$2} = ++$trm_nums unless defined $trm_addr{$2};
800 }
801 elsif ( $_ =~ /^(\+ )*called \{_nc_add_to_try\((0x[[:xdigit:]]+),/ )
802 {
803 $try_addr{$2} = ++$try_nums unless defined $try_addr{$2};
804 }
805 elsif ( $_ =~ /^(\+ )*_nc_alloc_screen_sp 0x([[:xdigit:]]+)/ ) {
806 $addr = "0x$2";
807 $scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
808 $awaiting = "";
809 }
810 elsif ( $_ =~ /^(\+ )*return }0x([[:xdigit:]]+)/ ) {
811 $addr = "0x$2";
812 if ( $awaiting eq "screen" ) {
813 $scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
814 }
815 }
816 elsif ( $_ =~ /^\.\.\.deleted win=0x([[:xdigit:]]+)/ ) {
817 $addr = "0x$1";
818 $_ = &transaddr($_);
819 if ( $addr eq $curscr ) {
820 $curscr = "";
821 }
822 elsif ( $addr eq $newscr ) {
823 $newscr = "";
824 }
825 elsif ( $addr eq $stdscr ) {
826 $stdscr = "";
827 }
828 else {
829 undef $win_addr{$addr};
830 }
831 }
832 elsif ( $_ =~ /^\.\.\.deleted pan=\"0x([[:xdigit:]]+)\"/ ) {
833 $addr = "0x$1";
834 $_ = &transaddr($_);
835 undef $pan_addr{$addr};
836 }
837 elsif ( $_ =~ /^([+ ])*called \{free_field\(0x([[:xdigit:]]+)\)/ ) {
838 $addr = "0x$2";
839 $_ = &transaddr($_);
840 undef $fld_addr{$addr};
841 }
842 elsif ( $_ =~ /^([+ ])*called \{free_form\(0x([[:xdigit:]]+)\)/ ) {
843 $addr = "0x$2";
844 $_ = &transaddr($_);
845 undef $frm_addr{$addr};
846 }
847 elsif ( $_ =~ /^([+ ])*called \{free_menu\(0x([[:xdigit:]]+)\)/ ) {
848 $addr = "0x$2";
849 $_ = &transaddr($_);
850 undef $mnu_addr{$addr};
851 }
852 elsif ( $_ =~ /^([+ ])*called \{free_item\(0x([[:xdigit:]]+)\)/ ) {
853 $addr = "0x$2";
854 $_ = &transaddr($_);
855 undef $itm_addr{$addr};
856 }
857
858 # Compactify runs of PutAttrChar
859 if ( ( ( $tracelevel & $TR{CHARPUT} ) != 0 ) and $_ =~ /$putattr/ )
860 {
861 my $putattr_chars = $1;
862 my $starty = $2;
863 my $startx = $3;
864 while (<$STDIN>) {
865 if ( $_ =~ /$putattr/ ) {
866 $putattr_chars .= $1;
867 }
868 else {
869 next if ( $_ =~ /^PUTC 0x[[:xdigit:]]+.*/ );
870 next if ( $_ =~ /^\.\.\.skip.*/ );
871 next if ( $_ =~ /^forced to blank.*/ );
872 last;
873 }
874 }
875 print "RUN of PutAttrChar()s:"
876 . " \"$putattr_chars\" from ${starty}, ${startx}\n";
877 redo CLASSIFY;
878 }
879
880 # Compactify runs of waddnstr calls
881 if ( ( ( $tracelevel & $TR{CALLS} ) != 0 ) and $_ =~ /$waddnstr/ ) {
882 my $waddnstr_chars = $2;
883 my $winaddr = $1;
884 while (<$STDIN>) {
885 next if ( $_ =~ /^return \}0/ );
886 if ( $_ =~ /$waddnstr/ && $1 eq $winaddr ) {
887 $waddnstr_chars .= $2;
888 }
889 else {
890 last;
891 }
892 }
893 my $winaddstr = &transaddr($winaddr);
894 print "RUN of waddnstr()s:"
895 . " $winaddstr, \"$waddnstr_chars\"\n";
896 redo CLASSIFY;
897 }
898
899 # More transformations can go here
900
901 # Repeated runs of anything
902 my $anyline = &transaddr($_);
903 my $repeatcount = 1;
904 while (<$STDIN>) {
905 if ( &transaddr($_) eq $anyline ) {
906 $repeatcount++;
907 }
908 else {
909 last;
910 }
911 }
912 if ( $repeatcount > 1 ) {
913 print "${repeatcount} REPEATS OF $anyline";
914 }
915 else {
916 print $thread . $anyline;
917 }
918 redo CLASSIFY if $_;
919
920 } # :CLASSIFY
921 }
922}
923
924for my $tr ( keys %TR ) {
925 $TR{$tr} = hex $TR{$tr};
926}
927
928if ( $#ARGV >= 0 ) {
929 while ( $#ARGV >= 0 ) {
930 my $file = shift @ARGV;
931 open my $ifh, "<", $file or die $!;
932 &muncher($ifh);
933 }
934}
935else {
936 &muncher( \*STDIN );
Steve Kondikae271bc2015-11-15 02:50:53 +0100937}
938
939# tracemunch ends here