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 / args.C < prev    next >
C/C++ Source or Header  |  1998-10-25  |  13KB  |  488 lines

  1. // $Id: args.C,v 1.30 1998/10/25 16:38:48 zeller Exp $ -*- C++ -*-
  2. // Argument Dialog
  3.  
  4. // Copyright (C) 1996-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 args_rcsid[] = 
  30.     "$Id: args.C,v 1.30 1998/10/25 16:38:48 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "args.h"
  37.  
  38. #include "Delay.h"
  39. #include "HelpCB.h"
  40. #include "StringA.h"
  41. #include "Command.h"
  42. #include "SourceView.h"
  43. #include "ddd.h"
  44. #include "disp-read.h"
  45. #include "file.h"
  46. #include "mydialogs.h"
  47. #include "options.h"
  48. #include "cook.h"
  49. #include "regexps.h"
  50. #include "string-fun.h"
  51. #include "verify.h"
  52. #include "wm.h"
  53.  
  54. #include <Xm/Xm.h>
  55. #include <Xm/List.h>
  56. #include <Xm/SelectioB.h>
  57. #include <Xm/Text.h>
  58.  
  59. #include <ctype.h>
  60.  
  61.  
  62. //-----------------------------------------------------------------------------
  63. // Run, Make, and CD Dialogs
  64. //-----------------------------------------------------------------------------
  65.  
  66. // Argument storage
  67. static Widget run_dialog;
  68. static Widget run_arguments_w;
  69. static StringArray run_arguments;
  70. static string last_run_argument;
  71. static bool run_arguments_updated = false;
  72.  
  73. static Widget make_dialog;
  74. static StringArray make_arguments;
  75. static Widget make_arguments_w;
  76. static bool make_arguments_updated = false;
  77. static string last_make_argument;
  78.  
  79. static Widget cd_dialog;
  80. static StringArray cd_arguments;
  81. static Widget cd_arguments_w;
  82. static bool cd_arguments_updated = false;
  83. static string last_cd_argument;
  84.  
  85.  
  86. // Add ARG to the list of arguments
  87. static void add_argument(string arg, StringArray& arguments, 
  88.              string& last, bool& updated)
  89. {
  90.     strip_trailing_space(arg);
  91.     while (arg.length() > 0 && isspace(arg[0]))
  92.     arg = arg.after(0);
  93.  
  94.     last = arg;
  95.  
  96.     // Insertion sort
  97.     int i;
  98.     for (i = 0; i < arguments.size(); i++)
  99.     {
  100.     int cmp = compare(arguments[i], arg);
  101.     if (cmp == 0)
  102.         return;        // Already present
  103.     if (cmp > 0)
  104.         break;
  105.     }
  106.  
  107.     arguments += "<dummy>";
  108.  
  109.     for (int j = arguments.size() - 1; j > i; j--)
  110.     arguments[j] = arguments[j - 1];
  111.     arguments[i] = arg;
  112.  
  113.     updated = false;
  114. }
  115.  
  116. // If LINE is an argument-setting command, add it to the list of arguments
  117. void add_to_arguments(string line)
  118. {
  119.     if (is_set_args_cmd(line))
  120.     {
  121.     string args = line.after("args");
  122.     args = args.after(rxwhite);
  123.     add_argument(args, run_arguments, last_run_argument, 
  124.              run_arguments_updated);
  125.     }
  126.     else if (gdb->type() == PERL && line.contains("@ARGV = ", 0))
  127.     {
  128.     // @ARGV = ('arg1', 'arg2', )
  129.     string args = line.after("('");
  130.     args.gsub("', '", " ");
  131.     args = args.before("', )");
  132.  
  133.     add_argument(args, run_arguments, last_run_argument, 
  134.              run_arguments_updated);
  135.     }
  136.     else if (is_run_cmd(line))
  137.     {
  138.     string args = line.after(rxwhite);
  139.     if (gdb->type() == JDB)
  140.     {
  141.         // Skip class name
  142.         args = args.after(rxwhite);
  143.     }
  144.     add_argument(args, run_arguments, last_run_argument, 
  145.              run_arguments_updated);
  146.     }
  147.     else if (is_make_cmd(line))
  148.     {
  149.     string args = line.after("make");
  150.     args = args.after(rxwhite);
  151.     add_argument(args, make_arguments, last_make_argument, 
  152.              make_arguments_updated);
  153.     }
  154.     else if (gdb->type() == PERL && line.contains("system 'make", 0))
  155.     {
  156.     string args = line.after("make");
  157.     args = args.after(rxwhite);
  158.     args = args.before("'");
  159.     add_argument(args, make_arguments, last_make_argument, 
  160.              make_arguments_updated);
  161.     }
  162.     else if (is_cd_cmd(line))
  163.     {
  164.     string dir = line.after("cd");
  165.     dir = dir.after(rxwhite);
  166.     dir = source_view->full_path(dir);
  167.     if (dir.contains('/', 0))
  168.         add_argument(dir, cd_arguments, last_cd_argument, 
  169.              cd_arguments_updated);
  170.     }
  171.     else if (gdb->type() == PERL && line.contains("chdir '", 0))
  172.     {
  173.     string dir = line.after("'");
  174.     dir = dir.before("'");
  175.     add_argument(dir, cd_arguments, last_cd_argument, 
  176.              cd_arguments_updated);
  177.     }
  178.     else if (gdb->type() == PERL && is_file_cmd(line, gdb))
  179.     {
  180.     string args = line.after(" -d ");
  181.     args = args.after(rxwhite); // Skip file name
  182.     args = args.before('\"');
  183.     add_argument(args, run_arguments, last_run_argument, 
  184.              run_arguments_updated);
  185.     }
  186. }
  187.  
  188.  
  189. // Update list of arguments
  190. static void update_arguments(Widget dialog, Widget arguments_w,
  191.                  StringArray& arguments, string& last,
  192.                  bool& updated)
  193. {
  194.     if (updated || dialog == 0)
  195.     return;
  196.  
  197.     bool *selected = new bool[arguments.size()];
  198.     int pos = -1;
  199.     for (int i = 0; i < arguments.size(); i++)
  200.     {
  201.     if (arguments[i] == last)
  202.         pos = i;
  203.     selected[i] = false;
  204.     }
  205.     if (pos >= 0)
  206.     selected[pos] = true;
  207.  
  208.     setLabelList(arguments_w, arguments.values(),
  209.          selected, arguments.size(), false, false);
  210.  
  211.     if (pos >= 0)
  212.     XmListSelectPos(arguments_w, pos + 1, False);
  213.  
  214.     delete[] selected;
  215.  
  216.     Widget text_w = XmSelectionBoxGetChild(dialog, XmDIALOG_TEXT);
  217.     XmTextSetString(text_w, (char *)last.chars());
  218.  
  219.     updated = true;
  220. }
  221.  
  222. void update_run_arguments()
  223. {
  224.     update_arguments(run_dialog, run_arguments_w, run_arguments,
  225.              last_run_argument, run_arguments_updated);
  226. }
  227.  
  228. void update_make_arguments()
  229. {
  230.     update_arguments(make_dialog, make_arguments_w, make_arguments,
  231.              last_make_argument, make_arguments_updated);
  232. }
  233.  
  234. void update_cd_arguments()
  235. {
  236.     update_arguments(cd_dialog, cd_arguments_w, cd_arguments,
  237.              last_cd_argument, cd_arguments_updated);
  238. }
  239.  
  240. void update_arguments()
  241. {
  242.     update_run_arguments();
  243.     update_make_arguments();
  244.     update_cd_arguments();
  245. }
  246.  
  247. //-----------------------------------------------------------------------------
  248. // Run Dialog
  249. //-----------------------------------------------------------------------------
  250.  
  251. // Run program with given arguments
  252. static void gdbRunDCB(Widget, XtPointer, XtPointer)
  253. {
  254.     Widget text  = XmSelectionBoxGetChild(run_dialog, XmDIALOG_TEXT);
  255.     String _args = XmTextGetString(text);
  256.     string args(_args);
  257.     XtFree(_args);
  258.  
  259.     string cmd = gdb->run_command(args);
  260.     while (cmd != "")
  261.     {
  262.     string c;
  263.     if (cmd.contains('\n'))
  264.         c = cmd.before('\n');
  265.     else
  266.         c = cmd;
  267.     cmd = cmd.after('\n');
  268.     gdb_command(c, run_dialog);
  269.     }
  270. }
  271.  
  272. // Set program arguments from list
  273. static void SelectRunArgsCB(Widget, XtPointer, XtPointer call_data)
  274. {
  275.     XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
  276.     int pos = cbs->item_position - 1;
  277.     const string& args = run_arguments[pos];
  278.     
  279.     Widget text_w = XmSelectionBoxGetChild(run_dialog, XmDIALOG_TEXT);
  280.     XmTextSetString(text_w, (char *)args.chars());
  281. }
  282.  
  283. // Create `Run' dialog
  284. void gdbRunCB(Widget w, XtPointer, XtPointer)
  285. {
  286.     if (run_dialog == 0)
  287.     {
  288.     Arg args[10];
  289.     int arg = 0;
  290.  
  291.     run_dialog = 
  292.         verify(XmCreateSelectionDialog(find_shell(w), "run_dialog", 
  293.                        args, arg));
  294.     XtUnmanageChild(XmSelectionBoxGetChild(run_dialog, 
  295.                            XmDIALOG_APPLY_BUTTON));
  296.  
  297.     Delay::register_shell(run_dialog);
  298.     XtAddCallback(run_dialog, XmNokCallback,     gdbRunDCB, 0);
  299.     XtAddCallback(run_dialog, XmNapplyCallback,  gdbRunDCB, 0);
  300.     XtAddCallback(run_dialog, XmNhelpCallback,   ImmediateHelpCB, 0);
  301.  
  302.     run_arguments_w = XmSelectionBoxGetChild(run_dialog, XmDIALOG_LIST);
  303.     XtAddCallback(run_arguments_w, XmNsingleSelectionCallback,
  304.               SelectRunArgsCB, 0);
  305.     XtAddCallback(run_arguments_w, XmNmultipleSelectionCallback,
  306.               SelectRunArgsCB, 0);
  307.     XtAddCallback(run_arguments_w, XmNextendedSelectionCallback,
  308.               SelectRunArgsCB, 0);
  309.     XtAddCallback(run_arguments_w, XmNbrowseSelectionCallback,
  310.               SelectRunArgsCB, 0);
  311.     }
  312.  
  313.     update_run_arguments();
  314.     manage_and_raise(run_dialog);
  315. }
  316.  
  317.  
  318. //-----------------------------------------------------------------------------
  319. // Make Dialog
  320. //-----------------------------------------------------------------------------
  321.  
  322. // Set program arguments from list
  323. static void SelectMakeArgsCB(Widget, XtPointer, XtPointer call_data)
  324. {
  325.     XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
  326.     int pos = cbs->item_position - 1;
  327.     const string& args = make_arguments[pos];
  328.     
  329.     Widget text_w = XmSelectionBoxGetChild(make_dialog, XmDIALOG_TEXT);
  330.     XmTextSetString(text_w, (char *)args.chars());
  331. }
  332.  
  333. // Make program with given arguments
  334. static void gdbMakeDCB(Widget, XtPointer, XtPointer)
  335. {
  336.     Widget text = XmSelectionBoxGetChild(make_dialog, XmDIALOG_TEXT);
  337.     String _args = XmTextGetString(text);
  338.     string args(_args);
  339.     XtFree(_args);
  340.  
  341.     gdb_command(gdb->make_command(args));
  342. }
  343.  
  344. void gdbMakeAgainCB(Widget, XtPointer, XtPointer)
  345. {
  346.     gdb_command(gdb->make_command(last_make_argument));
  347. }
  348.  
  349. // Create `Make' dialog
  350. void gdbMakeCB(Widget w, XtPointer, XtPointer)
  351. {
  352.     if (!gdb->has_make_command())
  353.     return;
  354.  
  355.     if (make_dialog == 0)
  356.     {
  357.     Arg args[10];
  358.     int arg = 0;
  359.  
  360.     make_dialog = 
  361.         verify(XmCreateSelectionDialog(find_shell(w), 
  362.                        "make_dialog", args, arg));
  363.     XtUnmanageChild(XmSelectionBoxGetChild(make_dialog, 
  364.                            XmDIALOG_APPLY_BUTTON));
  365.  
  366.     Delay::register_shell(make_dialog);
  367.     XtAddCallback(make_dialog, XmNokCallback,     gdbMakeDCB, 0);
  368.     XtAddCallback(make_dialog, XmNapplyCallback,  gdbMakeDCB, 0);
  369.     XtAddCallback(make_dialog, XmNhelpCallback,   ImmediateHelpCB, 0);
  370.  
  371.     make_arguments_w = XmSelectionBoxGetChild(make_dialog, XmDIALOG_LIST);
  372.     XtAddCallback(make_arguments_w, XmNsingleSelectionCallback,
  373.               SelectMakeArgsCB, 0);
  374.     XtAddCallback(make_arguments_w, XmNmultipleSelectionCallback,
  375.               SelectMakeArgsCB, 0);
  376.     XtAddCallback(make_arguments_w, XmNextendedSelectionCallback,
  377.               SelectMakeArgsCB, 0);
  378.     XtAddCallback(make_arguments_w, XmNbrowseSelectionCallback,
  379.               SelectMakeArgsCB, 0);
  380.     }
  381.  
  382.     update_make_arguments();
  383.     manage_and_raise(make_dialog);
  384. }
  385.  
  386.  
  387.  
  388. //-----------------------------------------------------------------------------
  389. // CD Dialog
  390. //-----------------------------------------------------------------------------
  391.  
  392. // Set program arguments from list
  393. static void SelectChangeDirectoryArgsCB(Widget, XtPointer, XtPointer call_data)
  394. {
  395.     XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
  396.     int pos = cbs->item_position - 1;
  397.     string args = source_view->full_path(cd_arguments[pos]);
  398.     
  399.     Widget text_w = XmSelectionBoxGetChild(cd_dialog, XmDIALOG_TEXT);
  400.     XmTextSetString(text_w, (char *)args.chars());
  401. }
  402.  
  403. // ChangeDirectory program with given arguments
  404. static void gdbChangeDirectoryDCB(Widget, XtPointer, XtPointer)
  405. {
  406.     Widget text = XmSelectionBoxGetChild(cd_dialog, XmDIALOG_TEXT);
  407.     String _args = XmTextGetString(text);
  408.     string args(_args);
  409.     XtFree(_args);
  410.  
  411.     string path = source_view->full_path(args);
  412.     if (gdb->type() == PERL)
  413.     gdb_command("chdir " + quote(path, '\''));
  414.     else
  415.     gdb_command("cd " + path);
  416. }
  417.  
  418. // Create `ChangeDirectory' dialog
  419. void gdbChangeDirectoryCB(Widget w, XtPointer, XtPointer)
  420. {
  421.     if (cd_dialog == 0)
  422.     {
  423.     Arg args[10];
  424.     int arg = 0;
  425.  
  426.     cd_dialog = 
  427.         verify(XmCreateSelectionDialog(find_shell(w), 
  428.                        "cd_dialog", args, arg));
  429.     XtUnmanageChild(XmSelectionBoxGetChild(cd_dialog, 
  430.                            XmDIALOG_APPLY_BUTTON));
  431.  
  432.     Delay::register_shell(cd_dialog);
  433.     XtAddCallback(cd_dialog, XmNokCallback,     gdbChangeDirectoryDCB, 0);
  434.     XtAddCallback(cd_dialog, XmNapplyCallback,  gdbChangeDirectoryDCB, 0);
  435.     XtAddCallback(cd_dialog, XmNhelpCallback,   ImmediateHelpCB, 0);
  436.  
  437.     cd_arguments_w = XmSelectionBoxGetChild(cd_dialog, XmDIALOG_LIST);
  438.     XtAddCallback(cd_arguments_w, XmNsingleSelectionCallback,
  439.               SelectChangeDirectoryArgsCB, 0);
  440.     XtAddCallback(cd_arguments_w, XmNmultipleSelectionCallback,
  441.               SelectChangeDirectoryArgsCB, 0);
  442.     XtAddCallback(cd_arguments_w, XmNextendedSelectionCallback,
  443.               SelectChangeDirectoryArgsCB, 0);
  444.     XtAddCallback(cd_arguments_w, XmNbrowseSelectionCallback,
  445.               SelectChangeDirectoryArgsCB, 0);
  446.  
  447.     add_argument("..", cd_arguments, last_cd_argument, 
  448.              cd_arguments_updated);
  449.     }
  450.  
  451.     update_cd_arguments();
  452.     manage_and_raise(cd_dialog);
  453. }
  454.  
  455. //-----------------------------------------------------------------------------
  456. // `run' arguments
  457. //-----------------------------------------------------------------------------
  458.  
  459. void add_running_arguments(string& cmd)
  460. {
  461.     if (cmd == "run")
  462.     cmd = gdb->rerun_command();
  463.  
  464.     if (gdb->type() != JDB || !is_run_cmd(cmd))
  465.     return;
  466.  
  467.     strip_leading_space(cmd);
  468.     string args = cmd.after(rxwhite);
  469.     switch (gdb->type()) 
  470.     {
  471.     case JDB:
  472.     if (args == "")
  473.     {
  474.         // JDB requires at least a class name after the `run' command.
  475.         ProgramInfo info;
  476.         cmd += " " + info.file;
  477.     }
  478.     break;
  479.  
  480.     case XDB:
  481.     case DBX:
  482.     case GDB:
  483.     case PYDB:
  484.     case PERL:
  485.     break;
  486.     }
  487. }
  488.