AUSAM/source/ded/tmpfile.c

Compare this file to the similar file:
Show the results in this format:

#include "ded.h"
#include "char.h"
#include "file.h"

/* file handler */

int f_tmp;
int f_write;
char f_cache[512];

#define fpLIM &f_cache[511]
int f_cblock;           /* block offset of file cache */

int tmp_block, tmp_offset; /* where the end of the temporary file is */
int l_block[NLINES], l_offset[NLINES]; /* addresses of lines in temp file */

/* data structure to help with definition of ranges of lines */
int b_range[26]
 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1
 };
int e_range[26]
 { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1
 };

/* create the temporary file */
maketemp(tname)
char *tname;
 { if ((f_tmp = creat(tname, 0666)) == -1)
      quit("cannot create temporary file %s", tname);
    close(f_tmp);
    if ((f_tmp = open(tname, 2)) == -1)
      quit("cannot re-open temporary file %s", tname);

    maxl = -1;
    tmp_block = tmp_offset = 0;
 }

getline(fline,linebuf)
int fline;
char *linebuf;
 { if (topl<=fline && fline<=topl+LASTINROW)
      copyrow(fline-topl,0,linebuf);
    else
      getfline(fline,linebuf);
 }

/* gets a line from disk, in disk format,
 * into store, in display format
 */
getfline(fline,linebuf)
int fline;
char *linebuf;
 { register char *lp, *fp;
    int block, offset;

    block = l_block[fline];
    offset = l_offset[fline];

    if (offset == -1 || fline>maxl)
      linebuf[0] = 0;
    else
     { getblock(block);
	lp = linebuf;
	fp = f_cache+offset;

	while ((*lp++ = *fp++) != 0)
	    if (fp > fpLIM)
	     {  getblock(++block);
		 fp = f_cache;
	     }

	*lp = 0;
     }
    return;

}

/* writes the line in buf
 * onto the end of the file
 */

addline(fline,linebuf)
int fline;
char *linebuf;
{
    register char *fp, *lp;
    int block, offset;
    register char c;
    char cb;
    int count;

    if (linebuf==0 || *linebuf==0)
      l_block[fline] = l_offset[fline] = -1;
    else
     { block = tmp_block;
	offset = tmp_offset;
	getblock(block); f_write++;
	fp = f_cache + offset;
	lp = linebuf;

	do
	 { *fp++ = c = *lp++;

	    if (fp > fpLIM)
	     { getblock(++block);
		f_write++;
		fp = f_cache;
	     }
	 } while (c != 0);

	l_block[fline] = tmp_block; tmp_block = block;
	l_offset[fline] = tmp_offset; tmp_offset = (fp-f_cache);
     }
}

emptyline(fline)
int fline;
 { return(topl<=fline && fline<=topl+LASTINROW ? emptyrow(fline-topl)
						: l_offset[fline] == -1);
 }


/* gets the block into the cache
 *
 */
getblock(block)
{

	if (f_cblock != block) {
		if (f_write) {
			seek(f_tmp, f_cblock, 3);
			write(f_tmp, f_cache, 512);
		}
		seek(f_tmp, f_cblock=block, 3);
		read(f_tmp, f_cache, 512);
		f_write = 0;
	}
}

/* procedure to move lines up or down to make or delete space */
shuffile(fline,incr)
int fline, incr;
 { xshuffile(fline, incr); adj_maxl(); }

xshuffile(fline, incr)
int fline, incr;
 { register int i;

    if (incr > 0) /* moving up */
     { if (maxl+incr > NLINES)
	  editerror("too many lines in file");

	for (i=maxl; i>=fline; i--)
	 { l_block[i+incr] = l_block[i];
	    l_offset[i+incr] = l_offset[i];
	 }

	for (i='a'; i<='z'; i++)
	 { if (b_range[i-'a']>=fline) b_range[i-'a'] =+ incr;
	    if (e_range[i-'a']>=fline) e_range[i-'a'] =+ incr;
	 }

	maxl =+ incr;
     }
    else
    if (incr < 0) /* moving down */
     { if (fline-incr < 0)
	  editerror("attempt to shuffle lines off top of file");

	for (i=fline; i<=maxl; i++)
	 { l_block[i+incr] = l_block[i];
	    l_offset[i+incr] = l_offset[i];
	 }

	for (i='a'; i<='z'; i++)
	 { if (b_range[i-'a']>=fline) b_range[i-'a'] =+ incr;
	    else
	    if (b_range[i-'a']>=fline+incr) b_range[i-'a'] = fline+incr;

	    if (e_range[i-'a']>=fline) e_range[i-'a'] =+ incr;
	    else
	    if (e_range[i-'a']>=fline+incr) e_range[i-'a'] = fline+incr;
	 }

	if (maxl+incr>=topl+LASTINROW) maxl =+ incr;
	else
	 { for (i=maxl+incr+1; i<=topl+LASTINROW; i++)
	     l_block[i] = l_offset[i] = -1;
	    maxl = topl+LASTINROW;
	 }
     }

    tmp_changed = true;
 }

/* strip trailing blank lines from the file -
 * but not if there are any refs to the last line
 */
adj_maxl()
{ register int i;
   while (maxl>topl+LASTINROW && l_offset[maxl]<0)
    { for (i='a'; i<='z'; i++)
	 if (b_range[i-'a']==maxl || e_range[i-'a']==maxl) return;
       maxl--;
    }
 }

/* procedures to shift lines about */
copyline(source, destination)
int source, destination;
 { register int block, offset;

    while(source>maxl) inc_maxl();
    block = l_block[source]; offset = l_offset[source];
    /* don't let shuffile alter any lines */
    xshuffile(destination, 1);
    l_block[destination] = block; l_offset[destination] = offset;
 }

moveline(source, destination)
int source, destination;
 { register int i;

    copyline(source, destination);
    if (source >= destination) source++;

    for (i='a'; i<='z'; i++)
     { if (b_range[i-'a']==source) b_range[i-'a'] = destination;
	if (e_range[i-'a']==source) e_range[i-'a'] = destination;
     }

    /* don't let shuffile alter any lines */
    xshuffile(source+1, -1);
 }