FOLD= ${BINDIR}/fold
CTAGS= ${BINDIR}/ctags
XSTR= ${BINDIR}/xstr
-DEBUGFLAGS= -DTRACE -g
+DEBUGFLAGS= -DMDEBUG -DTRACE -g
NONDEBUGFLAGS= -O
DEB= ${NONDEBUGFLAGS} # or ${DEBUGFLAGS} to to debug
-CFLAGS= -DTABS=8 -DCRYPT -DLISPCODE -DCHDIR -DUCVISUAL -DVFORK -DVMUNIX ${DEB}
+CFLAGS= -DTABS=8 -DCRYPT -DLISPCODE -DCHDIR -DUCVISUAL -DVFORK -DVMUNIX -DTIMEBOMB ${DEB}
LDFLAGS= -z # or -i or -n
-TERMLIB= -ltermlib
+TERMLIB= -ltermcap
MKSTR= ${BINDIR}/mkstr
CXREF= ${BINDIR}/cxref
INCLUDE=/usr/include
OBJS= ex.o ex_addr.o ex_cmds.o ex_cmds2.o ex_cmdsub.o \
ex_data.o ex_get.o ex_io.o ex_put.o ex_re.o \
ex_set.o ex_subr.o ex_temp.o ex_tty.o ex_unix.o \
- ex_v.o ex_vadj.o ex_vget.o ex_vmain.o ex_voperate.o \
+ ex_v.o ex_vadj.o ex_vget.o ex_vmain.o ex_voper.o \
ex_vops.o ex_vops2.o ex_vops3.o ex_vput.o ex_vwind.o \
printf.o bcopy.o strings.o
HDRS= ex.h ex_argv.h ex_re.h ex_temp.h ex_tty.h ex_tune.h ex_vars.h ex_vis.h
SRC1= ex.c ex_addr.c ex_cmds.c ex_cmds2.c ex_cmdsub.c
SRC2= ex_data.c ex_get.c ex_io.c ex_put.c ex_re.c
SRC3= ex_set.c ex_subr.c ex_temp.c ex_tty.c ex_unix.c
-SRC4= ex_v.c ex_vadj.c ex_vget.c ex_vmain.c ex_voperate.c
+SRC4= ex_v.c ex_vadj.c ex_vget.c ex_vmain.c ex_voper.c
SRC5= ex_vops.c ex_vops2.c ex_vops3.c ex_vput.c ex_vwind.c
SRC6= printf.c bcopy.c expreserve.c exrecover.c
MISC= makefile READ_ME :rofix
VHDR= "Ex Version ${VERSION}"
.c.o:
-# ${MKSTR} - ex${VERSION}strings x $*.c
+# ifdef VMUNIX
${CC} -E ${CFLAGS} $*.c | ${XSTR} -c -
+# else
+# ${MKSTR} - ex${VERSION}strings x $*.c
+# ${CC} -E ${CFLAGS} x$*.c | ${XSTR} -c -
# rm -f x$*.c
+# endif
${CC} ${CFLAGS} -c x.c
mv x.o $*.o
# install in standard place (/usr/ucb)
install: a.out exrecover expreserve
+ strip a.out
-rm -f ${DESTDIR}${BINDIR}/ex
-rm -f ${DESTDIR}${BINDIR}/vi
-rm -f ${DESTDIR}${BINDIR}/view
cp expreserve ${DESTDIR}${LIBDIR}/ex${VERSION}preserve
chmod 4755 ${DESTDIR}${LIBDIR}/ex${VERSION}recover ${DESTDIR}${LIBDIR}/ex${VERSION}preserve
# The following line normally fails. This is OK.
- mkdir ${DESTDIR}/usr/preserve
+ -mkdir ${DESTDIR}/usr/preserve
# move from /usr/new to /usr/ucb
newucb: a.out
${VGRIND} -h ${VHDR} ${SRC6}
${VGRIND} -n -h ${VHDR} ${MISC}
${VGRIND} -i -h ${VHDR} index
-
-ex.c: SCCS/s.ex.c ${HDRS}; rm -f ex.c; sccs get ex.c
-ex.h: SCCS/s.ex.h; rm -f ex.h; sccs get ex.h
-ex_addr.c: SCCS/s.ex_addr.c; rm -f ex_addr.c; sccs get ex_addr.c
-ex_argv.h: SCCS/s.ex_argv.h; rm -f ex_argv.h; sccs get ex_argv.h
-ex_cmds.c: SCCS/s.ex_cmds.c; rm -f ex_cmds.c; sccs get ex_cmds.c
-ex_cmds2.c: SCCS/s.ex_cmds2.c; rm -f ex_cmds2.c; sccs get ex_cmds2.c
-ex_cmdsub.c: SCCS/s.ex_cmdsub.c; rm -f ex_cmdsub.c; sccs get ex_cmdsub.c
-ex_data.c: SCCS/s.ex_data.c; rm -f ex_data.c; sccs get ex_data.c
-ex_get.c: SCCS/s.ex_get.c; rm -f ex_get.c; sccs get ex_get.c
-ex_io.c: SCCS/s.ex_io.c; rm -f ex_io.c; sccs get ex_io.c
-ex_put.c: SCCS/s.ex_put.c; rm -f ex_put.c; sccs get ex_put.c
-ex_re.c: SCCS/s.ex_re.c; rm -f ex_re.c; sccs get ex_re.c
-ex_re.h: SCCS/s.ex_re.h; rm -f ex_re.h; sccs get ex_re.h
-ex_set.c: SCCS/s.ex_set.c; rm -f ex_set.c; sccs get ex_set.c
-ex_subr.c: SCCS/s.ex_subr.c; rm -f ex_subr.c; sccs get ex_subr.c
-ex_temp.c: SCCS/s.ex_temp.c; rm -f ex_temp.c; sccs get ex_temp.c
-ex_temp.h: SCCS/s.ex_temp.h; rm -f ex_temp.h; sccs get ex_temp.h
-ex_tty.c: SCCS/s.ex_tty.c; rm -f ex_tty.c; sccs get ex_tty.c
-ex_tty.h: SCCS/s.ex_tty.h; rm -f ex_tty.h; sccs get ex_tty.h
-ex_tune.h: SCCS/s.ex_tune.h; rm -f ex_tune.h; sccs get ex_tune.h
-ex_unix.c: SCCS/s.ex_unix.c; rm -f ex_unix.c; sccs get ex_unix.c
-ex_v.c: SCCS/s.ex_v.c; rm -f ex_v.c; sccs get ex_v.c
-ex_vadj.c: SCCS/s.ex_vadj.c; rm -f ex_vadj.c; sccs get ex_vadj.c
-ex_vars.h: SCCS/s.ex_vars.h; rm -f ex_vars.h; sccs get ex_vars.h
-ex_vget.c: SCCS/s.ex_vget.c; rm -f ex_vget.c; sccs get ex_vget.c
-ex_vis.h: SCCS/s.ex_vis.h; rm -f ex_vis.h; sccs get ex_vis.h
-ex_vmain.c: SCCS/s.ex_vmain.c; rm -f ex_vmain.c; sccs get ex_vmain.c
-ex_voperate.c: SCCS/s.ex_voperate.c; rm -f ex_voperate.c; sccs get ex_voperate.c
-ex_vops.c: SCCS/s.ex_vops.c; rm -f ex_vops.c; sccs get ex_vops.c
-ex_vops2.c: SCCS/s.ex_vops2.c; rm -f ex_vops2.c; sccs get ex_vops2.c
-ex_vops3.c: SCCS/s.ex_vops3.c; rm -f ex_vops3.c; sccs get ex_vops3.c
-ex_vput.c: SCCS/s.ex_vput.c; rm -f ex_vput.c; sccs get ex_vput.c
-ex_vwind.c: SCCS/s.ex_vwind.c; rm -f ex_vwind.c; sccs get ex_vwind.c
-expreserve.c: SCCS/s.expreserve.c; rm -f expreserve.c; sccs get expreserve.c
-exrecover.c: SCCS/s.exrecover.c; rm -f exrecover.c; sccs get exrecover.c
-makeoptions: SCCS/s.makeoptions; rm -f makeoptions; sccs get makeoptions
-bcopy.c: SCCS/s.bcopy.c; rm -f bcopy.c; sccs get bcopy.c
-printf.c: SCCS/s.printf.c; rm -f printf.c; sccs get printf.c
/* block copy from from to to, count bytes */
-static char *sccsid = "@(#)bcopy.c 5.1 %G%";
+static char *sccsid = "@(#)bcopy.c 6.1 %G%";
bcopy(from, to, count)
#ifdef vax
char *from, *to;
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex.c 5.3 %G%";
+static char *sccsid = "@(#)ex.c 6.1 %G%";
#include "ex.h"
#include "ex_argv.h"
#include "ex_temp.h"
ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL;
if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
signal(SIGTERM, onhup);
-#ifdef SIGTSTP
- if (signal(SIGTSTP, SIG_IGN) == SIG_DFL)
- signal(SIGTSTP, onsusp), dosusp++;
-#endif
/*
* Initialize end of core pointers.
}
ac--, av++;
}
+
+#ifdef SIGTSTP
+ if (!hush && signal(SIGTSTP, SIG_IGN) == SIG_DFL)
+ signal(SIGTSTP, onsusp), dosusp++;
+#endif
+
if (ac && av[0][0] == '+') {
firstpat = &av[0][1];
ac--, av++;
* Initialize a temporary file (buffer) and
* set up terminal environment. Read user startup commands.
*/
- init();
if (setexit() == 0) {
setrupt();
intty = isatty(0);
if ((cp = getenv("HOME")) != 0 && *cp)
source(strcat(strcpy(genbuf, cp), "/.exrc"), 1);
}
+ init(); /* moved after prev 2 chunks to fix directory option */
/*
* Initial processing. Handle tag, recover, and file argument
* If you quit out of a 'vi' command by doing Q or ^\,
* you also fall through to here.
*/
+ seenprompt = 1;
ungetchar(0);
globp = 0;
initev = 0;
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex.h 5.1 %G% */
+/* sccs id: @(#)ex.h 6.1 %G% */
#ifdef V6
#include <retrofit.h>
#endif
jmp_buf resetlab; /* For error throws to top level (cmd mode) */
int rpid; /* Pid returned from wait() */
bool ruptible; /* Interruptible is normal state */
+bool seenprompt; /* 1 if have gotten user input */
bool shudclob; /* Have a prompt to clobber (e.g. on ^D) */
int status; /* Status returned from wait() */
int tchng; /* If nonzero, then [Modified] */
short tfile; /* Temporary file unit */
bool vcatch; /* Want to catch an error (open/visual) */
jmp_buf vreslab; /* For error throws to a visual catch */
+bool writing; /* 1 if in middle of a file write */
int xchng; /* Suppresses multiple "No writes" in !cmd */
/*
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex3.7preserve.c 5.1 %G%";
+static char *sccsid = "@(#)ex3.7preserve.c 6.1 %G%";
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
if (read(0, (char *) &H, sizeof H) != sizeof H) {
format:
if (name == 0)
- fprintf(stderr, "Buffer format error\n");
+ fprintf(stderr, "Buffer format error\t");
return (-1);
}
if (dcp[-1] == 'z') {
dcp[-1] = 'a';
if (dcp[-2] == 'z')
- fprintf(stderr, "Can't find a name\n");
+ fprintf(stderr, "Can't find a name\t");
dcp[-2]++;
} else
dcp[-1]++;
if (fname[0] == 0) {
fprintf(mf,
"A copy of an editor buffer of yours was saved when %s.\n",
- flag ? "the system went down" : "your phone was hung up");
+ flag ? "the system went down" : "the editor was killed");
fprintf(mf,
"No name was associated with this buffer so it has been named \"LOST\".\n");
} else
fprintf(mf,
"A copy of an editor buffer of your file \"%s\"\nwas saved when %s.\n", fname,
- flag ? "the system went down" : "your phone was hung up");
+ /*
+ * "the editor was killed" is perhaps still not an ideal
+ * error message. Usually, either it was forcably terminated
+ * or the phone was hung up, but we don't know which.
+ */
+ flag ? "the system went down" : "the editor was killed");
fprintf(mf,
"This buffer can be retrieved using the \"recover\" command of the editor.\n");
fprintf(mf,
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex3.7recover.c 5.1 %G%";
+static char *sccsid = "@(#)ex3.7recover.c 6.1 %G%";
#include "ex.h"
#include "ex_temp.h"
#include "ex_tty.h"
/* Copyright (c) 1979 Regents of the University of California */
-static char *sccsid = "@(#)ex_addr.c 5.1 %G%";
+static char *sccsid = "@(#)ex_addr.c 6.1 %G%";
#include "ex.h"
#include "ex_re.h"
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex_argv.h 5.1 %G% */
+/* sccs id: @(#)ex_argv.h 6.1 %G% */
/*
* The current implementation of the argument list is poor,
* using an argv even for internally done "next" commands.
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_cmds.c 5.3 %G%";
+static char *sccsid = "@(#)ex_cmds.c 6.1 %G%";
#include "ex.h"
#include "ex_argv.h"
#include "ex_temp.h"
vnfl();
else {
tostop();
- /* replaced by tostop
- putpad(VE);
- putpad(KE);
- */
}
flush();
setty(normf);
/* source */
case 'o':
+#ifdef notdef
if (inopen)
goto notinvis;
+#endif
tail("source");
setnoaddr();
getone();
source(file, 0);
continue;
#ifdef SIGTSTP
-/* stop */
+/* stop, suspend */
case 't':
tail("stop");
+ goto suspend;
+ case 'u':
+ tail("suspend");
+suspend:
if (!ldisc)
error("Old tty driver|Not using new tty driver/shell");
c = exclam();
eol();
if (!c)
ckaw();
- eol();
onsusp();
continue;
#endif
/* version */
tail("version");
setNAEOL();
- printf("@(#) Version 3.5, %G%."+5);
+ printf("@(#) Version 3.6, %G%. (EXPERIMENTAL version 3.6, Oct 1980)"+5);
noonl();
continue;
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_cmds2.c 5.1 %G%";
+static char *sccsid = "@(#)ex_cmds2.c 6.1 %G%";
#include "ex.h"
#include "ex_argv.h"
#include "ex_temp.h"
error0();
merror(str, i);
+ if (writing) {
+ serror(" [Warning - %s is incomplete]", file);
+ writing = 0;
+ }
error1(str);
}
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_cmdsub.c 5.1 %G%";
+static char *sccsid = "@(#)ex_cmdsub.c 6.1 %G%";
#include "ex.h"
#include "ex_argv.h"
#include "ex_temp.h"
if(FIXUNDO) {
register int (*dsavint)();
+#ifdef TRACE
+ if (trace)
+ vudump("before delete");
+#endif
change();
dsavint = signal(SIGINT, SIG_IGN);
undkind = UNDCHANGE;
dot = a1;
pkill[0] = pkill[1] = 0;
signal(SIGINT, dsavint);
+#ifdef TRACE
+ if (trace)
+ vudump("after delete");
+#endif
} else {
register line *a3;
register int i;
mid = (top + bot) / 2;
fseek(iof, mid, 0);
if (mid > 0) /* to get first tag in file to work */
- fgets(linebuf, sizeof linebuf, iof); /* scan to next \n */
- fgets(linebuf, sizeof linebuf, iof); /* get a line */
+ /* scan to next \n */
+ if(fgets(linebuf, sizeof linebuf, iof)==NULL)
+ goto goleft;
+ /* get the line itself */
+ if(fgets(linebuf, sizeof linebuf, iof)==NULL)
+ goto goleft;
linebuf[strlen(linebuf)-1] = 0; /* was '\n' */
#endif
while (*cp && *lp == *cp)
if (*lp > *cp)
bot = mid + 1;
else
+goleft:
top = mid - 1;
#endif
/* Not this tag. Try the next */
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_data.c 5.1 %G%";
+static char *sccsid = "@(#)ex_data.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_get.c 5.1 %G%";
+static char *sccsid = "@(#)ex_get.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_io.c 5.6 %G%";
+static char *sccsid = "@(#)ex_io.c 6.1 %G%";
#include "ex.h"
#include "ex_argv.h"
#include "ex_temp.h"
io = open(file, 0);
if (io < 0) {
- if (c == 'e' && errno == ENOENT)
+ if (c == 'e' && errno == ENOENT) {
edited++;
+ /*
+ * If the user just did "ex foo" he is probably
+ * creating a new file. Don't be an error, since
+ * this is ugly, and it screws up the + option.
+ */
+ if (!seenprompt) {
+ printf(" [New file]");
+ noonl();
+ return;
+ }
+ }
syserror();
}
if (fstat(io, &stbuf))
break;
}
}
- if (value(READONLY) && denied) {
- value(READONLY) = ovro;
- denied = 0;
- }
- if (c != 'r' && ((stbuf.st_mode & 0222) == 0 || access(file, 2) < 0)) {
- ovro = value(READONLY);
- denied = 1;
- value(READONLY) = 1;
+ if (c != 'r') {
+ if (value(READONLY) && denied) {
+ value(READONLY) = ovro;
+ denied = 0;
+ }
+ if ((stbuf.st_mode & 0222) == 0 || access(file, 2) < 0) {
+ ovro = value(READONLY);
+ denied = 1;
+ value(READONLY) = 1;
+ }
}
if (value(READONLY)) {
printf(" [Read only]");
#endif
if (io < 0)
syserror();
+ writing = 1;
if (hush == 0)
if (nonexist)
printf(" [New file]");
addr1 = saddr1;
addr2 = saddr2;
}
+ writing = 0;
}
/*
{
jmp_buf osetexit;
register int saveinp, ointty, oerrno;
+ char savepeekc, *saveglobp;
signal(SIGINT, SIG_IGN);
saveinp = dup(0);
+ savepeekc = peekc;
+ saveglobp = globp;
+ peekc = 0; globp = 0;
if (saveinp < 0)
error("Too many nested sources");
if (slevel <= 0)
close(0);
dup(saveinp);
close(saveinp);
+ globp = saveglobp;
+ peekc = savepeekc;
slevel--;
resexit(osetexit);
}
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_re.c 5.1 %G%";
+static char *sccsid = "@(#)ex_re.c 6.1 %G%";
#include "ex.h"
#include "ex_re.h"
if (a1 >= addr1 && a1 <= addr2 && execute(0, a1) == k)
*a1 |= 01;
}
- /* should use gdelete from ed to avoid n**2 here on g/.../d */
+ /*
+ * Special case: g/.../d (avoid n^2 algorithm)
+ */
+ if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') {
+ gdelete();
+ return;
+ }
if (inopen)
inopen = -1;
+ /*
+ * Now for each marked line, set dot there and do the commands.
+ * Note the n^2 behavior here for lots of lines matching.
+ * This is really needed: in some cases you could delete lines,
+ * causing a marked line to be moved before a1 and missed if
+ * we didn't restart at zero each time.
+ */
for (a1 = one; a1 <= dol; a1++) {
if (*a1 & 01) {
*a1 &= ~01;
}
}
+/*
+ * gdelete: delete inside a global command. Handles the
+ * special case g/r.e./d. All lines to be deleted have
+ * already been marked. Squeeze the remaining lines together.
+ * Note that other cases such as g/r.e./p, g/r.e./s/r.e.2/rhs/,
+ * and g/r.e./.,/r.e.2/d are not treated specially. There is no
+ * good reason for this except the question: where to you draw the line?
+ */
+gdelete()
+{
+ register line *a1, *a2, *a3;
+
+ a3 = dol;
+ /* find first marked line. can skip all before it */
+ for (a1=zero; (*a1&01)==0; a1++)
+ if (a1>=a3)
+ return;
+ /* copy down unmarked lines, compacting as we go. */
+ for (a2=a1+1; a2<=a3;) {
+ if (*a2&01) {
+ a2++; /* line is marked, skip it */
+ dot = a1; /* dot left after line deletion */
+ } else
+ *a1++ = *a2++; /* unmarked, copy it */
+ }
+ dol = a1-1;
+ if (dot>dol)
+ dot = dol;
+ change();
+}
+
bool cflag;
int scount, slines, stotal;
{
register line *addr;
register int n;
- int gsubf;
+ int gsubf, hopcount = 0;
gsubf = compsub(c);
if(FIXUNDO)
if (dosubcon(0, addr) == 0)
continue;
if (gsubf) {
-#ifdef notdef
/*
- * should check but loc2 is already munged.
- * This needs a fancier check later.
+ * The loop can happen from s/\</&/g
+ * but we don't want to break other, reasonable cases.
*/
- if (loc1 == loc2)
- error("substitution loop");
-#endif
- while (*loc2)
+ while (*loc2) {
+ if (++hopcount > sizeof linebuf)
+ error("substitution loop");
if (dosubcon(1, addr) == 0)
break;
+ }
}
if (scount) {
stotal += scount;
{
register char *rp, *orp;
register int c;
- char orhsbuf[LBSIZE / 2];
+ char orhsbuf[RHSSIZE];
rp = rhsbuf;
CP(orhsbuf, rp);
magic:
if (c == '~') {
for (orp = orhsbuf; *orp; *rp++ = *orp++)
- if (rp >= &rhsbuf[LBSIZE / 2 + 1])
+ if (rp >= &rhsbuf[RHSSIZE - 1])
goto toobig;
continue;
}
goto magic;
break;
}
- if (rp >= &rhsbuf[LBSIZE / 2 - 1])
+ if (rp >= &rhsbuf[RHSSIZE - 1]) {
toobig:
+ *rp = 0;
error("Replacement pattern too long@- limit 256 characters");
+ }
*rp++ = c;
}
endrhs:
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex_re.h 5.1 %G% */
+/* sccs id: @(#)ex_re.h 6.1 %G% */
/*
* Regular expression definitions.
* The regular expressions in ex are similar to those in ed,
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_set.c 5.1 %G%";
+static char *sccsid = "@(#)ex_set.c 6.1 %G%";
#include "ex.h"
#include "ex_temp.h"
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_subr.c 5.1 %G%";
+static char *sccsid = "@(#)ex_subr.c 6.1 %G%";
#include "ex.h"
#include "ex_re.h"
#include "ex_tty.h"
more = (a2 - a1 + 1) - (unddol - dol);
while (more > (endcore - truedol))
if (morelines() < 0)
- error("Out of memory@saving lines for undo - try using ed or re");
+ error("Out of memory@saving lines for undo - try using ed");
if (more)
(*(more > 0 ? copywR : copyw))(unddol + more + 1, unddol + 1,
(truedol - unddol));
dirtcnt = 0;
putchar(' ');
+ edited = 0; /* for temp file errors, for example */
if (e >= 0 && errno <= std_nerrs)
error(std_errlist[e]);
else
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_temp.c 5.1 %G%";
+static char *sccsid = "@(#)ex_temp.c 6.1 %G%";
#include "ex.h"
#include "ex_temp.h"
#include "ex_vis.h"
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex_temp.h 5.1 %G% */
+/* sccs id: @(#)ex_temp.h 6.1 %G% */
/*
* The editor uses a temporary file for files being edited, in a structure
* similar to that of ed. The first block of the file is used for a header
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_tty.c 5.1 %G%";
+static char *sccsid = "@(#)ex_tty.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
if (tgoto(CM, 2, 2)[0] == 'O') /* OOPS */
CA = 0, CM = 0;
else
- CA = 1, costCM = strlen(tgoto(CM, 8, 10));
+ CA = 1, costCM = cost(tgoto(CM, 8, 10));
+ costSR = cost(SR);
+ costAL = cost(AL);
PC = xPC ? xPC[0] : 0;
aoftspace = tspace;
CP(ttytype, longname(ltcbuf, type));
gettmode();
value(REDRAW) = AL && DL;
value(OPTIMIZE) = !CA && !GT;
+ if (ospeed == B1200 && !value(REDRAW))
+ value(SLOWOPEN) = 1; /* see also gettmode above */
if (unknown)
serror("%s: Unknown terminal type", type);
}
else
return(NOSTR);
}
+
+/*
+ * cost figures out how much (in characters) it costs to send the string
+ * str to the terminal. It takes into account padding information, as
+ * much as it can, for a typical case. (Right now the typical case assumes
+ * the number of lines affected is the size of the screen, since this is
+ * mainly used to decide if AL or SR is better, and this always happens
+ * at the top of the screen. We assume cursor motion (CM) has little
+ * padding, if any, required, so that case, which is really more important
+ * than AL vs SR, won't be really affected.)
+ */
+static int costnum;
+cost(str)
+char *str;
+{
+ int countnum();
+
+ if (str == NULL)
+ return 10000; /* infinity */
+ costnum = 0;
+ tputs(str, LINES, countnum);
+ return costnum;
+}
+
+/* ARGSUSED */
+countnum(ch)
+char ch;
+{
+ costnum++;
+}
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex_tty.h 5.1 %G% */
+/* sccs id: @(#)ex_tty.h 6.1 %G% */
/*
* Capabilities from termcap
*
short WBOT;
short WECHO;
-short costCM;
+short costCM; /* # chars to output a typical CM, with padding etc. */
+short costSR; /* likewise */
+short costAL;
#ifdef VMUNIX
# define MAXNOMACS 128 /* max number of macros of each kind */
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex_tune.h 5.1 %G% */
+/* sccs id: @(#)ex_tune.h 6.1 %G% */
/*
* Definitions of editor parameters and limits
*/
* "/usr/lib/..." here, "/lib" will be tried only for strings.
*/
#include "local/uparm.h"
-#define EXRECOVER libpath(ex3.5recover)
-#define EXPRESERVE libpath(ex3.5preserve)
+#define EXRECOVER libpath(ex3.6recover)
+#define EXPRESERVE libpath(ex3.6preserve)
#ifndef VMUNIX
-#define EXSTRINGS libpath(ex3.5strings)
+#define EXSTRINGS libpath(ex3.6strings)
#endif
/*
/* Copyright (c) 1979 Regents of the University of California */
-static char *sccsid = "@(#)ex_unix.c 5.2 %G%";
+static char *sccsid = "@(#)ex_unix.c 6.1 %G%";
#include "ex.h"
#include "ex_temp.h"
#include "ex_tty.h"
if(FIXUNDO)
undap1 = undap2 = addr2+1;
ignore(append(getfile, addr2));
+#ifdef TRACE
+ if (trace)
+ vudump("after append in filter");
+#endif
}
close(io);
io = -1;
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_v.c 5.1 %G%";
+static char *sccsid = "@(#)ex_v.c 6.1 %G%";
#include "ex.h"
#include "ex_re.h"
#include "ex_tty.h"
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vadj.c 5.1 %G%";
+static char *sccsid = "@(#)ex_vadj.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
vgoto(p, 0), vputp(CD, cnt);
vclrech(1);
vadjAL(p, cnt);
- } else if (AL) {
- /*
- * Use insert line.
- */
- vgoto(p, 0), vputp(AL, WECHO + 1 - p);
- for (i = cnt - 1; i > 0; i--) {
- vgoto(outline+1, 0), vputp(AL, WECHO + 1 - outline);
- if ((hold & HOLDAT) == 0)
- putchar('@');
- }
- vadjAL(p, cnt);
- } else if (SR && p == WTOP) {
+ } else if (SR && p == WTOP && costSR < costAL) {
/*
* Use reverse scroll mode of the terminal, at
- * the top of the window.
+ * the top of the window. Reverse linefeed works
+ * too, since we only use it from line WTOP.
*/
for (i = cnt; i > 0; i--) {
vgoto(p, 0), vputp(SR, 0);
vputp(CE, 1);
}
vadjAL(p, cnt);
+ } else if (AL) {
+ /*
+ * Use insert line.
+ */
+ vgoto(p, 0), vputp(AL, WECHO + 1 - p);
+ for (i = cnt - 1; i > 0; i--) {
+ vgoto(outline+1, 0), vputp(AL, WECHO + 1 - outline);
+ if ((hold & HOLDAT) == 0)
+ putchar('@');
+ }
+ vadjAL(p, cnt);
} else
could = 0;
vopenup(cnt, could, l);
-/* sccs id @(#)ex_vars.h 5.1 %G% */
+/* sccs id @(#)ex_vars.h 6.1 %G% */
#define AUTOINDENT 0
#define AUTOPRINT 1
#define AUTOWRITE 2
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vget.c 5.1 %G%";
+static char *sccsid = "@(#)ex_vget.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
vglobp = INS;
}
OP = Pline; Pline = normline;
- ignore(vgetline(0, genbuf + 1, &waste));
+ ignore(vgetline(0, genbuf + 1, &waste, c));
if (Outchar == termchar)
putchar('\n');
vscrap();
/* Copyright (c) 1980 Regents of the University of California */
-/* sccs id: @(#)ex_vis.h 5.1 %G% */
+/* sccs id: @(#)ex_vis.h 6.1 %G% */
/*
* Ex version 3
* Mark Horton, UCB
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vmain.c 5.3 %G%";
+static char *sccsid = "@(#)ex_vmain.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
vglobp = 0;
vreg = 0;
hold = 0;
+ seenprompt = 1;
wcursor = 0;
Xhadcnt = hadcnt = 0;
Xcnt = cnt = 1;
ungetkey(c);
goto looptop;
}
- if (!value(REMAP))
+ if (!value(REMAP)) {
+ c = op;
break;
+ }
if (++maphopcnt > 256)
error("Infinite macro loop");
} while (c != op);
case CTRL(f):
vsave();
if (vcnt > 2) {
- dot += (vcnt - vcline) - 2 + (cnt-1)*basWLINES;
+ addr = dot + (vcnt - vcline) - 2 + (cnt-1)*basWLINES;
+ forbid(addr > dol);
+ dot = addr;
vcnt = vcline = 0;
}
vzop(0, 0, '+');
case CTRL(b):
vsave();
if (one + vcline != dot && vcnt > 2) {
- dot -= vcline - 2 + (cnt-1)*basWLINES;
+ addr = dot - vcline - 2 + (cnt-1)*basWLINES;
+ forbid (addr <= zero);
+ dot = addr;
vcnt = vcline = 0;
}
vzop(0, 0, '^');
*/
case 'O':
case 'o':
- voOpen(c, cnt);
vmacchng(1);
+ voOpen(c, cnt);
continue;
/*
#ifdef SIGTSTP
/*
* ^Z: suspend editor session and temporarily return
- * to shell. Only works on Berkeley tty driver.
+ * to shell. Only works with Berkeley/IIASA process
+ * control in kernel.
*/
case CTRL(z):
forbid(dosusp == 0 || !ldisc);
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_voper.c 5.1 %G%";
+static char *sccsid = "@(#)ex_voper.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
* character.
*/
case 'r':
- vrep(cnt);
vmacchng(1);
+ vrep(cnt);
return;
default:
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vops.c 5.1 %G%";
+static char *sccsid = "@(#)ex_vops.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
{
line *savedot, *savedol;
char *savecursor;
+ char savelb[LBSIZE];
int nlines, more;
register line *a1, *a2;
char ch; /* DEBUG */
vudump("before vmacchng hairy case");
#endif
savedot = dot; savedol = dol; savecursor = cursor;
+ CP(savelb, linebuf);
nlines = dol - zero;
while ((line *) endcore - truedol < nlines)
morelines();
more = savedol - dol; /* amount we shift everything by */
if (more)
(*(more>0 ? copywR : copyw))(savedol+1, dol+1, truedol-dol);
- unddol += more; truedol += more;
+ unddol += more; truedol += more; undap2 += more;
truedol -= nlines;
copyw(zero+1, truedol+1, nlines);
dot = savedot; dol = savedol ; cursor = savecursor;
+ CP(linebuf, savelb);
vch_mac = VC_MANYCHANGE;
/* Arrange that no further undo saving happens within macro */
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vops2.c 5.1 %G%";
+static char *sccsid = "@(#)ex_vops2.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
register int i;
register char *gcursor;
bool escape;
- int repcnt;
+ int repcnt, savedoomed;
short oldhold = hold;
/*
if (ch == 'r' && repcnt == 0)
escape = 0;
else {
- gcursor = vgetline(repcnt, gcursor, &escape);
+ gcursor = vgetline(repcnt, gcursor, &escape, ch);
/*
* After an append, stick information
*/
if (state != HARDOPEN) {
DEPTH(vcline) = 0;
+ savedoomed = doomed;
if (doomed > 0) {
register int cind = cindent();
doomed = 0;
}
i = vreopen(LINE(vcline), lineDOT(), vcline);
+ doomed = savedoomed;
}
/*
* are careful about the way we do this so that it is
* repeatable. (I.e. so that your kill doesn't happen,
* when you repeat an insert if it was escaped with \ the
- * first time you did it.
+ * first time you did it. commch is the command character
+ * involved, including the prompt for readline.
*/
char *
-vgetline(cnt, gcursor, aescaped)
+vgetline(cnt, gcursor, aescaped, commch)
int cnt;
register char *gcursor;
bool *aescaped;
+ char commch;
{
register int c, ch;
register char *cp;
- int x, y, iwhite;
+ int x, y, iwhite, backsl=0;
char *iglobp;
char cstr[2];
int (*OO)() = Outchar;
vprepins();
}
for (;;) {
+ backsl = 0;
if (gobblebl)
gobblebl--;
if (cnt != 0) {
c &= (QUOTE|TRIM);
ch = c;
maphopcnt = 0;
- if (vglobp == 0 && Peekkey == 0)
+ if (vglobp == 0 && Peekkey == 0 && commch != 'r')
while ((ch = map(c, immacs)) != c) {
c = ch;
if (!value(REMAP))
vcsync();
c = getkey();
#ifndef USG3TTY
- if (c == tty.sg_erase || c == tty.sg_kill) {
+ if (c == tty.sg_erase || c == tty.sg_kill)
#else
if (c == tty.c_cc[VERASE]
- || c == tty.c_cc[VKILL]) {
+ || c == tty.c_cc[VKILL])
#endif
+ {
vgoto(y, x);
if (doomed >= 0)
doomed++;
goto def;
}
ungetkey(c), c = '\\';
- goto noput;
+ backsl = 1;
+ break;
/*
* ^Q Super quote following character
gobbled = 1;
continue;
}
- if (/* c <= ' ' && */ value(WRAPMARGIN) &&
- outcol >= OCOLUMNS - value(WRAPMARGIN)) {
+ if (value(WRAPMARGIN) &&
+ (outcol >= OCOLUMNS - value(WRAPMARGIN) ||
+ backsl && outcol==0) &&
+ commch != 'r') {
/*
* At end of word and hit wrapmargin.
* Move the word to next line and keep going.
*/
wdkind = 1;
*gcursor++ = c;
+ if (backsl)
+ *gcursor++ = getkey();
*gcursor = 0;
/*
* Find end of previous word if we are past it.
*/
for (cp=gcursor; cp>ogcursor && isspace(cp[-1]); cp--)
;
- if (outcol - (gcursor-cp) >= OCOLUMNS - value(WRAPMARGIN)) {
+ if (outcol+(backsl?OCOLUMNS:0) - (gcursor-cp) >= OCOLUMNS - value(WRAPMARGIN)) {
/*
* Find beginning of previous word.
*/
continue;
}
def:
- putchar(c);
- flush();
-noput:
+ if (!backsl) {
+ putchar(c);
+ flush();
+ }
if (gcursor > &genbuf[LBSIZE - 2])
error("Line too long");
*gcursor++ = c & TRIM;
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vops3.c 5.1 %G%";
+static char *sccsid = "@(#)ex_vops3.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vwind.c 5.1 %G%";
+static char *sccsid = "@(#)ex_vwind.c 6.1 %G%";
#include "ex.h"
#include "ex_tty.h"
#include "ex_vis.h"
set sh=/bin/csh
" delete junk (all but data lines)
g/^[ ]*$/d
- 1,/options/d
+ 1,/option options/d
/}/-1,$d
" get rid of all of line but option name
1,$s/ "//
.
$s/e[ ].*[ ]/e NOPTS /
0a
- /* sccs id @(#) ex_vars.h @(#)makeoptions 5.1 %G% */
+ /* sccs id @(#) ex_vars.h @(#)makeoptions 6.1 %G% */
.
w! ex_vars.h
q
/* The pwb version this is based on */
static char *printf_id = "@(#) printf.c:2.2 6/5/79";
/* The local sccs version within ex */
-static char *sccsid = "@(#)printf.c 5.1 %G%";
+static char *sccsid = "@(#)printf.c 6.1 %G%";
#include "varargs.h"
/*
* This version of printf is compatible with the Version 7 C