pierre@tce.COM (Pierre Willard) (03/07/91)
Submitted-by: pierre@tce.COM (Pierre Willard) Posting-number: Volume 11, Issue 55 Archive-name: xxgdb/part08 #! /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 7 (of 8)." # Contents: command.c datadpy.c # Wrapped by gilbert@phi on Tue Jan 15 13:12:50 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'command.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'command.c'\" else echo shar: Extracting \"'command.c'\" \(23715 characters\) sed "s/^X//" >'command.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/* command.c X * X * Create the command window, the command buttons and their callbacks. X * X * CreateCommandPanel() : Create a window with command buttons X * CreateButtons() : Create command buttons in panel X * AddButton() : Add a command button into the command window X * ButtonSet() : Action proc for command button translation X * X * Command callbacks for the command buttons: X * X * forwardSearch() : forward string search X * reverseSearch() : reverse string search X * Search() : call either forwardSearch() or reverseSearch() X * PopupSearch() : command callback for search button X * DoneSearch() : command callback for DONE button in search panel X * CreateSearchPopup() : create search panel X * X * Command queue manipulation routines: X * send_command(): send a command to dbx and record in the queue X * get_command(): read command off head of queue X * insert_command(): insert command at the head of queue X * delete_command(): delete command from head of queue X */ X X#include <signal.h> X#include <ctype.h> X#include <sys/wait.h> X#include "global.h" X X#define REVERSE 0 X#define FORWARD 1 X XWidget commandWindow; /* command panel with buttons */ XBoolean PopupMode = False; Xstatic int Button; Xstatic Widget searchPopupShell, searchPopup; Xstatic Widget AddButton(); Xstatic Widget button[30]; Xstatic char SearchString[BUFSIZ] = ""; /* search string buffer */ Xstatic char command[LINESIZ]; Xstatic CommandRec *commandQueue = NULL; X#ifdef BSD Xstatic char savedCommand[LINESIZ] = ""; X#endif X X/* ARGSUSED */ Xstatic void ButtonSet(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X Button = atoi(params[0]); X} X X/* ARGSUSED */ X/* Execute the dbx command specifed in client_data X */ Xstatic void DoIt (w, command, call_data) X Widget w; X XtPointer command; X XtPointer call_data; X{ X /* run, cont, next, step, where, up, down, status */ X send_command(command); X AppendDialogText(command); X} X X#ifndef GDB /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */ X/* ARGSUSED */ Xstatic void Return (w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *funcname; X int nbytes; X X funcname = XFetchBytes(display, &nbytes); /* from CUT_BUFFER0 */ X if (nbytes == 0) X strcpy(command, "return\n"); X else X sprintf(command, "return %s\n", funcname); X send_command(command); X AppendDialogText(command); X} X#endif /* NOT GDB */ X X#ifdef GDB /* >>>>>>>>>>>>>> GDB ONLY <<<<<<<<<<<<<<<< */ X/* X here client_data is "break" or "tbreak" X X*/ Xstatic void Break(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X XawTextPosition pos; X int line; X char *funcname; X int nbytes; X char *s; X X funcname = XFetchBytes(display, &nbytes); /* from CUT_BUFFER0 */ X if (nbytes) X { X s = funcname; X while (*s == ' ') s++; /* skip leading spaces (if any) */ X if ((*s >= '0') && (*s <= '9')) X sprintf(command, "%s *%s\n",client_data,funcname); X else X sprintf(command, "%s %s\n",client_data,funcname); X } X else X { X if (displayedFile != NULL) X { X pos = XawTextGetInsertionPoint(sourceWindow); X line = TextPositionToLine(pos); X sprintf(command, "%s %d\n",client_data,line); X } X else X { X UpdateMessageWindow(BREAK_HELP, NULL); X bell(0); X return; X } X } X X send_command(command); X AppendDialogText(command); X} X X#else /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */ X X/* ARGSUSED */ Xstatic void Stop_at(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X XawTextPosition pos; X int line; X X if (displayedFile == NULL) { X UpdateMessageWindow(STOP_AT_HELP, NULL); X bell(0); X return; X } X pos = XawTextGetInsertionPoint(sourceWindow); X line = TextPositionToLine(pos); X sprintf(command, "stop at %d\n", line); X send_command(command); X AppendDialogText(command); X} X X/* ARGSUSED */ Xstatic void Stop_in(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *funcname; X int nbytes; X X funcname = XFetchBytes(display, &nbytes); /* from CUT_BUFFER0 */ X if (nbytes == 0) { X UpdateMessageWindow(STOP_IN_HELP, NULL); X bell(0); X return; X } X sprintf(command, "stop in %s\n", funcname); X send_command(command); X AppendDialogText(command); X} X X#endif /* NOT GDB */ X X/* Delete removes the stop_no associated with a given line number. X * RemoveStop() is called to undisplay the stop sign only when there X * are no more stop_no's associated with that line number. X */ X/* ARGSUSED */ Xstatic void Delete(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X XawTextPosition pos; X char *string; X int stop_no, line, nbytes; X X string = XFetchBytes(display, &nbytes); X if (nbytes > 0 && (stop_no = atoi(string)) > 0) { X sprintf(command, "delete %d\n", stop_no); X send_command(command); X AppendDialogText(command); X return; X } X else if (displayedFile) { X pos = XawTextGetInsertionPoint(sourceWindow); X line = TextPositionToLine(pos); X if (stop_no = LineToStop_no(line)) { X sprintf(command, "delete %d\n", stop_no); X send_command(command); X AppendDialogText(command); X return; X } X } X UpdateMessageWindow(DELETE_HELP, NULL); X bell(0); X} X X/* ARGSUSED */ Xstatic void Print(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *string; X int nbytes; X X if (Button == 3) PopupMode = True; X X string = XFetchBytes(display, &nbytes); X if (nbytes == 0) { X UpdateMessageWindow(PRINT_HELP, NULL); X bell(0); X return; X } X if (client_data == (XtPointer)0) X sprintf(command, "print %s\n", string); X else if (client_data == (XtPointer)1) X sprintf(command, "print *%s\n", string); X send_command(command); X#ifdef GDB X if (!PopupMode) /* for GDB don't display print if everything goes in a window */ X#endif X AppendDialogText(command); X} X X#ifndef GDB /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */ X/* ARGSUSED */ Xstatic void Func(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *funcname; X int nbytes; X X funcname = XFetchBytes(display, &nbytes); X if (nbytes == 0) X strcpy(command, "func\n"); X else X sprintf(command, "func %s\n", funcname); X send_command(command); X AppendDialogText(command); X} X#endif /* NOT GDB */ X X/* ARGSUSED */ Xstatic void Quit(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X union wait status; X X write_dbx("quit\n"); X XtDestroyApplicationContext(app_context); X kill(dbxpid, SIGKILL); X wait3(&status, WNOHANG, NULL); X exit(0); X} X X X/* ARGSUSED */ Xstatic void Display_(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *string; X int nbytes; X X string = XFetchBytes(display, &nbytes); X sprintf(command, "display %s\n", string); X send_command(command); X AppendDialogText(command); X} X X#ifdef GDB /* >>>>>>>>>>>>>> GDB ONLY <<<<<<<<<<<<<<<< */ X/* ARGSUSED */ Xstatic void Undisplay(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *string; X int stop_no, nbytes; X X string = XFetchBytes(display, &nbytes); X if (nbytes != 0) X { X if ((stop_no = atoi(string)) > 0) X sprintf(command, "undisplay %d\n", stop_no); X else X { X UpdateMessageWindow(UNDISPLAY_HELP, NULL); X bell(0); X return; X } X } X else X sprintf(command, "undisplay\n"); X X send_command(command); X AppendDialogText(command); X} X X#else /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */ X X/* ARGSUSED */ Xstatic void Undisplay(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *string; X int stop_no, nbytes; X X string = XFetchBytes(display, &nbytes); X if (nbytes == 0) { X UpdateMessageWindow(UNDISPLAY_HELP, NULL); X bell(0); X return; X } X if ((stop_no = atoi(string)) > 0) X sprintf(command, "undisplay %d\n", stop_no); X else X sprintf(command, "undisplay %s\n", string); X send_command(command); X AppendDialogText(command); X} X#endif /* NOT GDB */ X X#ifndef GDB /* >>>>>>>>>> NOT USED FOR GDB <<<<<<<<<<<<<<< */ X/* ARGSUSED */ Xstatic void Dump(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X char *funcname; X int nbytes; X X funcname = XFetchBytes(display, &nbytes); X if (nbytes == 0) X strcpy(command, "dump\n"); X else X sprintf(command, "dump %s\n", funcname); X send_command(command); X AppendDialogText(command); X} X#endif /* NOT GDB */ X X X/* Beginning from startpos, this routine searches text forward for X * searchstring, and returns 1 if searchstring is found, also returning X * the left and right positions of the matched string in left and right; X * else 0 is returned. X * It also does wrap-around search. X */ Xstatic forwardSearch(text, startpos, searchstring, left, right) X char *text; X int startpos; X char *searchstring; X XawTextPosition *left, *right; X{ X int searchlength, searchsize, i, n=0; X char *s1, *s2; X X searchlength = strlen(searchstring); X searchsize = strlen(text) - searchlength; X for (i=startpos; i < searchsize; i++) { X n = searchlength; X s1 = &text[i]; X s2 = searchstring; X while (--n >= 0 && *++s1 == *s2++); X if (n < 0) break; X } X if (n < 0) { X *left = i+1; X *right = i+1+searchlength; X return 1; X } X else { X for (i=0; i < startpos; i++) { X n = searchlength; X s1 = &text[i]; X s2 = searchstring; X while (--n >= 0 && *++s1 == *s2++); X if (n < 0) break; X } X if (n < 0) { X *left = i+1; X *right = i+1+searchlength; X return 1; X } X return 0; X } X} X X X/* Similar to forwardSearch(), except that it does a reverse search X */ Xstatic reverseSearch(text, startpos, searchstring, left, right) X char *text; X XawTextPosition startpos; X char *searchstring; X XawTextPosition *left, *right; X{ X int searchlength, i, n=0; X char *s1, *s2; X X searchlength = strlen(searchstring); X for (i=startpos; i > searchlength; i--) { X n = searchlength; X s1 = &text[i]; X s2 = &searchstring[searchlength-1]; X while (--n >= 0 && *--s1 == *s2--); X if (n < 0) break; X } X if (n < 0) { X *right = i; X *left = *right-searchlength; X return 1; X } X else { X for (i=strlen(text)-1; i > startpos; i--) { X n = searchlength; X s1 = &text[i]; X s2 = &searchstring[searchlength-1]; X while (--n >= 0 && *--s1 == *s2--); X if (n < 0) break; X } X if (n < 0) { X *right = i; X *left = *right-searchlength; X return 1; X } X return 0; X } X} X X/* ARGSUSED */ Xstatic void PopupSearch(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X Arg args[MAXARGS]; X Cardinal n; X Dimension popup_width, dialog_width; X Position x, y; X X if (!displayedFile) { X UpdateMessageWindow(SEARCH_HELP, NULL); X bell(0); X } X else { X XtRealizeWidget(searchPopupShell); X n = 0; X XtSetArg(args[n], XtNwidth, &popup_width); n++; X XtGetValues(searchPopupShell, args, n); X n = 0; X XtSetArg(args[n], XtNwidth, &dialog_width); n++; X XtGetValues(dialogWindow, args, n); X XtTranslateCoords(dialogWindow, X (Position)(dialog_width - popup_width)/2, 10, &x, &y); X n = 0; X XtSetArg(args[n], XtNx, x); n++; X XtSetArg(args[n], XtNy, y); n++; X XtSetValues(searchPopupShell, args, n); X XtPopup(searchPopupShell, XtGrabNone); X } X} X X X/* ARGSUSED */ X/* This routine handles both forward and reverse text search. X * If no text has been entered, the contents of the cut buffer are used X * for searching. X */ Xstatic void Search(w, direction, call_data) X Widget w; X XtPointer direction; X XtPointer call_data; X{ X XawTextBlock textblock; X XawTextPosition pos, left, right; X char *searchString; X X searchString = XawDialogGetValueString(searchPopup); X if (strlen(searchString) == 0) { X textblock.ptr = XFetchBytes(display, &textblock.length); X if (!textblock.ptr) { X UpdateMessageWindow("No search string selected", NULL); X bell(0); X return; X } X searchString = textblock.ptr; X } X pos = XawTextGetInsertionPoint(sourceWindow); X if ((direction == (XtPointer)FORWARD && X forwardSearch(displayedFile->buf, pos, searchString, &left, &right)) || X (direction == (XtPointer)REVERSE && X reverseSearch(displayedFile->buf, pos, searchString, &left, &right))) { X AdjustText(TextPositionToLine(left)); X XawTextSetSelection(sourceWindow, left, right); X XawTextSetInsertionPoint(sourceWindow, left); X } X else { X if (direction == (XtPointer)FORWARD) X UpdateMessageWindow("String not found", NULL); X else if (direction == (XtPointer)REVERSE) X UpdateMessageWindow("String not found", NULL); X else X#ifdef GDB X UpdateMessageWindow("xxgdb error: illegal search direction", NULL); X#else X UpdateMessageWindow("xdbx error: illegal search direction", NULL); X#endif X bell(0); X } X} X X/* ARGSUSED */ Xstatic void DoneSearch(w, client_data, call_data) X Widget w; X XtPointer client_data; X XtPointer call_data; X{ X XtPopdown(client_data); X} X X/* ARGSUSED */ Xstatic void Activate(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X Search(w, (XtPointer)FORWARD, NULL); X DoneSearch(w, (XtPointer)searchPopupShell, NULL); X} X Xstatic void CreateSearchPopup() X{ X Widget dialogValue; X Arg args[MAXARGS]; X Cardinal n; X X static XtActionsRec search_actions[] = { X {"Activate", Activate}, X {NULL, NULL} X }; X X static String translations = "#override\n\ X <Key>Return: Activate() \n\ X "; X X n = 0; X XtSetArg(args[n], XtNinput, True); n++; X XtSetArg(args[n], XtNallowShellResize, True); n++; X searchPopupShell = XtCreatePopupShell("Search", transientShellWidgetClass, X toplevel, args, n); X X n = 0; X XtSetArg(args[n], XtNlabel, "Enter search string :"); n++; X XtSetArg(args[n], XtNvalue, SearchString); n++; X searchPopup = XtCreateManagedWidget("searchPopup", dialogWidgetClass, X searchPopupShell, args, n); X X AddButton(searchPopup, "<<", Search, (XtPointer) REVERSE); X AddButton(searchPopup, ">>", Search, (XtPointer) FORWARD); X AddButton(searchPopup, "DONE", DoneSearch, (XtPointer)searchPopupShell); X X dialogValue = XtNameToWidget(searchPopup, "value"); X XtOverrideTranslations(dialogValue, XtParseTranslationTable(translations)); X XtAppAddActions(app_context, search_actions, XtNumber(search_actions)); X} X X X Xstatic Widget AddButton(parent, name, function, client_data) XWidget parent; Xchar *name; Xvoid (*function) (); XXtPointer client_data; /* callback registered data */ X{ X Widget button; X Arg args[MAXARGS]; X Cardinal n; X X static XtActionsRec command_actions[] = { X {"ButtonSet", (XtActionProc) ButtonSet}, X {NULL, NULL} X }; X X static String translations = "\ X <EnterWindow>: highlight() \n\ X <LeaveWindow>: reset() \n\ X <Btn1Down>: set()\n\ X <Btn1Up>: ButtonSet(1) notify() unset() \n\ X <Btn3Down>: set()\n\ X <Btn3Up>: ButtonSet(3) notify() unset()\n\ X "; X X n = 0; X XtSetArg(args[n], XtNresize, (XtArgVal) False); n++; X if (strcmp(name, "print") == NULL || strcmp(name, "print *") == NULL) { X XtSetArg(args[n], XtNtranslations, X XtParseTranslationTable(translations)); n++; X } X button = XtCreateManagedWidget(name, commandWidgetClass, parent, args, n); X XtAddCallback(button, XtNcallback, function, client_data); X XtAppAddActions(app_context, command_actions, XtNumber(command_actions)); X return (button); X} X X Xstatic void CreateButtons (parent) XWidget parent; X{ X int i=0; X X#ifdef GDB /* >>>>>>>>>>>>>> GDB ONLY <<<<<<<<<<<<<<<< */ X button[i++] = AddButton (parent, "run", DoIt, "run\n"); X button[i++] = AddButton (parent, "cont", DoIt, "cont\n"); X button[i++] = AddButton (parent, "next", DoIt, "next\n"); X button[i++] = AddButton (parent, "step", DoIt, "step\n"); X button[i++] = AddButton (parent, "finish", DoIt, "finish\n"); X button[i++] = AddButton (parent, "break", Break, "break"); X button[i++] = AddButton (parent, "tbreak", Break, "tbreak"); X button[i++] = AddButton (parent, "delete", Delete, NULL); X button[i++] = AddButton (parent, "up", DoIt, "up\n"); X button[i++] = AddButton (parent, "down", DoIt, "down\n"); X button[i++] = AddButton (parent, "print", Print, (XtPointer)0); X button[i++] = AddButton (parent, "print *", Print, (XtPointer)1); X button[i++] = AddButton (parent, "display", Display_, NULL); X button[i++] = AddButton (parent, "undisplay", Undisplay, NULL); X button[i++] = AddButton (parent, "args", DoIt, "info args\n"); X button[i++] = AddButton (parent, "locals", DoIt, "info locals\n"); X button[i++] = AddButton (parent, "stack", DoIt, "info stack\n"); X button[i++] = AddButton (parent, "search", PopupSearch, NULL); X button[i++] = AddButton (parent, "file", File, NULL); X button[i++] = AddButton (parent, "quit", Quit, NULL); X#else /* >>>>>>>>>> IF NOT GDB <<<<<<<<<<<<<<< */ X X X button[i++] = AddButton (parent, "run", DoIt, "run\n"); X button[i++] = AddButton (parent, "cont", DoIt, "cont\n"); X button[i++] = AddButton (parent, "next", DoIt, "next\n"); X button[i++] = AddButton (parent, "step", DoIt, "step\n"); X#ifdef BSD X button[i++] = AddButton (parent, "return", Return, "return\n"); X#endif X button[i++] = AddButton (parent, "stop at", Stop_at, NULL); X button[i++] = AddButton (parent, "stop in", Stop_in, NULL); X button[i++] = AddButton (parent, "delete", Delete, NULL); X button[i++] = AddButton (parent, "where", DoIt, "where\n"); X button[i++] = AddButton (parent, "up", DoIt, "up\n"); X button[i++] = AddButton (parent, "down", DoIt, "down\n"); X button[i++] = AddButton (parent, "print", Print, (XtPointer)0); X button[i++] = AddButton (parent, "print *", Print, (XtPointer)1); X button[i++] = AddButton (parent, "func", Func, NULL); X button[i++] = AddButton (parent, "file", File, NULL); X button[i++] = AddButton (parent, "status", DoIt, "status\n"); X#ifndef BSD X button[i++] = AddButton (parent, "display", Display_, NULL); X button[i++] = AddButton (parent, "undisplay", Undisplay, NULL); X#endif X button[i++] = AddButton (parent, "dump", Dump, NULL); X button[i++] = AddButton (parent, "search", PopupSearch, NULL); X button[i++] = AddButton (parent, "quit", Quit, NULL); X#endif /* NOT GDB */ X X button[i++] = NULL; X CreateSearchPopup(); X} X X X/* Create a command widget, and the buttons. */ X Xvoid CreateCommandPanel(parent) XWidget parent; X{ X Arg args[10]; X Cardinal n; X X n = 0; X commandWindow = XtCreateManagedWidget("commandWindow", boxWidgetClass, X parent, args, n); X CreateButtons(commandWindow); X getwd(cwd); X} X X/************************************************************************** X * X * Command queue functions X * X **************************************************************************/ X X/* Append command to end of the command queue and send the command to dbx */ X Xvoid send_command(command) Xchar *command; X{ X CommandRec *p, *q, *r; X X#ifdef BSD X /* Save the command if it is not a blank command; else use the X last saved command instead */ X if (strcspn(command, " \n")) X strcpy(savedCommand, command); X else X strcpy(command, savedCommand); X#endif X X p = (CommandRec *)XtNew(CommandRec); X p->command = XtNewString(command); X p->next = NULL; X if (!commandQueue) X commandQueue = p; X else { X q = commandQueue; X while (r = q->next) X q = r; X q->next = p; X } X write_dbx(command); X} X X/* Read command at the head of the command queue */ X Xchar *get_command() X{ X if (commandQueue) { X return (commandQueue->command); X } X else X return NULL; X} X X/* Delete command from the head of the command queue */ X Xvoid delete_command() X{ X CommandRec *p; X X if (p = commandQueue) { X commandQueue = p->next; X XtFree(p->command); X XtFree(p); X } X} X X/* Insert command into head of queue */ X Xvoid insert_command(command) Xchar *command; X{ X CommandRec *p; X X p = (CommandRec *)XtNew(CommandRec); X p->command = XtNewString(command); X p->next = NULL; X if (!commandQueue) X commandQueue = p; X else { X p->next = commandQueue; X commandQueue = p; X } X} END_OF_FILE if test 23715 -ne `wc -c <'command.c'`; then echo shar: \"'command.c'\" unpacked with wrong size! fi # end of 'command.c' fi if test -f 'datadpy.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'datadpy.c'\" else echo shar: Extracting \"'datadpy.c'\" \(21580 characters\) sed "s/^X//" >'datadpy.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/* dataDpy.c: X * X * Provide graphical display of C pointers and structures. X * X * BuildLinePos(): Construct an array indexing the character position of X * each line. X * PositionToLine(): Return the character position of a given line. X * SelectPointer(): Action proc for double click on a pointer value, X * CreateDataPopup(): Create a popup to display the object pointed to by a X * pointer. X * UpdateDataPopup(): Update an unused popupshell to display data. X * AppendList(): Append a popup to the list. X * DeleteList(): Delete a popup from the list. X * pop_down(): pop down the popup and free storage. X * DestroyDataPopup():event handler for destroying a popup, call DeleteList() X * and pop_down(). X * MovePopup(): Position the popup. X * print_handler(): Action handler for displaying pointers and structures. X */ X X#include "global.h" X#include "regex.h" X#include "datadpy.h" X X#define MAXLEVELS 20 /* max level of indentation */ X#ifdef GDB X#define INDENT 2 /* # of spaces for each indentation */ X#else X#define INDENT 8 /* # of spaces for each indentation */ X#endif /* GDB */ X#define EMPTY 0 X#define UNUSED 1 X#define USED 2 X#define LEFT_MARGIN 10 X#define SCROLLBAR_WIDTH 15 X X Xstatic DataDpyRec **dataDpyTable; Xstatic int dataDpyTableSize = 0; Xstatic DataDpyRec *Parent = NULL; Xstatic DataDpyList *TopParentList = NULL; Xstatic int font_height, font_width; Xstatic void DestroyDataPopup(); X X/* X * Build an array which gives the starting text position of each line. X * Very similar to the routine in source.c. X */ Xstatic void BuildLinePos(dataDpy) XDataDpyRec *dataDpy; X{ X char *p; X int line, nlines; X int max=0; X X nlines = MAX(1, dataDpy->buflen/CHARS_PER_LINE); X dataDpy->linepos = (XawTextPosition *) X XtMalloc ((nlines+2) * sizeof(XawTextPosition)); X p = dataDpy->buf; X line = 0; X dataDpy->linepos[line++] = 0; X dataDpy->linepos[line++] = 0; X while (*p) { X if (*p++ == '\n') { X if (line == nlines) { /* buffer full, need more memory */ X dataDpy->linepos = (XawTextPosition *)XtRealloc(dataDpy->linepos, X (nlines + ADD_LINES) * sizeof(XawTextPosition)); X nlines += ADD_LINES; X } X dataDpy->linepos[line] = p - dataDpy->buf; X AssignMax(max, dataDpy->linepos[line] - dataDpy->linepos[line-1]); X line++; X } X } X dataDpy->numlines = line - 2; X dataDpy->maxLineLength = max; X /* shrink to min size */ X dataDpy->linepos = (XawTextPosition *) XtRealloc X (dataDpy->linepos, line * sizeof(XawTextPosition)); X} X X/* X * Return the line number for the specified text position. X */ Xstatic int PositionToLine(dataDpy, pos) XDataDpyRec *dataDpy; XXawTextPosition pos; X{ X int line; X X if (dataDpy && pos >= 0) { X for (line = 1; pos >= dataDpy->linepos[line]; line++); X return (line-1); X } X else X return (0); X} X X/* ARGSUSED */ X/* X * Called by double click of pointer button. X * If the selected text is a valid pointer, this routine parses the data X * output to obtain the full qualified name of the pointer, and asks X * dbx to print the value of the object the pointer is pointing to. X */ Xstatic void SelectPointer(w, event, params, num_params) X Widget w; X XEvent *event; X String *params; X Cardinal *num_params; X{ X struct re_registers regs; X XawTextPosition left, right; X char *selection, *p, *field[MAXLEVELS]; X DataDpyRec *dataDpy; X int fromLine, line; X int i, n, nbytes, r, level, newlevel; X char name[LINESIZ], command[LINESIZ]; X X /* Find out which data display output does the selection belong to */ X dataDpy = NULL; X for (i=0; dataDpyTable[i]; i++) X if ((Widget) w == (Widget) dataDpyTable[i]->dataDpyWindow) { X dataDpy = dataDpyTable[i]; X Parent = dataDpy; X break; X } X if (!dataDpy) return; X X /* Get the selection and check if it's a pointer value, 0x???? */ X selection = XFetchBytes(display, &nbytes); X if (re_match(dataPattern[D_POINTER].buf, selection, strlen(selection), 0, 0) X < 0) { X Parent = NULL; X return; X } X X /* Parse the output to get the fully qualified name of the pointer */ X XawTextGetSelectionPos(w, &left, &right); X fromLine = PositionToLine(dataDpy, left); X p = dataDpy->buf + dataDpy->linepos[fromLine]; X X if (re_match(dataPattern[D_FIELD].buf, p, strlen(p), 0, ®s) >= 0) { X r = dataPattern[D_FIELD].reg_token[TK_POINTER]; X if (strncmp(selection, p+regs.start[r], regs.end[r]-regs.start[r])) X return; X r = dataPattern[D_FIELD].reg_token[TK_INDENT]; X level = regs.end[r]/INDENT; X field[level+1] = NULL; X X r = dataPattern[D_FIELD].reg_token[TK_FIELD]; X n = regs.end[r] - regs.start[r]; X field[level] = (char *) XtMalloc ((n+1) * sizeof(char)); X strncpy(field[level], p+regs.start[r], n); X field[level][n] = '\0'; X X for (line = fromLine-1; line > 0; line--) { X p = dataDpy->buf + dataDpy->linepos[line]; X if (re_match(dataPattern[D_STRUCT].buf, p, strlen(p), 0, ®s)>=0){ X r = dataPattern[D_STRUCT].reg_token[TK_INDENT]; X newlevel = regs.end[r]/INDENT; X if (newlevel == level-1) { X level--; X r = dataPattern[D_STRUCT].reg_token[TK_FIELD]; X n = regs.end[r] - regs.start[r]; X field[level] = (char *) XtMalloc ((n+1) * sizeof(char)); X strncpy(field[level], p+regs.start[r], n); X field[level][n] = '\0'; X } X } X } X if (*field[0] == '*' && field[1]) X sprintf(name, "(%s)", field[0]+1); X else X strcpy(name, field[0]); X for (i=1; field[i]; i++) { X strcat(name, "."); X strcat(name, field[i]); X } X sprintf(command, "print *(%s)\n", name); X PopupMode = True; X query_dbx(command); X } X} X X X/* X * Create a data display with a label. X * The popupshell has a form widget which consists of a label and a text X * widget. X */ Xstatic void CreateDataPopup(dataDpy, label) XDataDpyRec *dataDpy; Xchar *label; X{ X Arg args[MAXARGS]; X Cardinal n; X Dimension dataDpyHeight, dataDpyWidth; X XFontStruct *text_font; X X static XtActionsRec datadpy_actions[] = { X {"SelectPointer", (XtActionProc) SelectPointer}, X {NULL, NULL} X }; X X static String translations = "#override \n\ X <Btn1Down>: SelectStart() SelectWord() SelectPointer() \n\ X <Btn1Up>: SelectEnd() \n\ X "; X X n = 0; X dataDpy->popupshell = XtCreatePopupShell("Data Popup", X transientShellWidgetClass, toplevel, args, n); X X n = 0; X XtSetArg(args[n], XtNdefaultDistance, 0); n++; X dataDpy->popup = XtCreateManagedWidget("popup", formWidgetClass, X dataDpy->popupshell, args, n); X X /* Create the label */ X n = 0; X XtSetArg(args[n], XtNtop, (XtArgVal) XawChainTop); n++; X XtSetArg(args[n], XtNbottom, (XtArgVal) XawChainTop); n++; X XtSetArg(args[n], XtNright, (XtArgVal) XawChainRight); n++; X XtSetArg(args[n], XtNleft, (XtArgVal) XawChainLeft); n++; X XtSetArg(args[n], XtNlabel, (XtArgVal) label); n++; X XtSetArg(args[n], XtNresize, (XtArgVal) False); n++; X XtSetArg(args[n], XtNjustify, (XtArgVal) XtJustifyCenter); n++; X dataDpy->label = XtCreateManagedWidget("label", labelWidgetClass, X dataDpy->popup, args, n); X XtAddEventHandler(dataDpy->label, (EventMask) ButtonPressMask, False, X DestroyDataPopup, dataDpy); X X /* Create the text window */ X n = 0; X XtSetArg(args[n], XtNfromVert, (XtArgVal) dataDpy->label); n++; X XtSetArg(args[n], XtNtop, (XtArgVal) XawChainTop); n++; X XtSetArg(args[n], XtNbottom, (XtArgVal) XawChainBottom); n++; X XtSetArg(args[n], XtNright, (XtArgVal) XawChainRight); n++; X XtSetArg(args[n], XtNleft, (XtArgVal) XawChainLeft); n++; X X XtSetArg(args[n], XtNleftMargin, (XtArgVal) LEFT_MARGIN); n++; X XtSetArg(args[n], XtNuseStringInPlace, (XtArgVal) True); n++; X XtSetArg(args[n], XtNstring, (XtArgVal) dataDpy->buf); n++; X XtSetArg(args[n], XtNlength, (XtArgVal) dataDpy->buflen); n++; X XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextRead); n++; X XtSetArg(args[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++; X XtSetArg(args[n], XtNscrollVertical, XawtextScrollWhenNeeded); n++; X XtSetArg(args[n], XtNtranslations, XtParseTranslationTable(translations)); X n++; X dataDpy->dataDpyWindow = XtCreateManagedWidget("dataDpyWindow", X asciiTextWidgetClass, dataDpy->popup, args, n); X XtAppAddActions(app_context, datadpy_actions, XtNumber(datadpy_actions)); X X /* Get the text font */ X n = 0; X XtSetArg(args[n], XtNfont, &text_font); n++; X XtGetValues(dataDpy->dataDpyWindow, args, n); X X /* Estimate the size of the text widget, dataDpyWindow, with the number X of lines and the maximum length of a line. Assume fixed font width. X */ X font_height = text_font->ascent + text_font->descent; X font_width = text_font->max_bounds.width; X dataDpyHeight = dataDpy->numlines * font_height + 5; X dataDpyWidth = dataDpy->maxLineLength * font_width + LEFT_MARGIN; X if (dataDpyHeight > app_resources.dataDpyMaxHeight) X dataDpyWidth += SCROLLBAR_WIDTH; X X#if 1 /*(PW)17DEC90 : bug ! */ X#define SCROLLBAR_HEIGHT 15 X if (dataDpyWidth > app_resources.dataDpyMaxWidth) X dataDpyHeight += SCROLLBAR_HEIGHT; X#endif X X AssignMin(dataDpyHeight, app_resources.dataDpyMaxHeight); X AssignMin(dataDpyWidth, app_resources.dataDpyMaxWidth); X X n = 0; X XtSetArg(args[n], XtNheight, (XtArgVal) dataDpyHeight); n++; X XtSetArg(args[n], XtNwidth, (XtArgVal) dataDpyWidth); n++; X XtSetValues(dataDpy->dataDpyWindow, args, n); X X n = 0; X XtSetArg(args[n], XtNwidth, (XtArgVal) dataDpyWidth); n++; X XtSetValues(dataDpy->label, args, n); X} X X/* X * Instead of creating a new popupshell, this routine uses an already X * existing popupshell for data display. X * It changes the label, calculates the size of the popupshell, X * and sets the source of the text window to that of the new data. X */ Xstatic void UpdateDataPopup(dataDpy, label) XDataDpyRec *dataDpy; Xchar *label; X{ X Arg args[MAXARGS]; X Cardinal n; X Dimension popupHeight, popupWidth, dataDpyHeight, dataDpyWidth, X labelHeight, labelBorderWidth, dataDpyBorderWidth; X X /* Update the label */ X n = 0; X XtSetArg(args[n], XtNlabel, (XtArgVal) label); n++; X XtSetValues(dataDpy->label, args, n); X X /* Calculate the size of popupshell */ X dataDpyHeight = dataDpy->numlines * font_height + 5; X dataDpyWidth = dataDpy->maxLineLength * font_width + 2*10; X X#if 1 /*(PW)18DEC90 : bug ! */ X if (dataDpyHeight > app_resources.dataDpyMaxHeight) X dataDpyWidth += SCROLLBAR_WIDTH; X X if (dataDpyWidth > app_resources.dataDpyMaxWidth) X dataDpyHeight += SCROLLBAR_HEIGHT; X#endif X X AssignMin(dataDpyHeight, app_resources.dataDpyMaxHeight); X AssignMin(dataDpyWidth, app_resources.dataDpyMaxWidth); X X n = 0; X XtSetArg(args[n], XtNheight, (XtArgVal) &labelHeight); n++; X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &labelBorderWidth); n++; X XtGetValues(dataDpy->label, args, n); X n = 0; X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &dataDpyBorderWidth); n++; X XtGetValues(dataDpy->dataDpyWindow, args, n); X X popupHeight = dataDpyHeight + labelHeight + 2*labelBorderWidth + X 2*dataDpyBorderWidth; X popupWidth = dataDpyWidth; X X n = 0; X XtSetArg(args[n], XtNheight, (XtArgVal) popupHeight); n++; X XtSetArg(args[n], XtNwidth, (XtArgVal) popupWidth); n++; X XtSetValues(dataDpy->popupshell, args, n); X X /* Set the text source */ X n = 0; X XtSetArg(args[n], XtNstring, (XtArgVal) dataDpy->buf); n++; X XtSetArg(args[n], XtNlength, (XtArgVal) dataDpy->buflen); n++; X XawTextSetSource(dataDpy->dataDpyWindow, X XtCreateWidget("textsrc", asciiSrcObjectClass, X dataDpy->dataDpyWindow, args, n), X 0); X} X X/* X * Append dataDpy to a DataDpyList pointed to by head. X */ Xstatic void AppendList(head, dataDpy) XDataDpyList **head; XDataDpyRec *dataDpy; X{ X DataDpyList *p, *q, *r; X X p = (DataDpyList *) XtNew (DataDpyList); X p->dataDpy = dataDpy; X p->next = NULL; X q = *head; X if (!q) X *head = p; X else { X while (r = q->next) X q = r; X q->next = p; X } X} X X/* X * Removes a dataDpy from its parent's list of children. X */ Xstatic void DeleteList(head, dataDpy) XDataDpyList **head; XDataDpyRec *dataDpy; X{ X DataDpyList *p, *q; X X if (p = *head) { X if (p->dataDpy == dataDpy) X *head = p->next; X else { X for (q = p->next; q && q->dataDpy != dataDpy;) { X p = q; X q = p->next; X } X if (q) p->next = q->next; X } X } X} X X/* X * Pop down a dataDpy and all its descendants, freeing storage and X * reinitializing fields. X */ Xstatic void pop_down(dataDpy) XDataDpyRec *dataDpy; X{ X DataDpyList *p, *q; X X XtPopdown(dataDpy->popupshell); X XtFree(dataDpy->linepos); X XtFree(dataDpy->buf); X dataDpy->buf = NULL; X dataDpy->buflen = 0; X dataDpy->linepos = NULL; X dataDpy->state = UNUSED; X dataDpy->parent = NULL; X for (p = dataDpy->childlist; p;) { X pop_down(p->dataDpy); X q = p; X p = p->next; X XtFree(q); X } X dataDpy->childlist = NULL; X} X X/* X * Invoked by a ButtonPress event on the label of a data display to X * pop down itself and its descendants. X */ X/* ARGSUSED */ Xstatic void DestroyDataPopup(w, dataDpy, event) X Widget w; X DataDpyRec *dataDpy; X XEvent *event; X{ X if (!dataDpy->parent) X DeleteList(&TopParentList, dataDpy); X else X DeleteList(&dataDpy->parent->childlist, dataDpy); X pop_down(dataDpy); X} X X/* X * Position the data display on the screen to reflect the parent-child X * relationship. X */ Xstatic void MovePopup(dataDpy) XDataDpyRec *dataDpy; X{ X Arg args[MAXARGS]; X Cardinal n; X Screen *screen; X int popupHeight, popupWidth, screenHeight, screenWidth; X Position x, y; X Dimension dataDpyWidth, dataDpyHeight, dataDpyBorderWidth, X labelHeight, labelBorderWidth, width, height, borderWidth; X DataDpyList *p, *q; X X Parent = NULL; X if (!dataDpy->parent) X p = TopParentList; X else X p = dataDpy->parent->childlist; X X /* Look for its previous sibling */ X for (q = p->next; q && q->dataDpy != dataDpy;) { X p = q; X q = q->next; X } X /* If a sibling exists, place the new popup right next to it */ X if (q) { X n = 0; X XtSetArg(args[n], XtNwidth, (XtArgVal) &width); n++; X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &borderWidth); n++; X XtGetValues(p->dataDpy->popupshell, args, n); X XtTranslateCoords(p->dataDpy->popupshell, 0, 0, &x, &y); X x += width; X y -= borderWidth; X } X else { /* no siblings */ X /* this is the very first popup */ X if (!dataDpy->parent) { X x = 0; X y = 0; X } X /* place it under its parent */ X else { X n = 0; X XtSetArg(args[n], XtNheight, (XtArgVal) &height); n++; X XtGetValues(dataDpy->parent->popupshell, args, n); X XtTranslateCoords(dataDpy->parent->popupshell, 30, (Position)height, X &x, &y); X } X } X X /* Make sure the popup does not go outside of the screen */ X n = 0; X XtSetArg(args[n], XtNwidth, (XtArgVal) &dataDpyWidth); n++; X XtSetArg(args[n], XtNheight, (XtArgVal) &dataDpyHeight); n++; X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &dataDpyBorderWidth); n++; X XtGetValues(dataDpy->dataDpyWindow, args, n); X X n = 0; X XtSetArg(args[n], XtNheight, (XtArgVal) &labelHeight); n++; X XtSetArg(args[n], XtNborderWidth, (XtArgVal) &labelBorderWidth); n++; X XtGetValues(dataDpy->label, args, n); X X popupHeight = dataDpyHeight + labelHeight + 2*labelBorderWidth + X 2*dataDpyBorderWidth; X popupWidth = dataDpyWidth; X X screen = XtScreen(toplevel); X screenHeight = XHeightOfScreen(screen); X screenWidth = XWidthOfScreen(screen); X X if (x + popupWidth > screenWidth && y + popupHeight > screenHeight) { X x = screenWidth - popupWidth; X y = screenHeight - popupHeight; X } X else if (x + popupWidth > screenWidth) X x = screenWidth - popupWidth; X else if (y + popupHeight > screenHeight) X y = screenHeight - popupHeight; X X n = 0; X XtSetArg(args[n], XtNx, x); n++; X XtSetArg(args[n], XtNy, y); n++; X XtSetValues(dataDpy->popupshell, args, n); X} X X/* X * Handler procedure called by parse(). X * The main function to popup a data display. X */ Xvoid print_handler(output) Xchar *output; X{ X DataDpyRec *dataDpy; X int i, j; X X if (!output) return; X if (!PopupMode) return; X PopupMode = False; X XDefineCursor(display, XtWindow(toplevel), watch); X if (Parent) X XDefineCursor(display, XtWindow(Parent->dataDpyWindow), watch); X UpdateMessageWindow("Click the label to pop down the data popup"); X X /* Searches the table for an unused or empty slot */ X for (i=0; dataDpyTable && dataDpyTable[i] && dataDpyTable[i]->state == USED X && i < dataDpyTableSize; i++); X if (i == dataDpyTableSize) { /* Table full */ X dataDpyTableSize += ADD_SIZE; X dataDpyTable = (DataDpyRec **) XtRealloc (dataDpyTable, X dataDpyTableSize * sizeof(DataDpyRec *)); X for (j=i; j<dataDpyTableSize; j++) X dataDpyTable[j] = NULL; X } X X /* Empty slot found, allocate a data structure and initializes some X of the fields. */ X if (dataDpyTable[i] == NULL) { X dataDpyTable[i] = (DataDpyRec *) XtMalloc (sizeof(DataDpyRec)); X dataDpyTable[i]->state = EMPTY; X dataDpyTable[i]->parent = NULL; X dataDpyTable[i]->childlist = NULL; X } X X dataDpy = dataDpyTable[i]; X dataDpy->id = i; /* not needed */ X dataDpy->buf = XtNewString(output); X dataDpy->buflen = strlen(output); X BuildLinePos(dataDpy); X X if (dataDpy->state == EMPTY) X CreateDataPopup(dataDpy, Token.mesg); X else if (dataDpy->state == UNUSED) X UpdateDataPopup(dataDpy, Token.mesg); X X dataDpy->state = USED; /* mark it used */ X if (dataDpy->parent = Parent) X AppendList(&Parent->childlist, dataDpy); X else X AppendList(&TopParentList, dataDpy); X X MovePopup(dataDpy); X XtPopup(dataDpy->popupshell, XtGrabNone); X if (dataDpy->parent) X XUndefineCursor(display, XtWindow(dataDpy->parent->dataDpyWindow)); X XUndefineCursor(display, XtWindow(toplevel)); X} END_OF_FILE if test 21580 -ne `wc -c <'datadpy.c'`; then echo shar: \"'datadpy.c'\" unpacked with wrong size! fi # end of 'datadpy.c' fi echo shar: End of archive 7 \(of 8\). cp /dev/null ark7isdone 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