[comp.sources.x] v03i065: Patches to xdbx, Part01/03

argv@island.uu.net (Dan Heller) (04/06/89)

Submitted-by: Ps Cheung <po@volta.ece.utexas.edu>
Posting-number: Volume 3, Issue 65
Archive-name: xdbx.patch/part01

#!/bin/sh
echo x - CHANGES
sed 's/^X//' > CHANGES <<'+END+OF+CHANGES'
X
XThis is patch #1 to vanilla xdbx posted to comp.sources.x.  There are three
Xparts.  The first part consists of two files, CHANGES and filemenu.c, and
Xsome initial patches.  The other files contain patches only.
X
X1. Changes
X
X   This is patch #1, upgrading xdbx version 1.0 to 1.1.  Included in this
X   patch is a context diff file, plus two new files: CHANGES and filemenu.c.
X   The following changes have been made to this directory since version 1.0.
X
X   o  Xdbx now works under SunOS 4.0.  To compile the program, edit the
X      Imakefile to include -DSUNOS4_0 flag.
X   o  Terminal interrupt (^C) to dbx is fixed.
X   o  Xdbx now handles the 'use' command.  It keeps track of a list of
X      directories for searching source files.  This is especially useful 
X      for debugging programs with source files residing in multiple 
X      directories.
X   o  The file menu is extended into a directory browser.  The user can
X      traverse up and down the directory tree, display source files,
X      and debug executable files (Sun dbx).
X   o  For Berkeley dbx, the 'status' button is replaced by the 'return'
X      button.
X   o  Lots of small changes to the source code.
X
X2. Bugs
X
X   o  Xdbx exercises some bugs in the Athena list widget.  Creating a 
X      file menu could cause segmentation violation.
X
X3. Acknowledgements
X
X      I must thank Guy Harris for correcting my misunderstanding of ptys 
X   and getting xdbx to work in SunOS 4.0.  Many thanks go to Duane Voth 
X   for his diffs, and many of his ideas in improving the user interface 
X   of the file menu, and allowing user customization of translation tables.  
X   D'arc Angel came up with the idea of introducing the DEBUGGER environment 
X   variable.  I would also like to thank Joseph Rahmeh, Mike Schoenfelder,
X   Gregory Melancon, and many others for their suggestions and bug fixes.
+END+OF+CHANGES
echo '-rw-rw-r--  1 argv         1849 Apr  5 23:53 CHANGES    (as sent)'
chmod u=rw,g=rw,o=r CHANGES
ls -l CHANGES
echo x - filemenu.c
sed 's/^X//' > filemenu.c <<'+END+OF+filemenu.c'
X/****************************************************************************** 
X *
X *  xdbx - X Window System interface to dbx
X *
X *  Copyright 1989 The University of Texas at Austin
X *
X *  Author:	Po Cheung
X *  Date:	March 20, 1989
X *
X *  Permission to use, copy, modify, and distribute this software and
X *  its 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.  The University of Texas at Austin makes no 
X *  representations about the suitability of this software for any purpose.  
X *  It is provided "as is" without express or implied warranty.
X *
X ******************************************************************************/
X
X
X/* Filemenu.c
X *
X *  This file contains routines for manipulation of a file menu.
X *  The file menu is popped up by the 'file' command button.  It allows
X *  a user to go up and down the directory tree, to select text files
X *  to display, and to select executable files to debug.
X *
X *  When xdbx is first started up, SetUpFileMenu() is called to construct
X *  the file menu.  Each time the user changes the current directory,
X *  UpdateFileMenu() is called to destroy the old popupshell and call
X *  SetUpFileMenu() to build a new menu.
X *
X *  Duane Voth contributed to the layout of the file menu, plus some
X *  other code and ideas.
X */
X
X#include <ctype.h>
X#include <X11/Xos.h>
X#include <sys/stat.h>
X#ifdef SUNOS4_0
X#include <dirent.h>
X#else
X#include <sys/dir.h>
X#endif
X#include "global.h"
X
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 */
Xstatic char	cwd[MAXPATHLEN];	/* current working directory of dbx */
X
X
X/*  Returns the current working directory.
X *  For Berkeley dbx, the current working directory info is stored in
X *  the static variable, cwd.
X *  For Sun dbx, the current working directory can be obtained from dbx.
X */
Xchar *dbxpwd()
X{
X#ifdef BSD
X    if (strcmp(cwd, "") == NULL)
X        getwd(cwd);
X#else
X    if (dbxfp == NULL)
X        getwd(cwd);
X    else
X	strcpy(cwd, (char *) strtok(QueryDbx("pwd\n", FALSE), "\n"));
X#endif
X    return cwd;
X}
X
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    int i;
X
X#ifdef BSD
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    QueryDbx(command, FALSE);
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 buffer[16], pathname[LINESIZ];
X    struct stat statbuf;
X    int i, n;
X    FILE *fp;
X
X    if (strcmp(entry->d_name, ".") == NULL || 	/* ignore current directory */
X	LASTCH(entry->d_name) == '~')		/* ignore Emacs backup 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    if ((fp = fopen(pathname, "r")) == NULL)
X        return False;
X    if (n = fread(buffer, sizeof(char), sizeof(buffer), fp)) {
X    	fclose(fp);
X    	for (i=0; i<n && (isprint(buffer[i]) || isspace(buffer[i])); i++);
X    	return ((i-sizeof(buffer)) ? False : True);	/* only ascii text */
X    }
X    fclose(fp);
X    return False;
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    	free(namelist[j]);
X    }
X    filelist[i++] = NULL;
X    free(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, client_data, call_data)
X    Widget w;
X    Widget client_data;
X    XtListReturnStruct *call_data;
X{
X    void UpdateFileMenu(), File();
X    char string[LINESIZ], *filename;
X
X    XtPopdown(client_data);
X    filename = call_data->string;
X    if (filename == NULL) return;
X    if (LASTCH(filename) == '/') {
X	changeDir(filename);
X	UpdateFileMenu();	/* create new menu */
X	File();			/* pop it up */
X    }
X    else if (LASTCH(filename) == '*') {
X    	UpdateMessageWindow("");
X#ifndef BSD
X	strcpy(string, filename);
X	LASTCH(string) = '\0';
X	sprintf(Command, "debug %s\n", string);
X    	AppendDialogText(Command);
X    	writeDbx(Command);
X#endif
X    }
X    else {
X    	UpdateMessageWindow("");
X    	LoadFile(filename);
X	sprintf(Command, "file %s\n", filename);
X    	AppendDialogText(Command);
X    	writeDbx(Command);
X    }
X}
X
X
X/*  Callback to popdown the file menu
X */
Xstatic void CancelFileMenu(w, client_data, call_data)
X    Widget w;
X    caddr_t client_data;
X    caddr_t call_data;
X{
X    XtPopdown(client_data);
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 */
Xvoid SetUpFileMenu(dir) 
Xchar *dir;
X{
X    Widget	cancelButton;
X    Arg 	args[MAXARGS];
X    Cardinal	n;
X    char	menulabel[LINESIZ];
X    int		ncolumns;
X
X    static String translations = "\
X	<Btn1Down>,<Btn1Up>:	Set() Notify() Unset()";
X
X    n = 0;
X    popupshell = XtCreatePopupShell("popupshell", overrideShellWidgetClass, 
X				    toplevel, args, n);
X
X    popup = XtCreateManagedWidget("popup", vPanedWidgetClass, popupshell,
X				  args, n);
X    ScanDir(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/app_resources.filesPerColumn + 1;
X    ncolumns = MIN(ncolumns, MAXCOLUMNS);
X    XtSetArg(args[n], XtNlist, filelist);				n++;
X    XtSetArg(args[n], XtNverticalList, True);				n++;
X    XtSetArg(args[n], XtNcolumnSpacing, app_resources.columnSpacing);	n++;
X    XtSetArg(args[n], XtNdefaultColumns, (XtArgVal) ncolumns);		n++;
X    XtSetArg(args[n], XtNtranslations, XtParseTranslationTable(translations));
X    n++;
X    fileMenu = XtCreateManagedWidget("fileMenu", listWidgetClass, 
X				     popup, args, n);
X    XtAddCallback(fileMenu, XtNcallback, DisplayMenuFile, popupshell);
X
X    n = 0;
X    cancelButton = XtCreateManagedWidget("CANCEL", 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 */
Xvoid UpdateFileMenu()
X{
X    XtDestroyWidget(popupshell);
X    SetUpFileMenu(dbxpwd());
X    MakeDirList(QueryDbx("use\n", FALSE));
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    /*  Place the file menu relative to the top right corner of dialogWindow */
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
X    XtTranslateCoords(dialogWindow, x_offset, -1, &x, &y);
X    x = MAX(0, x);
X    y = MAX(0, y);
X    XtMoveWidget(popupshell, x, y);
X    XtPopup(popupshell, XtGrabNonexclusive);
X    UpdateMessageWindow("Select a file or directory");
X}
+END+OF+filemenu.c
echo '-rw-rw-r--  1 argv        10219 Apr  5 23:54 filemenu.c    (as sent)'
chmod u=rw,g=rw,o=r filemenu.c
ls -l filemenu.c
echo x - xdbx.patch.1
sed 's/^X//' > xdbx.patch.1 <<'+END+OF+xdbx.patch.1'
X*** xdbx1.0/source.c	Fri Mar 24 01:18:41 1989
X--- xdbx1.1/source.c	Sun Apr  2 17:48:23 1989
X***************
X*** 18,31 ****
X   ******************************************************************************/
X  
X  
X! #include "global.h"
X  #include <X11/Xos.h>
X  #include <sys/stat.h>
X  
X! static FileRec	fileTable[MAXFILES];	/* table of file records */
X  FileRec  	*displayedFile;		/* pointer to table entry of currently
X  					   displayed file */
X  Boolean		Echo = True;		/* to intercept dbx output */
X  
X  
X  void source_init()
X--- 18,48 ----
X   ******************************************************************************/
X  
X  
X! /*  This file contains routines related to the source window.  They include:
X!  *    source_init : 	initialization routine.
X!  *    Update :		action proc to update source window on scrollbar action.
X!  *    UpdateLine :	action proc to update the current line.
X!  *    NotifyResize :	action proc to update source window on resize.
X!  *    CreateSourceWindow :
X!  *    BuildLinePos :	build an array of starting text position of each line.
X!  *    LookUpFileTable :	check out source file info from a file table.
X!  *    QueryFile :	ask dbx for the name of current source file.
X!  *    SaveDisplayedFileInfo : records displayed file info into file table.
X!  *    DisplayFile :	display a file on the source window
X!  *    LoadFile :	search for a file and open it for display.
X!  */
X! 
X  #include <X11/Xos.h>
X  #include <sys/stat.h>
X+ #include <pwd.h>
X+ #include "global.h"
X  
X! static FileRec	**fileTable;		/* table of file records */
X! static int	fileTableSize;		/* size of file table */
X  FileRec  	*displayedFile;		/* pointer to table entry of currently
X  					   displayed file */
X  Boolean		Echo = True;		/* to intercept dbx output */
X+ static char 	*dirList[MAXDIRS];	/* list of dirs for searching files */
X  
X  
X  void source_init()
X***************
X*** 32,45 ****
X  {
X      int i;
X  
X!     for (i=0; i<MAXFILES; i++) {
X! 	fileTable[i].filename = XtNewString("");
X      }
X  }
X  
X  /*
X   *  Update topline, bottomline, arrow sign, updown sign, stop signs, and
X!  *  line label.  Invoked by scrollbar action.
X   */
X  /* ARGSUSED */
X  static XtActionProc Update(w, event, params, num_params)
X--- 49,65 ----
X  {
X      int i;
X  
X!     fileTableSize = FILETABLESIZE;
X!     fileTable = (FileRec **) XtMalloc (fileTableSize * sizeof(FileRec *));
X!     for (i=0; i<fileTableSize; i++) {
X! 	fileTable[i] = NULL;
X      }
X+     dirList[0] = NULL;
X  }
X  
X  /*
X   *  Update topline, bottomline, arrow sign, updown sign, stop signs, and
X!  *  line label.  Invoked by scrolling action.
X   */
X  /* ARGSUSED */
X  static XtActionProc Update(w, event, params, num_params)
X***************
X*** 70,76 ****
X      }
X  }
X  
X! /*  Invoked by left mouse button down, update the line label. 
X   */
X  /* ARGSUSED */
X  static XtActionProc UpdateLine(w, event, params, num_params)
X--- 90,97 ----
X      }
X  }
X  
X! 
X! /*  Update the line label, invoked by left mouse button down.
X   */
X  /* ARGSUSED */
X  static XtActionProc UpdateLine(w, event, params, num_params)
X***************
X*** 88,96 ****
X  }
X  
X  /*
X!  *  Update bottomline, arrow sign, updown sign and stop signs
X   *  Invoked by ConfigureNotify event.
X-  *  Note that topline never changes with resize, only bottomline gets changed.
X   */
X  /* ARGSUSED */
X  static XtActionProc NotifyResize(w, event, params, num_params)
X--- 109,116 ----
X  }
X  
X  /*
X!  *  Update bottomline, arrow sign, updown sign and stop signs on resize.
X   *  Invoked by ConfigureNotify event.
X   */
X  /* ARGSUSED */
X  static XtActionProc NotifyResize(w, event, params, num_params)
X***************
X*** 99,109 ****
X--- 119,132 ----
X      String *params;
X      Cardinal *num_params;
X  {
X+     XtTextPosition pos;
X      TextWidget  ctx = (TextWidget) sourceWindow;
X      FileRec	*file;
X  
X      if (file = displayedFile) {
X  	file->lines = ctx->text.lt.lines;
X+ 	pos = XtTextTopPosition(sourceWindow);
X+ 	file->topline = TextPositionToLine(pos);
X          file->bottomline = MIN (file->topline + file->lines - 1, 
X  				file->lastline);
X          UpdateStops(file);
X***************
X*** 112,121 ****
X      }
X  }
X  
X- 
X  /* 
X!  *  On top of a form widget, we have a text widget with scrollbar, a label
X!  *  widget for the arrow sign, one for the updown sign and some for stop signs.
X   */
X  void CreateSourceWindow(parent)
X  Widget parent;
X--- 135,143 ----
X      }
X  }
X  
X  /* 
X!  *  On top of a form widget, we have a text widget with scrollbar, label
X!  *  widgets for the stop sign, arrow sign, and updown signs.
X   */
X  void CreateSourceWindow(parent)
X  Widget parent;
X***************
X*** 126,138 ****
X  
X      static XtActionsRec actionTable[] = {
X          {"NotifyResize",   (XtActionProc) NotifyResize},
X!         {"MySelectWord", (XtActionProc) MySelectWord},
X!         {"UpdateLine", (XtActionProc) UpdateLine},
X          {"Update", 	   (XtActionProc) Update},
X          {NULL, NULL}
X      };
X  
X!     static String translations = "\
X          <Btn1Down>:     select-start() ClearCutBuffer0() UpdateLine()\n\
X          <Btn1Up>(2):    MySelectWord()";
X  
X--- 148,160 ----
X  
X      static XtActionsRec actionTable[] = {
X          {"NotifyResize",   (XtActionProc) NotifyResize},
X!         {"MySelectWord",   (XtActionProc) MySelectWord},
X!         {"UpdateLine", 	   (XtActionProc) UpdateLine},
X          {"Update", 	   (XtActionProc) Update},
X          {NULL, NULL}
X      };
X  
X!     static String translations = "#replace\
X          <Btn1Down>:     select-start() ClearCutBuffer0() UpdateLine()\n\
X          <Btn1Up>(2):    MySelectWord()";
X  
X***************
X*** 150,258 ****
X  					 parent, args, n);
X  
X      n = 0;
X      XtSetArg(args[n], XtNheight, app_resources.sourceHeight); 		n++;
X      XtSetArg(args[n], XtNleftMargin, app_resources.leftMargin);		n++;
X-     XtSetArg(args[n], XtNborderWidth, 0);				n++;
X      XtSetArg(args[n], XtNtextOptions, (XtArgVal) scrollVertical);	n++;
X- 
X      sourceWindow = XtCreateManagedWidget("sourceWindow", asciiStringWidgetClass,
X  					  sourceWidget, args, n);
X      ctx = (TextWidget) sourceWindow;
X-     XtOverrideTranslations(sourceWindow, 
X- 			   XtParseTranslationTable(translations));
X      XtOverrideTranslations(ctx->text.sbar, 
X  			   XtParseTranslationTable(sbarTranslations));
X      XtAddActions(actionTable, XtNumber(actionTable));
X  }
X  
X  
X  /*
X!  * Build the array which gives the starting text position of each line
X!  *   look for CR, get the position, add 1, which becomes the starting
X!  *   position of next line.
X   */
X! static void BuildLinePos (file)
X  FileRec *file;
X  {
X!     char *s;
X      Line line, nlines;
X  
X!     nlines = file->filesize/CHARS_PER_LINE;
X!     file->linepos = (XtTextPosition *)XtMalloc(nlines * sizeof(XtTextPosition));
X!     s = file->buf;
X      line = 0;
X      file->linepos[line++] = 0;
X      file->linepos[line++] = 0;
X!     while (*s) {
X! 	if (*s++ == '\n') {
X! 	    if (line == nlines) {
X                  file->linepos = (XtTextPosition *) XtRealloc (file->linepos, 
X  			  (nlines + ADD_LINES) * sizeof(XtTextPosition));
X  		nlines += ADD_LINES;
X              }
X!             file->linepos[line++] = s - file->buf;
X  	}
X      }
X      file->lastline = line - 2;
X!     file->linepos = (XtTextPosition *) XtRealloc 
X  			(file->linepos, line * sizeof(XtTextPosition));
X  }
X  
X  
X- static long GetFileSize(fd)
X- int  fd;
X- {
X-     struct stat fileinfo;
X- 
X-     if (fstat(fd, &fileinfo))
X- 	return -1;
X-     return (fileinfo.st_size + 1);
X- }
X- 
X  /*
X   * Look up the file table for an entry with "filename"
X   * If not found, create an entry and initialize proper fields,
X   * else, return pointer to entry found.
X   */
X! static FileRec *LookUpFileTable(filename, fd)
X! char *filename;
X! int  fd;
X  {
X!     int i, c1, c2;
X!     char message[LINESIZ];
X  
X!     for (i=0; fileTable[i].filename &&
X! 	      (c1 = strcmp(fileTable[i].filename, "")) && 
X! 	      (c2 = strcmp(fileTable[i].filename, filename)) &&
X! 	      i < MAXFILES; i++);
X  
X!     if (i >= MAXFILES) {		/* too many files */
X! 	i = 0;
X! 	c1 = 0;
X! 	XtFree(fileTable[i].buf);
X      }
X!     if (c1 == 0) {			/* file does not exist in table */
X! 	if ((fileTable[i].filesize = GetFileSize(fd)) == -1)
X! 	    return NULL ;
X! 	fileTable[i].buf = XtMalloc(fileTable[i].filesize);
X! 	if (read(fd, fileTable[i].buf, fileTable[i].filesize) == -1) {
X! 	    sprintf(message, "Can't read %s: read error\n", filename);
X! 	    UpdateMessageWindow(message);
X! 	    XtFree(fileTable[i].buf);
X! 	    return NULL;
X!         }
X! 	fileTable[i].filename = XtNewString(filename);
X! 	strcpy(fileTable[i].funcname, "");
X! 	fileTable[i].currentline = 1;
X! 	fileTable[i].topline = 1;
X! 	fileTable[i].bottomline = 0;
X! 	fileTable[i].topPosition = 0;
X! 	BuildLinePos(&fileTable[i]);
X! 	return &fileTable[i];
X      }
X!     if (c2 == 0) {			/* file exists in table */
X!     	return &fileTable[i];
X      }
X  }
X  
X  
X--- 172,294 ----
X  					 parent, args, n);
X  
X      n = 0;
X+     XtSetArg(args[n], XtNtranslations,
X+ 	     XtParseTranslationTable(translations));  			n++;
X+     XtSetArg(args[n], XtNborderWidth, 0);				n++;
X      XtSetArg(args[n], XtNheight, app_resources.sourceHeight); 		n++;
X      XtSetArg(args[n], XtNleftMargin, app_resources.leftMargin);		n++;
X      XtSetArg(args[n], XtNtextOptions, (XtArgVal) scrollVertical);	n++;
X      sourceWindow = XtCreateManagedWidget("sourceWindow", asciiStringWidgetClass,
X  					  sourceWidget, args, n);
X+     if (app_resources.sourceTranslTable) {
X+ 	n = 0;
X+ 	XtSetArg(args[n], XtNtranslations, app_resources.sourceTranslTable);
X+ 	n++;
X+ 	XtSetValues(sourceWindow, args, n);
X+     }
X+ 
X      ctx = (TextWidget) sourceWindow;
X      XtOverrideTranslations(ctx->text.sbar, 
X  			   XtParseTranslationTable(sbarTranslations));
X+     if (app_resources.sbarTranslTable)
X+     	XtOverrideTranslations(ctx->text.sbar, app_resources.sbarTranslTable);
X+ 
X      XtAddActions(actionTable, XtNumber(actionTable));
X  }
X  
X  
X  /*
X!  *  Build the array which gives the starting text position of each line.
X!  *  > Estimate the number of lines in the file and allocate memory buffer.
X!  *  > Starting position of line #1 is 0, and is stored in linepos[1].
X!  *  > Search for \n till end of buffer.
X   */
X! static void BuildLinePos(file)
X  FileRec *file;
X  {
X!     char *p;
X      Line line, nlines;
X  
X!     nlines = MAX(1, file->filesize/CHARS_PER_LINE);
X!     file->linepos = (XtTextPosition *)
X! 		    XtMalloc ((nlines+2) * sizeof(XtTextPosition));
X!     p = file->buf;
X      line = 0;
X      file->linepos[line++] = 0;
X      file->linepos[line++] = 0;
X!     while (*p) {
X! 	if (*p++ == '\n') {
X! 	    if (line == nlines) { 	/* buffer full, need more memory */
X                  file->linepos = (XtTextPosition *) XtRealloc (file->linepos, 
X  			  (nlines + ADD_LINES) * sizeof(XtTextPosition));
X  		nlines += ADD_LINES;
X              }
X!             file->linepos[line++] = p - file->buf;
X  	}
X      }
X      file->lastline = line - 2;
X!     file->linepos = (XtTextPosition *) XtRealloc 	/* shrink to min size */
X  			(file->linepos, line * sizeof(XtTextPosition));
X  }
X  
X  
X  /*
X   * Look up the file table for an entry with "filename"
X   * If not found, create an entry and initialize proper fields,
X   * else, return pointer to entry found.
X   */
X! static FileRec *LookUpFileTable(pathname, filename)
X! char *pathname, *filename;
X  {
X!     struct stat fileinfo;
X!     int  	fd;
X!     int 	i, j, n;
X  
X!     for (i=0; fileTable[i] && i<fileTableSize; i++) {
X! 	if (strcmp(fileTable[i]->pathname, pathname) == NULL)
X! 	    return fileTable[i];	/* file found */
X!     }
X  
X!     /* file not found, add into file table */
X! 
X!     if (i == fileTableSize) {		/* file table full, enlarge it */
X! 	fileTableSize += ADD_FILES;
X! 	fileTable = (FileRec **) 
X! 		     XtRealloc (fileTable, fileTableSize * sizeof(FileRec *));
X! 	for (j=i; j<fileTableSize; j++)
X! 	    fileTable[j] = NULL;
X      }
X!     if ((fd = open(pathname, O_RDONLY)) == -1) {
X! 	UpdateMessageWindow("Error: cannot open file %s", pathname);
X! 	return NULL;
X      }
X!     if (fstat(fd, &fileinfo) == -1) {
X! 	UpdateMessageWindow("Error: cannot fstat file %s", pathname);
X! 	close(fd);
X! 	return NULL;
X      }
X+     fileTable[i] = (FileRec *) XtMalloc (sizeof(FileRec));
X+     fileTable[i]->filesize = fileinfo.st_size + 1;
X+     fileTable[i]->buf = XtMalloc(fileTable[i]->filesize);
X+     if ((n = read(fd, fileTable[i]->buf, fileTable[i]->filesize)) == -1) {
X+ 	UpdateMessageWindow("Error: cannot read file %s", pathname);
X+ 	XtFree(fileTable[i]->buf);
X+ 	XtFree(fileTable[i]);
X+ 	fileTable[i] = NULL;
X+ 	close(fd);
X+ 	return NULL;
X+     }
X+     fileTable[i]->buf[n] = '\0';
X+     fileTable[i]->pathname = XtNewString(pathname);
X+     fileTable[i]->filename = XtNewString(filename);
X+     strcpy(fileTable[i]->funcname, "");
X+     fileTable[i]->currentline = 1;
X+     fileTable[i]->topline = 1;
X+     fileTable[i]->bottomline = 0;
X+     fileTable[i]->topPosition = 0;
X+     BuildLinePos(fileTable[i]);
X+     close(fd);
X+     return fileTable[i];
X  }
X  
X  
X***************
X*** 281,287 ****
X  
X  /*  
X   *  Remember file position before closing.
X!  *  Clear field funcname for proper operation of parse() & UpdateFuncLabel()
X   */
X  static void SaveDisplayedFileInfo()
X  {
X--- 317,323 ----
X  
X  /*  
X   *  Remember file position before closing.
X!  *  Clear field funcname for parse().
X   */
X  static void SaveDisplayedFileInfo()
X  {
X***************
X*** 296,301 ****
X--- 332,342 ----
X  }
X  
X  
X+ /*   DisplayFile() displays the file onto the source window.  It
X+  *     uses topPosition to remember where it was last opened.  But it
X+  *     must recalculate bottomline because the window size might be
X+  *     different.
X+  */
X  static void DisplayFile(file)
X  FileRec *file;
X  {
X***************
X*** 316,383 ****
X  }
X  
X  
X! static void FullPath(filename, path)
X! char *filename, *path;
X  {
X!     char *dir;
X  
X!     dir = dbxpwd();
X!     if (dir) {
X!     	strcpy(path, dir);
X!     	strcat(path, "/");
X!     	strcat(path, filename);
X!     	XtFree(dir);
X      }
X!     else 
X! 	strcpy(path, filename);
X  }
X  
X  /*
X   * Given a file name, LoadFile attempts to open it and displays it onto
X!  * the source window.  
X!  *   LookUpFileTable checks if the file is already in the file table.
X!  *     if it exists, a pointer to the file structure is retured;
X!  *     otherwise, an entry is created and its info initialized;
X!  *     returns NULL only if file table full.
X!  *   SaveDisplayedFileInfo saves important information about the file
X!  *     back in the file table; they include: topPosition, breakpoints.
X!  *   DisplayFile displays the file onto the source window.  It
X!  *     uses topPosition to remember where it was last opened.  But it
X!  *     must recalculate bottomline because the window size might be
X!  *     different.
X   */
X! FileRec *LoadFile(filename)
X  char *filename;
X  {
X      FileRec 	*file;
X!     int 	fd;
X!     char	message[LINESIZ];
X!     char	pathname[LINESIZ];
X  
X!     if (filename == NULL)
X! 	return displayedFile;
X!     if (displayedFile && strcmp(filename, displayedFile->filename) == 0)
X! 	return displayedFile;
X!     FullPath(filename, pathname);
X!     if ((fd = open(pathname, O_RDONLY)) == -1) {
X! 	sprintf(message, "open: file not found : %s", pathname);
X! 	UpdateMessageWindow(message);
X! 	return displayedFile;
X      }
X!     else if (file = LookUpFileTable(filename, fd)) {
X      	SaveDisplayedFileInfo();
X      	DisplayFile(file);
X! 	UpdateFileLabel(file->filename);
X  	XtTextSetInsertionPoint(sourceWindow, file->linepos[file->currentline]);
X  	UpdateLineLabel(file->currentline);
X  	UpdateStops(file);
X  	UpdateArrow(file);
X  	UpdateUpdown(file);
X!     	close(fd);
X!     	return file;
X      }
X!     else {
X!     	close(fd);
X!     	return displayedFile;
X      }
X  }
X--- 357,499 ----
X  }
X  
X  
X! /*  Given a filename starting with a tilde (`~'), it expands ~[user] to
X!  *  the home directory of that user, or to the login home directory if user
X!  *  is not specified.
X!  */
X! static char *expand(filename)
X! char *filename;
X  {
X!     struct passwd *pwd;
X!     char 	  *string, *name, newfile[MAXNAME];
X  
X!     string = XtNewString(filename+1);
X!     if (*string == '\0' || *string == '/')
X! 	name = (char *) getlogin();
X!     else
X!     	name = (char *) strtok(string, "/");
X!     if (name == NULL)
X! 	return filename;
X!     pwd = (struct passwd *) getpwnam(name);
X!     if (pwd && pwd->pw_dir) {
X!     	sprintf(newfile, "%s%s", pwd->pw_dir, filename+strlen(name)+1);
X!     	return XtNewString(newfile);
X      }
X!     else
X! 	return filename;
X  }
X  
X+ 
X+ /*  Create a list of directories for searching source files.
X+  *  It reads the list of directories specified by the user, adding
X+  *  the current directory into the list if it is not already there.
X+  */
X+ void MakeDirList(output)
X+ char *output;
X+ {
X+     char *s, list[BUFSIZ], command[LINESIZ];
X+     int  i, use_cwd;
X+     struct passwd *pwd;
X+ 
X+     for (i=0; dirList[i]; i++)			/* remove old list */
X+ 	XtFree(dirList[i]);
X+     i = 0;
X+     if (output == NULL || strcmp(output, "") == NULL) {	/* add "." */
X+ 	use_cwd = TRUE;
X+     }
X+     else { 					/* create list */
X+ 	dirList[i++] = (char *) strtok(output, " \n");
X+ 	while (s = (char *) strtok(NULL, " \n")) {
X+ 	    dirList[i++] = XtNewString(s);
X+ 	}
X+ 	dirList[i++] = NULL;
X+ 	use_cwd = TRUE;
X+ 	for (i=0; dirList[i]; i++) {		
X+ 	    if (dirList[i][0] == '~')			/* expand '~' */
X+ 		dirList[i] = expand(dirList[i]);
X+ 	    if (LASTCH(dirList[i]) == '/')		/* remove last '/' */
X+ 	    	LASTCH(dirList[i]) = '\0';	
X+ 	    if (strcmp(dirList[i], ".") == NULL)	/* watch for "." */
X+ 		use_cwd = FALSE;
X+ 	}
X+     }
X+     if (use_cwd) {				/* include current dir */
X+ 	dirList[i++] = XtNewString(".");		
X+     	dirList[i] = NULL;
X+     }
X+     strcpy(list, "");				/* tell dbx our new list */
X+     for (i=0; dirList[i]; i++) {
X+ 	strcat(list, dirList[i]);
X+ 	strcat(list, " ");
X+     }
X+     sprintf(command, "use %s\n", list);
X+     QueryDbx(command, FALSE);
X+ }
X+ 
X+ 
X+ /*  Returns the full pathname of a given file.
X+  *  It searches for the file from a list of directories.
X+  */
X+ char *GetPathname(filename)
X+ char *filename;
X+ {
X+     char	pathname[LINESIZ];
X+     int 	i;
X+ 
X+     if (filename == NULL || strcmp(filename, "") == NULL)
X+ 	return NULL;
X+     for (i=0; dirList[i]; i++) {
X+ 	if (*filename == '/' || *filename == '~')
X+ 	     strcpy(pathname, filename);
X+ 	else if (*dirList[i] == '/' || *dirList[i] == '~')
X+ 	     sprintf(pathname, "%s/%s", dirList[i], filename);
X+ 	else if (strcmp(dirList[i], ".") == NULL)
X+ 	     sprintf(pathname, "%s/%s", dbxpwd(), filename);
X+ 	else
X+ 	     sprintf(pathname, "%s/%s/%s", dbxpwd(), dirList[i], filename);
X+ 	if (access(pathname, R_OK) == 0)
X+ 	    return XtNewString(pathname);
X+     }
X+     UpdateMessageWindow("File not found: %s", filename);
X+     return NULL;
X+ }
X+ 
X  /*
X   * Given a file name, LoadFile attempts to open it and displays it onto
X!  * the source window:
X!  *   1. get the full pathname of the file
X!  *   2. LookUpFileTable() returns a pointer to the file's entry if it's
X!  *      already in the table; else, creates an entry and return a pointer.
X!  *   3. save the current displayedFile info
X!  *   4. display the file
X!  *   5. update the file label and the various signs on the source window.
X!  *  LoadFile returns 0 upon successful completion, -1 otherwise.
X   */
X! int LoadFile(filename)
X  char *filename;
X  {
X      FileRec 	*file;
X!     char	*pathname;
X  
X!     pathname = GetPathname(filename);
X!     if (pathname == NULL) { 
X! 	return -1;
X      }
X!     if (displayedFile && strcmp(pathname, displayedFile->pathname) == 0)
X! 	return -1;
X!     else if (file = LookUpFileTable(pathname, filename)) {
X      	SaveDisplayedFileInfo();
X      	DisplayFile(file);
X! 	UpdateFileLabel(pathname);
X  	XtTextSetInsertionPoint(sourceWindow, file->linepos[file->currentline]);
X  	UpdateLineLabel(file->currentline);
X  	UpdateStops(file);
X  	UpdateArrow(file);
X  	UpdateUpdown(file);
X! 	displayedFile = file;
X!     	return 0;
X      }
X!     else {		/* LookUpFileTable() fails */
X!     	return -1;
X      }
X  }
X*** xdbx1.0/xdbx.c	Fri Mar 24 01:18:44 1989
X--- xdbx1.1/xdbx.c	Sun Apr  2 16:53:19 1989
X***************
X*** 18,23 ****
X--- 18,24 ----
X   ******************************************************************************/
X  
X  
X+ #include "errno.h"
X  #include "global.h"
X  
X  #define Offset(field) (XtOffset(XdbxResources *, field))
X***************
X*** 35,42 ****
X  	dialogWindow;		/* dialog window, asciiString widget    */
X  
X  XdbxResources 	app_resources;	/* application resources of xdbx 	*/
X! char 		*xdbxinit = "xdbx.XXXXXX";
X! Boolean		Homedir;
X  
X  
X  static XtResource resources[] = {
X--- 36,43 ----
X  	dialogWindow;		/* dialog window, asciiString widget    */
X  
X  XdbxResources 	app_resources;	/* application resources of xdbx 	*/
X! char 		*xdbxinit = "/tmp/xdbx.XXXXXX";	/* temp file for .dbxinit */
X! int		Homedir;			/* .dbxinit or ~/.dbxinit */
X  
X  
X  static XtResource resources[] = {
X***************
X*** 76,83 ****
X--- 77,112 ----
X  	Offset(arrowForeground), XtRString, "Blue"},
X      {"updownForeground", "UpdownForeground", XtRPixel, sizeof(Pixel), 
X  	Offset(updownForeground), XtRString, "Blue"},
X+     {"sourceTranslTable", "SourceTranslTable", 
X+ 	XtRTranslationTable, sizeof(XtTranslations),
X+ 	Offset(sourceTranslTable), XtRString, (caddr_t)NULL},
X+     {"dialogTranslTable", "DialogTranslTable", 
X+ 	XtRTranslationTable, sizeof(XtTranslations),
X+ 	Offset(dialogTranslTable), XtRTranslationTable, (caddr_t)NULL},
X+     {"sbarTranslTable", "SbarTranslTable", 
X+ 	XtRTranslationTable, sizeof(XtTranslations),
X+ 	Offset(sbarTranslTable), XtRString, (caddr_t)NULL},
X+     {"dbxopt_r", "Dbxoptions", XtRBoolean, sizeof(Boolean), 
X+ 	Offset(dbxopt_r), XtRImmediate, (caddr_t)False},
X+     {"dbxopt_i", "Dbxoptions", XtRBoolean, sizeof(Boolean), 
X+ 	Offset(dbxopt_i), XtRImmediate, (caddr_t)False},
X+     {"includeDir", "Dbxoptions", XtRString, sizeof(char *), 
X+ 	Offset(includeDir), XtRImmediate, (caddr_t)NULL},
X+     {"dbxopt_k", "Dbxoptions", XtRBoolean, sizeof(Boolean), 
X+ 	Offset(dbxopt_k), XtRImmediate, (caddr_t)False},
X+     {"cfile", "Dbxoptions", XtRString, sizeof(char *), 
X+ 	Offset(cfile), XtRImmediate, (caddr_t)NULL},
X+     {"dbxopt_kbd", "Dbxoptions", XtRBoolean, sizeof(Boolean), 
X+ 	Offset(dbxopt_kbd), XtRImmediate, (caddr_t)False},
X+     {"fcount", "Dbxoptions", XtRString, sizeof(char *), 
X+ 	Offset(fcount), XtRImmediate, (caddr_t)NULL},
X+     {"startup", "Dbxoptions", XtRString, sizeof(char *), 
X+ 	Offset(startup), XtRImmediate, (caddr_t)NULL},
X+     {"tstartup", "Dbxoptions", XtRString, sizeof(char *), 
X+ 	Offset(tstartup), XtRImmediate, (caddr_t)NULL},
X  };
X  
X+ 
X  static XrmOptionDescRec options[] = {
X      {"-r",	"dbxopt_r",	XrmoptionNoArg, "True"},
X      {"-i",	"dbxopt_i",	XrmoptionNoArg, "True"},
X***************
X*** 85,94 ****
X      {"-k",	"dbxopt_k",	XrmoptionNoArg, "True"},
X  #ifdef BSD   /* Berkeley dbx */
X      {"-c",	"cfile",	XrmoptionSepArg, NULL},
X! #else	     /* Sun Release 3.2 or 3.4 dbx */
X      {"-kbd",	"dbxopt_kbd",	XrmoptionNoArg, "True"},
X  #endif
X! #ifdef sparc /* SunOS 4.0 dbx */
X      {"-f",	"fcount",	XrmoptionSepArg, NULL},
X      {"-s",	"startup",	XrmoptionSepArg, NULL},
X      {"-sr",	"tstartup",	XrmoptionSepArg, NULL},
X--- 114,123 ----
X      {"-k",	"dbxopt_k",	XrmoptionNoArg, "True"},
X  #ifdef BSD   /* Berkeley dbx */
X      {"-c",	"cfile",	XrmoptionSepArg, NULL},
X! #else	     /* Sun dbx */
X      {"-kbd",	"dbxopt_kbd",	XrmoptionNoArg, "True"},
X  #endif
X! #ifdef SUNOS4_0 /* SunOS 4.0 dbx */
X      {"-f",	"fcount",	XrmoptionSepArg, NULL},
X      {"-s",	"startup",	XrmoptionSepArg, NULL},
X      {"-sr",	"tstartup",	XrmoptionSepArg, NULL},
X***************
X*** 105,111 ****
X  }
X  
X  
X! static void Initialize()
X  {
X      source_init();
X      signs_init();
X--- 134,152 ----
X  }
X  
X  
X! /*  Initialize routines in source.c, signs.c and parser.c.
X!  *  Disable window resize of titleBar and fileWindow.
X!  *  Dbx reads .dbxinit or ~/.dbxinit only once during invocation.
X!  *  (a) creates a temporary file /tmp/xdbx.XXXXXX 
X!  *  (b) attempts to rename .dbxinit to the temp file.
X!  *  (c) if rename fails because .dbxinit does not exist, xdbx attempts to
X!  *      rename ~/.dbxinit to the temp file.
X!  *  (d) if rename fails for other reasons, xdbx creates another temporary file
X!  *	xdbx.XXXXXX and repeat steps (b) and (c).
X!  *  The Homedir flag is set to 1 if ~/.dbxinit is found, 0 if .dbxinit is
X!  *  found, -1 if none of both is found.
X!  */
X! static void main_init()
X  {
X      source_init();
X      signs_init();
X***************
X*** 113,161 ****
X      if (!app_resources.noTitleBar) DisableWindowResize(titleBar);
X      DisableWindowResize(fileWindow);
X      mktemp(xdbxinit);
X!     Homedir = False;
X!     if (rename(".dbxinit", xdbxinit) == -1) {
X! 	rename("~/.dbxinit", xdbxinit);
X! 	Homedir = True;
X      }
X  }
X  
X  
X! int dbxoptions(argc, argv, app_resources)
X!     int  argc;
X      char **argv;
X!     XdbxResources app_resources;
X  {
X!     if (app_resources.dbxopt_r)
X! 	argv[argc++] = "-r";
X!     if (app_resources.dbxopt_i)
X! 	argv[argc++] = "-i";
X!     if (app_resources.includeDir) {
X! 	argv[argc++] = "-I";
X! 	strcpy(argv[argc++], app_resources.includeDir);
X      }
X!     if (app_resources.dbxopt_k)
X! 	argv[argc++] = "-k";
X!     if (app_resources.cfile) {
X! 	argv[argc++] = "-c";
X! 	strcpy(argv[argc++], app_resources.cfile);
X      }
X!     if (app_resources.dbxopt_kbd)
X! 	argv[argc++] = "-kbd";
X!     if (app_resources.fcount) {
X! 	argv[argc++] = "-f";
X! 	strcpy(argv[argc++], app_resources.fcount);
X      }
X!     if (app_resources.startup) {
X! 	argv[argc++] = "-s";
X! 	strcpy(argv[argc++], app_resources.startup);
X      }
X!     if (app_resources.tstartup) {
X! 	argv[argc++] = "-sr";
X! 	strcpy(argv[argc++], app_resources.tstartup);
X      }
X!     argv[argc] = NULL;
X!     return argc;
X  }
X  
X  
X--- 154,225 ----
X      if (!app_resources.noTitleBar) DisableWindowResize(titleBar);
X      DisableWindowResize(fileWindow);
X      mktemp(xdbxinit);
X!     Homedir = -1;
X!     if (rename(".dbxinit", xdbxinit) == 0)
X! 	Homedir = 0;
X!     else if (errno == ENOENT) {
X! 	if (rename("~/.dbxinit", xdbxinit) == 0)
X! 	    Homedir = 1;
X      }
X+     else {
X+ 	strcpy(xdbxinit, "xdbx.XXXXXX");
X+ 	mktemp(xdbxinit);
X+ 	if (rename(".dbxinit", xdbxinit) == 0)
X+ 	    Homedir = 0;
X+ 	else if (errno == ENOENT) {
X+ 	    if (rename("~/.dbxinit", xdbxinit) == 0)
X+ 		Homedir = 1;
X+ 	}
X+     }
X  }
X  
X  
X! /*  Reconstruct command line arguments for calling dbx.
X!  *  Return the argument list for dbx and new value of argc.
X!  */
X! char **dbxoptions(argc, argv, app_resources)
X!     int  *argc;
X      char **argv;
X!     XdbxResources *app_resources;
X  {
X!     char **dbxargv;
X!     int  i=0;
X! 
X!     dbxargv = (char **) XtMalloc (MAXARGS * sizeof(char *));
X!     for (i=0; i < *argc; i++)
X! 	dbxargv[i] = argv[i];
X! 
X!     if (app_resources->dbxopt_r)
X! 	dbxargv[i++] = "-r";
X!     if (app_resources->dbxopt_i)
X! 	dbxargv[i++] = "-i";
X!     if (app_resources->includeDir) {
X! 	dbxargv[i++] = "-I";
X! 	dbxargv[i++] = app_resources->includeDir;
X      }
X!     if (app_resources->dbxopt_k)
X! 	dbxargv[i++] = "-k";
X!     if (app_resources->cfile) {
X! 	dbxargv[i++] = "-c";
X! 	dbxargv[i++] = app_resources->cfile;
X      }
X!     if (app_resources->dbxopt_kbd)
X! 	dbxargv[i++] = "-kbd";
X!     if (app_resources->fcount) {
X! 	dbxargv[i++] = "-f";
X! 	dbxargv[i++] = app_resources->fcount;
X      }
X!     if (app_resources->startup) {
X! 	dbxargv[i++] = "-s";
X! 	dbxargv[i++] = app_resources->startup;
X      }
X!     if (app_resources->tstartup) {
X! 	dbxargv[i++] = "-sr";
X! 	dbxargv[i++] = app_resources->tstartup;
X      }
X!     dbxargv[i] = NULL;
X!     *argc = i;
X!     return dbxargv;
X  }
X  
X  
X***************
X*** 163,168 ****
X--- 227,234 ----
X  unsigned int argc;
X  char **argv;
X  {
X+     char **dbxargv;
X+ 
X      trap_signals();
X  
X      toplevel = XtInitialize("toplevel", "XDbx", options, XtNumber(options), 
X***************
X*** 177,185 ****
X  
X      XtRealizeWidget(toplevel);
X  
X!     Initialize();
X!     argc = dbxoptions(argc, argv, app_resources);
X!     calldbx(argc, argv);
X  
X      XtMainLoop();
X  }
X--- 243,251 ----
X  
X      XtRealizeWidget(toplevel);
X  
X!     main_init();
X!     dbxargv = dbxoptions(&argc, argv, &app_resources);
X!     calldbx(argc, dbxargv);
X  
X      XtMainLoop();
X  }
Xdiff -c xdbx1.0/xdbx.man xdbx1.1/xdbx.man
X*** xdbx1.0/xdbx.man	Fri Mar 24 01:18:41 1989
X--- xdbx1.1/xdbx.man	Sun Apr  2 18:01:39 1989
X***************
X*** 29,34 ****
X--- 29,37 ----
X  If a file named \fIcore\fP exists in the current directory or a
X  \fIcorefile\fP is specified, \fIxdbx\fP can be used to examine the 
X  state of the program when the core dump occurred.
X+ .LP
X+ The name of the debugger invoked by \fIxdbx\fP is, by default, dbx, 
X+ but it can be overridden with the environment variable DEBUGGER.
X  .SH OPTIONS
X  \fIXdbx\fP accepts all of the standard X Toolkit command line options 
X  (see \fIX\fP(1)), and all the dbx options (see \fIdbx\fP(1)).  
X***************
X*** 83,88 ****
X--- 86,94 ----
X  contains a function call.
X  .IP "\fBnext\fP"
X  Execute one source line, without stepping into any function call.
X+ .IP "\fBreturn\fP"
X+ Continue execution until the selected procedure returns; the current
X+ procedure is used if none is selected (only in Berkeley dbx).
X  
X  .LP 
X  .SS "Breakpoint Commands"
X***************
X*** 99,105 ****
X  Remove the breakpoint on the source line selected.  The stop sign will 
X  disappear.
X  .IP "\fBstatus\fP"
X! Show the current breakpoints and traces.
X  
X  .LP 
X  .SS "Stack Commands"
X--- 105,111 ----
X  Remove the breakpoint on the source line selected.  The stop sign will 
X  disappear.
X  .IP "\fBstatus\fP"
X! Show the current breakpoints and traces (only in Sun dbx).
X  
X  .LP 
X  .SS "Stack Commands"
X***************
X*** 121,128 ****
X  variable name resolution to the selected function.  The file scope is changed 
X  to the file containing the function.
X  .IP "\fBfile\fP"
X! Pop up a file menu to select a source file to be displayed, and
X! change the file scope to the selected file.
X  .IP "\fBquit\fP"
X  Exit \fIxdbx\fP.
X  
X--- 127,138 ----
X  variable name resolution to the selected function.  The file scope is changed 
X  to the file containing the function.
X  .IP "\fBfile\fP"
X! Pop up a file menu that allows the user to move up and down in the 
X! directory tree, to select a text file to be displayed, or (in Sun dbx) 
X! to select an executable file to debug.  Directory entries are marked
X! with a trailing slash (`/') and executables with a trailing asterisk (`*').
X! Filenames beginning with a dot (`.') or ending with a tilde (`~') are not 
X! included in the menu.  
X  .IP "\fBquit\fP"
X  Exit \fIxdbx\fP.
X  
X***************
X*** 187,192 ****
X--- 197,208 ----
X  Foreground color of the arrow sign.
X  .IP \fBupdownForeground\fP
X  Foreground color of the updown sign.
X+ .IP \fBsourceTranslTable\fP
X+ Translation table for the sourceWindow text widget.
X+ .IP \fBsbarTranslTable\fP
X+ Translation table for the sourceWindow scrollbar widget.
X+ .IP \fBdialogTranslTable\fP
X+ Translation table for the dialogWindow text widget.
X  .LP
X  
X  .SH FILES
X***************
X*** 201,220 ****
X  \fIXdbx\fP is developed primarily for C program debugging.  Other languages are 
X  not fully supported.
X  .SH BUGS
X! Typing control-C in the dialog window fails to interrupt dbx.
X  .LP
X  The \fBfile\fP button command does not unhighlight the button border.
X  .LP
X  Stuffing text to a window outside the \fIxdbx\fP window will sometimes give
X! such message: 
X! .ce
X  "X Toolkit Error: AtomPtr was not initialized"
X- .LP
X- \fIXdbx\fP does not work under SunOS 4.0 due to a problem in disabling the 
X- packet mode (TIOCPKT) of the pseudo-terminal.  If the packet mode is not 
X- disabled, each read from the master will return data written previously to 
X- the slave (dbx commands entered would reappear), and each newline character 
X- is incorrectly mapped to a carriage return and a newline during text display.
X  .LP
X  .SH COPYRIGHT
X  Copyright 1989 The University of Texas at Austin
X--- 217,231 ----
X  \fIXdbx\fP is developed primarily for C program debugging.  Other languages are 
X  not fully supported.
X  .SH BUGS
X! \fIXdbx\fP exercises some bugs in the Athena list widget.  Creating a file
X! menu could cause segmentation violation.
X  .LP
X  The \fBfile\fP button command does not unhighlight the button border.
X  .LP
X  Stuffing text to a window outside the \fIxdbx\fP window will sometimes give
X! an error message: 
X! .in 10
X  "X Toolkit Error: AtomPtr was not initialized"
X  .LP
X  .SH COPYRIGHT
X  Copyright 1989 The University of Texas at Austin
X
X
+END+OF+xdbx.patch.1
echo '-rw-r--r--  1 argv        32685 Apr  5 23:56 xdbx.patch.1    (as sent)'
chmod u=rw,g=r,o=r xdbx.patch.1
ls -l xdbx.patch.1
exit 0