mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 21:05:08 +00:00
940 lines
34 KiB
Perl
Executable file
940 lines
34 KiB
Perl
Executable file
#!/usr/bin/env perl
|
|
# $Id: tracemunch,v 1.41 2021/09/04 10:31:03 tom Exp $
|
|
##############################################################################
|
|
# Copyright 2018-2020,2021 Thomas E. Dickey #
|
|
# Copyright 1998-2005,2017 Free Software Foundation, Inc. #
|
|
# #
|
|
# Permission is hereby granted, free of charge, to any person obtaining a #
|
|
# copy of this software and associated documentation files (the "Software"), #
|
|
# to deal in the Software without restriction, including without limitation #
|
|
# the rights to use, copy, modify, merge, publish, distribute, distribute #
|
|
# with modifications, sublicense, and/or sell copies of the Software, and to #
|
|
# permit persons to whom the Software is furnished to do so, subject to the #
|
|
# following conditions: #
|
|
# #
|
|
# The above copyright notice and this permission notice shall be included in #
|
|
# all copies or substantial portions of the Software. #
|
|
# #
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL #
|
|
# THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
|
|
# DEALINGS IN THE SOFTWARE. #
|
|
# #
|
|
# Except as contained in this notice, the name(s) of the above copyright #
|
|
# holders shall not be used in advertising or otherwise to promote the sale, #
|
|
# use or other dealings in this Software without prior written #
|
|
# authorization. #
|
|
##############################################################################
|
|
# tracemunch -- compactify ncurses trace logs
|
|
#
|
|
# The error logs produced by ncurses with tracing enabled can be very tedious
|
|
# to wade through. This script helps by compacting runs of log lines that
|
|
# can be conveniently expressed as higher-level operations.
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
$| = 1;
|
|
|
|
our $putattr =
|
|
'PutAttrChar\(\{\{ ' . "'(.)'"
|
|
. ' = 0[0-7]+ \}\}\) at \(([0-9]+), ([0-9]+)\)';
|
|
our $waddnstr =
|
|
'^called \{waddnstr\((0x[[:xdigit:]]+|window\d+),"((\\.|[^\"]*))",[-]?[0-9]+\)';
|
|
|
|
our %TR = qw(
|
|
DISABLE 0x0000
|
|
TIMES 0x0001
|
|
TPUTS 0x0002
|
|
UPDATE 0x0004
|
|
MOVE 0x0008
|
|
CHARPUT 0x0010
|
|
ORDINARY 0x001F
|
|
CALLS 0x0020
|
|
VIRTPUT 0x0040
|
|
IEVENT 0x0080
|
|
BITS 0x0100
|
|
ICALLS 0x0200
|
|
CCALLS 0x0400
|
|
DATABASE 0x0800
|
|
ATTRS 0x1000
|
|
);
|
|
|
|
our $tracelevel = 0;
|
|
|
|
our $tSCREEN = 1; # SCREEN*
|
|
our $tWINDOW = 2; # WINDOW*
|
|
our $tTERMINAL = 3; # TERMINAL*
|
|
our $tPANEL = 4; # PANEL*
|
|
our $tFIELD = 5; # FIELD*
|
|
our $tFORM = 5; # FORM*
|
|
our $tMENU = 6; # MENU*
|
|
our $tITEM = 7; # ITEM*
|
|
|
|
our %known_p1_types = (
|
|
$tSCREEN => "SCREEN*",
|
|
$tWINDOW => "WINDOW*",
|
|
$tTERMINAL => "TERMINAL*",
|
|
$tPANEL => "PANEL*",
|
|
$tFORM => "FORM*",
|
|
$tFIELD => "FIELD*",
|
|
$tMENU => "MENU*",
|
|
$tITEM => "ITEM*",
|
|
);
|
|
|
|
# If the trace is complete, we can infer addresses using the return value from
|
|
# newwin, etc. But if it is incomplete, we can still check for special cases
|
|
# such as SCREEN* and WINDOW* parameters. In this table, the type for the
|
|
# first parameter is encoded, relying upon an ncurses programming convention:
|
|
our %known_p1 = (
|
|
TransformLine => $tSCREEN,
|
|
_nc_console_read => $tSCREEN,
|
|
_nc_freewin => $tWINDOW,
|
|
_nc_initscr => $tSCREEN,
|
|
_nc_makenew => $tSCREEN,
|
|
_nc_mingw_console_read => $tSCREEN,
|
|
_nc_reset_colors => $tSCREEN,
|
|
_nc_scroll_optimize => $tSCREEN,
|
|
_nc_tinfo => $tSCREEN,
|
|
_nc_tinfo_mvcur => $tSCREEN,
|
|
_nc_wgetch => $tWINDOW,
|
|
adjust_window => $tWINDOW,
|
|
assume_default_colors => $tSCREEN,
|
|
attr_get => $tWINDOW,
|
|
baudrate => $tSCREEN,
|
|
beep => $tSCREEN,
|
|
border_set => $tWINDOW,
|
|
bottom_panel => $tPANEL,
|
|
bottom_panel => $tPANEL,
|
|
box => $tWINDOW,
|
|
box_set => $tWINDOW,
|
|
can_change_color => $tSCREEN,
|
|
cbreak => $tSCREEN,
|
|
ceiling_panel => $tSCREEN,
|
|
clearok => $tWINDOW,
|
|
color_content => $tSCREEN,
|
|
copywin => $tWINDOW,
|
|
current_item => $tMENU,
|
|
curs_set => $tSCREEN,
|
|
decrease_size => $tSCREEN,
|
|
def_prog_mode => $tSCREEN,
|
|
def_shell_mode => $tSCREEN,
|
|
define_key => $tSCREEN,
|
|
del_curterm => $tSCREEN,
|
|
del_panel => $tPANEL,
|
|
del_panel => $tPANEL,
|
|
delay_output => $tSCREEN,
|
|
delscreen => $tSCREEN,
|
|
delwin => $tWINDOW,
|
|
derwin => $tWINDOW,
|
|
doupdate => $tSCREEN,
|
|
dup_field => $tFIELD,
|
|
dupwin => $tWINDOW,
|
|
echo => $tSCREEN,
|
|
endwin => $tSCREEN,
|
|
erasechar => $tSCREEN,
|
|
field_opts_off => $tFIELD,
|
|
field_opts_on => $tFIELD,
|
|
filter => $tSCREEN,
|
|
flash => $tSCREEN,
|
|
flushinp => $tSCREEN,
|
|
form_driver => $tFORM,
|
|
form_driver_w => $tFORM,
|
|
form_opts_off => $tFORM,
|
|
form_opts_on => $tFORM,
|
|
free_field => $tFIELD,
|
|
free_form => $tFORM,
|
|
free_item => $tITEM,
|
|
free_menu => $tMENU,
|
|
getattrs => $tWINDOW,
|
|
getbegx => $tWINDOW,
|
|
getbegy => $tWINDOW,
|
|
getbkgd => $tWINDOW,
|
|
getcurx => $tWINDOW,
|
|
getcury => $tWINDOW,
|
|
getmaxx => $tWINDOW,
|
|
getmaxy => $tWINDOW,
|
|
getmouse => $tSCREEN,
|
|
getparx => $tWINDOW,
|
|
getpary => $tWINDOW,
|
|
ground_panel => $tSCREEN,
|
|
halfdelay => $tSCREEN,
|
|
has_ic => $tSCREEN,
|
|
has_il => $tSCREEN,
|
|
has_key => $tSCREEN,
|
|
hide_panel => $tPANEL,
|
|
hide_panel => $tPANEL,
|
|
idcok => $tWINDOW,
|
|
idlok => $tWINDOW,
|
|
immedok => $tWINDOW,
|
|
increase_size => $tSCREEN,
|
|
init_color => $tSCREEN,
|
|
init_pair => $tSCREEN,
|
|
intrflush => $tSCREEN,
|
|
is_cleared => $tWINDOW,
|
|
is_idcok => $tWINDOW,
|
|
is_idlok => $tWINDOW,
|
|
is_immedok => $tWINDOW,
|
|
is_keypad => $tWINDOW,
|
|
is_leaveok => $tWINDOW,
|
|
is_linetouched => $tWINDOW,
|
|
is_nodelay => $tWINDOW,
|
|
is_notimeout => $tWINDOW,
|
|
is_pad => $tWINDOW,
|
|
is_scrollok => $tWINDOW,
|
|
is_subwin => $tWINDOW,
|
|
is_syncok => $tWINDOW,
|
|
is_term_resized => $tSCREEN,
|
|
is_wintouched => $tWINDOW,
|
|
item_count => $tMENU,
|
|
item_description => $tITEM,
|
|
item_index => $tITEM,
|
|
item_init => $tMENU,
|
|
item_name => $tITEM,
|
|
item_opts => $tITEM,
|
|
item_opts_off => $tITEM,
|
|
item_opts_on => $tITEM,
|
|
item_term => $tMENU,
|
|
item_userptr => $tITEM,
|
|
item_value => $tITEM,
|
|
item_visible => $tITEM,
|
|
key_defined => $tSCREEN,
|
|
keybound => $tSCREEN,
|
|
keyok => $tSCREEN,
|
|
keypad => $tWINDOW,
|
|
killchar => $tSCREEN,
|
|
leaveok => $tWINDOW,
|
|
link_field => $tFIELD,
|
|
longname => $tSCREEN,
|
|
menu_back => $tMENU,
|
|
menu_driver => $tMENU,
|
|
menu_fore => $tMENU,
|
|
menu_format => $tMENU,
|
|
menu_grey => $tMENU,
|
|
menu_init => $tMENU,
|
|
menu_items => $tMENU,
|
|
menu_mark => $tMENU,
|
|
menu_opts => $tMENU,
|
|
menu_opts_off => $tMENU,
|
|
menu_opts_on => $tMENU,
|
|
menu_pad => $tMENU,
|
|
menu_pattern => $tMENU,
|
|
menu_spacing => $tMENU,
|
|
menu_sub => $tMENU,
|
|
menu_term => $tMENU,
|
|
menu_userptr => $tMENU,
|
|
menu_win => $tMENU,
|
|
meta => $tWINDOW,
|
|
mouseinterval => $tSCREEN,
|
|
mousemask => $tSCREEN,
|
|
move_field => $tFIELD,
|
|
move_panel => $tPANEL,
|
|
move_panel => $tPANEL,
|
|
mvcur => $tSCREEN,
|
|
mvderwin => $tWINDOW,
|
|
mvwadd_wch => $tWINDOW,
|
|
mvwadd_wchnstr => $tWINDOW,
|
|
mvwadd_wchstr => $tWINDOW,
|
|
mvwaddch => $tWINDOW,
|
|
mvwaddchnstr => $tWINDOW,
|
|
mvwaddchstr => $tWINDOW,
|
|
mvwaddnstr => $tWINDOW,
|
|
mvwaddnwstr => $tWINDOW,
|
|
mvwaddstr => $tWINDOW,
|
|
mvwaddwstr => $tWINDOW,
|
|
mvwchgat => $tWINDOW,
|
|
mvwdelch => $tWINDOW,
|
|
mvwget_wch => $tWINDOW,
|
|
mvwget_wstr => $tWINDOW,
|
|
mvwgetch => $tWINDOW,
|
|
mvwgetn_wstr => $tWINDOW,
|
|
mvwgetnstr => $tWINDOW,
|
|
mvwgetstr => $tWINDOW,
|
|
mvwhline => $tWINDOW,
|
|
mvwhline_set => $tWINDOW,
|
|
mvwin => $tWINDOW,
|
|
mvwin_wch => $tWINDOW,
|
|
mvwin_wchnstr => $tWINDOW,
|
|
mvwin_wchstr => $tWINDOW,
|
|
mvwinch => $tWINDOW,
|
|
mvwinchnstr => $tWINDOW,
|
|
mvwinchstr => $tWINDOW,
|
|
mvwins_nwstr => $tWINDOW,
|
|
mvwins_wch => $tWINDOW,
|
|
mvwins_wstr => $tWINDOW,
|
|
mvwinsch => $tWINDOW,
|
|
mvwinsnstr => $tWINDOW,
|
|
mvwinsstr => $tWINDOW,
|
|
mvwinstr => $tWINDOW,
|
|
mvwinwstr => $tWINDOW,
|
|
mvwvline => $tWINDOW,
|
|
mvwvline_set => $tWINDOW,
|
|
new_panel => $tWINDOW,
|
|
new_panel => $tWINDOW,
|
|
newpad => $tSCREEN,
|
|
newterm => $tSCREEN,
|
|
newwin => $tSCREEN,
|
|
nl => $tSCREEN,
|
|
nocbreak => $tSCREEN,
|
|
nodelay => $tWINDOW,
|
|
noecho => $tSCREEN,
|
|
nofilter => $tSCREEN,
|
|
nonl => $tSCREEN,
|
|
noqiflush => $tSCREEN,
|
|
noraw => $tSCREEN,
|
|
notimeout => $tWINDOW,
|
|
overlap => $tWINDOW,
|
|
overlay => $tWINDOW,
|
|
overwrite => $tWINDOW,
|
|
pair_content => $tSCREEN,
|
|
panel_above => $tPANEL,
|
|
panel_above => $tPANEL,
|
|
panel_below => $tPANEL,
|
|
panel_below => $tPANEL,
|
|
panel_hidden => $tPANEL,
|
|
panel_hidden => $tPANEL,
|
|
panel_userptr => $tPANEL,
|
|
panel_userptr => $tPANEL,
|
|
panel_window => $tPANEL,
|
|
panel_window => $tPANEL,
|
|
pecho_wchar => $tWINDOW,
|
|
pechochar => $tWINDOW,
|
|
pnoutrefresh => $tWINDOW,
|
|
pos_form_cursor => $tFORM,
|
|
pos_menu_cursor => $tMENU,
|
|
post_form => $tFORM,
|
|
post_menu => $tMENU,
|
|
putwin => $tWINDOW,
|
|
qiflush => $tSCREEN,
|
|
raw => $tSCREEN,
|
|
redrawwin => $tWINDOW,
|
|
replace_panel => $tPANEL,
|
|
replace_panel => $tPANEL,
|
|
reset_prog_mode => $tSCREEN,
|
|
reset_shell_mode => $tSCREEN,
|
|
resetty => $tSCREEN,
|
|
resize_term => $tSCREEN,
|
|
resizeterm => $tSCREEN,
|
|
restartterm => $tSCREEN,
|
|
ripoffline => $tSCREEN,
|
|
savetty => $tSCREEN,
|
|
scale_menu => $tMENU,
|
|
scr_init => $tSCREEN,
|
|
scr_restore => $tSCREEN,
|
|
scr_set => $tSCREEN,
|
|
scroll => $tWINDOW,
|
|
scrollok => $tWINDOW,
|
|
set_current_field => $tFORM,
|
|
set_current_item => $tMENU,
|
|
set_curterm => $tTERMINAL,
|
|
set_field_back => $tFIELD,
|
|
set_field_buffer => $tFIELD,
|
|
set_field_fore => $tFIELD,
|
|
set_field_init => $tFORM,
|
|
set_field_just => $tFIELD,
|
|
set_field_opts => $tFIELD,
|
|
set_field_pad => $tFIELD,
|
|
set_field_status => $tFIELD,
|
|
set_field_term => $tFORM,
|
|
set_field_type => $tFIELD,
|
|
set_field_userptr => $tFIELD,
|
|
set_form_fields => $tFORM,
|
|
set_form_init => $tFORM,
|
|
set_form_opts => $tFORM,
|
|
set_form_page => $tFORM,
|
|
set_form_sub => $tFORM,
|
|
set_form_term => $tFORM,
|
|
set_form_userptr => $tFORM,
|
|
set_form_win => $tFORM,
|
|
set_item_init => $tMENU,
|
|
set_item_opts => $tITEM,
|
|
set_item_term => $tMENU,
|
|
set_item_userptr => $tITEM,
|
|
set_item_value => $tITEM,
|
|
set_menu_back => $tMENU,
|
|
set_menu_fore => $tMENU,
|
|
set_menu_format => $tMENU,
|
|
set_menu_grey => $tMENU,
|
|
set_menu_init => $tMENU,
|
|
set_menu_items => $tMENU,
|
|
set_menu_mark => $tMENU,
|
|
set_menu_opts => $tMENU,
|
|
set_menu_pad => $tMENU,
|
|
set_menu_pattern => $tMENU,
|
|
set_menu_spacing => $tMENU,
|
|
set_menu_sub => $tMENU,
|
|
set_menu_term => $tMENU,
|
|
set_menu_userptr => $tMENU,
|
|
set_menu_win => $tMENU,
|
|
set_new_page => $tFIELD,
|
|
set_panel_userptr => $tPANEL,
|
|
set_panel_userptr => $tPANEL,
|
|
set_term => $tSCREEN,
|
|
set_top_row => $tMENU,
|
|
show_panel => $tPANEL,
|
|
show_panel => $tPANEL,
|
|
slk_attr => $tSCREEN,
|
|
slk_attr_set => $tSCREEN,
|
|
slk_attroff => $tSCREEN,
|
|
slk_attron => $tSCREEN,
|
|
slk_attrset => $tSCREEN,
|
|
slk_clear => $tSCREEN,
|
|
slk_color => $tSCREEN,
|
|
slk_init => $tSCREEN,
|
|
slk_label => $tSCREEN,
|
|
slk_noutrefresh => $tSCREEN,
|
|
slk_refresh => $tSCREEN,
|
|
slk_restore => $tSCREEN,
|
|
slk_set => $tSCREEN,
|
|
slk_touch => $tSCREEN,
|
|
start_color => $tSCREEN,
|
|
subwin => $tWINDOW,
|
|
syncok => $tWINDOW,
|
|
termattrs => $tSCREEN,
|
|
termname => $tSCREEN,
|
|
tgetflag => $tSCREEN,
|
|
tgetnum => $tSCREEN,
|
|
tigetflag => $tSCREEN,
|
|
tigetnum => $tSCREEN,
|
|
tigetstr => $tSCREEN,
|
|
tinfo => $tSCREEN,
|
|
top_panel => $tPANEL,
|
|
top_panel => $tPANEL,
|
|
top_row => $tMENU,
|
|
touchline => $tWINDOW,
|
|
touchwin => $tWINDOW,
|
|
typeahead => $tSCREEN,
|
|
unfocus_current_field => $tFORM,
|
|
unget_wch => $tSCREEN,
|
|
ungetch => $tSCREEN,
|
|
ungetmouse => $tSCREEN,
|
|
unpost_form => $tFORM,
|
|
unpost_menu => $tMENU,
|
|
untouchwin => $tWINDOW,
|
|
update_panels_sp => $tSCREEN,
|
|
use_default_colors => $tSCREEN,
|
|
use_env => $tSCREEN,
|
|
use_legacy_coding => $tSCREEN,
|
|
use_screen => $tSCREEN,
|
|
use_tioctl => $tSCREEN,
|
|
use_window => $tWINDOW,
|
|
vidattr => $tSCREEN,
|
|
vidputs => $tSCREEN,
|
|
vw_printw => $tWINDOW,
|
|
vwprintw => $tWINDOW,
|
|
wadd_wch => $tWINDOW,
|
|
wadd_wchnstr => $tWINDOW,
|
|
wadd_wchstr => $tWINDOW,
|
|
waddch => $tWINDOW,
|
|
waddchnstr => $tWINDOW,
|
|
waddchstr => $tWINDOW,
|
|
waddnstr => $tWINDOW,
|
|
waddnwstr => $tWINDOW,
|
|
waddstr => $tWINDOW,
|
|
waddwstr => $tWINDOW,
|
|
wattr_get => $tWINDOW,
|
|
wattr_off => $tWINDOW,
|
|
wattr_on => $tWINDOW,
|
|
wattr_set => $tWINDOW,
|
|
wattroff => $tWINDOW,
|
|
wattron => $tWINDOW,
|
|
wattrset => $tWINDOW,
|
|
wbkgd => $tWINDOW,
|
|
wbkgdset => $tWINDOW,
|
|
wborder => $tWINDOW,
|
|
wborder_set => $tWINDOW,
|
|
wchgat => $tWINDOW,
|
|
wclear => $tWINDOW,
|
|
wclrtobot => $tWINDOW,
|
|
wclrtoeol => $tWINDOW,
|
|
wcolor_set => $tWINDOW,
|
|
wcursyncup => $tWINDOW,
|
|
wdelch => $tWINDOW,
|
|
wdeleteln => $tWINDOW,
|
|
wechochar => $tWINDOW,
|
|
wenclose => $tWINDOW,
|
|
werase => $tWINDOW,
|
|
wget_wch => $tWINDOW,
|
|
wget_wstr => $tWINDOW,
|
|
wgetbkgrnd => $tWINDOW,
|
|
wgetch => $tWINDOW,
|
|
wgetch_events => $tWINDOW,
|
|
wgetdelay => $tWINDOW,
|
|
wgetn_wstr => $tWINDOW,
|
|
wgetnstr => $tWINDOW,
|
|
wgetparent => $tWINDOW,
|
|
wgetscrreg => $tWINDOW,
|
|
wgetstr => $tWINDOW,
|
|
whline => $tWINDOW,
|
|
whline_set => $tWINDOW,
|
|
win_wch => $tWINDOW,
|
|
win_wchnstr => $tWINDOW,
|
|
win_wchstr => $tWINDOW,
|
|
winch => $tWINDOW,
|
|
winchnstr => $tWINDOW,
|
|
winchstr => $tWINDOW,
|
|
winnstr => $tWINDOW,
|
|
winnwstr => $tWINDOW,
|
|
wins_nwstr => $tWINDOW,
|
|
wins_wch => $tWINDOW,
|
|
wins_wstr => $tWINDOW,
|
|
winsch => $tWINDOW,
|
|
winsdelln => $tWINDOW,
|
|
winsertln => $tWINDOW,
|
|
winsnstr => $tWINDOW,
|
|
winsstr => $tWINDOW,
|
|
winstr => $tWINDOW,
|
|
winwstr => $tWINDOW,
|
|
wmouse_trafo => $tWINDOW,
|
|
wmove => $tWINDOW,
|
|
wnoutrefresh => $tWINDOW,
|
|
wprintw => $tWINDOW,
|
|
wredrawln => $tWINDOW,
|
|
wrefresh => $tWINDOW,
|
|
wresize => $tWINDOW,
|
|
wscrl => $tWINDOW,
|
|
wsetscrreg => $tWINDOW,
|
|
wstandend => $tWINDOW,
|
|
wstandout => $tWINDOW,
|
|
wsyncdown => $tWINDOW,
|
|
wsyncup => $tWINDOW,
|
|
wtimeout => $tWINDOW,
|
|
wtouchln => $tWINDOW,
|
|
wvline => $tWINDOW,
|
|
);
|
|
|
|
our $fld_nums = 0;
|
|
our $frm_nums = 0;
|
|
our $itm_nums = 0;
|
|
our $mnu_nums = 0;
|
|
our $pan_nums = 0;
|
|
our $scr_nums = 0;
|
|
our $thr_nums = 0;
|
|
our $trm_nums = 0;
|
|
our $try_nums = 0;
|
|
our $usr_nums = 0;
|
|
our $win_nums = 0;
|
|
|
|
our $curscr = "";
|
|
our $newscr = "";
|
|
our $stdscr = "";
|
|
|
|
our %fld_addr; # FIELD*
|
|
our %frm_addr; # FORM*
|
|
our %itm_addr; # ITEM*
|
|
our %mnu_addr; # MENU*
|
|
our %pan_addr; # PANEL*
|
|
our %scr_addr; # SCREEN*
|
|
our %thr_addr; # thread-id
|
|
our %trm_addr; # TERMINAL*
|
|
our %try_addr; # tries-number
|
|
our %usr_addr; # user-pointer
|
|
our %win_addr; # WINDOW*
|
|
|
|
sub has_addr($) {
|
|
my $value = shift;
|
|
my $result = 0;
|
|
$result = 1 if ( $value =~ /\b0x[[:xdigit:]]+\b/i );
|
|
return $result;
|
|
}
|
|
|
|
sub transaddr($) {
|
|
my $arg = shift;
|
|
my $n;
|
|
|
|
$arg =~ s/\b$curscr\b/curscr/g if ($curscr);
|
|
$arg =~ s/\b$newscr\b/newscr/g if ($newscr);
|
|
$arg =~ s/\b$stdscr\b/stdscr/g if ($stdscr);
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %fld_addr ) {
|
|
$n = $fld_addr{$addr};
|
|
$arg =~ s/\b$addr\b/field$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %frm_addr ) {
|
|
$n = $frm_addr{$addr};
|
|
$arg =~ s/\b$addr\b/form$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %itm_addr ) {
|
|
$n = $itm_addr{$addr};
|
|
$arg =~ s/\b$addr\b/item$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %mnu_addr ) {
|
|
$n = $mnu_addr{$addr};
|
|
$arg =~ s/\b$addr\b/menu$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %pan_addr ) {
|
|
$n = $pan_addr{$addr};
|
|
$arg =~ s/\b$addr\b/panel$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %scr_addr ) {
|
|
$n = $scr_addr{$addr};
|
|
$arg =~ s/\b$addr\b/screen$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %thr_addr ) {
|
|
$n = $thr_addr{$addr};
|
|
$arg =~ s/\b$addr\b/thread$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %trm_addr ) {
|
|
$n = $trm_addr{$addr};
|
|
$arg =~ s/\b$addr\b/terminal$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %try_addr ) {
|
|
$n = $try_addr{$addr};
|
|
$arg =~ s/\b$addr\b/tries_$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %usr_addr ) {
|
|
$n = $usr_addr{$addr};
|
|
$arg =~ s/\b$addr\b/user_ptr$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
foreach my $addr ( keys %win_addr ) {
|
|
$n = $win_addr{$addr};
|
|
$arg =~ s/\b$addr\b/window$n/g if ( defined $n );
|
|
}
|
|
}
|
|
if ( &has_addr($arg) ) {
|
|
if ( $arg =~ /add_wch\((window\d+,)?0x[[:xdigit:]]+\)/i ) {
|
|
$arg =~ s/(0x[[:xdigit:]]+)[)]/\&wch)/i;
|
|
}
|
|
elsif (
|
|
$arg =~ /color_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){3}/i )
|
|
{
|
|
$arg =~ s/(,0x[[:xdigit:]]+){3}[)]/,\&r,\&g,\&b)/i;
|
|
}
|
|
elsif ( $arg =~ /pair_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){2}/i )
|
|
{
|
|
$arg =~ s/(,0x[[:xdigit:]]+){2}[)]/,\&fg,\&bg)/i;
|
|
}
|
|
}
|
|
if ( &has_addr($arg) and $arg =~ /called\s+\{/ ) {
|
|
my $func = $arg;
|
|
chomp $func;
|
|
$func =~ s/^.*called\s+\{([[:alnum:]_]+)\(.*$/$1/;
|
|
if ( defined $known_p1{$func} ) {
|
|
my $addr = $arg;
|
|
my $type = $known_p1{$func};
|
|
chomp $addr;
|
|
$addr =~ s/^[^(]+\((0x[[:xdigit:]]+).*$/$1/i;
|
|
if ( $addr !~ /^0x[[:xdigit:]]+$/i ) {
|
|
if ( $type == $tSCREEN and $addr =~ /^[^(]+\(screen\d+[,)]/ ) {
|
|
|
|
# ignore
|
|
}
|
|
elsif ( $type == $tWINDOW
|
|
and $addr =~
|
|
/^[^(]+\((stdscr|newscr|curscr|window\d+)[,)]/ )
|
|
{
|
|
|
|
# ignore
|
|
}
|
|
elsif ( $type == $tTERMINAL
|
|
and $addr =~ /^[^(]+\(terminal\d+[,)]/ )
|
|
{
|
|
# ignore
|
|
}
|
|
elsif ( $type == $tPANEL and $addr =~ /^[^(]+\(panel\d+[,)]/ ) {
|
|
|
|
# ignore
|
|
}
|
|
elsif ( $type == $tFIELD and $addr =~ /^[^(]+\(field\d+[,)]/ ) {
|
|
|
|
# ignore
|
|
}
|
|
elsif ( $type == $tMENU and $addr =~ /^[^(]+\(menu\d+[,)]/ ) {
|
|
|
|
# ignore
|
|
}
|
|
elsif ( $type == $tITEM and $addr =~ /^[^(]+\(item\d+[,)]/ ) {
|
|
|
|
# ignore
|
|
}
|
|
else {
|
|
printf "OOPS - expected type \"%s\", skipping\n>>$addr\n",
|
|
$known_p1_types{$type};
|
|
}
|
|
}
|
|
elsif ( $type == $tSCREEN ) {
|
|
$scr_addr{$addr} = ++$scr_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tWINDOW ) {
|
|
$win_addr{$addr} = ++$win_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tTERMINAL ) {
|
|
$trm_addr{$addr} = ++$trm_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tPANEL ) {
|
|
$pan_addr{$addr} = ++$pan_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tFIELD ) {
|
|
$fld_addr{$addr} = ++$fld_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tFORM ) {
|
|
$frm_addr{$addr} = ++$frm_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tMENU ) {
|
|
$mnu_addr{$addr} = ++$mnu_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
elsif ( $type == $tITEM ) {
|
|
$itm_addr{$addr} = ++$itm_nums;
|
|
$arg = &transaddr($arg);
|
|
}
|
|
}
|
|
}
|
|
|
|
return $arg;
|
|
}
|
|
|
|
sub muncher($) {
|
|
my $STDIN = shift;
|
|
|
|
while (<$STDIN>) {
|
|
my $addr;
|
|
my $n;
|
|
my $awaiting = "";
|
|
|
|
CLASSIFY: {
|
|
|
|
next unless $_;
|
|
|
|
# just in case someone tries a file with cr/lf line-endings:
|
|
$_ =~ s/\r\n/\n/g;
|
|
$_ =~ s/\r/\n/g;
|
|
|
|
if ( $_ =~
|
|
/^TRACING NCURSES version.*\(tracelevel=(0x[[:xdigit:]]+)\)/ )
|
|
{
|
|
$tracelevel = hex $1;
|
|
print;
|
|
next;
|
|
}
|
|
|
|
my $thread = "";
|
|
if ( $_ =~ /^(0x[[:xdigit:]]+):/ ) {
|
|
$thr_addr{$1} = ++$thr_nums unless defined $thr_addr{$1};
|
|
$thread = "thread" . $thr_addr{$1} . ":";
|
|
$_ =~ s/^[^:]*://;
|
|
}
|
|
|
|
# Transform window pointer addresses to make it easier to compare logs
|
|
$awaiting = "curscr" if ( $_ =~ /creating curscr/ );
|
|
$awaiting = "newscr" if ( $_ =~ /creating newscr/ );
|
|
$awaiting = "stdscr" if ( $_ =~ /creating stdscr/ );
|
|
$awaiting = "screen" if ( $_ =~ /^(\+ )*called \{new_prescr\(\)/ );
|
|
if ( $_ =~ /^create :window 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
if ( $awaiting eq "curscr" ) {
|
|
$curscr = $addr;
|
|
}
|
|
elsif ( $awaiting eq "newscr" ) {
|
|
$newscr = $addr;
|
|
}
|
|
elsif ( $awaiting eq "stdscr" ) {
|
|
$stdscr = $addr;
|
|
}
|
|
else {
|
|
$win_addr{$addr} = $win_nums++;
|
|
}
|
|
$awaiting = "";
|
|
}
|
|
elsif ( $_ =~ /^create :(root|new)_panel 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$2";
|
|
$pan_addr{$addr} = $pan_nums++;
|
|
$_ = &transaddr($_);
|
|
}
|
|
elsif ( $_ =~ /^create :user_ptr 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
$usr_addr{$addr} = $usr_nums++;
|
|
$_ = &transaddr($_);
|
|
}
|
|
elsif ( $_ =~ /^create :field 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
$fld_addr{$addr} = $fld_nums++;
|
|
$_ = &transaddr($_);
|
|
}
|
|
elsif ( $_ =~ /^create :form 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
$frm_addr{$addr} = $frm_nums++;
|
|
$_ = &transaddr($_);
|
|
}
|
|
elsif ( $_ =~ /^create :menu 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
$mnu_addr{$addr} = $mnu_nums++;
|
|
$_ = &transaddr($_);
|
|
}
|
|
elsif ( $_ =~ /^create :item 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
$itm_addr{$addr} = $itm_nums++;
|
|
$_ = &transaddr($_);
|
|
}
|
|
elsif ( $_ =~ /^(\+ )*called \{set_curterm\((0x[[:xdigit:]]+)\)/ ) {
|
|
$trm_addr{$2} = ++$trm_nums unless defined $trm_addr{$2};
|
|
}
|
|
elsif ( $_ =~ /^(\+ )*called \{_nc_add_to_try\((0x[[:xdigit:]]+),/ )
|
|
{
|
|
$try_addr{$2} = ++$try_nums unless defined $try_addr{$2};
|
|
}
|
|
elsif ( $_ =~ /^(\+ )*_nc_alloc_screen_sp 0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$2";
|
|
$scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
|
|
$awaiting = "";
|
|
}
|
|
elsif ( $_ =~ /^(\+ )*return }0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$2";
|
|
if ( $awaiting eq "screen" ) {
|
|
$scr_addr{$addr} = ++$scr_nums unless ( $scr_addr{$addr} );
|
|
}
|
|
}
|
|
elsif ( $_ =~ /^\.\.\.deleted win=0x([[:xdigit:]]+)/ ) {
|
|
$addr = "0x$1";
|
|
$_ = &transaddr($_);
|
|
if ( $addr eq $curscr ) {
|
|
$curscr = "";
|
|
}
|
|
elsif ( $addr eq $newscr ) {
|
|
$newscr = "";
|
|
}
|
|
elsif ( $addr eq $stdscr ) {
|
|
$stdscr = "";
|
|
}
|
|
else {
|
|
undef $win_addr{$addr};
|
|
}
|
|
}
|
|
elsif ( $_ =~ /^\.\.\.deleted pan=\"0x([[:xdigit:]]+)\"/ ) {
|
|
$addr = "0x$1";
|
|
$_ = &transaddr($_);
|
|
undef $pan_addr{$addr};
|
|
}
|
|
elsif ( $_ =~ /^([+ ])*called \{free_field\(0x([[:xdigit:]]+)\)/ ) {
|
|
$addr = "0x$2";
|
|
$_ = &transaddr($_);
|
|
undef $fld_addr{$addr};
|
|
}
|
|
elsif ( $_ =~ /^([+ ])*called \{free_form\(0x([[:xdigit:]]+)\)/ ) {
|
|
$addr = "0x$2";
|
|
$_ = &transaddr($_);
|
|
undef $frm_addr{$addr};
|
|
}
|
|
elsif ( $_ =~ /^([+ ])*called \{free_menu\(0x([[:xdigit:]]+)\)/ ) {
|
|
$addr = "0x$2";
|
|
$_ = &transaddr($_);
|
|
undef $mnu_addr{$addr};
|
|
}
|
|
elsif ( $_ =~ /^([+ ])*called \{free_item\(0x([[:xdigit:]]+)\)/ ) {
|
|
$addr = "0x$2";
|
|
$_ = &transaddr($_);
|
|
undef $itm_addr{$addr};
|
|
}
|
|
|
|
# Compactify runs of PutAttrChar
|
|
if ( ( ( $tracelevel & $TR{CHARPUT} ) != 0 ) and $_ =~ /$putattr/ )
|
|
{
|
|
my $putattr_chars = $1;
|
|
my $starty = $2;
|
|
my $startx = $3;
|
|
while (<$STDIN>) {
|
|
if ( $_ =~ /$putattr/ ) {
|
|
$putattr_chars .= $1;
|
|
}
|
|
else {
|
|
next if ( $_ =~ /^PUTC 0x[[:xdigit:]]+.*/ );
|
|
next if ( $_ =~ /^\.\.\.skip.*/ );
|
|
next if ( $_ =~ /^forced to blank.*/ );
|
|
last;
|
|
}
|
|
}
|
|
print "RUN of PutAttrChar()s:"
|
|
. " \"$putattr_chars\" from ${starty}, ${startx}\n";
|
|
redo CLASSIFY;
|
|
}
|
|
|
|
# Compactify runs of waddnstr calls
|
|
if ( ( ( $tracelevel & $TR{CALLS} ) != 0 ) and $_ =~ /$waddnstr/ ) {
|
|
my $waddnstr_chars = $2;
|
|
my $winaddr = $1;
|
|
while (<$STDIN>) {
|
|
next if ( $_ =~ /^return \}0/ );
|
|
if ( $_ =~ /$waddnstr/ && $1 eq $winaddr ) {
|
|
$waddnstr_chars .= $2;
|
|
}
|
|
else {
|
|
last;
|
|
}
|
|
}
|
|
my $winaddstr = &transaddr($winaddr);
|
|
print "RUN of waddnstr()s:"
|
|
. " $winaddstr, \"$waddnstr_chars\"\n";
|
|
redo CLASSIFY;
|
|
}
|
|
|
|
# More transformations can go here
|
|
|
|
# Repeated runs of anything
|
|
my $anyline = &transaddr($_);
|
|
my $repeatcount = 1;
|
|
while (<$STDIN>) {
|
|
if ( &transaddr($_) eq $anyline ) {
|
|
$repeatcount++;
|
|
}
|
|
else {
|
|
last;
|
|
}
|
|
}
|
|
if ( $repeatcount > 1 ) {
|
|
print "${repeatcount} REPEATS OF $anyline";
|
|
}
|
|
else {
|
|
print $thread . $anyline;
|
|
}
|
|
redo CLASSIFY if $_;
|
|
|
|
} # :CLASSIFY
|
|
}
|
|
}
|
|
|
|
for my $tr ( keys %TR ) {
|
|
$TR{$tr} = hex $TR{$tr};
|
|
}
|
|
|
|
if ( $#ARGV >= 0 ) {
|
|
while ( $#ARGV >= 0 ) {
|
|
my $file = shift @ARGV;
|
|
open my $ifh, "<", $file or die $!;
|
|
&muncher($ifh);
|
|
}
|
|
}
|
|
else {
|
|
&muncher( \*STDIN );
|
|
}
|
|
|
|
# tracemunch ends here
|