BSD 2 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 9 May 1979 07:18:22 +0000 (23:18 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 9 May 1979 07:18:22 +0000 (23:18 -0800)
Work on file src/ex/ex_cmds.c
Work on file src/ex/ex_cmds2.c

Synthesized-from: 2bsd

src/ex/ex_cmds.c [new file with mode: 0644]
src/ex/ex_cmds2.c [new file with mode: 0644]

diff --git a/src/ex/ex_cmds.c b/src/ex/ex_cmds.c
new file mode 100644 (file)
index 0000000..ec9665e
--- /dev/null
@@ -0,0 +1,716 @@
+/* Copyright (c) 1979 Regents of the University of California */
+#include "ex.h"
+#include "ex_argv.h"
+#include "ex_temp.h"
+#include "ex_tty.h"
+
+bool   pflag, nflag;
+int    poffset;
+
+#define        nochng()        lchng = chng
+
+/*
+ * Main loop for command mode command decoding.
+ * A few commands are executed here, but main function
+ * is to strip command addresses, do a little address oriented
+ * processing and call command routines to do the real work.
+ */
+commands(noprompt, exitoneof)
+       bool noprompt, exitoneof;
+{
+       register line *addr;
+       register int c;
+       register int lchng;
+       int cnt;
+       bool hadpr;
+
+       resetflav();
+       nochng();
+       for (;;) {
+               /*
+                * If dot at last command
+                * ended up at zero, advance to one if there is a such.
+                */
+               if (dot <= zero) {
+                       dot = zero;
+                       if (dol > zero)
+                               dot = one;
+               }
+               shudclob = 0;
+
+               /*
+                * If autoprint or trailing print flags,
+                * print the line at the specified offset
+                * before the next command.
+                */
+               if (pflag || lchng != chng && value(AUTOPRINT) && !inglobal && !inopen && endline) {
+                       pflag = 0;
+                       nochng();
+                       if (dol != zero) {
+                               addr1 = addr2 = dot + poffset;
+                               if (addr1 < one || addr1 > dol)
+                                       error("Offset out-of-bounds|Offset after command too large");
+                               setdot1();
+                               goto print;
+                       }
+               }
+               nochng();
+
+               /*
+                * Print prompt if appropriate.
+                * If not in global flush output first to prevent
+                * going into pfast mode unreasonably.
+                */
+               if (inglobal == 0) {
+                       flush();
+                       if (hush == 0 && value(PROMPT) && globp == 0 && noprompt == 0 && intty && endline) {
+                               putchar(':');
+                               hadpr = 1;
+                       }
+                       TSYNC();
+               }
+
+               /*
+                * Gobble up the address.
+                * Degenerate addresses yield ".".
+                */
+               addr2 = 0;
+               do {
+                       addr1 = addr2;
+                       addr = address();
+                       c = getcd();
+                       if (addr == 0)
+                               if (c == ',')
+                                       addr = dot;
+                               else if (addr1 != 0) {
+                                       addr2 = dot;
+                                       break;
+                               } else
+                                       break;
+                       addr2 = addr;
+                       if (c == ';') {
+                               c = ',';
+                               dot = addr;
+                       }
+               } while (c == ',');
+               if (addr1 == 0)
+                       addr1 = addr2;
+               if (c == ':')
+                       c = getchar();
+
+               /*
+                * Set command name for special character commands.
+                */
+               tailspec(c);
+
+               /*
+                * If called via : escape from open or visual, limit
+                * the set of available commands here to save work below.
+                */
+               if (inopen) {
+                       if (c=='\n' || c=='\r' || c==CTRL(d) || c==EOF) {
+                               if (addr2)
+                                       dot = addr2;
+                               if (c == EOF)
+                                       return;
+                               continue;
+                       }
+                       if (any(c, "o"))
+notinvis:
+                               tailprim(Command, 1, 1);
+               }
+               switch (c) {
+
+               case 'a':
+
+                       if (peekchar() == 'r') {
+/* args */
+                               tail("args");
+                               setnoaddr();
+                               eol();
+                               pargs();
+                               continue;
+                       }
+
+/* append */
+                       if (inopen)
+                               goto notinvis;
+                       tail("append");
+                       setdot();
+                       aiflag = exclam();
+                       newline();
+                       deletenone();
+                       setin(addr2);
+                       ignore(append(gettty, addr2));
+                       nochng();
+                       continue;
+
+               case 'c':
+                       switch (peekchar()) {
+
+/* copy */
+                       case 'o':
+                               if (inopen)
+                                       goto notinvis;
+                               tail("copy");
+                               move();
+                               continue;
+
+#ifdef CHDIR
+/* cd */
+                       case 'd':
+                               tail("cd");
+                               goto changdir;
+
+/* chdir */
+                       case 'h':
+                               ignchar();
+                               if (peekchar() == 'd') {
+                                       register char *p;
+                                       tail2of("chdir");
+changdir:
+                                       if (savedfile[0] == '/' || !value(WARN))
+                                               ignore(exclam());
+                                       else
+                                               ignore(quickly());
+                                       if (skipend()) {
+                                               p = getenv("HOME");
+                                               if (p == NULL)
+                                                       error("Home directory unknown");
+                                       } else
+                                               getone(), p = file;
+                                       eol();
+                                       if (chdir(p) < 0)
+                                               filioerr(p);
+                                       if (savedfile[0] != '/')
+                                               edited = 0;
+                                       continue;
+                               }
+                               if (inopen)
+                                       tailprim("change", 2, 1);
+                               tail2of("change");
+                               break;
+
+#endif
+                       default:
+                               if (inopen)
+                                       goto notinvis;
+                               tail("change");
+                               break;
+                       }
+/* change */
+                       aiflag = exclam();
+                       setCNL();
+                       setin(addr1);
+                       delete(0);
+                       ignore(append(gettty, addr1 - 1));
+                       nochng();
+                       continue;
+
+/* delete */
+               case 'd':
+                       tail("delete");
+                       c = cmdreg();
+                       setCNL();
+                       if (c)
+                               YANKreg(c);
+                       delete(0);
+                       appendnone();
+                       continue;
+
+/* edit */
+/* ex */
+               case 'e':
+                       tail(peekchar() == 'x' ? "ex" : "edit");
+                       if (!exclam() && chng)
+                               c = 'E';
+                       filename(c);
+                       if (c == 'E') {
+                               ungetchar(lastchar());
+                               ignore(quickly());
+                       }
+                       setnoaddr();
+doecmd:
+                       init();
+                       addr2 = zero;
+                       laste++;
+                       sync();
+                       rop(c);
+                       nochng();
+                       continue;
+
+/* file */
+               case 'f':
+                       tail("file");
+                       setnoaddr();
+                       filename(c);
+                       noonl();
+                       synctmp();
+                       continue;
+
+/* global */
+               case 'g':
+                       tail("global");
+                       global(!exclam());
+                       nochng();
+                       continue;
+
+/* insert */
+               case 'i':
+                       if (inopen)
+                               goto notinvis;
+                       tail("insert");
+                       setdot();
+                       nonzero();
+                       aiflag = exclam();
+                       newline();
+                       deletenone();
+                       setin(addr2);
+                       ignore(append(gettty, addr2 - 1));
+                       if (dot == zero && dol > zero)
+                               dot = one;
+                       nochng();
+                       continue;
+
+/* join */
+               case 'j':
+                       tail("join");
+                       c = exclam();
+                       setcount();
+                       nonzero();
+                       newline();
+                       if (addr1 == addr2 && addr2 != dol)
+                               addr2++;
+                       join(c);
+                       continue;
+
+/* k */
+               case 'k':
+casek:
+                       pastwh();
+                       c = getchar();
+                       if (endcmd(c))
+                               serror("Mark what?|%s requires following letter", Command);
+                       newline();
+                       if (!islower(c))
+                               error("Bad mark|Mark must specify a letter");
+                       setdot();
+                       nonzero();
+                       names[c - 'a'] = *addr2 &~ 01;
+                       anymarks = 1;
+                       continue;
+
+/* list */
+               case 'l':
+                       tail("list");
+                       setCNL();
+                       ignorf(setlist(1));
+                       pflag = 0;
+                       goto print;
+
+               case 'm':
+                       if (peekchar() == 'a') {
+/* mark */
+                               tail("mark");
+                               goto casek;
+                       }
+/* move */
+                       tail("move");
+                       move();
+                       continue;
+
+               case 'n':
+                       if (peekchar() == 'u') {
+                               tail("number");
+                               goto numberit;
+                       }
+/* next */
+                       tail("next");
+                       setnoaddr();
+                       ignore(quickly());
+                       if (getargs())
+                               makargs();
+                       next();
+                       c = 'e';
+                       filename(c);
+                       goto doecmd;
+
+/* open */
+               case 'o':
+                       tail("open");
+                       oop();
+                       pflag = 0;
+                       nochng();
+                       continue;
+
+               case 'p':
+                       switch (peekchar()) {
+
+/* put */
+                       case 'u':
+                               tail("put");
+                               setdot();
+                               c = cmdreg();
+                               eol();
+                               if (c)
+                                       putreg(c);
+                               else
+                                       put();
+                               continue;
+
+                       case 'r':
+                               ignchar();
+                               if (peekchar() == 'e') {
+/* preserve */
+                                       tail2of("preserve");
+                                       eol();
+                                       if (preserve() == 0)
+                                               error("Preserve failed!");
+                                       else
+                                               error("File preserved.");
+                               }
+                               tail2of("print");
+                               break;
+
+                       default:
+                               tail("print");
+                               break;
+                       }
+/* print */
+                       setCNL();
+                       pflag = 0;
+print:
+                       nonzero();
+                       if (CL && span() > LINES) {
+                               flush1();
+                               vclear();
+                       }
+                       plines(addr1, addr2, 1);
+                       continue;
+
+/* quit */
+               case 'q':
+                       tail("quit");
+                       setnoaddr();
+                       c = quickly();
+                       eol();
+                       if (!c)
+quit:
+                               nomore();
+                       if (inopen) {
+                               vgoto(WECHO, 0);
+                               if (!ateopr())
+                                       vnfl();
+                               flush();
+                               setty(normf);
+                       }
+                       cleanup(1);
+                       exit(0);
+
+               case 'r':
+                       if (peekchar() == 'e') {
+                               ignchar();
+                               switch (peekchar()) {
+
+/* rewind */
+                               case 'w':
+                                       tail2of("rewind");
+                                       setnoaddr();
+                                       ignore(quickly());
+                                       eol();
+                                       erewind();
+                                       next();
+                                       c = 'e';
+                                       ungetchar(lastchar());
+                                       filename(c);
+                                       goto doecmd;
+
+/* recover */
+                               case 'c':
+                                       tail2of("recover");
+                                       setnoaddr();
+                                       c = 'e';
+                                       if (!exclam() && chng)
+                                               c = 'E';
+                                       filename(c);
+                                       if (c == 'E') {
+                                               ungetchar(lastchar());
+                                               ignore(quickly());
+                                       }
+                                       init();
+                                       addr2 = zero;
+                                       laste++;
+                                       sync();
+                                       recover();
+                                       rop2();
+                                       revocer();
+                                       if (status == 0)
+                                               rop3(c);
+                                       if (dol != zero)
+                                               change();
+                                       nochng();
+                                       continue;
+                               }
+                               tail2of("read");
+                       } else
+                               tail("read");
+/* read */
+                       if (savedfile[0] == 0 && dol == zero)
+                               c = 'e';
+                       pastwh();
+                       if (peekchar() == '!') {
+                               setdot();
+                               ignchar();
+                               unix0(0);
+                               filter(0);
+                               continue;
+                       }
+                       filename(c);
+                       rop(c);
+                       nochng();
+                       if (inopen && endline && addr1 > zero && addr1 < dol)
+                               dot = addr1 + 1;
+                       continue;
+
+               case 's':
+                       switch (peekchar()) {
+
+/* set */
+                       case 'e':
+                               tail("set");
+                               setnoaddr();
+                               set();
+                               continue;
+
+/* shell */
+                       case 'h':
+                               tail("shell");
+                               setNAEOL();
+                               vnfl();
+                               unixwt(1, unixex("-i", (char *) 0, 0, 0));
+                               vcontin(0);
+                               continue;
+
+/* source */
+                       case 'o':
+                               if (inopen)
+                                       goto notinvis;
+                               tail("source");
+                               setnoaddr();
+                               getone();
+                               eol();
+                               source(file, 0);
+                               continue;
+                       }
+                       /* fall into ... */
+
+/* & */
+/* ~ */
+/* substitute */
+               case '&':
+               case '~':
+                       Command = "substitute";
+                       if (c == 's')
+                               tail(Command);
+                       if (!substitute(c))
+                               pflag = 0;
+                       continue;
+
+/* t */
+               case 't':
+                       if (peekchar() == 'a') {
+                               tail("tag");
+                               tagfind(exclam());
+                               if (!inopen)
+                                       lchng = chng - 1;
+                               else
+                                       nochng();
+                               continue;
+                       }
+                       tail("t");
+                       move();
+                       continue;
+
+/* undo */
+               case 'u':
+                       tail("undo");
+                       setnoaddr();
+                       markDOT();
+                       c = exclam();
+                       newline();
+                       undo(c);
+                       continue;
+
+               case 'v':
+                       switch (peekchar()) {
+
+                       case 'e':
+/* version */
+                               tail("version");
+                               setNAEOL();
+                               /* should use SCCS subst here */
+                               printf("Version 2.2, May 6, 1979");
+                               noonl();
+                               continue;
+
+/* visual */
+                       case 'i':
+                               tail("visual");
+                               vop();
+                               pflag = 0;
+                               nochng();
+                               continue;
+                       }
+/* v */
+                       tail("v");
+                       global(0);
+                       nochng();
+                       continue;
+
+/* write */
+               case 'w':
+                       c = peekchar();
+                       tail(c == 'q' ? "wq" : "write");
+                       if (skipwh() && peekchar() == '!') {
+                               ignchar();
+                               setall();
+                               unix0(0);
+                               filter(1);
+                       } else {
+                               setall();
+                               wop();
+                               nochng();
+                       }
+                       if (c == 'q')
+                               goto quit;
+                       continue;
+
+/* yank */
+               case 'y':
+                       tail("yank");
+                       c = cmdreg();
+                       setcount();
+                       eol();
+                       if (c)
+                               YANKreg(c);
+                       else
+                               yank();
+                       continue;
+
+/* z */
+               case 'z':
+                       zop(0);
+                       pflag = 0;
+                       continue;
+
+/* | */
+               case '|':
+                       endline = 0;
+                       goto caseline;
+
+/* \n */
+               case '\n':
+                       endline = 1;
+caseline:
+                       notempty();
+                       if (addr2 == 0) {
+                               if (dot == dol)
+                                       error("At EOF|At end-of-file");
+                               if (UP != NOSTR && c == '\n' && !inglobal)
+                                       c = CTRL(k);
+                               addr2 = dot + 1;
+                       }
+                       addr1 = addr2;
+                       setdot();
+                       nonzero();
+                       getline(*addr1);
+                       if (c == CTRL(k)) {
+                               flush1();
+                               destline--;
+                               if (hadpr)
+                                       shudclob = 1;
+                       }
+                       plines(addr1, addr2, 1);
+                       continue;
+
+/* # */
+               case '#':
+numberit:
+                       setCNL();
+                       ignorf(setnumb(1));
+                       pflag = 0;
+                       goto print;
+
+/* = */
+               case '=':
+                       newline();
+                       setall();
+                       printf("%d", lineno(addr2));
+                       noonl();
+                       continue;
+
+/* ! */
+               case '!':
+                       if (addr2 != 0) {
+                               unix0(0);
+                               setdot();
+                               filter(2);
+                       } else {
+                               unix0(1);
+                               vnfl();
+                               unixwt(1, unixex("-c", uxb, 0, 0));
+                               vcontin(1);
+                       }
+                       continue;
+
+/* < */
+/* > */
+               case '<':
+               case '>':
+                       for (cnt = 1; peekchar() == c; cnt++)
+                               ignchar();
+                       setCNL();
+                       shift(c, cnt);
+                       continue;
+
+/* ^D */
+/* EOF */
+               case CTRL(d):
+               case EOF:
+                       if (exitoneof) {
+                               if (addr2 != 0)
+                                       dot = addr2;
+                               return;
+                       }
+                       if (!isatty(0)) {
+                               if (intty)
+                                       /*
+                                        * Chtty sys call at UCB may cause a
+                                        * input which was a tty to suddenly be
+                                        * turned into /dev/null.
+                                        */
+                                       onhup();
+                               return;
+                       }
+                       if (addr2 != 0) {
+                               setlastchar('\n');
+                               putnl();
+                       }
+                       if (dol == zero) {
+                               if (addr2 == 0)
+                                       putnl();
+                               notempty();
+                       }
+                       ungetchar(EOF);
+                       zop(hadpr);
+                       continue;
+
+               default:
+                       if (!isalpha(c))
+                               break;
+                       ungetchar(c);
+                       tailprim("", 0, 0);
+               }
+               error("What?|Unknown command character '%c'", c);
+       }
+}
diff --git a/src/ex/ex_cmds2.c b/src/ex/ex_cmds2.c
new file mode 100644 (file)
index 0000000..c290244
--- /dev/null
@@ -0,0 +1,491 @@
+/* Copyright (c) 1979 Regents of the University of California */
+#include "ex.h"
+#include "ex_argv.h"
+#include "ex_temp.h"
+#include "ex_tty.h"
+#include "ex_vis.h"
+
+bool   pflag, nflag;
+int    poffset;
+
+/*
+ * Subroutines for major command loop.
+ */
+
+/*
+ * Is there a single letter indicating a named buffer next?
+ */
+cmdreg()
+{
+       register int c = 0;
+
+       pastwh();
+       if (isalpha(peekchar()))
+               c = getchar();
+       return (c);
+}
+
+/*
+ * Tell whether the character ends a command
+ */
+endcmd(ch)
+       int ch;
+{
+       switch (ch) {
+       
+       case '\n':
+       case EOF:
+               endline = 1;
+               return (1);
+       
+       case '|':
+               endline = 0;
+               return (1);
+       }
+       return (0);
+}
+
+/*
+ * Insist on the end of the command.
+ */
+eol()
+{
+
+       if (!skipend())
+               error("Extra chars|Extra characters at end of command");
+       ignnEOF();
+}
+
+/*
+ * Print out the message in the error message file at str,
+ * with i an integer argument to printf.
+ */
+/*VARARGS2*/
+error(str, i)
+#ifdef lint
+       register char *str;
+#else
+       register int str;
+#endif
+       int i;
+{
+
+       error0();
+       merror(str, i);
+       error1(str);
+}
+
+/*
+ * Rewind the argument list.
+ */
+erewind()
+{
+
+       argc = argc0;
+       argv = argv0;
+       args = args0;
+       if (argc > 1 && !hush) {
+               printf(mesg("%d files@to edit"), argc);
+               if (inopen)
+                       putchar(' ');
+               else
+                       putNFL();
+       }
+}
+
+/*
+ * Guts of the pre-printing error processing.
+ * If in visual and catching errors, then we dont mung up the internals,
+ * just fixing up the echo area for the print.
+ * Otherwise we reset a number of externals, and discard unused input.
+ */
+error0()
+{
+
+       intag = 0;
+       if (vcatch) {
+               if (splitw == 0)
+                       fixech();
+               if (!SO || !SE)
+                       dingdong();
+               return;
+       }
+       if (input) {
+               input = strend(input) - 1;
+               if (*input == '\n')
+                       setlastchar('\n');
+               input = 0;
+       }
+       setoutt();
+       flush();
+       resetflav();
+       if (laste) {
+               laste = 0;
+               sync();
+       }
+       if (!SO || !SE)
+               dingdong();
+       if (inopen) {
+               /*
+                * We are coming out of open/visual ungracefully.
+                * Restore COLUMNS, undo, and fix tty mode.
+                */
+               COLUMNS = OCOLUMNS;
+               undvis();
+               ostop(normf);
+               putpad(VE);
+               putnl();
+       }
+       inopen = 0;
+       holdcm = 0;
+}
+
+/*
+ * Post error printing processing.
+ * Close the i/o file if left open.
+ * If catching in visual then throw to the visual catch,
+ * else if a child after a fork, then exit.
+ * Otherwise, in the normal command mode error case,
+ * finish state reset, and throw to top.
+ */
+error1(str)
+       char *str;
+{
+
+       if (io > 0) {
+               close(io);
+               io = -1;
+       }
+       if (vcatch && !die) {
+               inglobal = 0;
+               inopen = 1;
+               vcatch = 0;
+               fixol();
+               longjmp(vreslab);
+       }
+       if (str)
+               putNFL();
+       if (die)
+               exit(1);
+       lseek(0, 0L, 2);
+       if (inglobal)
+               setlastchar('\n');
+       inglobal = 0;
+       globp = 0;
+       while (lastchar() != '\n' && lastchar() != EOF)
+               ignchar();
+       ungetchar(0);
+       endline = 1;
+       reset();
+}
+
+fixol()
+{
+       if (Outchar != vputchar) {
+               flush();
+               if (state == ONEOPEN || state == HARDOPEN)
+                       outline = destline = 0;
+               Outchar = vputchar;
+               vcontin(1);
+       } else {
+               if (destcol)
+                       vclreol();
+               vclean();
+       }
+}
+
+/*
+ * Does an ! character follow in the command stream?
+ */
+exclam()
+{
+
+       if (peekchar() == '!') {
+               ignchar();
+               return (1);
+       }
+       return (0);
+}
+
+/*
+ * Make an argument list for e.g. next.
+ */
+makargs()
+{
+
+       glob(&frob);
+       argc0 = frob.argc0;
+       argv0 = frob.argv;
+       args0 = argv0[0];
+       erewind();
+}
+
+/*
+ * Advance to next file in argument list.
+ */
+next()
+{
+
+       if (argc == 0)
+               error("No more files@to edit");
+       morargc = argc;
+       if (savedfile[0])
+               CP(altfile, savedfile);
+       CP(savedfile, args);
+       argc--;
+       args = argv ? *++argv : strend(args) + 1;
+}
+
+/*
+ * Eat trailing flags and offsets after a command,
+ * saving for possible later post-command prints.
+ */
+newline()
+{
+       register int c;
+
+       resetflav();
+       for (;;) {
+               c = getchar();
+               switch (c) {
+
+               case '^':
+               case '-':
+                       poffset--;
+                       break;
+
+               case '+':
+                       poffset++;
+                       break;
+
+               case 'l':
+                       listf++;
+                       break;
+
+               case '#':
+                       nflag++;
+                       break;
+
+               case 'p':
+                       listf = 0;
+                       break;
+
+               case ' ':
+               case '\t':
+                       continue;
+
+               default:
+                       if (!endcmd(c))
+                               serror("Extra chars|Extra characters at end of \"%s\" command", Command);
+                       if (c == EOF)
+                               ungetchar(c);
+                       setflav();
+                       return;
+               }
+               pflag++;
+       }
+}
+
+/*
+ * Before quit or respec of arg list, check that there are
+ * no more files in the arg list.
+ */
+nomore()
+{
+
+       if (argc == 0 || morargc == argc)
+               return;
+       morargc = argc;
+       merror("%d more file", argc);
+       serror("%s@to edit", plural((long) argc));
+}
+
+/*
+ * Before edit of new file check that either an ! follows
+ * or the file has not been changed.
+ */
+quickly()
+{
+
+       if (exclam())
+               return (1);
+       if (chng) {
+/*
+               chng = 0;
+*/
+               xchng = 0;
+               error("No write@since last change (%s! overrides)", Command);
+       }
+       return (0);
+}
+
+/*
+ * Reset the flavor of the output to print mode with no numbering.
+ */
+resetflav()
+{
+
+       if (inopen)
+               return;
+       listf = 0;
+       nflag = 0;
+       pflag = 0;
+       poffset = 0;
+       setflav();
+}
+
+/*
+ * Print an error message with a %s type argument to printf.
+ * Message text comes from error message file.
+ */
+serror(str, cp)
+#ifdef lint
+       register char *str;
+#else
+       register int str;
+#endif
+       char *cp;
+{
+
+       error0();
+       smerror(str, cp);
+       error1(str);
+}
+
+/*
+ * Set the flavor of the output based on the flags given
+ * and the number and list options to either number or not number lines
+ * and either use normally decoded (ARPAnet standard) characters or list mode,
+ * where end of lines are marked and tabs print as ^I.
+ */
+setflav()
+{
+
+       if (inopen)
+               return;
+       setnumb(nflag || value(NUMBER));
+       setlist(listf || value(LIST));
+       setoutt();
+}
+
+/*
+ * Skip white space and tell whether command ends then.
+ */
+skipend()
+{
+
+       pastwh();
+       return (endcmd(peekchar()));
+}
+
+/*
+ * Set the command name for non-word commands.
+ */
+tailspec(c)
+       int c;
+{
+       static char foocmd[2];
+
+       foocmd[0] = c;
+       Command = foocmd;
+}
+
+/*
+ * Try to read off the rest of the command word.
+ * If alphabetics follow, then this is not the command we seek.
+ */
+tail(comm)
+       char *comm;
+{
+
+       tailprim(comm, 1, 0);
+}
+
+tail2of(comm)
+       char *comm;
+{
+
+       tailprim(comm, 2, 0);
+}
+
+char   tcommand[20];
+
+tailprim(comm, i, notinvis)
+       register char *comm;
+       int i;
+       bool notinvis;
+{
+       register char *cp;
+       register int c;
+
+       Command = comm;
+       for (cp = tcommand; i > 0; i--)
+               *cp++ = *comm++;
+       while (*comm && peekchar() == *comm)
+               *cp++ = getchar(), comm++;
+       c = peekchar();
+       if (notinvis || isalpha(c)) {
+               /*
+                * Of the trailing lp funny buisness, only dl and dp
+                * survive the move from ed to ex.
+                */
+               if (tcommand[0] == 'd' && any(c, "lp"))
+                       goto ret;
+               while (cp < &tcommand[19] && isalpha(peekchar()))
+                       *cp++ = getchar();
+               *cp = 0;
+               if (notinvis)
+                       serror("What?|%s: No such command from open/visual", tcommand);
+               else
+                       serror("What?|%s: Not an editor command", tcommand);
+       }
+ret:
+       *cp = 0;
+}
+
+/*
+ * Continue after a shell escape from open/visual.
+ */
+vcontin(ask)
+       bool ask;
+{
+
+       if (vcnt > 0)
+               vcnt = -vcnt;
+       if (inopen) {
+               if (state != VISUAL) {
+/*
+                       vtube[WECHO][0] = '*';
+                       vnfl();
+*/
+                       return;
+               }
+               if (ask) {
+                       merror("[Hit return to continue] ");
+                       flush();
+               }
+#ifdef V6
+               vraw();
+#endif
+               if (ask && getkey() == ':')
+                       ungetkey(':');
+       }
+}
+
+/*
+ * Put out a newline (before a shell escape)
+ * if in open/visual.
+ */
+vnfl()
+{
+
+       if (inopen) {
+               if (state != VISUAL && state != CRTOPEN && destline <= WECHO)
+                       vclean();
+               else
+                       vmoveitup(1);
+               vgoto(WECHO, 0);
+               vclrbyte(vtube[WECHO], WCOLS);
+               flush();
+       }
+}