home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource5 / 331_01 / store.c < prev    next >
Text File  |  1990-06-12  |  17KB  |  629 lines

  1. /*
  2. HEADER:         CUG999.08;
  3. DATE:           5/15/87;
  4.  
  5. DESCRIPTION:    "Text storage and manipulation routines for the GED editor.
  6.                  Virtual memory interface";
  7. KEYWORDS:       text storage, memory management, virtual storage, paging;
  8. SYSTEM:         MS-DOS;
  9. FILENAME:       VIRT2.C;
  10. AUTHORS:        G. Nigel Gilbert, James W. Haefner, Mel Tearle, G. Osborn;
  11. COMPILERS:      Microsoft 4.0;
  12. */
  13.  
  14. /*
  15.      e/qed/ged/se  screen editor
  16.  
  17.     (C) G. Nigel Gilbert, MICROLOGY, 1981
  18.            August-December 1981
  19.  
  20.     Modified:  Aug-Dec   1984:   BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
  21.                March     1985:   BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
  22.                May       1986:   converted to ged - Mel Tearle
  23.  
  24.  
  25.     FUNCTIONS: loc, gettext, getline, inject, deltp, puttext,
  26.                readtext, opentext, balloc,
  27.                addhistory, trim
  28.  
  29.     PURPOSE:   get and put text lines into and out of storage
  30.  
  31.  
  32.  
  33.  
  34.    The far and huge pointer definitions can be removed by changing
  35.    the preprocessor directives in ged.h
  36.  
  37.  
  38. */
  39.  
  40. #include <stdio.h>
  41. #include <ctype.h>
  42. #include "ged.h"
  43.  
  44.  
  45. int untrims;
  46.  
  47.  
  48. /* returns line + move, adjusted to be within text.
  49.  */
  50. loc(line,move)
  51. int line, move;
  52. {
  53.     int y, sav, i;
  54.  
  55.     if(charep) {
  56.         i = move;
  57.         if(i < 0)
  58.             i = -i;
  59.         if (i > 10) {
  60.             charep = 0;  /* exit character replace mode if line changes a lot*/
  61.             blankedmess = YES;  /* and change the header status indication */
  62.         }
  63.     }
  64.  
  65.     if ( ( y = line+move ) < 1 )
  66.         y = 1;
  67.     if ( y > lastl )
  68.         return lastl;
  69.     else
  70.         return y;
  71. }
  72.  
  73.  
  74. /* makes 'line' the current line.
  75.    Lines which appear on the screen cause the virtual memory page containing
  76.    the line to be marked as recently used.  The global search operations do
  77.    not call this routine.
  78.  */
  79. gettext(line, cp)
  80. int line, cp;
  81. {
  82.     int i;
  83.     char *getline();
  84.  
  85.     if (altered)
  86.         cerr(80);   /* the text buffer was not stored with puttext */
  87.  
  88.     strcpy( text, getline( line ) );
  89.     pad(cp);  /* add trailing spaces if cursor beyond end of line */
  90.  
  91.     cline = line;
  92.  
  93.     if (clock < (MAXINT-1) )
  94.         clock++;
  95. /* don't lower the priority of newpage */
  96.     i = virtslot[ tp[line].page ];
  97.     if (usage[i] < clock)
  98.         usage[i] = clock;
  99.  
  100.  
  101.     text[LLIM-1] = '\0';   /* for diagnostic checks only */
  102.     return;
  103. }
  104.  
  105. /* returns small memory model address of text of 'line' and updates
  106.  * page usage.  The buffers used by getline and gettext have to be
  107.  * different.  The extra text move for gettext has no significant effect
  108.  * on program timing.  getline is used for the string search operatios
  109.  * and needs to be fast.
  110.  *
  111.  * getline has to be used with caution because the page pointed to can
  112.  * be swapped out by subsequent activites, invalidating the pointer.  That
  113.  * problem does not exist in this version because the line is copied to
  114.  * a local buffer to satisfy the mixed memory model requirements.
  115.  * In this version the pointer is invalidated by a subsequent gettext().
  116.  *
  117.  * Requires that strings not cross 64 k boundaries.
  118.  */
  119.  
  120. char glbuf[LLIM];  /* this buffer is shared by getline, gethist, & gettext */
  121.  
  122. char *getline(line)
  123. int line;
  124. {
  125.     char FAR *hgetline();
  126.     register char FAR *hptr;
  127.     register char *s;
  128.  
  129.     hptr=hgetline(line);
  130.     s=&glbuf[0];
  131. /* The following is equivalent to the movesf() call.  movesf is in pcio.asm
  132.  *  while (*s++ = *hptr++)
  133.  *      ;
  134.  */
  135.     movesf(s,hptr);
  136.     return &glbuf[0];
  137. }
  138.  
  139. /* used by undo */
  140. char *gethist(page,offset)
  141. int page,offset;
  142. {
  143.     char HUGE *hptr;
  144.     char *s;
  145.     if(virtslot[page] < 0)
  146.         swappin(page);
  147.     hptr = slotaddr[virtslot[page]]+offset;
  148.     s = &glbuf[0];
  149.     while (*s++ = *hptr++)
  150.         ;
  151.     return &glbuf[0];
  152. }
  153. /* returns far address of text of 'line'
  154.  * and updates page usage.  Requires that 2<<16 % pagesize == 0 to
  155.  * avoid crosssing a 64 k boundary.
  156.  * the huge pointers are recast to far for consistancy and effieciency.
  157.  */
  158. /*
  159. char FAR *hgetline(line)
  160. int line;
  161. {
  162.     int pg;
  163.     line = loc(line,0);
  164.     pg = tp[line].page;
  165.     if ( virtslot[pg] < 0 )
  166.         swappin(pg);
  167.     return  (char FAR *) slotaddr[virtslot[pg]] + tp[line].moffset;
  168. }
  169. */
  170. char FAR *hgetline(line)
  171. int line;
  172. {
  173.     int pg;
  174.     int i,j;
  175.  
  176.     line = loc(line,0);
  177.     pg = tp[line].page;
  178.     if ( virtslot[pg] < 0 )
  179.         swappin(pg);
  180.  
  181.     i =  tp[line].moffset;
  182.     if(i > 0) {
  183.         j = *((char FAR *) slotaddr[virtslot[pg]] + tp[line].moffset -1);
  184.         if(j != 0)
  185.             cerr(84);
  186.     }
  187.     return  (char FAR *) slotaddr[virtslot[pg]] + tp[line].moffset;
  188. }
  189.  
  190.  
  191. /* Inserts 'txt' after 'line', moving following pointer array up.  Line 1
  192.  * is injected at 0.
  193.  *
  194.  * See also comment in deltp.
  195.  */
  196. inject(line,txt)
  197. int  line;
  198. char *txt;
  199. {
  200.     int  l, balloc();
  201.     int i, j, trims;
  202.     char *s;
  203.     char FAR *h;
  204.     long FAR *ht;
  205.     long FAR *hf;
  206.     long int ii;
  207.  
  208.  
  209.     trims = trim(txt);
  210.  
  211.     if (lastl > 16383)
  212.         goto tomany;
  213.  
  214.     ii = (long) (lastl + 1) * sizeof(*tp);
  215.     if ( (ii/PAGESIZE) >= tpslots) {
  216. /* need another slot to store tp's in */
  217.         if ( tpslots == slotsinmem-2)
  218.             goto tomany;
  219.         if ( usage[tpslots] > 0 )
  220.             swapout(tpslots);  /* bump for tp, which can't be swapped out */
  221.         usage[tpslots++] = -1;
  222.     }
  223.  
  224.     addhistory( line+1, line+1, HISTINSERT );
  225.  
  226.     if(line < lastl) {
  227.         ht = (long int FAR *) &tp[lastl+1];
  228.         hf = (long int FAR *) &tp[lastl];
  229.         j = lastl-line;
  230.         for (i = 0; i < j; i++)
  231.             *ht-- = *hf--;
  232.     }
  233.     lastl++;
  234.  
  235.     tp[line+1].moffset = balloc(1+trims);  /* increments newpage if necessary */
  236.     tp[line+1].page = newpage;
  237.     h = slotaddr[virtslot[newpage]] + tp[line+1].moffset;
  238.     s = &txt[0];
  239.     while (*h++ = *s++)
  240.         ;
  241.     stale(newpage);
  242.     untrim();
  243.  
  244. /* keep the default jump location on the same physical line */
  245.     if ( line <= jmpto)
  246.         jmpto++;
  247. /* keep the marked jump locations on the same physical line */
  248.     if ( line <= linem1)
  249.         linem1++;
  250.     if ( line <= linem2)
  251.         linem2++;
  252.     if ( line <= linem3)
  253.         linem3++;
  254. /* rember the last change for the jump command. never needs adjustment. */
  255.     lastc = line+1;
  256.  
  257.     return  line+1;
  258.  
  259. tomany:;
  260.     error(" Too many lines for RAM size.  Line lost. ");
  261.     return  FAIL;
  262. }
  263.  
  264.  
  265. /* delete line by shifting pointers
  266.  
  267.    The tp structures must have the same size as a long integer for
  268.    this routine to work.  Execution time is excessive for very large
  269.    documents if the shortcut is not used.
  270.  */
  271. deltp(dline, cnt)
  272. int dline, cnt;
  273. {
  274.     int i, j, lastls;
  275.     long FAR *ht;
  276.     long FAR *hf;
  277.  
  278.     lastls = lastl;
  279.     for (i = dline; i < dline+cnt; i++) {
  280.         addhistory( i, dline, HISTDELETE );    /* save for undo */
  281.         lastl--;
  282.         if ( lastl < 1 )
  283.             lastl = 1;
  284.         if (i < jmpto)
  285.             jmpto--;
  286.  
  287.         if (i < linem1)
  288.             linem1--;
  289.         if (i < linem2)
  290.             linem2--;
  291.         if (i < linem3)
  292.             linem3--;
  293.  
  294.         lastc = i;
  295.     }
  296.     ht = (long FAR *) &tp[dline];
  297.     hf = (long FAR *) &tp[dline+cnt];
  298.     j = lastls - dline;
  299.     for (i = 0; i < j; i++)
  300.         *ht++ = *hf++;
  301.  
  302.     return;
  303. }
  304.  
  305. /* replaces cline's text if it has been altered.  the new text goes to
  306.  * a newly allocated region.  the old text remains as is for the undo.
  307.  */
  308. puttext()
  309. {
  310.     int balloc();
  311.     char *s;
  312.     char FAR *h;
  313.     int tsize;
  314.  
  315.  
  316.     if (text[LLIM-1] != '\0')
  317.         cerr(81);
  318.  
  319.     if ( altered )  {
  320.         tsize = trim(text);   /* string restored before exit */
  321.         if (charn > untrims)
  322.             cerr(82);         /* trailing spaces lost */
  323.         addhistory( cline, cline, HISTREPLACE );   /* add for undo */
  324.         altered = NO;
  325.  
  326.         tp[cline].moffset = balloc(1+tsize);   /* increments newpage if necessary */
  327.         tp[cline].page = newpage;
  328.