micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 1 | #!/usr/bin/env perl |
| 2 | # $Id: tracemunch,v 1.41 2021/09/04 10:31:03 tom Exp $ |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 3 | ############################################################################## |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 4 | # Copyright 2018-2020,2021 Thomas E. Dickey # |
| 5 | # Copyright 1998-2005,2017 Free Software Foundation, Inc. # |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 6 | # # |
| 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. |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 36 | |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 37 | use strict; |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 38 | use warnings; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 39 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 40 | $| = 1; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 41 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 42 | our $putattr = |
| 43 | 'PutAttrChar\(\{\{ ' . "'(.)'" |
| 44 | . ' = 0[0-7]+ \}\}\) at \(([0-9]+), ([0-9]+)\)'; |
| 45 | our $waddnstr = |
| 46 | '^called \{waddnstr\((0x[[:xdigit:]]+|window\d+),"((\\.|[^\"]*))",[-]?[0-9]+\)'; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 47 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 48 | our %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 | |
| 66 | our $tracelevel = 0; |
| 67 | |
| 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* |
| 76 | |
| 77 | our %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: |
| 92 | our %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 | |
| 509 | our $fld_nums = 0; |
| 510 | our $frm_nums = 0; |
| 511 | our $itm_nums = 0; |
| 512 | our $mnu_nums = 0; |
| 513 | our $pan_nums = 0; |
| 514 | our $scr_nums = 0; |
| 515 | our $thr_nums = 0; |
| 516 | our $trm_nums = 0; |
| 517 | our $try_nums = 0; |
| 518 | our $usr_nums = 0; |
| 519 | our $win_nums = 0; |
| 520 | |
| 521 | our $curscr = ""; |
| 522 | our $newscr = ""; |
| 523 | our $stdscr = ""; |
| 524 | |
| 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* |
| 536 | |
| 537 | sub has_addr($) { |
| 538 | my $value = shift; |
| 539 | my $result = 0; |
| 540 | $result = 1 if ( $value =~ /\b0x[[:xdigit:]]+\b/i ); |
| 541 | return $result; |
| 542 | } |
| 543 | |
| 544 | sub transaddr($) { |
| 545 | my $arg = shift; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 546 | my $n; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 547 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 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 ); |
| 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 Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 711 | } |
| 712 | |
| 713 | return $arg; |
| 714 | } |
| 715 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 716 | sub muncher($) { |
| 717 | my $STDIN = shift; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 718 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 719 | while (<$STDIN>) { |
| 720 | my $addr; |
| 721 | my $n; |
| 722 | my $awaiting = ""; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 723 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 724 | CLASSIFY: { |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 725 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 726 | next unless $_; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 727 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 728 | # just in case someone tries a file with cr/lf line-endings: |
| 729 | $_ =~ s/\r\n/\n/g; |
| 730 | $_ =~ s/\r/\n/g; |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 731 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 732 | if ( $_ =~ |
| 733 | /^TRACING NCURSES version.*\(tracelevel=(0x[[:xdigit:]]+)\)/ ) |
| 734 | { |
| 735 | $tracelevel = hex $1; |
| 736 | print; |
| 737 | next; |
| 738 | } |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 739 | |
micky387 | 9b9f5e7 | 2025-07-08 18:04:53 -0400 | [diff] [blame] | 740 | 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 | |
| 924 | for my $tr ( keys %TR ) { |
| 925 | $TR{$tr} = hex $TR{$tr}; |
| 926 | } |
| 927 | |
| 928 | if ( $#ARGV >= 0 ) { |
| 929 | while ( $#ARGV >= 0 ) { |
| 930 | my $file = shift @ARGV; |
| 931 | open my $ifh, "<", $file or die $!; |
| 932 | &muncher($ifh); |
| 933 | } |
| 934 | } |
| 935 | else { |
| 936 | &muncher( \*STDIN ); |
Steve Kondik | ae271bc | 2015-11-15 02:50:53 +0100 | [diff] [blame] | 937 | } |
| 938 | |
| 939 | # tracemunch ends here |