home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xdbx / part04 / handler.c next >
C/C++ Source or Header  |  1990-08-27  |  13KB  |  488 lines

  1. /*****************************************************************************
  2.  *
  3.  *  xdbx - X Window System interface to the dbx debugger
  4.  *
  5.  *  Copyright 1989 The University of Texas at Austin
  6.  *  Copyright 1990 Microelectronics and Computer Technology Corporation
  7.  *
  8.  *  Permission to use, copy, modify, and distribute this software and its
  9.  *  documentation for any purpose and without fee is hereby granted,
  10.  *  provided that the above copyright notice appear in all copies and that
  11.  *  both that copyright notice and this permission notice appear in
  12.  *  supporting documentation, and that the name of The University of Texas
  13.  *  and Microelectronics and Computer Technology Corporation (MCC) not be 
  14.  *  used in advertising or publicity pertaining to distribution of
  15.  *  the software without specific, written prior permission.  The
  16.  *  University of Texas and MCC makes no representations about the 
  17.  *  suitability of this software for any purpose.  It is provided "as is" 
  18.  *  without express or implied warranty.
  19.  *
  20.  *  THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
  21.  *  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22.  *  FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
  23.  *  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  24.  *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  25.  *  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  26.  *  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  *
  28.  *  Author:      Po Cheung
  29.  *  Created:       March 10, 1989
  30.  *
  31.  *****************************************************************************/
  32.  
  33. /*  handler.c
  34.  *
  35.  *    Contain action handlers for the parser to invoke upon a dbx command.
  36.  *
  37.  *    TextSetTopPosition():    Set the top character position of text displayed
  38.  *    AdjustText():        Adjust the portion of text displayed.
  39.  *    exec_handler():        Update file, line label, arrow position.
  40.  *    done_handler():        Progrm execution completed, clear breakpoints
  41.  *    stop_at_handler():    Place stop sign on line specified.
  42.  *    stop_in_handler():    Place stop sign on function specified.
  43.  *    updown_handler():        Update file, line label, updown arrow position.
  44.  *    delete_handler():        Remove stop sign.
  45.  *    func_handler():        Display function, if specified.
  46.  *    file_handler():        Display file, if specified.
  47.  *    debug_handler():        Check directory use list, display source file.
  48.  *    cd_handler():        Record current working directory.
  49.  *    use_handler():        Record directory paths.
  50.  *    search_handler():        Adjust source file to display matched line.
  51.  *    list_handler();        Adjust source file to display result.
  52.  *    display_handler():    Display results in display window.
  53.  */
  54.  
  55. #include <ctype.h>
  56. #include "global.h"
  57. #ifdef BSD
  58. #define    BRACKET    "[%d]"
  59. #else
  60. #define    BRACKET    "(%d)"
  61. #endif
  62.  
  63. Boolean        Echo = True;        /* display dbx output if true */
  64. static Boolean    Skip_func_handler = False;
  65.  
  66. /*  Display text starting from the top position specified by pos */
  67.  
  68. void TextSetTopPosition(w, pos)
  69.     Widget w;
  70.     XawTextPosition pos;
  71. {
  72.     Arg args[MAXARGS];
  73.     Cardinal n;
  74.  
  75.     n = 0;
  76.     XtSetArg(args[n], XtNdisplayPosition, (XtArgVal) pos);               n++;
  77.     XtSetValues(w, args, n);
  78. }
  79.  
  80. /*
  81.  *  Adjust text so that 'line' will fall into the viewable part of the
  82.  *  source window.
  83.  *  Arrows, stop signs, and line label are updated accordingly.
  84.  */
  85. void AdjustText(line)
  86.     int           line;
  87. {
  88.     FileRec         *file;
  89.     int                nlines = 0;
  90.     int            i;
  91.     XawTextPosition     pos;
  92.  
  93.     if ((file = displayedFile) == NULL || line <= 0) return;
  94.     file->currentline = line;
  95.  
  96.     if (line < file->topline || line > file->bottomline ) {
  97.     /* Position line about 30% from the top */
  98.     nlines = file->lines*0.3;
  99.     if (line < nlines)               /* near top */
  100.         file->topline = 1;
  101.     else if (line > file->lastline - nlines)  /* near bottom */
  102.         file->topline = MAX(file->lastline - file->lines + 1, 1);
  103.     else
  104.         file->topline = line - nlines;
  105.     file->bottomline = MIN(file->topline + file->lines - 1, file->lastline);
  106.     TextSetTopPosition(sourceWindow, file->linepos[file->topline]);
  107.     file->topPosition = file->linepos[file->topline];
  108.     }
  109.     XawTextSetInsertionPoint(sourceWindow, file->linepos[line]);
  110.  
  111.     /* Text window might have scrolled, check topline & bottomline */
  112.     pos = XawTextTopPosition(sourceWindow);
  113.     for (i=1; pos >= file->linepos[i]; i++);
  114.     if (file->topline != i-1) {
  115.     file->topline = i-1;
  116.     file->bottomline = MIN (file->topline + file->lines - 1,
  117.                 file->lastline);
  118.     }
  119.     UpdateLineLabel(line);
  120.     UpdateStops(file);
  121.     UpdateArrow(file);
  122.     UpdateUpdown(file);
  123.     UpdateBomb(file);
  124. }
  125.     
  126.  
  127. /*  Handle dbx output of run, cont, next, step, return commands.
  128.  *  Result of output parsing is returned in a set of tokens.
  129.  */
  130. void exec_handler()
  131. {
  132.     int     line, status;
  133.     char *func, *mesg;
  134.     char *segv = "signal SEGV";
  135.     char *segfault = "Segmentation fault";
  136.  
  137.     /* Print "stopped in ..." line in message window 
  138.      * Adjust text displayed
  139.      */
  140.     if (Token.func == NULL || Token.line == 0) 
  141.     return; 
  142.     UpdateMessageWindow(Token.mesg);
  143.     line = Token.line;
  144.     func = XtNewString(Token.func);
  145.     mesg = XtNewString(Token.mesg);
  146. #ifdef MIPS
  147.     status = LoadCurrentFile();
  148. #else
  149.     if (Token.file)
  150.     status = LoadFile(Token.file);
  151. #endif
  152.     arrow.line = line;            /* update arrow sign position */
  153.     strcpy(arrow.func, func);
  154.     updown.line = 0;            /* remove updown, if any */
  155.     if (displayedFile) {
  156.         strcpy(arrow.file, displayedFile->pathname);
  157.     }
  158.     /* Display bomb sign if segmentation fault occurs in source code */
  159.     if (status != -1 && (strncmp(mesg, segv, strlen(segv)) == NULL ||
  160.     strncmp(mesg, segfault, strlen(segfault)) == NULL)) {
  161.     arrow.line = 0;
  162.     bomb.line = line;
  163.     strcpy(bomb.func, func);
  164.         if (displayedFile) strcpy(bomb.file, displayedFile->pathname);
  165.     }
  166.     else
  167.     bomb.line = 0;
  168.  
  169.     AdjustText(line);
  170. #ifndef BSD
  171.     display_handler();
  172. #endif
  173.     XtFree(func);
  174.     XtFree(mesg);
  175. }
  176.  
  177.  
  178. /*  Remove all the arrow and updown signs, print message, then 
  179.  *  change the file variable to the file name displayed.
  180.  */
  181. void done_handler()
  182. {
  183.     char command[LINESIZ];
  184.  
  185.     arrow.line = 0;
  186.     updown.line = 0;
  187.     UpdateArrow(displayedFile);
  188.     UpdateUpdown(displayedFile);
  189.     UpdateMessageWindow("Ready for execution");
  190.     if (displayedFile == NULL) return;
  191. #ifdef MIPS
  192.     sprintf(command, "file %s\n", displayedFile->filename);
  193. #else
  194.     sprintf(command, "file %s\n", displayedFile->pathname);
  195. #endif
  196.     Parse = False;
  197.     query_dbx(command);
  198. }
  199.  
  200.  
  201. /*  Place a stop sign next to the line specified on the source file window 
  202.  *  if it is to be viewable.
  203.  */
  204. void stop_at_handler()
  205. {
  206.     if (Token.stop == 0 || Token.line == 0 || displayedFile == NULL)
  207.     return;
  208.     if (Token.file == NULL)
  209.     stops[Token.stop].file = displayedFile->pathname;
  210.     else
  211.     stops[Token.stop].file = GetPathname(Token.file);
  212.     DisplayStop(displayedFile, Token.line);
  213.     stops[Token.stop].line = Token.line;
  214.     stops[Token.stop].tag = 0;
  215.     nstops = Token.stop;
  216. }
  217.  
  218.  
  219. /*
  220.  *  Place a stop sign next to the function routine, getting the line number 
  221.  *  by "list <func>", (or "func <func>" on a MIPS), and resetting the file 
  222.  *  variable properly.
  223.  */
  224. void stop_in_handler()
  225. {
  226.     char command[LINESIZ], *file;
  227.     int  stop;
  228.     int     line;
  229.  
  230.     if (Token.stop == 0 || Token.func == NULL || displayedFile == NULL)
  231.     return;
  232.     stop = Token.stop;
  233. #ifdef MIPS
  234.     /* For mips dbx, need to use func command to locate the function */
  235.     Skip_func_handler = True;
  236.     sprintf(command, "func %s\n", Token.func);
  237.     query_dbx(command);
  238. #else
  239. #ifdef BSD
  240.     sprintf(command, "list %s\n", Token.func);
  241.     query_dbx(command);
  242. #else
  243.     sprintf(command, "list %s\n", Token.func);
  244.     query_dbx(command);
  245.     if (Token.line <= 0) 
  246.     return;
  247.     else 
  248.     Token.line += 5;
  249. #endif
  250. #endif
  251.  
  252.     stops[stop].line = Token.line;
  253.     nstops = stop;
  254.     line = Token.line;
  255.  
  256.     /* Check the name of the file containing Token.func */
  257.     query_dbx("file\n");
  258.     if ((file = GetPathname(CurrentFile)) && 
  259.         strcmp(file, displayedFile->pathname)) {   /* new file, record stop */
  260.     stops[nstops].file = file;
  261. #ifdef MIPS
  262.     sprintf(command, "file %s\n", displayedFile->filename);
  263. #else
  264.     sprintf(command, "file %s\n", displayedFile->pathname);
  265. #endif
  266.     Parse = False;
  267.     query_dbx(command);
  268.     }
  269.     else {                        /* same file, display stop */
  270.     stops[nstops].file = displayedFile->pathname;
  271.     DisplayStop(displayedFile, line);
  272.     }
  273. }
  274.  
  275.  
  276. /*  
  277.  *  Display an outlined arrow to locate the calling routine in a stack
  278.  *  frame.  BSD and SUN dbx have slightly different output semantics here.
  279.  *  The appropriate file with the calling routine is displayed and the
  280.  *  file variable is set accordingly.
  281.  */
  282. void updown_handler()
  283. {
  284.     char command[LINESIZ], *func, *file;
  285.     int     line;
  286.  
  287.     line = Token.line;
  288.     func = XtNewString(Token.func);
  289. #ifdef MIPS
  290.     LoadCurrentFile();
  291. #endif
  292. #ifdef BSD
  293.     file = GetPathname(Token.file);
  294. #else
  295.     if (line <= 0) line = 1;
  296.     LoadCurrentFile();
  297.     if (displayedFile)
  298.     file = displayedFile->pathname;
  299. #endif
  300.  
  301.     if (line <= 0 || func == NULL || file == NULL) 
  302.     return;
  303.     if (displayedFile && strcmp(file, displayedFile->pathname)) {
  304.     LoadFile(file);
  305.     /* set dbx file variable to file */
  306. #ifdef MIPS
  307.     sprintf(command, "file %s\n", displayedFile->filename);
  308. #else
  309.     sprintf(command, "file %s\n", displayedFile->pathname);
  310. #endif
  311.     Parse = False;
  312.     query_dbx(command);
  313.     }
  314.     updown.line = line;
  315.     strcpy(updown.func, func);
  316.     if (displayedFile)
  317.         strcpy(updown.file, displayedFile->pathname);
  318.     AdjustText(line);
  319.     XtFree(func);
  320. }
  321.  
  322.  
  323. /*
  324.  *  Delete handler remove the stop specified and undisplayed the stopsign
  325.  *  if it's visible.
  326.  *  It calls the dbx status command to find out what stops are left, and
  327.  *  then update the array of stops accordingly.
  328.  */
  329. /* ARGSUSED */
  330. void delete_handler()
  331. {
  332.     char s[LINESIZ];
  333.     int  i; 
  334.     int     line;
  335.  
  336.     write_dbx("status\n");
  337.     while (fgets(s, LINESIZ, dbxfp) == NULL);
  338.     do {
  339.     if (strcmp(s, dbxprompt) || strcmp(s, "")) {
  340.         sscanf(s, BRACKET, &i);
  341.         if (i > 0 && i <= nstops && stops[i].line > 0) 
  342.             stops[i].tag = 1;
  343.     }
  344.     } while (fgets(s, LINESIZ, dbxfp));
  345.  
  346.     for (i=1; i<=nstops; i++)
  347.     if (stops[i].line > 0) {
  348.         if (stops[i].tag)
  349.         stops[i].tag = 0;
  350.         else {
  351.         line = stops[i].line;
  352.         stops[i].line = 0;
  353.         stops[i].file = NULL;
  354.         if (LineToStop_no(line) == 0)
  355.             RemoveStop(line);
  356.         }
  357.     }
  358. }
  359.  
  360. /*
  361.  *  This handler displays the function routine on the source window.
  362.  *  It locates the function by sending the dbx command "list <func>",
  363.  *  and loads the appropriate file accordingly.
  364.  */
  365. void func_handler()
  366. {
  367.     int     line;
  368.     char command[LINESIZ];
  369.  
  370.     if (Token.func && !Skip_func_handler) {
  371. #ifdef MIPS
  372.     line = Token.line;
  373. #else
  374.     sprintf(command, "list %s\n", Token.func);
  375.     query_dbx(command);
  376.     line = Token.line + 5;
  377. #endif
  378.     LoadCurrentFile();
  379.     AdjustText(line);
  380.     }
  381.     Skip_func_handler = False;
  382. }
  383.  
  384.  
  385. /*  File handler first queries the current file set by the user command,
  386.  *  and then loads the file.
  387.  */
  388. /* ARGSUSED */
  389. void file_handler()     /* Command was 'file' */
  390. {
  391.     if (Token.file)
  392.     strcpy(CurrentFile, Token.file);
  393.     else
  394.     strcpy(CurrentFile, "");
  395. }
  396.  
  397. /* ARGSUSED */
  398. void debug_handler()
  399. {
  400.     query_dbx("use\n");
  401.     displayedFile = NULL;        /* force reloading of source file */
  402.     if (LoadCurrentFile() == 0) {
  403.     arrow.line = 0;            /* clear arrow sign */
  404.     updown.line = 0;        /* clear updown sign */
  405.     bomb.line = 0;            /* clear bomb sign */
  406.     UpdateArrow(displayedFile);
  407.     UpdateUpdown(displayedFile);
  408.     UpdateBomb(displayedFile);
  409.     ClearStops();
  410.     UpdateStops(displayedFile);
  411.         UpdateMessageWindow("Ready for execution");
  412.     query_dbx("func main\n");
  413. #ifndef BSD
  414.     query_dbx("display\n");        /* clear display window */
  415. #endif
  416.     }
  417. }
  418.  
  419. /* ARGSUSED */
  420. void cd_handler()
  421. {
  422.     query_dbx("pwd\n");
  423. }
  424.  
  425. /* ARGSUSED */
  426. void pwd_handler(s)
  427. char *s;
  428. {
  429.     strcpy(cwd, (char *)strtok(s, "\n"));
  430. }
  431.  
  432. /* ARGSUSED */
  433. void use_handler(output)
  434. char *output;
  435. {
  436.     if (strcmp(output, "") == NULL)
  437.     query_dbx("use\n");
  438.     else
  439.         MakeDirList(output);
  440. }
  441.  
  442. /* ARGSUSED */
  443. void search_handler()
  444. {
  445.     AdjustText(Token.line);
  446. }
  447.  
  448. /* ARGSUSED */
  449. void list_handler()
  450. {
  451.     int     line;
  452.  
  453.     if (Echo) {
  454.     line = Token.line;
  455.     LoadCurrentFile();
  456.         AdjustText(line);
  457.     }
  458. }
  459.  
  460.  
  461. /* ARGSUSED */
  462. /*  Show output on the display window.
  463.  *  If output is null but the display window is managed, replace contents of
  464.  *  the display window with the null string.
  465.  */
  466. void display_handler()
  467. {
  468.     Arg        args[MAXARGS];
  469.     Cardinal    n;
  470.  
  471.     if (!Token.display || strcmp(Token.display, "") == NULL) {
  472.     if (!XtIsManaged(displayWindow))
  473.         return;
  474.     else {
  475.         XtFree(Token.display);
  476.         Token.display = XtNewString("");
  477.     }
  478.     }
  479.     if (!XtIsManaged(displayWindow)) {
  480.     XtManageChild(separator);
  481.     XtManageChild(displayWindow);
  482.     }
  483.     n = 0;
  484.     XtSetArg(args[n], XtNstring, (XtArgVal) Token.display);        n++;
  485.     XtSetValues(displayWindow, args, n);
  486.     XtFree(Token.display);
  487. }
  488.