home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / comm-manag.C < prev    next >
C/C++ Source or Header  |  1998-12-06  |  76KB  |  2,903 lines

  1. // $Id: comm-manag.C,v 1.240.4.2 1998/12/06 15:36:18 zeller Exp $
  2. // GDB communication manager
  3.  
  4. // Copyright (C) 1995-1998 Technische Universitaet Braunschweig, Germany.
  5. // Written by Dorothea Luetkehaus <luetke@ips.cs.tu-bs.de>
  6. // and Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  7. // 
  8. // This file is part of DDD.
  9. // 
  10. // DDD is free software; you can redistribute it and/or
  11. // modify it under the terms of the GNU General Public
  12. // License as published by the Free Software Foundation; either
  13. // version 2 of the License, or (at your option) any later version.
  14. // 
  15. // DDD is distributed in the hope that it will be useful,
  16. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  18. // See the GNU General Public License for more details.
  19. // 
  20. // You should have received a copy of the GNU General Public
  21. // License along with DDD -- see the file COPYING.
  22. // If not, write to the Free Software Foundation, Inc.,
  23. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24. // 
  25. // DDD is the data display debugger.
  26. // For details, see the DDD World-Wide-Web page, 
  27. // `http://www.cs.tu-bs.de/softech/ddd/',
  28. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  29.  
  30. char comm_manager_rcsid[] =
  31.     "$Id: comm-manag.C,v 1.240.4.2 1998/12/06 15:36:18 zeller Exp $";
  32.  
  33. #ifdef __GNUG__
  34. #pragma implementation
  35. #endif
  36.  
  37. //-----------------------------------------------------------------------------
  38. // GDB communication manager
  39. // Name conventions:
  40. // ...OA  : an OAProc used in GDBAgent::on_answer
  41. // ...OAC : an OACProc used in GDBAgent::on_answer_completion()
  42. // ...HP  : A handler procedure; see HandlerL.h
  43. //-----------------------------------------------------------------------------
  44.  
  45. //-----------------------------------------------------------------------------
  46. #include "comm-manag.h"
  47.  
  48. #include "AppData.h"
  49. #include "Command.h"
  50. #include "DataDisp.h"
  51. #include "DispBuffer.h"
  52. #include "DispValue.h"
  53. #include "PosBuffer.h"
  54. #include "UndoBuffer.h"
  55. #include "SourceView.h"
  56. #include "TimeOut.h"
  57. #include "VoidArray.h"
  58. #include "bool.h"
  59. #include "buttons.h"
  60. #include "cmdtty.h"
  61. #include "cook.h"
  62. #include "cmdtty.h"
  63. #include "dbx-lookup.h"
  64. #include "ddd.h"
  65. #include "disp-read.h"
  66. #include "editing.h"
  67. #include "exit.h"
  68. #include "file.h"
  69. #include "history.h"
  70. #include "home.h"
  71. #include "index.h"
  72. #include "post.h"
  73. #include "question.h"
  74. #include "regexps.h"
  75. #include "settings.h"
  76. #include "shell.h"
  77. #include "string-fun.h"
  78. #include "version.h"
  79. #include "windows.h"
  80.  
  81. #include <ctype.h>
  82. #include <fstream.h>
  83.  
  84.  
  85. //-----------------------------------------------------------------------------
  86. // Data
  87. //-----------------------------------------------------------------------------
  88.  
  89. // True if a running command is being executed
  90. bool debuggee_running = false;
  91.  
  92.  
  93. //-----------------------------------------------------------------------------
  94. // Types
  95. //-----------------------------------------------------------------------------
  96.  
  97. // Shall we filter data from the answer?
  98. enum Filtering {NoFilter, TryFilter, Filter};
  99.  
  100. // Additional data given to every single command.
  101. class CmdData {
  102. public:
  103.     string      command;      // The command issued
  104.     string      undo_command;      // Undoing command, if any
  105.     bool        undo_is_exec;      // True if undoing command is exec command
  106.     Widget      origin;          // Origin of this command
  107.     Filtering   filter_disp;      // NoFilter:  do not filter displays.
  108.                   // TryFilter: do filter if present.
  109.                                   // Filter:    do filter.
  110.     DispBuffer* disp_buffer;      // Display filter.
  111.     PosBuffer*  pos_buffer;       // Position filter.
  112.     bool        new_exec_pos;     // CMD results in new exec position.
  113.     bool        new_frame_pos;    // CMD results in new frame position.
  114.     bool        set_frame_pos;    // True if frame is to be changed manually.
  115.     int         set_frame_arg;    // Argument: 0: reset, +/-N: move N frames
  116.     string      set_frame_func;   // Argument: new function
  117.     string      graph_cmd;      // Graph command
  118.     string      lookup_arg;      // Argument when looking up sources
  119.  
  120.     string      user_answer;      // Buffer for the complete answer
  121.     OQCProc     user_callback;      // User callback
  122.     void *      user_data;      // User data
  123.     bool        user_verbose;      // Flag as given to send_gdb_command()
  124.     bool        user_prompt;      // Flag as given to send_gdb_command()
  125.     bool        user_check;      // Flag as given to send_gdb_command()
  126.     bool        recorded;      // True if command was recorded
  127.  
  128.     bool        disabling_occurred; // Flag: GDB disabled displays
  129.  
  130.     XtIntervalId position_timer;  // Still waiting for partial position
  131.     XtIntervalId display_timer;   // Still waiting for partial display
  132.  
  133. private:
  134.     static void clear_origin(Widget w, XtPointer client_data, 
  135.                  XtPointer call_data);
  136.  
  137.     void add_destroy_callback()
  138.     {
  139.     if (origin != 0)
  140.         XtAddCallback(origin, XtNdestroyCallback, clear_origin, 
  141.               (XtPointer)this);
  142.     }
  143.  
  144.     void remove_destroy_callback()
  145.     {
  146.     if (origin != 0)
  147.         XtRemoveCallback(origin, XtNdestroyCallback, clear_origin,
  148.                  (XtPointer)this);
  149.     }
  150.  
  151. public:
  152.     // Constructor
  153.     CmdData (Widget orig = 0, Filtering filter = TryFilter)
  154.     : command(""),
  155.       undo_command(""),
  156.       undo_is_exec(true),
  157.       origin(orig),
  158.       filter_disp(filter),
  159.       disp_buffer(0),
  160.       pos_buffer(0),
  161.       new_exec_pos(false),
  162.       new_frame_pos(false),
  163.       set_frame_pos(false),
  164.       set_frame_arg(0),
  165.       set_frame_func(""),
  166.       graph_cmd(""),
  167.       lookup_arg(""),
  168.  
  169.       user_answer(""),
  170.       user_callback(0),
  171.       user_data(0),
  172.       user_verbose(true),
  173.       user_prompt(true),
  174.       user_check(true),
  175.       recorded(false),
  176.  
  177.       disabling_occurred(false),
  178.  
  179.       position_timer(0),
  180.       display_timer(0)
  181.     {
  182.     add_destroy_callback();
  183.     }
  184.  
  185.     // Destructor
  186.     ~CmdData ()
  187.     {
  188.     remove_destroy_callback();
  189.     delete disp_buffer;
  190.     delete pos_buffer;
  191.  
  192.     if (position_timer != 0)
  193.         XtRemoveTimeOut(position_timer);
  194.     if (display_timer != 0)
  195.         XtRemoveTimeOut(display_timer);
  196.     }
  197.  
  198. private:
  199.     CmdData(const CmdData&)
  200.     : command(""),
  201.       undo_command(""),
  202.       undo_is_exec(true),
  203.       origin(0),
  204.       filter_disp(TryFilter),
  205.       disp_buffer(0),
  206.       pos_buffer(0),
  207.       new_exec_pos(false),
  208.       new_frame_pos(false),
  209.       set_frame_pos(false),
  210.       set_frame_arg(0),
  211.       set_frame_func(""),
  212.       graph_cmd(""),
  213.       lookup_arg(""),
  214.  
  215.       user_answer(""),
  216.       user_callback(0),
  217.       user_data(0),
  218.       user_verbose(true),
  219.       user_prompt(true),
  220.       user_check(true),
  221.       recorded(false),
  222.  
  223.       disabling_occurred(false),
  224.  
  225.       position_timer(0),
  226.       display_timer(0)
  227.     {
  228.     assert(0);
  229.     }
  230.  
  231.     CmdData& operator = (const CmdData&)
  232.     {
  233.     assert(0); return *this;
  234.     }
  235. };
  236.  
  237. void CmdData::clear_origin(Widget w, XtPointer client_data, XtPointer)
  238. {
  239.     (void) w;            // Use it
  240.  
  241.     // The widget is being destroyed.  Remove all references.
  242.     CmdData *cmd_data = (CmdData *)client_data;
  243.     assert(w == cmd_data->origin);
  244.     cmd_data->origin = 0;
  245. }
  246.  
  247.  
  248. // Data given to extra commands.
  249. class ExtraData {
  250. public:
  251.     string   command;               // The command issued
  252.     StringArray extra_commands;           // The additional commands
  253.  
  254.     int      n_init;                   // # of initialization commands
  255.  
  256.     bool     refresh_initial_line;     // send 'info line' / `func'
  257.     bool     refresh_file;             // send 'file'
  258.     bool     refresh_line;             // send 'list'
  259.     bool     refresh_recent_files;     // get program info
  260.     bool     refresh_pwd;           // send 'pwd'
  261.     bool     refresh_class_path;       // send 'use'
  262.     bool     refresh_breakpoints;      // send 'info b'
  263.     bool     refresh_where;            // send 'where'
  264.     bool     refresh_frame;            // send 'frame'
  265.     bool     refresh_pc;               // refresh pc
  266.     bool     refresh_registers;        // send 'info registers'
  267.     bool     refresh_threads;          // send 'info threads'
  268.     bool     refresh_data;             // send 'display'
  269.     bool     refresh_user;             // send user-defined commands
  270.     bool     refresh_addr;             // send commands to get addresses
  271.     bool     refresh_disp_info;        // send 'info display'
  272.     bool     refresh_history_filename; // send 'show history filename'
  273.     bool     refresh_history_size;     // send 'show history size'
  274.     bool     refresh_setting;           // send 'show SETTING'
  275.     string   set_command;           // setting to update
  276.     bool     refresh_handle;           // send 'info handle SIGNAL'
  277.     string   break_arg;               // argument when setting breakpoint
  278.     int      n_refresh_data;           // # of data displays to refresh
  279.     int      n_refresh_user;           // # of user displays to refresh
  280.  
  281.     bool     config_frame;           // try 'frame'
  282.     bool     config_func;           // try 'func'
  283.     bool     config_run_io;           // try 'dbxenv run_io'
  284.     bool     config_print_r;           // try 'print -r'
  285.     bool     config_where_h;           // try 'where -h'
  286.     bool     config_display;           // try 'display'
  287.     bool     config_clear;           // try 'clear'
  288.     bool     config_handler;           // try 'help handler'
  289.     bool     config_pwd;           // try 'pwd'
  290.     bool     config_setenv;           // try 'help setenv'
  291.     bool     config_edit;           // try 'help edit'
  292.     bool     config_make;           // try 'help make'
  293.     bool     config_regs;           // try 'help regs'
  294.     bool     config_named_values;      // try 'print "ddd"'
  295.     bool     config_when_semicolon;    // try 'help when'
  296.     bool     config_delete_comma;      // try 'delete 4711 4712'
  297.     bool     config_err_redirection;   // try 'help run'
  298.     bool     config_givenfile;         // try 'help givenfile'
  299.     bool     config_cont_sig;          // try 'help cont'
  300.     bool     config_examine;           // try 'help examine'
  301.     bool     config_rerun;             // try 'help rerun'
  302.     bool     config_xdb;           // try XDB settings
  303.     bool     config_output;            // try 'output'
  304.     bool     config_program_language;  // try 'show language'
  305.  
  306.     OACProc  user_callback;           // callback
  307.     void     *user_data;           // user data
  308.  
  309.     ExtraData ()
  310.     : command(""),
  311.       n_init(0),
  312.       refresh_initial_line(false),
  313.       refresh_file(false),
  314.       refresh_line(false),
  315.       refresh_recent_files(false),
  316.       refresh_pwd(false),
  317.       refresh_class_path(false),
  318.       refresh_breakpoints(false),
  319.       refresh_where(false),
  320.       refresh_frame(false),
  321.       refresh_pc(false),
  322.       refresh_registers(false),
  323.       refresh_threads(false),
  324.       refresh_data(false),
  325.       refresh_user(false),
  326.       refresh_addr(false),
  327.       refresh_disp_info(false),
  328.       refresh_history_filename(false),
  329.       refresh_history_size(false),
  330.       refresh_setting(false),
  331.       set_command(""),
  332.       refresh_handle(false),
  333.       break_arg(""),
  334.       n_refresh_data(0),
  335.       n_refresh_user(0),
  336.  
  337.       config_frame(false),
  338.       config_func(false),
  339.       config_run_io(false),
  340.       config_print_r(false),
  341.       config_where_h(false),
  342.       config_display(false),
  343.       config_clear(false),
  344.       config_handler(false),
  345.       config_pwd(false),
  346.       config_setenv(false),
  347.       config_edit(false),
  348.       config_make(false),
  349.       config_regs(false),
  350.       config_named_values(false),
  351.       config_when_semicolon(false),
  352.       config_delete_comma(false),
  353.       config_err_redirection(false),
  354.       config_givenfile(false),
  355.       config_cont_sig(false),
  356.       config_examine(false),
  357.       config_rerun(false),
  358.       config_xdb(false),
  359.       config_output(false),
  360.       config_program_language(false),
  361.  
  362.       user_callback(0),
  363.       user_data(0)
  364.     {}
  365. };
  366.  
  367. static void partial_answer_received(const string&, void *);
  368. static void command_completed(void *);
  369. static void extra_completed(const StringArray&, const VoidArray&, void *);
  370.  
  371. // Handle graph command in CMD, with WHERE_ANSWER being the GDB reply
  372. // to a `where 1' command; return true iff recognized
  373. static bool handle_graph_cmd(string& cmd, const string& where_answer,
  374.                  Widget origin, bool verbose, bool prompt);
  375.  
  376. // Handle output of initialization commands
  377. static void process_init(const string& answer, void *data = 0);
  378.  
  379. // Handle output of batch commands
  380. static void process_batch(const string& answer, void *data = 0);
  381.  
  382. // Process asynchronous GDB answers
  383. static void AsyncAnswerHP(Agent *, void *, void *);
  384.  
  385. static string print_cookie = "4711";
  386.  
  387.  
  388.  
  389. //-----------------------------------------------------------------------------
  390. // Symbol fixing
  391. //-----------------------------------------------------------------------------
  392.  
  393. // Replace all occurrences of `@N@' by N + the current breakpoint base;
  394. // Replace all occurrences of `@AUTO@' by the current command prefix.
  395. static void fix_symbols(string& cmd)
  396. {
  397. #if RUNTIME_REGEX
  398.     static regex rxnum("@[0-9]+@");
  399. #endif
  400.     int i;
  401.     while ((i = index(cmd, rxnum, "@")) >= 0)
  402.     {
  403.     int j = cmd.index('@', i + 1);
  404.     int base = SourceView::next_breakpoint_number() - 1;
  405.     cmd.at(i, j - i + 1) = itostring(atoi(cmd.chars() + i + 1) + base);
  406.     }
  407.  
  408.     cmd.gsub("@AUTO@", app_data.auto_command_prefix);
  409. }
  410.  
  411.  
  412. //-----------------------------------------------------------------------------
  413. // Initialization
  414. //-----------------------------------------------------------------------------
  415.  
  416. inline String str(String s)
  417. {
  418.     return s != 0 ? s : "";
  419. }
  420.  
  421. void start_gdb(bool config)
  422. {
  423.     // Register asynchronous answer handler
  424.     gdb->removeHandler(AsyncAnswer, AsyncAnswerHP);
  425.     gdb->addHandler(AsyncAnswer, AsyncAnswerHP);
  426.  
  427.     // Setup command data
  428.     CmdData* cmd_data     = new CmdData;
  429.     cmd_data->command     = "<init>";
  430.     cmd_data->filter_disp = NoFilter;      // No `display' output
  431.     cmd_data->pos_buffer  = new PosBuffer; // Find initial pos
  432.     cmd_data->user_prompt = true;
  433.  
  434.     ExtraData* extra_data = new ExtraData;
  435.     extra_data->command = "<init>";
  436.     StringArray cmds;
  437.     VoidArray dummy;
  438.  
  439.     // Fetch initialization commands
  440.     string init;
  441.     string settings;
  442.     switch (gdb->type())
  443.     {
  444.     case GDB:
  445.     init     = str(app_data.gdb_init_commands);
  446.     settings = str(app_data.gdb_settings);
  447.     break;
  448.  
  449.     case DBX:
  450.     init     = str(app_data.dbx_init_commands);
  451.     settings = str(app_data.dbx_settings);
  452.     break;
  453.  
  454.     case XDB:
  455.     init     = str(app_data.xdb_init_commands);
  456.     settings = str(app_data.xdb_settings);
  457.     break;
  458.  
  459.     case JDB:
  460.     init     = str(app_data.jdb_init_commands);
  461.     settings = str(app_data.jdb_settings);
  462.     break;
  463.  
  464.     case PYDB:
  465.     init     = str(app_data.pydb_init_commands);
  466.     settings = str(app_data.pydb_settings);
  467.     break;
  468.  
  469.     case PERL:
  470.     init     = str(app_data.perl_init_commands);
  471.     settings = str(app_data.perl_settings);
  472.     break;
  473.     }
  474.     string restart = str(app_data.restart_commands);
  475.  
  476.     // Place init commands in CMDS array
  477.     while (init != "")
  478.     {
  479.     string command = init.before('\n');
  480.     if (is_graph_cmd(command))
  481.     {
  482.         // To be handled later by DDD - enqueue in command queue
  483.         Command c(command, 0, process_batch);
  484.         c.priority = COMMAND_PRIORITY_INIT;
  485.         gdb_command(c);
  486.     }
  487.     else
  488.     {
  489.         // Process right now
  490.         cmds += command;
  491.     }
  492.     init = init.after('\n');
  493.     }
  494.     extra_data->n_init = cmds.size();
  495.     extra_data->refresh_recent_files = true;
  496.  
  497.     // Add some additional init commands with reply handling
  498.     switch (gdb->type())
  499.     {
  500.     case GDB:
  501.     cmds += "info line";    // Fails if no symbol table is loaded.
  502.     cmds += "list";        // But works just fine after a `list'.
  503.     cmds += "info line";
  504.     extra_data->refresh_initial_line = true;
  505.     cmds += "output " + print_cookie;
  506.     extra_data->config_output = true;
  507.     cmds += "show language";
  508.     extra_data->config_program_language = true;
  509.     cmds += "pwd";
  510.     extra_data->refresh_pwd = true;
  511.     cmds += "info breakpoints";
  512.     extra_data->refresh_breakpoints = true;
  513.     cmds += "show history filename";
  514.     extra_data->refresh_history_filename = true;
  515.     cmds += "show history size";
  516.     extra_data->refresh_history_size = true;
  517.     break;
  518.  
  519.     case DBX:
  520.     extra_data->refresh_initial_line = true;
  521.  
  522.     if (config)
  523.     {
  524.         cmds += "frame";
  525.         extra_data->config_frame = true;
  526.         cmds += "func";
  527.         extra_data->config_func = true;
  528.         cmds += "dbxenv run_io";
  529.         extra_data->config_run_io = true;
  530.         cmds += "print -r " + print_cookie;
  531.         extra_data->config_print_r = true;
  532.         cmds += "where -h";
  533.         extra_data->config_where_h = true;
  534.         cmds += "display";
  535.         extra_data->config_display = true;
  536.         cmds += "clear";
  537.         extra_data->config_clear = true;
  538.         cmds += "help handler";
  539.         extra_data->config_handler = true;
  540.         cmds += "pwd";
  541.         extra_data->config_pwd = true;
  542.         cmds += "help setenv";
  543.         extra_data->config_setenv = true;
  544.         cmds += "help edit";
  545.         extra_data->config_edit = true;
  546.         cmds += "help make";
  547.         extra_data->config_make = true;
  548.         cmds += "help regs";
  549.         extra_data->config_regs = true;
  550.         cmds += "print \"" DDD_NAME "\"";
  551.         extra_data->config_named_values = true;
  552.         cmds += "help when";
  553.         extra_data->config_when_semicolon = true;
  554.         cmds += "delete " + print_cookie + " " + print_cookie;
  555.         extra_data->config_delete_comma = true;
  556.         cmds += "help run";
  557.         extra_data->config_err_redirection = true;
  558.         cmds += "help givenfile";
  559.         extra_data->config_givenfile = true;
  560.         cmds += "help cont";
  561.         extra_data->config_cont_sig = true;
  562.         cmds += "help examine";
  563.         extra_data->config_examine = true;
  564.         cmds += "help rerun";
  565.         extra_data->config_rerun = true;
  566.         cmds += "language";
  567.         extra_data->config_program_language = true;
  568.     }
  569.  
  570.     cmds += "sh pwd";
  571.     extra_data->refresh_pwd = true;
  572.     cmds += "file";
  573.     extra_data->refresh_file = true;
  574.     cmds += "list";
  575.     extra_data->refresh_line = true;
  576.     cmds += "status";
  577.     extra_data->refresh_breakpoints = true;
  578.     break;
  579.  
  580.     case XDB:
  581.     cmds += "L";
  582.     extra_data->refresh_initial_line = true;
  583.  
  584.     if (config)
  585.     {
  586.         cmds += "tm";
  587.         extra_data->config_xdb = true;
  588.     }
  589.     cmds += "!pwd";
  590.     extra_data->refresh_pwd = true;
  591.     cmds += "lb";
  592.     extra_data->refresh_breakpoints = true;
  593.     break;
  594.  
  595.     case JDB:
  596.     extra_data->refresh_initial_line = true;
  597.  
  598.     cmds += "use";
  599.     extra_data->refresh_class_path = true;
  600.     break;
  601.  
  602.     case PYDB:
  603.     extra_data->refresh_initial_line = true;
  604.  
  605.     cmds += "pwd";
  606.     extra_data->refresh_pwd = true;
  607.     cmds += "info breakpoints";
  608.     extra_data->refresh_breakpoints = true;
  609.     break;
  610.  
  611.     case PERL:
  612.     // Perl starts immediately with the execution.
  613.     cmd_data->new_exec_pos = true;
  614.  
  615.     cmds += gdb->pwd_command();
  616.     extra_data->refresh_pwd = true;
  617.     cmds += "L";
  618.     extra_data->refresh_breakpoints = true;
  619.     break;
  620.     }
  621.  
  622.     while (dummy.size() < cmds.size())
  623.     dummy += (void *)0;
  624.  
  625.     gdb->start_plus (partial_answer_received,
  626.              command_completed,
  627.              cmd_data,
  628.              cmds,
  629.              dummy,
  630.              cmds.size(),
  631.              extra_completed,
  632.              (void *)extra_data);
  633.  
  634.     // Enqueue restart and settings commands.  Since we're starting up
  635.     // and don't care for detailed diagnostics, we allow the GDB
  636.     // `source' command.
  637.     init_session(restart, settings, app_data.source_init_commands);
  638.  
  639.     // One last command to clear the delay, set up breakpoints and
  640.     // issue prompt
  641.     Command c("# reset");
  642.     c.priority = COMMAND_PRIORITY_INIT;
  643.     c.echo     = false;
  644.     c.verbose  = false;
  645.     c.prompt   = false;
  646.     c.check    = true;
  647.     gdb_command(c);
  648. }
  649.  
  650. struct InitSessionInfo {
  651.     string restart;
  652.     string settings;
  653.     string tempfile;
  654. };
  655.  
  656. static void SourceDoneCB(const string& answer, void *qu_data)
  657. {
  658.     InitSessionInfo *info = (InitSessionInfo *)qu_data;
  659.     unlink(info->tempfile);
  660.  
  661.     string a = downcase(answer);
  662.     if (a.contains(info->tempfile) && a.contains("error"))
  663.     {
  664.     // We've had an error while sourcing the file.  This keeps GDB
  665.     // from reading the entire file, so we issue commands the
  666.     // ordinary way.
  667.     init_session(info->restart, info->settings, false);
  668.     }
  669.  
  670.     delete info;
  671. }
  672.  
  673. // Enqueue init commands
  674. void init_session(const string& restart, const string& settings, 
  675.           bool try_source)
  676. {
  677.     string init_commands = restart + settings;
  678.  
  679.     InitSessionInfo *info = 0;
  680.  
  681.     if (try_source && !remote_gdb() && gdb->type() == GDB)
  682.     {
  683.     // Source start-up commands from temp file
  684.     info = new InitSessionInfo;
  685.     info->restart  = restart;
  686.     info->settings = settings;
  687.     info->tempfile = tmpnam(0);
  688.  
  689.     string file_commands = "";
  690.  
  691.     {
  692.         ofstream os(info->tempfile);
  693.         while (init_commands != "")
  694.         {
  695.         string cmd = init_commands.before('\n');
  696.         init_commands = init_commands.after('\n');
  697.  
  698.         if (is_file_cmd(cmd, gdb) || is_core_cmd(cmd) || 
  699.             cmd.contains("set confirm", 0))
  700.         {
  701.             // Use this command the ordinary way
  702.             file_commands += cmd + "\n";
  703.         }
  704.         else
  705.         {
  706.             // Source this command
  707.             fix_symbols(cmd);
  708.             if (is_graph_cmd(cmd))
  709.             add_auto_command_prefix(cmd);
  710.             os << cmd << "\n";
  711.         }
  712.         }
  713.     }
  714.  
  715.     init_commands = file_commands;
  716.     }
  717.  
  718.     // Process all start-up commands (load file, etc.)
  719.     while (init_commands != "")
  720.     {
  721.     Command c(init_commands.before('\n'), Widget(0), OQCProc(0));
  722.     c.priority = COMMAND_PRIORITY_INIT;
  723.     if (is_file_cmd(c.command, gdb) || is_core_cmd(c.command))
  724.     {
  725.         // Give feedback on the files used and their state
  726.         c.verbose = true;
  727.         c.echo    = true;
  728.         c.prompt  = true;
  729.         c.check   = true;
  730.     }
  731.     else if (gdb->type() == JDB && is_use_cmd(c.command))
  732.     {
  733.         c.check = true;
  734.     }
  735.  
  736.     // Translate breakpoint numbers to the current base.
  737.     fix_symbols(c.command);
  738.     gdb_command(c);
  739.  
  740.     init_commands = init_commands.after('\n');
  741.     }
  742.  
  743.     if (info != 0)
  744.     {
  745.     // Source remaining commands (settings, etc.)
  746.     Command c("source " + info->tempfile, Widget(0), 
  747.           SourceDoneCB, (void *)info);
  748.     c.priority = COMMAND_PRIORITY_INIT;
  749.     c.check    = true;
  750.     gdb_command(c);
  751.     }
  752. }
  753.  
  754.  
  755.  
  756. //-----------------------------------------------------------------------------
  757. // Send the CMD to GDB, without any special processing.
  758. //-----------------------------------------------------------------------------
  759.  
  760. void send_gdb_ctrl(string cmd, Widget origin)
  761. {
  762.     CmdData* cmd_data      = new CmdData(origin, TryFilter);
  763.     cmd_data->command      = cmd;
  764.     cmd_data->disp_buffer  = new DispBuffer;
  765.     cmd_data->pos_buffer   = new PosBuffer;
  766.     cmd_data->new_exec_pos = true;
  767.     cmd_data->origin       = origin;
  768.  
  769.     if (cmd == '\004' && gdb_input_at_prompt)
  770.     gdb_is_exiting = true;
  771.  
  772.     bool send_ok = gdb->send_user_ctrl_cmd(cmd, cmd_data);
  773.     if (!send_ok)
  774.     post_gdb_busy(origin);
  775. }
  776.  
  777.  
  778.  
  779. //-----------------------------------------------------------------------------
  780. // Handle DDD commands
  781. //-----------------------------------------------------------------------------
  782.  
  783. // Do internal command; return reply
  784. string internal_command(const string& command)
  785. {
  786.     if (command.contains("graph history ", 0))
  787.     {
  788.     string name = command.after("history ");
  789.     strip_space(name);
  790.     return undo_buffer.display_history(name);
  791.     }
  792.  
  793.     return "";            // Nothing
  794. }
  795.  
  796. bool is_internal_command(const string& command)
  797. {
  798.     return command.contains("graph history ", 0);
  799. }
  800.  
  801. void internal_command(const string& command, OQCProc callback, void *data,
  802.               bool echo, bool verbose, bool do_prompt)
  803. {
  804.     if (echo && verbose)
  805.     gdb_out(command + "\n");
  806.  
  807.     string answer = internal_command(command);
  808.  
  809.     if (verbose)
  810.     {
  811.     // Show answer
  812.     _gdb_out(answer);
  813.     }
  814.  
  815.     if (callback != 0)
  816.     {
  817.     // Invoke user-defined callback
  818.     callback(answer, data);
  819.     }
  820.  
  821.     if (do_prompt)
  822.     prompt();
  823. }
  824.  
  825.  
  826. //-----------------------------------------------------------------------------
  827. // Send user command to GDB
  828. //-----------------------------------------------------------------------------
  829.  
  830. // True iff last command was cancelled
  831. static bool command_was_cancelled = false;
  832.  
  833. // Send user command CMD to GDB.  Invoke CALLBACK with DATA upon
  834. // completion of CMD; invoke EXTRA_CALLBACK with DATA when all extra
  835. // commands (see CHECK) are done.  If ECHO and either VERBOSE or
  836. // PROMPT are set, issue command in GDB console.  If VERBOSE is set,
  837. // issue answer in GDB console.  If PROMPT is set, issue prompt.  If
  838. // CHECK is set, add extra GDB commands to get GDB state.
  839. void send_gdb_command(string cmd, Widget origin,
  840.               OQCProc callback, OACProc extra_callback, void *data,
  841.               bool echo, bool verbose, bool prompt, bool check)
  842. {
  843.     string echoed_cmd = cmd;
  844.  
  845.     // Pass control commands unprocessed to GDB.
  846.     if (cmd.length() == 1 && iscntrl(cmd[0]))
  847.     {
  848.     // Don't issue control characters at the GDB prompt
  849.     if (verbose && !gdb->isReadyWithPrompt())
  850.     {
  851.         char c = cmd[0];
  852.  
  853.         if (c < ' ')
  854.         gdb_out(string("^") + char('@' + c));
  855.         else
  856.         gdb_out("^?");    // DEL
  857.     }
  858.  
  859.     if (cmd == "\004")
  860.         command_was_cancelled = true;
  861.  
  862.     send_gdb_ctrl(cmd, origin);
  863.     return;
  864.     }
  865.  
  866.     // Pass process I/O unprocessed to GDB.
  867.     if (!gdb->isReadyWithPrompt())
  868.     {
  869.     // GDB isn't ready; maybe this is input to the debugged
  870.     // process or an answer to a GDB confirmation question.
  871.  
  872.     bool send_ok = true;
  873.     if (gdb->isBusyOnQuestion())
  874.     {
  875.         // We have a question pending.  Don't interfere.
  876.         send_ok = false;
  877.     }
  878.     else
  879.     {
  880.         if (cmd == "no")
  881.         command_was_cancelled = true;
  882.  
  883.         // We do not wait for GDB output.  Pass CMD unprocessed to
  884.         // GDB, leaving current user_data unharmed.
  885.         cmd += '\n';
  886.         send_ok = gdb->send_user_ctrl_cmd(cmd);
  887.     }
  888.  
  889.     if (!send_ok)
  890.         post_gdb_busy(origin);
  891.     return;
  892.     }
  893.  
  894.     command_was_cancelled = false;
  895.  
  896.     // Setup extra command information
  897.     CmdData* cmd_data       = new CmdData(origin);
  898.     cmd_data->command       = cmd;
  899.     cmd_data->disp_buffer   = new DispBuffer;
  900.     cmd_data->pos_buffer    = new PosBuffer;
  901.     cmd_data->user_callback = callback;
  902.     cmd_data->recorded      = gdb->recording();
  903.  
  904.     ExtraData* extra_data = new ExtraData;
  905.     extra_data->command       = cmd;
  906.     extra_data->user_callback = extra_callback;
  907.     extra_data->user_data     = data;
  908.  
  909.  
  910.     // Breakpoints may change any time
  911.     if (gdb->has_volatile_breakpoints())
  912.     extra_data->refresh_breakpoints = true;
  913.  
  914.     // User command output may change any time
  915.     extra_data->refresh_user    = true;
  916.  
  917.     // Addresses may change any time
  918.     extra_data->refresh_addr    = true;
  919.  
  920.     // Any command may break the `undo' state
  921.     bool abort_undo = true;
  922.  
  923.     if (source_view->where_required())
  924.     {
  925.     extra_data->refresh_where = true;
  926.     extra_data->refresh_frame = true;
  927.     }
  928.  
  929.     if (source_view->register_required())
  930.     {
  931.     extra_data->refresh_registers = true;
  932.     }
  933.  
  934.     if (source_view->thread_required())
  935.     {
  936.     extra_data->refresh_threads = true;
  937.     }
  938.  
  939.     if (data_disp->count_data_displays() == 0 || 
  940.     !gdb->has_display_command())
  941.     {
  942.     // No displays
  943.     cmd_data->filter_disp = NoFilter;
  944.     }
  945.  
  946.     if (is_list_cmd(cmd))
  947.     {
  948.     string arg = cmd.after(rxwhite);
  949.     strip_space(arg);
  950.     if (arg == "" || 
  951.         arg.contains('-', 0) || 
  952.         arg.contains('+', 0) || 
  953.         arg.matches(rxlist_range))
  954.     {
  955.         // Ordinary `list', `list +', `list -', or `list N, M'.
  956.         // Leave as is.
  957.     }
  958.     else
  959.     {
  960.         // `list ARG'
  961.         if (have_source_window())
  962.         {
  963.         // Lookup ARG in source window only
  964.         switch (gdb->type())
  965.         {
  966.         case GDB:
  967.         case PYDB:
  968.             // Translate `list' to `info line'.
  969.             cmd = "info line " + arg;
  970.             break;
  971.  
  972.         case DBX:
  973.         case XDB:
  974.         case JDB:
  975.             // Just lookup ARG; ignore `list' output
  976.             verbose = false;
  977.             cmd_data->lookup_arg = arg;
  978.             break;
  979.  
  980.         case PERL:
  981.             // Perl `l' command issues a position anyway.
  982.             break;
  983.         }
  984.         }
  985.     }
  986.  
  987.     extra_data->refresh_breakpoints = false;
  988.     extra_data->refresh_where       = false;
  989.     extra_data->refresh_registers   = false;
  990.     extra_data->refresh_threads     = false;
  991.     extra_data->refresh_addr        = false;
  992.  
  993.     abort_undo = false;
  994.     }
  995.  
  996.     if (!check || 
  997.     gdb->recording() ||
  998.     is_nop_cmd(cmd) || 
  999.     is_graph_cmd(cmd) || 
  1000.     (gdb->type() == GDB && starts_recording(cmd)))
  1001.     {
  1002.     cmd_data->filter_disp = NoFilter;
  1003.  
  1004.     if (check)
  1005.     {
  1006.         delete cmd_data->pos_buffer;
  1007.         cmd_data->pos_buffer = 0;
  1008.     }
  1009.  
  1010.     if (check && is_define_cmd(cmd))
  1011.     {
  1012.         string name = cmd.after(rxwhite);
  1013.         strip_space(name);
  1014.  
  1015.         update_define_later(name);
  1016.         set_need_save_defines(true);
  1017.     }
  1018.  
  1019.     extra_data->refresh_breakpoints = ends_recording(cmd);
  1020.     extra_data->refresh_addr        = false;
  1021.     extra_data->refresh_user        = false;
  1022.     extra_data->refresh_where       = false;
  1023.     extra_data->refresh_frame       = false;
  1024.     extra_data->refresh_registers   = false;
  1025.     extra_data->refresh_threads     = false;
  1026.  
  1027.     if (is_graph_cmd(cmd))
  1028.     {
  1029.         cmd_data->graph_cmd = cmd;
  1030.     }
  1031.     else if (gdb->type() == GDB && starts_recording(cmd))
  1032.     {
  1033.         gdb->recording(true);
  1034.     }
  1035.  
  1036.     if (gdb->recording())
  1037.         echoed_cmd = cmd;
  1038.  
  1039.     abort_undo = false;
  1040.     }
  1041.     else if (is_file_cmd(cmd, gdb))
  1042.     {
  1043.     // File may change: display main() function and update displays
  1044.     bool is_reset_cmd = (cmd == "# reset");
  1045.     if (!is_reset_cmd)
  1046.         extra_data->refresh_initial_line = true;
  1047.  
  1048.     extra_data->refresh_data = true;
  1049.     extra_data->refresh_recent_files = true;
  1050.  
  1051.     if (gdb->has_display_command())
  1052.         extra_data->refresh_disp_info = true;
  1053.     
  1054.     switch (gdb->type())
  1055.     {
  1056.     case DBX:
  1057.         extra_data->refresh_file = true;
  1058.         extra_data->refresh_line = true;
  1059.         break;
  1060.  
  1061.     case PERL:
  1062.         if (!is_reset_cmd)
  1063.         cmd_data->new_exec_pos = true;
  1064.         extra_data->refresh_initial_line = false;
  1065.         break;
  1066.  
  1067.     case GDB:
  1068.     case XDB:
  1069.     case JDB:
  1070.     case PYDB:
  1071.         break;        // FIXME
  1072.     }
  1073.     }
  1074.     else if (is_single_display_cmd(cmd, gdb))
  1075.     {
  1076.     // No new displays
  1077.     cmd_data->filter_disp = NoFilter;
  1078.  
  1079.     // Breakpoints, Frames, Code and Registers won't change
  1080.     extra_data->refresh_breakpoints = false;
  1081.     extra_data->refresh_where       = false;
  1082.     extra_data->refresh_frame       = false;
  1083.     extra_data->refresh_registers   = false;
  1084.     extra_data->refresh_threads     = false;
  1085.     extra_data->refresh_addr        = false;
  1086.     }
  1087.     else if (is_data_cmd(cmd))
  1088.     {
  1089.     extra_data->refresh_data      = true;
  1090.  
  1091.     // Breakpoints, Frames, Code and Registers won't change
  1092.     extra_data->refresh_breakpoints = false;
  1093.     extra_data->refresh_where       = false;
  1094.     extra_data->refresh_frame       = false;
  1095.     extra_data->refresh_registers   = false;
  1096.     extra_data->refresh_threads     = false;
  1097.     extra_data->refresh_addr        = false;
  1098.     }
  1099.     else if (is_running_cmd(cmd, gdb) || is_pc_cmd(cmd))
  1100.     {
  1101.     // New displays and new exec position
  1102.     if (gdb->has_display_command())
  1103.         cmd_data->filter_disp = Filter;
  1104.     cmd_data->new_exec_pos = true;
  1105.     if (gdb->type() == DBX)
  1106.     {
  1107.         extra_data->refresh_file  = true;
  1108.         // extra_data->refresh_line  = true;
  1109.         if (gdb->has_frame_command())
  1110.         extra_data->refresh_frame = true;
  1111.     }
  1112.     if (is_pc_cmd(cmd))
  1113.     {
  1114.         extra_data->refresh_frame = true;
  1115.         extra_data->refresh_pc    = true;
  1116.     }
  1117.     if (!gdb->has_display_command())
  1118.         extra_data->refresh_data = true;
  1119.  
  1120. #if 0
  1121.     // Allow undoing `kill' and `run'
  1122.     if (is_run_cmd(cmd))
  1123.         cmd_data->undo_command = gdb->kill_command();
  1124.     else if (is_kill_cmd(cmd))
  1125.         cmd_data->undo_command = gdb->rerun_command();
  1126.     cmd_data->undo_is_exec = true;
  1127. #endif
  1128.  
  1129.     // Any later input is user interaction.
  1130.     gdb_input_at_prompt = false;
  1131.  
  1132.     // Debuggee should now be running
  1133.     debuggee_running = true;
  1134.     }
  1135.     else if (is_thread_cmd(cmd) || is_core_cmd(cmd))
  1136.     {
  1137.     // No new displays
  1138.     cmd_data->filter_disp   = NoFilter;
  1139.     cmd_data->new_frame_pos = true;
  1140.     cmd_data->new_exec_pos  = true;
  1141.  
  1142.     extra_data->refresh_breakpoints = is_thread_cmd(cmd);
  1143.     extra_data->refresh_where       = true;
  1144.     extra_data->refresh_frame       = true;
  1145.     extra_data->refresh_data        = true;
  1146.     extra_data->refresh_threads     = true;
  1147.     }
  1148.     else if (is_frame_cmd(cmd))
  1149.     {
  1150.     // No new displays
  1151.     cmd_data->filter_disp   = NoFilter;
  1152.     cmd_data->new_frame_pos = true;
  1153.  
  1154.     extra_data->refresh_breakpoints = false;
  1155.     extra_data->refresh_where       = false;
  1156.     extra_data->refresh_frame       = true;
  1157.     extra_data->refresh_registers   = false;
  1158.     extra_data->refresh_threads     = false;
  1159.     extra_data->refresh_data        = true;
  1160.  
  1161.     if (gdb->type() == DBX)
  1162.     {
  1163.         // We need to get the current file as well...
  1164.         extra_data->refresh_file  = true;
  1165.     }
  1166.     if (gdb->type() == JDB)
  1167.     {
  1168.         // Get the current frame via `where'
  1169.         extra_data->refresh_where = true;
  1170.     }
  1171.  
  1172.     abort_undo = false;
  1173.     }
  1174.     else if (is_assign_cmd(cmd, gdb))
  1175.     {
  1176.     // Update displays
  1177.     extra_data->refresh_data = true;
  1178.  
  1179.     // Addresses won't change
  1180.     extra_data->refresh_addr = false;
  1181.  
  1182.     // Set up appropriate undoing command
  1183.     string var = get_assign_variable(cmd);
  1184.     if (var != "")
  1185.     {
  1186.         string value = assignment_value(gdbValue(var));
  1187.         if (value != NO_GDB_ANSWER)
  1188.         {
  1189.         cmd_data->undo_command = gdb->assign_command(var, value);
  1190.         cmd_data->undo_is_exec = true;
  1191.         }
  1192.     }
  1193.     }
  1194.     else if (is_lookup_cmd(cmd))
  1195.     {
  1196.     if (gdb->type() == DBX)
  1197.     {
  1198.         // In DBX, `func' changes the stack frame
  1199.         cmd_data->new_frame_pos   = true;
  1200.         extra_data->refresh_frame = true;
  1201.         extra_data->refresh_file  = true;
  1202.         extra_data->refresh_line  = true;
  1203.     }
  1204.     extra_data->refresh_breakpoints = false;
  1205.     extra_data->refresh_where       = false;
  1206.     extra_data->refresh_registers   = false;
  1207.     extra_data->refresh_threads     = false;
  1208.     extra_data->refresh_addr        = false;
  1209.  
  1210.     if (!gdb->has_display_command())
  1211.         extra_data->refresh_data = true;
  1212.  
  1213.     abort_undo = false;
  1214.     }
  1215.     else if (is_cd_cmd(cmd))
  1216.     {
  1217.     extra_data->refresh_pwd         = true;
  1218.     extra_data->refresh_breakpoints = false;
  1219.     extra_data->refresh_where       = false;
  1220.     extra_data->refresh_frame       = false;
  1221.     extra_data->refresh_registers   = false;
  1222.     extra_data->refresh_threads     = false;
  1223.     extra_data->refresh_addr        = false;
  1224.  
  1225.     abort_undo = false;
  1226.     }
  1227.     else if (gdb->type() == JDB && is_use_cmd(cmd))
  1228.     {
  1229.     extra_data->refresh_class_path  = true;
  1230.     extra_data->set_command         = cmd;
  1231.     extra_data->refresh_breakpoints = false;
  1232.     extra_data->refresh_where       = false;
  1233.     extra_data->refresh_frame       = false;
  1234.     extra_data->refresh_registers   = false;
  1235.     extra_data->refresh_threads     = false;
  1236.     extra_data->refresh_addr        = false;
  1237.     }
  1238.     else if (is_setting_cmd(cmd))
  1239.     {
  1240.     get_settings(gdb->type());
  1241.     extra_data->refresh_setting     = true;
  1242.     extra_data->set_command         = cmd;
  1243.     extra_data->refresh_data        = false;
  1244.     extra_data->refresh_addr        = false;
  1245.     extra_data->refresh_breakpoints = false;
  1246.  
  1247.     if (gdb->type() == GDB && cmd.contains("history"))
  1248.     {
  1249.         // Refresh history settings, too
  1250.         extra_data->refresh_history_filename = true;
  1251.         extra_data->refresh_history_size     = true;
  1252.     }
  1253.  
  1254.     abort_undo = false;
  1255.     }
  1256.     else if (is_handle_cmd(cmd))
  1257.     {
  1258.     (void) get_signals(gdb->type());
  1259.     extra_data->refresh_handle      = true;
  1260.     extra_data->refresh_data        = false;
  1261.     extra_data->refresh_addr        = false;
  1262.     extra_data->refresh_breakpoints = false;
  1263.  
  1264.     abort_undo = false;
  1265.     }
  1266.     else if (is_quit_cmd(cmd))
  1267.     {
  1268.     gdb_is_exiting = true;
  1269.     }
  1270.     else if (is_break_cmd(cmd))
  1271.     {
  1272.     extra_data->break_arg = get_break_expression(cmd);
  1273.     extra_data->refresh_breakpoints = true;
  1274.  
  1275.     abort_undo = false;
  1276.     }
  1277.     else if (is_print_cmd(cmd, gdb))
  1278.     {
  1279.     // A printing command - be sure to abort current undo
  1280.     abort_undo = true;
  1281.  
  1282.     // Don't filter the print output
  1283.     cmd_data->filter_disp = NoFilter;
  1284.     }
  1285.     else if (is_other_builtin_cmd(cmd, gdb))
  1286.     {
  1287.     // Some other built-in command -- nothing special
  1288.     abort_undo = false;
  1289.     }
  1290.     else if (is_defined_cmd(cmd))
  1291.     {
  1292.     // User-defined command -- refresh everything
  1293.     if (gdb->has_display_command())
  1294.         cmd_data->filter_disp = Filter;
  1295.  
  1296.     cmd_data->new_frame_pos = true;
  1297.     cmd_data->new_exec_pos  = true;
  1298.  
  1299.     extra_data->refresh_breakpoints = true;
  1300.     extra_data->refresh_where       = true;
  1301.     extra_data->refresh_frame       = true;
  1302.     extra_data->refresh_data        = true;
  1303.     extra_data->refresh_threads     = true;
  1304.  
  1305.     // Any later input is user interaction.
  1306.     gdb_input_at_prompt = false;
  1307.     }
  1308.  
  1309.     if (undo_buffer.showing_earlier_state() && !cmd_data->new_exec_pos)
  1310.     {
  1311.     // Showing earlier state.  Don't update anything related to
  1312.     // program state.
  1313.     extra_data->refresh_where     = false;
  1314.     extra_data->refresh_frame     = false;
  1315.     extra_data->refresh_data      = false;
  1316.     extra_data->refresh_user      = false;
  1317.     extra_data->refresh_threads   = false;
  1318.     extra_data->refresh_registers = false;
  1319.     extra_data->refresh_addr      = false;
  1320.     }
  1321.  
  1322.     if (cmd_data->new_exec_pos
  1323.     || extra_data->refresh_frame 
  1324.     || extra_data->refresh_data)
  1325.     {
  1326.     // New program state: clear value cache
  1327.     clear_value_cache();
  1328.     DispValue::clear_type_cache();
  1329.     }
  1330.  
  1331.     if (!gdb->has_named_values() && is_print_cmd(cmd, gdb))
  1332.     {
  1333.     // The debugger `print NAME' does not prepend 'NAME = ' before
  1334.     // the value.  Fix this.
  1335.     cmd_data->user_answer = cmd.after(rxwhite) + " = ";
  1336.     }
  1337.  
  1338.     if (extra_data->refresh_frame && 
  1339.     !gdb->has_frame_command() && 
  1340.     gdb->type() != JDB)
  1341.     {
  1342.     // We have a backtrace window open, but DBX has no ``frame''
  1343.     // command to set the selected frame.  Use this hack instead.
  1344.     string arg_s = cmd.after(rxblanks_or_tabs);
  1345.  
  1346.     if (is_up_cmd(cmd) || is_down_cmd(cmd))
  1347.     {
  1348.         // Set the new selected frame from the `up'/`down'
  1349.         // argument.
  1350.  
  1351.         int arg;
  1352.         if (arg_s == "")
  1353.         arg = 1;
  1354.         else
  1355.         arg = get_positive_nr(arg_s);
  1356.         if (arg > 0)
  1357.         {
  1358.         cmd_data->set_frame_pos = true;
  1359.  
  1360.         int direction = 1;
  1361.         if (is_up_cmd(cmd))
  1362.             direction = -direction;
  1363.         if (gdb->type() == XDB)
  1364.             direction = -direction;
  1365.  
  1366.         cmd_data->set_frame_arg = direction * arg;
  1367.         }
  1368.     }
  1369.     else if (is_lookup_cmd(cmd))
  1370.     {
  1371.         // Switch to new function
  1372.         cmd_data->set_frame_pos = true;
  1373.         cmd_data->set_frame_func = arg_s;
  1374.     }
  1375.     else
  1376.     {
  1377.         // Make bottom frame the selected frame
  1378.         cmd_data->set_frame_pos = true;
  1379.         cmd_data->set_frame_arg = 0;
  1380.     }
  1381.  
  1382.     extra_data->refresh_frame = false;
  1383.  
  1384.     if (!gdb->has_display_command())
  1385.         extra_data->refresh_data = true;
  1386.     }
  1387.  
  1388.     if (!gdb->has_regs_command())
  1389.     {
  1390.     // No `regs' command => no refresh
  1391.     extra_data->refresh_registers = false;
  1392.     }
  1393.  
  1394.     if (gdb->type() != GDB && gdb->type() != JDB)
  1395.     {
  1396.     // No threads
  1397.     extra_data->refresh_threads = false;
  1398.     }
  1399.  
  1400.     if (gdb->type() == GDB && cmd_data->pos_buffer != 0)
  1401.     {
  1402.     // Filtering GDB output for current function and PC is rather
  1403.     // expensive.  Hence, we scan GDB output only if actually
  1404.     // required.
  1405.     cmd_data->pos_buffer->check_pc   = source_view->need_pc();
  1406.     cmd_data->pos_buffer->check_func = data_disp->need_scope();
  1407.     }
  1408.  
  1409.     if (echo && (verbose || prompt))
  1410.     {
  1411.     strip_auto_command_prefix(echoed_cmd);
  1412.     gdb_out(echoed_cmd + "\n");
  1413.     }
  1414.  
  1415.     if (abort_undo)
  1416.     undo_buffer.restore_current_state();
  1417.  
  1418.     StringArray cmds;
  1419.     VoidArray dummy;
  1420.  
  1421.     assert(extra_data->n_init == 0);
  1422.     assert(!extra_data->config_frame);
  1423.     assert(!extra_data->config_func);
  1424.     assert(!extra_data->config_run_io);
  1425.     assert(!extra_data->config_print_r);
  1426.     assert(!extra_data->config_where_h);
  1427.     assert(!extra_data->config_display);
  1428.     assert(!extra_data->config_clear);
  1429.     assert(!extra_data->config_handler);
  1430.     assert(!extra_data->config_pwd);
  1431.     assert(!extra_data->config_setenv);
  1432.     assert(!extra_data->config_edit);
  1433.     assert(!extra_data->config_make);
  1434.     assert(!extra_data->config_regs);
  1435.     assert(!extra_data->config_named_values);
  1436.     assert(!extra_data->config_when_semicolon);
  1437.     assert(!extra_data->config_delete_comma);
  1438.     assert(!extra_data->config_err_redirection);
  1439.     assert(!extra_data->config_givenfile);
  1440.     assert(!extra_data->config_cont_sig);
  1441.     assert(!extra_data->config_examine);
  1442.     assert(!extra_data->config_rerun);
  1443.     assert(!extra_data->config_xdb);
  1444.     assert(!extra_data->config_output);
  1445.     assert(!extra_data->config_program_language);
  1446.     
  1447.     // Setup additional trailing commands
  1448.     switch (gdb->type())
  1449.     {
  1450.     case GDB:
  1451.     if (extra_data->refresh_initial_line)
  1452.     {
  1453.         cmds += "info line";    // Fails if no symbol table is loaded.
  1454.         cmds += "list";        // But works just fine after a `list'.
  1455.         cmds += "info line";
  1456.     }
  1457.     if (extra_data->refresh_pwd)
  1458.         cmds += "pwd";
  1459.     assert(!extra_data->refresh_class_path);
  1460.     assert(!extra_data->refresh_file);
  1461.     assert(!extra_data->refresh_line);
  1462.     if (extra_data->refresh_breakpoints)
  1463.         cmds += "info breakpoints";
  1464.     if (extra_data->refresh_where)
  1465.         cmds += "where";
  1466.     if (extra_data->refresh_frame)
  1467.         cmds += gdb->frame_command();
  1468.     if (extra_data->refresh_registers)
  1469.         cmds += source_view->refresh_registers_command();
  1470.     if (extra_data->refresh_threads)
  1471.         cmds += "info threads";
  1472.     if (extra_data->refresh_data)
  1473.         extra_data->n_refresh_data = 
  1474.         data_disp->add_refresh_data_commands(cmds);
  1475.     if (extra_data->refresh_user)
  1476.         extra_data->n_refresh_user = 
  1477.         data_disp->add_refresh_user_commands(cmds);
  1478.     if (extra_data->refresh_disp_info)
  1479.         cmds += gdb->info_display_command();
  1480.     if (extra_data->refresh_history_filename)
  1481.         cmds += "show history filename";
  1482.     if (extra_data->refresh_history_size)
  1483.         cmds += "show history size";
  1484.     if (extra_data->refresh_setting)
  1485.         cmds += show_command(cmd, gdb->type());
  1486.     if (extra_data->refresh_handle)
  1487.     {
  1488.         string sig = cmd.after(rxwhite);
  1489.         sig = sig.before(rxwhite);
  1490.         if (sig == "all")
  1491.         sig = "";
  1492.         cmds += "info handle " + sig;
  1493.     }
  1494.     break;
  1495.  
  1496.     case DBX:
  1497.     if (extra_data->refresh_pwd)
  1498.         cmds += "pwd";
  1499.     assert(!extra_data->refresh_class_path);
  1500.     if (extra_data->refresh_file)
  1501.         cmds += "file";
  1502.     if (extra_data->refresh_line)
  1503.         cmds += "list";
  1504.     if (extra_data->refresh_breakpoints)
  1505.         cmds += "status";
  1506.     if (extra_data->refresh_where)
  1507.         cmds += "where";
  1508.     if (extra_data->refresh_frame)
  1509.         cmds += gdb->frame_command();
  1510.     assert (!extra_data->refresh_registers);
  1511.     assert (!extra_data->refresh_threads);
  1512.     if (extra_data->refresh_data)
  1513.         extra_data->n_refresh_data = 
  1514.         data_disp->add_refresh_data_commands(cmds);
  1515.     if (extra_data->refresh_user)
  1516.         extra_data->n_refresh_user = 
  1517.         data_disp->add_refresh_user_commands(cmds);
  1518.     if (extra_data->refresh_disp_info)
  1519.         cmds += gdb->info_display_command();
  1520.     assert (!extra_data->refresh_history_filename);
  1521.     assert (!extra_data->refresh_history_size);
  1522.     if (extra_data->refresh_setting)
  1523.         cmds += show_command(cmd, gdb->type());
  1524.     assert (!extra_data->refresh_handle);
  1525.     break;
  1526.  
  1527.     case XDB:
  1528.     if (extra_data->refresh_initial_line)
  1529.         cmds += "L";
  1530.     if (extra_data->refresh_pwd)
  1531.         cmds += "!pwd";
  1532.     assert(!extra_data->refresh_class_path);
  1533.     assert(!extra_data->refresh_file);
  1534.     assert(!extra_data->refresh_line);
  1535.     if (extra_data->refresh_breakpoints)
  1536.         cmds += "lb";
  1537.     if (extra_data->refresh_where)
  1538.         cmds += "t";
  1539.     if (extra_data->refresh_frame)
  1540.         cmds += gdb->frame_command();
  1541.     assert (!extra_data->refresh_registers);
  1542.     assert (!extra_data->refresh_threads);
  1543.     if (extra_data->refresh_data)
  1544.         extra_data->n_refresh_data = 
  1545.         data_disp->add_refresh_data_commands(cmds);
  1546.     if (extra_data->refresh_user)
  1547.         extra_data->n_refresh_user = 
  1548.         data_disp->add_refresh_user_commands(cmds);
  1549.     if (extra_data->refresh_disp_info)
  1550.         cmds += gdb->display_command();
  1551.     assert (!extra_data->refresh_history_filename);
  1552.     assert (!extra_data->refresh_history_size);
  1553.     assert (!extra_data->refresh_setting);
  1554.     assert (!extra_data->refresh_handle);
  1555.     break;
  1556.  
  1557.     case JDB:
  1558.     assert (!extra_data->refresh_pwd);
  1559.     if (extra_data->refresh_class_path)
  1560.         cmds += "use";
  1561.     assert(!extra_data->refresh_file);
  1562.     assert(!extra_data->refresh_line);
  1563.     if (extra_data->refresh_breakpoints)
  1564.         cmds += "clear";
  1565.     if (extra_data->refresh_where)
  1566.         cmds += "where";
  1567.     assert (!extra_data->refresh_registers);
  1568.     if (extra_data->refresh_threads)
  1569.         cmds += "threads";
  1570.     if (extra_data->refresh_data)
  1571.         extra_data->n_refresh_data = 
  1572.         data_disp->add_refresh_data_commands(cmds);
  1573.     if (extra_data->refresh_user)
  1574.         extra_data->n_refresh_user = 
  1575.         data_disp->add_refresh_user_commands(cmds);
  1576.     assert (!extra_data->refresh_history_filename);
  1577.     assert (!extra_data->refresh_history_size);
  1578.     assert (!extra_data->refresh_setting);
  1579.     assert (!extra_data->refresh_handle);
  1580.     break;
  1581.  
  1582.     case PYDB:
  1583.     if (extra_data->refresh_pwd)
  1584.         cmds += "pwd";
  1585.     if (extra_data->refresh_breakpoints)
  1586.         cmds += "info breakpoints";
  1587.     if (extra_data->refresh_where)
  1588.         cmds += "where";
  1589.     if (extra_data->refresh_data)
  1590.         extra_data->n_refresh_data = 
  1591.         data_disp->add_refresh_data_commands(cmds);
  1592.     if (extra_data->refresh_user)
  1593.         extra_data->n_refresh_user = 
  1594.         data_disp->add_refresh_user_commands(cmds);
  1595.     if (extra_data->refresh_disp_info)
  1596.         cmds += gdb->info_display_command();
  1597.     break;
  1598.  
  1599.     case PERL:
  1600.     if (extra_data->refresh_pwd)
  1601.         cmds += gdb->pwd_command();
  1602.     if (extra_data->refresh_breakpoints)
  1603.         cmds += "L";
  1604.     if (extra_data->refresh_data)
  1605.         extra_data->n_refresh_data = 
  1606.         data_disp->add_refresh_data_commands(cmds);
  1607.     if (extra_data->refresh_user)
  1608.         extra_data->n_refresh_user = 
  1609.         data_disp->add_refresh_user_commands(cmds);
  1610.     if (extra_data->refresh_setting)
  1611.         cmds += show_command(cmd, gdb->type());
  1612.     break;
  1613.     }
  1614.  
  1615.     while (dummy.size() < cmds.size())
  1616.     dummy += (void *)0;
  1617.  
  1618.     if (cmd_data->graph_cmd != "")
  1619.     {
  1620.     // Instead of DDD `graph' commands, we send a `func', `frame'
  1621.     // or `where' command to get the current scope.
  1622.     if (gdb->has_func_command())
  1623.         cmd = gdb->func_command();
  1624.     else if (gdb->has_frame_command())
  1625.         cmd = gdb->frame_command();
  1626.     else
  1627.         cmd = gdb->where_command();
  1628.     }
  1629.  
  1630.     cmd_data->user_data    = data;
  1631.     cmd_data->user_verbose = verbose;
  1632.     cmd_data->user_prompt  = prompt;
  1633.     cmd_data->user_check   = check;
  1634.  
  1635.     extra_data->extra_commands = cmds;
  1636.  
  1637.     // Send commands
  1638.     bool send_ok = gdb->send_user_cmd_plus(cmds, dummy, cmds.size(),
  1639.                        extra_completed, (void*)extra_data,
  1640.                        cmd, (void *)cmd_data);
  1641.  
  1642.     if (!send_ok)
  1643.     post_gdb_busy(origin);
  1644. }
  1645.  
  1646.  
  1647. //-----------------------------------------------------------------------------
  1648. // Part of the answer has been received
  1649. //-----------------------------------------------------------------------------
  1650.  
  1651. static void print_partial_answer(const string& answer, CmdData *cmd_data)
  1652. {
  1653.     cmd_data->user_answer += answer;
  1654.  
  1655.     // Output remaining answer
  1656.     if (cmd_data->user_verbose && cmd_data->graph_cmd == "")
  1657.     {
  1658.     gdb_out(answer);
  1659.     }
  1660.     else if (cmd_data->user_answer.contains("(y or n) ", -1))
  1661.     {
  1662.     // GDB wants confirmation for a batch command
  1663.     gdb->send_user_ctrl_cmd("y\n");
  1664.     }
  1665. }
  1666.  
  1667. static void CancelPartialPositionCB(XtPointer client_data, XtIntervalId *id)
  1668. {
  1669.     (void) id;            // Use it
  1670.  
  1671.     CmdData *cmd_data = (CmdData *)client_data;
  1672.     assert(cmd_data->position_timer == *id);
  1673.     cmd_data->position_timer = 0;
  1674.  
  1675.     string ans = cmd_data->pos_buffer->answer_ended();
  1676.     print_partial_answer(ans, cmd_data);
  1677. }
  1678.  
  1679. static void CancelPartialDisplayCB(XtPointer client_data, XtIntervalId *id)
  1680. {
  1681.     (void) id;            // Use it
  1682.  
  1683.     CmdData *cmd_data = (CmdData *)client_data;
  1684.     assert(cmd_data->display_timer == *id);
  1685.     cmd_data->display_timer = 0;
  1686.  
  1687.     string ans = cmd_data->disp_buffer->answer_ended();
  1688.     print_partial_answer(ans, cmd_data);
  1689. }
  1690.  
  1691.  
  1692. static CmdData *current_cmd_data = 0;
  1693.  
  1694. // Return GDB output that has not been echoed yet
  1695. string buffered_gdb_output()
  1696. {
  1697.     string output = "";
  1698.     if (current_cmd_data != 0)
  1699.     {
  1700.     if (current_cmd_data->pos_buffer != 0)
  1701.         output += current_cmd_data->pos_buffer->answer_ended();
  1702.     if (current_cmd_data->disp_buffer != 0)
  1703.         output += current_cmd_data->disp_buffer->answer_ended();
  1704.     }
  1705.  
  1706.     return output;
  1707. }
  1708.  
  1709. static void partial_answer_received(const string& answer, void *data)
  1710. {
  1711.     string ans = answer;
  1712.     CmdData *cmd_data = (CmdData *) data;
  1713.     current_cmd_data = cmd_data;
  1714.  
  1715.     XtAppContext app_con = XtWidgetToApplicationContext(gdb_w);
  1716.  
  1717.     if (cmd_data->pos_buffer)
  1718.     {
  1719.     // Filter position
  1720.     cmd_data->pos_buffer->filter(ans);
  1721.  
  1722.     if (cmd_data->pos_buffer->pos_found() || 
  1723.         cmd_data->pos_buffer->partial_pos_found())
  1724.     {
  1725.         if (cmd_data->position_timer != 0)
  1726.         XtRemoveTimeOut(cmd_data->position_timer);
  1727.         cmd_data->position_timer = 0;
  1728.     }
  1729.  
  1730.     if (cmd_data->pos_buffer->partial_pos_found())
  1731.     {
  1732.         // Get the remaining position within posTimeOut ms.
  1733.         if (app_data.position_timeout >= 0)
  1734.         {
  1735.         assert(cmd_data->position_timer == 0);
  1736.  
  1737.         cmd_data->position_timer = 
  1738.             XtAppAddTimeOut(app_con, app_data.position_timeout,
  1739.                     CancelPartialPositionCB, 
  1740.                     XtPointer(cmd_data));
  1741.         }
  1742.     }
  1743.     }
  1744.  
  1745.     if (cmd_data->filter_disp != NoFilter)
  1746.     {
  1747.     // Filter displays
  1748.     cmd_data->disp_buffer->filter(ans);
  1749.  
  1750.     if (cmd_data->disp_buffer->displays_found() || 
  1751.         cmd_data->disp_buffer->partial_displays_found())
  1752.     {
  1753.         if (cmd_data->display_timer != 0)
  1754.         XtRemoveTimeOut(cmd_data->display_timer);
  1755.         cmd_data->display_timer = 0;
  1756.     }
  1757.  
  1758.     if (cmd_data->disp_buffer->partial_displays_found())
  1759.     {
  1760.         // Get the remaining displays within displayTimeOut ms.
  1761.         if (app_data.display_timeout >= 0)
  1762.         {
  1763.         assert(cmd_data->display_timer == 0);
  1764.  
  1765.         cmd_data->display_timer = 
  1766.             XtAppAddTimeOut(app_con, app_data.display_timeout,
  1767.                     CancelPartialDisplayCB,
  1768.                     XtPointer(cmd_data));
  1769.         }
  1770.     }
  1771.     }
  1772.  
  1773.     print_partial_answer(ans, cmd_data);
  1774. }
  1775.  
  1776.  
  1777. //-----------------------------------------------------------------------------
  1778. // Answer is complete
  1779. //-----------------------------------------------------------------------------
  1780.  
  1781. // These two are required for the DBX `file' command.
  1782. // DBX does not issue file names when stopping, so use these instead.
  1783. static string last_pos_found;    // Last position found
  1784. static bool last_new_exec_pos;    // True if last command was new exec position
  1785. static bool last_new_frame_pos;    // True if last command was new frame position
  1786.  
  1787. // Return current JDB frame; 0 if none
  1788. inline int jdb_frame()
  1789. {
  1790.     return get_positive_nr(gdb->prompt().from("["));
  1791. }
  1792.  
  1793. // Command completed
  1794. static void command_completed(void *data)
  1795. {
  1796.     gdb_is_exiting = false;
  1797.  
  1798.     CmdData *cmd_data = (CmdData *) data;
  1799.     PosBuffer *pos_buffer = cmd_data->pos_buffer;
  1800.     bool check     = cmd_data->user_check;
  1801.     bool verbose   = cmd_data->user_verbose;
  1802.     bool do_prompt = cmd_data->user_prompt;
  1803.  
  1804.     if (cmd_data->position_timer != 0)
  1805.     XtRemoveTimeOut(cmd_data->position_timer);
  1806.     cmd_data->position_timer = 0;
  1807.  
  1808.     if (cmd_data->display_timer != 0)
  1809.     XtRemoveTimeOut(cmd_data->display_timer);
  1810.     cmd_data->display_timer = 0;
  1811.  
  1812.     if (verbose && !cmd_data->recorded)
  1813.     {
  1814.     // Begin a new undo command
  1815.  
  1816.     const string& cmd = cmd_data->command;
  1817.     string source = cmd;
  1818.     if (cmd.length() == 1 && iscntrl(cmd[0]))
  1819.     {
  1820.         char c = cmd[0];
  1821.  
  1822.         if (c == '\003')
  1823.         source = "interrupt";
  1824.         else if (c == '\034')
  1825.         source = "abort";
  1826.         else if (c < ' ')
  1827.         source = string("^") + char('@' + c);
  1828.         else
  1829.         source = "^?";    // DEL
  1830.     }
  1831.  
  1832.      undo_buffer.set_source(source);
  1833.     }
  1834.  
  1835.     string answer = "";
  1836.     if (pos_buffer)
  1837.     {
  1838.     answer = pos_buffer->answer_ended();
  1839.     cmd_data->user_answer += answer;
  1840.     }
  1841.  
  1842.     if (cmd_data->undo_command != "")
  1843.     {
  1844.     undo_buffer.add_command(cmd_data->undo_command, 
  1845.                 cmd_data->undo_is_exec);
  1846.     }
  1847.  
  1848.     if (pos_buffer && pos_buffer->started_found())
  1849.     {
  1850.     // Program has been restarted - clear position history
  1851.     undo_buffer.clear_exec_pos();
  1852.     }
  1853.  
  1854.     if (pos_buffer && pos_buffer->terminated_found())
  1855.     {
  1856.     // Program has been terminated - clear execution position
  1857.     source_view->clear_execution_position();
  1858.     }
  1859.  
  1860.     if (pos_buffer && pos_buffer->recompiled_found())
  1861.     {
  1862.     // Program has been recompiled - clear code and source cache,
  1863.     // clear execution position, and reload current source.
  1864.     source_view->clear_code_cache();
  1865.     source_view->clear_file_cache();
  1866.     source_view->clear_execution_position();
  1867.     source_view->reload();
  1868.  
  1869.     // Refresh current displays -- they'll probably be lost
  1870.     Command c(data_disp->refresh_display_cmd());
  1871.     c.verbose  = false;
  1872.     c.prompt   = false;
  1873.     c.priority = COMMAND_PRIORITY_SYSTEM;
  1874.     gdb_command(c);
  1875.     }
  1876.  
  1877.     if (pos_buffer && pos_buffer->auto_cmd_found())
  1878.     {
  1879.     // Program (or GDB) issued auto command(s) to be executed by DDD
  1880.     string auto_commands = pos_buffer->get_auto_cmd();
  1881.     if (!auto_commands.contains('\n', -1))
  1882.         auto_commands += '\n';
  1883.  
  1884.     while (auto_commands != "")
  1885.     {
  1886.         string command = auto_commands.before('\n');
  1887.         auto_commands = auto_commands.after('\n');
  1888.  
  1889.         Command c(command, cmd_data->origin);
  1890.         c.priority = COMMAND_PRIORITY_BATCH;
  1891.         c.echo    = false;
  1892.         c.verbose = true;
  1893.         c.prompt  = do_prompt && (auto_commands == "");
  1894.         gdb_command(c);
  1895.     }
  1896.  
  1897.     // Don't issue prompt now; let the last auto command do this
  1898.     do_prompt = false;
  1899.     }
  1900.  
  1901.     if (cmd_data->graph_cmd != "")
  1902.     {
  1903.     // Process graph command
  1904.     string cmd = cmd_data->graph_cmd;
  1905.     bool ok = handle_graph_cmd(cmd, cmd_data->user_answer, 
  1906.                    cmd_data->origin,
  1907.                    cmd_data->user_verbose,
  1908.                    cmd_data->user_prompt);
  1909.     if (!ok)
  1910.     {
  1911.         // Unknown command -- try again with base command
  1912.         cmd_data->graph_cmd   = "";
  1913.         cmd_data->user_answer = "";
  1914.         gdb->send_user_cmd(cmd, (void *)cmd_data);
  1915.         return;
  1916.     }
  1917.  
  1918.     // No need for further checks
  1919.     check        = false;
  1920.  
  1921.     // Ignore the answer
  1922.     verbose      = false;
  1923.  
  1924.     // Don't issue any further prompt
  1925.     do_prompt = false;
  1926.     }
  1927.  
  1928.     // Set execution position
  1929.     if (check && pos_buffer && pos_buffer->pos_found())
  1930.     {
  1931.     string pos  = pos_buffer->get_position();
  1932.     string func = pos_buffer->get_function();
  1933.  
  1934.     if (func != "")
  1935.     {
  1936.         // clog << "Current function is " << quote(func) << "\n";
  1937.         data_disp->process_scope(func);
  1938.     }
  1939.  
  1940.     last_pos_found = pos;
  1941.     tty_full_name(pos);
  1942.  
  1943.     if (!pos.contains(':') && func != "")
  1944.     {
  1945.         string file = "";
  1946.  
  1947.         // No file found, but a function name
  1948.         switch (gdb->type())
  1949.         {
  1950.         case DBX:
  1951.         case XDB:
  1952.         file = dbx_lookup(func);
  1953.         file = file.before(':');
  1954.         break;
  1955.  
  1956.         case GDB:
  1957.         // GDB always issues file names on positions...
  1958.         break;
  1959.  
  1960.         case JDB:
  1961.         case PYDB:
  1962.         case PERL:
  1963.         // FIXME
  1964.         break;
  1965.         }
  1966.  
  1967.         if (file != "")
  1968.         pos = file + ':' + pos;
  1969.     }
  1970.  
  1971.     last_new_exec_pos =  cmd_data->new_exec_pos;
  1972.     last_new_frame_pos = cmd_data->new_frame_pos;
  1973.  
  1974.     if (gdb->type() == JDB && jdb_frame() > 1)
  1975.     {
  1976.         // A breakpoint was reached at some lower frame.  Don't
  1977.         // change the current position now.
  1978.     }
  1979.     else if (cmd_data->new_exec_pos || cmd_data->new_frame_pos)
  1980.     {
  1981.         source_view->show_execution_position(pos, cmd_data->new_exec_pos, 
  1982.                          pos_buffer->signaled_found());
  1983.     }
  1984.     else
  1985.     {
  1986.         // Lookup command: do not change exec position
  1987.         source_view->show_position(pos);
  1988.     }
  1989.     }
  1990.     else if (check && pos_buffer)
  1991.     {
  1992.     // Command should have issued new position, or only PC was
  1993.     // found, and command was not cancelled: Clear old exec position
  1994.     if ((cmd_data->new_exec_pos || pos_buffer->pc_found())
  1995.         && !command_was_cancelled)
  1996.         source_view->show_execution_position();
  1997.     }
  1998.  
  1999.     // Up/Down is done: set frame position in backtrace window
  2000.     if (cmd_data->set_frame_pos)
  2001.     {
  2002.     if (cmd_data->set_frame_func != "")
  2003.         source_view->set_frame_func(cmd_data->set_frame_func);
  2004.     else
  2005.         source_view->set_frame_pos(cmd_data->set_frame_arg);
  2006.     }
  2007.  
  2008.     // Set PC position
  2009.     if (check && pos_buffer && pos_buffer->pc_found())
  2010.     {
  2011.     string pc = pos_buffer->get_pc();
  2012.     if (cmd_data->new_exec_pos || cmd_data->new_frame_pos)
  2013.         source_view->show_pc(pc, XmHIGHLIGHT_SELECTED,
  2014.                  cmd_data->new_exec_pos,
  2015.                  pos_buffer->signaled_found());
  2016.     else
  2017.         source_view->show_pc(pc, XmHIGHLIGHT_NORMAL);
  2018.     }
  2019.  
  2020.     if (verbose)
  2021.     {
  2022.     // Show answer
  2023.     gdb_out(answer);
  2024.     }
  2025.  
  2026.     // Process displays
  2027.     if (check && cmd_data->filter_disp != NoFilter)
  2028.     {
  2029.     assert(cmd_data->filter_disp == TryFilter || 
  2030.            gdb->has_display_command());
  2031.  
  2032.     if (verbose)
  2033.         gdb_out(cmd_data->disp_buffer->answer_ended());
  2034.  
  2035.     if (cmd_data->filter_disp == Filter
  2036.         || cmd_data->disp_buffer->displays_found())
  2037.     {
  2038.         string displays = cmd_data->disp_buffer->get_displays();
  2039.         string not_my_displays = 
  2040.         data_disp->process_displays(displays, 
  2041.                         cmd_data->disabling_occurred);
  2042.  
  2043.         if (verbose)
  2044.         gdb_out(not_my_displays);
  2045.  
  2046.         cmd_data->disp_buffer->clear();
  2047.     }
  2048.     }
  2049.  
  2050.     // If GDB disabled any display, try once more
  2051.     if (check && cmd_data->disabling_occurred)
  2052.     {
  2053.     cmd_data->filter_disp = Filter;
  2054.     cmd_data->user_prompt = false;    // No more prompts
  2055.     gdb->send_user_cmd(gdb->display_command());
  2056.     return;
  2057.     }
  2058.  
  2059.     if (cmd_data->user_callback != 0)
  2060.     {
  2061.     // Invoke user-defined callback
  2062.     cmd_data->user_callback(cmd_data->user_answer, cmd_data->user_data);
  2063.     }
  2064.  
  2065.     if (gdb->type() == JDB)
  2066.     {
  2067.     // Get a current program info to update the `recent files' list.
  2068.     // (In JDB, there will be no debugger interaction.)
  2069.     ProgramInfo info;
  2070.     }
  2071.  
  2072.     if (cmd_data->lookup_arg != "")
  2073.     {
  2074.     // As a side effect of `list X', lookup X in the source
  2075.     source_view->lookup(cmd_data->lookup_arg, false);
  2076.     }
  2077.  
  2078.     delete cmd_data;
  2079.     current_cmd_data = 0;
  2080.  
  2081.     if (do_prompt)
  2082.     prompt();
  2083. }
  2084.  
  2085.  
  2086. //-----------------------------------------------------------------------------
  2087. // Process DDD `graph' commands (graph display, graph refresh).
  2088. //-----------------------------------------------------------------------------
  2089.  
  2090. // Fetch display numbers from ARG into NUMBERS
  2091. static bool read_displays(string arg, IntArray& numbers, bool verbose)
  2092. {
  2093.     while (has_nr(arg))
  2094.     numbers += atoi(read_nr_str(arg));
  2095.  
  2096.     strip_space(arg);
  2097.     if (arg != "")
  2098.     {
  2099.     int nr = data_disp->display_number(arg, verbose);
  2100.     if (nr == 0)
  2101.         return false;    // No such display
  2102.  
  2103.     // Get all displays with name ARG
  2104.     data_disp->get_display_numbers(arg, numbers);
  2105.     }
  2106.  
  2107.     return true;        // Ok
  2108. }
  2109.  
  2110. // Handle graph command in CMD, with WHERE_ANSWER being the GDB reply
  2111. // to a `where 1' command; return true iff recognized
  2112. static bool handle_graph_cmd(string& cmd, const string& where_answer, 
  2113.                  Widget origin, bool verbose, bool do_prompt)
  2114. {
  2115.     string scope;
  2116.     if (gdb->has_func_command())
  2117.     scope = ((string&)where_answer).before('\n'); // `func' output
  2118.     else
  2119.     scope = get_scope(where_answer); // `where' or `frame' output
  2120.  
  2121.     cmd = cmd.after("graph ");
  2122.     if (is_display_cmd(cmd) || cmd.contains("plot", 0))
  2123.     {
  2124.     string rcmd = reverse(cmd);
  2125.  
  2126.     string depends_on = "";
  2127.     string when_in    = "";
  2128.     DeferMode deferred = DeferNever;
  2129.     bool clustered = false;
  2130.     BoxPoint *pos = 0;
  2131.     bool plotted = cmd.contains("plot", 0);
  2132.  
  2133.     for (;;)
  2134.     {
  2135.         strip_leading_space(rcmd);
  2136.  
  2137. #if RUNTIME_REGEX
  2138.         static regex rxdep("[ \t]+no[ \t]+tnedneped[ \t]+");
  2139.         static regex rxwhen("[ \t]+ni[ \t]+nehw[ \t]+(ro[ \t]won[ \t])?");
  2140.         static regex rxat(
  2141.         "[)]?[0-9]*[1-9]-?[ \t]*,[ \t]*[0-9]*[1-9]-?[(]?"
  2142.         "[ \t]+ta[ \t]+.*");
  2143. #endif
  2144.  
  2145.         int dep_index  = rcmd.index(rxdep);
  2146.         int when_index = rcmd.index(rxwhen);
  2147.  
  2148.         if (dep_index >= 0 && (when_index < 0 || dep_index < when_index))
  2149.         {
  2150.         // Check for `dependent on DISPLAY'
  2151.         depends_on = reverse(rcmd.before(dep_index));
  2152.         strip_space(depends_on);
  2153.  
  2154.         rcmd = rcmd.after(dep_index);
  2155.         rcmd = rcmd.after("tnedneped");
  2156.         continue;
  2157.         }
  2158.  
  2159.         if (when_index >= 0 && (dep_index < 0 || when_index < dep_index))
  2160.         {
  2161.         // Check for `[now or] when in FUNC'
  2162.         when_in = reverse(rcmd.before(when_index));
  2163.         strip_space(when_in);
  2164.         rcmd = rcmd.from(when_index);
  2165.  
  2166.         int matchlen = rxwhen.match(rcmd.chars(), rcmd.length());
  2167.         string clause = rcmd.before(matchlen);
  2168.         rcmd = rcmd.from(matchlen);
  2169.  
  2170.         if (clause.contains("won"))
  2171.             deferred = DeferIfNeeded;
  2172.         else
  2173.             deferred = DeferAlways;
  2174.         continue;
  2175.         }
  2176.  
  2177.         if (rcmd.matches(rxat))
  2178.         {
  2179.         // Check for `at X, Y' or `at (X, Y)'
  2180.         if (pos == 0)
  2181.             pos = new BoxPoint;
  2182.  
  2183.         string y = reverse(rcmd.before(','));
  2184.         (*pos)[Y] = get_nr(y);
  2185.         string x = rcmd.after(',');
  2186.         x = reverse(x.before(rxwhite));
  2187.         (*pos)[X] = get_nr(x);
  2188.         rcmd = rcmd.after("ta");
  2189.         continue;
  2190.         }
  2191.  
  2192.         if (rcmd.contains("deretsulc", 0))
  2193.         {
  2194.         clustered = true;
  2195.         rcmd = rcmd.after("deretsulc");
  2196.         continue;
  2197.         }
  2198.  
  2199.         break;
  2200.     }
  2201.  
  2202.     cmd = reverse(rcmd);
  2203.     string display_expression = get_display_expression(cmd);
  2204.  
  2205.     if (display_expression == "")
  2206.     {
  2207.         // No argument.
  2208.         // GDB gives no diagnostics in this case.  So, nor do we.
  2209.         if (do_prompt)
  2210.         prompt();
  2211.         return true;
  2212.     }
  2213.  
  2214.     if (when_in != "" && when_in != scope)
  2215.     {
  2216.         data_disp->new_displaySQ(display_expression, when_in, pos,
  2217.                      depends_on, deferred, clustered, plotted,
  2218.                      origin, verbose, do_prompt);
  2219.     }
  2220.     else
  2221.     {
  2222.         data_disp->new_displaySQ(display_expression, scope, pos,
  2223.                      depends_on, deferred, clustered, plotted,
  2224.                      origin, verbose, do_prompt);
  2225.     }
  2226.     }
  2227.     else if (is_refresh_cmd(cmd))
  2228.     {
  2229.     data_disp->refresh_displaySQ(origin, verbose, do_prompt);
  2230.     }
  2231.     else if (is_data_cmd(cmd))
  2232.     {
  2233.     IntArray numbers;
  2234.     bool ok = read_displays(cmd.after("display"), numbers, verbose);
  2235.     if (ok)
  2236.     {
  2237.         // If no arg is given, apply command to all numbers
  2238.         if (numbers.size() == 0)
  2239.         data_disp->get_all_display_numbers(numbers);
  2240.         
  2241.         if (is_delete_display_cmd(cmd))
  2242.         {
  2243.         data_disp->delete_displaySQ(numbers, verbose, do_prompt);
  2244.         }
  2245.         else if (is_disable_display_cmd(cmd))
  2246.         {
  2247.         data_disp->disable_displaySQ(numbers, verbose, do_prompt);
  2248.         }
  2249.         else if (is_enable_display_cmd(cmd))
  2250.         {
  2251.         data_disp->enable_displaySQ(numbers, verbose, do_prompt);
  2252.         }
  2253.         else
  2254.         {
  2255.         // Unknown command
  2256.         return false;
  2257.         }
  2258.     }
  2259.     }
  2260.     else
  2261.     {
  2262.     // Unknown command
  2263.     return false;
  2264.     }
  2265.  
  2266.     // Command done
  2267.     return true;
  2268. }
  2269.  
  2270.  
  2271. //-----------------------------------------------------------------------------
  2272. // Process output of configuration commands
  2273. //-----------------------------------------------------------------------------
  2274.  
  2275. bool is_known_command(const string& answer)
  2276. {
  2277.     string ans = downcase(answer);
  2278.  
  2279.     strip_space(ans);
  2280.  
  2281.     // In longer messages (help texts and such), only check the first
  2282.     // and last line.
  2283.     if (ans.freq('\n') > 1)
  2284.     {
  2285.     int last_nl = ans.index('\n', -1);
  2286.     ans = ans.before('\n') + ans.from(last_nl + 1);
  2287.     }
  2288.  
  2289.     if (ans.contains("program is not active")) // DBX
  2290.     return true;
  2291.  
  2292.     if (ans.contains("syntax"))                  // DEC DBX, Perl
  2293.     return false;
  2294.  
  2295.     if (ans.contains("invalid keyword"))      // DEC DBX
  2296.     return false;
  2297.  
  2298.     if (ans.contains("undefined command"))    // GDB
  2299.     return false;
  2300.  
  2301.     if (ans.contains("ambiguous command"))    // GDB
  2302.     return false;
  2303.  
  2304.     if (ans.contains("not found"))            // SUN DBX 3.0
  2305.     return false;
  2306.  
  2307.     if (ans.contains("is unknown"))           // SUN DBX 3.0
  2308.     return false;
  2309.  
  2310.     if (ans.contains("is a shell keyword"))   // SUN DBX 3.0
  2311.     return false;
  2312.  
  2313.     if (ans.contains("not a known"))          // AIX DBX 3.1
  2314.     return false;
  2315.  
  2316.     if (ans.contains("unrecognized"))         // AIX DBX & SUN DBX 1.0
  2317.     return false;
  2318.  
  2319.     if (ans.contains("no help available"))    // AIX DBX
  2320.     return false;
  2321.  
  2322.     if (ans.contains("expected"))             // SGI DBX
  2323.     return false;
  2324.  
  2325.     if (ans.contains("invoked in line mode")) // SCO DBX
  2326.     return false;
  2327.  
  2328.     if (ans.contains("huh?"))                  // JDB
  2329.     return false;
  2330.  
  2331.     if (ans.contains("can't locate"))         // Perl
  2332.     return false;
  2333.  
  2334.     if (ans.contains("unknown", 0))           // XDB
  2335.     return false;
  2336.  
  2337.     return true;
  2338. }
  2339.  
  2340. static void process_init(const string& answer, void *)
  2341. {
  2342.     if (answer == NO_GDB_ANSWER)
  2343.     return;            // Command was canceled
  2344.  
  2345.     // cerr << answer;
  2346. }
  2347.  
  2348. static void process_batch(const string& answer, void *)
  2349. {
  2350.     if (answer == NO_GDB_ANSWER)
  2351.     return;            // Command was canceled
  2352.  
  2353.     // cerr << answer;
  2354. }
  2355.  
  2356. static void process_config_frame(string& answer)
  2357. {
  2358.     gdb->has_frame_command(is_known_command(answer));
  2359. }
  2360.  
  2361. static void process_config_func(string& answer)
  2362. {
  2363.     gdb->has_func_command(is_known_command(answer));
  2364. }
  2365.  
  2366. static void process_config_run_io(string& answer)
  2367. {
  2368.     gdb->has_run_io_command(is_known_command(answer));
  2369. }
  2370.  
  2371. static void process_config_print_r(string& answer)
  2372. {
  2373.     gdb->has_print_r_option(is_known_command(answer) 
  2374.                 && answer.contains(print_cookie));
  2375. }
  2376.  
  2377. static void process_config_output(string& answer)
  2378. {
  2379.     gdb->has_output_command(is_known_command(answer) 
  2380.                 && answer.contains(print_cookie));
  2381. }
  2382.  
  2383. static void process_config_where_h(string& answer)
  2384. {
  2385.     gdb->has_where_h_option(is_known_command(answer));
  2386. }
  2387.  
  2388. static void process_config_display(string& answer)
  2389. {
  2390.     gdb->has_display_command(is_known_command(answer));
  2391. }
  2392.  
  2393. static void process_config_clear(string& answer)
  2394. {
  2395.     gdb->has_clear_command(is_known_command(answer));
  2396. }
  2397.  
  2398. static void process_config_handler(string& answer)
  2399. {
  2400.     gdb->has_handler_command(is_known_command(answer));
  2401. }
  2402.  
  2403. static void process_config_pwd(string& answer)
  2404. {
  2405.     gdb->has_pwd_command(is_known_command(answer));
  2406. }
  2407.  
  2408. static void process_config_setenv(string& answer)
  2409. {
  2410.     gdb->has_setenv_command(is_known_command(answer));
  2411. }
  2412.  
  2413. static void process_config_edit(string& answer)
  2414. {
  2415.     gdb->has_edit_command(is_known_command(answer));
  2416. }
  2417.  
  2418. static void process_config_make(string& answer)
  2419. {
  2420.     gdb->has_make_command(is_known_command(answer));
  2421. }
  2422.  
  2423. static void process_config_regs(string& answer)
  2424. {
  2425.     gdb->has_regs_command(is_known_command(answer));
  2426. }
  2427.  
  2428. static void process_config_named_values(string& answer)
  2429. {
  2430.     // SUN DBX 4.0 issues "DDD" on `print -r "DDD"', but has named
  2431.     // values anyway.  Work around this.
  2432.     gdb->has_named_values(gdb->has_print_r_option() 
  2433.               || answer.contains(" = "));
  2434. }
  2435.  
  2436. static void process_config_when_semicolon(string& answer)
  2437. {
  2438.     gdb->has_when_command(is_known_command(answer));
  2439. #if RUNTIME_REGEX
  2440.     static regex rxsemicolon_and_brace("; *[}]");
  2441. #endif
  2442.     gdb->has_when_semicolon(answer.contains(rxsemicolon_and_brace));
  2443. }
  2444.  
  2445. static void process_config_delete_comma(string& answer)
  2446. {
  2447.     gdb->wants_delete_comma(!is_known_command(answer));
  2448. }
  2449.  
  2450. static void process_config_err_redirection(string& answer)
  2451. {
  2452.     gdb->has_err_redirection(answer.contains(">&"));
  2453.  
  2454.     // If `help run' contains `with the current arguments', then `run'
  2455.     // without args uses the current args.  Hence, `rerun' without
  2456.     // args must run the program without args.  SUN DBX feature.
  2457.     gdb->rerun_clears_args(answer.contains("with the current arg"));
  2458. }
  2459.  
  2460. static void process_config_givenfile(string& answer)
  2461. {
  2462.     gdb->has_givenfile_command(is_known_command(answer));
  2463. }
  2464.  
  2465. static void process_config_cont_sig(string& answer)
  2466. {
  2467.     gdb->has_cont_sig_command(answer.contains("[sig "));
  2468. }
  2469.  
  2470. static void process_config_examine(string& answer)
  2471. {
  2472.     gdb->has_examine_command(is_known_command(answer));
  2473. }
  2474.  
  2475. static void process_config_rerun(string& answer)
  2476. {
  2477.     gdb->has_rerun_command(is_known_command(answer));
  2478. }
  2479.  
  2480. static void process_config_tm(string& answer)
  2481. {
  2482.     // If the `tm' command we just sent SUSPENDED macros instead of
  2483.     // ACTIVATING them, we sent another `tm' in order to re-activate
  2484.     // them.
  2485.     if (answer.contains("SUSPENDED"))
  2486.     gdb_question("tm", 0);
  2487. }
  2488.  
  2489. static void process_config_program_language(string& lang)
  2490. {
  2491.     gdb->program_language(lang);
  2492. }
  2493.  
  2494.  
  2495. //-----------------------------------------------------------------------------
  2496. // Handle GDB answers to DDD questions sent after GDB command
  2497. //-----------------------------------------------------------------------------
  2498.  
  2499. static void extra_completed (const StringArray& answers,
  2500.                  const VoidArray& /* qu_datas */,
  2501.                  void*  data)
  2502. {
  2503.     int count = answers.size();
  2504.  
  2505.     ExtraData* extra_data = (ExtraData *)data;
  2506.     int qu_count = 0;
  2507.     string file;
  2508.  
  2509.     while (extra_data->n_init > 0)
  2510.     {
  2511.     // Handle output of initialization commands
  2512.     process_init(answers[qu_count++]);
  2513.     extra_data->n_init--;
  2514.     }
  2515.  
  2516.     if (extra_data->refresh_recent_files)
  2517.     {
  2518.     // Clear undo buffer.  Do this before setting the initial line,
  2519.     // such that it becomes part of the history.
  2520.     undo_buffer.clear();
  2521.     }
  2522.  
  2523.     if (extra_data->refresh_initial_line)
  2524.     {
  2525.     switch (gdb->type())
  2526.     {
  2527.     case GDB:
  2528.     {
  2529.         // Handle `info line' output
  2530.         string info_line1 = answers[qu_count++];
  2531.         string list       = answers[qu_count++];
  2532.         string info_line2 = answers[qu_count++];
  2533.  
  2534.         // Skip initial message lines like `Reading symbols...'
  2535.         while (list != "" && !has_nr(list))
  2536.         list = list.after('\n');
  2537.  
  2538.         if (atoi(list) == 0)
  2539.         {
  2540.         // No listing => no source => ignore `info line' output
  2541.         }
  2542.         else
  2543.         {
  2544.         // Handle `info line' output
  2545.         string info_line = info_line1;
  2546.         if (!info_line.contains("Line ", 0))
  2547.             info_line = info_line2;
  2548.  
  2549.         // Goto initial line
  2550.         source_view->process_info_line_main(info_line);
  2551.         }
  2552.         break;
  2553.     }
  2554.  
  2555.     case XDB:
  2556.     {
  2557.         // Goto initial line
  2558.         source_view->process_info_line_main(answers[qu_count++]);
  2559.         break;
  2560.     }
  2561.  
  2562.     case DBX:
  2563.     case JDB:
  2564.     case PYDB:
  2565.     case PERL:
  2566.     {
  2567.         // Clear caches and such
  2568.         string dummy = "";
  2569.         source_view->process_info_line_main(dummy);
  2570.         break;
  2571.     }
  2572.     }
  2573.     }
  2574.  
  2575.     // Make sure XDB understands macros
  2576.     if (extra_data->config_xdb)
  2577.     process_config_tm(answers[qu_count++]);
  2578.  
  2579.     if (extra_data->config_frame)
  2580.     process_config_frame(answers[qu_count++]);
  2581.  
  2582.     if (extra_data->config_func)
  2583.     process_config_func(answers[qu_count++]);
  2584.  
  2585.     if (extra_data->config_run_io)
  2586.     process_config_run_io(answers[qu_count++]);
  2587.  
  2588.     if (extra_data->config_print_r)
  2589.     process_config_print_r(answers[qu_count++]);
  2590.  
  2591.     if (extra_data->config_where_h)
  2592.     process_config_where_h(answers[qu_count++]);
  2593.  
  2594.     if (extra_data->config_display)
  2595.     process_config_display(answers[qu_count++]);
  2596.  
  2597.     if (extra_data->config_clear)
  2598.     process_config_clear(answers[qu_count++]);
  2599.  
  2600.     if (extra_data->config_handler)
  2601.     process_config_handler(answers[qu_count++]);
  2602.  
  2603.     if (extra_data->config_pwd)
  2604.     process_config_pwd(answers[qu_count++]);
  2605.  
  2606.     if (extra_data->config_setenv)
  2607.     process_config_setenv(answers[qu_count++]);
  2608.  
  2609.     if (extra_data->config_edit)
  2610.     process_config_edit(answers[qu_count++]);
  2611.  
  2612.     if (extra_data->config_make)
  2613.     process_config_make(answers[qu_count++]);
  2614.  
  2615.     if (extra_data->config_regs)
  2616.     process_config_regs(answers[qu_count++]);
  2617.  
  2618.     if (extra_data->config_named_values)
  2619.     process_config_named_values(answers[qu_count++]);
  2620.  
  2621.     if (extra_data->config_when_semicolon)
  2622.     process_config_when_semicolon(answers[qu_count++]);
  2623.  
  2624.     if (extra_data->config_delete_comma)
  2625.     process_config_delete_comma(answers[qu_count++]);
  2626.  
  2627.     if (extra_data->config_err_redirection)
  2628.     process_config_err_redirection(answers[qu_count++]);
  2629.  
  2630.     if (extra_data->config_givenfile)
  2631.     process_config_givenfile(answers[qu_count++]);
  2632.  
  2633.     if (extra_data->config_cont_sig)
  2634.     process_config_cont_sig(answers[qu_count++]);
  2635.  
  2636.     if (extra_data->config_examine)
  2637.     process_config_examine(answers[qu_count++]);
  2638.  
  2639.     if (extra_data->config_rerun)
  2640.     process_config_rerun(answers[qu_count++]);
  2641.  
  2642.     if (extra_data->config_output)
  2643.     process_config_output(answers[qu_count++]);
  2644.  
  2645.     if (extra_data->config_program_language)
  2646.     process_config_program_language(answers[qu_count++]);
  2647.  
  2648.     if (extra_data->refresh_pwd)
  2649.     source_view->process_pwd(answers[qu_count++]);
  2650.  
  2651.     if (extra_data->refresh_class_path)
  2652.     {
  2653.     string ans = answers[qu_count++];
  2654.     source_view->process_use(ans);
  2655.     process_show(extra_data->set_command, ans);
  2656.     }
  2657.  
  2658.     if (extra_data->refresh_file)
  2659.     {
  2660.     assert (gdb->type() == DBX);
  2661.  
  2662.     file = answers[qu_count++];
  2663.  
  2664.     // Simple sanity check
  2665.     strip_trailing_space(file);
  2666.     if (file.contains('\n'))
  2667.         file = file.before('\n');
  2668.     if (file.contains(' '))
  2669.         file = "";
  2670.  
  2671.     if (file != "" && !extra_data->refresh_line)
  2672.     {
  2673.         string current_file = source_view->file_of_cursor().before(':');
  2674.         if (current_file != file)
  2675.         {
  2676.         // File has changed and we already have the current line
  2677.         // - load new current file
  2678.         if (last_pos_found.contains(':'))
  2679.             last_pos_found = file + ":" + last_pos_found.after(':');
  2680.         else
  2681.             last_pos_found = file + ":" + last_pos_found;
  2682.  
  2683.         if (last_new_exec_pos || last_new_frame_pos)
  2684.         {
  2685.             source_view->show_execution_position(last_pos_found,
  2686.                              last_new_exec_pos,
  2687.                              false, true);
  2688.         }
  2689.         else
  2690.         {
  2691.             source_view->lookup(last_pos_found, true);
  2692.         }
  2693.         }
  2694.     }
  2695.     }
  2696.  
  2697.     if (extra_data->refresh_line)
  2698.     {
  2699.     string listing = answers[qu_count++];
  2700.  
  2701.     if (file != "")
  2702.     {
  2703.         int line;
  2704.         if (extra_data->refresh_initial_line && atoi(listing) > 0)
  2705.         line = atoi(listing);
  2706.         else
  2707.         line = line_of_listing(listing);
  2708.         last_pos_found = file + ":" + itostring(line);
  2709.  
  2710.         if (last_new_exec_pos || last_new_frame_pos)
  2711.         {
  2712.         source_view->show_execution_position(last_pos_found,
  2713.                              last_new_exec_pos);
  2714.         }
  2715.         else
  2716.         {
  2717.         source_view->lookup(last_pos_found, true);
  2718.         }
  2719.     }
  2720.     }
  2721.  
  2722.     if (extra_data->refresh_breakpoints)
  2723.     {
  2724.     source_view->process_info_bp(answers[qu_count++], 
  2725.                      extra_data->break_arg);
  2726.     update_arg_buttons();
  2727.     }
  2728.  
  2729.     if (extra_data->refresh_where)
  2730.     {
  2731.     string& where_output = answers[qu_count++];
  2732.  
  2733.     if (gdb->type() == JDB)
  2734.     {
  2735.         // In JDB, the first line issued by `where' is also the
  2736.         // current exec position in the current frame.
  2737.         PosBuffer pb;
  2738.         string w(where_output);
  2739.         pb.filter(w);
  2740.         pb.answer_ended();
  2741.  
  2742.         if (pb.pos_found())
  2743.         source_view->show_execution_position(pb.get_position());
  2744.     }
  2745.  
  2746.     source_view->process_where(where_output);
  2747.     }
  2748.     else
  2749.     {
  2750.     undo_buffer.remove_where();
  2751.     }
  2752.  
  2753.     if (extra_data->refresh_frame)
  2754.     {
  2755.     if (gdb->type() == JDB)
  2756.     {
  2757.         // In JDB, the current frame is part of the prompt.
  2758.         string prompt = gdb->prompt();
  2759.         source_view->process_frame(prompt);
  2760.     }
  2761.     else
  2762.     {
  2763.         string& answer = answers[qu_count++];
  2764.  
  2765.         if (extra_data->refresh_pc)
  2766.         {
  2767.         PosBuffer pb;
  2768.         pb.filter(answer);
  2769.         if (pb.pos_found())
  2770.             source_view->show_execution_position(pb.get_position(), 
  2771.                              true);
  2772.         if (pb.pc_found())
  2773.             source_view->show_pc(pb.get_pc(), 
  2774.                      XmHIGHLIGHT_SELECTED, true);
  2775.         }
  2776.         source_view->process_frame(answer);
  2777.     }
  2778.     }
  2779.     else
  2780.     {
  2781.     undo_buffer.remove_frame();
  2782.     }
  2783.  
  2784.     if (extra_data->refresh_registers)
  2785.     source_view->process_registers(answers[qu_count++]);
  2786.     else
  2787.     undo_buffer.remove_registers();
  2788.  
  2789.     if (extra_data->refresh_threads)
  2790.     source_view->process_threads(answers[qu_count++]);
  2791.     else
  2792.     undo_buffer.remove_threads();
  2793.  
  2794.     if (extra_data->refresh_data)
  2795.     {
  2796.     string ans = "";
  2797.     for (int i = 0; i < extra_data->n_refresh_data; i++)
  2798.     {
  2799.         const string& cmd = extra_data->extra_commands[qu_count];
  2800.         string var = cmd.after(rxwhite);
  2801.  
  2802.         if (!gdb->has_named_values())
  2803.         ans += var + " = ";
  2804.  
  2805.         string value = answers[qu_count++];
  2806.         gdb->munch_value(value, var);
  2807.         ans += value + "\n";
  2808.     }
  2809.  
  2810.     if (extra_data->n_refresh_data > 0)
  2811.     {
  2812.         bool disabling_occurred = false;
  2813.         data_disp->process_displays(ans, disabling_occurred);
  2814.         if (disabling_occurred)
  2815.         data_disp->refresh_displaySQ();
  2816.     }
  2817.     }
  2818.  
  2819.     if (extra_data->refresh_user)
  2820.     {
  2821.     StringArray answers(((string *)answers) + qu_count,
  2822.                 extra_data->n_refresh_user);
  2823.     data_disp->process_user(answers);
  2824.     qu_count += extra_data->n_refresh_user;
  2825.     }
  2826.  
  2827.     if (extra_data->refresh_addr)
  2828.     data_disp->refresh_addr();
  2829.  
  2830.     if (extra_data->refresh_disp_info)
  2831.     data_disp->process_info_display(answers[qu_count++]);
  2832.  
  2833.     if (extra_data->refresh_history_filename)
  2834.     process_history_filename(answers[qu_count++]);
  2835.  
  2836.     if (extra_data->refresh_history_size)
  2837.     process_history_size(answers[qu_count++]);
  2838.  
  2839.     if (extra_data->refresh_setting)
  2840.     {
  2841.     string ans = answers[qu_count++];
  2842.     process_show(extra_data->set_command, ans);
  2843.  
  2844.     // Just in case we've changed the source language
  2845.     PosBuffer pb;
  2846.     pb.filter(ans);
  2847.     }
  2848.  
  2849.     if (extra_data->refresh_handle)
  2850.     {
  2851.     process_handle(answers[qu_count++]);
  2852.     }
  2853.  
  2854.     if (extra_data->refresh_recent_files)
  2855.     {
  2856.     // Get a current program info to update the `recent files' list
  2857.     ProgramInfo info;
  2858.  
  2859.     // Update the source list in `Open Source'
  2860.     update_sources();
  2861.     }
  2862.  
  2863.     assert (qu_count == count);
  2864.     if (qu_count != count)
  2865.     abort();
  2866.  
  2867.     if (extra_data->user_callback != 0)
  2868.     (*extra_data->user_callback)(extra_data->user_data);
  2869.  
  2870.     delete extra_data;
  2871. }
  2872.  
  2873.  
  2874. //-----------------------------------------------------------------------------
  2875. // Process asynchronous GDB answers
  2876. //-----------------------------------------------------------------------------
  2877.  
  2878. static void AsyncAnswerHP(Agent *source, void *, void *call_data)
  2879. {
  2880.     string& answer = *((string *)call_data);
  2881.     GDBAgent *gdb = ptr_cast(GDBAgent, source);
  2882.  
  2883.     if (gdb->type() == JDB)
  2884.     {
  2885.     // In JDB, any thread may hit a breakpoint asynchronously.
  2886.     // Fetch its position.
  2887.     static string answer_buffer;
  2888.     answer_buffer += answer;
  2889.     if (gdb->ends_with_prompt(answer_buffer))
  2890.     {
  2891.         PosBuffer pb;
  2892.         pb.filter(answer_buffer);
  2893.         pb.answer_ended();
  2894.         if (pb.pos_found())
  2895.         source_view->show_execution_position(pb.get_position());
  2896.  
  2897.         answer_buffer = "";
  2898.     }
  2899.     }
  2900.  
  2901.     _gdb_out(answer);
  2902. }
  2903.