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 >
Wrap
Text File
|
1990-06-12
|
17KB
|
629 lines
/*
HEADER: CUG999.08;
DATE: 5/15/87;
DESCRIPTION: "Text storage and manipulation routines for the GED editor.
Virtual memory interface";
KEYWORDS: text storage, memory management, virtual storage, paging;
SYSTEM: MS-DOS;
FILENAME: VIRT2.C;
AUTHORS: G. Nigel Gilbert, James W. Haefner, Mel Tearle, G. Osborn;
COMPILERS: Microsoft 4.0;
*/
/*
e/qed/ged/se screen editor
(C) G. Nigel Gilbert, MICROLOGY, 1981
August-December 1981
Modified: Aug-Dec 1984: BDS-C 'e'(vers 4.6a) to 'qe' (J.W. Haefner)
March 1985: BDS-C 'qe' to DeSmet-C 'qed' (J.W. Haefner)
May 1986: converted to ged - Mel Tearle
FUNCTIONS: loc, gettext, getline, inject, deltp, puttext,
readtext, opentext, balloc,
addhistory, trim
PURPOSE: get and put text lines into and out of storage
The far and huge pointer definitions can be removed by changing
the preprocessor directives in ged.h
*/
#include <stdio.h>
#include <ctype.h>
#include "ged.h"
int untrims;
/* returns line + move, adjusted to be within text.
*/
loc(line,move)
int line, move;
{
int y, sav, i;
if(charep) {
i = move;
if(i < 0)
i = -i;
if (i > 10) {
charep = 0; /* exit character replace mode if line changes a lot*/
blankedmess = YES; /* and change the header status indication */
}
}
if ( ( y = line+move ) < 1 )
y = 1;
if ( y > lastl )
return lastl;
else
return y;
}
/* makes 'line' the current line.
Lines which appear on the screen cause the virtual memory page containing
the line to be marked as recently used. The global search operations do
not call this routine.
*/
gettext(line, cp)
int line, cp;
{
int i;
char *getline();
if (altered)
cerr(80); /* the text buffer was not stored with puttext */
strcpy( text, getline( line ) );
pad(cp); /* add trailing spaces if cursor beyond end of line */
cline = line;
if (clock < (MAXINT-1) )
clock++;
/* don't lower the priority of newpage */
i = virtslot[ tp[line].page ];
if (usage[i] < clock)
usage[i] = clock;
text[LLIM-1] = '\0'; /* for diagnostic checks only */
return;
}
/* returns small memory model address of text of 'line' and updates
* page usage. The buffers used by getline and gettext have to be
* different. The extra text move for gettext has no significant effect
* on program timing. getline is used for the string search operatios
* and needs to be fast.
*
* getline has to be used with caution because the page pointed to can
* be swapped out by subsequent activites, invalidating the pointer. That
* problem does not exist in this version because the line is copied to
* a local buffer to satisfy the mixed memory model requirements.
* In this version the pointer is invalidated by a subsequent gettext().
*
* Requires that strings not cross 64 k boundaries.
*/
char glbuf[LLIM]; /* this buffer is shared by getline, gethist, & gettext */
char *getline(line)
int line;
{
char FAR *hgetline();
register char FAR *hptr;
register char *s;
hptr=hgetline(line);
s=&glbuf[0];
/* The following is equivalent to the movesf() call. movesf is in pcio.asm
* while (*s++ = *hptr++)
* ;
*/
movesf(s,hptr);
return &glbuf[0];
}
/* used by undo */
char *gethist(page,offset)
int page,offset;
{
char HUGE *hptr;
char *s;
if(virtslot[page] < 0)
swappin(page);
hptr = slotaddr[virtslot[page]]+offset;
s = &glbuf[0];
while (*s++ = *hptr++)
;
return &glbuf[0];
}
/* returns far address of text of 'line'
* and updates page usage. Requires that 2<<16 % pagesize == 0 to
* avoid crosssing a 64 k boundary.
* the huge pointers are recast to far for consistancy and effieciency.
*/
/*
char FAR *hgetline(line)
int line;
{
int pg;
line = loc(line,0);
pg = tp[line].page;
if ( virtslot[pg] < 0 )
swappin(pg);
return (char FAR *) slotaddr[virtslot[pg]] + tp[line].moffset;
}
*/
char FAR *hgetline(line)
int line;
{
int pg;
int i,j;
line = loc(line,0);
pg = tp[line].page;
if ( virtslot[pg] < 0 )
swappin(pg);
i = tp[line].moffset;
if(i > 0) {
j = *((char FAR *) slotaddr[virtslot[pg]] + tp[line].moffset -1);
if(j != 0)
cerr(84);
}
return (char FAR *) slotaddr[virtslot[pg]] + tp[line].moffset;
}
/* Inserts 'txt' after 'line', moving following pointer array up. Line 1
* is injected at 0.
*
* See also comment in deltp.
*/
inject(line,txt)
int line;
char *txt;
{
int l, balloc();
int i, j, trims;
char *s;
char FAR *h;
long FAR *ht;
long FAR *hf;
long int ii;
trims = trim(txt);
if (lastl > 16383)
goto tomany;
ii = (long) (lastl + 1) * sizeof(*tp);
if ( (ii/PAGESIZE) >= tpslots) {
/* need another slot to store tp's in */
if ( tpslots == slotsinmem-2)
goto tomany;
if ( usage[tpslots] > 0 )
swapout(tpslots); /* bump for tp, which can't be swapped out */
usage[tpslots++] = -1;
}
addhistory( line+1, line+1, HISTINSERT );
if(line < lastl) {
ht = (long int FAR *) &tp[lastl+1];
hf = (long int FAR *) &tp[lastl];
j = lastl-line;
for (i = 0; i < j; i++)
*ht-- = *hf--;
}
lastl++;
tp[line+1].moffset = balloc(1+trims); /* increments newpage if necessary */
tp[line+1].page = newpage;
h = slotaddr[virtslot[newpage]] + tp[line+1].moffset;
s = &txt[0];
while (*h++ = *s++)
;
stale(newpage);
untrim();
/* keep the default jump location on the same physical line */
if ( line <= jmpto)
jmpto++;
/* keep the marked jump locations on the same physical line */
if ( line <= linem1)
linem1++;
if ( line <= linem2)
linem2++;
if ( line <= linem3)
linem3++;
/* rember the last change for the jump command. never needs adjustment. */
lastc = line+1;
return line+1;
tomany:;
error(" Too many lines for RAM size. Line lost. ");
return FAIL;
}
/* delete line by shifting pointers
The tp structures must have the same size as a long integer for
this routine to work. Execution time is excessive for very large
documents if the shortcut is not used.
*/
deltp(dline, cnt)
int dline, cnt;
{
int i, j, lastls;
long FAR *ht;
long FAR *hf;
lastls = lastl;
for (i = dline; i < dline+cnt; i++) {
addhistory( i, dline, HISTDELETE ); /* save for undo */
lastl--;
if ( lastl < 1 )
lastl = 1;
if (i < jmpto)
jmpto--;
if (i < linem1)
linem1--;
if (i < linem2)
linem2--;
if (i < linem3)
linem3--;
lastc = i;
}
ht = (long FAR *) &tp[dline];
hf = (long FAR *) &tp[dline+cnt];
j = lastls - dline;
for (i = 0; i < j; i++)
*ht++ = *hf++;
return;
}
/* replaces cline's text if it has been altered. the new text goes to
* a newly allocated region. the old text remains as is for the undo.
*/
puttext()
{
int balloc();
char *s;
char FAR *h;
int tsize;
if (text[LLIM-1] != '\0')
cerr(81);
if ( altered ) {
tsize = trim(text); /* string restored before exit */
if (charn > untrims)
cerr(82); /* trailing spaces lost */
addhistory( cline, cline, HISTREPLACE ); /* add for undo */
altered = NO;
tp[cline].moffset = balloc(1+tsize); /* increments newpage if necessary */
tp[cline].page = newpage;