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 / source.C < prev    next >
C/C++ Source or Header  |  1998-10-23  |  11KB  |  422 lines

  1. // $Id: source.C,v 1.45 1998/10/23 20:30:31 zeller Exp $ -*- C++ -*-
  2. // Source callbacks and actions
  3.  
  4. // Copyright (C) 1996 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 source_rcsid[] = 
  30.     "$Id: source.C,v 1.45 1998/10/23 20:30:31 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "source.h"
  37.  
  38. #include "AppData.h"
  39. #include "ArgField.h"
  40. #include "GDBAgent.h"
  41. #include "UndoBuffer.h"
  42. #include "SourceView.h"
  43. #include "TimeOut.h"
  44. #include "Command.h"
  45. #include "cook.h"
  46. #include "ctrl.h"
  47. #include "dbx-lookup.h"
  48. #include "events.h"
  49. #include "ddd.h"
  50. #include "deref.h"
  51. #include "post.h"
  52. #include "regexps.h"
  53. #include "shell.h"
  54. #include "status.h"
  55. #include "fortranize.h"
  56.  
  57. #include <iostream.h>
  58. #include <Xm/Xm.h>
  59. #include <Xm/Text.h>
  60.  
  61.  
  62. //-----------------------------------------------------------------------------
  63. // Arg
  64. //-----------------------------------------------------------------------------
  65.  
  66. static string current_arg(bool globals_first = false)
  67. {
  68.     return fortranize(source_arg->get_string(), globals_first);
  69. }
  70.  
  71. //-----------------------------------------------------------------------------
  72. // Moving
  73. //-----------------------------------------------------------------------------
  74.  
  75. void gdbLookupCB(Widget, XtPointer, XtPointer)
  76. {
  77.     source_view->lookup(current_arg(true));
  78. }
  79.  
  80. void gdbUndoCB(Widget, XtPointer, XtPointer)
  81. {
  82.     undo_buffer.undo();
  83. }
  84.  
  85. void gdbRedoCB(Widget, XtPointer, XtPointer)
  86. {
  87.     undo_buffer.redo();
  88. }
  89.  
  90.  
  91. //-----------------------------------------------------------------------------
  92. // Printing
  93. //-----------------------------------------------------------------------------
  94.  
  95. void gdbPrintCB(Widget w, XtPointer, XtPointer)
  96. {
  97.     string arg = current_arg();
  98.  
  99.     if (arg != "" && !arg.matches(rxwhite))
  100.     gdb_command(gdb->print_command(arg, false), w);
  101. }
  102.  
  103. void gdbPrintRefCB(Widget w, XtPointer, XtPointer)
  104. {
  105.     string arg = current_arg();
  106.  
  107.     if (arg != "" && !arg.matches(rxwhite))
  108.     gdb_command(gdb->print_command(deref(arg), false), w);
  109. }
  110.  
  111. void gdbDisplayCB(Widget w, XtPointer, XtPointer)
  112. {
  113.     string arg = current_arg();
  114.  
  115.     if (arg != "" && !arg.matches(rxwhite))
  116.     gdb_command("graph display " + arg, w);
  117. }
  118.  
  119. void gdbDispRefCB(Widget w, XtPointer, XtPointer)
  120. {
  121.     string arg = current_arg();
  122.  
  123.     if (arg != "" && !arg.matches(rxwhite))
  124.     gdb_command("graph display " + deref(arg), w);
  125. }
  126.  
  127. void gdbWhatisCB(Widget w, XtPointer, XtPointer)
  128. {
  129.     string arg = current_arg();
  130.  
  131.     if (arg != "" && !arg.matches(rxwhite))
  132.     gdb_command(gdb->whatis_command(arg), w);
  133. }
  134.  
  135.  
  136.  
  137.  
  138. //-----------------------------------------------------------------------------
  139. // Breakpoints
  140. //-----------------------------------------------------------------------------
  141.  
  142. bool have_breakpoint_at_arg()
  143. {
  144.     return source_view->breakpoint_at(current_arg(true)) != 0;
  145. }
  146.  
  147. bool have_enabled_breakpoint_at_arg()
  148. {
  149.     BreakPoint *bp = source_view->breakpoint_at(current_arg(true));
  150.     return bp != 0 && bp->enabled();
  151. }
  152.  
  153. void gdbBreakAtCB(Widget w, XtPointer, XtPointer)
  154. {
  155.     source_view->create_bp(current_arg(true), w);
  156. }
  157.  
  158. void gdbTempBreakAtCB(Widget w, XtPointer, XtPointer)
  159. {
  160.     source_view->create_temp_bp(current_arg(true), w);
  161. }
  162.  
  163. void gdbRegexBreakAtCB(Widget w, XtPointer, XtPointer)
  164. {
  165.     gdb_command("rbreak " + source_arg->get_string(), w);
  166. }
  167.  
  168. void gdbClearAtCB(Widget w, XtPointer, XtPointer)
  169. {
  170.     source_view->clear_bp(current_arg(true), w);
  171. }
  172.  
  173. void gdbToggleBreakCB(Widget w, XtPointer, XtPointer)
  174. {
  175.     source_view->set_bp(current_arg(true), 
  176.                !have_breakpoint_at_arg(), false, "", w);
  177. }
  178.  
  179. void gdbContUntilCB(Widget w, XtPointer, XtPointer)
  180. {
  181.     source_view->temp_n_cont(current_arg(true), w);
  182. }
  183.  
  184. void gdbSetPCCB(Widget w, XtPointer, XtPointer)
  185. {
  186.     source_view->move_pc(current_arg(true), w);
  187. }
  188.  
  189. void gdbToggleEnableBreakpointCB(Widget w, XtPointer, XtPointer)
  190. {
  191.     BreakPoint *bp = source_view->breakpoint_at(current_arg(true));
  192.     if (bp != 0)
  193.     {
  194.     if (bp->enabled())
  195.         source_view->disable_bp(bp->number(), w);
  196.     else
  197.         source_view->enable_bp(bp->number(), w);
  198.     }
  199. }
  200.  
  201. void gdbToggleEnableWatchpointCB(Widget w, XtPointer, XtPointer)
  202. {
  203.     BreakPoint *bp = source_view->watchpoint_at(current_arg(true));
  204.     if (bp != 0)
  205.     {
  206.     if (bp->enabled())
  207.         source_view->disable_bp(bp->number(), w);
  208.     else
  209.         source_view->enable_bp(bp->number(), w);
  210.     }
  211. }
  212.  
  213. void gdbEditBreakpointPropertiesCB(Widget, XtPointer, XtPointer)
  214. {
  215.     BreakPoint *bp = source_view->breakpoint_at(current_arg(true));
  216.     if (bp != 0)
  217.     source_view->edit_breakpoint_properties(bp->number());
  218. }
  219.  
  220. void gdbEditWatchpointPropertiesCB(Widget, XtPointer, XtPointer)
  221. {
  222.     BreakPoint *bp = source_view->watchpoint_at(current_arg(true));
  223.     if (bp != 0)
  224.     source_view->edit_breakpoint_properties(bp->number());
  225. }
  226.  
  227.  
  228.  
  229. //-----------------------------------------------------------------------------
  230. // Watchpoints
  231. //-----------------------------------------------------------------------------
  232.  
  233. // Like in `print', we don't use GLOBALS_FIRST for fortranizing the
  234. // current arg
  235. bool have_watchpoint_at_arg()
  236. {
  237.     return source_view->watchpoint_at(current_arg()) != 0;
  238. }
  239. bool have_watchpoint_at_ref_arg()
  240. {
  241.     return source_view->watchpoint_at(deref(current_arg())) != 0;
  242. }
  243.  
  244. bool have_enabled_watchpoint_at_arg()
  245. {
  246.     BreakPoint *bp = source_view->watchpoint_at(current_arg());
  247.     return bp != 0 && bp->enabled();
  248. }
  249.  
  250. void gdbWatchCB(Widget w, XtPointer client_data, XtPointer call_data)
  251. {
  252.     (void) call_data;        // Use it
  253.     string arg = current_arg();
  254.  
  255. #if 0 // We may have different kinds of watchpoints!
  256.     if (have_watchpoint_at_arg())
  257.     {
  258.     // Don't place multiple watchpoints on one expression
  259.     gdbUnwatchCB(w, client_data, call_data);
  260.     }
  261. #endif
  262.  
  263.     if (arg != "" && !arg.matches(rxwhite))
  264.     gdb_command(gdb->watch_command(arg, 
  265.                        WatchMode((int)(long)client_data)), w);
  266. }
  267.  
  268. void gdbWatchRefCB(Widget w, XtPointer, XtPointer)
  269. {
  270.     string arg = current_arg();
  271.  
  272.     if (arg != "" && !arg.matches(rxwhite))
  273.     gdb_command(gdb->watch_command(deref(arg)), w);
  274. }
  275.  
  276. void gdbUnwatchCB(Widget, XtPointer, XtPointer)
  277. {
  278.     BreakPoint *wp = source_view->watchpoint_at(current_arg());
  279.     if (wp == 0)
  280.     return;
  281.     source_view->delete_bp(wp->number());
  282. }
  283.  
  284. void gdbToggleWatchCB(Widget w, XtPointer client_data, XtPointer call_data)
  285. {
  286.     BreakPoint *bp = source_view->watchpoint_at(current_arg());
  287.     if (bp == 0)
  288.     gdbWatchCB(w, client_data, call_data);
  289.     else
  290.     gdbUnwatchCB(w, client_data, call_data);
  291. }
  292.  
  293.  
  294. //-----------------------------------------------------------------------------
  295. // Searching
  296. //-----------------------------------------------------------------------------
  297.  
  298. static SourceView::SearchDirection last_find_direction = SourceView::forward;
  299.  
  300. void gdbFindCB(Widget w, 
  301.            XtPointer client_data,
  302.            XtPointer call_data)
  303. {
  304.     SourceView::SearchDirection direction = 
  305.     (SourceView::SearchDirection) (long) client_data;
  306.  
  307.     assert(direction == SourceView::forward || 
  308.        direction == SourceView::backward);
  309.  
  310.     if (direction != last_find_direction)
  311.     {
  312.     last_find_direction = direction;
  313.     update_options();
  314.     }
  315.  
  316.     XmPushButtonCallbackStruct *cbs = 
  317.     (XmPushButtonCallbackStruct *)call_data;
  318.  
  319.     // LessTif 0.79 sometimes returns NULL in cbs->event.  Handle this.
  320.     Time tm;
  321.     if (cbs->event != 0)
  322.     tm = time(cbs->event);
  323.     else
  324.     tm = XtLastTimestampProcessed(XtDisplay(w));
  325.  
  326.     string key = source_arg->get_string();
  327.     source_view->find(key, direction, 
  328.               app_data.find_words_only,
  329.               app_data.find_case_sensitive,
  330.               tm);
  331.     source_arg->set_string(key);
  332. }
  333.  
  334. void gdbFindAgainCB(Widget w, XtPointer, XtPointer call_data)
  335. {
  336.     gdbFindCB(w, XtPointer(current_find_direction()), call_data);
  337. }
  338.  
  339. SourceView::SearchDirection current_find_direction()
  340. {
  341.     return last_find_direction;
  342. }
  343.  
  344.  
  345. //-----------------------------------------------------------------------------
  346. // Editor invocation
  347. //-----------------------------------------------------------------------------
  348.  
  349. static void gdbDeleteEditAgent(XtPointer client_data, XtIntervalId *)
  350. {
  351.     // Delete agent after use
  352.     Agent *edit_agent = (Agent *)client_data;
  353.     delete edit_agent;
  354. }
  355.  
  356. static string output_buffer;
  357.  
  358. static void gdbEditOutputHP(Agent *, void *, void *call_data)
  359. {
  360.     DataLength *input = (DataLength *)call_data;
  361.     output_buffer += string(input->data, input->length);
  362.     while (output_buffer.contains('\n'))
  363.     {
  364.     set_status(output_buffer.before('\n'));
  365.     output_buffer = output_buffer.after('\n');
  366.     }
  367.     if (output_buffer != "")
  368.     set_status(output_buffer);
  369. }
  370.  
  371. static void gdbEditDoneHP(Agent *edit_agent, void *, void *)
  372. {
  373.     // Editor has terminated: reload current source file
  374.  
  375.     XtAppAddTimeOut(XtWidgetToApplicationContext(gdb_w), 0, 
  376.             gdbDeleteEditAgent, 
  377.             XtPointer(edit_agent));
  378.  
  379.     gdbReloadSourceCB(gdb_w, 0, 0);
  380.  
  381.     edit_agent->removeHandler(InputEOF, gdbEditDoneHP);
  382.     edit_agent->removeHandler(Died,     gdbEditDoneHP);
  383. }
  384.  
  385. void gdbEditSourceCB  (Widget w, XtPointer, XtPointer)
  386. {
  387.     string pos = source_view->file_of_cursor();
  388.     string file = pos.before(':');
  389.     string line = pos.after(':');
  390.  
  391.     if (file == "" || line == "0")
  392.     {
  393.     post_error("No source.", "no_source_edit_error", w);
  394.     return;
  395.     }
  396.  
  397.     StatusDelay delay("Invoking editor for " + quote(file));
  398.  
  399.     string cmd = app_data.edit_command;
  400.     cmd.gsub("@FILE@", file);
  401.     cmd.gsub("@LINE@", line);
  402.     cmd = sh_command(cmd);
  403.  
  404.     // Invoke an editor in the background
  405.     LiterateAgent *edit_agent = 
  406.     new LiterateAgent(XtWidgetToApplicationContext(w), cmd);
  407.  
  408.     output_buffer = "";
  409.  
  410.     edit_agent->removeAllHandlers(Died);
  411.     edit_agent->addHandler(InputEOF, gdbEditDoneHP);
  412.     edit_agent->addHandler(Died,     gdbEditDoneHP);
  413.     edit_agent->addHandler(Input,    gdbEditOutputHP);
  414.     edit_agent->addHandler(Error,    gdbEditOutputHP);
  415.     edit_agent->start();
  416. }
  417.  
  418. void gdbReloadSourceCB(Widget, XtPointer, XtPointer)
  419. {
  420.     source_view->reload();
  421. }
  422.