home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / xdbx / part02 / source.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-14  |  10.5 KB  |  384 lines

  1. /****************************************************************************** 
  2.  *
  3.  *  xdbx - X Window System interface to dbx
  4.  *
  5.  *  Copyright 1989 The University of Texas at Austin
  6.  *
  7.  *  Author:    Po Cheung
  8.  *  Date:    March 10, 1989
  9.  *
  10.  *  Permission to use, copy, modify, and distribute this software and
  11.  *  its documentation for any purpose and without fee is hereby granted,
  12.  *  provided that the above copyright notice appear in all copies and that
  13.  *  both that copyright notice and this permission notice appear in
  14.  *  supporting documentation.  The University of Texas at Austin makes no 
  15.  *  representations about the suitability of this software for any purpose.  
  16.  *  It is provided "as is" without express or implied warranty.
  17.  *
  18.  ******************************************************************************/
  19.  
  20.  
  21. #include "global.h"
  22. #include <X11/Xos.h>
  23. #include <sys/stat.h>
  24.  
  25. static FileRec    fileTable[MAXFILES];    /* table of file records */
  26. FileRec      *displayedFile;        /* pointer to table entry of currently
  27.                        displayed file */
  28. Boolean        Echo = True;        /* to intercept dbx output */
  29.  
  30.  
  31. void source_init()
  32. {
  33.     int i;
  34.  
  35.     for (i=0; i<MAXFILES; i++) {
  36.     fileTable[i].filename = XtNewString("");
  37.     }
  38. }
  39.  
  40. /*
  41.  *  Update topline, bottomline, arrow sign, updown sign, stop signs, and
  42.  *  line label.  Invoked by scrollbar action.
  43.  */
  44. /* ARGSUSED */
  45. static XtActionProc Update(w, event, params, num_params)
  46.     Widget w;
  47.     XEvent *event;
  48.     String *params;
  49.     Cardinal *num_params;
  50. {
  51.     TextWidget      ctx = (TextWidget) sourceWindow;
  52.     XtTextPosition      pos;
  53.     Line        line;
  54.     FileRec         *file;
  55.  
  56.     if (displayedFile) {
  57.         file = displayedFile;
  58.     pos = ctx->text.lt.top;
  59.     for(line=1; pos >= file->linepos[line]; line++);
  60.     if (file->topline != line-1) {
  61.         file->topline = line-1;
  62.         file->bottomline = MIN (file->topline + file->lines - 1, 
  63.                     file->lastline);
  64.         XtTextSetInsertionPoint(sourceWindow, file->linepos[file->topline]);
  65.         UpdateLineLabel(file->topline);
  66.             UpdateStops(file);
  67.             UpdateArrow(file);
  68.             UpdateUpdown(file);
  69.     }
  70.     }
  71. }
  72.  
  73. /*  Invoked by left mouse button down, update the line label. 
  74.  */
  75. /* ARGSUSED */
  76. static XtActionProc UpdateLine(w, event, params, num_params)
  77.     Widget w;
  78.     XEvent *event;
  79.     String *params;
  80.     Cardinal *num_params;
  81. {
  82.     XtTextPosition pos;
  83.     Line line;
  84.  
  85.     pos = XtTextGetInsertionPoint(sourceWindow);
  86.     line = TextPositionToLine(pos);
  87.     UpdateLineLabel(line);
  88. }
  89.  
  90. /*
  91.  *  Update bottomline, arrow sign, updown sign and stop signs
  92.  *  Invoked by ConfigureNotify event.
  93.  *  Note that topline never changes with resize, only bottomline gets changed.
  94.  */
  95. /* ARGSUSED */
  96. static XtActionProc NotifyResize(w, event, params, num_params)
  97.     Widget w;
  98.     XEvent *event;
  99.     String *params;
  100.     Cardinal *num_params;
  101. {
  102.     TextWidget  ctx = (TextWidget) sourceWindow;
  103.     FileRec    *file;
  104.  
  105.     if (file = displayedFile) {
  106.     file->lines = ctx->text.lt.lines;
  107.         file->bottomline = MIN (file->topline + file->lines - 1, 
  108.                 file->lastline);
  109.         UpdateStops(file);
  110.         UpdateArrow(file);
  111.         UpdateUpdown(file);
  112.     }
  113. }
  114.  
  115.  
  116. /* 
  117.  *  On top of a form widget, we have a text widget with scrollbar, a label
  118.  *  widget for the arrow sign, one for the updown sign and some for stop signs.
  119.  */
  120. void CreateSourceWindow(parent)
  121. Widget parent;
  122. {
  123.     TextWidget ctx;
  124.     Arg args[MAXARGS];
  125.     Cardinal n;
  126.  
  127.     static XtActionsRec actionTable[] = {
  128.         {"NotifyResize",   (XtActionProc) NotifyResize},
  129.         {"MySelectWord", (XtActionProc) MySelectWord},
  130.         {"UpdateLine", (XtActionProc) UpdateLine},
  131.         {"Update",        (XtActionProc) Update},
  132.         {NULL, NULL}
  133.     };
  134.  
  135.     static String translations = "\
  136.         <Btn1Down>:     select-start() ClearCutBuffer0() UpdateLine()\n\
  137.         <Btn1Up>(2):    MySelectWord()";
  138.  
  139.     static String sbarTranslations = "\
  140.         <Configure>:    NotifyResize() \n\
  141.         <Btn2Down>:     StartScroll(Continuous) MoveThumb() NotifyThumb() \
  142.                         Update() \n\
  143.         <Btn2Motion>:   MoveThumb() NotifyThumb() Update() \n\
  144.         <BtnUp>:        NotifyScroll(Proportional) EndScroll() Update()";
  145.  
  146.  
  147.     n = 0;
  148.     XtSetArg(args[n], XtNdefaultDistance, 0);                           n++;
  149.     sourceWidget = XtCreateManagedWidget("sourceWidget", formWidgetClass, 
  150.                      parent, args, n);
  151.  
  152.     n = 0;
  153.     XtSetArg(args[n], XtNheight, app_resources.sourceHeight);         n++;
  154.     XtSetArg(args[n], XtNleftMargin, app_resources.leftMargin);        n++;
  155.     XtSetArg(args[n], XtNborderWidth, 0);                n++;
  156.     XtSetArg(args[n], XtNtextOptions, (XtArgVal) scrollVertical);    n++;
  157.  
  158.     sourceWindow = XtCreateManagedWidget("sourceWindow", asciiStringWidgetClass,
  159.                       sourceWidget, args, n);
  160.     ctx = (TextWidget) sourceWindow;
  161.     XtOverrideTranslations(sourceWindow, 
  162.                XtParseTranslationTable(translations));
  163.     XtOverrideTranslations(ctx->text.sbar, 
  164.                XtParseTranslationTable(sbarTranslations));
  165.     XtAddActions(actionTable, XtNumber(actionTable));
  166. }
  167.  
  168.  
  169. /*
  170.  * Build the array which gives the starting text position of each line
  171.  *   look for CR, get the position, add 1, which becomes the starting
  172.  *   position of next line.
  173.  */
  174. static void BuildLinePos (file)
  175. FileRec *file;
  176. {
  177.     char *s;
  178.     Line line, nlines;
  179.  
  180.     nlines = file->filesize/CHARS_PER_LINE;
  181.     file->linepos = (XtTextPosition *)XtMalloc(nlines * sizeof(XtTextPosition));
  182.     s = file->buf;
  183.     line = 0;
  184.     file->linepos[line++] = 0;
  185.     file->linepos[line++] = 0;
  186.     while (*s) {
  187.     if (*s++ == '\n') {
  188.         if (line == nlines) {
  189.                 file->linepos = (XtTextPosition *) XtRealloc (file->linepos, 
  190.               (nlines + ADD_LINES) * sizeof(XtTextPosition));
  191.         nlines += ADD_LINES;
  192.             }
  193.             file->linepos[line++] = s - file->buf;
  194.     }
  195.     }
  196.     file->lastline = line - 2;
  197.     file->linepos = (XtTextPosition *) XtRealloc 
  198.             (file->linepos, line * sizeof(XtTextPosition));
  199. }
  200.  
  201.  
  202. static long GetFileSize(fd)
  203. int  fd;
  204. {
  205.     struct stat fileinfo;
  206.  
  207.     if (fstat(fd, &fileinfo))
  208.     return -1;
  209.     return (fileinfo.st_size + 1);
  210. }
  211.  
  212. /*
  213.  * Look up the file table for an entry with "filename"
  214.  * If not found, create an entry and initialize proper fields,
  215.  * else, return pointer to entry found.
  216.  */
  217. static FileRec *LookUpFileTable(filename, fd)
  218. char *filename;
  219. int  fd;
  220. {
  221.     int i, c1, c2;
  222.     char message[LINESIZ];
  223.  
  224.     for (i=0; fileTable[i].filename &&
  225.           (c1 = strcmp(fileTable[i].filename, "")) && 
  226.           (c2 = strcmp(fileTable[i].filename, filename)) &&
  227.           i < MAXFILES; i++);
  228.  
  229.     if (i >= MAXFILES) {        /* too many files */
  230.     i = 0;
  231.     c1 = 0;
  232.     XtFree(fileTable[i].buf);
  233.     }
  234.     if (c1 == 0) {            /* file does not exist in table */
  235.     if ((fileTable[i].filesize = GetFileSize(fd)) == -1)
  236.         return NULL ;
  237.     fileTable[i].buf = XtMalloc(fileTable[i].filesize);
  238.     if (read(fd, fileTable[i].buf, fileTable[i].filesize) == -1) {
  239.         sprintf(message, "Can't read %s: read error\n", filename);
  240.         UpdateMessageWindow(message);
  241.         XtFree(fileTable[i].buf);
  242.         return NULL;
  243.         }
  244.     fileTable[i].filename = XtNewString(filename);
  245.     strcpy(fileTable[i].funcname, "");
  246.     fileTable[i].currentline = 1;
  247.     fileTable[i].topline = 1;
  248.     fileTable[i].bottomline = 0;
  249.     fileTable[i].topPosition = 0;
  250.     BuildLinePos(&fileTable[i]);
  251.     return &fileTable[i];
  252.     }
  253.     if (c2 == 0) {            /* file exists in table */
  254.         return &fileTable[i];
  255.     }
  256. }
  257.  
  258.  
  259. /*
  260.  * Get the name of the file returned by the 'file' command to dbx
  261.  * If no source file is specified, QueryFile returns NULL
  262.  */
  263. char *QueryFile()
  264. {
  265.     char *string, s[LINESIZ], t[LINESIZ];
  266.  
  267.     Echo = FALSE;
  268.     writeDbx("file\n");
  269.     while (fgets(s, LINESIZ, dbxfp) == NULL);
  270.     if (string = (char *) strtok(s, " \n")) {
  271.     if (strtok(NULL, " \n"))
  272.         string = NULL;
  273.     }
  274.     while (fgets(t, LINESIZ, dbxfp));
  275.     Echo = TRUE;
  276.     if (string) 
  277.     return XtNewString(string);
  278.     else
  279.     return NULL;
  280. }
  281.  
  282. /*  
  283.  *  Remember file position before closing.
  284.  *  Clear field funcname for proper operation of parse() & UpdateFuncLabel()
  285.  */
  286. static void SaveDisplayedFileInfo()
  287. {
  288.     XtTextPosition pos;
  289.  
  290.     if (displayedFile) {
  291.         displayedFile->topPosition = XtTextTopPosition(sourceWindow);
  292.     pos = XtTextGetInsertionPoint(sourceWindow);
  293.     displayedFile->currentline = TextPositionToLine(pos);
  294.     strcpy(displayedFile->funcname, "");
  295.     }
  296. }
  297.  
  298.  
  299. static void DisplayFile(file)
  300. FileRec *file;
  301. {
  302.     Arg args[MAXARGS];
  303.     Cardinal n;
  304.     TextWidget ctx = (TextWidget) sourceWindow;
  305.  
  306.     n = 0;
  307.     XtSetArg(args[n], XtNstring, (XtArgVal) file->buf);            n++;
  308.     XtSetArg(args[n], XtNlength, (XtArgVal) file->filesize);        n++;
  309.     XtSetArg(args[n], XtNeditType, (XtArgVal) XttextRead);        n++;
  310.  
  311.     XtTextSetSource(sourceWindow, 
  312.             XtStringSourceCreate(sourceWindow, args, n),
  313.             file->topPosition);
  314.     file->lines = ctx->text.lt.lines;
  315.     file->bottomline = MIN (file->topline + file->lines - 1, file->lastline);
  316. }
  317.  
  318.  
  319. static void FullPath(filename, path)
  320. char *filename, *path;
  321. {
  322.     char *dir;
  323.  
  324.     dir = dbxpwd();
  325.     if (dir) {
  326.         strcpy(path, dir);
  327.         strcat(path, "/");
  328.         strcat(path, filename);
  329.         XtFree(dir);
  330.     }
  331.     else 
  332.     strcpy(path, filename);
  333. }
  334.  
  335. /*
  336.  * Given a file name, LoadFile attempts to open it and displays it onto
  337.  * the source window.  
  338.  *   LookUpFileTable checks if the file is already in the file table.
  339.  *     if it exists, a pointer to the file structure is retured;
  340.  *     otherwise, an entry is created and its info initialized;
  341.  *     returns NULL only if file table full.
  342.  *   SaveDisplayedFileInfo saves important information about the file
  343.  *     back in the file table; they include: topPosition, breakpoints.
  344.  *   DisplayFile displays the file onto the source window.  It
  345.  *     uses topPosition to remember where it was last opened.  But it
  346.  *     must recalculate bottomline because the window size might be
  347.  *     different.
  348.  */
  349. FileRec *LoadFile(filename)
  350. char *filename;
  351. {
  352.     FileRec     *file;
  353.     int     fd;
  354.     char    message[LINESIZ];
  355.     char    pathname[LINESIZ];
  356.  
  357.     if (filename == NULL)
  358.     return displayedFile;
  359.     if (displayedFile && strcmp(filename, displayedFile->filename) == 0)
  360.     return displayedFile;
  361.     FullPath(filename, pathname);
  362.     if ((fd = open(pathname, O_RDONLY)) == -1) {
  363.     sprintf(message, "open: file not found : %s", pathname);
  364.     UpdateMessageWindow(message);
  365.     return displayedFile;
  366.     }
  367.     else if (file = LookUpFileTable(filename, fd)) {
  368.         SaveDisplayedFileInfo();
  369.         DisplayFile(file);
  370.     UpdateFileLabel(file->filename);
  371.     XtTextSetInsertionPoint(sourceWindow, file->linepos[file->currentline]);
  372.     UpdateLineLabel(file->currentline);
  373.     UpdateStops(file);
  374.     UpdateArrow(file);
  375.     UpdateUpdown(file);
  376.         close(fd);
  377.         return file;
  378.     }
  379.     else {
  380.         close(fd);
  381.         return displayedFile;
  382.     }
  383. }
  384.