]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/tracemunch
ncurses 6.2 - patch 20211009
[ncurses.git] / test / tracemunch
index 2b7ad41a0224cb0496910012cd4ce7b87c2c5718..b2d3b03b216ca73e820f0e4b981a5a9b3cd5fb5f 100755 (executable)
@@ -1,7 +1,8 @@
 #!/usr/bin/env perl
-# $Id: tracemunch,v 1.18 2018/03/22 08:50:15 tom Exp $
+# $Id: tracemunch,v 1.41 2021/09/04 10:31:03 tom Exp $
 ##############################################################################
-# Copyright (c) 1998-2005,2017 Free Software Foundation, Inc.                #
+# 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"), #
 use strict;
 use warnings;
 
+$| = 1;
+
 our $putattr =
-  "PutAttrChar\\({{ '(.)' = 0[0-7]+ }}\\) at \\(([0-9]+), ([0-9]+)\\)";
+    'PutAttrChar\(\{\{ ' . "'(.)'"
+  . ' = 0[0-7]+ \}\}\) at \(([0-9]+), ([0-9]+)\)';
 our $waddnstr =
-  "waddnstr\\(0x([[:xdigit:]]+),\"([^\"]+)\",[0-9]+\\) called {A_NORMAL}";
+'^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 %scr_addr;
-our %thr_addr;
-our %try_addr;
-our %win_addr;
-
-sub transaddr {
+
+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;
-    my $arg = $_[0];
 
     $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);
-    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 %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 );
+        }
     }
-    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 %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 );
+        }
     }
-    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 %thr_addr ) {
+            $n = $thr_addr{$addr};
+            $arg =~ s/\b$addr\b/thread$n/g if ( defined $n );
+        }
     }
-    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) ) {
+        foreach my $addr ( keys %trm_addr ) {
+            $n = $trm_addr{$addr};
+            $arg =~ s/\b$addr\b/terminal$n/g if ( defined $n );
+        }
     }
-    if ( $arg =~ /add_wch\((window\d+,)?0x[[:xdigit:]]+\)/i ) {
-        $arg =~ s/(0x[[:xdigit:]]+)[)]/\&wch)/i;
+    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 );
+        }
     }
-    elsif ( $arg =~ /color_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){3}/i ) {
-        $arg =~ s/(,0x[[:xdigit:]]+){3}[)]/,\&r,\&g,\&b)/i;
+    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 );
+        }
     }
-    elsif ( $arg =~ /pair_content\((screen\d+,)?\d+(,0x[[:xdigit:]]+){2}/i ) {
-        $arg =~ s/(,0x[[:xdigit:]]+){2}[)]/,\&fg,\&bg)/i;
+    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;
 }
 
-while (<STDIN>) {
-    my $addr;
-    my $n;
-    my $awaiting = "";
+sub muncher($) {
+    my $STDIN = shift;
 
-  CLASSIFY: {
+    while (<$STDIN>) {
+        my $addr;
+        my $n;
+        my $awaiting = "";
 
-        my $thread = "";
-        if ( $_ =~ /^(0x[[:xdigit:]]+):/ ) {
-            $thr_addr{$1} = ++$thr_nums unless defined $thr_addr{$1};
-            $thread = "thread" . $thr_addr{$1} . ":";
-            $_ =~ s/^[^:]*://;
-        }
+      CLASSIFY: {
+
+            next unless $_;
 
-        # Transform window pointer addresses so it's 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;
+            # 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;
             }
-            elsif ( $awaiting eq "newscr" ) {
-                $newscr = $addr;
+
+            my $thread = "";
+            if ( $_ =~ /^(0x[[:xdigit:]]+):/ ) {
+                $thr_addr{$1} = ++$thr_nums unless defined $thr_addr{$1};
+                $thread = "thread" . $thr_addr{$1} . ":";
+                $_ =~ s/^[^:]*://;
             }
-            elsif ( $awaiting eq "stdscr" ) {
-                $stdscr = $addr;
+
+            # 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 = "";
             }
-            else {
-                $win_addr{$addr} = $win_nums++;
+            elsif ( $_ =~ /^create :(root|new)_panel 0x([[:xdigit:]]+)/ ) {
+                $addr            = "0x$2";
+                $pan_addr{$addr} = $pan_nums++;
+                $_               = &transaddr($_);
             }
-            $awaiting = "";
-        }
-        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" ) {
+            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 ( $_ =~ /^\.\.\.deleted win=0x([[:xdigit:]]+)/ ) {
-            $addr = "0x$1";
-            $_    = &transaddr($_);
-            if ( $addr eq $curscr ) {
-                $curscr = "";
+            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 ( $addr eq $newscr ) {
-                $newscr = "";
+            elsif ( $_ =~ /^\.\.\.deleted pan=\"0x([[:xdigit:]]+)\"/ ) {
+                $addr = "0x$1";
+                $_    = &transaddr($_);
+                undef $pan_addr{$addr};
             }
-            elsif ( $addr eq $stdscr ) {
-                $stdscr = "";
+            elsif ( $_ =~ /^([+ ])*called \{free_field\(0x([[:xdigit:]]+)\)/ ) {
+                $addr = "0x$2";
+                $_    = &transaddr($_);
+                undef $fld_addr{$addr};
             }
-            else {
-                undef $win_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 calls (TR_CHARPUT)
-        if ( $_ =~ /$putattr/ ) {
-            my $putattr_chars = $1;
-            my $starty        = $2;
-            my $startx        = $3;
-            while (<STDIN>) {
-                if ( $_ =~ /$putattr/ ) {
-                    $putattr_chars .= $1;
+            # 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;
+                    }
                 }
-                else {
-                    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;
             }
-            print
-"RUN of PutAttrChar()s: \"$putattr_chars\" from ${starty}, ${startx}\n";
-            redo CLASSIFY;
-        }
 
-        # Compactify runs of waddnstr calls (TR_CALLS)
-        if ( $_ =~ /$waddnstr/ ) {
-            my $waddnstr_chars = $2;
-            my $winaddr        = $1;
-            while (<STDIN>) {
-                if ( $_ =~ /$waddnstr/ && $1 eq $winaddr ) {
-                    $waddnstr_chars .= $2;
+            # More transformations can go here
+
+            # Repeated runs of anything
+            my $anyline     = &transaddr($_);
+            my $repeatcount = 1;
+            while (<$STDIN>) {
+                if ( &transaddr($_) eq $anyline ) {
+                    $repeatcount++;
                 }
                 else {
                     last;
                 }
             }
-            my $winaddstr = &transaddr($winaddr);
-            print "RUN of waddnstr()s: $winaddr, \"$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++;
+            if ( $repeatcount > 1 ) {
+                print "${repeatcount} REPEATS OF $anyline";
             }
             else {
-                last;
+                print $thread . $anyline;
             }
-        }
-        if ( $repeatcount > 1 ) {
-            print "${repeatcount} REPEATS OF $anyline";
-        }
-        else {
-            print $thread . $anyline;
-        }
-        redo CLASSIFY if $_;
+            redo CLASSIFY if $_;
 
-    }    # :CLASSIFY
+        }    # :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