home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / p2demo21.exe / PEL / DEBUG.PEL < prev    next >
Text File  |  1995-04-04  |  57KB  |  2,048 lines

  1. # $Header:   P:\source\wmacros\debug.pev   1.47   04 Apr 1995 18:06:32   PFHDWM0  $
  2.  
  3. ##############################################################################
  4. #
  5. #       Compuware Corporation
  6. #         31440 Northwestern Highway
  7. #           Farmington Hills, Michigan 48334-2564
  8. #
  9. #   This source code listing contains information that is
  10. #   proprietary to Compuware Corporation and may not be copied
  11. #   duplicated, translated, transmitted, stored, retrieved
  12. #   or in any manner or by any method conveyed or disclosed
  13. #   to a third party or parties without express written
  14. #   permission from Compuware Corporation.
  15. #
  16. #  
  17. ##############################################################################
  18.  
  19.  
  20. #### $Workfile:   debug.pel  $: sageedit debugger entry points
  21. #
  22.  
  23. global dhDebug
  24.  
  25. global original_keymap           
  26. local main_window          
  27. local main_buffer          
  28.            
  29. local debug_text_fg           = COLOR_NEON_BABY_BLUE
  30. local debug_text_bg           = COLOR_BLACK
  31. local debug_line_fg           = COLOR_RED
  32. local debug_line_bg           = COLOR_BLACK
  33. #local debug_color_text        = COLOR_NEON_BABY_BLUE
  34. local debug_color_highlight   = COLOR_YELLOW
  35.  
  36. global debug_flip = 1;
  37. local debug_remote_window
  38. local debug_window;
  39. local debug_empty_name = "Debug Window: no function active"
  40. local debug_keymap;
  41. local debug_buffer;
  42. local debug_filename = "";
  43. local debug_enabled             # True if debug has been called
  44. local original_window;          # Saved when function is debugged.
  45. local original_buffer;
  46. local debug_id;
  47. local debug_tabs = default_buffer_tabs;
  48. local debug_view_file = "???"
  49. local debug_num_steps = 0;
  50.  
  51. local IDM_FIRST_ITEM           = 0x200
  52. local IDM_DEBUG_FILE_OPEN      = 0x200
  53. local IDM_DEBUG_FILE_EXIT      = 0x201
  54. local IDM_DEBUG_FILE           = 0x202
  55. local IDM_DEBUG_BP_LIST        = 0x203
  56. local IDM_DEBUG_BP_SETCLR      = 0x204
  57. local IDM_DEBUG_BP_CLRALL      = 0x205
  58. local IDM_DEBUG_BP             = 0x206
  59. local IDM_DEBUG_VIEW_CALLSTACK = 0x207
  60. local IDM_DEBUG_VIEW_LOCALS    = 0x208
  61. local IDM_DEBUG_VIEW_VAR       = 0x209
  62. local IDM_DEBUG_VIEW           = 0x20A
  63. local IDM_DEBUG_RUN_GO         = 0x20B
  64. local IDM_DEBUG_RUN_STEPINTO   = 0x20C
  65. local IDM_DEBUG_RUN_STEPOVER   = 0x20D
  66. local IDM_DEBUG_RUN            = 0x20E
  67. local IDM_DEBUG_SEARCH_FORWARD = 0x20F
  68. local IDM_DEBUG_SEARCH_AGAIN   = 0x210
  69. local IDM_DEBUG_SEARCH_LINE    = 0x211
  70. local IDM_DEBUG_SEARCH         = 0x212
  71. local IDM_LAST_ITEM            = 0x212
  72.  
  73. local debug_mta[]
  74.  
  75. #
  76. # debug_fun_breakpoints is an array of function gids to break on.
  77. # The index is the gid as a string.  The value is the gid itself.
  78. # The distinction is important because function_name requires the gid itself.
  79. # debug_fun_lineno are the line numbers of the start of the function,
  80. # determined when we hit it.
  81. #
  82. local debug_fun_breakpoints;
  83. local debug_fun_breakpoint_names;
  84. local debug_fun_bp_types;               # 0 = disabled, 1 = enabled, 2 = goto point
  85. local debug_bp_linenos;
  86. local breakpoints_visible = 0;
  87. local ctrl_break_attached = 0;
  88.  
  89. local BP_ENABLED                = 0x01;
  90. local BP_GOTO_POINT             = 0x02;
  91.  
  92. local debug_gid, debug_lineno = 0; # GID and lineno of current debugged function
  93. local debug_step_gid;           # GID of function during debug_step
  94. local debug_go_mode;
  95.  
  96. local debug_tbhand   = 0
  97. local debug_menu     = 0
  98. local filemenu         = 0
  99. local bpmenu        = 0
  100. local runmenu       = 0
  101. local viewmenu         = 0
  102. local searchmenu    = 0
  103.  
  104. #local debug_command_keymap
  105. #local debug_command_window
  106. #local debug_command_buffer
  107.  
  108. #local CTRL_G = 8711
  109. #local CTRL_T = 5140
  110.  
  111. local function set_debug_window()
  112. {
  113.    current_window = debug_window
  114.    current_buffer = debug_buffer
  115.    current_keymap = debug_keymap
  116. }
  117.  
  118. local function set_user_window()
  119. {
  120.    current_window = original_window
  121.    current_buffer = original_buffer
  122.    current_keymap = original_keymap
  123. }
  124.  
  125. local function update_bp_marks()
  126. {
  127.    local old_window = current_window
  128.    current_window = debug_window
  129.  
  130.    linenumber_format = linenumber_format
  131.  
  132.    current_window = old_window
  133. }
  134.  
  135. global debugger_running = 0;
  136.  
  137. global function debug_reset()
  138. {
  139.    debug_gid        = 0;
  140.    debug_filename   = "";
  141. }      
  142.  
  143. global function debug_win( dialogTitle)
  144. {
  145. } #end debug window
  146.  
  147.  
  148. local function create_debug_menu( parent )
  149. {
  150.    # Create Debugger menu
  151.    debug_menu = create_menu()
  152.    
  153.    # File menu
  154.    debug_mta[ IDM_DEBUG_FILE_OPEN      ] =  "~Open..."
  155.    debug_mta[ IDM_DEBUG_FILE_EXIT      ] =  "~Exit"
  156.  
  157.    filemenu = create_menu();
  158.    append_menuitem( filemenu, IDM_DEBUG_FILE_OPEN, MI_DEFAULT, 
  159.                      debug_mta[ IDM_DEBUG_FILE_OPEN ], "debug_open" )
  160.    append_menuitem( filemenu, IDM_DEBUG_FILE_EXIT, MI_DEFAULT, 
  161.                      debug_mta[ IDM_DEBUG_FILE_EXIT ], "debug_esc" )
  162.  
  163.    append_menuitem( debug_menu, IDM_DEBUG_FILE, MI_SUBDEFAULT, "~File", filemenu )
  164.  
  165.    # Breakpoint submenu
  166.    debug_mta[ IDM_DEBUG_BP_LIST        ] =  "~List..."   
  167.    debug_mta[ IDM_DEBUG_BP_SETCLR      ] =  "~Set/Clear"
  168.    debug_mta[ IDM_DEBUG_BP_CLRALL      ] =  "~Clear all"
  169.  
  170.    bpmenu = create_menu();
  171.    append_menuitem( bpmenu, IDM_DEBUG_BP_LIST,     MI_DEFAULT, 
  172.                      debug_mta[ IDM_DEBUG_BP_LIST ], "debug_breakpoint_list" )
  173.    append_menuitem( bpmenu, IDM_DEBUG_BP_SETCLR,   MI_DEFAULT, 
  174.                      debug_mta[ IDM_DEBUG_BP_SETCLR ], "bp_line" )
  175.    append_menuitem( bpmenu, IDM_DEBUG_BP_CLRALL,   MI_DEFAULT, 
  176.                      debug_mta[ IDM_DEBUG_BP_CLRALL ],"bc -1" )
  177.    
  178.    append_menuitem( debug_menu, IDM_DEBUG_BP, MI_SUBDEFAULT, "~Breakpoints", bpmenu )
  179.  
  180.    # Run submenu
  181.    debug_mta[ IDM_DEBUG_RUN_GO         ] =  "~Go"     
  182.    debug_mta[ IDM_DEBUG_RUN_STEPINTO   ] =  "~Step into"
  183.    debug_mta[ IDM_DEBUG_RUN_STEPOVER   ] =  "~Step over"
  184.  
  185.    runmenu = create_menu()
  186.    append_menuitem( runmenu, IDM_DEBUG_RUN_GO,        MI_DEFAULT, 
  187.                      debug_mta[ IDM_DEBUG_RUN_GO ], "debug_go" )
  188.    append_menuitem( runmenu, IDM_DEBUG_RUN_STEPINTO,  MI_DEFAULT, 
  189.                      debug_mta[ IDM_DEBUG_RUN_STEPINTO ], "debug_trace" )
  190.    append_menuitem( runmenu, IDM_DEBUG_RUN_STEPOVER,  MI_DEFAULT, 
  191.                      debug_mta[ IDM_DEBUG_RUN_STEPOVER ], "debug_step" )
  192.    
  193.    append_menuitem( debug_menu, IDM_DEBUG_RUN, MI_SUBDEFAULT, "~Run", runmenu )
  194.  
  195.    # View submenu
  196.    debug_mta[ IDM_DEBUG_VIEW_CALLSTACK ] =  "~Call stack"      
  197.    debug_mta[ IDM_DEBUG_VIEW_LOCALS    ] =  "~Local variables"
  198.    debug_mta[ IDM_DEBUG_VIEW_VAR       ] =  "~Variable"     
  199.  
  200.    viewmenu = create_menu();
  201.    append_menuitem( viewmenu, IDM_DEBUG_VIEW_CALLSTACK, MI_DEFAULT, 
  202.                      debug_mta[ IDM_DEBUG_VIEW_CALLSTACK ], "my_debug_callstack" )
  203.    append_menuitem( viewmenu, IDM_DEBUG_VIEW_LOCALS,    MI_DEFAULT, 
  204.                      debug_mta[ IDM_DEBUG_VIEW_LOCALS ], "debug_local_variables" )
  205.    append_menuitem( viewmenu, IDM_DEBUG_VIEW_VAR,       MI_DEFAULT, 
  206.                      debug_mta[ IDM_DEBUG_VIEW_VAR ], "debug_query_var_info" )
  207.    
  208.    append_menuitem( debug_menu, IDM_DEBUG_VIEW, MI_SUBMENU+MI_DISABLED, "~View", viewmenu )
  209.  
  210.    # Search submenu
  211.    debug_mta[ IDM_DEBUG_SEARCH_FORWARD ] =  "~Search"       
  212.    debug_mta[ IDM_DEBUG_SEARCH_AGAIN   ] =  "Search ~again"
  213.    debug_mta[ IDM_DEBUG_SEARCH_LINE   ]  =  "~Goto line"
  214.  
  215.    searchmenu = create_menu();
  216.    append_menuitem( searchmenu, IDM_DEBUG_SEARCH_FORWARD,   MI_DEFAULT, 
  217.                      debug_mta[ IDM_DEBUG_SEARCH_FORWARD ], "search_forward" )
  218.    append_menuitem( searchmenu, IDM_DEBUG_SEARCH_AGAIN,     MI_DEFAULT, 
  219.                      debug_mta[ IDM_DEBUG_SEARCH_AGAIN ], "search_again" )
  220.    append_menuitem( searchmenu, IDM_DEBUG_SEARCH_LINE,     MI_DEFAULT, 
  221.                      debug_mta[ IDM_DEBUG_SEARCH_LINE ], "goto_line_key" )
  222.    
  223.    append_menuitem( debug_menu, IDM_DEBUG_SEARCH, MI_SUBDEFAULT, "~Search", searchmenu )
  224.  
  225.    change_menu( debug_menu, parent )
  226. }
  227.  
  228. # disable all invalid menu options
  229. local function disable_debug_menu()
  230. {
  231.    modify_menuitem( debug_menu, IDM_DEBUG_VIEW,          MI_DISABLED )
  232.    modify_menuitem( debug_menu, IDM_DEBUG_RUN,           MI_DISABLED )
  233. }
  234.  
  235. # enable all invalid menu options
  236. local function enable_debug_menu()
  237. {
  238.    modify_menuitem( debug_menu, IDM_DEBUG_VIEW,          MI_ENABLED )
  239.    modify_menuitem( debug_menu, IDM_DEBUG_RUN,           MI_ENABLED )
  240. }
  241.  
  242. # This function will use the given id and change the menu text so that
  243. # the key assigned to the function that the menu item executes is displayed
  244. # on the menu
  245. #
  246. local function fix_debug_menu_text()
  247. {
  248.    local keys
  249.    local tab = "\t"
  250.    local functionid
  251.    local menuid
  252.    local oldLevel = message_level
  253.  
  254.    for ( menuid in debug_mta )
  255.       {
  256.       functionid = function_id( menu_functions[menuid] )
  257.    
  258.       # make sure it's valid
  259.       if ( functionid ) 
  260.          {
  261.          # turn of messages
  262.          message_level = 3
  263.             
  264.          # Get the list of keys bound to the id with no angle brackets and 
  265.          # with the "+" as separator within the key name
  266.          #
  267.          keys = function_binding_key( functionid, 1, 1)
  268.             
  269.          modify_menuitem( debug_menu, menuid, MI_ITEMTEXT, debug_mta[menuid] tab keys )
  270.          }  
  271.       }
  272.  
  273.    # restore old message level
  274.    message_level = oldLevel
  275. }
  276.  
  277. local curr_bmp_pos = 0
  278.  
  279. local function bmp_pos( pos )
  280. {
  281.    if ( pos == -1 )
  282.       curr_bmp_pos = 0  
  283.    else if ( pos == TRUE )
  284.       curr_bmp_pos += 34
  285.    else
  286.       curr_bmp_pos += 27
  287.       
  288.    return curr_bmp_pos
  289. }
  290.  
  291. local function create_debug_toolbar( parent )
  292. {
  293.    # copied here from tbar.pel for debugger use
  294.    local    TBMP_FIND         =  10
  295.    local    TBMP_FINDNEXT     =  11
  296.  
  297.    local    TBMP_GO           = 20
  298.    local    TBMP_STEP_INTO    = 21
  299.    local    TBMP_STEP_OVER    = 22
  300.    local    TBMP_DEBUG_END    = 23       
  301.    local    TBMP_SETBP        = 24       
  302.    local    TBMP_QUERY        = 25       
  303.                  
  304.    debug_tbhand = create_toolbar( parent )
  305.  
  306.    insert_toolbaritem(  debug_tbhand, IDM_DEBUG_RUN_GO, TOOLBAR_BUTTON, bmp_pos(-1), 4,  
  307.                         TBMP_GO,       
  308.                         function_id( "debug_go" ) )
  309.  
  310.    insert_toolbaritem(  debug_tbhand, IDM_DEBUG_RUN_STEPINTO, TOOLBAR_BUTTON, bmp_pos(1), 4,
  311.                         TBMP_STEP_INTO,       
  312.                         function_id( "debug_trace" ) )
  313.  
  314.    insert_toolbaritem(  debug_tbhand, IDM_DEBUG_RUN_STEPOVER, TOOLBAR_BUTTON, bmp_pos(0), 4,
  315.                         TBMP_STEP_OVER,       
  316.                         function_id( "debug_step" ) )
  317.  
  318.    insert_toolbaritem(  debug_tbhand, IDM_DEBUG_SEARCH_FORWARD, TOOLBAR_BUTTON, bmp_pos(1), 4,
  319.                         TBMP_FIND,     
  320.                         function_id( "search_forward" ) )
  321.  
  322.    insert_toolbaritem(  debug_tbhand, IDM_DEBUG_SEARCH_AGAIN, TOOLBAR_BUTTON, bmp_pos(0), 4,  
  323.                         TBMP_FINDNEXT, 
  324.                         function_id( "search_again" ) )
  325.  
  326.    insert_toolbaritem(  debug_tbhand, IDM_DEBUG_BP_SETCLR, TOOLBAR_BUTTON, bmp_pos(1), 4,  
  327.                         TBMP_SETBP,       
  328.                         function_id( "bp_line" ) )
  329.  
  330.    insert_toolbaritem(  debug_tbhand, TBMP_QUERY, TOOLBAR_BUTTON, bmp_pos(0), 4,
  331.                         TBMP_QUERY,       
  332.                         function_id( "debug_query_var_info" ) )
  333.  
  334. #   insert_toolbaritem(  debug_tbhand, IDM_DEBUG_FILE_EXIT, TOOLBAR_BUTTON, bmp_pos(1), 4,
  335. #                        TBMP_DEBUG_END,       
  336. #                        function_id( "debug_esc" ) )
  337.  
  338.    show_toolbar( debug_tbhand )
  339.  
  340.    return debug_tbhand
  341. }
  342.  
  343. local function create_debug_keymap()
  344. {
  345.    original_keymap   = current_keymap        
  346.  
  347.    if ( !debug_keymap )
  348.    {
  349.       debug_keymap      = create_keymap( ascii_keymap ) 
  350.                                    
  351.       push_keymap( debug_keymap )
  352.     
  353.       #
  354.       # define command keymap bindings for the debug window and
  355.       # the command window.
  356.       #
  357.       assign_key( "<Up>",             "up"                     )
  358.       assign_key( "<Down>",           "down"                   )
  359.       assign_key( "<Left>",           "left"                   )
  360.       assign_key( "<Right>",          "right"                  )
  361.       assign_key( "<PageUp>",         "page_up"                )
  362.       assign_key( "<PageDown>",       "page_down"              )
  363.       assign_key( "<Home>",           "goto_bol"               )
  364.       assign_key( "<End>",            "goto_eol"               )
  365.                                                                   
  366.       assign_key( "<Num-Up>",         "up"                     )
  367.       assign_key( "<Num-Down>",       "down"                   )
  368.       assign_key( "<Num-Left>",       "left"                   )
  369.       assign_key( "<Num-Right>",      "right"                  )
  370.       assign_key( "<Num-PageUp>",     "page_up"                )
  371.       assign_key( "<Num-PageDown>",   "page_down"              )
  372.       assign_key( "<Num-Home>",       "goto_bol"               )
  373.       assign_key( "<Num-End>",        "goto_eol"               )
  374.                                                                
  375.       assign_key( "<F5>",             "debug_go"               )
  376.       assign_key( "<F8>",             "debug_trace"            )
  377.       assign_key( "<F9>",             "bp_line"                )   
  378.       assign_key( "<F10>",            "debug_step"             )      
  379.       assign_key( "<Alt-C>",          "my_debug_callstack"     )
  380.       assign_key( "<Alt-S>",          "search_forward"         )
  381.       assign_key( "<Alt-A>",          "search_again"           )
  382.                                        
  383.       assign_key( "<F9>",             "bp_line"                )
  384.    
  385.       assign_key( "a",                "search_again"           )
  386.       assign_key( "b",                "debug_breakpoint_list"  )
  387.       assign_key( "g",                "goto_line_key"          )
  388.       assign_key( "s",                "search_forward"         )
  389.       assign_key( "v",                "debug_open"             )
  390.    
  391.       assign_key( "A",                "search_again"           )
  392.       assign_key( "B",                "debug_breakpoint_list"  )
  393.       assign_key( "G",                "goto_line_key"          )
  394.       assign_key( "S",                "search_forward"         )
  395.       assign_key( "V",                "debug_open"             )
  396.    }
  397.    else
  398.       push_keymap( debug_keymap )
  399.  
  400. #   pop_keymap()
  401. }
  402.  
  403. local function create_debug_display_window( parent )
  404. {
  405.    current_window = debug_window = create_factory_window( 0, 0,     
  406.                                                           0, 0, 
  407.                                                           WINDOW_VERT_SB      +      
  408.                                                             WINDOW_HORIZ_SB   +      
  409.                                                             WINDOW_SYSTEM     +
  410.                                                             WINDOW_EXPANDED   +
  411.                                                             0x8,
  412.                                                           parent )
  413.  
  414.    expand_window()
  415.  
  416.    linenumber_format = " %5d:%m "
  417.  
  418.    color_window_fg      = debug_text_fg
  419.    color_window_bg      = debug_text_bg
  420.    color_linenumbers_fg = debug_line_fg
  421.    color_linenumbers_bg = debug_line_bg
  422.    
  423.    if ( debug_buffer )
  424.       delete_buffer( debug_buffer )
  425.  
  426.    debug_buffer = create_buffer( debug_empty_name, 
  427.                                  "", 
  428.                                  BUFFER_SYSTEM        + 
  429.                                     BUFFER_NO_UNDO    + 
  430.                                     BUFFER_READ_ONLY     )
  431. }
  432.  
  433. local function debug_init()
  434. {
  435.    local    cw;
  436.    local    cb;
  437.    local    i;
  438.    local    win_height
  439.    local    debug_sbar_flags
  440.  
  441.    #  This was taken out because this function is only called if a 
  442.    #  window is open.
  443.  
  444. #   if ( !current_window )
  445. #   {
  446. #      current_window = create_window( 0, 0, display_width, display_height);
  447. #      attach_window_buffer( current_window, current_buffer );
  448. #   }
  449.  
  450.    # DWM 5/10/94
  451.    original_window = current_window
  452.    original_buffer = current_buffer
  453.    original_keymap = current_keymap
  454.  
  455.    cw = current_window
  456.    cb = current_buffer
  457.  
  458.    if ( debug_enabled )
  459.    { 
  460.       expand_window( debug_window )  
  461.       debug_reset()
  462.       return;
  463.    }
  464.  
  465.    debug_enabled  = 1
  466.    debug_go_mode  = 0
  467.    debug_id       = function_id( "debug_fun" )
  468.  
  469.    debug_sbar_flags     = status_bar_flags
  470.    debug_remote_window  = create_remote_window( "Pel Debugger" )
  471.    status_bar_flags     = debug_sbar_flags
  472.  
  473.    create_debug_toolbar( debug_remote_window )
  474.  
  475.    create_debug_menu( debug_remote_window )
  476.  
  477.    create_debug_display_window( debug_remote_window )
  478.  
  479.    create_debug_keymap()
  480.  
  481.    fix_debug_menu_text()
  482.  
  483.    attach_window_buffer( debug_window, debug_buffer );
  484.    
  485.    scroll_context_top = 0;
  486.    scroll_context_bottom = 0;
  487.  
  488.    set_debug_window()
  489. }
  490.  
  491. # array containing all non-debugger mouse events
  492. local debug_event_handlers[] 
  493.  
  494. # call original event handlers of mouse_event
  495. local function original_handler( mouse_event )
  496. {
  497.    local handler 
  498.  
  499.    for ( handler in debug_event_handlers[ mouse_event ] )
  500.       execute_function( debug_event_handlers[mouse_event][handler] )
  501. }
  502.  
  503. global function dummy_handler()
  504. {
  505.    local mouse_event = event_id
  506.  
  507.    if ( current_window == debug_window )
  508.       {
  509.       if ( mouse_event == EVENT.MOUSE_LEFT_CLICK2 )
  510.          debug_lmouse_double_click()
  511.  
  512.       else if ( mouse_event == EVENT.MOUSE_LEFT_DOWN )
  513.          {
  514.          goto_pos( mouse_event_y + window_first, mouse_event_x + window_margin + 1 );
  515.          update_current_view();
  516.          }
  517.       else if ( mouse_event == EVENT.EXIT_EDITOR )
  518.          {
  519.          debug_esc()
  520.          original_handler()
  521.          }
  522.       }
  523.    else
  524.       original_handler( mouse_event )
  525.       
  526. }
  527.  
  528. local function override_events()
  529. {
  530.    local event
  531.    local mouse_events[]
  532.    local mouse_drag_events[]
  533.    local exit_events[]
  534.    local dummy_handler_id = function_id( "dummy_handler" )
  535.  
  536.    # store all mouse event handlers 
  537.    mouse_events      = save_and_remove_events( EVENT.MOUSE_LEFT_DOWN, EVENT.MOUSE_MID_CLICK2 ) 
  538.    mouse_drag_events = save_and_remove_events( EVENT.LMOUSE_DRAG, EVENT.RMOUSE_DRAG )
  539.    exit_events       = save_and_remove_events( EVENT.EXIT_EDITOR, EVENT.EXIT_EDITOR )
  540.  
  541.    debug_event_handlers = merge_arrays( mouse_events, mouse_drag_events )
  542.    debug_event_handlers = merge_arrays( debug_event_handlers, exit_events )
  543.  
  544.    # attach dummy handlers for all mouse events
  545.    for ( event in debug_event_handlers )
  546.       attach_event_handler( event, dummy_handler_id )
  547.  
  548.    attach_event_handler( EVENT.NEW_CURNT_WINDOW,         "changing_windows"   ) 
  549.    attach_event_handler( EVENT.CLOSING_REMOTE_WINDOW,    "debug_esc"          ) 
  550. }
  551.  
  552. local function debug_restore_events()
  553. {
  554.    local event
  555.    local dummy_handler_id = function_id( "dummy_handler" )
  556.  
  557.    # delete dummy handlers for all mouse events
  558.    for ( event in debug_event_handlers )
  559.       delete_event( event, dummy_handler_id )
  560.  
  561.    restore_events( debug_event_handlers )
  562.  
  563.    delete debug_event_handlers
  564.  
  565.    delete_event( EVENT.NEW_CURNT_WINDOW,           "changing_windows"   ) 
  566.    delete_event( EVENT.CLOSING_REMOTE_WINDOW,      "debug_esc"          ) 
  567. }
  568.  
  569. # Invoke this to start debugging.
  570. #
  571. function debug()
  572. {
  573.    local gid;
  574.    local fn;
  575.  
  576.    local user_file = buffer_filename
  577.    local user_line = 1
  578.  
  579.    if(!current_window)
  580.    {
  581.       warning("PEL Debugger may not be run with no windows open.");
  582.       return FALSE;
  583.    }
  584.  
  585.    # DWM 4/4/95
  586.    # Why would this only be useful for modified buffers?
  587.    #if ( and(buffer_flags, BUFFER_MODIFIED) )
  588.       user_line = current_line
  589.  
  590.    main_window = current_window
  591.    main_buffer = current_buffer
  592.                          
  593.    attach_break_handler()
  594.  
  595.    override_events()
  596.  
  597.    debug_function( 0 );
  598.    debug_init()
  599.  
  600.    # if the user is looking at a pel file, load it
  601.    if ( path_ext(user_file) == ".pel" && path_fname(user_file) != "debug" )
  602.       {
  603.       debug_filename = user_file
  604.       debug_view( user_file, user_line )
  605.       }
  606.  
  607.    # Put debugger in trace mode.
  608.    debug_step_gid = 0
  609.    debug_go_mode = 0
  610.    debug_num_steps = 0;
  611.  
  612.    for ( gid in debug_fun_breakpoints )
  613.    {
  614.       if ( and(debug_fun_bp_types[gid], BP_GOTO_POINT) )
  615.          debug_remove_goto_point( gid );
  616.    }
  617.             
  618.    if ( debugger_running )
  619.       debugger_running = 0;
  620.  
  621.    debug_fun( 0, 1 );
  622. }        
  623.  
  624. function changing_windows ()
  625. {
  626.    if ( current_window == debug_window )
  627.    {                                              
  628.       if ( current_keymap != debug_keymap )
  629.          original_keymap = current_keymap 
  630.  
  631.       if ( debug_keymap )
  632.          current_keymap = debug_keymap
  633.    
  634.       if ( !debug_go_mode && debugger_running )
  635.          highlight_line()
  636.       else
  637.          unhighlight_line()
  638.    }                               
  639.    else 
  640.    {
  641.       current_keymap = original_keymap
  642.    
  643.       if ( !debug_enabled )
  644.          debug_reset()        
  645.    }
  646. }
  647.  
  648. # Step over function call.
  649. # This will not work if the function is called recursively.
  650. function debug_step()
  651. {
  652.    if ( !debug_go_mode )
  653.    {
  654.       if ( debug_gid )
  655.       {         
  656.          debug_go_mode  = 0
  657.          debug_step_gid = debug_gid
  658.    
  659.          process_end( 1 )          
  660.       }
  661.       else
  662.          debug_view( debug_view_file )
  663.    }
  664.    else
  665.       beep()
  666. }
  667.  
  668. function debug_trace()
  669. {
  670.    if ( !debug_go_mode )
  671.    {
  672.       debug_go_mode  = 0
  673.       debug_step_gid = 0
  674.    
  675.       process_end( 1 )
  676.    }
  677.    else
  678.       beep()
  679. }
  680.  
  681. function debug_esc()
  682. {
  683.    local i
  684.    local event = event_id
  685.  
  686.    debug_function( 0 )
  687.  
  688.    debug_restore_events()
  689.  
  690.    debug_go_mode     = 0
  691.    debug_step_gid    = 0
  692.    debug_enabled     = 0
  693.    debug_view_file   = "???";
  694.    debug_filename    = ""
  695.  
  696.    debug_reset()
  697.  
  698.    pop_keymap()                    
  699.    remove_break_handler()
  700.  
  701.    if ( debug_menu )
  702.       {
  703.       # delete our local list that maps function id's to menu item
  704.       # id's.  This list was created during the append_menuitem calls.   
  705.       for ( i = IDM_FIRST_ITEM; i <= IDM_LAST_ITEM; i++ )
  706.          if ( i in menu_functions )
  707.             delete menu_functions[i]
  708.  
  709.       delete_menu( filemenu, debug_remote_window )
  710.       delete_menu( bpmenu, debug_remote_window )
  711.       delete_menu( runmenu, debug_remote_window )
  712.       delete_menu( viewmenu, debug_remote_window )
  713.       delete_menu( searchmenu, debug_remote_window )
  714.       delete_menu( debug_menu, debug_remote_window )
  715.       debug_menu = 0
  716.       filemenu       = 0
  717.       bpmenu         = 0
  718.       runmenu        = 0
  719.       viewmenu       = 0
  720.       searchmenu     = 0
  721.       }
  722.  
  723.    if ( debug_tbhand )
  724.       {
  725.       delete_toolbar( debug_tbhand )
  726.       debug_tbhand = 0
  727.       }
  728.  
  729.    if ( bl_hdlg )
  730.       {
  731.       delete_dialog( bl_hdlg )
  732.       bl_hdlg = 0
  733.       }
  734.  
  735.    if ( debug_keymap )
  736.       {
  737.       delete_keymap( debug_keymap )
  738.       debug_keymap = 0
  739.       }
  740.  
  741.    enable_all_windows()
  742.    set_user_window()
  743.  
  744.    debug_enabled  = FALSE
  745.  
  746.    if ( event != EVENT.CLOSING_REMOTE_WINDOW )
  747.       {
  748.       delete_remote_window( debug_remote_window )
  749.       debug_remote_window  = 0
  750.       debug_window         = 0
  751.       }
  752.  
  753.    process_end( 0 ) 
  754. }
  755.  
  756. # If name is a function parameter or local variable of the current
  757. # function being debugged, then return the index of that variable.
  758. # stframe is the frame number of the function desired.
  759. local function debug_find_stvar(varname,stframe)
  760. {
  761.    local x, list,list1,n,i
  762.  
  763.    if ((x = debug_get_frame(stframe)))
  764.    {
  765.       split(x[4],list1,";")           # x[4] is the parameter;local list
  766.       n = split(list1[1],list)        # list1[1] is the parameters
  767.       for (i = 1; i <= n; i++)
  768.       {
  769.          if (list[i] == varname) 
  770.          return(i)
  771.       }
  772.       n = split(list1[2],list)        # list1[2] is the locals
  773.       for (i = 1; i <= n; i++)
  774.       {
  775.          if (list[i] == varname)
  776.          return(- i)
  777.       }                        
  778.    }
  779.  
  780.    return( 0 )
  781. }
  782.  
  783. #
  784. # Clear Breakpoint
  785. #
  786. function bc( bpindex )
  787. {
  788.    local gid
  789.    local mark
  790.    
  791.    if ( bpindex >= 0 ) 
  792.       {
  793.       gid = bpindex_to_gid( bpindex )
  794.  
  795.       if ( gid && gid in debug_fun_breakpoints ) 
  796.          {
  797.          mark = debug_marks[ debug_fun_breakpoints[ gid ] ]
  798.          if ( mark )
  799.             delete_mark( mark )
  800.  
  801.          delete debug_fun_breakpoints[ gid ]
  802.          delete debug_fun_breakpoint_names[ gid ]
  803.          delete debug_fun_bp_types[ gid ]
  804.          } 
  805.       } 
  806.    # Clear all breakpoints
  807.    else 
  808.       {
  809.       for ( gid in debug_fun_breakpoints )
  810.          {
  811.          mark = debug_marks[ debug_fun_breakpoints[ gid ] ]
  812.          if ( mark )
  813.             delete_mark( mark )
  814.          }
  815.  
  816.       delete debug_fun_breakpoints
  817.       delete debug_fun_breakpoint_names;
  818.       delete debug_fun_bp_types;
  819.       }
  820.  
  821.    update_bl( bpindex )
  822. }        
  823.  
  824.  
  825. #
  826. # Disable Breakpoint
  827. #
  828. function bd( bpindex )
  829. {
  830.    local gid
  831.    
  832.    if ( bpindex >= 0 ) 
  833.       {
  834.       gid = bpindex_to_gid( bpindex )
  835.  
  836.       if ( gid && gid in debug_fun_breakpoints )
  837.          debug_fun_bp_types[ gid ] = and( debug_fun_bp_types[gid], not(BP_ENABLED) )
  838.       } 
  839.    else 
  840.       {
  841.       for ( gid in debug_fun_bp_types )
  842.          debug_fun_bp_types[ gid ] = and( debug_fun_bp_types[gid], not(BP_ENABLED) )
  843.       }
  844.  
  845.    update_bl( bpindex )
  846. }        
  847.  
  848. #
  849. # Enable Breakpoint
  850. #
  851. function be( bpindex )
  852. {
  853.    local gid
  854.    
  855.    if ( bpindex >= 0 ) 
  856.       {
  857.       gid = bpindex_to_gid( bpindex );
  858.  
  859.       if ( gid ) 
  860.          debug_fun_bp_types[ gid ] = or( debug_fun_bp_types[ gid ], BP_ENABLED )
  861.       } 
  862.    else 
  863.       {
  864.       for ( gid in debug_fun_bp_types )
  865.          debug_fun_bp_types[ gid ] = or( debug_fun_bp_types[ gid ], BP_ENABLED )
  866.       }
  867.  
  868.    update_bl( bpindex )
  869. }       
  870.  
  871.  
  872.  
  873. # Set Breakpoints
  874. #
  875. function bp( funname )
  876. {
  877.    local   gid = 0
  878.    local   i   = 0;
  879.    
  880.    debug_init()
  881.    
  882.    gid = function_id( funname )
  883.    
  884.    # This is magic: acceptable gids lie in the range 1000 to 8000
  885.    if ( !(!gid || (gid < 1000 || gid >= 8000)) ) 
  886.       {
  887.       debug_fun_breakpoints[gid] = 0
  888.       debug_fun_breakpoint_names[gid] = function_name( gid );
  889.       # DWM 1/24/94
  890.       # The old concept of a BP_GOTO_POINT doesn't exist anymore.
  891.       # debug_fun_bp_types[gid] = debug_go_mode ? BP_ENABLED + BP_GOTO_POINT : BP_ENABLED;
  892.       debug_fun_bp_types[gid] = BP_ENABLED;
  893.       
  894.       if ( !debugger_running ) 
  895.          {
  896.          debug_go_mode = 1;
  897.          debug_step_gid = 0;
  898.          debug_function(debug_id)
  899.          }
  900.       }
  901.  
  902.    update_bl( gid_to_bpindex(gid) )
  903.  
  904.    return gid;
  905. }
  906.  
  907. local debug_marks[]
  908.  
  909. function bp_line()
  910. {
  911.    local   fn;
  912.    local   mark
  913.  
  914.    if ( debug_view_file )
  915.       {
  916.       fn = buildpath( debug_view_file ) ":" current_line;
  917.    
  918.       if ( fn in debug_fun_breakpoints ) 
  919.          {        
  920.          delete( debug_fun_breakpoints[fn] );
  921.          delete( debug_fun_bp_types[fn] );
  922.          delete( debug_fun_breakpoint_names[fn] );
  923.  
  924.          delete_mark( debug_marks[ current_line ] )
  925.          linenumber_format = linenumber_format
  926.          } 
  927.       else 
  928.          {
  929.          debug_bp_linenos[ current_line ] = 1;
  930.          debug_fun_breakpoints[ fn ] = current_line;
  931.          debug_fun_bp_types[ fn ] = BP_ENABLED;     
  932.          debug_fun_breakpoint_names[ fn ] = fn;
  933.  
  934.          mark = pick_unused_mark()
  935.          create_mark( mark )
  936.          debug_marks[ current_line ] = mark
  937.          linenumber_format = linenumber_format
  938.  
  939.          breakpoints_visible = 1;
  940.          }
  941.    
  942.       update_bl( gid_to_bpindex(fn) )
  943.       }
  944. }        
  945.  
  946. function debug_go()
  947. {
  948.    debug_step_gid = 0;
  949.    debug_go_mode  = 1
  950.  
  951.    process_end( 1 )
  952.  
  953.    set_user_window()
  954. }        
  955.  
  956. global function disable_all_windows()
  957. {
  958.    local start_win
  959.    local cur_win
  960.  
  961.    set_editwin_property( EWC_DISABLE, 0 )            
  962.  
  963.    #set_editwin_property( 18, 0 )            
  964.  
  965.    start_win = current_window
  966.    cur_win = next_window( "", 0, 1 )
  967.    while ( cur_win != start_win )
  968.    {
  969.       if ( cur_win != debug_window )
  970.          set_editwin_property( EWC_DISABLE, cur_win )            
  971.  
  972.       cur_win = next_window( "", 0, 1 )
  973.    }
  974.  
  975.    if ( cur_win != debug_window )
  976.       set_editwin_property( EWC_DISABLE, cur_win )            
  977.  
  978.    #set_editwin_property( 18, debug_remote_window )            
  979. }
  980.  
  981. global function enable_all_windows()
  982. {
  983.    local start_win
  984.    local cur_win
  985.  
  986.    set_editwin_property( EWC_ENABLE, 0 )            
  987.  
  988.    #set_editwin_property( 18, 0 )            
  989.  
  990.    start_win = current_window
  991.    cur_win = next_window( "", 0, 1 )
  992.    while ( cur_win != start_win )
  993.    {
  994.       if ( cur_win != debug_window )
  995.          set_editwin_property( EWC_ENABLE, cur_win )            
  996.  
  997.       cur_win = next_window( "", 0, 1 )
  998.    }
  999.  
  1000.    if ( cur_win != debug_window )
  1001.       set_editwin_property( EWC_ENABLE, cur_win )            
  1002.  
  1003.    #set_editwin_property( 18, debug_remote_window )            
  1004. }
  1005.  
  1006. # Call this with the gid and line number of function being debugged,
  1007. # or with gid == 0 to just bring up the debugger on nothing.
  1008. # debug_session returns 1 to continue debugging, 0 to quit
  1009. local function debug_session()
  1010. {
  1011.    local   filename = debug_filename;
  1012.    local   cb;
  1013.    
  1014.    attach_break_handler()
  1015.    
  1016.    if ( current_window != debug_window )
  1017.       {
  1018.       original_window = current_window
  1019.       original_keymap = current_keymap
  1020.       original_buffer = current_buffer
  1021.       }
  1022.    
  1023.    if ( !debugger_running ) 
  1024.       debugger_running = 1;
  1025.    
  1026.    debug_at()
  1027.  
  1028.    disable_all_windows()
  1029.  
  1030.    if ( debug_gid )
  1031.       enable_debug_menu()
  1032.  
  1033.    debugger_running = process_begin() + 0
  1034.  
  1035.    enable_all_windows()
  1036.  
  1037.    if ( debug_enabled )
  1038.       disable_debug_menu()
  1039.    
  1040.    set_user_window()
  1041.  
  1042.    if ( debugger_running != 0 )      
  1043.       pop_keymap()                     
  1044.    
  1045.    return( debugger_running )
  1046. }
  1047.  
  1048. local function debug_file_display( filename )
  1049. {
  1050.    local def_buf_eol = default_buffer_eol_string;
  1051.    
  1052.    debug_view_file = filename;
  1053.    delete_buffer( debug_buffer )
  1054.    
  1055.    default_buffer_eol_string = "\r\n"     
  1056.    current_buffer = debug_buffer = 
  1057.       create_buffer( debug_gid \
  1058.                         ? "FILE: " debug_filename " FUNCTION: " function_name(debug_gid) \
  1059.                         : debug_empty_name,
  1060.                      debug_filename,
  1061.                      BUFFER_SYSTEM + BUFFER_NO_UNDO + BUFFER_READ_ONLY )
  1062.  
  1063.    default_buffer_eol_string = def_buf_eol;
  1064.    
  1065.    buffer_tabs = debug_tabs;
  1066.    attach_window_buffer( debug_window, debug_buffer );
  1067. }        
  1068.  
  1069. function debug_at()
  1070. {
  1071.    if ( current_window != debug_window )
  1072.       set_debug_window()
  1073.  
  1074.    #                      
  1075.    # if the current file displayed doesn't equal the one that's
  1076.    # suppose to be displayed, find the one to display
  1077.    #
  1078.    if ( debug_filename != debug_view_file ) 
  1079.    {
  1080.       debug_filename  = debug_gid ? get_source_file_name(debug_gid) : "";
  1081.  
  1082.       debug_file_display( debug_filename );
  1083.       debug_file_display( debug_filename );
  1084.    }
  1085.    
  1086.    if ( debug_gid )  
  1087.    {
  1088.       current_line = debug_lineno;
  1089.       unhighlight_line()
  1090.       center_cursor();
  1091.       highlight_line( debug_color_highlight );
  1092.    }
  1093. }        
  1094.  
  1095.  
  1096. local   currentFrame = 1;
  1097.  
  1098. # Gid is the function_id of the function being executed.
  1099. # lineno is the line number in that function.
  1100. #
  1101. function debug_fun(gid,lineno)
  1102. {
  1103.    local   fn;
  1104.    local   i,ln;
  1105.    local   x;
  1106.    local   done;           
  1107.    local   ck
  1108.  
  1109.    ck = current_keymap
  1110.    if ( ck != debug_keymap )
  1111.       original_keymap = ck
  1112.  
  1113.    # If we are performing a debug_step function,
  1114.    # keep going until we get back to the function
  1115.    # we did the step in or stepping out of.
  1116.    #
  1117.    done = 0
  1118.    if ( debug_step_gid && (gid != debug_step_gid) ) 
  1119.    {
  1120.       if ( debug_get_frame(currentFrame) ) 
  1121.       {
  1122.          debug_function( debug_id )
  1123.          return;
  1124.       }
  1125.    }
  1126.  
  1127.    # If we are performing a debug_go function, keep going
  1128.    # until a breakpoint is reached.
  1129.    # We remember the first line number of each function.
  1130.    if ( debug_go_mode ) 
  1131.    {
  1132.       if (  (gid in debug_fun_breakpoints)            && 
  1133.             and(debug_fun_bp_types[gid], BP_ENABLED)  &&
  1134.             (!debug_fun_breakpoints[gid] || (debug_fun_breakpoints[gid] == lineno)) )
  1135.       {
  1136.          if ( !debug_fun_breakpoints[gid] )
  1137.             debug_fun_breakpoints[gid] = lineno;
  1138.          
  1139.          if ( and(debug_fun_bp_types[gid], BP_GOTO_POINT) )
  1140.             debug_remove_goto_point( gid );
  1141.       } 
  1142.       else if ( lineno in debug_bp_linenos ) 
  1143.       {
  1144.          fn = gid ? get_source_file_name( gid ) ":" lineno : ""
  1145. #         if ( !(fn in debug_fun_breakpoints) && and(debug_fun_bp_types[fn], BP_ENABLED) ) 
  1146.          if ( !(fn in debug_fun_breakpoints) ) 
  1147.          {
  1148.             debug_function( debug_id )
  1149.             return;        
  1150.          }
  1151.  
  1152.          delete( debug_bp_linenos );
  1153.  
  1154.          for ( i in debug_fun_breakpoints )
  1155.             if ( (ln = debug_fun_breakpoints[i]) )
  1156.                debug_bp_linenos[ ln ] = ln;
  1157.  
  1158.       } # if lineno in debug_bp_linenos
  1159.       else 
  1160.       {
  1161.          debug_function( debug_id )
  1162.          return;
  1163.       }
  1164.  
  1165.       debug_go_mode = 0;                                  
  1166.       debug_num_steps = 0;
  1167.  
  1168.    } # if debug_go_mode
  1169.  
  1170.    if ( debug_gid != gid ) 
  1171.    {                                
  1172.       debug_filename = gid ? get_source_file_name(gid) : "";
  1173.       debug_gid = gid;
  1174.  
  1175.       if ( path_fname(debug_filename) == "debug" &&
  1176.             path_ext(debug_filename) == ".pel" )
  1177.       {
  1178.          # DWM 5/20/94
  1179.          # don't quit debugger when we get 
  1180.          # into debug code, just step over it
  1181.          debug_function( debug_id )
  1182.          return;
  1183.  
  1184.          #debug_esc()
  1185.          #current_keymap = original_keymap
  1186.          #return;
  1187.       }
  1188.    }       
  1189.    debug_lineno = lineno;
  1190.  
  1191.    for ( currentFrame=0; debug_get_frame(currentFrame+1); currentFrame++ )
  1192.       continue;
  1193.         
  1194.    remove_break_handler()  
  1195.  
  1196.    if ( debug_session() ) 
  1197.    {
  1198.       debug_function( debug_id )
  1199.       attach_break_handler()
  1200.    }
  1201. }                      
  1202.  
  1203. local function debug_remove_goto_point( gid )
  1204. {
  1205.    delete( debug_fun_breakpoints[gid] )
  1206.    delete( debug_fun_bp_types[gid] )
  1207.    delete( debug_fun_breakpoint_names[gid] )
  1208. }
  1209.  
  1210. local function bpindex_to_gid( index )
  1211. {
  1212.    local gid
  1213.    
  1214.    for ( gid in debug_fun_bp_types ) 
  1215.       {
  1216.       if ( !index ) 
  1217.          return gid
  1218.  
  1219.       index--;
  1220.       }
  1221.  
  1222.    return 0
  1223. }
  1224.  
  1225. local function gid_to_bpindex( gid )
  1226. {
  1227.    local bpindex  = 0
  1228.    local curr_gid
  1229.    
  1230.    for ( curr_gid in debug_fun_bp_types ) 
  1231.       {
  1232.       if ( gid == curr_gid ) 
  1233.          break
  1234.  
  1235.       bpindex++
  1236.       }
  1237.  
  1238.    if ( gid != curr_gid )
  1239.       bpindex = -1
  1240.  
  1241.    return bpindex
  1242. }
  1243.  
  1244. function debug_view( fname, line )
  1245. {
  1246.    local cb          = current_buffer;
  1247.    local def_buf_eol = default_buffer_eol_string;
  1248.    
  1249.    fname = ltrim( trim( fname ) )
  1250.  
  1251.    default_buffer_eol_string = "\r\n"
  1252.  
  1253.    current_buffer = create_buffer(  "FILE: " path_fname(fname) path_ext(fname),
  1254.                                     fname,
  1255.                                     BUFFER_SYSTEM  + 
  1256.                                     BUFFER_NO_UNDO + 
  1257.                                     BUFFER_READ_ONLY )
  1258.  
  1259.    default_buffer_eol_string = def_buf_eol;
  1260.    
  1261.    if ( buffer_size ) 
  1262.       {
  1263.       buffer_tabs = debug_tabs;
  1264.       
  1265. #new_buf = current_buffer
  1266. #current_buffer = debug_buffer
  1267.       delete_buffer(debug_buffer); 
  1268.       debug_buffer = current_buffer
  1269. #     debug_buffer = new_buf;
  1270. #current_buffer = debug_buffer
  1271. #      debug_buffer = current_buffer;
  1272.  
  1273. #if ( buffer_last_line >= line )
  1274. #  ; 
  1275.  
  1276. #      if ( argcount() > 1 && buffer_last_line >= line )
  1277.          current_line = line
  1278.  
  1279.       debug_view_file = fname;
  1280.       attach_window_buffer( debug_window, debug_buffer )
  1281.       }
  1282.    else
  1283.       current_buffer = cb;
  1284. }
  1285.  
  1286. #local y_highlight = -1;
  1287. #local y_ext = -1;
  1288. #local x_ext = -1;
  1289.  
  1290. local function highlight_line( attr )
  1291. {
  1292.    remove_selection()
  1293.    update_current_view()
  1294.  
  1295.    save_position()
  1296.  
  1297.    current_line = debug_lineno
  1298.    begin_selection(LINE_SELECTION)
  1299.    end_selection()
  1300.    update_current_view()
  1301.  
  1302.    restore_position(TRUE)
  1303. }
  1304.  
  1305. local function unhighlight_line()
  1306. {
  1307.    remove_selection()
  1308.    update_current_view()
  1309.  
  1310. #   if ( breakpoints_visible )
  1311. #   {
  1312. #      breakpoints_visible = 0;
  1313. #      update_current_view()
  1314. #   }
  1315. #   else
  1316. #   {
  1317. #      # use the last highlighted line setting to unhighlight
  1318. #      #
  1319. #      if ( (y_highlight >= 0) && (y_highlight < y_ext) )
  1320. #      {
  1321. #         highlight_window( 0, y_highlight, x_ext, 1, debug_color_text,
  1322. #                           debug_window );
  1323. #      }
  1324. #   }
  1325. #
  1326. #   y_highlight = -1;
  1327. }
  1328.  
  1329.  
  1330.  
  1331. local function get_source_file_name( gid )
  1332. {
  1333.    local   fn = source_file_name( gid );
  1334.    local   src_name;
  1335.  
  1336.    if (findfirst( fn ) == "")
  1337.       return buildpath( path_fname( fn ) path_ext( fn ) );
  1338.    else
  1339.       return fn;
  1340. }
  1341.  
  1342. global function debug_ctrl_break()
  1343. {
  1344.    debug_num_steps = 0;
  1345.    debug_go_mode = 0;
  1346. }
  1347.  
  1348.  
  1349. function attach_break_handler()
  1350. {
  1351.    if (!ctrl_break_attached)
  1352.    {
  1353.       attach_event_handler( EVENT.CTRL_BREAK, function_id( "debug_ctrl_break" ));
  1354.       ctrl_break_attached = 1;
  1355.    }
  1356. }
  1357.  
  1358. function remove_break_handler()
  1359. {
  1360.    if (ctrl_break_attached)
  1361.    {
  1362.       delete_event( EVENT.CTRL_BREAK, function_id( "debug_ctrl_break" ) )
  1363.       ctrl_break_attached = 0;
  1364.    }
  1365. }
  1366.  
  1367. local function my_debug_cvdebug(outline)
  1368. {
  1369.    local MAX = 80;
  1370.  
  1371.    outline = prefix(outline, MAX);
  1372.    cvdebug(outline);
  1373. }
  1374.  
  1375. local my_debug_gid         = 0
  1376. local my_last_gid          = 0
  1377. local my_target_gid        = 0
  1378. local my_do_callstack      = FALSE
  1379. local my_last_stacklevel   = 0
  1380. local my_debug_level       = 0
  1381. local my_last_caller       = 0
  1382.  
  1383. global function my_debug_fun( gid, lineno )
  1384. {
  1385.    local currentFrame 
  1386.  
  1387.    if ( !my_debug_gid )
  1388.       my_debug_gid = function_id("my_debug_fun")
  1389.  
  1390.    if ( argcount() > 0 && gid && gid != my_debug_gid )
  1391.       {
  1392.       if ( my_target_gid != 0 && gid == my_target_gid )
  1393.          {
  1394.          if ( argcount() < 2 )
  1395.             lineno = -1
  1396.          
  1397.          if ( my_do_callstack )
  1398.             {
  1399.             my_debug_callstack()
  1400.             my_do_callstack = FALSE
  1401.             }
  1402.          else
  1403.             my_debug_fun_call( my_debug_level, currentFrame )
  1404.          }
  1405.       else if ( my_target_gid == 0 && gid != my_last_gid )
  1406.          {
  1407.          if ( argcount() < 2 )
  1408.             lineno = -1
  1409.          
  1410.          for ( currentFrame=0; debug_get_frame(currentFrame+1); currentFrame++ )
  1411.             continue;
  1412.  
  1413.          if ( my_last_stacklevel && currentFrame > my_last_stacklevel )
  1414.          {
  1415.             my_last_caller = my_last_gid
  1416.             my_debug_cvdebug(sprintf("%s{", strrepeat("\t",my_last_stacklevel-1) ));
  1417.          }
  1418.  
  1419.          if ( my_last_stacklevel && currentFrame < my_last_stacklevel )
  1420.             my_debug_cvdebug(sprintf( "%s}", strrepeat("\t",currentFrame-1) ));
  1421.  
  1422.          if ( gid != my_last_caller )
  1423.             my_debug_fun_call( my_debug_level, currentFrame )
  1424.  
  1425.          my_last_stacklevel = currentFrame
  1426.          }
  1427.  
  1428.       my_last_gid = gid
  1429.       }
  1430.  
  1431.    debug_function( my_debug_gid )
  1432. }
  1433.  
  1434. global function my_debug( onOff )
  1435. {
  1436.    if ( argcount() > 0 && !onOff )
  1437.       debug_function( 0 )
  1438.    else
  1439.       my_debug_fun( 0, 0 )
  1440. }
  1441.  
  1442. global function my_debug_var_at( fname, var_name ) 
  1443. {
  1444.    
  1445. }
  1446.  
  1447. global function my_debug_at_fun( fname )
  1448. {
  1449.    my_target_gid     = function_id( fname )
  1450.    my_do_callstack   = FALSE
  1451.  
  1452. #   cvdebug( "targetting %s(%d)", fname, my_target_gid )
  1453.  
  1454.    return my_target_gid
  1455. }
  1456.  
  1457. global function my_debug_in( file_name )
  1458. {
  1459. }
  1460.  
  1461. global function my_debug_callstack()
  1462. {
  1463.    local list[]
  1464.    local vars[]
  1465.    local x[]
  1466.    local argc     = 0
  1467.    local i        = 1
  1468.    local n        = 1
  1469.    local arglist  = ""
  1470.    local var_val  = ""
  1471.    local var_type = ""
  1472.    local popbuf[]
  1473.  
  1474.    if (!debug_gid)
  1475.       return;
  1476.  
  1477.    for (n=1; (x = debug_get_frame(n)); n++)
  1478.    {
  1479.       # x[1] is gid, x[2] is lineno, x[3] is argc, x[4] is param list
  1480.       # Create the list of function arguments
  1481.       argc = x[3]
  1482.       split( x[4], list, ";" )   # list[1] = parameters, list[2] = local vars
  1483.       split( list[1], vars )
  1484.       for (i = 1; i <= argc; i++)
  1485.       {
  1486.          var_val = debug_get_stack_var( 1, i )
  1487.          var_type = typeof( var_val )
  1488.    
  1489.          if ( var_type == "string" || var_type == "regular expression" )
  1490.             var_val = "\"" var_val "\""
  1491.    
  1492.          if ( var_val )
  1493.             {
  1494.             arglist = arglist vars[i] "=" var_val
  1495.    
  1496.             if ( i != argc )
  1497.                arglist = arglist ", "
  1498.             }
  1499.       }
  1500.       popbuf[ n ] = sprintf( "%s %d: %s( %s )", 
  1501.                               get_source_file_name(x[1]), 
  1502.                               x[2],  
  1503.                               function_name( x[1] ),
  1504.                               arglist )
  1505.    }
  1506.  
  1507.    debug_display_info( popbuf, "Pel Debugger:  Call Stack" )
  1508. }
  1509.  
  1510. function my_debug_fun_call()
  1511. {
  1512.    local list[]
  1513.    local vars[]
  1514.    local x[]
  1515.    local argc     = 0
  1516.    local i        = 1
  1517.    local arglist  = ""
  1518.    local var_val  = ""
  1519.    local var_type = ""
  1520.  
  1521.    x = debug_get_frame( 1 )
  1522.  
  1523.    # x[1] is gid, x[2] is lineno, x[3] is argc, x[4] is param list
  1524.    # Create the list of function arguments
  1525.    argc = x[3]
  1526.    split( x[4], list, ";" )   # list[1] = parameters, list[2] = local vars
  1527.    split( list[1], vars )
  1528.    for (i = 1; i <= argc; i++)
  1529.    {
  1530.       var_val = debug_get_stack_var( 1, i )
  1531.       var_type = typeof( var_val )
  1532.  
  1533.       if ( var_type == "string" || var_type == "regular expression" )
  1534.          var_val = "\"" var_val "\""
  1535.  
  1536.       if ( var_val )
  1537.          {
  1538.          arglist = arglist vars[i] "=" var_val
  1539.  
  1540.          if ( i != argc )
  1541.             arglist = arglist ", "
  1542.          }
  1543.    }
  1544.  
  1545.    cvdebug( "%s %d: %s( %s )", 
  1546.             get_source_file_name(x[1]), 
  1547.             x[2],  
  1548.             function_name( x[1] ),
  1549.             arglist )
  1550. }
  1551.  
  1552. # displays type/value of named var 
  1553. global function debug_query_var_info( var )
  1554. {
  1555.    local type     = ""
  1556.    local i        = 0
  1557.    local value    = 0
  1558.    local var_fid  = 0
  1559.    local info[]
  1560.    local str
  1561.  
  1562.    if ( !var )
  1563.       {
  1564.       str = symbol_under_cursor()
  1565.       var = prompt_history( "DEBUG_QUERY", "Query pel var:  ", str, str ? FALSE : TRUE, 1, "debug_query_prompt" )
  1566.       }
  1567.  
  1568.    if ( var )
  1569.       {
  1570.       i = debug_find_stvar( var, 1 )
  1571.    
  1572.       if ( i != 0 )
  1573.          {
  1574.          value = debug_get_stack_var( 1, i )
  1575.          type = typeof( value )
  1576.          }
  1577.       else
  1578.          {
  1579.          # try for a var local to the file
  1580.          var_fid = function_id( path_fname(debug_filename) ":" var )
  1581.  
  1582.          # else see if its a global var
  1583.          if ( !var_fid )
  1584.             var_fid = function_id( var )
  1585.  
  1586.          if ( var_fid )
  1587.             {
  1588.             # is it a user function id?
  1589.             if ( var_fid >= 1000 && var_fid <= 2999 )
  1590.                {
  1591.                value = var_fid
  1592.                type = typeof( var_fid )
  1593.                }
  1594.             else
  1595.                {
  1596.                # switch context in case its buffer_filename, etc
  1597.                set_user_window()
  1598.                value = execute_function( var_fid )
  1599.                set_debug_window()
  1600.  
  1601.                type = typeof( value )
  1602.                }
  1603.             }
  1604.          }
  1605.  
  1606.       if ( type )
  1607.          {
  1608.          if ( type == "string" )
  1609.             value = "\"" value "\""
  1610.          
  1611.          if ( type == "array" )
  1612.             display_array( value )
  1613.          else
  1614.             {
  1615.             info[ 1 ] = type " " var " : " value
  1616.             debug_display_info( info, "Pel Debugger:  Inspector" )
  1617.             }
  1618.          }
  1619.       else
  1620.          beep()
  1621.  
  1622.       }
  1623. }
  1624.  
  1625. global function debug_lmouse_double_click()
  1626. {
  1627.    local var = ""
  1628.  
  1629.    if ( current_window == debug_window )
  1630.       {
  1631.       var = symbol_under_cursor()
  1632.  
  1633.       if ( var && debug_gid && mouse_event_x >= 1 )
  1634.          debug_query_var_info( var )
  1635.  
  1636.       else if ( mouse_event_x < 1 )
  1637.          bp_line()
  1638.       }
  1639. }
  1640.  
  1641.  
  1642. local function debug_display_info( info, title )
  1643. {
  1644.    local   i      = ""
  1645.    local   width  = 30
  1646.    local   dhArray
  1647.  
  1648.    # check argument type
  1649.    if ( typeof( info ) != "array" )
  1650.       return
  1651.  
  1652.    if ( !title )
  1653.       title = "Pel Debugger"
  1654.  
  1655.    # create a dialog box for the list
  1656.    dhArray = create_selection_dialog( title, width )
  1657.    set_dialog_item( dhArray, DI_OK, DAC_HIDE)
  1658.  
  1659.    # insert the array contents
  1660.    for ( i in info )
  1661.    {
  1662.       set_dialog_item( dhArray, IDL_LIST, DAC_ADD_ITEM, info[i] )
  1663.    }
  1664.  
  1665.    begin_dialog(dhArray)
  1666. }
  1667.  
  1668. global function debug_local_variables()
  1669. {
  1670.    local list[]
  1671.    local vars[]
  1672.    local local_list[]
  1673.  
  1674.    local type           = ""
  1675.    local value          = ""
  1676.    local pad            = 0
  1677.    local frame          = 0
  1678.    local n              = 0
  1679.    local i              = 1
  1680.    local j              = 1
  1681.    local longest_var    = 0
  1682.    local longest_type   = 0
  1683.  
  1684.    if ( (frame = debug_get_frame(1)) )
  1685.    {
  1686.       split( frame[4], vars, ";" )      # frame[4] is the parameter;local list
  1687.       n = split( vars[1], list )        # vars[1] is the parameters
  1688.  
  1689.       longest_var = 0
  1690.       for (i = 1; i <= n; i++)
  1691.          longest_var = max( length( list[i] ), longest_var )
  1692.  
  1693.       longest_var += 5
  1694.  
  1695.       longest_type = 0
  1696.       for (i = 1; i <= n; i++) 
  1697.          longest_type = max( length( typeof(list[i]) ), longest_type )
  1698.  
  1699.       longest_type += 5
  1700.  
  1701.       j = 1
  1702.       for (i = 1; i <= n; i++,j++)
  1703.          {
  1704.          value = debug_get_stack_var( 1, i )
  1705.          type  = typeof( value )
  1706.  
  1707.          if ( type == "string" && value == "" )
  1708.             value = "\"\""
  1709.  
  1710.          local_list[ j ] = sprintf( "%s%s %s%s : %s", 
  1711.                                     type, 
  1712.                                     strrepeat(" ", longest_type - length(type) ), 
  1713.                                     list[i],
  1714.                                     strrepeat(" ", longest_var - length(list[i]) ),
  1715.                                     value )
  1716.          }
  1717.  
  1718.       n = split( vars[2], list )        # vars[2] is the locals
  1719.       longest_var = 0
  1720.       for (i = 1; i <= n; i++)
  1721.          longest_var = max( length( list[i] ), longest_var )
  1722.  
  1723.       longest_var += 5
  1724.  
  1725.       longest_type = 0
  1726.       for (i = 1; i <= n; i++)
  1727.          longest_type = max( length( typeof(list[i]) ), longest_type )
  1728.  
  1729.       longest_type += 5
  1730.  
  1731.       for (i = 1; i <= n; i++,j++)
  1732.          {
  1733.          value = debug_get_stack_var( 1, -i )
  1734.          type  = typeof( value )
  1735.  
  1736.          if ( type == "string" && value == "" )
  1737.             value = "\"\""
  1738.  
  1739.          local_list[ j ] = sprintf( "%s%s %s%s : %s", 
  1740.                                     type, 
  1741.                                     strrepeat(" ", longest_type - length(type) ), 
  1742.                                     list[i],
  1743.                                     strrepeat(" ", longest_var - length(list[i]) ),
  1744.                                     value )
  1745.          }
  1746.  
  1747.    }
  1748.    debug_display_info( local_list, "Pel Debugger:  Local Variables" )
  1749. }
  1750.  
  1751. local function debug_calc_functions()
  1752. {
  1753.    local i
  1754.    local j
  1755.  
  1756.    local sorted_global_funs[]
  1757.    local sorted_local_funs[]
  1758.  
  1759.    local global_funs = symbol_match( "", 0x4 )  
  1760.    local local_funs  = symbol_match( "", 0x10 ) 
  1761.  
  1762.    local fun_list[]
  1763.  
  1764.    message( "Working..." )
  1765.  
  1766.    # sort global functions
  1767.    for ( i in global_funs )
  1768.       sorted_global_funs[ global_funs[ i ] ] = i
  1769.  
  1770.    # add globals to info list
  1771.    j = 1
  1772.    for ( i in sorted_global_funs )
  1773.       fun_list[ j++ ] = i
  1774.  
  1775.    # sort local functions
  1776.    for ( i in local_funs )
  1777.       sorted_local_funs[ local_funs[ i ] ] = i
  1778.  
  1779.    # append locals to info list
  1780.    for ( i in sorted_local_funs )
  1781.       fun_list[ j++ ] = i
  1782.  
  1783.    return fun_list
  1784. }
  1785.  
  1786. global function my_debug_functions()
  1787. {
  1788.    debug_display_info( debug_calc_functions(), "Pel Debugger:  User Functions" ) 
  1789. }
  1790.  
  1791. #
  1792. # List Breakpoints
  1793. #
  1794. global function my_debug_bl()
  1795. {
  1796.    local    i        
  1797.    local    j        
  1798.    local    info[]
  1799.    
  1800.    j = 0
  1801.    for ( i in debug_fun_breakpoint_names )  
  1802.       info[ j + 1 ] = sprintf("%4d %s %s", 
  1803.                               j++, 
  1804.                               and(debug_fun_bp_types[i],BP_ENABLED) ? "Enabled " : "Disabled", 
  1805.                               debug_fun_breakpoint_names[i] )
  1806.  
  1807.    debug_display_info( info, "Pel Debugger:  Breakpoint List" )
  1808. }
  1809.  
  1810. local lastPath = "*.pel"
  1811.  
  1812. global function debug_open()
  1813. {
  1814.    local fileArray[]
  1815.    local fileToOpen
  1816.    local str
  1817.    local file
  1818.    local mode
  1819.    
  1820.    #  if infileToOpen is specified use it otherwise use 
  1821.    #  use the last path that was used.
  1822.    fileToOpen = open_dialog( lastPath, "Open" )
  1823.    
  1824.    split( fileToOpen, fileArray, ";" )
  1825.    file = fileArray[ 2 ]
  1826.  
  1827.    if ( file )
  1828.       {
  1829.       str = buildpath( file )
  1830.  
  1831.       mode = filemode(str)
  1832.       if ( str && mode != -1 && mode != _SUBDIR )
  1833.          {
  1834.          lastPath = path_path( str ) "*.pel"
  1835.  
  1836.          debug_view( str )
  1837.          }
  1838.       else
  1839.          beep()
  1840.       }
  1841. }
  1842.  
  1843. local DI_ABLE_BUTTON       = DI_NEXT_BUTTON   
  1844. local DI_CLEAR_BUTTON      = DI_PREV_BUTTON   
  1845. local DI_CLEAR_ALL_BUTTON  = DI_STOP_BUTTON   
  1846.  
  1847. local function debug_create_bl_dlg()
  1848. {
  1849.    local dlgid
  1850.    local newtitle
  1851.    local id = 1
  1852.    local callbackid = function_id( "debug_bl_callback" )
  1853.  
  1854.    dlgid = create_mdialog( callbackid, 0, DLG_LIST_DIALOG, resource_dll )
  1855.  
  1856.    set_dialog_item( dlgid, DI_GOTO_BUTTON,    DAC_DISABLE )
  1857.  
  1858.    add_dialog_item( dlgid, DI_STOP_BUTTON,      DCTRL_PUSH_BUTTON )
  1859.    add_dialog_item( dlgid, DI_CLEAR_ALL_BUTTON, DCTRL_PUSH_BUTTON )
  1860.  
  1861.    add_dialog_item( dlgid, IDL_LIST, DCTRL_LIST_BOX )
  1862.    
  1863.    # add items for the buttons. Since the buttons are disabled the assumed type
  1864.    # is incorrect so we must explicitly tell the dialog manager what type these
  1865.    # controls are.
  1866.    add_dialog_item( dlgid, DI_GOTO_BUTTON,      DCTRL_DEFAULT_PUSH_BUTTON  )
  1867.    add_dialog_item( dlgid, DI_CLEAR_BUTTON,     DCTRL_PUSH_BUTTON          )
  1868.    add_dialog_item( dlgid, DI_ABLE_BUTTON,      DCTRL_PUSH_BUTTON          ) 
  1869.    add_dialog_item( dlgid, DI_CLEAR_ALL_BUTTON, DCTRL_PUSH_BUTTON          )
  1870.    add_dialog_item( dlgid, DI_HELP,             DCTRL_PUSH_BUTTON          )
  1871.    add_dialog_item( dlgid, IDL_LIST,            DCTRL_LIST_BOX             )
  1872.    add_dialog_item( dlgid, IDB_CLOSE_BTN,       DCTRL_PUSH_BUTTON          )
  1873.  
  1874.    set_dialog_item( dlgid, DI_ABLE_BUTTON,      DAC_TEXT, "~Disable"       )
  1875.    set_dialog_item( dlgid, DI_CLEAR_BUTTON,     DAC_TEXT, "~Clear"         )
  1876.    set_dialog_item( dlgid, DI_CLEAR_ALL_BUTTON, DAC_TEXT, "Clear ~all"     )
  1877.  
  1878.    set_dialog_window( dlgid, DWC_TITLE, "Pel Debugger Breakpoints" )
  1879.  
  1880. #   attach_help(help_file, dlgid)
  1881.  
  1882.    return dlgid
  1883. }
  1884.  
  1885. local bl_hdlg = 0
  1886. local function update_bl( bpindex )
  1887. {
  1888.    local j           = 0
  1889.    local i           = 0
  1890.    local info        = ""
  1891.    local num_items   = 0
  1892.  
  1893.    if ( !bl_hdlg )
  1894.       {
  1895.       bl_hdlg = debug_create_bl_dlg()
  1896.       set_debug_window()
  1897.       }
  1898.  
  1899.    set_dialog_item( bl_hdlg, IDL_LIST, DAC_CLEAR_LIST )
  1900.  
  1901.    j = 0
  1902.    for ( i in debug_fun_breakpoint_names )  
  1903.       {
  1904.       info = sprintf(   "%4d %s %s", 
  1905.                         j++, 
  1906.                         and(debug_fun_bp_types[i],BP_ENABLED) \
  1907.                            ? "Enabled " \
  1908.                            : "Disabled", 
  1909.                         debug_fun_breakpoint_names[i] )
  1910.    
  1911.       set_dialog_item( bl_hdlg, IDL_LIST, DAC_ADD_ITEM, info )
  1912.       }
  1913.    
  1914.    if ( bpindex >= 0 )
  1915.       {
  1916.       num_items = query_dialog_item( bl_hdlg, IDL_LIST, DAC_COUNT_ITEMS )
  1917.  
  1918.       if ( bpindex < num_items )
  1919.          set_dialog_item( bl_hdlg, IDL_LIST, DAC_SELECT_INDEX, bpindex+0 )
  1920.       else 
  1921.          set_dialog_item( bl_hdlg, IDL_LIST, DAC_SELECT_INDEX, num_items-1 )
  1922.       }
  1923.    else
  1924.       set_dialog_item( bl_hdlg, IDL_LIST, DAC_SELECT_INDEX, 0 )
  1925.  
  1926.    # update breakpoints
  1927.    update_bp_marks()
  1928. }
  1929.  
  1930. global function debug_breakpoint_list()
  1931. {
  1932.    local    i        
  1933.    local    j        
  1934.    local    info[]
  1935.  
  1936.    if ( !bl_hdlg )
  1937.       bl_hdlg = debug_create_bl_dlg()
  1938.  
  1939.    update_bl()
  1940.  
  1941.    begin_dialog( bl_hdlg )
  1942. }
  1943.  
  1944. global function debug_bl_callback()
  1945. {
  1946.    local j
  1947.    local able_str
  1948.    local bpindex
  1949.    local gid
  1950.    local file
  1951.    local data[]
  1952.    local pos
  1953.    local str
  1954.    local line
  1955.    local ret_val = DRC_CONTINUE
  1956.  
  1957.    if ( callback_msg == DM_SET_FOCUS && callback_index != IDL_LIST )
  1958.       set_dialog_item( callback_dialog_handle, IDL_LIST, DAC_SETFOCUS )
  1959.  
  1960.    else if ( callback_msg == DM_INIT )
  1961.       set_dialog_item( callback_dialog_handle, IDL_LIST, DAC_SELECT_INDEX, 0 )
  1962.  
  1963.    else if ( callback_msg == DM_SELECT )
  1964.    {
  1965.       bpindex = query_dialog_item( callback_dialog_handle, IDL_LIST, DAC_SELECT_INDEX )
  1966.  
  1967.       if ( bpindex != -1 )
  1968.       {
  1969.          gid = bpindex_to_gid( bpindex )
  1970.  
  1971.          if ( debug_fun_breakpoints[ gid ] )
  1972.             set_dialog_item( callback_dialog_handle, DI_GOTO_BUTTON,    DAC_ENABLE )
  1973.          else
  1974.             set_dialog_item( callback_dialog_handle, DI_GOTO_BUTTON,    DAC_DISABLE )
  1975.  
  1976.          if ( and( debug_fun_bp_types[gid], BP_ENABLED ) )
  1977.             able_str = "~Disable"
  1978.          else
  1979.             able_str = "~Enable"
  1980.  
  1981.          set_dialog_item( callback_dialog_handle, DI_ABLE_BUTTON,       DAC_ENABLE ) 
  1982.          set_dialog_item( callback_dialog_handle, DI_CLEAR_BUTTON,      DAC_ENABLE )
  1983.          set_dialog_item( callback_dialog_handle, DI_CLEAR_ALL_BUTTON,  DAC_ENABLE )
  1984.  
  1985.          set_dialog_item( callback_dialog_handle, DI_ABLE_BUTTON, DAC_TEXT, able_str )
  1986.       }
  1987.       else
  1988.       {
  1989.          set_dialog_item( callback_dialog_handle, DI_GOTO_BUTTON,       DAC_DISABLE )
  1990.          set_dialog_item( callback_dialog_handle, DI_ABLE_BUTTON,       DAC_DISABLE ) 
  1991.          set_dialog_item( callback_dialog_handle, DI_CLEAR_BUTTON,      DAC_DISABLE )
  1992.          set_dialog_item( callback_dialog_handle, DI_CLEAR_ALL_BUTTON,  DAC_DISABLE )
  1993.       }
  1994.    }
  1995.    else if ( callback_msg == DM_CLICK || callback_msg == DM_DOUBLE_CLICK )
  1996.    {
  1997.       ret_val = DRC_MSG_PROCESSED
  1998.  
  1999.       bpindex  = query_dialog_item( callback_dialog_handle, IDL_LIST, DAC_SELECT_INDEX )
  2000.       gid      = bpindex_to_gid( bpindex )
  2001.  
  2002.       if ( callback_index == DI_GOTO_BUTTON && debug_fun_breakpoints[gid] > 0 )
  2003.       {
  2004.          str = query_dialog_item( callback_dialog_handle, IDL_LIST, DAC_SELECT_ITEM )
  2005.  
  2006.          # parse out the filename
  2007.          str = suffix( str, length(str) - rindex(str, " ") )
  2008.  
  2009.          pos = rindex( str, ":" )
  2010.          file = prefix( str, pos - 1 )
  2011.          line = suffix( str, length(str) - pos )
  2012.  
  2013.          debug_view( file, line )
  2014.       }
  2015.       else if ( callback_index == DI_ABLE_BUTTON )
  2016.       {
  2017.          if ( bpindex >= 0 )
  2018.          {
  2019.             able_str = query_dialog_item( callback_dialog_handle, DI_ABLE_BUTTON, DAC_TEXT )
  2020.    
  2021.             if ( able_str == "Enable" )
  2022.                be( bpindex )
  2023.             else
  2024.                bd( bpindex )
  2025.          }
  2026.       }
  2027.       else if ( callback_index == DI_CLEAR_BUTTON )
  2028.       {
  2029.          if ( bpindex >= 0 )
  2030.             bc( bpindex )
  2031.       }
  2032.       else if ( callback_index == DI_CLEAR_ALL_BUTTON )
  2033.          bc( -1 )
  2034.       else if ( callback_index == IDB_CLOSE_BTN )
  2035.          ret_val = DRC_EXIT
  2036.       else
  2037.          ret_val = dlg_list_callback()
  2038.    }
  2039.    else if (callback_msg == DM_CLOSE || callback_msg == DM_CANCEL )
  2040.       ret_val = DRC_EXIT;
  2041.    else 
  2042.       ret_val = dlg_list_callback()
  2043.  
  2044.    return ret_val
  2045. }
  2046.  
  2047.