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 / WhatNextCB.C < prev    next >
C/C++ Source or Header  |  1998-10-28  |  5KB  |  253 lines

  1. // $Id: WhatNextCB.C,v 1.17 1998/10/28 14:15:19 zeller Exp $ -*- C++ -*-
  2. // DDD `What Now?' help
  3.  
  4. // Copyright (C) 1997-1998 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char WhatNextCB_rcsid[] = 
  30.     "$Id: WhatNextCB.C,v 1.17 1998/10/28 14:15:19 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "WhatNextCB.h"
  37.  
  38. #include "Command.h"
  39. #include "converters.h"
  40. #include "comm-manag.h"
  41. #include "ddd.h"
  42. #include "editing.h"
  43. #include "exit.h"
  44. #include "file.h"
  45. #include "question.h"
  46. #include "regexps.h"
  47. #include "status.h"
  48. #include "verify.h"
  49. #include "version.h"
  50. #include "wm.h"
  51. #include "AppData.h"
  52. #include "DataDisp.h"
  53. #include "Delay.h"
  54. #include "DestroyCB.h"
  55. #include "HelpCB.h"
  56. #include "SourceView.h"
  57. #include "UndoBuffer.h"
  58.  
  59. #include <Xm/Xm.h>
  60. #include <Xm/Text.h>
  61. #include <Xm/MessageB.h>
  62.  
  63. // Show a suggestion named NAME
  64. static void hint_on(String name)
  65. {
  66.     // Create some `dummy' widget and create a help text for it
  67.     Widget suggestion = 
  68.     verify(XmCreateInformationDialog(find_shell(), name, 0, 0));
  69.  
  70.     ImmediateHelpCB(suggestion, XtPointer(0), XtPointer(0));
  71.  
  72.     DestroyWhenIdle(suggestion);
  73. }
  74.  
  75. static bool no_source_and_no_code()
  76. {
  77.     return !source_view->have_source()
  78.     && (gdb->type() != GDB || !app_data.disassemble);
  79. }
  80.  
  81. static bool no_gdb()
  82. {
  83.     return !gdb_initialized;
  84. }
  85.  
  86. static bool gdb_has_crashed()
  87. {
  88.     return !no_gdb() && (gdb == 0 || gdb->pid() <= 0 || !gdb->running());
  89. }
  90.  
  91. static bool code_but_no_source()
  92. {
  93.     return source_view->have_pc() && !source_view->have_exec_pos()
  94.     && (gdb->type() != GDB || !app_data.disassemble);
  95. }
  96.  
  97. // Return 1 if the signal specified in PROGRAM_STATE is passed to the
  98. // program; 0 if not, -1 if undecided.
  99. static int passed_to_program(string program_state)
  100. {
  101.     string signal = program_state.from("SIG");
  102.     signal = signal.through(rxalpha);
  103.  
  104.     if (signal != "")
  105.     {
  106.     string signal_description = program_state.after(signal);
  107.     signal_description = signal_description.after(rxwhite);
  108.  
  109.     if (signal_description == "")
  110.         signal_description = signal;
  111.     
  112.     defineConversionMacro("SIGNAL", signal);
  113.     defineConversionMacro("SIGNAL_DESCRIPTION", signal_description);
  114.  
  115.     string ans = gdb_question("info handle " + signal);
  116.  
  117.     // `info handle SIGINT' output has the form
  118.     // "Signal        Stop\tPrint\tPass to program\tDescription\n"
  119.     // "SIGINT        Yes\tYes\tNo\t\tInterrupt\n"
  120.  
  121.     ans.downcase();
  122.     string header = ans.before("pass ");
  123.     int tabs_before_pass = header.freq('\t');
  124.     string info = ans.after('\n');
  125.     while (tabs_before_pass--)
  126.         info = info.after('\t');
  127.     if (info.contains('y', 0))
  128.         return 1;
  129.     if (info.contains('n', 0))
  130.         return 0;
  131.     }
  132.     return -1;
  133. }
  134.  
  135. // Give a help dependent on current DDD state
  136. void WhatNextCB(Widget, XtPointer, XtPointer)
  137. {
  138.     // Special DDD states
  139.     if (ddd_has_crashed)
  140.     {
  141.     hint_on("fatal_dialog");
  142.     return;
  143.     }
  144.  
  145.     // Special GDB states
  146.     if (no_gdb())
  147.     {
  148.     hint_on("no_debugger_dialog");
  149.     return;
  150.     }
  151.  
  152.     if (gdb_has_crashed())
  153.     {
  154.     hint_on("terminated_dialog");
  155.     return;
  156.     }
  157.  
  158.     if (gdb_asks_yn)
  159.     {
  160.     hint_on("yn_dialog");
  161.     return;
  162.     }
  163.  
  164.     if (gdb->recording())
  165.     {
  166.     hint_on("recording");
  167.     return;
  168.     }
  169.  
  170.     if (debuggee_running)
  171.     {
  172.     hint_on("running");
  173.     return;
  174.     }
  175.  
  176.     if (!gdb->isReadyWithPrompt())
  177.     {
  178.     hint_on("busy");
  179.     return;
  180.     }
  181.  
  182.     if (undo_buffer.showing_earlier_state())
  183.     {
  184.     hint_on("showing_earlier_state");
  185.     return;
  186.     }
  187.  
  188.     // Typical start-up situations
  189.     ProgramInfo info;
  190.     if (info.file == "")
  191.     {
  192.     hint_on("no_program");
  193.     return;
  194.     }
  195.  
  196.     if (no_source_and_no_code())
  197.     {
  198.     hint_on("no_source_and_no_code");
  199.     return;
  200.     }
  201.  
  202.     // Examine state
  203.     if (source_view->have_selection())
  204.     {
  205.     hint_on("item_selected");
  206.     return;
  207.     }
  208.  
  209.     if (data_disp->have_selection())
  210.     {
  211.     hint_on("display_selected");
  212.     return;
  213.     }
  214.  
  215.     if (current_line() != "")
  216.     {
  217.     hint_on("command_entered");
  218.     return;
  219.     }
  220.  
  221.     if (!info.running)
  222.     {
  223.     hint_on("program_not_running");
  224.     return;
  225.     }
  226.  
  227.     // Program has stopped and nothing is selected.
  228.     defineConversionMacro("PROGRAM_STATE", info.state);
  229.  
  230.     if (code_but_no_source())
  231.     {
  232.     hint_on("code_but_no_source");
  233.     return;
  234.     }
  235.  
  236.     if (gdb->type() == GDB && info.state.contains("signal"))
  237.     {
  238.     int p = passed_to_program(info.state);
  239.     if (p > 0)
  240.     {
  241.         hint_on("stopped_at_passed_signal");
  242.         return;
  243.     }
  244.     else if (p == 0)
  245.     {
  246.         hint_on("stopped_at_ignored_signal");
  247.         return;
  248.     }
  249.     }
  250.  
  251.     hint_on("stopped");
  252. }
  253.