release 3.4, June 24, 1980
authorMark Horton <mark@ucbvax.Berkeley.EDU>
Fri, 1 Aug 1980 15:21:26 +0000 (07:21 -0800)
committerMark Horton <mark@ucbvax.Berkeley.EDU>
Fri, 1 Aug 1980 15:21:26 +0000 (07:21 -0800)
SCCS-vsn: usr.bin/ex/ex.c 4.1
SCCS-vsn: usr.bin/ex/ex.h 4.1
SCCS-vsn: usr.bin/ex/ex_addr.c 4.1
SCCS-vsn: usr.bin/ex/ex_argv.h 4.1
SCCS-vsn: usr.bin/ex/ex_cmds.c 4.1
SCCS-vsn: usr.bin/ex/ex_cmds2.c 4.1
SCCS-vsn: usr.bin/ex/ex_cmdsub.c 4.1
SCCS-vsn: usr.bin/ex/ex_data.c 4.1
SCCS-vsn: usr.bin/ex/ex_get.c 4.1
SCCS-vsn: usr.bin/ex/ex_io.c 4.1
SCCS-vsn: usr.bin/ex/ex_put.c 4.1
SCCS-vsn: usr.bin/ex/ex_re.c 4.1
SCCS-vsn: usr.bin/ex/ex_re.h 4.1
SCCS-vsn: usr.bin/ex/ex_set.c 4.1
SCCS-vsn: usr.bin/ex/ex_subr.c 4.1
SCCS-vsn: usr.bin/ex/ex_temp.c 4.1
SCCS-vsn: usr.bin/ex/ex_temp.h 4.1
SCCS-vsn: usr.bin/ex/ex_tty.c 4.1
SCCS-vsn: usr.bin/ex/ex_tty.h 4.1
SCCS-vsn: usr.bin/ex/ex_tune.h 4.1
SCCS-vsn: usr.bin/ex/ex_v.c 4.1
SCCS-vsn: usr.bin/ex/ex_vadj.c 4.1
SCCS-vsn: usr.bin/ex/ex_vars.h 4.1
SCCS-vsn: usr.bin/ex/ex_vget.c 4.1
SCCS-vsn: usr.bin/ex/ex_vis.h 4.1
SCCS-vsn: usr.bin/ex/ex_vmain.c 4.1
SCCS-vsn: usr.bin/ex/ex_voper.c 4.1
SCCS-vsn: usr.bin/ex/ex_vops.c 4.1
SCCS-vsn: usr.bin/ex/ex_vops2.c 4.1
SCCS-vsn: usr.bin/ex/ex_vops3.c 4.1
SCCS-vsn: usr.bin/ex/ex_vput.c 4.1
SCCS-vsn: usr.bin/ex/ex_vwind.c 4.1
SCCS-vsn: usr.bin/ex/ex3.7preserve/ex3.7preserve.c 4.1
SCCS-vsn: usr.bin/ex/ex3.7recover/ex3.7recover.c 4.1
SCCS-vsn: usr.bin/ex/Makefile 4.1
SCCS-vsn: usr.bin/ex/OTHER/makefile.70 4.1
SCCS-vsn: usr.bin/ex/makeoptions 4.1
SCCS-vsn: usr.bin/ex/printf.c 4.1

32 files changed:
usr/src/usr.bin/ex/Makefile
usr/src/usr.bin/ex/OTHER/makefile.70
usr/src/usr.bin/ex/ex.c
usr/src/usr.bin/ex/ex.h
usr/src/usr.bin/ex/ex3.7recover/ex3.7recover.c
usr/src/usr.bin/ex/ex_addr.c
usr/src/usr.bin/ex/ex_cmds.c
usr/src/usr.bin/ex/ex_cmds2.c
usr/src/usr.bin/ex/ex_cmdsub.c
usr/src/usr.bin/ex/ex_data.c
usr/src/usr.bin/ex/ex_io.c
usr/src/usr.bin/ex/ex_put.c
usr/src/usr.bin/ex/ex_re.c
usr/src/usr.bin/ex/ex_re.h
usr/src/usr.bin/ex/ex_set.c
usr/src/usr.bin/ex/ex_subr.c
usr/src/usr.bin/ex/ex_temp.c
usr/src/usr.bin/ex/ex_tty.c
usr/src/usr.bin/ex/ex_tty.h
usr/src/usr.bin/ex/ex_tune.h
usr/src/usr.bin/ex/ex_v.c
usr/src/usr.bin/ex/ex_vadj.c
usr/src/usr.bin/ex/ex_vars.h
usr/src/usr.bin/ex/ex_vget.c
usr/src/usr.bin/ex/ex_vis.h
usr/src/usr.bin/ex/ex_vmain.c
usr/src/usr.bin/ex/ex_voper.c
usr/src/usr.bin/ex/ex_vops.c
usr/src/usr.bin/ex/ex_vops2.c
usr/src/usr.bin/ex/ex_vops3.c
usr/src/usr.bin/ex/ex_vput.c
usr/src/usr.bin/ex/makeoptions

index 77f5700..bb182d7 100644 (file)
@@ -1,4 +1,4 @@
-VERSION=3.3
+VERSION=3.4
 #
 # Ex skeletal makefile for version 7
 #
 #
 # Ex skeletal makefile for version 7
 #
@@ -41,7 +41,7 @@ CXREF=        ${BINDIR}/cxref
 INCLUDE=/usr/include
 PR=    pr
 OBJS=  ex.o ex_addr.o ex_cmds.o ex_cmds2.o ex_cmdsub.o ex_data.o ex_get.o \
 INCLUDE=/usr/include
 PR=    pr
 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_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_vops.o ex_vops2.o ex_vops3.o ex_vput.o ex_vwind.o \
        printf.o strings.o
        ex_v.o ex_vadj.o ex_vget.o ex_vmain.o ex_voperate.o \
        ex_vops.o ex_vops2.o ex_vops3.o ex_vput.o ex_vwind.o \
        printf.o strings.o
@@ -91,15 +91,17 @@ clean:
        -rm -f *.o x*.[cs]
 
 ninstall: a.out
        -rm -f *.o x*.[cs]
 
 ninstall: a.out
-       -rm -f ${NBINDIR}/ex ${NBINDIR}/vi
+       -rm -f ${NBINDIR}/ex ${NBINDIR}/vi ${DESTDIR}${NBINDIR}/view
        cp a.out ${NBINDIR}/ex
 #      -cp ex${VERSION}strings ${LIBDIR}/ex${VERSION}strings
        ln ${NBINDIR}/ex ${NBINDIR}/vi
        cp a.out ${NBINDIR}/ex
 #      -cp ex${VERSION}strings ${LIBDIR}/ex${VERSION}strings
        ln ${NBINDIR}/ex ${NBINDIR}/vi
+       ln ${DESTDIR}${NBINDIR}/ex ${DESTDIR}${NBINDIR}/view
        chmod 1755 ${NBINDIR}/ex
 
 install: a.out exrecover expreserve
        -rm -f ${DESTDIR}${BINDIR}/ex
        -rm -f ${DESTDIR}${BINDIR}/vi
        chmod 1755 ${NBINDIR}/ex
 
 install: a.out exrecover expreserve
        -rm -f ${DESTDIR}${BINDIR}/ex
        -rm -f ${DESTDIR}${BINDIR}/vi
+       -rm -f ${DESTDIR}${BINDIR}/view
        -rm -f ${DESTDIR}${BINDIR}/edit
        -rm -f ${DESTDIR}${BINDIR}/e
        -rm -f ${DESTDIR}/usr/bin/ex
        -rm -f ${DESTDIR}${BINDIR}/edit
        -rm -f ${DESTDIR}${BINDIR}/e
        -rm -f ${DESTDIR}/usr/bin/ex
@@ -108,6 +110,7 @@ install: a.out exrecover expreserve
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/edit
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/e
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/vi
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/edit
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/e
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/vi
+       ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/view
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}/usr/bin/ex
        chmod 1755 ${DESTDIR}${BINDIR}/ex
        cp exrecover ${DESTDIR}${LIBDIR}/ex${VERSION}recover
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}/usr/bin/ex
        chmod 1755 ${DESTDIR}${BINDIR}/ex
        cp exrecover ${DESTDIR}${LIBDIR}/ex${VERSION}recover
index 77f5700..bb182d7 100644 (file)
@@ -1,4 +1,4 @@
-VERSION=3.3
+VERSION=3.4
 #
 # Ex skeletal makefile for version 7
 #
 #
 # Ex skeletal makefile for version 7
 #
@@ -41,7 +41,7 @@ CXREF=        ${BINDIR}/cxref
 INCLUDE=/usr/include
 PR=    pr
 OBJS=  ex.o ex_addr.o ex_cmds.o ex_cmds2.o ex_cmdsub.o ex_data.o ex_get.o \
 INCLUDE=/usr/include
 PR=    pr
 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_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_vops.o ex_vops2.o ex_vops3.o ex_vput.o ex_vwind.o \
        printf.o strings.o
        ex_v.o ex_vadj.o ex_vget.o ex_vmain.o ex_voperate.o \
        ex_vops.o ex_vops2.o ex_vops3.o ex_vput.o ex_vwind.o \
        printf.o strings.o
@@ -91,15 +91,17 @@ clean:
        -rm -f *.o x*.[cs]
 
 ninstall: a.out
        -rm -f *.o x*.[cs]
 
 ninstall: a.out
-       -rm -f ${NBINDIR}/ex ${NBINDIR}/vi
+       -rm -f ${NBINDIR}/ex ${NBINDIR}/vi ${DESTDIR}${NBINDIR}/view
        cp a.out ${NBINDIR}/ex
 #      -cp ex${VERSION}strings ${LIBDIR}/ex${VERSION}strings
        ln ${NBINDIR}/ex ${NBINDIR}/vi
        cp a.out ${NBINDIR}/ex
 #      -cp ex${VERSION}strings ${LIBDIR}/ex${VERSION}strings
        ln ${NBINDIR}/ex ${NBINDIR}/vi
+       ln ${DESTDIR}${NBINDIR}/ex ${DESTDIR}${NBINDIR}/view
        chmod 1755 ${NBINDIR}/ex
 
 install: a.out exrecover expreserve
        -rm -f ${DESTDIR}${BINDIR}/ex
        -rm -f ${DESTDIR}${BINDIR}/vi
        chmod 1755 ${NBINDIR}/ex
 
 install: a.out exrecover expreserve
        -rm -f ${DESTDIR}${BINDIR}/ex
        -rm -f ${DESTDIR}${BINDIR}/vi
+       -rm -f ${DESTDIR}${BINDIR}/view
        -rm -f ${DESTDIR}${BINDIR}/edit
        -rm -f ${DESTDIR}${BINDIR}/e
        -rm -f ${DESTDIR}/usr/bin/ex
        -rm -f ${DESTDIR}${BINDIR}/edit
        -rm -f ${DESTDIR}${BINDIR}/e
        -rm -f ${DESTDIR}/usr/bin/ex
@@ -108,6 +110,7 @@ install: a.out exrecover expreserve
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/edit
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/e
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/vi
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/edit
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/e
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/vi
+       ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}${BINDIR}/view
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}/usr/bin/ex
        chmod 1755 ${DESTDIR}${BINDIR}/ex
        cp exrecover ${DESTDIR}${LIBDIR}/ex${VERSION}recover
        ln ${DESTDIR}${BINDIR}/ex ${DESTDIR}/usr/bin/ex
        chmod 1755 ${DESTDIR}${BINDIR}/ex
        cp exrecover ${DESTDIR}${LIBDIR}/ex${VERSION}recover
index fbb4c3a..b10ceb8 100644 (file)
@@ -52,6 +52,8 @@ char  tttrace[]       = { '/','d','e','v','/','t','t','y','x','x',0 };
  *                     data base, grabbing of tty modes (at beginning
  *                     and after escapes).
  *
  *                     data base, grabbing of tty modes (at beginning
  *                     and after escapes).
  *
+ * ex_unix.c           Routines for the ! command and its variations.
+ *
  * ex_v*.c             Visual/open mode routines... see ex_v.c for a
  *                     guide to the overall organization.
  */
  * ex_v*.c             Visual/open mode routines... see ex_v.c for a
  *                     guide to the overall organization.
  */
@@ -59,12 +61,11 @@ char        tttrace[]       = { '/','d','e','v','/','t','t','y','x','x',0 };
 /*
  * Main procedure.  Process arguments and then
  * transfer control to the main command processing loop
 /*
  * Main procedure.  Process arguments and then
  * transfer control to the main command processing loop
- * in the routine commands.  We are entered as either "ex", "edit" or "vi"
- * and the distinction is made here.  Actually, we are "vi" if
- * there is a 'v' in our name, and "edit" if there is a 'd' in our
- * name.  For edit we just diddle options; for vi we actually
- * force an early visual command, setting the external initev so
- * the q command in visual doesn't give command mode.
+ * in the routine commands.  We are entered as either "ex", "edit", "vi"
+ * or "view" and the distinction is made here.  Actually, we are "vi" if
+ * there is a 'v' in our name, "view" is there is a 'w', and "edit" if
+ * there is a 'd' in our name.  For edit we just diddle options;
+ * for vi we actually force an early visual command.
  */
 main(ac, av)
        register int ac;
  */
 main(ac, av)
        register int ac;
@@ -88,33 +89,37 @@ main(ac, av)
         * get messed up if an interrupt comes in quickly.
         */
        gTTY(1);
         * get messed up if an interrupt comes in quickly.
         */
        gTTY(1);
+#ifndef USG3TTY
        normf = tty.sg_flags;
        normf = tty.sg_flags;
+#else
+       normf = tty;
+#endif
        ppid = getpid();
        /*
        ppid = getpid();
        /*
-        * Defend against d's, v's, and a's in directories of
+        * Defend against d's, v's, w's, and a's in directories of
         * path leading to our true name.
         */
        av[0] = tailpath(av[0]);
         * path leading to our true name.
         */
        av[0] = tailpath(av[0]);
-       ivis = any('v', av[0]);
 
        /*
 
        /*
-        * For debugging take files out of . if name is a.out.
-        * If a 'd' in our name, then set options for edit.
+        * Figure out how we were invoked: ex, edit, vi, view.
         */
         */
-#ifndef VMUNIX
-       if (av[0][0] == 'a')
-               erpath = tailpath(erpath);
-#endif
-       if (ivis) {
-#ifdef notdef
-               options[BEAUTIFY].odefault = value(BEAUTIFY) = 1;
-#endif
-       } else if (any('d', av[0])) {
+       ivis = any('v', av[0]); /* "vi" */
+       if (any('w', av[0]))    /* "view" */
+               value(READONLY) = 1;
+       if (any('d', av[0])) {  /* "edit" */
                value(OPEN) = 0;
                value(REPORT) = 1;
                value(MAGIC) = 0;
        }
 
                value(OPEN) = 0;
                value(REPORT) = 1;
                value(MAGIC) = 0;
        }
 
+#ifndef VMUNIX
+       /*
+        * For debugging take files out of . if name is a.out.
+        */
+       if (av[0][0] == 'a')
+               erpath = tailpath(erpath);
+#endif
        /*
         * Open the error message file.
         */
        /*
         * Open the error message file.
         */
@@ -137,6 +142,10 @@ main(ac, av)
        ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL;
        if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
                signal(SIGTERM, onhup);
        ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL;
        if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
                signal(SIGTERM, onhup);
+#ifdef TIOCLGET
+       if (signal(SIGTSTP, SIG_IGN) == SIG_DFL)
+               signal(SIGTSTP, onsusp), dosusp++;
+#endif
 
        /*
         * Initialize end of core pointers.
 
        /*
         * Initialize end of core pointers.
@@ -161,6 +170,10 @@ main(ac, av)
                        fast++;
                } else switch (c) {
 
                        fast++;
                } else switch (c) {
 
+               case 'R':
+                       value(READONLY) = 1;
+                       break;
+
 #ifdef TRACE
                case 'T':
                        if (av[0][2] == 0)
 #ifdef TRACE
                case 'T':
                        if (av[0][2] == 0)
@@ -212,6 +225,11 @@ main(ac, av)
                                defwind = 10*defwind + *cp - '0';
                        break;
 
                                defwind = 10*defwind + *cp - '0';
                        break;
 
+               case 'x':
+                       /* -x: encrypted mode */
+                       xflag = 1;
+                       break;
+
                default:
                        smerror("Unknown option %s\n", av[0]);
                        break;
                default:
                        smerror("Unknown option %s\n", av[0]);
                        break;
@@ -223,6 +241,11 @@ main(ac, av)
                ac--, av++;
        }
 
                ac--, av++;
        }
 
+       if(xflag){
+               key = getpass(KEYPROMPT);
+               kflag = crinit(key, perm);
+       }
+
        /*
         * If we are doing a recover and no filename
         * was given, then execute an exrecover command with
        /*
         * If we are doing a recover and no filename
         * was given, then execute an exrecover command with
@@ -258,19 +281,24 @@ main(ac, av)
                setrupt();
                intty = isatty(0);
                value(PROMPT) = intty;
                setrupt();
                intty = isatty(0);
                value(PROMPT) = intty;
+               if (cp = getenv("SHELL"))
+                       CP(shell, cp);
                if (fast || !intty)
                        setterm("dumb");
                else {
                        gettmode();
                if (fast || !intty)
                        setterm("dumb");
                else {
                        gettmode();
-                       if ((cp = getenv("TERM")) != 0)
+                       if ((cp = getenv("TERM")) != 0 && *cp)
                                setterm(cp);
                }
        }
        if (setexit() == 0 && !fast && intty)
                                setterm(cp);
                }
        }
        if (setexit() == 0 && !fast && intty)
-               if (globp = getenv("EXINIT"))
+               if ((globp = getenv("EXINIT")) && *globp)
                        commands(1,1);
                        commands(1,1);
-               else if ((cp = getenv("HOME")) != 0)
-                       source(strcat(strcpy(genbuf, cp), "/.exrc"), 1);
+               else {
+                       globp = 0;
+                       if ((cp = getenv("HOME")) != 0 && *cp)
+                               source(strcat(strcpy(genbuf, cp), "/.exrc"), 1);
+               }
 
        /*
         * Initial processing.  Handle tag, recover, and file argument
 
        /*
         * Initial processing.  Handle tag, recover, and file argument
@@ -342,9 +370,21 @@ init()
        undkind = UNDNONE;
        chng = 0;
        edited = 0;
        undkind = UNDNONE;
        chng = 0;
        edited = 0;
+#ifdef USG
+       signal (SIGHUP, SIG_IGN);
+#endif
+#ifdef USG3TTY
+#ifndef USG
+       signal (SIGHUP, SIG_IGN);
+#endif
+#endif
        for (i = 0; i <= 'z'-'a'+1; i++)
                names[i] = 1;
        anymarks = 0;
        for (i = 0; i <= 'z'-'a'+1; i++)
                names[i] = 1;
        anymarks = 0;
+        if(xflag) {
+                xtflag = 1;
+                makekey(key, tperm);
+        }
 }
 
 /*
 }
 
 /*
@@ -360,6 +400,11 @@ init()
 onhup()
 {
 
 onhup()
 {
 
+       /*
+        * USG tty driver can send multiple HUP's!!
+        */
+       signal(SIGINT, SIG_IGN);
+       signal(SIGHUP, SIG_IGN);
        if (chng == 0) {
                cleanup(1);
                exit(0);
        if (chng == 0) {
                cleanup(1);
                exit(0);
@@ -410,12 +455,17 @@ onintr()
 setrupt()
 {
 
 setrupt()
 {
 
-       if (ruptible)
+       if (ruptible) {
 #ifndef CBREAK
                signal(SIGINT, onintr);
 #else
                signal(SIGINT, inopen ? vintr : onintr);
 #endif
 #ifndef CBREAK
                signal(SIGINT, onintr);
 #else
                signal(SIGINT, inopen ? vintr : onintr);
 #endif
+#ifdef TIOCLGET
+               if (dosusp)
+                       signal(SIGTSTP, onsusp);
+#endif
+       }
 }
 
 preserve()
 }
 
 preserve()
index e7a8d3d..c9c0c76 100644 (file)
@@ -4,7 +4,7 @@
 #endif
 
 /*
 #endif
 
 /*
- * Ex version 3.1
+ * Ex version 3 (see exact version in ex_cmds.c, search for /Version/)
  *
  * Mark Horton, UC Berkeley
  * Bill Joy, UC Berkeley
  *
  * Mark Horton, UC Berkeley
  * Bill Joy, UC Berkeley
  *
  * Please forward bug reports to
  *
  *
  * Please forward bug reports to
  *
- *     Bill Joy
+ *     Mark Horton
  *     Computer Science Division, EECS
  *     EVANS HALL
  *     U.C. Berkeley 94704
  *     (415) 642-4948
  *     (415) 642-1024 (dept. office)
  *
  *     Computer Science Division, EECS
  *     EVANS HALL
  *     U.C. Berkeley 94704
  *     (415) 642-4948
  *     (415) 642-1024 (dept. office)
  *
- * or to wnj@mit-mc on the ARPA-net.  I would particularly like to hear
+ * or to csvax.mark@berkeley on the ARPA-net.  I would particularly like to hear
  * of additional terminal descriptions you add to the termcap data base.
  */
 
 #include <sys/types.h>
 #include <ctype.h>
 #include <errno.h>
  * of additional terminal descriptions you add to the termcap data base.
  */
 
 #include <sys/types.h>
 #include <ctype.h>
 #include <errno.h>
-#include <sgtty.h>
 #include <signal.h>
 #include <setjmp.h>
 #include <sys/stat.h>
 
 #include <signal.h>
 #include <setjmp.h>
 #include <sys/stat.h>
 
+/*
+ *     The following little dance copes with the new USG tty handling.
+ *     This stuff has the advantage of considerable flexibility, and
+ *     the disadvantage of being incompatible with anything else.
+ *     The presence of the symbol USG3TTY will indicate the new code:
+ *     in this case, we define CBREAK (because we can simulate it exactly),
+ *     but we won't actually use it, so we set it to a value that will
+ *     probably blow the compilation if we goof up.
+ */
+#ifdef USG3TTY
+#include <termio.h>
+#define CBREAK xxxxx
+#else
+#include <sgtty.h>
+#endif
+
 extern int errno;
 
 #ifndef VMUNIX
 extern int errno;
 
 #ifndef VMUNIX
@@ -142,6 +157,9 @@ int chng;                   /* Warn "No write" */
 char   *Command;
 short  defwind;                /* -w# change default window size */
 int    dirtcnt;                /* When >= MAXDIRT, should sync temporary */
 char   *Command;
 short  defwind;                /* -w# change default window size */
 int    dirtcnt;                /* When >= MAXDIRT, should sync temporary */
+#ifdef TIOCLGET
+bool   dosusp;                 /* Do SIGTSTP in visual when ^Z typed */
+#endif
 bool   edited;                 /* Current file is [Edited] */
 line   *endcore;               /* Last available core location */
 bool   endline;                /* Last cmd mode command ended with \n */
 bool   edited;                 /* Current file is [Edited] */
 line   *endcore;               /* Last available core location */
 bool   endline;                /* Last cmd mode command ended with \n */
@@ -154,6 +172,7 @@ char        genbuf[LBSIZE];         /* Working buffer when manipulating linebuf */
 bool   hush;                   /* Command line option - was given, hush up! */
 char   *globp;                 /* (Untyped) input string to command mode */
 bool   holdcm;                 /* Don't cursor address */
 bool   hush;                   /* Command line option - was given, hush up! */
 char   *globp;                 /* (Untyped) input string to command mode */
 bool   holdcm;                 /* Don't cursor address */
+bool   inappend;               /* in ex command append mode */
 bool   inglobal;               /* Inside g//... or v//... */
 char   *initev;                /* Initial : escape for visual */
 bool   inopen;                 /* Inside open or visual */
 bool   inglobal;               /* Inside g//... or v//... */
 char   *initev;                /* Initial : escape for visual */
 bool   inopen;                 /* Inside open or visual */
@@ -173,6 +192,7 @@ line        names['z'-'a'+2];       /* Mark registers a-z,' */
 int    notecnt;                /* Count for notify (to visual from cmd) */
 bool   numberf;                /* Command should run in number mode */
 char   obuf[BUFSIZ];           /* Buffer for tty output */
 int    notecnt;                /* Count for notify (to visual from cmd) */
 bool   numberf;                /* Command should run in number mode */
 char   obuf[BUFSIZ];           /* Buffer for tty output */
+short  oprompt;                /* Saved during source */
 short  ospeed;                 /* Output speed (from gtty) */
 int    otchng;                 /* Backup tchng to find changes in macros */
 short  peekc;                  /* Peek ahead character (cmd mode input) */
 short  ospeed;                 /* Output speed (from gtty) */
 int    otchng;                 /* Backup tchng to find changes in macros */
 short  peekc;                  /* Peek ahead character (cmd mode input) */
@@ -276,6 +296,20 @@ line       *undadot;               /* If we saved all lines, dot reverts here */
 #define        UNDNONE         3
 #define        UNDPUT          4
 
 #define        UNDNONE         3
 #define        UNDPUT          4
 
+/*
+ * Various miscellaneous flags and buffers needed by the encryption routines.
+ */
+#define        KSIZE   9       /* key size for encryption */
+#define        KEYPROMPT       "Key: "
+int    xflag;          /* True if we are in encryption mode */
+int    xtflag;         /* True if the temp file is being encrypted */
+int    kflag;          /* True if the key has been accepted */
+char   perm[768];
+char   tperm[768];
+char   *key;
+char   crbuf[CRSIZE];
+char   *getpass();
+
 /*
  * Function type definitions
  */
 /*
  * Function type definitions
  */
@@ -333,6 +367,7 @@ int numbline();
 int    (*oldquit)();
 int    onhup();
 int    onintr();
 int    (*oldquit)();
 int    onhup();
 int    onintr();
+int    onsusp();
 int    putch();
 int    shift();
 int    termchar();
 int    putch();
 int    shift();
 int    termchar();
index 9781fb9..218e65a 100644 (file)
@@ -175,8 +175,13 @@ error(str, inf)
 {
 
        fprintf(stderr, str, inf);
 {
 
        fprintf(stderr, str, inf);
+#ifndef USG3TTY
        gtty(2, &tty);
        if ((tty.sg_flags & RAW) == 0)
        gtty(2, &tty);
        if ((tty.sg_flags & RAW) == 0)
+#else
+       ioctl(2, TCGETA, &tty);
+       if (tty.c_lflag & ICANON)
+#endif
                fprintf(stderr, "\n");
        exit(1);
 }
                fprintf(stderr, "\n");
        exit(1);
 }
index 5621e5e..afe1b7c 100644 (file)
@@ -192,9 +192,12 @@ address(inline)
                        addr = dot;
                        if (inline && execute(0, dot)) {
                                if (c == '/') {
                        addr = dot;
                        if (inline && execute(0, dot)) {
                                if (c == '/') {
-                                       while (loc1 <= inline)
+                                       while (loc1 <= inline) {
+                                               if (loc1 == loc2)
+                                                       loc2++;
                                                if (!execute(1))
                                                        goto nope;
                                                if (!execute(1))
                                                        goto nope;
+                                       }
                                        break;
                                } else if (loc1 < inline) {
                                        char *last;
                                        break;
                                } else if (loc1 < inline) {
                                        char *last;
@@ -202,6 +205,8 @@ doques:
 
                                        do {
                                                last = loc1;
 
                                        do {
                                                last = loc1;
+                                               if (loc1 == loc2)
+                                                       loc2++;
                                                if (!execute(1))
                                                        break;
                                        } while (loc1 < inline);
                                                if (!execute(1))
                                                        break;
                                        } while (loc1 < inline);
index a85b1b2..7e85951 100644 (file)
@@ -137,7 +137,15 @@ choice:
 
                case 'a':
 
 
                case 'a':
 
-                       if (peekchar() == 'r') {
+                       switch(peekchar()) {
+                       case 'b':
+/* abbreviate */
+                               tail("abbreviate");
+                               setnoaddr();
+                               mapcmd(0, 1);
+                               anyabbrs = 1;
+                               continue;
+                       case 'r':
 /* args */
                                tail("args");
                                setnoaddr();
 /* args */
                                tail("args");
                                setnoaddr();
@@ -153,9 +161,12 @@ choice:
                        setdot();
                        aiflag = exclam();
                        newline();
                        setdot();
                        aiflag = exclam();
                        newline();
+                       vmacchng(0);
                        deletenone();
                        setin(addr2);
                        deletenone();
                        setin(addr2);
+                       inappend = 1;
                        ignore(append(gettty, addr2));
                        ignore(append(gettty, addr2));
+                       inappend = 0;
                        nochng();
                        continue;
 
                        nochng();
                        continue;
 
@@ -165,6 +176,7 @@ choice:
 /* copy */
                        case 'o':
                                tail("copy");
 /* copy */
                        case 'o':
                                tail("copy");
+                               vmacchng(0);
                                move();
                                continue;
 
                                move();
                                continue;
 
@@ -213,9 +225,12 @@ changdir:
 /* change */
                        aiflag = exclam();
                        setCNL();
 /* change */
                        aiflag = exclam();
                        setCNL();
+                       vmacchng(0);
                        setin(addr1);
                        delete(0);
                        setin(addr1);
                        delete(0);
+                       inappend = 1;
                        ignore(append(gettty, addr1 - 1));
                        ignore(append(gettty, addr1 - 1));
+                       inappend = 0;
                        nochng();
                        continue;
 
                        nochng();
                        continue;
 
@@ -227,6 +242,7 @@ changdir:
                        tail("delete");
                        c = cmdreg();
                        setCNL();
                        tail("delete");
                        c = cmdreg();
                        setCNL();
+                       vmacchng(0);
                        if (c)
                                YANKreg(c);
                        delete(0);
                        if (c)
                                YANKreg(c);
                        delete(0);
@@ -237,6 +253,7 @@ changdir:
 /* ex */
                case 'e':
                        tail(peekchar() == 'x' ? "ex" : "edit");
 /* ex */
                case 'e':
                        tail(peekchar() == 'x' ? "ex" : "edit");
+editcmd:
                        if (!exclam() && chng)
                                c = 'E';
                        filename(c);
                        if (!exclam() && chng)
                                c = 'E';
                        filename(c);
@@ -281,9 +298,12 @@ doecmd:
                        nonzero();
                        aiflag = exclam();
                        newline();
                        nonzero();
                        aiflag = exclam();
                        newline();
+                       vmacchng(0);
                        deletenone();
                        setin(addr2);
                        deletenone();
                        setin(addr2);
+                       inappend = 1;
                        ignore(append(gettty, addr2 - 1));
                        ignore(append(gettty, addr2 - 1));
+                       inappend = 0;
                        if (dot == zero && dol > zero)
                                dot = one;
                        nochng();
                        if (dot == zero && dol > zero)
                                dot = one;
                        nochng();
@@ -296,6 +316,7 @@ doecmd:
                        setcount();
                        nonzero();
                        newline();
                        setcount();
                        nonzero();
                        newline();
+                       vmacchng(0);
                        if (given < 2 && addr2 != dol)
                                addr2++;
                        join(c);
                        if (given < 2 && addr2 != dol)
                                addr2++;
                        join(c);
@@ -332,7 +353,7 @@ casek:
 /* map */
                                        tail2of("map");
                                        setnoaddr();
 /* map */
                                        tail2of("map");
                                        setnoaddr();
-                                       mapcmd(0);
+                                       mapcmd(0, 0);
                                        continue;
                                }
 /* mark */
                                        continue;
                                }
 /* mark */
@@ -341,6 +362,7 @@ casek:
                        }
 /* move */
                        tail("move");
                        }
 /* move */
                        tail("move");
+                       vmacchng(0);
                        move();
                        continue;
 
                        move();
                        continue;
 
@@ -379,6 +401,7 @@ casek:
                                setdot();
                                c = cmdreg();
                                eol();
                                setdot();
                                c = cmdreg();
                                eol();
+                               vmacchng(0);
                                if (c)
                                        putreg(c);
                                else
                                if (c)
                                        putreg(c);
                                else
@@ -429,8 +452,11 @@ quit:
                                if (!ateopr())
                                        vnfl();
                                else {
                                if (!ateopr())
                                        vnfl();
                                else {
+                                       tostop();
+                                       /* replaced by tostop
                                        putpad(VE);
                                        putpad(KE);
                                        putpad(VE);
                                        putpad(KE);
+                                       */
                                }
                                flush();
                                setty(normf);
                                }
                                flush();
                                setty(normf);
@@ -447,8 +473,9 @@ quit:
                                case 'w':
                                        tail2of("rewind");
                                        setnoaddr();
                                case 'w':
                                        tail2of("rewind");
                                        setnoaddr();
-                                       ignore(quickly());
                                        eol();
                                        eol();
+                                       ckaw();
+                                       ignore(quickly());
                                        erewind();
                                        next();
                                        c = 'e';
                                        erewind();
                                        next();
                                        c = 'e';
@@ -489,6 +516,7 @@ quit:
                        if (savedfile[0] == 0 && dol == zero)
                                c = 'e';
                        pastwh();
                        if (savedfile[0] == 0 && dol == zero)
                                c = 'e';
                        pastwh();
+                       vmacchng(0);
                        if (peekchar() == '!') {
                                setdot();
                                ignchar();
                        if (peekchar() == '!') {
                                setdot();
                                ignchar();
@@ -538,6 +566,21 @@ quit:
                                eol();
                                source(file, 0);
                                continue;
                                eol();
                                source(file, 0);
                                continue;
+#ifdef TIOCLGET
+/* stop */
+                       case 't':
+                               tail("stop");
+                               if (!ldisc)
+                                       error("Old tty driver|Not using new tty driver/shell");
+                               c = exclam();
+                               eol();
+                               if (!c)
+                                       ckaw();
+                               eol();
+                               onsusp();
+                               continue;
+#endif
+
                        }
                        /* fall into ... */
 
                        }
                        /* fall into ... */
 
@@ -549,6 +592,7 @@ quit:
                        Command = "substitute";
                        if (c == 's')
                                tail(Command);
                        Command = "substitute";
                        if (c == 's')
                                tail(Command);
+                       vmacchng(0);
                        if (!substitute(c))
                                pflag = 0;
                        continue;
                        if (!substitute(c))
                                pflag = 0;
                        continue;
@@ -565,17 +609,26 @@ quit:
                                continue;
                        }
                        tail("t");
                                continue;
                        }
                        tail("t");
+                       vmacchng(0);
                        move();
                        continue;
 
                case 'u':
                        if (peekchar() == 'n') {
                        move();
                        continue;
 
                case 'u':
                        if (peekchar() == 'n') {
-/* unmap */
                                ignchar();
                                ignchar();
-                               if (peekchar() == 'm') {
+                               switch(peekchar()) {
+/* unmap */
+                               case 'm':
                                        tail2of("unmap");
                                        setnoaddr();
                                        tail2of("unmap");
                                        setnoaddr();
-                                       mapcmd(1);
+                                       mapcmd(1, 0);
+                                       continue;
+/* unabbreviate */
+                               case 'a':
+                                       tail2of("unabbreviate");
+                                       setnoaddr();
+                                       mapcmd(1, 1);
+                                       anyabbrs = 1;
                                        continue;
                                }
 /* undo */
                                        continue;
                                }
 /* undo */
@@ -597,13 +650,17 @@ quit:
                                tail("version");
                                setNAEOL();
                                /* should use SCCS subst here */
                                tail("version");
                                setNAEOL();
                                /* should use SCCS subst here */
-                               printf("Version 3.3, February 2, 1980");
+                               printf("Version 3.4, June 24, 1980");
                                noonl();
                                continue;
 
 /* visual */
                        case 'i':
                                tail("visual");
                                noonl();
                                continue;
 
 /* visual */
                        case 'i':
                                tail("visual");
+                               if (inopen) {
+                                       c = 'e';
+                                       goto editcmd;
+                               }
                                vop();
                                pflag = 0;
                                nochng();
                                vop();
                                pflag = 0;
                                nochng();
@@ -649,6 +706,7 @@ wq:
                        c = cmdreg();
                        setcount();
                        eol();
                        c = cmdreg();
                        setcount();
                        eol();
+                       vmacchng(0);
                        if (c)
                                YANKreg(c);
                        else
                        if (c)
                                YANKreg(c);
                        else
@@ -714,6 +772,11 @@ caseline:
                        plines(addr1, addr2, 1);
                        continue;
 
                        plines(addr1, addr2, 1);
                        continue;
 
+/* " */
+               case '"':
+                       comment();
+                       continue;
+
 /* # */
                case '#':
 numberit:
 /* # */
                case '#':
 numberit:
@@ -735,6 +798,7 @@ numberit:
 /* ! */
                case '!':
                        if (addr2 != 0) {
 /* ! */
                case '!':
                        if (addr2 != 0) {
+                               vmacchng(0);
                                unix0(0);
                                setdot();
                                filter(2);
                                unix0(0);
                                setdot();
                                filter(2);
@@ -744,7 +808,7 @@ numberit:
                                putpad(TE);
                                flush();
                                unixwt(1, unixex("-c", uxb, 0, 0));
                                putpad(TE);
                                flush();
                                unixwt(1, unixex("-c", uxb, 0, 0));
-                               vcontin(0);
+                               vclrech(1);     /* vcontin(0); */
                                nochng();
                        }
                        continue;
                                nochng();
                        }
                        continue;
@@ -756,6 +820,7 @@ numberit:
                        for (cnt = 1; peekchar() == c; cnt++)
                                ignchar();
                        setCNL();
                        for (cnt = 1; peekchar() == c; cnt++)
                                ignchar();
                        setCNL();
+                       vmacchng(0);
                        shift(c, cnt);
                        continue;
 
                        shift(c, cnt);
                        continue;
 
index fd1d68f..67210cc 100644 (file)
@@ -39,6 +39,7 @@ endcmd(ch)
                return (1);
        
        case '|':
                return (1);
        
        case '|':
+       case '"':
                endline = 0;
                return (1);
        }
                endline = 0;
                return (1);
        }
@@ -102,6 +103,10 @@ erewind()
 error0()
 {
 
 error0()
 {
 
+       if (laste) {
+               laste = 0;
+               sync();
+       }
        if (vcatch) {
                if (splitw == 0)
                        fixech();
        if (vcatch) {
                if (splitw == 0)
                        fixech();
@@ -118,10 +123,6 @@ error0()
        setoutt();
        flush();
        resetflav();
        setoutt();
        flush();
        resetflav();
-       if (laste) {
-               laste = 0;
-               sync();
-       }
        if (!SO || !SE)
                dingdong();
        if (inopen) {
        if (!SO || !SE)
                dingdong();
        if (inopen) {
@@ -132,8 +133,10 @@ error0()
                COLUMNS = OCOLUMNS;
                undvis();
                ostop(normf);
                COLUMNS = OCOLUMNS;
                undvis();
                ostop(normf);
+               /* ostop should be doing this
                putpad(VE);
                putpad(KE);
                putpad(VE);
                putpad(KE);
+               */
                putnl();
        }
        inopen = 0;
                putnl();
        }
        inopen = 0;
@@ -158,7 +161,7 @@ error1(str)
                io = -1;
        }
        die = (getpid() != ppid);       /* Only children die */
                io = -1;
        }
        die = (getpid() != ppid);       /* Only children die */
-       inglobal = 0;
+       inappend = inglobal = 0;
        globp = vglobp = vmacp = 0;
        if (vcatch && !die) {
                inopen = 1;
        globp = vglobp = vmacp = 0;
        if (vcatch && !die) {
                inopen = 1;
@@ -228,10 +231,12 @@ makargs()
  */
 next()
 {
  */
 next()
 {
+       extern short isalt;     /* defined in ex_io.c */
 
        if (argc == 0)
                error("No more files@to edit");
        morargc = argc;
 
        if (argc == 0)
                error("No more files@to edit");
        morargc = argc;
+       isalt = (strcmp(altfile, args)==0) + 1;
        if (savedfile[0])
                CP(altfile, savedfile);
        CP(savedfile, args);
        if (savedfile[0])
                CP(altfile, savedfile);
        CP(savedfile, args);
@@ -277,6 +282,11 @@ newline()
                case '\t':
                        continue;
 
                case '\t':
                        continue;
 
+               case '"':
+                       comment();
+                       setflav();
+                       return;
+
                default:
                        if (!endcmd(c))
 serror("Extra chars|Extra characters at end of \"%s\" command", Command);
                default:
                        if (!endcmd(c))
 serror("Extra chars|Extra characters at end of \"%s\" command", Command);
@@ -378,7 +388,7 @@ skipend()
 {
 
        pastwh();
 {
 
        pastwh();
-       return (endcmd(peekchar()));
+       return (endcmd(peekchar()) && peekchar() != '"');
 }
 
 /*
 }
 
 /*
@@ -503,10 +513,13 @@ vcontin(ask)
                        }
                }
                vclrech(1);
                        }
                }
                vclrech(1);
-               if (ask && Peekkey != ':') {
+               if (Peekkey != ':') {
                        putpad(TI);
                        putpad(TI);
+                       tostart();
+                       /* replaced by ostart.
                        putpad(VS);
                        putpad(KS);
                        putpad(VS);
                        putpad(KS);
+                       */
                }
        }
 }
                }
        }
 }
@@ -525,8 +538,11 @@ vnfl()
                        vmoveitup(1, 0);
                vgoto(WECHO, 0);
                vclrbyte(vtube[WECHO], WCOLS);
                        vmoveitup(1, 0);
                vgoto(WECHO, 0);
                vclrbyte(vtube[WECHO], WCOLS);
+               tostop();
+               /* replaced by the ostop above
                putpad(VE);
                putpad(KE);
                putpad(VE);
                putpad(KE);
+               */
        }
        flush();
 }
        }
        flush();
 }
index 8bd125a..ae7b2f6 100644 (file)
@@ -3,6 +3,7 @@
 #include "ex_argv.h"
 #include "ex_temp.h"
 #include "ex_tty.h"
 #include "ex_argv.h"
 #include "ex_temp.h"
 #include "ex_tty.h"
+#include "ex_vis.h"
 
 /*
  * Command mode subroutines implementing
 
 /*
  * Command mode subroutines implementing
@@ -12,6 +13,7 @@
 
 bool   endline = 1;
 line   *tad1;
 
 bool   endline = 1;
 line   *tad1;
+static jnoop();
 
 /*
  * Append after line a lines returned by function f.
 
 /*
  * Append after line a lines returned by function f.
@@ -213,7 +215,11 @@ join(c)
        strcLIN(genbuf);
        delete(0);
        jcount = 1;
        strcLIN(genbuf);
        delete(0);
        jcount = 1;
+       if (FIXUNDO)
+               undap1 = undap2 = addr1;
        ignore(append(jnoop, --addr1));
        ignore(append(jnoop, --addr1));
+       if (FIXUNDO)
+               vundkind = VMANY;
 }
 
 static
 }
 
 static
@@ -524,6 +530,7 @@ badtag:
                io = open(fn, 0);
                if (io<0)
                        continue;
                io = open(fn, 0);
                if (io<0)
                        continue;
+               tfcount++;
                while (getfile() == 0) {
 #endif
                        /* loop for each tags file entry */
                while (getfile() == 0) {
 #endif
                        /* loop for each tags file entry */
@@ -541,7 +548,7 @@ badtag:
 #endif
                        while (*cp && *lp == *cp)
                                cp++, lp++;
 #endif
                        while (*cp && *lp == *cp)
                                cp++, lp++;
-                       if (*lp || !iswhite(*cp)) {
+                       if ((*lp || !iswhite(*cp)) && (value(TAGLENGTH)==0 || lp-lasttag < value(TAGLENGTH))) {
 #ifdef VMUNIX
                                if (*lp > *cp)
                                        bot = mid + 1;
 #ifdef VMUNIX
                                if (*lp > *cp)
                                        bot = mid + 1;
@@ -560,6 +567,10 @@ badtag:
 #else
                        close(io);
 #endif
 #else
                        close(io);
 #endif
+                       /* Rest of tag if abbreviated */
+                       while (!iswhite(*cp))
+                               cp++;
+
                        /* name of file */
                        while (*cp && iswhite(*cp))
                                cp++;
                        /* name of file */
                        while (*cp && iswhite(*cp))
                                cp++;
@@ -582,7 +593,7 @@ badtags:
                                 */
                                names['t'-'a'] = *dot &~ 01;
                                if (inopen) {
                                 */
                                names['t'-'a'] = *dot &~ 01;
                                if (inopen) {
-                                       extern char *ncols['z'-'a'+1];
+                                       extern char *ncols['z'-'a'+2];
                                        extern char *cursor;
 
                                        ncols['t'-'a'] = cursor;
                                        extern char *cursor;
 
                                        ncols['t'-'a'] = cursor;
@@ -985,7 +996,11 @@ undo(c)
                } else
                        undkind = UNDCHANGE;
        }
                } else
                        undkind = UNDCHANGE;
        }
-       if (dot == zero && dot != dol)
+       /*
+        * Defensive programming - after a munged undadot.
+        * Also handle empty buffer case.
+        */
+       if ((dot <= zero || dot > dol) && dot != dol)
                dot = one;
 #ifdef TRACE
        if (trace)
                dot = one;
 #ifdef TRACE
        if (trace)
@@ -1034,22 +1049,25 @@ somechange()
  * Map command:
  * map src dest
  */
  * Map command:
  * map src dest
  */
-mapcmd(un)
+mapcmd(un, ab)
        int un; /* true if this is unmap command */
        int un; /* true if this is unmap command */
+       int ab; /* true if this is abbr command */
 {
 {
-       char lhs[10], rhs[100]; /* max sizes resp. */
+       char lhs[100], rhs[100];        /* max sizes resp. */
        register char *p;
        register char c;
        char *dname;
        struct maps *mp;        /* the map structure we are working on */
 
        register char *p;
        register char c;
        char *dname;
        struct maps *mp;        /* the map structure we are working on */
 
-       mp = exclam() ? immacs : arrows;
+       mp = ab ? abbrevs : exclam() ? immacs : arrows;
        if (skipend()) {
                int i;
 
                /* print current mapping values */
                if (peekchar() != EOF)
                        ignchar();
        if (skipend()) {
                int i;
 
                /* print current mapping values */
                if (peekchar() != EOF)
                        ignchar();
+               if (un)
+                       error("Missing lhs");
                if (inopen)
                        pofix();
                for (i=0; mp[i].mapto; i++)
                if (inopen)
                        pofix();
                for (i=0; mp[i].mapto; i++)
@@ -1069,15 +1087,14 @@ mapcmd(un)
                c = getchar();
                if (c == CTRL(v)) {
                        c = getchar();
                c = getchar();
                if (c == CTRL(v)) {
                        c = getchar();
-               } else if (any(c, " \t")) {
-                       if (un)
-                               eol();  /* will usually cause an error */
-                       else
-                               break;
-               } else if (endcmd(c)) {
+               } else if (!un && any(c, " \t")) {
+                       /* End of lhs */
+                       break;
+               } else if (endcmd(c) && c!='"') {
                        ungetchar(c);
                        if (un) {
                                newline();
                        ungetchar(c);
                        if (un) {
                                newline();
+                               *p = 0;
                                addmac(lhs, NOSTR, NOSTR, mp);
                                return;
                        } else
                                addmac(lhs, NOSTR, NOSTR, mp);
                                return;
                        } else
@@ -1093,7 +1110,7 @@ mapcmd(un)
                c = getchar();
                if (c == CTRL(v)) {
                        c = getchar();
                c = getchar();
                if (c == CTRL(v)) {
                        c = getchar();
-               } else if (endcmd(c)) {
+               } else if (endcmd(c) && c!='"') {
                        ungetchar(c);
                        break;
                }
                        ungetchar(c);
                        break;
                }
@@ -1134,6 +1151,10 @@ addmac(src,dest,dname,mp)
 {
        register int slot, zer;
 
 {
        register int slot, zer;
 
+#ifdef TRACE
+       if (trace)
+               fprintf(trace, "addmac(src='%s', dest='%s', dname='%s', mp=%x\n", src, dest, dname, mp);
+#endif
        if (dest && mp==arrows) {
                /* Make sure user doesn't screw himself */
                /*
        if (dest && mp==arrows) {
                /* Make sure user doesn't screw himself */
                /*
@@ -1170,7 +1191,7 @@ addmac(src,dest,dname,mp)
        zer = -1;
        for (slot=0; mp[slot].mapto; slot++) {
                if (mp[slot].cap) {
        zer = -1;
        for (slot=0; mp[slot].mapto; slot++) {
                if (mp[slot].cap) {
-                       if (eq(src, mp[slot].cap))
+                       if (eq(src, mp[slot].cap) || eq(src, mp[slot].mapto))
                                break;  /* if so, reuse slot */
                } else {
                        zer = slot;     /* remember an empty slot */
                                break;  /* if so, reuse slot */
                } else {
                        zer = slot;     /* remember an empty slot */
index dd29535..5883f16 100644 (file)
@@ -46,11 +46,13 @@ struct      option options[NOPTS + 1] = {
        "lisp",         0,      ONOFF,          0,      0,      0,
        "list",         0,      ONOFF,          0,      0,      0,
        "magic",        0,      ONOFF,          1,      1,      0,
        "lisp",         0,      ONOFF,          0,      0,      0,
        "list",         0,      ONOFF,          0,      0,      0,
        "magic",        0,      ONOFF,          1,      1,      0,
+       "mesg",         0,      ONOFF,          1,      1,      0,
        "number",       "nu",   ONOFF,          0,      0,      0,
        "open",         0,      ONOFF,          1,      1,      0,
        "optimize",     "opt",  ONOFF,          0,      0,      0,
        "paragraphs",   "para", STRING,         0,      0,      paragraphs,
        "prompt",       0,      ONOFF,          1,      1,      0,
        "number",       "nu",   ONOFF,          0,      0,      0,
        "open",         0,      ONOFF,          1,      1,      0,
        "optimize",     "opt",  ONOFF,          0,      0,      0,
        "paragraphs",   "para", STRING,         0,      0,      paragraphs,
        "prompt",       0,      ONOFF,          1,      1,      0,
+       "readonly",     "ro",   ONOFF,          0,      0,      0,
        "redraw",       0,      ONOFF,          0,      0,      0,
        "remap",        0,      ONOFF,          1,      1,      0,
        "report",       0,      NUMERIC,        5,      5,      0,
        "redraw",       0,      ONOFF,          0,      0,      0,
        "remap",        0,      ONOFF,          1,      1,      0,
        "report",       0,      NUMERIC,        5,      5,      0,
@@ -60,13 +62,13 @@ struct      option options[NOPTS + 1] = {
        "shiftwidth",   "sw",   NUMERIC,        TABS,   TABS,   0,
        "showmatch",    "sm",   ONOFF,          0,      0,      0,
        "slowopen",     "slow", ONOFF,          0,      0,      0,
        "shiftwidth",   "sw",   NUMERIC,        TABS,   TABS,   0,
        "showmatch",    "sm",   ONOFF,          0,      0,      0,
        "slowopen",     "slow", ONOFF,          0,      0,      0,
-       "tags",         "tag",  STRING,         0,      0,      tags,
        "tabstop",      "ts",   NUMERIC,        TABS,   TABS,   0,
        "tabstop",      "ts",   NUMERIC,        TABS,   TABS,   0,
+       "taglength",    "tl",   NUMERIC,        0,      0,      0,
+       "tags",         "tag",  STRING,         0,      0,      tags,
        "term",         0,      OTERM,          0,      0,      ttytype,
        "terse",        0,      ONOFF,          0,      0,      0,
        "timeout",      "to",   ONOFF,          1,      1,      0,
        "ttytype",      "tty",  OTERM,          0,      0,      ttytype,
        "term",         0,      OTERM,          0,      0,      ttytype,
        "terse",        0,      ONOFF,          0,      0,      0,
        "timeout",      "to",   ONOFF,          1,      1,      0,
        "ttytype",      "tty",  OTERM,          0,      0,      ttytype,
-       "undomacro",    "um",   ONOFF,          1,      1,      0,
        "warn",         0,      ONOFF,          1,      1,      0,
        "window",       "wi",   NUMERIC,        23,     23,     0,
        "wrapscan",     "ws",   ONOFF,          1,      1,      0,
        "warn",         0,      ONOFF,          1,      1,      0,
        "window",       "wi",   NUMERIC,        23,     23,     0,
        "wrapscan",     "ws",   ONOFF,          1,      1,      0,
index 3f0a227..1c329dd 100644 (file)
@@ -6,7 +6,7 @@
 #include "ex_vis.h"
 
 /*
 #include "ex_vis.h"
 
 /*
- * File input/output, unix escapes, source, filtering preserve and recover
+ * File input/output, source, preserve and recover
  */
 
 /*
  */
 
 /*
@@ -16,6 +16,7 @@
 int    altdot;
 int    oldadot;
 bool   wasalt;
 int    altdot;
 int    oldadot;
 bool   wasalt;
+short  isalt;
 
 long   cntch;                  /* Count of characters on unit io */
 #ifndef VMUNIX
 
 long   cntch;                  /* Count of characters on unit io */
 #ifndef VMUNIX
@@ -42,8 +43,11 @@ filename(comm)
                if (savedfile[0] == 0 && comm != 'f')
                        error("No file|No current filename");
                CP(file, savedfile);
                if (savedfile[0] == 0 && comm != 'f')
                        error("No file|No current filename");
                CP(file, savedfile);
-               wasalt = 0;
+               wasalt = (isalt > 0) ? isalt-1 : 0;
+               isalt = 0;
                oldadot = altdot;
                oldadot = altdot;
+               if (c == 'e' || c == 'E')
+                       altdot = lineDOT();
                if (d == EOF)
                        ungetchar(d);
        } else {
                if (d == EOF)
                        ungetchar(d);
        } else {
@@ -84,6 +88,8 @@ filename(comm)
        if (file[0] != 0) {
                lprintf("\"%s\"", file);
                if (comm == 'f') {
        if (file[0] != 0) {
                lprintf("\"%s\"", file);
                if (comm == 'f') {
+                       if (value(READONLY))
+                               printf(" [Read only]");
                        if (!edited)
                                printf(" [Not edited]");
                        if (tchng)
                        if (!edited)
                                printf(" [Not edited]");
                        if (tchng)
@@ -138,7 +144,7 @@ getargs()
                switch (c) {
 
                case '\\':
                switch (c) {
 
                case '\\':
-                       if (any(peekchar(), "#%"))
+                       if (any(peekchar(), "#%|"))
                                c = getchar();
                        /* fall into... */
 
                                c = getchar();
                        /* fall into... */
 
@@ -322,6 +328,8 @@ rop(c)
                error(" Directory");
 
        case S_IFREG:
                error(" Directory");
 
        case S_IFREG:
+               if (xflag)
+                       break;
                i = read(io, (char *) &magic, sizeof(magic));
                lseek(io, 0l, 0);
                if (i != sizeof(magic))
                i = read(io, (char *) &magic, sizeof(magic));
                lseek(io, 0l, 0);
                if (i != sizeof(magic))
@@ -462,7 +470,8 @@ bool dofname;       /* if 1 call filename, else use savedfile */
        switch (c) {
 
        case 0:
        switch (c) {
 
        case 0:
-               if (!exclam && !value(WRITEANY)) switch (edfile()) {
+               if (!exclam && (!value(WRITEANY) || value(READONLY)))
+               switch (edfile()) {
                
                case NOTEDF:
                        if (nonexist)
                
                case NOTEDF:
                        if (nonexist)
@@ -481,7 +490,14 @@ bool dofname;      /* if 1 call filename, else use savedfile */
                        close(io);
                        break;
 
                        close(io);
                        break;
 
+               case EDF:
+                       if (value(READONLY))
+                               error(" File is read only");
+                       break;
+
                case PARTBUF:
                case PARTBUF:
+                       if (value(READONLY))
+                               error(" File is read only");
                        error(" Use \"w!\" to write partial buffer");
                }
 cre:
                        error(" Use \"w!\" to write partial buffer");
                }
 cre:
@@ -539,318 +555,6 @@ edfile()
        return (addr1 == one && addr2 == dol ? EDF : PARTBUF);
 }
 
        return (addr1 == one && addr2 == dol ? EDF : PARTBUF);
 }
 
-/*
- * First part of a shell escape,
- * parse the line, expanding # and % and ! and printing if implied.
- */
-unix0(warn)
-       bool warn;
-{
-       register char *up, *fp;
-       register short c;
-       char printub, puxb[UXBSIZE + sizeof (int)];
-
-       printub = 0;
-       CP(puxb, uxb);
-       c = getchar();
-       if (c == '\n' || c == EOF)
-               error("Incomplete shell escape command@- use 'shell' to get a shell");
-       up = uxb;
-       do {
-               switch (c) {
-
-               case '\\':
-                       if (any(peekchar(), "%#!"))
-                               c = getchar();
-               default:
-                       if (up >= &uxb[UXBSIZE]) {
-tunix:
-                               uxb[0] = 0;
-                               error("Command too long");
-                       }
-                       *up++ = c;
-                       break;
-
-               case '!':
-                       fp = puxb;
-                       if (*fp == 0) {
-                               uxb[0] = 0;
-                               error("No previous command@to substitute for !");
-                       }
-                       printub++;
-                       while (*fp) {
-                               if (up >= &uxb[UXBSIZE])
-                                       goto tunix;
-                               *up++ = *fp++;
-                       }
-                       break;
-
-               case '#':
-                       fp = altfile;
-                       if (*fp == 0) {
-                               uxb[0] = 0;
-                               error("No alternate filename@to substitute for #");
-                       }
-                       goto uexp;
-
-               case '%':
-                       fp = savedfile;
-                       if (*fp == 0) {
-                               uxb[0] = 0;
-                               error("No filename@to substitute for %%");
-                       }
-uexp:
-                       printub++;
-                       while (*fp) {
-                               if (up >= &uxb[UXBSIZE])
-                                       goto tunix;
-                               *up++ = *fp++ | QUOTE;
-                       }
-                       break;
-               }
-               c = getchar();
-       } while (c == '|' || !endcmd(c));
-       if (c == EOF)
-               ungetchar(c);
-       *up = 0;
-       if (!inopen)
-               resetflav();
-       if (warn)
-               ckaw();
-       if (warn && hush == 0 && chng && xchng != chng && value(WARN) && dol > zero) {
-               xchng = chng;
-               vnfl();
-               printf(mesg("[No write]|[No write since last change]"));
-               noonl();
-               flush();
-       } else
-               warn = 0;
-       if (printub) {
-               if (uxb[0] == 0)
-                       error("No previous command@to repeat");
-               if (inopen) {
-                       splitw++;
-                       vclean();
-                       vgoto(WECHO, 0);
-               }
-               if (warn)
-                       vnfl();
-               if (hush == 0)
-                       lprintf("!%s", uxb);
-               if (inopen && Outchar != termchar) {
-                       vclreol();
-                       vgoto(WECHO, 0);
-               } else
-                       putnl();
-               flush();
-       }
-}
-
-/*
- * Do the real work for execution of a shell escape.
- * Mode is like the number passed to open system calls
- * and indicates filtering.  If input is implied, newstdin
- * must have been setup already.
- */
-unixex(opt, up, newstdin, mode)
-       char *opt, *up;
-       int newstdin, mode;
-{
-       int pvec[2], f;
-
-       signal(SIGINT, SIG_IGN);
-       if (inopen)
-               f = setty(normf);
-       if ((mode & 1) && pipe(pvec) < 0) {
-               /* Newstdin should be io so it will be closed */
-               if (inopen)
-                       setty(f);
-               error("Can't make pipe for filter");
-       }
-#ifndef VFORK
-       pid = fork();
-#else
-       pid = vfork();
-#endif
-       if (pid < 0) {
-               if (mode & 1) {
-                       close(pvec[0]);
-                       close(pvec[1]);
-               }
-               setrupt();
-               error("No more processes");
-       }
-       if (pid == 0) {
-               if (mode & 2) {
-                       close(0);
-                       dup(newstdin);
-                       close(newstdin);
-               }
-               if (mode & 1) {
-                       close(pvec[0]);
-                       close(1);
-                       dup(pvec[1]);
-                       if (inopen) {
-                               close(2);
-                               dup(1);
-                       }
-                       close(pvec[1]);
-               }
-               if (io)
-                       close(io);
-               if (tfile)
-                       close(tfile);
-#ifndef VMUNIX
-               close(erfile);
-#endif
-               signal(SIGHUP, oldhup);
-               signal(SIGQUIT, oldquit);
-               if (ruptible)
-                       signal(SIGINT, SIG_DFL);
-               execl(svalue(SHELL), "sh", opt, up, (char *) 0);
-               printf("No %s!\n", svalue(SHELL));
-               error(NOSTR);
-       }
-       if (mode & 1) {
-               io = pvec[0];
-               close(pvec[1]);
-       }
-       if (newstdin)
-               close(newstdin);
-       return (f);
-}
-
-/*
- * Wait for the command to complete.
- * F is for restoration of tty mode if from open/visual.
- * C flags suppression of printing.
- */
-unixwt(c, f)
-       bool c;
-       int f;
-{
-
-       waitfor();
-       if (inopen)
-               setty(f);
-       setrupt();
-       if (!inopen && c && hush == 0) {
-               printf("!\n");
-               flush();
-               termreset();
-               gettmode();
-       }
-}
-
-/*
- * Setup a pipeline for the filtration implied by mode
- * which is like a open number.  If input is required to
- * the filter, then a child editor is created to write it.
- * If output is catch it from io which is created by unixex.
- */
-filter(mode)
-       register int mode;
-{
-       static int pvec[2];
-       register int f;
-       register int lines = lineDOL();
-
-       mode++;
-       if (mode & 2) {
-               signal(SIGINT, SIG_IGN);
-               if (pipe(pvec) < 0)
-                       error("Can't make pipe");
-               pid = fork();
-               io = pvec[0];
-               if (pid < 0) {
-                       setrupt();
-                       close(pvec[1]);
-                       error("No more processes");
-               }
-               if (pid == 0) {
-                       setrupt();
-                       io = pvec[1];
-                       close(pvec[0]);
-                       putfile();
-                       exit(0);
-               }
-               close(pvec[1]);
-               io = pvec[0];
-               setrupt();
-       }
-       f = unixex("-c", uxb, (mode & 2) ? pvec[0] : 0, mode);
-       if (mode == 3) {
-               delete(0);
-               addr2 = addr1 - 1;
-       }
-       if (mode & 1) {
-               if(FIXUNDO)
-                       undap1 = undap2 = addr2+1;
-               ignore(append(getfile, addr2));
-       }
-       close(io);
-       io = -1;
-       unixwt(!inopen, f);
-       netchHAD(lines);
-}
-
-/*
- * Set up to do a recover, getting io to be a pipe from
- * the recover process.
- */
-recover()
-{
-       static int pvec[2];
-
-       if (pipe(pvec) < 0)
-               error(" Can't make pipe for recovery");
-       pid = fork();
-       io = pvec[0];
-       if (pid < 0) {
-               close(pvec[1]);
-               error(" Can't fork to execute recovery");
-       }
-       if (pid == 0) {
-               close(2);
-               dup(1);
-               close(1);
-               dup(pvec[1]);
-               close(pvec[1]);
-               execl(EXRECOVER, "exrecover", svalue(DIRECTORY), file, (char *) 0);
-               close(1);
-               dup(2);
-               error(" No recovery routine");
-       }
-       close(pvec[1]);
-}
-
-/*
- * Wait for the process (pid an external) to complete.
- */
-waitfor()
-{
-
-       do
-               rpid = wait(&status);
-       while (rpid != pid && rpid != -1);
-       status = (status >> 8) & 0377;
-}
-
-/*
- * The end of a recover operation.  If the process
- * exits non-zero, force not edited; otherwise force
- * a write.
- */
-revocer()
-{
-
-       waitfor();
-       if (pid == rpid && status != 0)
-               edited = 0;
-       else
-               change();
-}
-
 /*
  * Extract the next line from the io stream.
  */
 /*
  * Extract the next line from the io stream.
  */
@@ -868,12 +572,23 @@ getfile()
                        ninbuf = read(io, genbuf, LBSIZE) - 1;
                        if (ninbuf < 0) {
                                if (lp != linebuf) {
                        ninbuf = read(io, genbuf, LBSIZE) - 1;
                        if (ninbuf < 0) {
                                if (lp != linebuf) {
+                                       lp++;
                                        printf(" [Incomplete last line]");
                                        break;
                                }
                                return (EOF);
                        }
                        fp = genbuf;
                                        printf(" [Incomplete last line]");
                                        break;
                                }
                                return (EOF);
                        }
                        fp = genbuf;
+                       while(fp < &genbuf[ninbuf]) {
+                               if (*fp++ & 0200) {
+                                       if (kflag)
+                                               crblock(perm, genbuf, ninbuf+1,
+cntch);
+                                       break;
+                               }
+                       }
+                       fp = genbuf;
+                       cntch += ninbuf+1;
                }
                if (lp >= &linebuf[LBSIZE]) {
                        error(" Line too long");
                }
                if (lp >= &linebuf[LBSIZE]) {
                        error(" Line too long");
@@ -891,7 +606,6 @@ getfile()
                }
                *lp++ = c;
        } while (c != '\n');
                }
                *lp++ = c;
        } while (c != '\n');
-       cntch += lp - linebuf;
        *--lp = 0;
        nextip = fp;
        cntln++;
        *--lp = 0;
        nextip = fp;
        cntln++;
@@ -920,6 +634,8 @@ putfile()
                for (;;) {
                        if (--nib < 0) {
                                nib = fp - genbuf;
                for (;;) {
                        if (--nib < 0) {
                                nib = fp - genbuf;
+                               if(kflag)
+                                        crblock(perm, genbuf, nib, cntch);
                                if (write(io, genbuf, nib) != nib) {
                                        wrerror();
                                }
                                if (write(io, genbuf, nib) != nib) {
                                        wrerror();
                                }
@@ -934,6 +650,8 @@ putfile()
                }
        } while (a1 <= addr2);
        nib = fp - genbuf;
                }
        } while (a1 <= addr2);
        nib = fp - genbuf;
+       if(kflag)
+               crblock(perm, genbuf, nib, cntch);
        if (write(io, genbuf, nib) != nib) {
                wrerror();
        }
        if (write(io, genbuf, nib) != nib) {
                wrerror();
        }
@@ -957,7 +675,8 @@ wrerror()
  * Source command, handles nested sources.
  * Traps errors since it mungs unit 0 during the source.
  */
  * Source command, handles nested sources.
  * Traps errors since it mungs unit 0 during the source.
  */
-static short slevel;
+short slevel;
+short ttyindes;
 
 source(fil, okfail)
        char *fil;
 
 source(fil, okfail)
        char *fil;
@@ -965,12 +684,13 @@ source(fil, okfail)
 {
        jmp_buf osetexit;
        register int saveinp, ointty, oerrno;
 {
        jmp_buf osetexit;
        register int saveinp, ointty, oerrno;
-       int oprompt;
 
        signal(SIGINT, SIG_IGN);
        saveinp = dup(0);
        if (saveinp < 0)
                error("Too many nested sources");
 
        signal(SIGINT, SIG_IGN);
        saveinp = dup(0);
        if (saveinp < 0)
                error("Too many nested sources");
+       if (slevel <= 0)
+               ttyindes = saveinp;
        close(0);
        if (open(fil, 0) < 0) {
                oerrno = errno;
        close(0);
        if (open(fil, 0) < 0) {
                oerrno = errno;
index 033c05b..74fbb42 100644 (file)
@@ -194,12 +194,8 @@ slobber(c)
  * The output buffer is initialized with a useful error
  * message so we don't have to keep it in data space.
  */
  * The output buffer is initialized with a useful error
  * message so we don't have to keep it in data space.
  */
-static char linb[66] = {
-       'E', 'r', 'r', 'o', 'r', ' ', 'm', 'e', 's', 's', 'a', 'g', 'e', ' ',
-       'f', 'i', 'l', 'e', ' ', 'n', 'o', 't', ' ',
-       'a', 'v', 'a', 'i', 'l', 'a', 'b', 'l', 'e', '\n', 0
-};
-static char *linp = linb + 33;
+static char linb[66];
+static char *linp = linb;
 
 /*
  * Phadnl records when we have already had a complete line ending with \n.
 
 /*
  * Phadnl records when we have already had a complete line ending with \n.
@@ -344,8 +340,14 @@ fgoto()
                if (AM == 0) {
                        while (l > 0) {
                                if (pfast)
                if (AM == 0) {
                        while (l > 0) {
                                if (pfast)
-                                       putch('\r');
-                               putch('\n');
+                                       if (xCR)
+                                               tputs(xCR, 0, putch);
+                                       else
+                                               putch('\r');
+                               if (xNL)
+                                       tputs(xNL, 0, putch);
+                               else
+                                       putch('\n');
                                l--;
                        }
                        outcol = 0;
                                l--;
                        }
                        outcol = 0;
@@ -366,7 +368,28 @@ fgoto()
                        destcol = c;
                }
                while (l > LINES - 1) {
                        destcol = c;
                }
                while (l > LINES - 1) {
-                       putch('\n');
+                       /*
+                        * The following linefeed (or simulation thereof)
+                        * is supposed to scroll up the screen, since we
+                        * are on the bottom line.  We make the assumption
+                        * that linefeed will scroll.  If ns is in the
+                        * capability list this won't work.  We should
+                        * probably have an sc capability but sf will
+                        * generally take the place if it works.
+                        *
+                        * Superbee glitch:  in the middle of the screen we
+                        * have to use esc B (down) because linefeed screws up
+                        * in "Efficient Paging" (what a joke) mode (which is
+                        * essential in some SB's because CRLF mode puts garbage
+                        * in at end of memory), but you must use linefeed to
+                        * scroll since down arrow won't go past memory end.
+                        * I turned this off after recieving Paul Eggert's
+                        * Superbee description which wins better.
+                        */
+                       if (xNL /* && !XB */ && pfast)
+                               tputs(xNL, 0, putch);
+                       else
+                               putch('\n');
                        l--;
                        if (pfast == 0)
                                outcol = 0;
                        l--;
                        if (pfast == 0)
                                outcol = 0;
@@ -423,40 +446,74 @@ plod(cnt)
        plodcnt = plodflg = cnt;
        soutcol = outcol;
        soutline = outline;
        plodcnt = plodflg = cnt;
        soutcol = outcol;
        soutline = outline;
+       /*
+        * Consider homing and moving down/right from there, vs moving
+        * directly with local motions to the right spot.
+        */
        if (HO) {
        if (HO) {
+               /*
+                * i is the cost to home and tab/space to the right to
+                * get to the proper column.  This assumes ND space costs
+                * 1 char.  So i+destcol is cost of motion with home.
+                */
                if (GT)
                if (GT)
-               i = (destcol / value(HARDTABS)) + (destcol % value(HARDTABS));
+                       i = (destcol / value(HARDTABS)) + (destcol % value(HARDTABS));
                else
                        i = destcol;
                else
                        i = destcol;
-       if (destcol >= outcol) {
-               j = destcol / value(HARDTABS) - outcol / value(HARDTABS);
-               if (GT && j)
-                       j += destcol % value(HARDTABS);
+               /*
+                * j is cost to move locally without homing
+                */
+               if (destcol >= outcol) {        /* if motion is to the right */
+                       j = destcol / value(HARDTABS) - outcol / value(HARDTABS);
+                       if (GT && j)
+                               j += destcol % value(HARDTABS);
                        else
                                j = destcol - outcol;
                        else
                                j = destcol - outcol;
-       } else
+               } else
+                       /* leftward motion only works if we can backspace. */
                        if (outcol - destcol <= i && (BS || BC))
                        if (outcol - destcol <= i && (BS || BC))
-                               i = j = outcol - destcol;
+                               i = j = outcol - destcol; /* cheaper to backspace */
                        else
                        else
-                               j = i + 1;
+                               j = i + 1; /* impossibly expensive */
+
+               /* k is the absolute value of vertical distance */
                k = outline - destline;
                if (k < 0)
                        k = -k;
                j += k;
                k = outline - destline;
                if (k < 0)
                        k = -k;
                j += k;
-               if (i + destline < j) {
+
+               /*
+                * Decision.  We may not have a choice if no UP.
+                */
+               if (i + destline < j || (!UP && destline < outline)) {
+                       /*
+                        * Cheaper to home.  Do it now and pretend it's a
+                        * regular local motion.
+                        */
                        tputs(HO, 0, plodput);
                        outcol = outline = 0;
                } else if (LL) {
                        tputs(HO, 0, plodput);
                        outcol = outline = 0;
                } else if (LL) {
+                       /*
+                        * Quickly consider homing down and moving from there.
+                        * Assume cost of LL is 2.
+                        */
                        k = (LINES - 1) - destline;
                        k = (LINES - 1) - destline;
-                       if (i + k + 2 < j) {
+                       if (i + k + 2 < j && (k<=0 || UP)) {
                                tputs(LL, 0, plodput);
                                outcol = 0;
                                outline = LINES - 1;
                        }
                }
                                tputs(LL, 0, plodput);
                                outcol = 0;
                                outline = LINES - 1;
                        }
                }
-       }
+       } else
+       /*
+        * No home and no up means it's impossible, so we return an
+        * incredibly big number to make cursor motion win out.
+        */
+               if (!UP && destline < outline)
+                       return (500);
        if (GT)
        if (GT)
-       i = destcol % value(HARDTABS) + destcol / value(HARDTABS);
+               i = destcol % value(HARDTABS)
+                   + destcol / value(HARDTABS);
        else
                i = destcol;
 /*
        else
                i = destcol;
 /*
@@ -486,9 +543,19 @@ plod(cnt)
         * a return preliminarily.
         */
        if (j > i + 1 || outcol > destcol && !BS && !BC) {
         * a return preliminarily.
         */
        if (j > i + 1 || outcol > destcol && !BS && !BC) {
-               plodput('\r');
+               /*
+                * BUG: this doesn't take the (possibly long) length
+                * of xCR into account.
+                */
+               if (xCR)
+                       tputs(xCR, 0, plodput);
+               else
+                       plodput('\r');
                if (NC) {
                if (NC) {
-                       plodput('\n');
+                       if (xNL)
+                               tputs(xNL, 0, plodput);
+                       else
+                               plodput('\n');
                        outline++;
                }
                outcol = 0;
                        outline++;
                }
                outcol = 0;
@@ -496,7 +563,10 @@ plod(cnt)
 dontcr:
        while (outline < destline) {
                outline++;
 dontcr:
        while (outline < destline) {
                outline++;
-               plodput('\n');
+               if (xNL && pfast)
+                       tputs(xNL, 0, plodput);
+               else
+                       plodput('\n');
                if (plodcnt < 0)
                        goto out;
                if (NONL || pfast == 0)
                if (plodcnt < 0)
                        goto out;
                if (NONL || pfast == 0)
@@ -529,7 +599,7 @@ dontcr:
        }
        if (GT && !insmode && destcol - outcol > 1) {
        for (;;) {
        }
        if (GT && !insmode && destcol - outcol > 1) {
        for (;;) {
-               i = (outcol / value(HARDTABS) + 1) * value(HARDTABS);
+               i = tabcol(outcol, value(HARDTABS));
                if (i > destcol)
                        break;
                        if (TA)
                if (i > destcol)
                        break;
                        if (TA)
@@ -562,10 +632,6 @@ dontcr:
                 * a null or a tab we want to print a space.  Other random
                 * chars we use space for instead, too.
                 */
                 * a null or a tab we want to print a space.  Other random
                 * chars we use space for instead, too.
                 */
-#ifdef TRACE
-               if (trace)
-                       fprintf(trace, "ND: inopen=%d, i=%d, outline=%d, outcol=%d\n", inopen, i, outline, outcol);
-#endif
                if (!inopen || vtube[outline]==NULL ||
                        (i=vtube[outline][outcol]) < ' ')
                        i = ' ';
                if (!inopen || vtube[outline]==NULL ||
                        (i=vtube[outline][outcol]) < ' ')
                        i = ' ';
@@ -668,7 +734,7 @@ putch(c)
        int c;
 {
 
        int c;
 {
 
-       *obp++ = c;
+       *obp++ = c & 0177;
        if (obp >= &obuf[sizeof obuf])
                flusho();
 }
        if (obp >= &obuf[sizeof obuf])
                flusho();
 }
@@ -677,16 +743,6 @@ putch(c)
  * Miscellaneous routines related to output.
  */
 
  * Miscellaneous routines related to output.
  */
 
-/*
- * Cursor motion.
- */
-char *
-cgoto()
-{
-
-       return (tgoto(CM, destcol, destline));
-}
-
 /*
  * Put with padding
  */
 /*
  * Put with padding
  */
@@ -747,7 +803,13 @@ pstart()
        flusho();
        pfast = 1;
        normtty++;
        flusho();
        pfast = 1;
        normtty++;
+#ifndef USG3TTY
        tty.sg_flags = normf & ~(ECHO|XTABS|CRMOD);
        tty.sg_flags = normf & ~(ECHO|XTABS|CRMOD);
+#else
+       tty = normf;
+       tty.c_oflag &= ~(ONLCR|TAB3);
+       tty.c_lflag &= ~ECHO;
+#endif
        sTTY(1);
 }
 
        sTTY(1);
 }
 
@@ -769,42 +831,116 @@ pstop()
 /*
  * Prep tty for open mode.
  */
 /*
  * Prep tty for open mode.
  */
+ttymode
 ostart()
 {
 ostart()
 {
-       int f;
+       ttymode f;
 
        if (!intty)
                error("Open and visual must be used interactively");
        gTTY(1);
        normtty++;
 
        if (!intty)
                error("Open and visual must be used interactively");
        gTTY(1);
        normtty++;
+#ifndef USG3TTY
        f = tty.sg_flags;
        f = tty.sg_flags;
-#ifdef CBREAK
-       tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) | CBREAK;
+       tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) |
+# ifdef CBREAK
+                                                       CBREAK;
+# else
+                                                       RAW;
+# endif
+# ifdef TIOCGETC
+       ttcharoff();
+# endif
 #else
 #else
-       tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) | RAW;
-#endif
-#ifdef EATQS
-       nttyc.t_quitc = nttyc.t_startc = nttyc.t_stopc = '\377';
+       f = tty;
+       tty = normf;
+       tty.c_iflag &= ~ICRNL;
+       tty.c_lflag &= ~(ECHO|ICANON);
+       tty.c_oflag &= ~TAB3;
+       tty.c_cc[VMIN] = 1;
+       tty.c_cc[VTIME] = 1;
+       ttcharoff();
 #endif
        sTTY(1);
 #endif
        sTTY(1);
-       putpad(VS);
-       putpad(KS);
+       tostart();
        pfast |= 2;
        return (f);
 }
 
        pfast |= 2;
        return (f);
 }
 
+/* actions associated with putting the terminal in open mode */
+tostart()
+{
+       putpad(VS);
+       putpad(KS);
+       if (!value(MESG))
+               chmod(ttynbuf, 0611);   /* 11 = urgent only allowed */
+}
+
+/*
+ * Turn off start/stop chars if they aren't the default ^S/^Q.
+ * This is so idiots who make esc their start/stop don't lose.
+ * We always turn off quit since datamedias send ^\ for their
+ * right arrow key.
+ */
+#ifdef TIOCGETC
+ttcharoff()
+{
+       nttyc.t_quitc = '\377';
+       if (nttyc.t_startc != CTRL(q))
+               nttyc.t_startc = '\377';
+       if (nttyc.t_stopc != CTRL(s))
+               nttyc.t_stopc = '\377';
+# ifdef TIOCLGET
+       nlttyc.t_suspc = '\377';        /* ^Z */
+       nlttyc.t_dsuspc = '\377';       /* ^Y */
+       nlttyc.t_flushc = '\377';       /* ^O */
+       nlttyc.t_lnextc = '\377';       /* ^V */
+# endif
+}
+#endif
+
+#ifdef USG3TTY
+ttcharoff()
+{
+       tty.c_cc[VQUIT] = '\377';
+# ifdef VSTART
+       /*
+        * The following is sample code if USG ever lets people change
+        * their start/stop chars.  As long as they can't we can't get
+        * into trouble so we just leave them alone.
+        */
+       if (tty.c_cc[VSTART] != CTRL(q))
+               tty.c_cc[VSTART] = '\377';
+       if (tty.c_cc[VSTOP] != CTRL(s))
+               tty.c_cc[VSTOP] = '\377';
+# endif
+}
+#endif
+
 /*
  * Stop open, restoring tty modes.
  */
 ostop(f)
 /*
  * Stop open, restoring tty modes.
  */
 ostop(f)
-       int f;
+       ttymode f;
 {
 
 {
 
+#ifndef USG3TTY
        pfast = (f & CRMOD) == 0;
        pfast = (f & CRMOD) == 0;
+#else
+       pfast = (f.c_oflag & OCRNL) == 0;
+#endif
        termreset(), fgoto(), flusho();
        normal(f);
        termreset(), fgoto(), flusho();
        normal(f);
+       tostop();
+}
+
+/* Actions associated with putting the terminal in the right mode. */
+tostop()
+{
        putpad(VE);
        putpad(KE);
        putpad(VE);
        putpad(KE);
+       if (!value(MESG))
+               chmod(ttynbuf, ttymesg);
 }
 
 #ifndef CBREAK
 }
 
 #ifndef CBREAK
@@ -833,7 +969,7 @@ vraw()
  * Restore flags to normal state f.
  */
 normal(f)
  * Restore flags to normal state f.
  */
 normal(f)
-       int f;
+       ttymode f;
 {
 
        if (normtty > 0) {
 {
 
        if (normtty > 0) {
@@ -845,18 +981,31 @@ normal(f)
 /*
  * Straight set of flags to state f.
  */
 /*
  * Straight set of flags to state f.
  */
+ttymode
 setty(f)
 setty(f)
-       int f;
+       ttymode f;
 {
 {
+#ifndef USG3TTY
        register int ot = tty.sg_flags;
        register int ot = tty.sg_flags;
+#else
+       ttymode ot;
+       ot = tty;
+#endif
 
 
-#ifdef EATQS
-       if (f == normf)
+#ifndef USG3TTY
+       if (f == normf) {
                nttyc = ottyc;
                nttyc = ottyc;
-       else
-               nttyc.t_quitc = nttyc.t_startc = nttyc.t_stopc = '\377';
-#endif
+# ifdef TIOCLGET
+               nlttyc = olttyc;
+# endif
+       } else
+               ttcharoff();
        tty.sg_flags = f;
        tty.sg_flags = f;
+#else
+       if (tty.c_lflag & ICANON)
+               ttcharoff();
+       tty = f;
+#endif
        sTTY(1);
        return (ot);
 }
        sTTY(1);
        return (ot);
 }
@@ -864,32 +1013,63 @@ setty(f)
 gTTY(i)
        int i;
 {
 gTTY(i)
        int i;
 {
+       char *tn;
+       struct stat sbuf;
 
 
+#ifndef USG3TTY
        ignore(gtty(i, &tty));
        ignore(gtty(i, &tty));
-#ifdef EATQS
+# ifdef TIOCGETC
        ioctl(i, TIOCGETC, &ottyc);
        nttyc = ottyc;
        ioctl(i, TIOCGETC, &ottyc);
        nttyc = ottyc;
+# endif
+# ifdef TIOCLGET
+       ioctl(i, TIOCGLTC, &olttyc);
+       nlttyc = olttyc;
+# endif
+#else
+       ioctl(i, TCGETA, &tty);
 #endif
 #endif
+       if ((tn=ttyname(0)) == NULL && (tn=ttyname(1)) == NULL && (tn=ttyname(2)) == NULL)
+               tn = "/dev/tty";
+       strcpy(ttynbuf, tn);
+       stat(ttynbuf, &sbuf);
+       ttymesg = sbuf.st_mode & 0777;
 }
 
 }
 
+/*
+ * sTTY: set the tty modes on file descriptor i to be what's
+ * currently in global "tty".  (Also use nttyc if needed.)
+ */
 sTTY(i)
        int i;
 {
 
 sTTY(i)
        int i;
 {
 
-/*
- * Bug in USG tty driver, put out a null char as a patch.
- */
-#ifdef USG
-       if (tty.sg_ospeed == B1200)
-               write(1, "", 1);
-#endif
-#ifdef TIOCSETN
+#ifndef USG3TTY
+# ifdef USG
+       /* Bug in USG tty driver, put out a DEL as a patch. */
+       if (tty.sg_ospeed >= B1200)
+               write(1, "\377", 1);
+# endif
+
+# ifdef TIOCSETN
+       /* Don't flush typeahead if we don't have to */
        ioctl(i, TIOCSETN, &tty);
        ioctl(i, TIOCSETN, &tty);
-#else
+# else
+       /* We have to.  Too bad. */
        stty(i, &tty);
        stty(i, &tty);
-#endif
-#ifdef EATQS
+# endif
+
+# ifdef TIOCGETC
+       /* Update the other random chars while we're at it. */
        ioctl(i, TIOCSETC, &nttyc);
        ioctl(i, TIOCSETC, &nttyc);
+# endif
+# ifdef TIOCLGET
+       ioctl(i, TIOCSLTC, &nlttyc);
+# endif
+
+#else
+       /* USG 3 very simple: just set everything */
+       ioctl(i, TCSETAW, &tty);
 #endif
 }
 
 #endif
 }
 
@@ -901,3 +1081,39 @@ noonl()
 
        putchar(Outchar != termchar ? ' ' : '\n');
 }
 
        putchar(Outchar != termchar ? ' ' : '\n');
 }
+
+#ifdef TIOCLGET
+/*
+ * We have just gotten a susp.  Suspend and prepare to resume.
+ */
+onsusp()
+{
+       ttymode f;
+
+       f = setty(normf);
+       vnfl();
+       putpad(TE);
+       flush();
+
+       signal(SIGTSTP, SIG_DFL);
+       kill(0, SIGTSTP);
+
+       /* the pc stops here */
+
+       signal(SIGTSTP, onsusp);
+       vcontin(0);
+       setty(f);
+       if (!inopen)
+               error(0);
+       else {
+               if (vcnt < 0) {
+                       vcnt = -vcnt;
+                       if (state == VISUAL)
+                               vclear();
+                       else if (state == CRTOPEN)
+                               vcnt = 0;
+               }
+               vdirty(0, LINES);
+               vrepaint(cursor);
+       }
+}
index cf06929..c2b21d3 100644 (file)
@@ -104,7 +104,7 @@ out:
        }
 }
 
        }
 }
 
-bool   xflag;
+bool   cflag;
 int    scount, slines, stotal;
 
 substitute(c)
 int    scount, slines, stotal;
 
 substitute(c)
@@ -145,7 +145,7 @@ substitute(c)
                        addr2 += n;
                }
        }
                        addr2 += n;
                }
        }
-       if (stotal == 0 && !inglobal && !xflag)
+       if (stotal == 0 && !inglobal && !cflag)
                error("Fail|Substitute pattern match failed");
        snote(stotal, slines);
        return (stotal);
                error("Fail|Substitute pattern match failed");
        snote(stotal, slines);
        return (stotal);
@@ -157,7 +157,7 @@ compsub(ch)
        static int gsubf;
 
        if (!value(EDCOMPATIBLE))
        static int gsubf;
 
        if (!value(EDCOMPATIBLE))
-               gsubf = xflag = 0;
+               gsubf = cflag = 0;
        uselastre = 0;
        switch (ch) {
 
        uselastre = 0;
        switch (ch) {
 
@@ -174,7 +174,7 @@ compsub(ch)
                uselastre = 1;
                comprhs(seof);
                gsubf = 0;
                uselastre = 1;
                comprhs(seof);
                gsubf = 0;
-               xflag = 0;
+               cflag = 0;
                break;
 
        case '~':
                break;
 
        case '~':
@@ -184,6 +184,8 @@ compsub(ch)
        redo:
                if (re.Expbuf[0] == 0)
                        error("No previous re|No previous regular expression");
        redo:
                if (re.Expbuf[0] == 0)
                        error("No previous re|No previous regular expression");
+               if (subre.Expbuf[0] == 0)
+                       error("No previous substitute re|No previous substitute to repeat");
                break;
        }
        for (;;) {
                break;
        }
        for (;;) {
@@ -195,7 +197,7 @@ compsub(ch)
                        continue;
 
                case 'c':
                        continue;
 
                case 'c':
-                       xflag = !xflag;
+                       cflag = !cflag;
                        continue;
 
                case 'r':
                        continue;
 
                case 'r':
@@ -307,7 +309,7 @@ confirmed(a)
 {
        register int c, ch;
 
 {
        register int c, ch;
 
-       if (xflag == 0)
+       if (cflag == 0)
                return (1);
        pofix();
        pline(lineno(a));
                return (1);
        pofix();
        pline(lineno(a));
@@ -522,7 +524,7 @@ complex:
                if (c == eof || c == EOF) {
                        if (bracketp != bracket)
 cerror("Unmatched \\(|More \\('s than \\)'s in regular expression");
                if (c == eof || c == EOF) {
                        if (bracketp != bracket)
 cerror("Unmatched \\(|More \\('s than \\)'s in regular expression");
-                       *ep++ = CEOF;
+                       *ep++ = CEOFC;
                        if (c == EOF)
                                ungetchar(c);
                        return (eof);
                        if (c == EOF)
                                ungetchar(c);
                        return (eof);
@@ -647,7 +649,7 @@ cerror("Bad \\n|\\n in regular expression with n greater than the number of \\('
                case '\n':
                        if (oknl) {
                                ungetchar(c);
                case '\n':
                        if (oknl) {
                                ungetchar(c);
-                               *ep++ = CEOF;
+                               *ep++ = CEOFC;
                                return (eof);
                        }
 cerror("Badly formed re|Missing closing delimiter for regular expression");
                                return (eof);
                        }
 cerror("Badly formed re|Missing closing delimiter for regular expression");
@@ -701,10 +703,6 @@ execute(gf, addr)
        if (gf) {
                if (circfl)
                        return (0);
        if (gf) {
                if (circfl)
                        return (0);
-#ifdef notdef
-               if (loc1 == loc2)
-                       loc2++;
-#endif
                locs = p1 = loc2;
        } else {
                if (addr == zero)
                locs = p1 = loc2;
        } else {
                if (addr == zero)
@@ -783,7 +781,7 @@ advance(lp, ep)
                        continue;
                return (0);
 
                        continue;
                return (0);
 
-       case CEOF:
+       case CEOFC:
                loc2 = lp;
                return (1);
 
                loc2 = lp;
                return (1);
 
index 500d5d5..e1bb3b4 100644 (file)
@@ -59,7 +59,7 @@ char  rhsbuf[RHSSIZE];        /* Rhs of last substitute */
 #define        CCL     8
 #define        NCCL    12
 #define        CDOL    16
 #define        CCL     8
 #define        NCCL    12
 #define        CDOL    16
-#define        CEOF    17
+#define        CEOFC   17
 #define        CKET    18
 #define        CCHR    20
 #define        CBRC    24
 #define        CKET    18
 #define        CCHR    20
 #define        CBRC    24
index bb7f2d8..0939742 100644 (file)
@@ -74,6 +74,8 @@ printone:
                }
                if (op->otype == ONOFF) {
                        op->ovalue = 1 - no;
                }
                if (op->otype == ONOFF) {
                        op->ovalue = 1 - no;
+                       if (op == &options[PROMPT])
+                               oprompt = 1 - no;
                        goto next;
                }
                if (no)
                        goto next;
                }
                if (no)
index babd233..c77e5fc 100644 (file)
@@ -56,6 +56,21 @@ column(cp)
        return (qcolumn(cp, (char *) 0));
 }
 
        return (qcolumn(cp, (char *) 0));
 }
 
+/*
+ * Ignore a comment to the end of the line.
+ * This routine eats the trailing newline so don't call newline().
+ */
+comment()
+{
+       register int c;
+
+       do {
+               c = getchar();
+       } while (c != '\n' && c != EOF);
+       if (c == EOF)
+               ungetchar(c);
+}
+
 Copy(to, from, size)
        register char *from, *to;
        register int size;
 Copy(to, from, size)
        register char *from, *to;
        register int size;
@@ -179,6 +194,8 @@ ignnEOF()
 
        if (c == EOF)
                ungetchar(c);
 
        if (c == EOF)
                ungetchar(c);
+       else if (c=='"')
+               comment();
 }
 
 iswhite(c)
 }
 
 iswhite(c)
@@ -437,13 +454,15 @@ putmk1(addr, n)
        int n;
 {
        register line *markp;
        int n;
 {
        register line *markp;
+       register oldglobmk;
 
 
+       oldglobmk = *addr & 1;
        *addr &= ~1;
        for (markp = (anymarks ? names : &names['z'-'a'+1]);
          markp <= &names['z'-'a'+1]; markp++)
                if (*markp == *addr)
                        *markp = n;
        *addr &= ~1;
        for (markp = (anymarks ? names : &names['z'-'a'+1]);
          markp <= &names['z'-'a'+1]; markp++)
                if (*markp == *addr)
                        *markp = n;
-       *addr = n;
+       *addr = n | oldglobmk;
 }
 
 char *
 }
 
 char *
@@ -684,6 +703,25 @@ syserror()
                error("System error %d", e);
 }
 
                error("System error %d", e);
 }
 
+/*
+ * Return the column number that results from being in column col and
+ * hitting a tab, where tabs are set every ts columns.  Work right for
+ * the case where col > COLUMNS, even if ts does not divide COLUMNS.
+ */
+tabcol(col, ts)
+int col, ts;
+{
+       int offset, result;
+
+       if (col >= COLUMNS) {
+               offset = COLUMNS * (col/COLUMNS);
+               col -= offset;
+       } else
+               offset = 0;
+       result = col + ts - (col % ts) + offset;
+       return (result);
+}
+
 char *
 vfindcol(i)
        int i;
 char *
 vfindcol(i)
        int i;
@@ -767,4 +805,3 @@ markit(addr)
        if (addr != dot && addr >= one && addr <= dol)
                markDOT();
 }
        if (addr != dot && addr >= one && addr <= dol)
                markDOT();
 }
-
index 3f4bc5a..597d881 100644 (file)
@@ -137,6 +137,8 @@ getblock(atl, iof)
        int iof;
 {
        register int bno, off;
        int iof;
 {
        register int bno, off;
+        register char *p1, *p2;
+        register int n;
        
        bno = (atl >> OFFBTS) & BLKMSK;
        off = (atl << SHFT) & LBTMSK;
        
        bno = (atl >> OFFBTS) & BLKMSK;
        off = (atl << SHFT) & LBTMSK;
@@ -157,24 +159,48 @@ getblock(atl, iof)
                return (obuff + off);
        if (iof == READ) {
                if (hitin2 == 0) {
                return (obuff + off);
        if (iof == READ) {
                if (hitin2 == 0) {
-                       if (ichang2)
+                       if (ichang2) {
+                               if(xtflag)
+                                       crblock(tperm, ibuff2, CRSIZE, (long)0);
                                blkio(iblock2, ibuff2, write);
                                blkio(iblock2, ibuff2, write);
+                       }
                        ichang2 = 0;
                        iblock2 = bno;
                        blkio(bno, ibuff2, read);
                        ichang2 = 0;
                        iblock2 = bno;
                        blkio(bno, ibuff2, read);
+                       if(xtflag)
+                               crblock(tperm, ibuff2, CRSIZE, (long)0);
                        hitin2 = 1;
                        return (ibuff2 + off);
                }
                hitin2 = 0;
                        hitin2 = 1;
                        return (ibuff2 + off);
                }
                hitin2 = 0;
-               if (ichanged)
+               if (ichanged) {
+                       if(xtflag)
+                               crblock(tperm, ibuff, CRSIZE, (long)0);
                        blkio(iblock, ibuff, write);
                        blkio(iblock, ibuff, write);
+               }
                ichanged = 0;
                iblock = bno;
                blkio(bno, ibuff, read);
                ichanged = 0;
                iblock = bno;
                blkio(bno, ibuff, read);
+               if(xtflag)
+                       crblock(tperm, ibuff, CRSIZE, (long)0);
                return (ibuff + off);
        }
                return (ibuff + off);
        }
-       if (oblock >= 0)
-               blkio(oblock, obuff, write);
+       if (oblock >= 0) {
+               if(xtflag) {
+                       /*
+                        * Encrypt block before writing, so some devious
+                        * person can't look at temp file while editing.
+                        */
+                       p1 = obuff;
+                       p2 = crbuf;
+                       n = CRSIZE;
+                       while(n--)
+                               *p2++ = *p1++;
+                       crblock(tperm, crbuf, CRSIZE, (long)0);
+                       blkio(oblock, crbuf, write);
+               } else
+                       blkio(oblock, obuff, write);
+       }
        oblock = bno;
        return (obuff + off);
 }
        oblock = bno;
        return (obuff + off);
 }
@@ -217,6 +243,8 @@ synctmp()
                if (*bp < 0) {
                        tline = (tline + OFFMSK) &~ OFFMSK;
                        *bp = ((tline >> OFFBTS) & BLKMSK);
                if (*bp < 0) {
                        tline = (tline + OFFMSK) &~ OFFMSK;
                        *bp = ((tline >> OFFBTS) & BLKMSK);
+                       if (*bp > NMBLKS)
+                               error(" Tmp file too large");
                        tline += INCRMT;
                        oblock = *bp + 1;
                        bp[1] = -1;
                        tline += INCRMT;
                        oblock = *bp + 1;
                        bp[1] = -1;
@@ -573,3 +601,147 @@ int buflen;
        *p = '\0';
        getDOT();
 }
        *p = '\0';
        getDOT();
 }
+
+/*
+ * Encryption routines.  These are essentially unmodified from ed.
+ */
+
+/*
+ * crblock: encrypt/decrypt a block of text.
+ * buf is the buffer through which the text is both input and
+ * output. nchar is the size of the buffer. permp is a work
+ * buffer, and startn is the beginning of a sequence.
+ */
+crblock(permp, buf, nchar, startn)
+char *permp;
+char *buf;
+int nchar;
+long startn;
+{
+       register char *p1;
+       int n1;
+       int n2;
+       register char *t1, *t2, *t3;
+
+       t1 = permp;
+       t2 = &permp[256];
+       t3 = &permp[512];
+
+       n1 = startn&0377;
+       n2 = (startn>>8)&0377;
+       p1 = buf;
+       while(nchar--) {
+               *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
+               n1++;
+               if(n1==256){
+                       n1 = 0;
+                       n2++;
+                       if(n2==256) n2 = 0;
+               }
+               p1++;
+       }
+}
+
+/*
+ * makekey: initialize buffers based on user key a.
+ */
+makekey(a, b)
+char *a, *b;
+{
+       register int i;
+       long t;
+       char temp[KSIZE + 1];
+
+       for(i = 0; i < KSIZE; i++)
+               temp[i] = *a++;
+       time(&t);
+       t += getpid();
+       for(i = 0; i < 4; i++)
+               temp[i] ^= (t>>(8*i))&0377;
+       crinit(temp, b);
+}
+
+/*
+ * crinit: besides initializing the encryption machine, this routine
+ * returns 0 if the key is null, and 1 if it is non-null.
+ */
+crinit(keyp, permp)
+char    *keyp, *permp;
+{
+       register char *t1, *t2, *t3;
+       register i;
+       int ic, k, temp;
+       unsigned random;
+       char buf[13];
+       long seed;
+
+       t1 = permp;
+       t2 = &permp[256];
+       t3 = &permp[512];
+       if(*keyp == 0)
+               return(0);
+       strncpy(buf, keyp, 8);
+       while (*keyp)
+               *keyp++ = '\0';
+
+       buf[8] = buf[0];
+       buf[9] = buf[1];
+       domakekey(buf);
+
+       seed = 123;
+       for (i=0; i<13; i++)
+               seed = seed*buf[i] + i;
+       for(i=0;i<256;i++){
+               t1[i] = i;
+               t3[i] = 0;
+       }
+       for(i=0; i<256; i++) {
+               seed = 5*seed + buf[i%13];
+               random = seed % 65521;
+               k = 256-1 - i;
+               ic = (random&0377) % (k+1);
+               random >>= 8;
+               temp = t1[k];
+               t1[k] = t1[ic];
+               t1[ic] = temp;
+               if(t3[k]!=0) continue;
+               ic = (random&0377) % k;
+               while(t3[ic]!=0) ic = (ic+1) % k;
+               t3[k] = ic;
+               t3[ic] = k;
+       }
+       for(i=0; i<256; i++)
+               t2[t1[i]&0377] = i;
+       return(1);
+}
+
+/*
+ * domakekey: the following is the major nonportable part of the encryption
+ * mechanism. A 10 character key is supplied in buffer.
+ * This string is fed to makekey (an external program) which
+ * responds with a 13 character result. This result is placed
+ * in buffer.
+ */
+domakekey(buffer)
+char *buffer;
+{
+       int pf[2];
+
+       if (pipe(pf)<0)
+               pf[0] = pf[1] = -1;
+       if (fork()==0) {
+               close(0);
+               close(1);
+               dup(pf[0]);
+               dup(pf[1]);
+               execl("/usr/lib/makekey", "-", 0);
+               execl("/lib/makekey", "-", 0);
+               exit(1);
+       }
+       write(pf[1], buffer, 10);
+       if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13)
+               error("crypt: cannot generate key");
+       close(pf[0]);
+       close(pf[1]);
+       /* end of nonportable part */
+}
index 6085348..99b14e7 100644 (file)
@@ -12,6 +12,7 @@ short ospeed = -1;
 gettmode()
 {
 
 gettmode()
 {
 
+#ifndef USG3TTY
        if (gtty(1, &tty) < 0)
                return;
        if (ospeed != tty.sg_ospeed)
        if (gtty(1, &tty) < 0)
                return;
        if (ospeed != tty.sg_ospeed)
@@ -21,17 +22,29 @@ gettmode()
        UPPERCASE = (tty.sg_flags & LCASE) != 0;
        GT = (tty.sg_flags & XTABS) != XTABS && !XT;
        NONL = (tty.sg_flags & CRMOD) == 0;
        UPPERCASE = (tty.sg_flags & LCASE) != 0;
        GT = (tty.sg_flags & XTABS) != XTABS && !XT;
        NONL = (tty.sg_flags & CRMOD) == 0;
+#else
+       if (ioctl(1, TCGETA, &tty) < 0)
+               return;
+       if (ospeed != tty.c_cflag & CBAUD)
+               value(SLOWOPEN) = (tty.c_cflag & CBAUD) < B1200;
+       ospeed = tty.c_cflag & CBAUD;
+       normf = tty;
+       UPPERCASE = (tty.c_iflag & IUCLC) != 0;
+       GT = (tty.c_oflag & TABDLY) != TAB3 && !XT;
+       NONL = (tty.c_oflag & OCRNL) == 0;
+#endif
 }
 
 char *xPC;
 char **sstrs[] = {
 }
 
 char *xPC;
 char **sstrs[] = {
-       &AL, &BC, &BT, &CD, &CE, &CL, &CM, &DC, &DL, &DM, &DO, &ED, &EI,
+       &AL, &BC, &BT, &CD, &CE, &CL, &CM, &xCR, &DC, &DL, &DM, &DO, &ED, &EI,
        &F0, &F1, &F2, &F3, &F4, &F5, &F6, &F7, &F8, &F9,
        &HO, &IC, &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, &LL,
        &F0, &F1, &F2, &F3, &F4, &F5, &F6, &F7, &F8, &F9,
        &HO, &IC, &IM, &IP, &KD, &KE, &KH, &KL, &KR, &KS, &KU, &LL,
-       &ND, &xPC, &SE, &SF, &SO, &SR, &TA, &TE, &TI, &UP, &VB, &VS, &VE
+       &ND, &xNL, &xPC, &SE, &SF, &SO, &SR, &TA, &TE, &TI, &UP, &VB, &VS, &VE
 };
 bool *sflags[] = {
 };
 bool *sflags[] = {
-       &AM, &BS, &DA, &DB, &EO, &HC, &HZ, &IN, &MI, &NC, &OS, &UL, &XN, &XT
+       &AM, &BS, &DA, &DB, &EO, &HC, &HZ, &IN, &MI, &NC, &NS, &OS, &UL,
+       &XB, &XN, &XT, &XX
 };
 char **fkeys[10] = {
        &F0, &F1, &F2, &F3, &F4, &F5, &F6, &F7, &F8, &F9
 };
 char **fkeys[10] = {
        &F0, &F1, &F2, &F3, &F4, &F5, &F6, &F7, &F8, &F9
@@ -39,7 +52,7 @@ char **fkeys[10] = {
 setterm(type)
        char *type;
 {
 setterm(type)
        char *type;
 {
-       char *cgoto();
+       char *tgoto();
        register int unknown, i;
        register int l;
        char ltcbuf[TCBUFSIZE];
        register int unknown, i;
        register int l;
        char ltcbuf[TCBUFSIZE];
@@ -73,13 +86,36 @@ setterm(type)
        arrows[3].cap = KR; arrows[3].mapto = "l"; arrows[3].descr = "right";
        arrows[4].cap = KH; arrows[4].mapto = "H"; arrows[4].descr = "home";
 
        arrows[3].cap = KR; arrows[3].mapto = "l"; arrows[3].descr = "right";
        arrows[4].cap = KH; arrows[4].mapto = "H"; arrows[4].descr = "home";
 
+#ifdef TIOCLGET
+       /*
+        * Now map users susp char to ^Z, being careful that the susp
+        * overrides any arrow key, but only for hackers (=new tty driver).
+        */
+       {
+               static char sc[2];
+               int i, fnd;
+
+               ioctl(0, TIOCGETD, &ldisc);
+               if (ldisc == NTTYDISC) {
+                       sc[0] = olttyc.t_suspc;
+                       sc[1] = 0;
+                       if (olttyc.t_suspc == CTRL(z)) {
+                               for (i=0; i<=4; i++)
+                                       if (arrows[i].cap[0] == CTRL(z))
+                                               addmac(sc, NULL, NULL, arrows);
+                       } else
+                               addmac(sc, "\32", "susp", arrows);
+               }
+       }
+#endif
+
        options[WINDOW].ovalue = options[WINDOW].odefault = l - 1;
        if (defwind) options[WINDOW].ovalue = defwind;
        options[SCROLL].ovalue = options[SCROLL].odefault = HC ? 11 : ((l-1) / 2);
        COLUMNS = tgetnum("co");
        options[WINDOW].ovalue = options[WINDOW].odefault = l - 1;
        if (defwind) options[WINDOW].ovalue = defwind;
        options[SCROLL].ovalue = options[SCROLL].odefault = HC ? 11 : ((l-1) / 2);
        COLUMNS = tgetnum("co");
-       if (COLUMNS <= 20)
+       if (COLUMNS <= 4)
                COLUMNS = 1000;
                COLUMNS = 1000;
-       if (cgoto()[0] == 'O')  /* OOPS */
+       if (tgoto(CM, 2, 2)[0] == 'O')  /* OOPS */
                CA = 0, CM = 0;
        else
                CA = 1, costCM = strlen(tgoto(CM, 8, 10));
                CA = 0, CM = 0;
        else
                CA = 1, costCM = strlen(tgoto(CM, 8, 10));
@@ -89,11 +125,6 @@ setterm(type)
        if (i <= 0)
                LINES = 2;
        /* proper strings to change tty type */
        if (i <= 0)
                LINES = 2;
        /* proper strings to change tty type */
-#ifdef notdef
-       /* Taken out because we don't allow it. See ex_set.c for reasons. */
-       if (inopen)
-               putpad(VE);
-#endif
        termreset();
        gettmode();
        value(REDRAW) = AL && DL;
        termreset();
        gettmode();
        value(REDRAW) = AL && DL;
@@ -108,13 +139,13 @@ zap()
        register bool **fp;
        register char ***sp;
 
        register bool **fp;
        register char ***sp;
 
-       namp = "ambsdadbeohchzinmincosulxnxt";
+       namp = "ambsdadbeohchzinmincnsosulxbxnxtxx";
        fp = sflags;
        do {
                *(*fp++) = tgetflag(namp);
                namp += 2;
        } while (*namp);
        fp = sflags;
        do {
                *(*fp++) = tgetflag(namp);
                namp += 2;
        } while (*namp);
-       namp = "albcbtcdceclcmdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullndpcsesfsosrtatetiupvbvsve";
+       namp = "albcbtcdceclcmcrdcdldmdoedeik0k1k2k3k4k5k6k7k8k9hoicimipkdkekhklkrkskullndnlpcsesfsosrtatetiupvbvsve";
        sp = sstrs;
        do {
                *(*sp++) = tgetstr(namp, &aoftspace);
        sp = sstrs;
        do {
                *(*sp++) = tgetstr(namp, &aoftspace);
index a4c6962..522421f 100644 (file)
@@ -35,6 +35,7 @@ char  *CD;                    /* P* Clear to end of display */
 char   *CE;                    /* P  Clear to end of line */
 char   *CL;                    /* P* Clear screen */
 char   *CM;                    /* P  Cursor motion */
 char   *CE;                    /* P  Clear to end of line */
 char   *CL;                    /* P* Clear screen */
 char   *CM;                    /* P  Cursor motion */
+char   *xCR;                   /* P  Carriage return */
 char   *DC;                    /* P* Delete character */
 char   *DL;                    /* P* Delete line sequence */
 char   *DM;                    /*    Delete mode (enter)  */
 char   *DC;                    /* P* Delete character */
 char   *DL;                    /* P* Delete line sequence */
 char   *DM;                    /*    Delete mode (enter)  */
@@ -56,6 +57,7 @@ char  *KS;                    /*    Keypad start xmitting */
 char   *KU;                    /*    Keypad up arrow */
 char   *LL;                    /*    Quick to last line, column 0 */
 char   *ND;                    /*    Non-destructive space */
 char   *KU;                    /*    Keypad up arrow */
 char   *LL;                    /*    Quick to last line, column 0 */
 char   *ND;                    /*    Non-destructive space */
+char   *xNL;                   /*    Line feed (new line) */
 char   PC;                     /*    Pad character */
 char   *SE;                    /*    Standout end (may leave space) */
 char   *SF;                    /* P  Scroll forwards */
 char   PC;                     /*    Pad character */
 char   *SE;                    /*    Standout end (may leave space) */
 char   *SF;                    /* P  Scroll forwards */
@@ -80,10 +82,13 @@ bool        HZ;                     /* Hazeltine ~ braindamage */
 bool   IN;                     /* Insert-null blessing */
 bool   MI;                     /* can move in insert mode */
 bool   NC;                     /* No Cr - \r snds \r\n then eats \n (dm2500) */
 bool   IN;                     /* Insert-null blessing */
 bool   MI;                     /* can move in insert mode */
 bool   NC;                     /* No Cr - \r snds \r\n then eats \n (dm2500) */
+bool   NS;                     /* No scroll - linefeed at bottom won't scroll */
 bool   OS;                     /* Overstrike works */
 bool   UL;                     /* Underlining works even though !os */
 bool   OS;                     /* Overstrike works */
 bool   UL;                     /* Underlining works even though !os */
+bool   XB;                     /* Beehive (no escape key, simulate with f1) */
 bool   XN;                     /* A newline gets eaten after wrap (concept) */
 bool   XT;                     /* Tabs are destructive */
 bool   XN;                     /* A newline gets eaten after wrap (concept) */
 bool   XT;                     /* Tabs are destructive */
+bool   XX;                     /* Tektronix 4025 insert line */
        /* X? is reserved for severely nauseous glitches */
        /* If there are enough of these we may need bit masks! */
 
        /* X? is reserved for severely nauseous glitches */
        /* If there are enough of these we may need bit masks! */
 
@@ -102,12 +107,42 @@ short     outline;
 short  destcol;                /* Where the cursor should be */
 short  destline;
 
 short  destcol;                /* Where the cursor should be */
 short  destline;
 
-#ifdef         TIOCSETC
-struct tchars ottyc, nttyc;    /* For V7 character masking */
+/*
+ * There are several kinds of tty drivers to contend with.  These include:
+ * (1) V6:             no CBREAK, no ioctl.  (Include PWB V1 here).
+ * (2) V7 research:    has CBREAK, has ioctl, and has the tchars (TIOCSETC)
+ *                     business to change start, stop, etc. chars.
+ * (3) USG V2:         Basically like V6 but RAW mode is like V7 RAW.
+ *                     (We treat it as V6.)
+ * (4) USG V3:         equivalent to V7 but totally incompatible.
+ * (5)  Berkeley:      has ltchars in addition to all of V7.
+ *
+ * The following attempts to decide what we are on, and declare
+ * some variables in the appropriate format.  The wierd looking one (ttymode)
+ * is the thing we pass to sTTY and family to turn "RAW" mode on or off
+ * when we go into or out of visual mode.  In V7/V6 it's just the flags word
+ * to stty.  In USG V3 it's the whole tty structure.
+ */
+#ifdef USG3TTY                 /* USG V3 */
+  struct       termio tty;     /* Use this one structure to change modes */
+  typedef      struct termio ttymode;  /* Mode to contain tty flags */
+
+#else                          /* All others */
+  struct       sgttyb tty;     /* Always stty/gtty using this one structure */
+  typedef      int ttymode;    /* Mode to contain tty flags */
+# ifdef        TIOCSETC        /* V7 */
+   struct      tchars ottyc, nttyc;    /* For V7 character masking */
+# endif
+# ifdef                TIOCLGET        /* Berkeley */
+   struct      ltchars olttyc, nlttyc; /* More of tchars style stuff */
+# endif
+
 #endif
 #endif
-struct sgttyb tty;             /* Always stty/gtty using this one structure */
-bool   normtty;                /* Have to restor normal mode from normf */
-int    normf;                  /* Restore tty flags to this (someday) */
+
+ttymode        normf;                  /* Restore tty flags to this (someday) */
+bool   normtty;                /* Have to restore normal mode from normf */
+
+ttymode ostart(), setty(), unixex();
 
 short  WBOT;
 short  WECHO;
 
 short  WBOT;
 short  WECHO;
@@ -128,5 +163,11 @@ struct maps {
 };
 struct maps arrows[MAXNOMACS]; /* macro defs - 1st 5 built in */
 struct maps immacs[MAXNOMACS]; /* for while in insert mode */
 };
 struct maps arrows[MAXNOMACS]; /* macro defs - 1st 5 built in */
 struct maps immacs[MAXNOMACS]; /* for while in insert mode */
+struct maps abbrevs[MAXNOMACS];        /* for word abbreviations */
+int    ldisc;                  /* line discipline for ucb tty driver */
 char   mapspace[MAXCHARMACS];
 char   *msnext;        /* next free location in mapspace */
 char   mapspace[MAXCHARMACS];
 char   *msnext;        /* next free location in mapspace */
+int    maphopcnt;      /* check for infinite mapping loops */
+bool   anyabbrs;       /* true if abbr or unabbr has been done */
+char   ttynbuf[20];    /* result of ttyname() */
+int    ttymesg;        /* original mode of users tty */
index ddb0869..79dde46 100644 (file)
  * "/usr/lib/..." here, "/lib" will be tried only for strings.
  */
 #include "local/uparm.h"
  * "/usr/lib/..." here, "/lib" will be tried only for strings.
  */
 #include "local/uparm.h"
-#define        EXRECOVER       libpath(ex3.3recover)
-#define        EXPRESERVE      libpath(ex3.3preserve)
+#define        EXRECOVER       libpath(ex3.4recover)
+#define        EXPRESERVE      libpath(ex3.4preserve)
 #ifndef VMUNIX
 #ifndef VMUNIX
-#define        EXSTRINGS       libpath(ex3.3strings)
+#define        EXSTRINGS       libpath(ex3.4strings)
 #endif
 
 /*
 #endif
 
 /*
 #ifdef VMUNIX
 #define        LBSIZE          1024
 #define        ESIZE           512
 #ifdef VMUNIX
 #define        LBSIZE          1024
 #define        ESIZE           512
+#define CRSIZE         1024
 #else
 #define        LBSIZE          512             /* Line length */
 #define        ESIZE           128             /* Size of compiled re */
 #else
 #define        LBSIZE          512             /* Line length */
 #define        ESIZE           128             /* Size of compiled re */
+#define CRSIZE         512
 #endif
 #define        RHSSIZE         256             /* Size of rhs of substitute */
 #define        NBRA            9               /* Number of re \( \) pairs */
 #endif
 #define        RHSSIZE         256             /* Size of rhs of substitute */
 #define        NBRA            9               /* Number of re \( \) pairs */
  * Attention is the interrupt character (normally 0177 -- delete).
  * Quit is the quit signal (normally FS -- control-\) and quits open/visual.
  */
  * Attention is the interrupt character (normally 0177 -- delete).
  * Quit is the quit signal (normally FS -- control-\) and quits open/visual.
  */
-#define        ATTN    0177
+#define        ATTN    (-2)
 #define        QUIT    ('\\' & 037)
 #define        QUIT    ('\\' & 037)
index 0f8afc4..00ef0fa 100644 (file)
@@ -53,7 +53,7 @@ oop()
 {
        register char *ic;
        char atube[TUBESIZE + LBSIZE];
 {
        register char *ic;
        char atube[TUBESIZE + LBSIZE];
-       register int f;
+       register ttymode f;
 
        ovbeg();
        if (peekchar() == '/') {
 
        ovbeg();
        if (peekchar() == '/') {
@@ -128,7 +128,7 @@ ovbeg()
 }
 
 ovend(f)
 }
 
 ovend(f)
-       int f;
+       ttymode f;
 {
 
        splitw++;
 {
 
        splitw++;
@@ -153,7 +153,7 @@ vop()
 {
        register int c;
        char atube[TUBESIZE + LBSIZE];
 {
        register int c;
        char atube[TUBESIZE + LBSIZE];
-       register int f;
+       register ttymode f;
 
        if (!CA && UP == NOSTR) {
                if (initev) {
 
        if (!CA && UP == NOSTR) {
                if (initev) {
@@ -175,6 +175,11 @@ toopen:
                        goto toopen;
                error("Visual requires clear screen capability");
        }
                        goto toopen;
                error("Visual requires clear screen capability");
        }
+       if (NS && !SF) {
+               if (initev)
+                       goto toopen;
+               error("Visual requires scrolling");
+       }
        ovbeg();
        bastate = VISUAL;
        c = 0;
        ovbeg();
        bastate = VISUAL;
        c = 0;
@@ -258,6 +263,8 @@ undvis()
        undap1 = one;
        undap2 = dol + 1;
        undkind = UNDALL;
        undap1 = one;
        undap2 = dol + 1;
        undkind = UNDALL;
+       if (undadot <= zero || undadot > dol)
+               undadot = zero+1;
 }
 
 /*
 }
 
 /*
index 7837339..b0d9e1e 100644 (file)
@@ -115,7 +115,15 @@ vreopen(p, lineno, l)
         *              necessary to determine which way to go.
         */
        vigoto(p, 0);
         *              necessary to determine which way to go.
         */
        vigoto(p, 0);
+#ifdef TRACE
+       if (trace)
+               fprintf(trace, "before pline in vreopen\n");
+#endif
        pline(lineno);
        pline(lineno);
+#ifdef TRACE
+       if (trace)
+               fprintf(trace, "after pline in vreopen\n");
+#endif
 
        /*
         * When we are typing part of a line for hardcopy open, don't
 
        /*
         * When we are typing part of a line for hardcopy open, don't
@@ -362,8 +370,8 @@ vrollup(dl)
        cnt = dl - (splitw ? WECHO : WBOT);
        if (splitw && (state == VISUAL || state == CRTOPEN))
                holdupd = 1;
        cnt = dl - (splitw ? WECHO : WBOT);
        if (splitw && (state == VISUAL || state == CRTOPEN))
                holdupd = 1;
-       vscroll(cnt);
        vmoveitup(cnt, 1);
        vmoveitup(cnt, 1);
+       vscroll(cnt);
        destline = dl - cnt, destcol = dc;
 }
 
        destline = dl - cnt, destcol = dc;
 }
 
index af2ea9f..b4cc3d8 100644 (file)
 #define LISP            9
 #define LIST            10
 #define MAGIC           11
 #define LISP            9
 #define LIST            10
 #define MAGIC           11
-#define NUMBER          12
-#define OPEN            13
-#define OPTIMIZE        14
-#define PARAGRAPHS      15
-#define PROMPT          16
-#define REDRAW          17
-#define REMAP           18
-#define REPORT          19
-#define SCROLL          20
-#define SECTIONS        21
-#define SHELL           22
-#define SHIFTWIDTH      23
-#define SHOWMATCH       24
-#define SLOWOPEN        25
-#define TAGS            26
-#define TABSTOP         27
-#define TERM            28
-#define TERSE           29
-#define TIMEOUT         30
-#define TTYTYPE         31
-#define UNDOMACRO       32
-#define WARN            33
-#define WINDOW          34
-#define WRAPSCAN        35
-#define WRAPMARGIN      36
-#define WRITEANY        37
+#define MESG            12
+#define NUMBER          13
+#define OPEN            14
+#define OPTIMIZE        15
+#define PARAGRAPHS      16
+#define PROMPT          17
+#define READONLY        18
+#define REDRAW          19
+#define REMAP           20
+#define REPORT          21
+#define SCROLL          22
+#define SECTIONS        23
+#define SHELL           24
+#define SHIFTWIDTH      25
+#define SHOWMATCH       26
+#define SLOWOPEN        27
+#define TABSTOP         28
+#define TAGLENGTH       29
+#define TAGS            30
+#define TERM            31
+#define TERSE           32
+#define TIMEOUT         33
+#define TTYTYPE         34
+#define WARN            35
+#define WINDOW          36
+#define WRAPSCAN        37
+#define WRAPMARGIN      38
+#define WRITEANY        39
 
 
-#define        NOPTS   38
+#define        NOPTS   40
index 4135d99..177c854 100644 (file)
@@ -63,6 +63,11 @@ getbr()
        char ch;
        register int c, d;
        register char *colp;
        char ch;
        register int c, d;
        register char *colp;
+#define BEEHIVE
+#ifdef BEEHIVE
+       static char Peek2key;
+#endif
+       extern short slevel, ttyindes;
 
 getATTN:
        if (Peekkey) {
 
 getATTN:
        if (Peekkey) {
@@ -70,6 +75,13 @@ getATTN:
                Peekkey = 0;
                return (c);
        }
                Peekkey = 0;
                return (c);
        }
+#ifdef BEEHIVE
+       if (Peek2key) {
+               c = Peek2key;
+               Peek2key = 0;
+               return (c);
+       }
+#endif
        if (vglobp) {
                if (*vglobp)
                        return (lastvgk = *vglobp++);
        if (vglobp) {
                if (*vglobp)
                        return (lastvgk = *vglobp++);
@@ -84,15 +96,36 @@ getATTN:
                if (inopen == -1)       /* don't screw up undo for esc esc */
                        vundkind = VMANY;
                inopen = 1;     /* restore old setting now that macro done */
                if (inopen == -1)       /* don't screw up undo for esc esc */
                        vundkind = VMANY;
                inopen = 1;     /* restore old setting now that macro done */
+               vch_mac = VC_NOTINMAC;
        }
        flusho();
 again:
        }
        flusho();
 again:
-       if (read(0, &ch, 1) != 1) {
+       if (read(slevel == 0 ? 0 : ttyindes, &ch, 1) != 1) {
                if (errno == EINTR)
                        goto getATTN;
                error("Input read error");
        }
        c = ch & TRIM;
                if (errno == EINTR)
                        goto getATTN;
                error("Input read error");
        }
        c = ch & TRIM;
+#ifdef BEEHIVE
+       if (XB && slevel==0 && c == ESCAPE) {
+               if (read(0, &Peek2key, 1) != 1)
+                       goto getATTN;
+               Peek2key &= TRIM;
+               switch (Peek2key) {
+               case 'C':       /* SPOW mode sometimes sends \EC for space */
+                       c = ' ';
+                       Peek2key = 0;
+                       break;
+               case 'q':       /* f2 -> ^C */
+                       c = CTRL(c);
+                       Peek2key = 0;
+                       break;
+               case 'p':       /* f1 -> esc */
+                       Peek2key = 0;
+                       break;
+               }
+       }
+#endif
 
 #ifdef UCVISUAL
        /*
 
 #ifdef UCVISUAL
        /*
@@ -218,6 +251,8 @@ readecho(c)
        }
        OP = Pline; Pline = normline;
        ignore(vgetline(0, genbuf + 1, &waste));
        }
        OP = Pline; Pline = normline;
        ignore(vgetline(0, genbuf + 1, &waste));
+       if (Outchar == termchar)
+               putchar('\n');
        vscrap();
        Pline = OP;
        if (Peekkey != ATTN && Peekkey != QUIT && Peekkey != CTRL(h)) {
        vscrap();
        Pline = OP;
        if (Peekkey != ATTN && Peekkey != QUIT && Peekkey != CTRL(h)) {
@@ -243,7 +278,7 @@ blewit:
 setLAST()
 {
 
 setLAST()
 {
 
-       if (vglobp)
+       if (vglobp || vmacp)
                return;
        lastreg = vreg;
        lasthad = Xhadcnt;
                return;
        lastreg = vreg;
        lasthad = Xhadcnt;
@@ -387,12 +422,19 @@ map(c,maps)
        if (trace)
                fprintf(trace,"map(%c): ",c);
 #endif
        if (trace)
                fprintf(trace,"map(%c): ",c);
 #endif
+       /*
+        * If c==0, the char came from getesc typing escape.  Pass it through
+        * unchanged.  0 messes up the following code anyway.
+        */
+       if (c==0)
+               return(0);
+
        b[0] = c;
        b[1] = 0;
        for (d=0; maps[d].mapto; d++) {
 #ifdef MDEBUG
                if (trace)
        b[0] = c;
        b[1] = 0;
        for (d=0; maps[d].mapto; d++) {
 #ifdef MDEBUG
                if (trace)
-                       fprintf(trace,"d=%d, ",d);
+                       fprintf(trace,"\ntry '%s', ",maps[d].cap);
 #endif
                if (p = maps[d].cap) {
                        for (q=b; *p; p++, q++) {
 #endif
                if (p = maps[d].cap) {
                        for (q=b; *p; p++, q++) {
@@ -402,6 +444,8 @@ map(c,maps)
 #endif
                                if (*q==0) {
                                        /*
 #endif
                                if (*q==0) {
                                        /*
+                                        * Is there another char waiting?
+                                        *
                                         * This test is oversimplified, but
                                         * should work mostly. It handles the
                                         * case where we get an ESCAPE that
                                         * This test is oversimplified, but
                                         * should work mostly. It handles the
                                         * case where we get an ESCAPE that
@@ -410,9 +454,13 @@ map(c,maps)
                                        if ((c=='#' ? peekkey() : fastpeekkey()) == 0) {
 #ifdef MDEBUG
                                                if (trace)
                                        if ((c=='#' ? peekkey() : fastpeekkey()) == 0) {
 #ifdef MDEBUG
                                                if (trace)
-                                                       fprintf(trace,"fpk=0: return %c",c);
+                                                       fprintf(trace,"fpk=0: return '%c'",c);
 #endif
                                                /*
 #endif
                                                /*
+                                                * Nothing waiting.  Push back
+                                                * what we peeked at & return
+                                                * failure (c).
+                                                *
                                                 * We want to be able to undo
                                                 * commands, but it's nonsense
                                                 * to undo part of an insertion
                                                 * We want to be able to undo
                                                 * commands, but it's nonsense
                                                 * to undo part of an insertion
@@ -427,11 +475,11 @@ map(c,maps)
                                if (*p != *q)
                                        goto contin;
                        }
                                if (*p != *q)
                                        goto contin;
                        }
-                       macpush(maps[d].mapto,1);
+                       macpush(maps[d].mapto,maps == arrows);
                        c = getkey();
 #ifdef MDEBUG
                        c = getkey();
 #ifdef MDEBUG
-       if (trace)
-               fprintf(trace,"Success: return %c",c);
+                       if (trace)
+                               fprintf(trace,"Success: push(%s), return %c",maps[d].mapto, c);
 #endif
                        return(c);      /* first char of map string */
                        contin:;
 #endif
                        return(c);      /* first char of map string */
                        contin:;
@@ -439,7 +487,7 @@ map(c,maps)
        }
 #ifdef MDEBUG
        if (trace)
        }
 #ifdef MDEBUG
        if (trace)
-               fprintf(trace,"Fail: return %c",c); /* DEBUG */
+               fprintf(trace,"Fail: push(%s), return %c", &b[1], c);
 #endif
        macpush(&b[1],0);
        return(c);
 #endif
        macpush(&b[1],0);
        return(c);
@@ -462,11 +510,13 @@ int canundo;
 
        if (st==0 || *st==0)
                return;
 
        if (st==0 || *st==0)
                return;
+#ifdef notdef
        if (!value(UNDOMACRO))
                canundo = 0;
        if (!value(UNDOMACRO))
                canundo = 0;
+#endif
 #ifdef TRACE
        if (trace)
 #ifdef TRACE
        if (trace)
-               fprintf(trace, "macpush(%s), canundo=%d",st,canundo);
+               fprintf(trace, "macpush(%s), canundo=%d\n",st,canundo);
 #endif
        if ((vmacp ? strlen(vmacp) : 0) + strlen(st) > BUFSIZ)
                error("Macro too long@ - maybe recursive?");
 #endif
        if ((vmacp ? strlen(vmacp) : 0) + strlen(st) > BUFSIZ)
                error("Macro too long@ - maybe recursive?");
@@ -481,20 +531,50 @@ int canundo;
        vmacp = vmacbuf;
        /* arrange to be able to undo the whole macro */
        if (canundo) {
        vmacp = vmacbuf;
        /* arrange to be able to undo the whole macro */
        if (canundo) {
+#ifdef notdef
                otchng = tchng;
                vsave();
                saveall();
                inopen = -1;    /* no need to save since it had to be 1 or -1 before */
                vundkind = VMANY;
                otchng = tchng;
                vsave();
                saveall();
                inopen = -1;    /* no need to save since it had to be 1 or -1 before */
                vundkind = VMANY;
+#endif
+               vch_mac = VC_NOCHANGE;
        }
 }
 
 #ifdef TRACE
        }
 }
 
 #ifdef TRACE
+visdump(s)
+char *s;
+{
+       register int i;
+
+       if (!trace) return;
+
+       fprintf(trace, "\n%s: basWTOP=%d, basWLINES=%d, WTOP=%d, WBOT=%d, WLINES=%d, WCOLS=%d, WECHO=%d\n",
+               s, basWTOP, basWLINES, WTOP, WBOT, WLINES, WCOLS, WECHO);
+       fprintf(trace, "   vcnt=%d, vcline=%d, cursor=%d, wcursor=%d, wdot=%d\n",
+               vcnt, vcline, cursor-linebuf, wcursor-linebuf, wdot-zero);
+       for (i=0; i<TUBELINES; i++)
+               if (vtube[i] && *vtube[i])
+                       fprintf(trace, "%d: '%s'\n", i, vtube[i]);
+       tvliny();
+}
+
 vudump(s)
 char *s;
 {
 vudump(s)
 char *s;
 {
-       if (trace)
-               fprintf(trace, "%s: undkind=%d, vundkind=%d, unddel=%d, undap1=%d, undap2=%d, dot=%d, dol=%d, unddol=%d, truedol=%d\n", s, undkind, vundkind, lineno(unddel), lineno(undap1), lineno(undap2), lineno(dot), lineno(dol), lineno(unddol), lineno(truedol));
+       register line *p;
+
+       if (!trace) return;
+
+       fprintf(trace, "\n%s: undkind=%d, vundkind=%d, unddel=%d, undap1=%d, undap2=%d,\n",
+               s, undkind, vundkind, lineno(unddel), lineno(undap1), lineno(undap2));
+       fprintf(trace, "  undadot=%d, dot=%d, dol=%d, unddol=%d, truedol=%d\n",
+               lineno(undadot), lineno(dot), lineno(dol), lineno(unddol), lineno(truedol));
+       fprintf(trace, "  [");
+       for (p=zero+1; p<=truedol; p++)
+               fprintf(trace, "%o ", *p);
+       fprintf(trace, "]\n");
 }
 #endif
 
 }
 #endif
 
index 9fac3bc..ee375c0 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (c) 1979 Regents of the University of California */
 /*
 /* Copyright (c) 1979 Regents of the University of California */
 /*
- * Ex version 2
+ * Ex version 3
  * Mark Horton, UCB
  * Bill Joy UCB
  *
  * Mark Horton, UCB
  * Bill Joy UCB
  *
@@ -134,6 +134,20 @@ line       *wdot;
 short  vundkind;       /* Which kind of undo - from above */
 char   *vutmp;         /* Prev line image when "VCHNG" */
 
 short  vundkind;       /* Which kind of undo - from above */
 char   *vutmp;         /* Prev line image when "VCHNG" */
 
+/*
+ * State information for undoing of macros.  The basic idea is that
+ * if the macro does only 1 change or even none, we don't treat it
+ * specially.  If it does 2 or more changes we want to be able to
+ * undo it as a unit.  We remember how many changes have been made
+ * within the current macro.  (Remember macros can be nested.)
+ */
+#define VC_NOTINMAC    0       /* Not in a macro */
+#define VC_NOCHANGE    1       /* In a macro, no changes so far */
+#define VC_ONECHANCE   2       /* In a macro, one change so far */
+#define VC_MANYCHANGE  3       /* In a macro, at least 2 changes so far */
+
+short  vch_mac;        /* Change state - one of the above */
+
 /*
  * For U undo's the line is grabbed by "vmove" after it first appears
  * on that line.  The "vUNDdot" which specifies which line has been
 /*
  * For U undo's the line is grabbed by "vmove" after it first appears
  * on that line.  The "vUNDdot" which specifies which line has been
index cc763b3..3ee9828 100644 (file)
@@ -24,6 +24,8 @@ vmain()
        int shouldpo = 0;
        int onumber, olist, (*OPline)(), (*OPutchar)();
 
        int shouldpo = 0;
        int onumber, olist, (*OPline)(), (*OPutchar)();
 
+       vch_mac = VC_NOTINMAC;
+
        /*
         * If we started as a vi command (on the command line)
         * then go process initial commands (recover, next or tag).
        /*
         * If we started as a vi command (on the command line)
         * then go process initial commands (recover, next or tag).
@@ -121,6 +123,7 @@ reread:
                        fprintf(trace,"pcb=%c,",peekkey());
 #endif
                op = getkey();
                        fprintf(trace,"pcb=%c,",peekkey());
 #endif
                op = getkey();
+               maphopcnt = 0;
                do {
                        /*
                         * Keep mapping the char as long as it changes.
                do {
                        /*
                         * Keep mapping the char as long as it changes.
@@ -144,6 +147,8 @@ reread:
                        }
                        if (!value(REMAP))
                                break;
                        }
                        if (!value(REMAP))
                                break;
+                       if (++maphopcnt > 256)
+                               error("Infinite macro loop");
                } while (c != op);
 
                /*
                } while (c != op);
 
                /*
@@ -378,14 +383,12 @@ reread:
 
                /*
                 * ^F           Window forwards, with 2 lines of continuity.
 
                /*
                 * ^F           Window forwards, with 2 lines of continuity.
-                *              Count gives new screen size.
+                *              Count repeats.
                 */
                case CTRL(f):
                        vsave();
                 */
                case CTRL(f):
                        vsave();
-                       if (hadcnt)
-                               vsetsiz(cnt);
                        if (vcnt > 2) {
                        if (vcnt > 2) {
-                               dot += (vcnt - vcline) - 2;
+                               dot += (vcnt - vcline) - 2 + (cnt-1)*basWLINES;
                                vcnt = vcline = 0;
                        }
                        vzop(0, 0, '+');
                                vcnt = vcline = 0;
                        }
                        vzop(0, 0, '+');
@@ -397,10 +400,8 @@ reread:
                 */
                case CTRL(b):
                        vsave();
                 */
                case CTRL(b):
                        vsave();
-                       if (hadcnt)
-                               vsetsiz(cnt);
                        if (one + vcline != dot && vcnt > 2) {
                        if (one + vcline != dot && vcnt > 2) {
-                               dot -= vcline - 2;
+                               dot -= vcline - 2 + (cnt-1)*basWLINES;
                                vcnt = vcline = 0;
                        }
                        vzop(0, 0, '^');
                                vcnt = vcline = 0;
                        }
                        vzop(0, 0, '^');
@@ -453,6 +454,7 @@ reread:
                        if (cnt > (i = dol - dot + 1))
                                cnt = i;
                        vsave();
                        if (cnt > (i = dol - dot + 1))
                                cnt = i;
                        vsave();
+                       vmacchng(1);
                        setLAST();
                        cursor = strend(linebuf);
                        vremote(cnt, join, 0);
                        setLAST();
                        cursor = strend(linebuf);
                        vremote(cnt, join, 0);
@@ -488,6 +490,7 @@ reread:
                case 'O':
                case 'o':
                        voOpen(c, cnt);
                case 'O':
                case 'o':
                        voOpen(c, cnt);
+                       vmacchng(1);
                        continue;
 
                /*
                        continue;
 
                /*
@@ -506,6 +509,7 @@ reread:
                case '~':
                        {
                                char mbuf[4];
                case '~':
                        {
                                char mbuf[4];
+                               setLAST();
                                mbuf[0] = 'r';
                                mbuf[1] = *cursor;
                                mbuf[2] = cursor[1]==0 ? 0 : ' ';
                                mbuf[0] = 'r';
                                mbuf[1] = *cursor;
                                mbuf[2] = cursor[1]==0 ? 0 : ' ';
@@ -574,6 +578,7 @@ insrt:
                         * is doomed, unless R when all is, and save the
                         * current line in a the undo temporary buffer.
                         */
                         * is doomed, unless R when all is, and save the
                         * current line in a the undo temporary buffer.
                         */
+                       vmacchng(1);
                        setLAST();
                        vcursat(cursor);
                        prepapp();
                        setLAST();
                        vcursat(cursor);
                        prepapp();
@@ -644,6 +649,17 @@ insrt:
                 */
                case 'Q':
                        vsave();
                 */
                case 'Q':
                        vsave();
+                       /*
+                        * If we are in the middle of a macro, throw away
+                        * the rest and fix up undo.
+                        * This code copied from getbr().
+                        */
+                       if (vmacp) {
+                               vmacp = 0;
+                               if (inopen == -1)       /* don't screw up undo for esc esc */
+                                       vundkind = VMANY;
+                               inopen = 1;     /* restore old setting now that macro done */
+                       }
                        return;
 
 
                        return;
 
 
@@ -671,7 +687,9 @@ insrt:
                case 'P':
                case 'p':
                        vmoving = 0;
                case 'P':
                case 'p':
                        vmoving = 0;
+#ifdef notdef
                        forbid (!vreg && value(UNDOMACRO) && inopen < 0);
                        forbid (!vreg && value(UNDOMACRO) && inopen < 0);
+#endif
                        /*
                         * If previous delete was partial line, use an
                         * append or insert to put it back so as to
                        /*
                         * If previous delete was partial line, use an
                         * append or insert to put it back so as to
@@ -689,7 +707,13 @@ insrt:
                         * sure there is something to put back.
                         */
                        forbid (!vreg && unddol == dol);
                         * sure there is something to put back.
                         */
                        forbid (!vreg && unddol == dol);
+                       /*
+                        * If we just did a macro the whole buffer is in
+                        * the undo save area.  We don't want to put THAT.
+                        */
+                       forbid (vundkind == VMANY && undkind==UNDALL);
                        vsave();
                        vsave();
+                       vmacchng(1);
                        setLAST();
                        i = 0;
                        if (vreg && partreg(vreg) || !vreg && pkill[0]) {
                        setLAST();
                        i = 0;
                        if (vreg && partreg(vreg) || !vreg && pkill[0]) {
@@ -836,6 +860,19 @@ gogo:
                        vsave();
                        goto doinit;
 
                        vsave();
                        goto doinit;
 
+#ifdef TIOCLGET
+               /*
+                * ^Z:  suspend editor session and temporarily return
+                *      to shell.  Only works on Berkeley tty driver.
+                */
+               case CTRL(z):
+                       forbid(dosusp == 0 || !ldisc);
+                       vsave();
+                       oglobp = globp;
+                       globp = "stop";
+                       goto gogo;
+#endif
+
                /*
                 * :            Read a command from the echo area and
                 *              execute it in command mode.
                /*
                 * :            Read a command from the echo area and
                 *              execute it in command mode.
@@ -850,6 +887,7 @@ gogo:
                                esave[0] = 0;
                                goto fixup;
                        }
                                esave[0] = 0;
                                goto fixup;
                        }
+                       getDOT();
                        /*
                         * Use the visual undo buffer to store the global
                         * string for command mode, since it is idle right now.
                        /*
                         * Use the visual undo buffer to store the global
                         * string for command mode, since it is idle right now.
@@ -1037,7 +1075,7 @@ fixup:
                 * u            undo the last changing command.
                 */
                case 'u':
                 * u            undo the last changing command.
                 */
                case 'u':
-                       vundo();
+                       vundo(1);
                        continue;
 
                /*
                        continue;
 
                /*
index 42812bf..63bf53c 100644 (file)
@@ -106,11 +106,13 @@ operate(c, cnt)
         */
        case 'r':
                vrep(cnt);
         */
        case 'r':
                vrep(cnt);
+               vmacchng(1);
                return;
 
        default:
                goto nocount;
        }
                return;
 
        default:
                goto nocount;
        }
+       vmacchng(1);
        /*
         * Had an operator, so accept another count.
         * Multiply counts together.
        /*
         * Had an operator, so accept another count.
         * Multiply counts together.
@@ -413,6 +415,7 @@ deleteit:
        case 'x':
                if (margin())
                        goto errlab;
        case 'x':
                if (margin())
                        goto errlab;
+               vmacchng(1);
                while (cnt > 0 && !margin())
                        wcursor += dir, cnt--;
                opf = deleteop;
                while (cnt > 0 && !margin())
                        wcursor += dir, cnt--;
                opf = deleteop;
index cb433c3..21e83ed 100644 (file)
@@ -50,10 +50,12 @@ vUndo()
        }
        vdirty(vcline, 1);
        vsyncCL();
        }
        vdirty(vcline, 1);
        vsyncCL();
+       cursor = linebuf;
        vfixcurs();
 }
 
        vfixcurs();
 }
 
-vundo()
+vundo(show)
+bool show;     /* if true update the screen */
 {
        register int cnt;
        register line *addr;
 {
        register int cnt;
        register line *addr;
@@ -88,22 +90,29 @@ vundo()
                 * with dol through unddol-1.  Hack screen image to
                 * reflect this replacement.
                 */
                 * with dol through unddol-1.  Hack screen image to
                 * reflect this replacement.
                 */
-               vreplace(undap1 - addr, undap2 - undap1,
-                   undkind == UNDPUT ? 0 : unddol - dol);
+               if (show)
+                       if (undkind == UNDMOVE)
+                               vdirty(0, LINES);
+                       else
+                               vreplace(undap1 - addr, undap2 - undap1,
+                                   undkind == UNDPUT ? 0 : unddol - dol);
                savenote = notecnt;
                undo(1);
                savenote = notecnt;
                undo(1);
-               if (vundkind != VMCHNG || addr != dot)
+               if (show && (vundkind != VMCHNG || addr != dot))
                        killU();
                vundkind = VMANY;
                cnt = dot - addr;
                if (cnt < 0 || cnt > vcnt || state != VISUAL) {
                        killU();
                vundkind = VMANY;
                cnt = dot - addr;
                if (cnt < 0 || cnt > vcnt || state != VISUAL) {
-                       vjumpto(dot, NOSTR, '.');
+                       if (show)
+                               vjumpto(dot, NOSTR, '.');
                        break;
                }
                if (!savenote)
                        notecnt = 0;
                        break;
                }
                if (!savenote)
                        notecnt = 0;
-               vcline = cnt;
-               vrepaint(vmcurs);
+               if (show) {
+                       vcline = cnt;
+                       vrepaint(vmcurs);
+               }
                vmcurs = 0;
                break;
 
                vmcurs = 0;
                break;
 
@@ -116,6 +125,8 @@ vundo()
                strcLIN(temp);
                cp = vUA1; vUA1 = vUD1; vUD1 = cp;
                cp = vUA2; vUA2 = vUD2; vUD2 = cp;
                strcLIN(temp);
                cp = vUA1; vUA1 = vUD1; vUD1 = cp;
                cp = vUA2; vUA2 = vUD2; vUD2 = cp;
+               if (!show)
+                       break;
                cursor = vUD1;
                if (state == HARDOPEN) {
                        doomed = 0;
                cursor = vUD1;
                if (state == HARDOPEN) {
                        doomed = 0;
@@ -150,6 +161,94 @@ vundo()
        }
 }
 
        }
 }
 
+/*
+ * Routine to handle a change inside a macro.
+ * Fromvis is true if we were called from a visual command (as
+ * opposed to an ex command).  This has nothing to do with being
+ * in open/visual mode as :s/foo/bar is not fromvis.
+ */
+vmacchng(fromvis)
+bool fromvis;
+{
+       line *savedot, *savedol;
+       char *savecursor;
+       int nlines, more;
+       register line *a1, *a2;
+       char ch;        /* DEBUG */
+       int copyw(), copywR();
+
+       if (!inopen)
+               return;
+       if (!vmacp)
+               vch_mac = VC_NOTINMAC;
+#ifdef TRACE
+       if (trace)
+               fprintf(trace, "vmacchng, vch_mac=%d, linebuf='%s', *dot=%o\n", vch_mac, linebuf, *dot);
+#endif
+       if (vmacp && fromvis)
+               vsave();
+#ifdef TRACE
+       if (trace)
+               fprintf(trace, "after vsave, linebuf='%s', *dot=%o\n", linebuf, *dot);
+#endif
+       switch(vch_mac) {
+       case VC_NOCHANGE:
+               vch_mac = VC_ONECHANGE;
+               break;
+       case VC_ONECHANGE:
+               /* Save current state somewhere */
+#ifdef TRACE
+               vudump("before vmacchng hairy case");
+#endif
+               savedot = dot; savedol = dol; savecursor = cursor;
+               nlines = dol - zero;
+               while ((line *) endcore - truedol < nlines)
+                       morelines();
+               copyw(truedol+1, zero+1, nlines);
+               truedol += nlines;
+
+#ifdef TRACE
+               visdump("before vundo");
+#endif
+               /* Restore state as it was at beginning of macro */
+               vundo(0);
+#ifdef TRACE
+               visdump("after vundo");
+               vudump("after vundo");
+#endif
+
+               /* Do the saveall we should have done then */
+               saveall();
+#ifdef TRACE
+               vudump("after saveall");
+#endif
+
+               /* Restore current state from where saved */
+               more = savedol - dol; /* amount we shift everything by */
+               if (more)
+                       (*(more>0 ? copywR : copyw))(savedol+1, dol+1, truedol-dol);
+               unddol += more; truedol += more;
+
+               truedol -= nlines;
+               copyw(zero+1, truedol+1, nlines);
+               dot = savedot; dol = savedol ; cursor = savecursor;
+               vch_mac = VC_MANYCHANGE;
+
+               /* Arrange that no further undo saving happens within macro */
+               otchng = tchng; /* Copied this line blindly - bug? */
+               inopen = -1;    /* no need to save since it had to be 1 or -1 before */
+               vundkind = VMANY;
+#ifdef TRACE
+               vudump("after vmacchng");
+#endif
+               break;
+       case VC_NOTINMAC:
+       case VC_MANYCHANGE:
+               /* Nothing to do for various reasons. */
+               break;
+       }
+}
+
 /*
  * Initialize undo information before an append.
  */
 /*
  * Initialize undo information before an append.
  */
index 8304179..cfffc8d 100644 (file)
@@ -407,6 +407,7 @@ vgetline(cnt, gcursor, aescaped)
        register char *cp;
        int x, y, iwhite;
        char *iglobp;
        register char *cp;
        int x, y, iwhite;
        char *iglobp;
+       char cstr[2];
        int (*OO)() = Outchar;
 
        /*
        int (*OO)() = Outchar;
 
        /*
@@ -442,12 +443,18 @@ vgetline(cnt, gcursor, aescaped)
                        if (cnt == 0)
                                goto vadone;
                }
                        if (cnt == 0)
                                goto vadone;
                }
-               ch = c = getkey() & (QUOTE|TRIM);
+               c = getkey();
+               if (c != ATTN)
+                       c &= (QUOTE|TRIM);
+               ch = c;
+               maphopcnt = 0;
                if (vglobp == 0 && Peekkey == 0)
                        while ((ch = map(c, immacs)) != c) {
                                c = ch;
                                if (!value(REMAP))
                                        break;
                if (vglobp == 0 && Peekkey == 0)
                        while ((ch = map(c, immacs)) != c) {
                                c = ch;
                                if (!value(REMAP))
                                        break;
+                               if (++maphopcnt > 256)
+                                       error("Infinite macro loop");
                        }
                if (!iglobp) {
 
                        }
                if (!iglobp) {
 
@@ -457,10 +464,17 @@ vgetline(cnt, gcursor, aescaped)
                         * from untyped input when we started.
                         * Map users erase to ^H, kill to -1 for switch.
                         */
                         * from untyped input when we started.
                         * Map users erase to ^H, kill to -1 for switch.
                         */
+#ifndef USG3TTY
                        if (c == tty.sg_erase)
                                c = CTRL(h);
                        else if (c == tty.sg_kill)
                                c = -1;
                        if (c == tty.sg_erase)
                                c = CTRL(h);
                        else if (c == tty.sg_kill)
                                c = -1;
+#else
+                       if (c == tty.c_cc[VERASE])
+                               c = CTRL(h);
+                       else if (c == tty.c_cc[VKILL])
+                               c = -1;
+#endif
                        switch (c) {
 
                        /*
                        switch (c) {
 
                        /*
@@ -544,7 +558,12 @@ vbackup:
                                putchar('\\');
                                vcsync();
                                c = getkey();
                                putchar('\\');
                                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]) {
+#endif
                                        vgoto(y, x);
                                        if (doomed >= 0)
                                                doomed++;
                                        vgoto(y, x);
                                        if (doomed >= 0)
                                                doomed++;
@@ -584,16 +603,85 @@ vbackup:
                 * If we get a blank not in the echo area
                 * consider splitting the window in the wrapmargin.
                 */
                 * If we get a blank not in the echo area
                 * consider splitting the window in the wrapmargin.
                 */
-               if (c == ' ' && !splitw) {
-                       if (gobblebl) {
+               if (c != NL && !splitw) {
+                       if (c == ' ' && gobblebl) {
                                gobbled = 1;
                                continue;
                        }
                                gobbled = 1;
                                continue;
                        }
-                       if (value(WRAPMARGIN) && outcol >= OCOLUMNS - value(WRAPMARGIN)) {
-                               c = NL;
-                               gobblebl = 2;
+                       if (/* c <= ' ' && */ value(WRAPMARGIN) &&
+                               outcol >= OCOLUMNS - value(WRAPMARGIN)) {
+                               /*
+                                * At end of word and hit wrapmargin.
+                                * Move the word to next line and keep going.
+                                */
+                               wdkind = 1;
+                               *gcursor++ = c;
+                               *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)) {
+                                       /*
+                                        * Find beginning of previous word.
+                                        */
+                                       for (; cp>ogcursor && !isspace(cp[-1]); cp--)
+                                               ;
+                                       if (cp <= ogcursor) {
+                                               /*
+                                                * There is a single word that
+                                                * is too long to fit.  Just
+                                                * let it pass, but beep for
+                                                * each new letter to warn
+                                                * the luser.
+                                                */
+                                               c = *--gcursor;
+                                               *gcursor = 0;
+                                               beep();
+                                               goto dontbreak;
+                                       }
+                                       /*
+                                        * Save it for next line.
+                                        */
+                                       macpush(cp, 0);
+                                       cp--;
+                               }
+                               macpush("\n", 0);
+                               /*
+                                * Erase white space before the word.
+                                */
+                               while (cp > ogcursor && isspace(cp[-1]))
+                                       cp--;   /* skip blank */
+                               gobblebl = 3;
+                               goto vbackup;
                        }
                        }
+               dontbreak:;
+               }
+
+               /*
+                * Word abbreviation mode.
+                */
+               cstr[0] = c;
+               if (anyabbrs && gcursor > ogcursor && !wordch(cstr) && wordch(gcursor-1)) {
+                               int wdtype, abno;
+
+                               cstr[1] = 0;
+                               wdkind = 1;
+                               cp = gcursor - 1;
+                               for (wdtype = wordch(cp - 1);
+                                   cp > ogcursor && wordof(wdtype, cp - 1); cp--)
+                                       ;
+                               *gcursor = 0;
+                               for (abno=0; abbrevs[abno].mapto; abno++) {
+                                       if (eq(cp, abbrevs[abno].cap)) {
+                                               macpush(cstr, 0);
+                                               macpush(abbrevs[abno].mapto);
+                                               goto vbackup;
+                                       }
+                               }
                }
                }
+
                switch (c) {
 
                /*
                switch (c) {
 
                /*
@@ -702,22 +790,22 @@ vbackup:
                        }
 def:
                        putchar(c);
                        }
 def:
                        putchar(c);
+                       flush();
 noput:
                        if (gcursor > &genbuf[LBSIZE - 2])
                                error("Line too long");
                        *gcursor++ = c & TRIM;
                        vcsync();
 noput:
                        if (gcursor > &genbuf[LBSIZE - 2])
                                error("Line too long");
                        *gcursor++ = c & TRIM;
                        vcsync();
-#ifdef LISPCODE
                        if (value(SHOWMATCH) && !iglobp)
                                if (c == ')' || c == '}')
                                        lsmatch(gcursor);
                        if (value(SHOWMATCH) && !iglobp)
                                if (c == ')' || c == '}')
                                        lsmatch(gcursor);
-#endif
                        continue;
                }
        }
 vadone:
        *gcursor = 0;
                        continue;
                }
        }
 vadone:
        *gcursor = 0;
-       Outchar = OO;
+       if (Outchar != termchar)
+               Outchar = OO;
        endim();
        return (gcursor);
 }
        endim();
        return (gcursor);
 }
index b0e9697..b1ae183 100644 (file)
@@ -322,11 +322,11 @@ lmatchp(addr)
        register int i;
        register char *parens, *cp;
 
        register int i;
        register char *parens, *cp;
 
-       for (cp = cursor; !any(*cp, "({)}");)
+       for (cp = cursor; !any(*cp, "({[)}]");)
                if (*cp++ == 0)
                        return (0);
        lf = 0;
                if (*cp++ == 0)
                        return (0);
        lf = 0;
-       parens = any(*cp, "()") ? "()" : "{}";
+       parens = any(*cp, "()") ? "()" : any(*cp, "[]") ? "[]" : "{}";
        if (*cp == parens[1]) {
                dir = -1;
                llimit = one;
        if (*cp == parens[1]) {
                dir = -1;
                llimit = one;
@@ -370,6 +370,12 @@ lsmatch(cp)
                if (i)
                        goim();
        }
                if (i)
                        goim();
        }
+       else {
+               strcLIN(sp);
+               strcpy(scurs, genbuf);
+               if (!lmatchp((line *) 0))
+                       beep();
+       }
        strcLIN(sp);
        wdot = 0;
        wcursor = 0;
        strcLIN(sp);
        wdot = 0;
        wcursor = 0;
@@ -456,7 +462,7 @@ lnext()
                if (*wcursor)
                        return (1);
                if (wdot >= llimit) {
                if (*wcursor)
                        return (1);
                if (wdot >= llimit) {
-                       if (wcursor > linebuf)
+                       if (lf == vmove && wcursor > linebuf)
                                wcursor--;
                        return (0);
                }
                                wcursor--;
                        return (0);
                }
index 36434a3..b06da78 100644 (file)
@@ -115,10 +115,28 @@ vclrech(didphys)
                 * since we don't really know whats out there.
                 * Vigoto might decide (incorrectly) to do nothing.
                 */
                 * since we don't really know whats out there.
                 * Vigoto might decide (incorrectly) to do nothing.
                 */
-               if (DB)
-                       vgoto(WECHO, 0), vputp(CD ? CD : CE, 1);
-               else
-                       vigoto(WECHO, 0), vclreol();
+               if (DB) {
+                       vgoto(WECHO, 0);
+                       vputp(CD ? CD : CE, 1);
+               } else {
+                       if (XT) {
+                               /*
+                                * This code basically handles the t1061
+                                * where positioning at (0, 0) won't work
+                                * because the terminal won't let you put
+                                * the cursor on it's magic cookie.
+                                *
+                                * Should probably be XS above, or even a
+                                * new X? glitch, but right now t1061 is the
+                                * only terminal with XT.
+                                */
+                               vgoto(WECHO, 0);
+                               vputp(DL, 1);
+                       } else {
+                               vigoto(WECHO, 0);
+                               vclreol();
+                       }
+               }
                splitw = 0;
                didphys = 1;
        }
                splitw = 0;
                didphys = 1;
        }
@@ -399,11 +417,11 @@ vgoto(y, x)
  */
 vgotab()
 {
  */
 vgotab()
 {
-       register int i = (LINE(vcline) - destline) * WCOLS + destcol;
+       register int i = tabcol(destcol, value(TABSTOP)) - destcol;
 
        do
                (*Outchar)(QUOTE);
 
        do
                (*Outchar)(QUOTE);
-       while (++i % value(TABSTOP));
+       while (--i);
 }
 
 /*
 }
 
 /*
@@ -443,7 +461,7 @@ vmaktop(p, cp)
        register int i;
        char temp[TUBECOLS];
 
        register int i;
        char temp[TUBECOLS];
 
-       if (vtube[p] == cp)
+       if (p < 0 || vtube[p] == cp)
                return;
        for (i = ZERO; i <= WECHO; i++)
                if (vtube[i] == cp) {
                return;
        for (i = ZERO; i <= WECHO; i++)
                if (vtube[i] == cp) {
@@ -542,7 +560,7 @@ vinschar(c)
                 * use QUOTE here since we really need to print blanks.
                 * QUOTE|' ' is the representation of this.
                 */
                 * use QUOTE here since we really need to print blanks.
                 * QUOTE|' ' is the representation of this.
                 */
-               inssiz = value(TABSTOP) - inscol % value(TABSTOP);
+               inssiz = tabcol(inscol, value(TABSTOP)) - inscol;
                c = ' ' | QUOTE;
        } else
                inssiz = 1;
                c = ' ' | QUOTE;
        } else
                inssiz = 1;
@@ -618,7 +636,7 @@ vinschar(c)
                 * line is now deeper.  We then do the shift
                 * implied by the insertion.
                 */
                 * line is now deeper.  We then do the shift
                 * implied by the insertion.
                 */
-               if (inssiz >= doomed + value(TABSTOP) - tabstart % value(TABSTOP)) {
+               if (inssiz >= doomed + tabcol(tabstart, value(TABSTOP)) - tabstart) {
                        if (IN)
                                vrigid();
                        vneedpos(value(TABSTOP));
                        if (IN)
                                vrigid();
                        vneedpos(value(TABSTOP));
index 84d2639..dd7e027 100644 (file)
@@ -1,40 +1,43 @@
 #
 # remake options -- this isn't necessary unless you add/delete options
 #
 #
 # remake options -- this isn't necessary unless you add/delete options
 #
-       onintr ifintr
-       cp ex_data.c /tmp/$$.c
-       ex - /tmp/$$.c <<'%'
-               g/^#include/d
-               w
-               q
+onintr ifintr
+cp ex_data.c /tmp/$$.c
+ex - /tmp/$$.c <<'%'
+       g/^#include/d
+       w
+       q
 '%'
 '%'
-       cc -E $* /tmp/$$.c >/tmp/foo.c
-       ex - /tmp/foo.c <<'X'
-               g/^# /d
-               set sh=/bin/csh
-               g/^[    ]*$/d
-               1,/options/d
-               /}/-1,$d
-               1,$s/   "//
-               1,$s/".*//
-               1m$
-               w! ex_vars.h
-               !rm -f %; num ex_vars.h >%
-               e
-               $t0
-               1s/......../     0  /
-               1,$s/\(......\)\(.*\)/#define   \U\2\L  \1/
-               1,$s/    */     /g
-               g/  */s//       /g
-               w
-               !rm -f ex_vars.h; expand -8,24 % >ex_vars.h
-               e! ex_vars.h
-               $i
+cc -E $* /tmp/$$.c >/tmp/foo.c
+ex - /tmp/foo.c <<'X'
+       " delete all preprocessor output (# line, etc)
+       g/^# /d
+       set sh=/bin/csh
+       " delete junk (all but data lines)
+       g/^[    ]*$/d
+       1,/options/d
+       /}/-1,$d
+       " get rid of all of line but option name
+       1,$s/   "//
+       1,$s/".*//
+       1m$     " kludge since options start at 0 but num at 1
+       %!num
+       $t0     " unkludge
+       1s/......../     0  /   " unkludge
+       " make #define lines
+       1,$s/\(......\)\(.*\)/#define   \U\2\L  \1/
+       " get rid of extra blanks, turning into (single) tabs.
+       1,$s/    */     /g
+       g/  */s//       /g
+       " filter through expand to make it line up nice
+       %!expand -8\,24
+       " blank line and number of options.
+       $i
 
 .
 
 .
-               $s/e[   ].*[    ]/e     NOPTS   /
-               w
-               q
+       $s/e[   ].*[    ]/e     NOPTS   /
+       w! ex_vars.h
+       q
 'X'
 ifintr:
 'X'
 ifintr:
-       rm /tmp/foo.c
+rm /tmp/foo.c