home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / xdbx / part05 / source.c < prev   
Encoding:
C/C++ Source or Header  |  1990-08-28  |  19.0 KB  |  643 lines

  1. /*****************************************************************************
  2.  *
  3.  *  xdbx - X Window System interface to the dbx debugger
  4.  *
  5.  *  Copyright 1989 The University of Texas at Austin
  6.  *  Copyright 1990 Microelectronics and Computer Technology Corporation
  7.  *
  8.  *  Permission to use, copy, modify, and distribute this software and its
  9.  *  documentation for any purpose and without fee is hereby granted,
  10.  *  provided that the above copyright notice appear in all copies and that
  11.  *  both that copyright notice and this permission notice appear in
  12.  *  supporting documentation, and that the name of The University of Texas
  13.  *  and Microelectronics and Computer Technology Corporation (MCC) not be 
  14.  *  used in advertising or publicity pertaining to distribution of
  15.  *  the software without specific, written prior permission.  The
  16.  *  University of Texas and MCC makes no representations about the 
  17.  *  suitability of this software for any purpose.  It is provided "as is" 
  18.  *  without express or implied warranty.
  19.  *
  20.  *  THE UNIVERSITY OF TEXAS AND MCC DISCLAIMS ALL WARRANTIES WITH REGARD TO
  21.  *  THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22.  *  FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF TEXAS OR MCC BE LIABLE FOR
  23.  *  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  24.  *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
  25.  *  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  26.  *  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  *
  28.  *  Author:      Po Cheung
  29.  *  Created:       March 10, 1989
  30.  *
  31.  *****************************************************************************/
  32.  
  33. /*  source.c
  34.  *
  35.  *    Create the source window and handle display of file.
  36.  *
  37.  *    source_init():     Initialization routine.
  38.  *    Update():        Action proc to update source window on scrollbar action.
  39.  *    NotifyResize():    Action proc to update source window on resize.
  40.  *    CreateSourceWindow(): Create the source window.
  41.  *    BuildLinePos():    Build an array of starting text position of each line.
  42.  *    LookUpFileTable():Check out source file info from a file table.
  43.  *    SaveDisplayedFileInfo(): records displayed file info into file table.
  44.  *    DisplayFile():    Display a file on the source window
  45.  *    LoadFile():    Search for a file and open it for display.
  46.  */
  47.  
  48. #include <X11/Xos.h>
  49. #include <sys/stat.h>
  50. #include <pwd.h>
  51. #include "global.h"
  52.  
  53. #define    MAXDIRS    256            /* max number of dirs in dirList */
  54.  
  55. char        CurrentFile[MAXNAME];    /* current contents of file variable */
  56. Widget        sourceForm,        /* parent of sourceWindow */
  57.         sourceWindow;        /* text window for source file */
  58. FileRec      *displayedFile;        /* pointer to table entry of currently
  59.                        displayed file */
  60.  
  61. static FileRec    **fileTable;        /* table of file records */
  62. static int    fileTableSize;        /* size of file table */
  63. static char     *dirList[MAXDIRS];    /* list of dirs for searching files */
  64.  
  65. void source_init()
  66. {
  67.     dirList[0] = NULL;
  68. }
  69.  
  70. /*
  71.  *  Update topline, bottomline, arrow sign, updown sign, stop signs, and
  72.  *  line label.
  73.  */
  74. /* ARGSUSED */
  75. void Update(w, event, params, num_params)
  76.     Widget w;
  77.     XEvent *event;
  78.     String *params;
  79.     Cardinal *num_params;
  80. {
  81.     XawTextPosition     pos;
  82.     int            topline;
  83.     FileRec         *file;
  84.  
  85.     if (displayedFile) {
  86.         file = displayedFile;
  87.     pos = XawTextTopPosition(sourceWindow);
  88.     file->topPosition = pos;
  89.     topline = TextPositionToLine(pos);
  90.     /* Update the symbols only if the text scrolls */
  91.     if (file->topline != topline) {
  92.         file->topline = topline;
  93.         file->bottomline = MIN (file->topline + file->lines - 1, 
  94.                     file->lastline);
  95.         XawTextSetInsertionPoint(sourceWindow, file->linepos[file->topline]);
  96.         UpdateLineLabel(file->topline);
  97.             UpdateStops(file);
  98.             UpdateArrow(file);
  99.             UpdateUpdown(file);
  100.             UpdateBomb(file);
  101.     }
  102.     else {/* Update caret position only */
  103.         pos = XawTextGetInsertionPoint(sourceWindow);
  104.         UpdateLineLabel(TextPositionToLine(pos));
  105.     }
  106.     }
  107. }
  108.  
  109. /*
  110.  *  Update bottomline, arrow sign, updown sign and stop signs on resize.
  111.  *  Invoked by ConfigureNotify event.
  112.  */
  113. /* ARGSUSED */
  114. static void NotifyResize(w, event, params, num_params)
  115.     Widget w;
  116.     XEvent *event;
  117.     String *params;
  118.     Cardinal *num_params;
  119. {
  120.     XawTextPosition pos;
  121.     TextWidget  ctx = (TextWidget) sourceWindow;
  122.     FileRec    *file;
  123.  
  124.     if (file = displayedFile) {
  125.     file->lines = ctx->text.lt.lines;
  126.     pos = XawTextTopPosition(sourceWindow);
  127.     file->topline = TextPositionToLine(pos);
  128.         file->bottomline = MIN (file->topline + file->lines - 1, 
  129.                 file->lastline);
  130.         UpdateStops(file);
  131.         UpdateArrow(file);
  132.         UpdateUpdown(file);
  133.         UpdateBomb(file);
  134.     }
  135. }
  136.  
  137. /*  Update the position of the caret */
  138. /*  ARGSUSED */
  139. #ifdef notdef
  140. void UpdateLine(w, event, params, num_params)
  141.     Widget w;
  142.     XEvent *event;
  143.     String *params;
  144.     Cardinal *num_params;
  145. {
  146.     XawTextPosition pos;
  147.     int    line;
  148.  
  149.     pos = XawTextGetInsertionPoint(w);
  150.     line = TextPositionToLine(pos);
  151.     UpdateLineLabel(line);
  152. }
  153. #endif
  154.  
  155. /*  My select-start routine that cancels the effect of automatic scrolling
  156.  *  near the bottom of an Athena text widget window.
  157.  */
  158. /*  ARGSUSED */
  159. void SelectStart(w, event, params, num_params)
  160.     Widget w;
  161.     XEvent *event;
  162.     String *params;
  163.     Cardinal *num_params;
  164. {
  165.     XawTextPosition topPosition;
  166.  
  167.     /* remember the top display position before automatic scrolling */
  168.     /* displayedFile->topPosition = XawTextTopPosition(w); */
  169.     topPosition = XawTextTopPosition(w);
  170.  
  171.     XtCallActionProc(w, "select-start", event, params, num_params);
  172.  
  173.     /* reset to remembered position if top position changed */
  174.     /* if (XawTextTopPosition(w) != displayedFile->topPosition)
  175.         TextSetTopPosition(w, displayedFile->topPosition); */
  176.     if (XawTextTopPosition(w) != topPosition)
  177.         TextSetTopPosition(w, topPosition);
  178. }
  179.  
  180. /*  My select-end routine to store the text selection into both the PRIMARY
  181.  *  selection and cut buffer 0. 
  182.  */
  183. /*  ARGSUSED */
  184. void SelectEnd(w, event, params, num_params)
  185.     Widget w;
  186.     XEvent *event;
  187.     String *params;
  188.     Cardinal *num_params;
  189. {
  190.     XawTextPosition begin, end, start;
  191.     Widget textsrc;
  192.     XawTextBlock buffer;
  193.     char s[10000];
  194.     int nchars;
  195.  
  196.     XawTextGetSelectionPos(w, &begin, &end);
  197.     XawTextSetSelection(w, begin, end);
  198.     if (begin == end) return;
  199.     textsrc = XawTextGetSource(w);
  200.     strcpy(s, "");
  201.     for (start=begin, nchars=end-begin; nchars > 0; 
  202.     start=begin+buffer.length, nchars-=buffer.length) {
  203.         XawTextSourceRead(textsrc, start, &buffer, nchars);
  204.     strncat(s, buffer.ptr, buffer.length);
  205.     }
  206.     XStoreBytes(display, s, strlen(s));
  207. }
  208.  
  209. /*  This is my own select word routine to replace the standard action
  210.  *  procedure provided by the Text widget.
  211.  *  It selects a word delimited by DELIMITERS, not whitespace.
  212.  */
  213. /* ARGSUSED */
  214. void SelectWord(w, event, params, num_params)
  215.     Widget w;
  216.     XEvent *event;
  217.     String *params;
  218.     Cardinal *num_params;
  219. {
  220.     XawTextPosition pos, left, right, start;
  221.     XawTextBlock buffer;
  222.     Widget    textsrc;
  223.     char     s[LINESIZ];
  224.     char     *p, *ls, *rs;
  225.     int        nchars;
  226.  
  227.     pos = XawTextGetInsertionPoint(w);
  228.     textsrc = XawTextGetSource(w);
  229.  
  230.     XawTextSourceRead(textsrc, pos, &buffer, 1);
  231.     if (buffer.length == 0 || (buffer.length == 1 &&
  232.     strchr(app_resources.delimiters, (int)*(buffer.ptr)) != NULL)) {
  233.     XStoreBytes(display, NULL, 0);
  234.     return;
  235.     }
  236.  
  237.     left = XawTextSourceScan(textsrc, pos+1, XawstWhiteSpace, XawsdLeft, 1,
  238.                              FALSE);
  239.     right = XawTextSourceScan(textsrc, left, XawstWhiteSpace, XawsdRight, 1,
  240.                               FALSE);
  241.     
  242.     strcpy(s, "");
  243.     for (start=left, nchars=right-left; nchars > 0; 
  244.     start=left+buffer.length, nchars-=buffer.length) {
  245.         XawTextSourceRead(textsrc, start, &buffer, nchars);
  246.     strncat(s, buffer.ptr, buffer.length);
  247.     }
  248.  
  249.     if (!strcmp(s, "")) return;
  250.     p = s+pos-left;
  251.     ls = (char *) strtok(s, app_resources.delimiters);
  252.     rs = (char *) strtok(NULL, app_resources.delimiters);
  253.     if (!ls) return;
  254.     while (rs<=p && rs!=NULL) {
  255.     ls = rs;
  256.     rs = (char *) strtok(NULL, app_resources.delimiters);
  257.     }
  258.     left = left + ls - s;
  259.     right = left + strlen(ls) - 1; 
  260.  
  261.     XawTextUnsetSelection(w);
  262.     XStoreBytes(display, ls, strlen(ls));
  263.     XawTextSetSelection(w, left, right+1);
  264. }
  265.  
  266. /*  Print the value of the expression  in cut buffer 0. */
  267. /*  ARGSUSED */
  268. void PrintSelection(w, event, params, num_params)
  269.     Widget w;
  270.     XEvent *event;
  271.     String *params;
  272.     Cardinal *num_params;
  273. {
  274.     char command[LINESIZ];
  275.     char *string;
  276.     int nbytes;
  277.  
  278.     string = XFetchBytes(display, &nbytes);
  279.     if (nbytes == 0) {
  280.         UpdateMessageWindow(PRINT_HELP, NULL);
  281.         bell(0);
  282.         return;
  283.     }
  284.     sprintf(command, "print %s\n", string);
  285.     send_command(command);
  286.     AppendDialogText(command);
  287. }
  288.  
  289. /* 
  290.  *  On top of a form widget, we have a text widget with scrollbar, label
  291.  *  widgets for the stop sign, arrow sign, and updown signs.
  292.  */
  293. void CreateSourceWindow(parent)
  294. Widget parent;
  295. {
  296.     TextWidget ctx;
  297.     Arg args[MAXARGS];
  298.     Cardinal n;
  299.  
  300.     static XtActionsRec sbar_actions[] = {
  301.         {"NotifyResize",   NotifyResize},
  302.         {"Update",        Update},
  303.         {NULL, NULL}
  304.     };
  305.  
  306.     static String sbarTranslations = "\
  307.         <Configure>:    NotifyResize() \n\
  308.         <Btn2Down>:     StartScroll(Continuous) MoveThumb() NotifyThumb() \
  309.                         Update() \n\
  310.         <Btn2Motion>:   MoveThumb() NotifyThumb() Update() \n\
  311.         <BtnUp>:        NotifyScroll(Proportional) EndScroll() Update() \n\
  312.     ";
  313.  
  314.     n = 0;
  315.     XtSetArg(args[n], XtNdefaultDistance, 0);                           n++;
  316.     sourceForm = XtCreateManagedWidget("sourceForm", formWidgetClass, 
  317.                      parent, args, n);
  318.  
  319.     n = 0;
  320.     XtSetArg(args[n], XtNborderWidth, 0);                n++;
  321.     XtSetArg(args[n], XtNtype, (XtArgVal)XawAsciiFile);            n++;
  322.     XtSetArg(args[n], XtNstring, (XtArgVal)"/dev/null");        n++;
  323.     XtSetArg(args[n], XtNscrollVertical, (XtArgVal) XawtextScrollAlways);n++;
  324.     sourceWindow = XtCreateManagedWidget("sourceWindow", asciiTextWidgetClass,
  325.                       sourceForm, args, n);
  326.  
  327.     ctx = (TextWidget) sourceWindow;
  328.     if (ctx->text.vbar)
  329.         XtOverrideTranslations(ctx->text.vbar, 
  330.                 XtParseTranslationTable(sbarTranslations));
  331.     XtAppAddActions(app_context, sbar_actions, XtNumber(sbar_actions));
  332. }
  333.  
  334.  
  335. /*
  336.  *  Build the array which gives the starting text position of each line.
  337.  *  > Estimate the number of lines in the file and allocate memory buffer.
  338.  *  > Starting position of line #1 is 0, and is stored in linepos[1].
  339.  *  > Search for '\n' till end of buffer.
  340.  */
  341. static void BuildLinePos(file)
  342. FileRec *file;
  343. {
  344.     char *p;
  345.     int     line, nlines;
  346.  
  347.     nlines = MAX(1, file->filesize/CHARS_PER_LINE);
  348.     file->linepos = (XawTextPosition *)
  349.             XtMalloc ((nlines+2) * sizeof(XawTextPosition));
  350.     p = file->buf;
  351.     line = 0;
  352.     file->linepos[line++] = 0;
  353.     file->linepos[line++] = 0;
  354.     while (*p) {
  355.     if (*p++ == '\n') {
  356.         if (line == nlines) {     /* buffer full, need more memory */
  357.                 file->linepos = (XawTextPosition *) XtRealloc (file->linepos, 
  358.               (nlines + ADD_LINES) * sizeof(XawTextPosition));
  359.         nlines += ADD_LINES;
  360.             }
  361.             file->linepos[line++] = p - file->buf;
  362.     }
  363.     }
  364.     file->lastline = line - 2;
  365.     file->linepos = (XawTextPosition *) XtRealloc     /* shrink to min size */
  366.             (file->linepos, line * sizeof(XawTextPosition));
  367. }
  368.  
  369.  
  370. /*
  371.  * Look up the file table for an entry with "filename"
  372.  * If not found, create an entry and initialize proper fields,
  373.  * else, return pointer to entry found.
  374.  */
  375. static LookUpFileTable(pathname, filename, file)
  376. char *pathname, *filename;
  377. FileRec **file;
  378. {
  379.     struct stat fileinfo;
  380.     int      fd;
  381.     int     i, j, n;
  382.  
  383.     for (i=0; fileTable && fileTable[i] && i<fileTableSize; i++) {
  384.     if (strcmp(fileTable[i]->pathname, pathname) == NULL) { /* file found */
  385.         if (stat(pathname, &fileinfo) == -1) {
  386.         UpdateMessageWindow("Error: cannot stat file %s", pathname);
  387.             *file = fileTable[i];
  388.         return 0;
  389.         }
  390.         if (fileinfo.st_mtime > fileTable[i]->mtime) { /* file modified */
  391.         XtFree((char *)fileTable[i]->buf);
  392.         XtFree((char *)fileTable[i]->linepos);
  393.         XtFree((char *)fileTable[i]);
  394.         displayedFile = NULL;
  395.         break;
  396.         }
  397.         else if (displayedFile &&         /* same as displayed file */
  398.              strcmp(pathname, displayedFile->pathname) == 0) {
  399.         *file = NULL;
  400.         return 0;
  401.         }
  402.         else {
  403.             *file = fileTable[i];
  404.         return 0;
  405.         }
  406.     }
  407.     }
  408.  
  409.     /* Record file into file table */
  410.  
  411.     if (i == fileTableSize) {        /* file table full, enlarge it */
  412.     fileTableSize += ADD_SIZE;
  413.     fileTable = (FileRec **) 
  414.              XtRealloc (fileTable, fileTableSize * sizeof(FileRec *));
  415.     for (j=i; j<fileTableSize; j++)
  416.         fileTable[j] = NULL;
  417.     }
  418.     if ((fd = open(pathname, O_RDONLY)) == -1) {
  419.     UpdateMessageWindow("Error: cannot open file %s", pathname);
  420.     return -1;
  421.     }
  422.     if (fstat(fd, &fileinfo) == -1) {
  423.     UpdateMessageWindow("Error: cannot fstat file %s", pathname);
  424.     close(fd);
  425.     return -1;
  426.     }
  427.     fileTable[i] = (FileRec *) XtMalloc (sizeof(FileRec));
  428.     fileTable[i]->filesize = fileinfo.st_size + 1;
  429.     fileTable[i]->mtime = fileinfo.st_mtime;
  430.     fileTable[i]->buf = XtMalloc((int)fileTable[i]->filesize);
  431.     if ((n = read(fd, fileTable[i]->buf, (int) fileTable[i]->filesize)) == -1) {
  432.     UpdateMessageWindow("Error: cannot read file %s", pathname);
  433.     XtFree(fileTable[i]->buf);
  434.     XtFree(fileTable[i]);
  435.     fileTable[i] = NULL;
  436.     close(fd);
  437.     return -1;
  438.     }
  439.     fileTable[i]->buf[n] = '\0';
  440.     fileTable[i]->pathname = XtNewString(pathname);
  441.     fileTable[i]->filename = XtNewString(filename);
  442.     fileTable[i]->currentline = 1;
  443.     fileTable[i]->topline = 1;
  444.     fileTable[i]->bottomline = 0;
  445.     fileTable[i]->topPosition = 0;
  446.     BuildLinePos(fileTable[i]);
  447.     close(fd);
  448.     *file = fileTable[i];
  449.     return 0;
  450. }
  451.  
  452. /*  
  453.  *  Remember file position and current line before closing.
  454.  */
  455. static void SaveDisplayedFileInfo()
  456. {
  457.     XawTextPosition pos;
  458.  
  459.     if (displayedFile) {
  460.         displayedFile->topPosition = XawTextTopPosition(sourceWindow);
  461.     pos = XawTextGetInsertionPoint(sourceWindow);
  462.     displayedFile->currentline = TextPositionToLine(pos);
  463.     }
  464. }
  465.  
  466.  
  467. /*   DisplayFile() displays the file onto the source window.  It
  468.  *     uses topPosition to remember where it was last opened.  But it
  469.  *     must recalculate bottomline because the window size might be
  470.  *     different.
  471.  */
  472. static void DisplayFile(file)
  473. FileRec *file;
  474. {
  475.     Arg     args[MAXARGS];
  476.     Cardinal     n;
  477.     TextWidget     ctx = (TextWidget) sourceWindow;
  478.  
  479.     n = 0;
  480.     XtSetArg(args[n], XtNdisplayPosition, (XtArgVal)file->topPosition);    n++;
  481.     XtSetArg(args[n], XtNstring, (XtArgVal) file->pathname);        n++;
  482.     XtSetArg(args[n], XtNeditType, (XtArgVal) XawtextRead);        n++;
  483.     XtSetValues(sourceWindow, args, n);
  484.     file->lines = ctx->text.lt.lines;
  485.     file->bottomline = MIN (file->topline + file->lines - 1, file->lastline);
  486. }
  487.  
  488.  
  489. /*  Given a filename starting with a tilde (`~'), it expands ~[user] to
  490.  *  the home directory of that user, or to the login home directory if user
  491.  *  is not specified.
  492.  */
  493. static char *expand(filename)
  494. char *filename;
  495. {
  496.     struct passwd *pwd;
  497.     char       *string, *name, newfile[MAXNAME];
  498.  
  499.     string = XtNewString(filename+1);
  500.     if (*string == '\0' || *string == '/')
  501.     name = (char *) getlogin();
  502.     else
  503.         name = (char *) strtok(string, "/");
  504.     if (name == NULL)
  505.     return filename;
  506.     pwd = (struct passwd *) getpwnam(name);
  507.     if (pwd && pwd->pw_dir) {
  508.         sprintf(newfile, "%s%s", pwd->pw_dir, filename+strlen(name)+1);
  509.         return XtNewString(newfile);
  510.     }
  511.     else
  512.     return filename;
  513. }
  514.  
  515.  
  516. /*  Create a list of directories for searching source files.
  517.  *  It reads the list of directories specified by the user, adding
  518.  *  the current directory into the list if it is not already there.
  519.  *
  520.  *  With fix from Dave Gagne (daveg@fs1.ee.ubc.ca) 7/30/90
  521.  */
  522. void MakeDirList(output)
  523. char *output;
  524. {
  525.     char *s, list[BUFSIZ], command[LINESIZ];
  526.     int  i, use_cwd;
  527.  
  528.     for (i=0; dirList[i]; i++)            /* remove old list */
  529.     XtFree(dirList[i]);
  530.     i = 0;
  531.     use_cwd = TRUE;
  532.     if (output) {                                        /* create list */
  533.         s = (char *) strtok(output, " \n");
  534.         while (s) {
  535.             dirList[i] = XtNewString(s);
  536.  
  537.             if (dirList[i][0] == '~')                   /* expand '~' */
  538.                 dirList[i] = expand(dirList[i]);
  539.             if (LASTCH(dirList[i]) == '/')              /* remove last '/' */
  540.                 LASTCH(dirList[i]) = '\0';
  541.             if (strcmp(dirList[i], ".") == NULL)        /* watch for "." */
  542.                 use_cwd = FALSE;
  543.  
  544.             ++i;
  545.             s = (char *) strtok(NULL, " \n");
  546.         }
  547.         dirList[i] = NULL;
  548.     }
  549.  
  550.     if (use_cwd) {                /* include current dir */
  551.     dirList[i++] = XtNewString(".");        
  552.         dirList[i] = NULL;
  553.     }
  554.     strcpy(list, "");                /* tell dbx our new list */
  555.     for (i=0; dirList[i]; i++) {
  556.     strcat(list, dirList[i]);
  557.     strcat(list, " ");
  558.     }
  559.     sprintf(command, "use %s\n", list);
  560.     Parse = False;
  561.     query_dbx(command);
  562. }
  563.  
  564.  
  565. /*  Returns the full pathname of a given file.
  566.  *  It searches for the file from a list of directories.
  567.  */
  568. char *GetPathname(filename)
  569. char *filename;
  570. {
  571.     char    pathname[LINESIZ];
  572.     int     i;
  573.  
  574.     if (filename == NULL || strcmp(filename, "") == NULL)
  575.     return NULL;
  576.     for (i=0; dirList[i]; i++) {
  577.     if (*filename == '/' && access(filename, R_OK) == -1) { 
  578.         /* this handles the exceptional case of sun4 dbx output */
  579.         strcpy(filename, &filename[1]);
  580.     }
  581.     if (*filename == '/' || *filename == '~')
  582.          strcpy(pathname, filename);
  583.     else if (strcmp(dirList[i], ".") == NULL)
  584.          sprintf(pathname, "%s/%s", cwd, filename);
  585.     else if (*dirList[i] == '/' || *dirList[i] == '~')
  586.          sprintf(pathname, "%s/%s", dirList[i], filename);
  587.     else
  588.          sprintf(pathname, "%s/%s/%s", cwd, dirList[i], filename);
  589.     if (access(pathname, R_OK) == 0)
  590.         return XtNewString(pathname);
  591.     }
  592.     UpdateMessageWindow("File not found: %s", filename);
  593.     return NULL;
  594. }
  595.  
  596. /*
  597.  * Given a file name, LoadFile attempts to open it and displays it onto
  598.  * the source window:
  599.  *   1. get the full pathname of the file
  600.  *   2. LookUpFileTable() returns a pointer to the file's entry if it's
  601.  *      already in the table; else, creates an entry and return a pointer.
  602.  *   3. save the current displayedFile info
  603.  *   4. display the file
  604.  *   5. update the file label and the various signs on the source window.
  605.  *  LoadFile returns 0 upon successful completion, -1 otherwise.
  606.  */
  607. int LoadFile(filename)
  608. char *filename;
  609. {
  610.     FileRec     *file;
  611.     char    *pathname;
  612.  
  613.     pathname = GetPathname(filename);
  614.     if (pathname == NULL) { 
  615.     return -1;
  616.     }
  617.     if (LookUpFileTable(pathname, filename, &file) != -1) {
  618.     if (file) {    /* load new file */
  619.         SaveDisplayedFileInfo();
  620.         DisplayFile(file);
  621.         UpdateFileLabel(pathname);
  622.         XawTextUnsetSelection(sourceWindow);
  623.         XawTextSetInsertionPoint(sourceWindow, file->linepos[file->currentline]);
  624.         UpdateLineLabel(file->currentline);
  625.         UpdateStops(file);
  626.         UpdateArrow(file);
  627.         UpdateUpdown(file);
  628.         UpdateBomb(file);
  629.         displayedFile = file;
  630.     }
  631.         return 0;
  632.     }
  633.     else {        /* LookUpFileTable() fails */
  634.         return -1;
  635.     }
  636. }
  637.  
  638. int LoadCurrentFile()
  639. {
  640.     query_dbx("file\n");
  641.     return LoadFile(CurrentFile);
  642. }
  643.