ex_temp.c revision a1d23db49e78dc7df89e59f7da940e5530218b1d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/* Copyright (c) 1981 Regents of the University of California */
#pragma ident "%Z%%M% %I% %E% SMI"
#include "ex.h"
#include "ex_temp.h"
#include "ex_vis.h"
#include "ex_tty.h"
/*
* Editor temporary file routines.
* Very similar to those of ed, except uses 2 input buffers.
*/
#define READ 0
#define WRITE 1
int havetmp;
short tfile = -1;
static short rfile = -1;
extern int junk();
extern int checkjunk();
fileinit()
{
register unsigned char *p;
register pid_t j;
register int i;
return;
cleanup(0);
if (tfile != -1)
dirtcnt = 0;
iblock = -1;
iblock2 = -1;
oblock = -1;
if (setexit() == 0)
else
putNFL();
cleanup(1);
}
goto dumbness;
}
ichanged = 0;
ichang2 = 0;
goto dumbness;
#ifdef VMUNIX
{
extern stilinc; /* see below */
stilinc = 0;
}
#endif
havetmp = 1;
/* brk((unsigned char *)fendcore); */
}
bool all;
{
if (all) {
if (kflag)
if (xtflag)
flush();
#ifdef XPG4
}
#endif /* XPG4 */
resetterm();
normtty--;
}
} else {
#ifdef XPG4
}
#endif /* XPG4 */
resetterm();
normtty--;
}
}
if (havetmp)
havetmp = 0;
rfile = -1;
}
if (all == 1)
}
{
register int nl;
if (--nl == 0) {
}
}
int
putline(void)
{
unsigned char tmpbp;
int nl;
dirtcnt++;
change();
if (tmpbp == '\n') {
*bp = 0;
break;
*--bp;
}
if (--nl == 0) {
}
}
return (tl);
}
int read();
int write();
unsigned char *
int iof;
{
register int n;
/*
* When we overflow tmpfile buffers,
* throw away line which could not be
* put into buffer.
*/
dot--;
dol--;
unddol--;
}
hitin2 = 0;
}
hitin2 = 1;
}
if (hitin2 == 0) {
if (ichang2) {
if (xtflag)
}
ichang2 = 0;
if (xtflag)
hitin2 = 1;
}
hitin2 = 0;
if (ichanged) {
if (xtflag)
}
ichanged = 0;
if (xtflag)
}
if (oblock >= 0) {
if (xtflag) {
/*
* Encrypt block before writing, so some devious
* person can't look at temp file while editing.
*/
n = CRSIZE;
while (n--)
} else
}
}
#ifdef VMUNIX
#define INCORB 64
int stilinc; /* up to here not written yet */
#endif
short b;
unsigned char *buf;
int (*iofcn)();
{
#ifdef VMUNIX
if (b < INCORB) {
return;
}
if (laste) {
if (b >= stilinc)
stilinc = b + 1;
return;
}
} else if (stilinc)
tflush();
#endif
}
#ifdef VMUNIX
tlaste()
{
if (stilinc)
dirtcnt = 0;
}
tflush()
{
int i = stilinc;
stilinc = 0;
}
#endif
/*
* Synchronize the state of the temporary file in case
* a crash occurs.
*/
synctmp()
{
register int cnt;
register line *a;
register short *bp;
register int n;
#ifdef VMUNIX
if (stilinc)
return;
#endif
return;
/*
* In theory, we need to encrypt iblock and iblock2 before writing
* them out, as well as oblock, but in practice ichanged and ichang2
* can never be set, so this isn't really needed. Likewise, the
* code in getblock above for iblock+iblock2 isn't needed.
*/
if (ichanged)
ichanged = 0;
if (ichang2)
ichang2 = 0;
if (oblock != -1)
if (xtflag) {
/*
* Encrypt block before writing, so some devious
* person can't look at temp file while editing.
*/
n = CRSIZE;
while (n--)
} else
if (xtflag)
H.encrypted = 1;
else
H.encrypted = 0;
"file too large to recover with -r option"));
if (*bp < 0) {
}
oops:
*zero = 0;
}
*zero = 0;
}
goto oops;
}
TSYNC()
{
#ifdef VMUNIX
if (stilinc)
tflush();
#endif
dirtcnt = 0;
synctmp();
}
}
/*
* Named buffer routines.
* These are implemented differently than the main buffer.
* Each named buffer has a chain of blocks in the register file.
* Each block contains roughly 508 chars of text,
* and a previous and next block number. We also have information
* about which blocks came from deletes of multiple partial lines,
* e.g. deleting a sentence or a LISP object.
*
* We maintain a free map for the temp file. To free the blocks
* in a register we must read the blocks to find how they are chained
* together.
*
* BUG: The default savind of deleted lines in numbered
* buffers may be rather inefficient; it hasn't been profiled.
*/
struct strreg {
short rg_flags;
short rg_nleft;
short rg_first;
short rg_last;
struct rbuf {
short rb_prev;
short rb_next;
#ifdef VMUNIX
short rused[256];
#else
short rused[32];
#endif
short rnleft;
short rblock;
short rnext;
unsigned char *rbufcp;
short b;
int (*iofcn)();
{
if (rfile == -1) {
}
rblock = b;
}
REGblk()
{
register int i, j, m;
if (i == 0)
m &= ~1;
if (m != 0) {
j = 0;
while ((m & 1) == 0)
j++, m >>= 1;
rused[i] |= (1 << j);
#ifdef RDEBUG
#endif
return (i * 16 + j);
}
}
/*NOTREACHED*/
}
struct strreg *
mapreg(c)
register int c;
{
if (isupper(c))
c = tolower(c);
}
int shread();
KILLreg(c)
register int c;
{
while (rblock != 0) {
#ifdef RDEBUG
#endif
}
}
/*VARARGS*/
shread()
{
struct front { short a; short b; };
sizeof (struct front))
return (sizeof (struct rbuf));
return (0);
}
int getREG();
putreg(c)
unsigned char c;
{
register int cnt;
deletenone();
appendnone();
rnleft = 0;
rblock = 0;
if (rnext == 0) {
if (inopen) {
splitw++;
vclean();
}
vreg = -1;
}
if (!FIXUNDO) {
}
squish();
}
pragged(0);
}
}
partreg(c)
unsigned char c;
{
}
notpart(c)
register int c;
{
if (c)
}
getREG()
{
register int c;
for (;;) {
if (rnleft == 0) {
if (rnext == 0)
return (EOF);
}
c = *rbufcp;
if (c == 0)
return (EOF);
if (c == '\n') {
*lp++ = 0;
return (0);
}
*lp++ = c;
}
}
YANKreg(c)
register int c;
{
if (isdigit(c))
kshift();
if (islower(c))
KILLreg(c);
} else {
rblock = 0;
rnleft = 0;
}
*wcursor = 0;
}
YANKline();
}
rbflush();
killed();
}
kshift()
{
register int i;
KILLreg('9');
for (i = '8'; i >= '0'; i--)
}
YANKline()
{
register int c;
do {
c = *lp++;
if (c == 0)
c = '\n';
if (rnleft == 0) {
rbflush();
}
*rbufcp++ = c;
--rnleft;
} while (c != '\n');
if (rnleft)
*rbufcp = 0;
}
rbflush()
{
if (rblock == 0)
return;
}
/* Register c to char buffer buf of size buflen */
unsigned char c;
unsigned char *buf;
int buflen;
{
register unsigned char *p, *lp;
rnleft = 0;
rblock = 0;
if (rnext == 0) {
*buf = 0;
}
p = buf;
while (getREG() == 0) {
while (*lp) {
*p++ = *lp++;
}
*p++ = '\n';
}
if (partreg(c)) p--;
*p = '\0';
getDOT();
}
#ifdef TRACE
/*
* Test code for displaying named registers.
*/
shownam()
{
int k;
printf("\nRegister Contents\n");
printf("======== ========\n");
for (k = 'a'; k <= 'z'; k++) {
rnleft = 0;
rblock = 0;
printf(" %c:", k);
if (rnext == 0)
printf("\t\tNothing in register.\n");
while (getREG() == 0) {
}
}
return (0);
}
/*
* Test code for displaying numbered registers.
*/
shownbr()
{
int k;
printf("\nRegister Contents\n");
printf("======== ========\n");
for (k = '1'; k <= '9'; k++) {
rnleft = 0;
rblock = 0;
printf(" %c:", k);
if (rnext == 0)
printf("\t\tNothing in register.\n");
while (getREG() == 0) {
}
}
return (0);
}
#endif