pierre@tce.COM (Pierre Willard) (03/07/91)
Submitted-by: pierre@tce.COM (Pierre Willard) Posting-number: Volume 11, Issue 53 Archive-name: xxgdb/part06 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 4 (of 8)." # Contents: filemenu.c gdb_handler.c parser.c # Wrapped by gilbert@phi on Tue Jan 15 13:12:47 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'filemenu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'filemenu.c'\" else echo shar: Extracting \"'filemenu.c'\" \(13542 characters\) sed "s/^X//" >'filemenu.c' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* filemenu.c X * X * Construct a file menu (directory browser) which allows a user to go X * up and down the directory tree, to select text files to display, and X * to select executable files to debug. The file menu is popped up by X * the 'file' command button. X * Duane Voth (duanev@mcc.com) contributed to the layout of the file menu, X * plus some code and ideas. X * X * changeDir(): Record the current working directory. X * InList(): Select files to be displayed in the menu. X * ScanDir(): Scan the directory and record selected filenames. X * DisplayMenuFile(): Callback for the file menu. X * CancelFileMenu(): Pop down the file menu. X * SetUpFileMenu(): Create the file menu popupshell. X * UpdateFileMenu(): Update entries in the file menu. X * File(): Command callback for the 'file' command button. X */ X X#include <ctype.h> X#include <X11/Xos.h> X#include <sys/stat.h> X#ifdef SUNOS4 X#include <dirent.h> X#else X#include <sys/dir.h> X#endif X#include "global.h" X X#define MAXCOLUMNS 8 /* max number of columns in file menu */ X#define FILES_PER_COL 10 /* # of files per column in file menu */ X Xchar cwd[MAXPATHLEN]; /* current working directory of dbx */ Xstatic char fileMenuDir[MAXPATHLEN];/* current directory of file menu */ Xstatic char **filelist; /* list of file names in fileMenu */ Xstatic int nfiles = 0; /* number of files in filelist */ Xstatic Widget popupshell, /* parent of popup */ X popup, /* vpane widget containing file menu */ X fileMenu, /* list widget as file menu */ X fileMenuLabel; /* label widget as file menu label */ X Xvoid File(), UpdateFileMenu(); X X/* Change working directory to 'dir'. X * For Berkeley dbx, modify static global variable, cwd, to keep track of X * current working directory. X * For Sun dbx, change working directory of dbx. X */ Xstatic void changeDir(dir) Xchar *dir; X{ X char command[LINESIZ]; X X#ifdef BSD X int i; X X if (strcmp(dir, "./") == NULL) X return; X if (dir[0] == '/' || dir[0] == '~') X strcpy(cwd, dir); X if (strcmp(dir, "../") == NULL) { X for (i=strlen(cwd); cwd[i] != '/' && i > 0; i--); X cwd[i] = '\0'; X if (strcmp(cwd, "") == NULL) X strcpy(cwd, "/"); X } X else { X sprintf(cwd, "%s/%s", cwd, dir); X LASTCH(cwd) = '\0'; X } X#else X sprintf(command, "cd %s\n", dir); X query_dbx(command); X#endif X} X X X/* Determines if a directory entry should appear in the file menu. X * The files included in the menu are : X * .. (parent directory) X * directories X * text files X * executable files X */ Xstatic int InList(entry) XDirectory *entry; X{ X char pathname[LINESIZ]; X struct stat statbuf; X X if (strcmp(entry->d_name, ".") == NULL || /* ignore current directory */ X LASTCH(entry->d_name) == '~' || /* ignore Emacs backup files */ X (LASTCH(entry->d_name) == 'o' && SECLASTCH(entry->d_name) == '.')) X /* ignore object files */ X return False; X if (entry->d_name[0] == '.' && entry->d_name[1] != '.') X return False; /* ignore hidden files */ X if (strcmp(cwd, "")) /* give full path name */ X sprintf(pathname, "%s/%s", cwd, entry->d_name); X else X strcpy(pathname, entry->d_name); X if (stat(pathname, &statbuf) == -1) X return False; X if (statbuf.st_mode & S_IFDIR) { /* is directory */ X strcat(entry->d_name, "/"); X ++(entry->d_namlen); X return True; X } X if (statbuf.st_mode & S_IEXEC) { /* is executable */ X strcat(entry->d_name, "*"); X ++(entry->d_namlen); X return True; X } X#ifdef GDB X /* for GDB, we only want directories and executable files */ X return FALSE; X#else X return True; X#endif /* GDB */ X} X X X/* Scans the working directory for files selected by InList(), sorted X * alphabetically, and stored in an array of pointers to directory X * entries called namelist. X * The names of the selected files are stored in filelist. X */ Xstatic void ScanDir(dir) Xchar *dir; X{ X extern alphasort(); X Directory **namelist; X int i, j; X X nfiles = scandir(dir, &namelist, InList, alphasort); X if (nfiles == -1) { X UpdateMessageWindow("scandir: cannot open %s", dir); X return; X } X if (filelist) { X for (i=0; filelist[i]; i++) X XtFree(filelist[i]); X XtFree(filelist); X } X filelist = (char **) XtMalloc((nfiles+1) * sizeof(char *)); X i = 0; X for (j=0; j<nfiles; j++) { X filelist[i++] = XtNewString(namelist[j]->d_name); X XtFree(namelist[j]); X } X filelist[i++] = NULL; X XtFree(namelist); X return; X} X X X/* Callback for the fileMenu list widget. X * > if the selected item is a directory, display contents of that directory. X * > (Sun dbx only) if the selected item is an executable file, issue the X * debug command. X * > if the selected item is a readable file, display the file. X */ X/* ARGSUSED */ Xstatic void DisplayMenuFile(w, popupshell, call_data) X Widget w; X Widget popupshell; X XawListReturnStruct *call_data; X{ X char string[LINESIZ], *filename, command[LINESIZ]; X X XtPopdown(popupshell); X filename = call_data->string; X if (filename == NULL) return; X if (LASTCH(filename) == '/') { X changeDir(filename); X XtDestroyWidget(popupshell); X UpdateFileMenu(); /* create new menu */ X File(); /* pop it up */ X } X else if (LASTCH(filename) == '*') { X UpdateMessageWindow(""); X#ifdef GDB X /* for GDB, we send the commands : exec-file & symbol-file */ X X /* (PW)21DEC90 : this button is special because it has to send X TWO commands to GDB. We should wait for the prompt before X sending the second command !. X I think it is cleaner to send this 2nd command in the parser X after it matches 'exec-file' command. X But do that latter X */ X X strcpy(string, filename); X LASTCH(string) = '\0'; X X sprintf(command, "exec-file %s\n", string); X send_command(command); X AppendDialogText(command); X X Echo = True; X Parse = True; X Prompt = False; X while (!Prompt) X read_dbx(); X X sprintf(command, "symbol-file %s\n", string); X send_command(command); X AppendDialogText(command); X#else X#ifndef BSD X strcpy(string, filename); X LASTCH(string) = '\0'; X sprintf(command, "debug %s\n", string); X send_command(command); X AppendDialogText(command); X#endif X#endif /* GDB */ X } X else { X UpdateMessageWindow(""); X#ifndef GDB X sprintf(command, "file %s\n", filename); X send_command(command); X AppendDialogText(command); X#endif /* GDB */ X } X} X X X/* Callback to popdown the file menu X */ X/* ARGSUSED */ Xstatic void CancelFileMenu(w, popupshell, call_data) X Widget w; X Widget popupshell; X caddr_t call_data; X{ X XtPopdown(popupshell); X UpdateMessageWindow(""); X} X X X/* Creates a popup shell with its child being a vpane widget containing X * a file menu label, a file menu containing file names returned from X * ScanDir(), and a cancel command button. X * When an item in the list is selected, DisplayMenuFile is called. X */ Xstatic void SetUpFileMenu(dir) Xchar *dir; X{ X Widget cancelButton; X Arg args[MAXARGS]; X Cardinal n; X char menulabel[LINESIZ]; X int ncolumns; X X n = 0; X popupshell = XtCreatePopupShell("File Directory", transientShellWidgetClass, X toplevel, args, n); X X n = 0; X popup = XtCreateManagedWidget("popup", panedWidgetClass, popupshell, X args, n); X ScanDir(dir); X strcpy(fileMenuDir, dir); X X n = 0; X sprintf(menulabel, " %s ", dir); X XtSetArg(args[n], XtNlabel, (XtArgVal) menulabel); n++; X XtSetArg(args[n], XtNjustify, (XtArgVal) XtJustifyCenter); n++; X fileMenuLabel = XtCreateManagedWidget("fileMenuLabel", labelWidgetClass, X popup, args, n); X X n = 0; X ncolumns = nfiles/FILES_PER_COL + 1; X ncolumns = MIN(ncolumns, MAXCOLUMNS); X XtSetArg(args[n], XtNlist, filelist); n++; X XtSetArg(args[n], XtNverticalList, True); n++; X XtSetArg(args[n], XtNdefaultColumns, (XtArgVal) ncolumns); n++; X fileMenu = XtCreateManagedWidget("fileMenu", listWidgetClass, X popup, args, n); X XtAddCallback(fileMenu, XtNcallback, DisplayMenuFile, popupshell); X X n = 0; X XtSetArg(args[n], XtNresize, False); n++; X XtSetArg(args[n], XtNlabel, "CANCEL"); n++; X cancelButton = XtCreateManagedWidget("cancelButton", commandWidgetClass, X popup, args, n); X XtAddCallback(cancelButton, XtNcallback, CancelFileMenu, popupshell); X X DisableWindowResize(fileMenuLabel); X DisableWindowResize(cancelButton); X} X X X/* This routine is called when there is a a change in current directory. X * It destroys the existing popup shell and creates a new file menu based X * on the new current directory. A new directory list is created. X */ Xstatic void UpdateFileMenu() X{ X SetUpFileMenu(cwd); X#ifdef GDB X query_dbx("info directories\n"); X#else X query_dbx("use\n"); X#endif /* GDB */ X} X X X/* File command button callback. X */ X/* ARGSUSED */ Xvoid File(w, client_data, call_data) X Widget w; X caddr_t client_data; X caddr_t call_data; X{ X Arg args[MAXARGS]; X Cardinal n; X Position x, y, x_offset; X Dimension fileMenu_width, fileMenuLabel_width, border_width, X width, dialog_width; X X XDefineCursor(display, XtWindow(toplevel), watch); X XDefineCursor(display, XtWindow(sourceWindow), watch); X XDefineCursor(display, XtWindow(dialogWindow), watch); X XFlush(display); X if (strcmp(fileMenuDir, cwd)) X UpdateFileMenu(); X X n = 0; X XtSetArg(args[n], XtNwidth, &fileMenu_width); n++; X XtSetArg(args[n], XtNborderWidth, &border_width); n++; X XtGetValues(fileMenu, args, n); X X n = 0; X XtSetArg(args[n], XtNwidth, &fileMenuLabel_width); n++; X XtGetValues(fileMenuLabel, args, n); X X n = 0; X XtSetArg(args[n], XtNwidth, &dialog_width); n++; X XtGetValues(dialogWindow, args, n); X X width = MAX(fileMenu_width, fileMenuLabel_width); X x_offset = (Position) (dialog_width - width - border_width); X XtTranslateCoords(dialogWindow, x_offset, 0, &x, &y); X X x = MAX(0, x); X y = MAX(0, y); X X n = 0; X XtSetArg(args[n], XtNx, x); n++; X XtSetArg(args[n], XtNy, y); n++; X XtSetValues(popupshell, args, n); X XtPopup(popupshell, XtGrabNonexclusive); X X#ifdef GDB X UpdateMessageWindow("Select an executable file or a directory"); X#else X UpdateMessageWindow("Select a file or directory"); X#endif /* GDB */ X XUndefineCursor(display, XtWindow(toplevel)); X XUndefineCursor(display, XtWindow(sourceWindow)); X XUndefineCursor(display, XtWindow(dialogWindow)); X} END_OF_FILE if test 13542 -ne `wc -c <'filemenu.c'`; then echo shar: \"'filemenu.c'\" unpacked with wrong size! fi # end of 'filemenu.c' fi if test -f 'gdb_handler.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'gdb_handler.c'\" else echo shar: Extracting \"'gdb_handler.c'\" \(14177 characters\) sed "s/^X//" >'gdb_handler.c' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* gdb_handler.c X * X * WARNING : gdb_handler.c is included by handler.c for GDB. X * X * Contain action handlers for the parser to invoke upon a dbx command. X * X * updown_handler(): Update file, line label, updown arrow position. X * debug_handler(): Check directory use list, display main source file. X * pwd_handler(): Update current working directory. X * search_handler(): Adjust source file to display matched line. X * display_info_handler(): Update display window. X * break_handler(): Place stop sign on line or function or address specified. X * info_dir_handler(): Update search directory list. X * directory_handler(): Update search directory list. X * list_handler(): Adjust source file to display result. X * info_line_handler(): Update current file. X * delete_handler(): Remove stop sign. X * display_handler(): Update display window. X * info_break_handler(): Update stop signs. X * cd_handler(): Record current working directory. X * frame_curr_handler(): Update current function name. X * exec_handler(): Update file, line label, arrow position. X * done_handler(): Progrm execution completed, clear breakpoints X * source_handler(): Exec commands of source file specified. X * query_dbx_echo(): Send command with echo on. X */ X X Xvoid query_dbx_echo(); X X/* X * Display an outlined arrow to locate the calling routine in a stack X * frame. BSD and SUN dbx have slightly different output semantics here. X * The appropriate file with the calling routine is displayed and the X * file variable is set accordingly. X */ Xvoid updown_handler() X{ X char command[LINESIZ], *func, *file; X int line; X X line = Token.line; X func = XtNewString(Token.func); X#ifdef MIPS X LoadCurrentFile(); X#endif X#ifdef BSD X file = GetPathname(Token.file); X#else X if (line <= 0) line = 1; X LoadCurrentFile(); X if (displayedFile) X file = displayedFile->pathname; X#endif X X if (line <= 0 || func == NULL || file == NULL) X { X XtFree(func); X return; X } X X if (displayedFile && strcmp(file, displayedFile->pathname)) { X LoadFile(file); X } X updown.line = line; X strcpy(updown.func, func); X if (displayedFile) X strcpy(updown.file, displayedFile->pathname); X AdjustText(line); X XtFree(func); X} X X/* ARGSUSED */ Xvoid debug_handler() X{ X /* debug_handler is executed at start-up and with 'symbol-file' command */ X X query_dbx("set screensize 0\n"); X query_dbx("set prettyprint on\n"); X query_dbx("info directories\n"); X X displayedFile = NULL; /* force reloading of source file */ X X /* here we use query_dbx_echo instead of query_dbx so that any X error message will be displayed ! */ X X query_dbx_echo("list ,main\n"); /* tell gdb to use main file X and get line number of main(). (,main will end at main) */ X X if (LoadCurrentFile() == 0) X { X arrow.line = 0; /* clear arrow sign */ X updown.line = 0; /* clear updown sign */ X bomb.line = 0; /* clear bomb sign */ X UpdateArrow(displayedFile); X UpdateUpdown(displayedFile); X UpdateBomb(displayedFile); X ClearStops(); X UpdateStops(displayedFile); X } X X UpdateMessageWindow("Ready for execution"); X query_dbx("display\n"); /* clear display window */ X} X X/* ARGSUSED */ Xvoid pwd_handler(s) Xchar *s; X{ X strcpy(cwd, (char *)strtok(s, "\n")); X} X X/* ARGSUSED */ Xvoid search_handler() X{ X AdjustText(Token.line); X} X X/* ARGSUSED */ X/* Show output on the display window. X * If output is null but the display window is managed, replace contents of X * the display window with the null string. X */ Xvoid display_info_handler() X{ X Arg args[MAXARGS]; X Cardinal n; X X if (!Token.display || strcmp(Token.display, "") == NULL) { X if (!XtIsManaged(displayWindow)) X return; X else { X XtFree(Token.display); X Token.display = XtNewString(""); X } X } X if (!XtIsManaged(displayWindow)) { X XtManageChild(separator); X XtManageChild(displayWindow); X } X n = 0; X XtSetArg(args[n], XtNstring, (XtArgVal) Token.display); n++; X XtSetValues(displayWindow, args, n); X XtFree(Token.display); X Token.display = 0; /*(PW)14JAN91 */ X} X X/* Place a stop sign next to the line specified on the source file window X * if it is to be viewable. X */ Xvoid break_handler() X{ Xchar * file; Xint line; Xint stop; X X if (Token.stop == 0 || Token.line == 0 || Token.file == 0) X return; X X line = Token.line; X stop = Token.stop; X X if (Token.stop >= 256) /* see MAXSTOPS in signs.c */ X { X fprintf(stderr,"Too many breakpoints\n"); X return; X } X X /* load & display file if none is displayed */ X X file = GetPathname(Token.file); X X if (file == NULL) X return; /* (PW)11JAN91 */ X X if (displayedFile == NULL) X { X LoadFile(file); X AdjustText(line); X } X X stops[stop].file = file; X stops[stop].line = line; X stops[stop].tag = 0; X nstops = stop; X X /* display breakpoint sign if file is displayed */ X X if (displayedFile) X { X if (!strcmp(file, displayedFile->pathname)) X DisplayStop(displayedFile, line); X } X} X X/* info directories X */ Xvoid info_dir_handler() X{ X if (Token.file) X MakeDirList(Token.file); X} X X/* ARGSUSED */ Xvoid directory_handler(output) Xchar *output; X{ X /* Note : for GDB, the 'directory' command with no X parameter will reset search directories to current X directory only. GDB requires confirmation */ X X query_dbx("info directories\n"); X} X Xvoid list_handler() X{ X int line; X X line = Token.line; X X if (line) X { X /* We will display the last line listed. X Since we used 'list ,main' we will effectively display main in that case. */ X X LoadCurrentFile(); X AdjustText(line); X } X else X { X AppendDialogText("Error list command\n"); X bell(0); X } X} X X/* ARGSUSED */ Xvoid info_line_handler() /* Command was 'info line' */ X{ X if (Token.file) X strcpy(CurrentFile, Token.file); X else X strcpy(CurrentFile, ""); X} X X/* X * Delete handler remove the stop specified and undisplayed the stopsign X * if it's visible. X * It calls the dbx status command to find out what stops are left, and X * then update the array of stops accordingly. X */ X/* ARGSUSED */ X Xvoid delete_handler() X{ X query_dbx("info break\n"); /* update breakpoints */ X} X Xvoid display_handler() /* display or undisplay */ X{ X query_dbx("display\n"); /* update display */ X} X X/* X(gdb) info break XBreakpoints: XNum Enb Address Where X#1 y 0x000022f4 in main (pw.c line 34) X#2 y 0x000022a0 in foo (pw.c line 5) X(gdb) info break XNo breakpoints. X*/ X Xvoid info_break_handler(output_string) Xchar *output_string; X{ Xint i; Xint line; Xchar c; X X if (!output_string) X return; X X while(*output_string) X { X if (*(output_string++) == '#') X { X if (sscanf(output_string, "%d %c", &i,&c) == 2) X if (i > 0 && i <= nstops && stops[i].line > 0 && c == 'y') X stops[i].tag = 1; X } X } X X for (i=1; i<=nstops; i++) X if (stops[i].line > 0) X { X if (stops[i].tag) X stops[i].tag = 0; X else X { X line = stops[i].line; X stops[i].line = 0; X stops[i].file = NULL; X if (LineToStop_no(line) == 0) X RemoveStop(line); X } X } X} X X/* ARGSUSED */ Xvoid cd_handler(s) Xchar *s; X{ X strcpy(cwd,s); X} X X/* this handler justs update the function name. XBecause the function name is not always displayed Xafter next,step ... */ X Xstatic char* funcname = 0; X Xvoid frame_curr_handler() X{ X if (Token.func == NULL) X return; X X if (funcname) X { X XtFree(funcname); X funcname = 0; X } X X funcname = XtNewString(Token.func); X} X X/* Handle dbx output of run, cont, next, step, return commands. X * Result of output parsing is returned in a set of tokens. X * X * If message is not 0, this is an important message and should X * be displayed instead of Token.mesg. X * This message will hold the Bus error and segmentation violation errors. X * signal is the signal number received (if any). X */ Xvoid exec_handler(message,signal) Xchar *message; Xint signal; X{ X int line, status; X char *func; X X /* Print "stopped in ..." line in message window X * Adjust text displayed X */ X if (Token.line == 0) X return; X X if (message) X UpdateMessageWindow(message); X else X UpdateMessageWindow(Token.mesg); X X line = Token.line; X func = (Token.func) ? XtNewString(Token.func) : 0; X X#ifdef MIPS X status = LoadCurrentFile(); X#else X if (Token.file) X status = LoadFile(Token.file); X#endif X X#ifndef BSD X display_info_handler(); /* uses Token.display ! */ X#endif X X /* because of tbreak, we have to call info break here */ X X query_dbx("info break\n"); /* update breakpoints */ X X if (func == NULL) X { X query_dbx("frame\n"); /* this will just update funcname (see frame_curr_handler) */ X func = funcname; X if (func == NULL) X return; X funcname = 0; /* tell frame_curr_handler WE are going to XtFree it */ X } X X arrow.line = line; /* update arrow sign position */ X strcpy(arrow.func, func); X X updown.line = 0; /* remove updown, if any */ X if (displayedFile) { X strcpy(arrow.file, displayedFile->pathname); X } X X /* Display bomb sign if segmentation fault occurs in source code */ X X if (status != -1 && message && signal == SIGSEGV) { X arrow.line = 0; X bomb.line = line; X if (func) X strcpy(bomb.func, func); X if (displayedFile) strcpy(bomb.file, displayedFile->pathname); X } X else X bomb.line = 0; X X AdjustText(line); X XtFree(func); X} X X/* Remove all the arrow and updown signs, print message, then X * change the file variable to the file name displayed. X */ Xvoid done_handler(message,signal) Xchar *message; Xint signal; X{ X char command[LINESIZ]; X X arrow.line = 0; X updown.line = 0; X UpdateArrow(displayedFile); X UpdateUpdown(displayedFile); X UpdateMessageWindow("Ready for execution"); X} X X/* WARNING : source_handler() is NOT called by the parser. XIt is called by gdb_source_command() in gdb_parser.c. XThis is because 'source' command is NEVER sent to gdb, Xinstead xxgdb sends the commands in the specified file Xone by one. */ X Xvoid source_handler() X{ Xchar *file; XFILE *fp; Xchar s[LINESIZ]; X X if (!Token.file || strcmp(Token.file, "") == NULL) X { X XtFree(Token.file); X Token.file = XtNewString(".gdbinit"); /* default is .gdbinit */ X } X X file = GetPathname(Token.file); X X if (file == NULL) X return; /* (PW)11JAN91 */ X X if (fp = fopen(file, "r")) X { X while (fgets(s, LINESIZ, fp)) X { X /* DO NOT SEND \n and Take care of source command */ X if ((*s != '#') && strcmp(s,"\n") && (!gdb_source_command(s,TRUE))) X { X write_dbx(s); X insert_command(s); X AppendDialogText(s); X Prompt = False; X while (!Prompt) X read_dbx(); X } X } X close(fp); X } X} X X/* Sends a command to dbx and read the corresponding output, directly X * invoking the Xt input procedure, read_dbx(). X * X * Same as query_dbx() in dbx.c except that Echo = True. X */ Xvoid query_dbx_echo(command) Xchar *command; X{ X write_dbx(command); X insert_command(command); X X Echo = True; X Prompt = False; X while (!Prompt) X read_dbx(); X X Parse = True; /* Always reset Parse and Echo to True */ X Echo = True; X} END_OF_FILE if test 14177 -ne `wc -c <'gdb_handler.c'`; then echo shar: \"'gdb_handler.c'\" unpacked with wrong size! fi # end of 'gdb_handler.c' fi if test -f 'parser.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'parser.c'\" else echo shar: Extracting \"'parser.c'\" \(12874 characters\) sed "s/^X//" >'parser.c' <<'END_OF_FILE' X/***************************************************************************** X * X * xdbx - X Window System interface to the dbx debugger X * X * Copyright 1989 The University of Texas at Austin X * Copyright 1990 Microelectronics and Computer Technology Corporation X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of The University of Texas X * and Microelectronics and Computer Technology Corporation (MCC) not be X * used in advertising or publicity pertaining to distribution of X * the software without specific, written prior permission. The X * University of Texas and MCC makes no representations about the X * suitability of this software for any purpose. It is provided "as is" X * without express or implied warranty. X * X * THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO X * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND X * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR X * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER X * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF X * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN X * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. X * X * Author: Po Cheung X * Created: March 10, 1989 X * X ***************************************************************************** X * X * xxgdb - X Window System interface to the gdb debugger X * X * Copyright 1990 Thomson Consumer Electronics, Inc. X * X * Permission to use, copy, modify, and distribute this software and its X * documentation for any purpose and without fee is hereby granted, X * provided that the above copyright notice appear in all copies and that X * both that copyright notice and this permission notice appear in X * supporting documentation, and that the name of Thomson Consumer X * Electronics (TCE) not be used in advertising or publicity pertaining X * to distribution of the software without specific, written prior X * permission. TCE makes no representations about the suitability of X * this software for any purpose. It is provided "as is" without express X * or implied warranty. X * X * TCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING X * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT X * SHALL TCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES X * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, X * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, X * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS X * SOFTWARE. X * X * Adaptation to GDB: Pierre Willard X * XXGDB Created: December, 1990 X * X *****************************************************************************/ X X/* parser.c: X * X * Parse output messages from dbx using regular expression pattern matching, X * and take appropriate action. X * X * compile(): Compile the regular expressions in a table. X * match(): Try to best match a given string with the regular X * expressions found in the table and return an index. X * parser_init(): Initialization. X * parse(): Parse the dbx output and invoke the appropriate action X * handler. X * filter(): Modify the dbx output before it gets displayed on the X * dialog window. X * query_dbx(): Send a query command to dbx and process it. X */ X X#include "global.h" X#include "regex.h" X#ifdef GDB X#include "gdb_regex.h" X#else X#ifdef BSD X#ifdef MIPS X#include "mips_regex.h" X#else X#include "bsd_regex.h" X#endif X#else X#include "sun_regex.h" X#endif X#endif /* GDB */ X X#define BYTEWIDTH 8 X#define RE_BUFFER 100 X XTokens Token; /* gloabl token structure */ XBoolean Parse = True; /* Parse flag for parse routine */ X X/* X * Compile all the regular expression patterns in a pattern table. X * A pattern table is an array of pattern records. X * Each pattern record consists of a regular X * expression, a buffer for the to-be-compiled regular expression, X * and an array to associate a given token with a matched register number. X */ Xstatic void compile(patternTable) XPatternRec *patternTable; X{ X PatternRec *p; X char fastmap[(1 << BYTEWIDTH)]; X int i; X X for (i=0; patternTable[i].pat; i++) { X p = &patternTable[i]; X p->buf = (struct re_pattern_buffer *) X XtMalloc (sizeof (struct re_pattern_buffer)); X p->buf->allocated = RE_BUFFER; X p->buf->buffer = (char *) XtMalloc (p->buf->allocated); X p->buf->fastmap = fastmap; X p->buf->translate = NULL; X re_compile_pattern(p->pat, strlen(p->pat), p->buf); X re_compile_fastmap(p->buf); X } X} X X/* X * This routine tries to match a given string with each regular X * expression in a given pattern table. The best match is found, and X * the function returns an index to the pattern table. X */ X#ifndef GDB /* for GDB, match is called from gdb_parser.c */ Xstatic X#endif Xint match(patternTable, string, type) X PatternRec *patternTable; X char *string; X int type; X{ X struct re_registers regs; X int m, bestmatch = -1, index = -1, i, j, r, start, n; X char *s; X X if (strcmp(string, "") == NULL) return -1; X for (i=0; patternTable[i].pat; i++) { X if (type != C_ANY && type != i) X continue; X m = re_match(patternTable[i].buf, string, strlen(string), 0, ®s); X if (m == -2 ) { /* match error - failure stack overflow */ X#ifdef GDB X fprintf(stderr, "xxgdb error: regular expression matching failed \ X(failure stack overflow)\n"); X#else X fprintf(stderr, "xdbx error: regular expression matching failed \ X(failure stack overflow)\n"); X#endif X return (-1); X } X if (m > bestmatch) { X bestmatch = m; X index = i; X#ifdef GDB X /* for GDB, free memory (if not done earlier) */ X XtFree(Token.mesg); X XtFree(Token.file); X XtFree(Token.func); X XtFree(Token.display); X#endif /* GDB */ X Token.mesg = Token.file = Token.func = Token.display = NULL; X Token.line = Token.stop = 0; X for (j=0; j<NTOKENS; j++) { X if ((r = patternTable[i].reg_token[j]) >= 0) { X start = regs.start[r]; X if ((n = regs.end[r] - start) > 0) { X#ifdef GDB X /* The following error could happen if the pattern table is not correct, X better test it here.. */ X X if ( n > strlen(string)) /* Something is wrong here ! */ X { X fprintf(stderr,"Error match() : n = %d is too big\n",n); X n = 0; X } X#endif /* GDB */ X s = (char *) XtMalloc ((n+1) * sizeof(char)); X strncpy(s, string+start, n); X s[n] = '\0'; X switch (j) { X case TK_MESG: Token.mesg = s; break; X case TK_STOP: Token.stop = atoi(s); XtFree(s); break; X case TK_FUNC: Token.func = s; break; X case TK_LINE: Token.line = atoi(s); XtFree(s); break; X case TK_FILE: Token.file = s; break; X case TK_DISP: Token.display = s; break; X } X } X } X } X } X } X return index; X} X X/* Compile the regular expressions in the output and command pattern tables. */ X Xvoid parser_init() X{ X compile(output_pattern); X compile(command_pattern); X compile(dataPattern); X} X X X#ifdef GDB X X#include "gdb_parser.c" X X#else /*>>>>>>>>>> ALL THE FOLLOWING IS NOT COMPILED FOR GDB <<<<<<<<<<<<<<<<<<<*/ X X/* This routine first parses the command string. X * If the command is one of run, cont, next, step, stop at, stop in, X * where, up, or down, it parses the dbx output to decide what action X * to take and dispatch it to one of the handlers. X * For other commands, the appropriate handler is called. X * X * !!! This routine has to be re-entrant. X */ Xvoid parse(output, command) Xchar *output; Xchar *command; X{ X int command_type; X char *output_string; X X if (debug) { X fprintf(stderr, "parse(output = %s, command = %s)\n", output, command); X } X X /* Make a local copy of `output' and use that instead */ X output_string = XtNewString(output); X if (output) strcpy(output, ""); X X if (!command) { X if (match(output_pattern, output_string, O_DEBUG) != -1) X debug_handler(); X debug_init(); X return; X } X if (!Parse) X return; X X command_type = match(command_pattern, command, C_ANY); X switch (command_type) { X case C_EXEC: X if (match(output_pattern, output_string, O_EXEC) != -1) X exec_handler(); X else if (match(output_pattern, output_string, O_DONE) != -1) X done_handler(); X else X bell(0); X break; X case C_STOPAT: X if (match(output_pattern, output_string, O_STOPAT) != -1) X stop_at_handler(); X else X bell(0); X break; X case C_STOPIN: X if (match(output_pattern, output_string, O_STOPIN) != -1) X stop_in_handler(); X else X bell(0); X break; X case C_UPDOWN: X if (match(output_pattern, output_string, O_UPDOWN) != -1) X updown_handler(); X else X bell(0); X break; X case C_SEARCH: X if (match(output_pattern, output_string, O_SEARCH) != -1) X search_handler(); X else X bell(0); X break; X case C_DELETE: X delete_handler(); X break; X case C_FILE: X if (match(output_pattern, output_string, O_FILE) != -1) X file_handler(); /* command was 'file' */ X else X LoadCurrentFile(); /* command was 'file ...' */ X break; X case C_LIST: X if (match(output_pattern, output_string, O_LIST) != -1) X list_handler(); X else X bell(0); X break; X case C_FUNC: X#ifdef MIPS X if (match(output_pattern, output_string, O_FUNC) != -1) X#else X if (strcmp(output_string, "") == NULL) X#endif X func_handler(); X else X bell(0); X break; X case C_USE: X use_handler(output_string); X break; X X#ifndef BSD X case C_PRINT: X if (match(output_pattern, output_string, O_PRINT) != -1) X print_handler(output_string); X else X bell(0); X break; X case C_DEBUG: X if (match(output_pattern, output_string, O_DEBUG) != -1) X debug_handler(); X else X bell(0); X break; X case C_CD: X if (strcmp(output_string, "") == NULL) X cd_handler(); X else X bell(0); X break; X case C_PWD: X pwd_handler(output_string); X break; X case C_DISPLAY: X if (strcmp(output_string, "") == NULL || X match(output_pattern, output_string, O_PRINT) != -1) X display_handler(); X else X bell(0); X break; X#endif X#ifdef BSD X case C_STATUS: X break; X#endif X X default: X break; X } X XtFree(output_string); X} X X/* This function edits the dbx output so that unnecessary information is X * not displayed on the dialog window. X * It filters away the some output returned by the execution commands; X * output from the search commands, and the display command. X * On Sun dbx, it also filters away part of the output returned by the X * up and down commands. X */ Xvoid filter(string, output, command) Xchar *string, *output, *command; X{ X struct re_registers regs; X char *p; X int r; X static Boolean deleteRest = False; X int command_type = -1; X X if (output == NULL || strcmp(output, "") == NULL) X return; X X X#ifdef BSD X if (!command) { X AppendDialogText(string); X return; X } X#endif X X if (command) X command_type = match(command_pattern, command, C_ANY); X if (command_type == C_EXEC) { X if (re_match(output_pattern[O_EXEC].buf, string, strlen(string), 0, X ®s) > 0) { X r = output_pattern[O_EXEC].reg_token[TK_MESG]; X for (p=string+regs.start[r]; p!=string && *(p-1) != '\n'; p--); X strcpy(p, ""); X if (!Prompt) X deleteRest = True; X } X else if (deleteRest) { X strcpy(string, ""); X if (Prompt) X deleteRest = False; X } X AppendDialogText(string); X return; X } X X if (Prompt) { X char *s; X X s = XtNewString(output); X switch (command_type) { X#ifndef BSD X case C_UPDOWN: X if (match(output_pattern, s, O_UPDOWN) != -1) X strcpy(s, Token.mesg); X break; X case C_DISPLAY: X if (match(output_pattern, s, O_PRINT) != -1) X strcpy(s, ""); X break; X#endif X#ifdef MIPS X case C_UPDOWN: X if (match(output_pattern, s, O_UPDOWN) != -1) X strcpy(s, Token.mesg); X strcat(s, "\n"); X break; X case C_FUNC: X if (match(output_pattern, s, O_FUNC) != -1) X strcpy(s, ""); X break; X#endif X case C_SEARCH: X if (match(output_pattern, s, O_SEARCH) != -1) X strcpy(s, ""); X break; X case C_LIST: X if (match(output_pattern, s, O_LIST) != -1) X strcpy(s, ""); X break; X default: X s = XtNewString(string); /* append 'string' only */ X break; X } X AppendDialogText(s); X XtFree(s); X } X else { X switch (command_type) { X#ifndef BSD X case C_UPDOWN: X case C_DISPLAY: X#endif X#ifdef MIPS X case C_UPDOWN: X case C_FUNC: X#endif X case C_SEARCH: X case C_LIST: X break; X default: X AppendDialogText(string); X break; X } X } X} X#endif /* NOT GDB */ END_OF_FILE if test 12874 -ne `wc -c <'parser.c'`; then echo shar: \"'parser.c'\" unpacked with wrong size! fi # end of 'parser.c' fi echo shar: End of archive 4 \(of 8\). cp /dev/null ark4isdone MISSING="" for I in 1 2 3 4 5 6 7 8 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 8 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Dan Heller ------------------------------------------------ O'Reilly && Associates Z-Code Software Senior Writer President argv@ora.com argv@zipcode.com