Merge from vendor branch LESS:
[dragonfly.git] / contrib / nvi / ex / ex.c
1 /*-
2  * Copyright (c) 1992, 1993, 1994
3  *      The Regents of the University of California.  All rights reserved.
4  * Copyright (c) 1992, 1993, 1994, 1995, 1996
5  *      Keith Bostic.  All rights reserved.
6  *
7  * See the LICENSE file for redistribution information.
8  */
9
10 /* $FreeBSD: src/contrib/nvi/ex/ex.c,v 1.2 1999/09/14 14:34:58 ru Exp $ */
11 /* $DragonFly: src/contrib/nvi/ex/ex.c,v 1.2 2003/06/17 04:24:04 dillon Exp $ */
12
13 #include "config.h"
14
15 #ifndef lint
16 static const char sccsid[] = "@(#)ex.c  10.57 (Berkeley) 10/10/96";
17 #endif /* not lint */
18
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/stat.h>
22 #include <sys/time.h>
23
24 #include <bitstring.h>
25 #include <ctype.h>
26 #include <errno.h>
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33
34 #include "../common/common.h"
35 #include "../vi/vi.h"
36
37 #if defined(DEBUG) && defined(COMLOG)
38 static void     ex_comlog __P((SCR *, EXCMD *));
39 #endif
40 static EXCMDLIST const *
41                 ex_comm_search __P((char *, size_t));
42 static int      ex_discard __P((SCR *));
43 static int      ex_line __P((SCR *, EXCMD *, MARK *, int *, int *));
44 static int      ex_load __P((SCR *));
45 static void     ex_unknown __P((SCR *, char *, size_t));
46
47 /*
48  * ex --
49  *      Main ex loop.
50  *
51  * PUBLIC: int ex __P((SCR **));
52  */
53 int
54 ex(spp)
55         SCR **spp;
56 {
57         EX_PRIVATE *exp;
58         GS *gp;
59         MSGS *mp;
60         SCR *sp;
61         TEXT *tp;
62         u_int32_t flags;
63
64         sp = *spp;
65         gp = sp->gp;
66         exp = EXP(sp);
67
68         /* Start the ex screen. */
69         if (ex_init(sp))
70                 return (1);
71
72         /* Flush any saved messages. */
73         while ((mp = gp->msgq.lh_first) != NULL) {
74                 gp->scr_msg(sp, mp->mtype, mp->buf, mp->len);
75                 LIST_REMOVE(mp, q);
76                 free(mp->buf);
77                 free(mp);
78         }
79
80         /* If reading from a file, errors should have name and line info. */
81         if (F_ISSET(gp, G_SCRIPTED)) {
82                 gp->excmd.if_lno = 1;
83                 gp->excmd.if_name = "script";
84         }
85
86         /*
87          * !!!
88          * Initialize the text flags.  The beautify edit option historically
89          * applied to ex command input read from a file.  In addition, the
90          * first time a ^H was discarded from the input, there was a message,
91          * "^H discarded", that was displayed.  We don't bother.
92          */
93         LF_INIT(TXT_BACKSLASH | TXT_CNTRLD | TXT_CR);
94         for (;; ++gp->excmd.if_lno) {
95                 /* Display status line and flush. */
96                 if (F_ISSET(sp, SC_STATUS)) {
97                         if (!F_ISSET(sp, SC_EX_SILENT))
98                                 msgq_status(sp, sp->lno, 0);
99                         F_CLR(sp, SC_STATUS);
100                 }
101                 (void)ex_fflush(sp);
102
103                 /* Set the flags the user can reset. */
104                 if (O_ISSET(sp, O_BEAUTIFY))
105                         LF_SET(TXT_BEAUTIFY);
106                 if (O_ISSET(sp, O_PROMPT))
107                         LF_SET(TXT_PROMPT);
108
109                 /* Clear any current interrupts, and get a command. */
110                 CLR_INTERRUPT(sp);
111                 if (ex_txt(sp, &sp->tiq, ':', flags))
112                         return (1);
113                 if (INTERRUPTED(sp)) {
114                         (void)ex_puts(sp, "\n");
115                         (void)ex_fflush(sp);
116                         continue;
117                 }
118
119                 /* Initialize the command structure. */
120                 CLEAR_EX_PARSER(&gp->excmd);
121
122                 /*
123                  * If the user entered a single carriage return, send
124                  * ex_cmd() a separator -- it discards single newlines.
125                  */
126                 tp = sp->tiq.cqh_first;
127                 if (tp->len == 0) {
128                         gp->excmd.cp = " ";     /* __TK__ why not |? */
129                         gp->excmd.clen = 1;
130                 } else {
131                         gp->excmd.cp = tp->lb;
132                         gp->excmd.clen = tp->len;
133                 }
134                 F_INIT(&gp->excmd, E_NRSEP);
135
136                 if (ex_cmd(sp) && F_ISSET(gp, G_SCRIPTED))
137                         return (1);
138
139                 if (INTERRUPTED(sp)) {
140                         CLR_INTERRUPT(sp);
141                         msgq(sp, M_ERR, "170|Interrupted");
142                 }
143
144                 /*
145                  * If the last command caused a restart, or switched screens
146                  * or into vi, return.
147                  */
148                 if (F_ISSET(gp, G_SRESTART) || F_ISSET(sp, SC_SSWITCH | SC_VI)) {
149                         *spp = sp;
150                         break;
151                 }
152
153                 /* If the last command switched files, we don't care. */
154                 F_CLR(sp, SC_FSWITCH);
155
156                 /*
157                  * If we're exiting this screen, move to the next one.  By
158                  * definition, this means returning into vi, so return to the
159                  * main editor loop.  The ordering is careful, don't discard
160                  * the contents of sp until the end.
161                  */
162                 if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) {
163                         if (file_end(sp, NULL, F_ISSET(sp, SC_EXIT_FORCE)))
164                                 return (1);
165                         *spp = screen_next(sp);
166                         return (screen_end(sp));
167                 }
168         }
169         return (0);
170 }
171
172 /*
173  * ex_cmd --
174  *      The guts of the ex parser: parse and execute a string containing
175  *      ex commands.
176  *
177  * !!!
178  * This code MODIFIES the string that gets passed in, to delete quoting
179  * characters, etc.  The string cannot be readonly/text space, nor should
180  * you expect to use it again after ex_cmd() returns.
181  *
182  * !!!
183  * For the fun of it, if you want to see if a vi clone got the ex argument
184  * parsing right, try:
185  *
186  *      echo 'foo|bar' > file1; echo 'foo/bar' > file2;
187  *      vi
188  *      :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq
189  *
190  * or:  vi
191  *      :set|file|append|set|file
192  *
193  * For extra credit, try them in a startup .exrc file.
194  *
195  * PUBLIC: int ex_cmd __P((SCR *));
196  */
197 int
198 ex_cmd(sp)
199         SCR *sp;
200 {
201         enum nresult nret;
202         EX_PRIVATE *exp;
203         EXCMD *ecp;
204         GS *gp;
205         MARK cur;
206         recno_t lno;
207         size_t arg1_len, discard, len;
208         u_int32_t flags;
209         long ltmp;
210         int at_found, gv_found;
211         int ch, cnt, delim, isaddr, namelen;
212         int newscreen, notempty, tmp, vi_address;
213         char *arg1, *p, *s, *t;
214
215         gp = sp->gp;
216         exp = EXP(sp);
217
218         /*
219          * We always start running the command on the top of the stack.
220          * This means that *everything* must be resolved when we leave
221          * this function for any reason.
222          */
223 loop:   ecp = gp->ecq.lh_first;
224
225         /* If we're reading a command from a file, set up error information. */
226         if (ecp->if_name != NULL) {
227                 gp->if_lno = ecp->if_lno;
228                 gp->if_name = ecp->if_name;
229         }
230
231         /*
232          * If a move to the end of the file is scheduled for this command,
233          * do it now.
234          */
235         if (F_ISSET(ecp, E_MOVETOEND)) {
236                 if (db_last(sp, &sp->lno))
237                         goto rfail;
238                 sp->cno = 0;
239                 F_CLR(ecp, E_MOVETOEND);
240         }
241
242         /* If we found a newline, increment the count now. */
243         if (F_ISSET(ecp, E_NEWLINE)) {
244                 ++gp->if_lno;
245                 ++ecp->if_lno;
246                 F_CLR(ecp, E_NEWLINE);
247         }
248
249         /* (Re)initialize the EXCMD structure, preserving some flags. */
250         CLEAR_EX_CMD(ecp);
251
252         /* Initialize the argument structures. */
253         if (argv_init(sp, ecp))
254                 goto err;
255
256         /* Initialize +cmd, saved command information. */
257         arg1 = NULL;
258         ecp->save_cmdlen = 0;
259
260         /* Skip <blank>s, empty lines.  */
261         for (notempty = 0; ecp->clen > 0; ++ecp->cp, --ecp->clen)
262                 if ((ch = *ecp->cp) == '\n') {
263                         ++gp->if_lno;
264                         ++ecp->if_lno;
265                 } else if (isblank(ch))
266                         notempty = 1;
267                 else
268                         break;
269
270         /*
271          * !!!
272          * Permit extra colons at the start of the line.  Historically,
273          * ex/vi allowed a single extra one.  It's simpler not to count.
274          * The stripping is done here because, historically, any command
275          * could have preceding colons, e.g. ":g/pattern/:p" worked.
276          */
277         if (ecp->clen != 0 && ch == ':') {
278                 notempty = 1;
279                 while (--ecp->clen > 0 && (ch = *++ecp->cp) == ':');
280         }
281
282         /*
283          * Command lines that start with a double-quote are comments.
284          *
285          * !!!
286          * Historically, there was no escape or delimiter for a comment, e.g.
287          * :"foo|set was a single comment and nothing was output.  Since nvi
288          * permits users to escape <newline> characters into command lines, we
289          * have to check for that case.
290          */
291         if (ecp->clen != 0 && ch == '"') {
292                 while (--ecp->clen > 0 && *++ecp->cp != '\n');
293                 if (*ecp->cp == '\n') {
294                         F_SET(ecp, E_NEWLINE);
295                         ++ecp->cp;
296                         --ecp->clen;
297                 }
298                 goto loop;
299         }
300
301         /* Skip whitespace. */
302         for (; ecp->clen > 0; ++ecp->cp, --ecp->clen) {
303                 ch = *ecp->cp;
304                 if (!isblank(ch))
305                         break;
306         }
307
308         /*
309          * The last point at which an empty line can mean do nothing.
310          *
311          * !!!
312          * Historically, in ex mode, lines containing only <blank> characters
313          * were the same as a single <carriage-return>, i.e. a default command.
314          * In vi mode, they were ignored.  In .exrc files this was a serious
315          * annoyance, as vi kept trying to treat them as print commands.  We
316          * ignore backward compatibility in this case, discarding lines that
317          * contain only <blank> characters from .exrc files.
318          *
319          * !!!
320          * This is where you end up when you're done a command, i.e. clen has
321          * gone to zero.  Continue if there are more commands to run.
322          */
323         if (ecp->clen == 0 &&
324             (!notempty || F_ISSET(sp, SC_VI) || F_ISSET(ecp, E_BLIGNORE))) {
325                 if (ex_load(sp))
326                         goto rfail;
327                 ecp = gp->ecq.lh_first;
328                 if (ecp->clen == 0)
329                         goto rsuccess;
330                 goto loop;
331         }
332
333         /*
334          * Check to see if this is a command for which we may want to move
335          * the cursor back up to the previous line.  (The command :1<CR>
336          * wants a <newline> separator, but the command :<CR> wants to erase
337          * the command line.)  If the line is empty except for <blank>s,
338          * <carriage-return> or <eof>, we'll probably want to move up.  I
339          * don't think there's any way to get <blank> characters *after* the
340          * command character, but this is the ex parser, and I've been wrong
341          * before.
342          */
343         if (F_ISSET(ecp, E_NRSEP) &&
344             ecp->clen != 0 && (ecp->clen != 1 || ecp->cp[0] != '\004'))
345                 F_CLR(ecp, E_NRSEP);
346
347         /* Parse command addresses. */
348         if (ex_range(sp, ecp, &tmp))
349                 goto rfail;
350         if (tmp)
351                 goto err;
352
353         /*
354          * Skip <blank>s and any more colons (the command :3,5:print
355          * worked, historically).
356          */
357         for (; ecp->clen > 0; ++ecp->cp, --ecp->clen) {
358                 ch = *ecp->cp;
359                 if (!isblank(ch) && ch != ':')
360                         break;
361         }
362
363         /*
364          * If no command, ex does the last specified of p, l, or #, and vi
365          * moves to the line.  Otherwise, determine the length of the command
366          * name by looking for the first non-alphabetic character.  (There
367          * are a few non-alphabetic characters in command names, but they're
368          * all single character commands.)  This isn't a great test, because
369          * it means that, for the command ":e +cut.c file", we'll report that
370          * the command "cut" wasn't known.  However, it makes ":e+35 file" work
371          * correctly.
372          *
373          * !!!
374          * Historically, lines with multiple adjacent (or <blank> separated)
375          * command separators were very strange.  For example, the command
376          * |||<carriage-return>, when the cursor was on line 1, displayed
377          * lines 2, 3 and 5 of the file.  In addition, the command "   |  "
378          * would only display the line after the next line, instead of the
379          * next two lines.  No ideas why.  It worked reasonably when executed
380          * from vi mode, and displayed lines 2, 3, and 4, so we do a default
381          * command for each separator.
382          */
383 #define SINGLE_CHAR_COMMANDS    "\004!#&*<=>@~"
384         newscreen = 0;
385         if (ecp->clen != 0 && ecp->cp[0] != '|' && ecp->cp[0] != '\n') {
386                 if (strchr(SINGLE_CHAR_COMMANDS, *ecp->cp)) {
387                         p = ecp->cp;
388                         ++ecp->cp;
389                         --ecp->clen;
390                         namelen = 1;
391                 } else {
392                         for (p = ecp->cp;
393                             ecp->clen > 0; --ecp->clen, ++ecp->cp)
394                                 if (!isalpha(*ecp->cp))
395                                         break;
396                         if ((namelen = ecp->cp - p) == 0) {
397                                 msgq(sp, M_ERR, "080|Unknown command name");
398                                 goto err;
399                         }
400                 }
401
402                 /*
403                  * !!!
404                  * Historic vi permitted flags to immediately follow any
405                  * subset of the 'delete' command, but then did not permit
406                  * further arguments (flag, buffer, count).  Make it work.
407                  * Permit further arguments for the few shreds of dignity
408                  * it offers.
409                  *
410                  * Adding commands that start with 'd', and match "delete"
411                  * up to a l, p, +, - or # character can break this code.
412                  *
413                  * !!!
414                  * Capital letters beginning the command names ex, edit,
415                  * next, previous, tag and visual (in vi mode) indicate the
416                  * command should happen in a new screen.
417                  */
418                 switch (p[0]) {
419                 case 'd':
420                         for (s = p,
421                             t = cmds[C_DELETE].name; *s == *t; ++s, ++t);
422                         if (s[0] == 'l' || s[0] == 'p' || s[0] == '+' ||
423                             s[0] == '-' || s[0] == '^' || s[0] == '#') {
424                                 len = (ecp->cp - p) - (s - p);
425                                 ecp->cp -= len;
426                                 ecp->clen += len;
427                                 ecp->rcmd = cmds[C_DELETE];
428                                 ecp->rcmd.syntax = "1bca1";
429                                 ecp->cmd = &ecp->rcmd;
430                                 goto skip_srch;
431                         }
432                         break;
433                 case 'E': case 'F': case 'N': case 'P': case 'T': case 'V':
434                         newscreen = 1;
435                         p[0] = tolower(p[0]);
436                         break;
437                 }
438
439                 /*
440                  * Search the table for the command.
441                  *
442                  * !!!
443                  * Historic vi permitted the mark to immediately follow the
444                  * 'k' in the 'k' command.  Make it work.
445                  *
446                  * !!!
447                  * Historic vi permitted any flag to follow the s command, e.g.
448                  * "s/e/E/|s|sgc3p" was legal.  Make the command "sgc" work.
449                  * Since the following characters all have to be flags, i.e.
450                  * alphabetics, we can let the s command routine return errors
451                  * if it was some illegal command string.  This code will break
452                  * if an "sg" or similar command is ever added.  The substitute
453                  * code doesn't care if it's a "cgr" flag or a "#lp" flag that
454                  * follows the 's', but we limit the choices here to "cgr" so
455                  * that we get unknown command messages for wrong combinations.
456                  */
457                 if ((ecp->cmd = ex_comm_search(p, namelen)) == NULL)
458                         switch (p[0]) {
459                         case 'k':
460                                 if (namelen == 2) {
461                                         ecp->cp -= namelen - 1;
462                                         ecp->clen += namelen - 1;
463                                         ecp->cmd = &cmds[C_K];
464                                         break;
465                                 }
466                                 goto unknown;
467                         case 's':
468                                 for (s = p + 1, cnt = namelen; --cnt; ++s)
469                                         if (s[0] != 'c' &&
470                                             s[0] != 'g' && s[0] != 'r')
471                                                 break;
472                                 if (cnt == 0) {
473                                         ecp->cp -= namelen - 1;
474                                         ecp->clen += namelen - 1;
475                                         ecp->rcmd = cmds[C_SUBSTITUTE];
476                                         ecp->rcmd.fn = ex_subagain;
477                                         ecp->cmd = &ecp->rcmd;
478                                         break;
479                                 }
480                                 /* FALLTHROUGH */
481                         default:
482 unknown:                        if (newscreen)
483                                         p[0] = toupper(p[0]);
484                                 ex_unknown(sp, p, namelen);
485                                 goto err;
486                         }
487
488                 /*
489                  * The visual command has a different syntax when called
490                  * from ex than when called from a vi colon command.  FMH.
491                  * Make the change now, before we test for the newscreen
492                  * semantic, so that we're testing the right one.
493                  */
494 skip_srch:      if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI))
495                         ecp->cmd = &cmds[C_VISUAL_VI];
496
497                 /*
498                  * !!!
499                  * Historic vi permitted a capital 'P' at the beginning of
500                  * any command that started with 'p'.  Probably wanted the
501                  * P[rint] command for backward compatibility, and the code
502                  * just made Preserve and Put work by accident.  Nvi uses
503                  * Previous to mean previous-in-a-new-screen, so be careful.
504                  */
505                 if (newscreen && !F_ISSET(ecp->cmd, E_NEWSCREEN) &&
506                     (ecp->cmd == &cmds[C_PRINT] ||
507                     ecp->cmd == &cmds[C_PRESERVE]))
508                         newscreen = 0;
509
510                 /* Test for a newscreen associated with this command. */
511                 if (newscreen && !F_ISSET(ecp->cmd, E_NEWSCREEN))
512                         goto unknown;
513
514                 /* Secure means no shell access. */
515                 if (F_ISSET(ecp->cmd, E_SECURE) && O_ISSET(sp, O_SECURE)) {
516                         ex_emsg(sp, ecp->cmd->name, EXM_SECURE);
517                         goto err;
518                 }
519
520                 /*
521                  * Multiple < and > characters; another "feature".  Note,
522                  * The string passed to the underlying function may not be
523                  * nul terminated in this case.
524                  */
525                 if ((ecp->cmd == &cmds[C_SHIFTL] && *p == '<') ||
526                     (ecp->cmd == &cmds[C_SHIFTR] && *p == '>')) {
527                         for (ch = *p;
528                             ecp->clen > 0; --ecp->clen, ++ecp->cp)
529                                 if (*ecp->cp != ch)
530                                         break;
531                         if (argv_exp0(sp, ecp, p, ecp->cp - p))
532                                 goto err;
533                 }
534
535                 /* Set the format style flags for the next command. */
536                 if (ecp->cmd == &cmds[C_HASH])
537                         exp->fdef = E_C_HASH;
538                 else if (ecp->cmd == &cmds[C_LIST])
539                         exp->fdef = E_C_LIST;
540                 else if (ecp->cmd == &cmds[C_PRINT])
541                         exp->fdef = E_C_PRINT;
542                 F_CLR(ecp, E_USELASTCMD);
543         } else {
544                 /* Print is the default command. */
545                 ecp->cmd = &cmds[C_PRINT];
546
547                 /* Set the saved format flags. */
548                 F_SET(ecp, exp->fdef);
549
550                 /*
551                  * !!!
552                  * If no address was specified, and it's not a global command,
553                  * we up the address by one.  (I have no idea why globals are
554                  * exempted, but it's (ahem) historic practice.)
555                  */
556                 if (ecp->addrcnt == 0 && !F_ISSET(sp, SC_EX_GLOBAL)) {
557                         ecp->addrcnt = 1;
558                         ecp->addr1.lno = sp->lno + 1;
559                         ecp->addr1.cno = sp->cno;
560                 }
561
562                 F_SET(ecp, E_USELASTCMD);
563         }
564
565         /*
566          * !!!
567          * Historically, the number option applied to both ex and vi.  One
568          * strangeness was that ex didn't switch display formats until a
569          * command was entered, e.g. <CR>'s after the set didn't change to
570          * the new format, but :1p would.
571          */
572         if (O_ISSET(sp, O_NUMBER)) {
573                 F_SET(ecp, E_OPTNUM);
574                 FL_SET(ecp->iflags, E_C_HASH);
575         } else
576                 F_CLR(ecp, E_OPTNUM);
577
578         /* Check for ex mode legality. */
579         if (F_ISSET(sp, SC_EX) && (F_ISSET(ecp->cmd, E_VIONLY) || newscreen)) {
580                 msgq(sp, M_ERR,
581                     "082|%s: command not available in ex mode", ecp->cmd->name);
582                 goto err;
583         }
584
585         /* Add standard command flags. */
586         F_SET(ecp, ecp->cmd->flags);
587         if (!newscreen)
588                 F_CLR(ecp, E_NEWSCREEN);
589
590         /*
591          * There are three normal termination cases for an ex command.  They
592          * are the end of the string (ecp->clen), or unescaped (by <literal
593          * next> characters) <newline> or '|' characters.  As we're now past
594          * possible addresses, we can determine how long the command is, so we
595          * don't have to look for all the possible terminations.  Naturally,
596          * there are some exciting special cases:
597          *
598          * 1: The bang, global, v and the filter versions of the read and
599          *    write commands are delimited by <newline>s (they can contain
600          *    shell pipes).
601          * 2: The ex, edit, next and visual in vi mode commands all take ex
602          *    commands as their first arguments.
603          * 3: The s command takes an RE as its first argument, and wants it
604          *    to be specially delimited.
605          *
606          * Historically, '|' characters in the first argument of the ex, edit,
607          * next, vi visual, and s commands didn't delimit the command.  And,
608          * in the filter cases for read and write, and the bang, global and v
609          * commands, they did not delimit the command at all.
610          *
611          * For example, the following commands were legal:
612          *
613          *      :edit +25|s/abc/ABC/ file.c
614          *      :s/|/PIPE/
615          *      :read !spell % | columnate
616          *      :global/pattern/p|l
617          *
618          * It's not quite as simple as it sounds, however.  The command:
619          *
620          *      :s/a/b/|s/c/d|set
621          *
622          * was also legal, i.e. the historic ex parser (using the word loosely,
623          * since "parser" implies some regularity of syntax) delimited the RE's
624          * based on its delimiter and not anything so irretrievably vulgar as a
625          * command syntax.
626          *
627          * Anyhow, the following code makes this all work.  First, for the
628          * special cases we move past their special argument(s).  Then, we
629          * do normal command processing on whatever is left.  Barf-O-Rama.
630          */
631         discard = 0;            /* Characters discarded from the command. */
632         arg1_len = 0;
633         ecp->save_cmd = ecp->cp;
634         if (ecp->cmd == &cmds[C_EDIT] || ecp->cmd == &cmds[C_EX] ||
635             ecp->cmd == &cmds[C_NEXT] || ecp->cmd == &cmds[C_VISUAL_VI]) {
636                 /*
637                  * Move to the next non-whitespace character.  A '!'
638                  * immediately following the command is eaten as a
639                  * force flag.
640                  */
641                 if (ecp->clen > 0 && *ecp->cp == '!') {
642                         ++ecp->cp;
643                         --ecp->clen;
644                         FL_SET(ecp->iflags, E_C_FORCE);
645
646                         /* Reset, don't reparse. */
647                         ecp->save_cmd = ecp->cp;
648                 }
649                 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp)
650                         if (!isblank(*ecp->cp))
651                                 break;
652                 /*
653                  * QUOTING NOTE:
654                  *
655                  * The historic implementation ignored all escape characters
656                  * so there was no way to put a space or newline into the +cmd
657                  * field.  We do a simplistic job of fixing it by moving to the
658                  * first whitespace character that isn't escaped.  The escaping
659                  * characters are stripped as no longer useful.
660                  */
661                 if (ecp->clen > 0 && *ecp->cp == '+') {
662                         ++ecp->cp;
663                         --ecp->clen;
664                         for (arg1 = p = ecp->cp;
665                             ecp->clen > 0; --ecp->clen, ++ecp->cp) {
666                                 ch = *ecp->cp;
667                                 if (IS_ESCAPE(sp, ecp, ch) &&
668                                     ecp->clen > 1) {
669                                         ++discard;
670                                         --ecp->clen;
671                                         ch = *++ecp->cp;
672                                 } else if (isblank(ch))
673                                         break;
674                                 *p++ = ch;
675                         }
676                         arg1_len = ecp->cp - arg1;
677
678                         /* Reset, so the first argument isn't reparsed. */
679                         ecp->save_cmd = ecp->cp;
680                 }
681         } else if (ecp->cmd == &cmds[C_BANG] ||
682             ecp->cmd == &cmds[C_GLOBAL] || ecp->cmd == &cmds[C_V]) {
683                 /*
684                  * QUOTING NOTE:
685                  *
686                  * We use backslashes to escape <newline> characters, although
687                  * this wasn't historic practice for the bang command.  It was
688                  * for the global and v commands, and it's common usage when
689                  * doing text insert during the command.  Escaping characters
690                  * are stripped as no longer useful.
691                  */
692                 for (p = ecp->cp; ecp->clen > 0; --ecp->clen, ++ecp->cp) {
693                         ch = *ecp->cp;
694                         if (ch == '\\' && ecp->clen > 1 && ecp->cp[1] == '\n') {
695                                 ++discard;
696                                 --ecp->clen;
697                                 ch = *++ecp->cp;
698
699                                 ++gp->if_lno;
700                                 ++ecp->if_lno;
701                         } else if (ch == '\n')
702                                 break;
703                         *p++ = ch;
704                 }
705         } else if (ecp->cmd == &cmds[C_READ] || ecp->cmd == &cmds[C_WRITE]) {
706                 /*
707                  * For write commands, if the next character is a <blank>, and
708                  * the next non-blank character is a '!', it's a filter command
709                  * and we want to eat everything up to the <newline>.  For read
710                  * commands, if the next non-blank character is a '!', it's a
711                  * filter command and we want to eat everything up to the next
712                  * <newline>.  Otherwise, we're done.
713                  */
714                 for (tmp = 0; ecp->clen > 0; --ecp->clen, ++ecp->cp) {
715                         ch = *ecp->cp;
716                         if (isblank(ch))
717                                 tmp = 1;
718                         else
719                                 break;
720                 }
721                 if (ecp->clen > 0 && ch == '!' &&
722                     (ecp->cmd == &cmds[C_READ] || tmp))
723                         for (; ecp->clen > 0; --ecp->clen, ++ecp->cp)
724                                 if (ecp->cp[0] == '\n')
725                                         break;
726         } else if (ecp->cmd == &cmds[C_SUBSTITUTE]) {
727                 /*
728                  * Move to the next non-whitespace character, we'll use it as
729                  * the delimiter.  If the character isn't an alphanumeric or
730                  * a '|', it's the delimiter, so parse it.  Otherwise, we're
731                  * into something like ":s g", so use the special s command.
732                  */
733                 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp)
734                         if (!isblank(ecp->cp[0]))
735                                 break;
736
737                 if (isalnum(ecp->cp[0]) || ecp->cp[0] == '|') {
738                         ecp->rcmd = cmds[C_SUBSTITUTE];
739                         ecp->rcmd.fn = ex_subagain;
740                         ecp->cmd = &ecp->rcmd;
741                 } else if (ecp->clen > 0) {
742                         /*
743                          * QUOTING NOTE:
744                          *
745                          * Backslashes quote delimiter characters for RE's.
746                          * The backslashes are NOT removed since they'll be
747                          * used by the RE code.  Move to the third delimiter
748                          * that's not escaped (or the end of the command).
749                          */
750                         delim = *ecp->cp;
751                         ++ecp->cp;
752                         --ecp->clen;
753                         for (cnt = 2; ecp->clen > 0 &&
754                             cnt != 0; --ecp->clen, ++ecp->cp)
755                                 if (ecp->cp[0] == '\\' &&
756                                     ecp->clen > 1) {
757                                         ++ecp->cp;
758                                         --ecp->clen;
759                                 } else if (ecp->cp[0] == delim)
760                                         --cnt;
761                 }
762         }
763
764         /*
765          * Use normal quoting and termination rules to find the end of this
766          * command.
767          *
768          * QUOTING NOTE:
769          *
770          * Historically, vi permitted ^V's to escape <newline>'s in the .exrc
771          * file.  It was almost certainly a bug, but that's what bug-for-bug
772          * compatibility means, Grasshopper.  Also, ^V's escape the command
773          * delimiters.  Literal next quote characters in front of the newlines,
774          * '|' characters or literal next characters are stripped as they're
775          * no longer useful.
776          */
777         vi_address = ecp->clen != 0 && ecp->cp[0] != '\n';
778         for (p = ecp->cp; ecp->clen > 0; --ecp->clen, ++ecp->cp) {
779                 ch = ecp->cp[0];
780                 if (IS_ESCAPE(sp, ecp, ch) && ecp->clen > 1) {
781                         tmp = ecp->cp[1];
782                         if (tmp == '\n' || tmp == '|') {
783                                 if (tmp == '\n') {
784                                         ++gp->if_lno;
785                                         ++ecp->if_lno;
786                                 }
787                                 ++discard;
788                                 --ecp->clen;
789                                 ++ecp->cp;
790                                 ch = tmp;
791                         }
792                 } else if (ch == '\n' || ch == '|') {
793                         if (ch == '\n')
794                                 F_SET(ecp, E_NEWLINE);
795                         --ecp->clen;
796                         break;
797                 }
798                 *p++ = ch;
799         }
800
801         /*
802          * Save off the next command information, go back to the
803          * original start of the command.
804          */
805         p = ecp->cp + 1;
806         ecp->cp = ecp->save_cmd;
807         ecp->save_cmd = p;
808         ecp->save_cmdlen = ecp->clen;
809         ecp->clen = ((ecp->save_cmd - ecp->cp) - 1) - discard;
810
811         /*
812          * QUOTING NOTE:
813          *
814          * The "set tags" command historically used a backslash, not the
815          * user's literal next character, to escape whitespace.  Handle
816          * it here instead of complicating the argv_exp3() code.  Note,
817          * this isn't a particularly complex trap, and if backslashes were
818          * legal in set commands, this would have to be much more complicated.
819          */
820         if (ecp->cmd == &cmds[C_SET])
821                 for (p = ecp->cp, len = ecp->clen; len > 0; --len, ++p)
822                         if (*p == '\\')
823                                 *p = CH_LITERAL;
824
825         /*
826          * Set the default addresses.  It's an error to specify an address for
827          * a command that doesn't take them.  If two addresses are specified
828          * for a command that only takes one, lose the first one.  Two special
829          * cases here, some commands take 0 or 2 addresses.  For most of them
830          * (the E_ADDR2_ALL flag), 0 defaults to the entire file.  For one
831          * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
832          *
833          * Also, if the file is empty, some commands want to use an address of
834          * 0, i.e. the entire file is 0 to 0, and the default first address is
835          * 0.  Otherwise, an entire file is 1 to N and the default line is 1.
836          * Note, we also add the E_ADDR_ZERO flag to the command flags, for the
837          * case where the 0 address is only valid if it's a default address.
838          *
839          * Also, set a flag if we set the default addresses.  Some commands
840          * (ex: z) care if the user specified an address or if we just used
841          * the current cursor.
842          */
843         switch (F_ISSET(ecp, E_ADDR1 | E_ADDR2 | E_ADDR2_ALL | E_ADDR2_NONE)) {
844         case E_ADDR1:                           /* One address: */
845                 switch (ecp->addrcnt) {
846                 case 0:                         /* Default cursor/empty file. */
847                         ecp->addrcnt = 1;
848                         F_SET(ecp, E_ADDR_DEF);
849                         if (F_ISSET(ecp, E_ADDR_ZERODEF)) {
850                                 if (db_last(sp, &lno))
851                                         goto err;
852                                 if (lno == 0) {
853                                         ecp->addr1.lno = 0;
854                                         F_SET(ecp, E_ADDR_ZERO);
855                                 } else
856                                         ecp->addr1.lno = sp->lno;
857                         } else
858                                 ecp->addr1.lno = sp->lno;
859                         ecp->addr1.cno = sp->cno;
860                         break;
861                 case 1:
862                         break;
863                 case 2:                         /* Lose the first address. */
864                         ecp->addrcnt = 1;
865                         ecp->addr1 = ecp->addr2;
866                 }
867                 break;
868         case E_ADDR2_NONE:                      /* Zero/two addresses: */
869                 if (ecp->addrcnt == 0)          /* Default to nothing. */
870                         break;
871                 goto two_addr;
872         case E_ADDR2_ALL:                       /* Zero/two addresses: */
873                 if (ecp->addrcnt == 0) {        /* Default entire/empty file. */
874                         F_SET(ecp, E_ADDR_DEF);
875                         ecp->addrcnt = 2;
876                         if (sp->ep == NULL)
877                                 ecp->addr2.lno = 0;
878                         else if (db_last(sp, &ecp->addr2.lno))
879                                 goto err;
880                         if (F_ISSET(ecp, E_ADDR_ZERODEF) &&
881                             ecp->addr2.lno == 0) {
882                                 ecp->addr1.lno = 0;
883                                 F_SET(ecp, E_ADDR_ZERO);
884                         } else
885                                 ecp->addr1.lno = 1;
886                         ecp->addr1.cno = ecp->addr2.cno = 0;
887                         F_SET(ecp, E_ADDR2_ALL);
888                         break;
889                 }
890                 /* FALLTHROUGH */
891         case E_ADDR2:                           /* Two addresses: */
892 two_addr:       switch (ecp->addrcnt) {
893                 case 0:                         /* Default cursor/empty file. */
894                         ecp->addrcnt = 2;
895                         F_SET(ecp, E_ADDR_DEF);
896                         if (sp->lno == 1 &&
897                             F_ISSET(ecp, E_ADDR_ZERODEF)) {
898                                 if (db_last(sp, &lno))
899                                         goto err;
900                                 if (lno == 0) {
901                                         ecp->addr1.lno = ecp->addr2.lno = 0;
902                                         F_SET(ecp, E_ADDR_ZERO);
903                                 } else
904                                         ecp->addr1.lno =
905                                             ecp->addr2.lno = sp->lno;
906                         } else
907                                 ecp->addr1.lno = ecp->addr2.lno = sp->lno;
908                         ecp->addr1.cno = ecp->addr2.cno = sp->cno;
909                         break;
910                 case 1:                         /* Default to first address. */
911                         ecp->addrcnt = 2;
912                         ecp->addr2 = ecp->addr1;
913                         break;
914                 case 2:
915                         break;
916                 }
917                 break;
918         default:
919                 if (ecp->addrcnt)               /* Error. */
920                         goto usage;
921         }
922
923         /*
924          * !!!
925          * The ^D scroll command historically scrolled the value of the scroll
926          * option or to EOF.  It was an error if the cursor was already at EOF.
927          * (Leading addresses were permitted, but were then ignored.)
928          */
929         if (ecp->cmd == &cmds[C_SCROLL]) {
930                 ecp->addrcnt = 2;
931                 ecp->addr1.lno = sp->lno + 1;
932                 ecp->addr2.lno = sp->lno + O_VAL(sp, O_SCROLL);
933                 ecp->addr1.cno = ecp->addr2.cno = sp->cno;
934                 if (db_last(sp, &lno))
935                         goto err;
936                 if (lno != 0 && lno > sp->lno && ecp->addr2.lno > lno)
937                         ecp->addr2.lno = lno;
938         }
939
940         ecp->flagoff = 0;
941         for (p = ecp->cmd->syntax; *p != '\0'; ++p) {
942                 /*
943                  * The force flag is sensitive to leading whitespace, i.e.
944                  * "next !" is different from "next!".  Handle it before
945                  * skipping leading <blank>s.
946                  */
947                 if (*p == '!') {
948                         if (ecp->clen > 0 && *ecp->cp == '!') {
949                                 ++ecp->cp;
950                                 --ecp->clen;
951                                 FL_SET(ecp->iflags, E_C_FORCE);
952                         }
953                         continue;
954                 }
955
956                 /* Skip leading <blank>s. */
957                 for (; ecp->clen > 0; --ecp->clen, ++ecp->cp)
958                         if (!isblank(*ecp->cp))
959                                 break;
960                 if (ecp->clen == 0)
961                         break;
962
963                 switch (*p) {
964                 case '1':                               /* +, -, #, l, p */
965                         /*
966                          * !!!
967                          * Historically, some flags were ignored depending
968                          * on where they occurred in the command line.  For
969                          * example, in the command, ":3+++p--#", historic vi
970                          * acted on the '#' flag, but ignored the '-' flags.
971                          * It's unambiguous what the flags mean, so we just
972                          * handle them regardless of the stupidity of their
973                          * location.
974                          */
975                         for (; ecp->clen; --ecp->clen, ++ecp->cp)
976                                 switch (*ecp->cp) {
977                                 case '+':
978                                         ++ecp->flagoff;
979                                         break;
980                                 case '-':
981                                 case '^':
982                                         --ecp->flagoff;
983                                         break;
984                                 case '#':
985                                         F_CLR(ecp, E_OPTNUM);
986                                         FL_SET(ecp->iflags, E_C_HASH);
987                                         exp->fdef |= E_C_HASH;
988                                         break;
989                                 case 'l':
990                                         FL_SET(ecp->iflags, E_C_LIST);
991                                         exp->fdef |= E_C_LIST;
992                                         break;
993                                 case 'p':
994                                         FL_SET(ecp->iflags, E_C_PRINT);
995                                         exp->fdef |= E_C_PRINT;
996                                         break;
997                                 default:
998                                         goto end_case1;
999                                 }
1000 end_case1:              break;
1001                 case '2':                               /* -, ., +, ^ */
1002                 case '3':                               /* -, ., +, ^, = */
1003                         for (; ecp->clen; --ecp->clen, ++ecp->cp)
1004                                 switch (*ecp->cp) {
1005                                 case '-':
1006                                         FL_SET(ecp->iflags, E_C_DASH);
1007                                         break;
1008                                 case '.':
1009                                         FL_SET(ecp->iflags, E_C_DOT);
1010                                         break;
1011                                 case '+':
1012                                         FL_SET(ecp->iflags, E_C_PLUS);
1013                                         break;
1014                                 case '^':
1015                                         FL_SET(ecp->iflags, E_C_CARAT);
1016                                         break;
1017                                 case '=':
1018                                         if (*p == '3') {
1019                                                 FL_SET(ecp->iflags, E_C_EQUAL);
1020                                                 break;
1021                                         }
1022                                         /* FALLTHROUGH */
1023                                 default:
1024                                         goto end_case23;
1025                                 }
1026 end_case23:             break;
1027                 case 'b':                               /* buffer */
1028                         /*
1029                          * !!!
1030                          * Historically, "d #" was a delete with a flag, not a
1031                          * delete into the '#' buffer.  If the current command
1032                          * permits a flag, don't use one as a buffer.  However,
1033                          * the 'l' and 'p' flags were legal buffer names in the
1034                          * historic ex, and were used as buffers, not flags.
1035                          */
1036                         if ((ecp->cp[0] == '+' || ecp->cp[0] == '-' ||
1037                             ecp->cp[0] == '^' || ecp->cp[0] == '#') &&
1038                             strchr(p, '1') != NULL)
1039                                 break;
1040                         /*
1041                          * !!!
1042                          * Digits can't be buffer names in ex commands, or the
1043                          * command "d2" would be a delete into buffer '2', and
1044                          * not a two-line deletion.
1045                          */
1046                         if (!isdigit(ecp->cp[0])) {
1047                                 ecp->buffer = *ecp->cp;
1048                                 ++ecp->cp;
1049                                 --ecp->clen;
1050                                 FL_SET(ecp->iflags, E_C_BUFFER);
1051                         }
1052                         break;
1053                 case 'c':                               /* count [01+a] */
1054                         ++p;
1055                         /* Validate any signed value. */
1056                         if (!isdigit(*ecp->cp) && (*p != '+' ||
1057                             (*ecp->cp != '+' && *ecp->cp != '-')))
1058                                 break;
1059                         /* If a signed value, set appropriate flags. */
1060                         if (*ecp->cp == '-')
1061                                 FL_SET(ecp->iflags, E_C_COUNT_NEG);
1062                         else if (*ecp->cp == '+')
1063                                 FL_SET(ecp->iflags, E_C_COUNT_POS);
1064                         if ((nret =
1065                             nget_slong(&ltmp, ecp->cp, &t, 10)) != NUM_OK) {
1066                                 ex_badaddr(sp, NULL, A_NOTSET, nret);
1067                                 goto err;
1068                         }
1069                         if (ltmp == 0 && *p != '0') {
1070                                 msgq(sp, M_ERR, "083|Count may not be zero");
1071                                 goto err;
1072                         }
1073                         ecp->clen -= (t - ecp->cp);
1074                         ecp->cp = t;
1075
1076                         /*
1077                          * Counts as address offsets occur in commands taking
1078                          * two addresses.  Historic vi practice was to use
1079                          * the count as an offset from the *second* address.
1080                          *
1081                          * Set a count flag; some underlying commands (see
1082                          * join) do different things with counts than with
1083                          * line addresses.
1084                          */
1085                         if (*p == 'a') {
1086                                 ecp->addr1 = ecp->addr2;
1087                                 ecp->addr2.lno = ecp->addr1.lno + ltmp - 1;
1088                         } else
1089                                 ecp->count = ltmp;
1090                         FL_SET(ecp->iflags, E_C_COUNT);
1091                         break;
1092                 case 'f':                               /* file */
1093                         if (argv_exp2(sp, ecp, ecp->cp, ecp->clen))
1094                                 goto err;
1095                         goto arg_cnt_chk;
1096                 case 'l':                               /* line */
1097                         /*
1098                          * Get a line specification.
1099                          *
1100                          * If the line was a search expression, we may have
1101                          * changed state during the call, and we're now
1102                          * searching the file.  Push ourselves onto the state
1103                          * stack.
1104                          */
1105                         if (ex_line(sp, ecp, &cur, &isaddr, &tmp))
1106                                 goto rfail;
1107                         if (tmp)
1108                                 goto err;
1109
1110                         /* Line specifications are always required. */
1111                         if (!isaddr) {
1112                                 msgq_str(sp, M_ERR, ecp->cp,
1113                                      "084|%s: bad line specification");
1114                                 goto err;
1115                         }
1116                         /*
1117                          * The target line should exist for these commands,
1118                          * but 0 is legal for them as well.
1119                          */
1120                         if (cur.lno != 0 && !db_exist(sp, cur.lno)) {
1121                                 ex_badaddr(sp, NULL, A_EOF, NUM_OK);
1122                                 goto err;
1123                         }
1124                         ecp->lineno = cur.lno;
1125                         break;
1126                 case 'S':                               /* string, file exp. */
1127                         if (ecp->clen != 0) {
1128                                 if (argv_exp1(sp, ecp, ecp->cp,
1129                                     ecp->clen, ecp->cmd == &cmds[C_BANG]))
1130                                         goto err;
1131                                 goto addr_verify;
1132                         }
1133                         /* FALLTHROUGH */
1134                 case 's':                               /* string */
1135                         if (argv_exp0(sp, ecp, ecp->cp, ecp->clen))
1136                                 goto err;
1137                         goto addr_verify;
1138                 case 'W':                               /* word string */
1139                         /*
1140                          * QUOTING NOTE:
1141                          *
1142                          * Literal next characters escape the following
1143                          * character.  Quoting characters are stripped here
1144                          * since they are no longer useful.
1145                          *
1146                          * First there was the word.
1147                          */
1148                         for (p = t = ecp->cp;
1149                             ecp->clen > 0; --ecp->clen, ++ecp->cp) {
1150                                 ch = *ecp->cp;
1151                                 if (IS_ESCAPE(sp,
1152                                     ecp, ch) && ecp->clen > 1) {
1153                                         --ecp->clen;
1154                                         *p++ = *++ecp->cp;
1155                                 } else if (isblank(ch)) {
1156                                         ++ecp->cp;
1157                                         --ecp->clen;
1158                                         break;
1159                                 } else
1160                                         *p++ = ch;
1161                         }
1162                         if (argv_exp0(sp, ecp, t, p - t))
1163                                 goto err;
1164
1165                         /* Delete intervening whitespace. */
1166                         for (; ecp->clen > 0;
1167                             --ecp->clen, ++ecp->cp) {
1168                                 ch = *ecp->cp;
1169                                 if (!isblank(ch))
1170                                         break;
1171                         }
1172                         if (ecp->clen == 0)
1173                                 goto usage;
1174
1175                         /* Followed by the string. */
1176                         for (p = t = ecp->cp; ecp->clen > 0;
1177                             --ecp->clen, ++ecp->cp, ++p) {
1178                                 ch = *ecp->cp;
1179                                 if (IS_ESCAPE(sp,
1180                                     ecp, ch) && ecp->clen > 1) {
1181                                         --ecp->clen;
1182                                         *p = *++ecp->cp;
1183                                 } else
1184                                         *p = ch;
1185                         }
1186                         if (argv_exp0(sp, ecp, t, p - t))
1187                                 goto err;
1188                         goto addr_verify;
1189                 case 'w':                               /* word */
1190                         if (argv_exp3(sp, ecp, ecp->cp, ecp->clen))
1191                                 goto err;
1192 arg_cnt_chk:            if (*++p != 'N') {              /* N */
1193                                 /*
1194                                  * If a number is specified, must either be
1195                                  * 0 or that number, if optional, and that
1196                                  * number, if required.
1197                                  */
1198                                 tmp = *p - '0';
1199                                 if ((*++p != 'o' || exp->argsoff != 0) &&
1200                                     exp->argsoff != tmp)
1201                                         goto usage;
1202                         }
1203                         goto addr_verify;
1204                 default:
1205                         msgq(sp, M_ERR,
1206                             "085|Internal syntax table error (%s: %s)",
1207                             ecp->cmd->name, KEY_NAME(sp, *p));
1208                 }
1209         }
1210
1211         /* Skip trailing whitespace. */
1212         for (; ecp->clen > 0; --ecp->clen) {
1213                 ch = *ecp->cp++;
1214                 if (!isblank(ch))
1215                         break;
1216         }
1217
1218         /*
1219          * There shouldn't be anything left, and no more required fields,
1220          * i.e neither 'l' or 'r' in the syntax string.
1221          */
1222         if (ecp->clen != 0 || strpbrk(p, "lr")) {
1223 usage:          msgq(sp, M_ERR, "086|Usage: %s", ecp->cmd->usage);
1224                 goto err;
1225         }
1226
1227         /*
1228          * Verify that the addresses are legal.  Check the addresses here,
1229          * because this is a place where all ex addresses pass through.
1230          * (They don't all pass through ex_line(), for instance.)  We're
1231          * assuming that any non-existent line doesn't exist because it's
1232          * past the end-of-file.  That's a pretty good guess.
1233          *
1234          * If it's a "default vi command", an address of zero is okay.
1235          */
1236 addr_verify:
1237         switch (ecp->addrcnt) {
1238         case 2:
1239                 /*
1240                  * Historic ex/vi permitted commands with counts to go past
1241                  * EOF.  So, for example, if the file only had 5 lines, the
1242                  * ex command "1,6>" would fail, but the command ">300"
1243                  * would succeed.  Since we don't want to have to make all
1244                  * of the underlying commands handle random line numbers,
1245                  * fix it here.
1246                  */
1247                 if (ecp->addr2.lno == 0) {
1248                         if (!F_ISSET(ecp, E_ADDR_ZERO) &&
1249                             (F_ISSET(sp, SC_EX) ||
1250                             !F_ISSET(ecp, E_USELASTCMD))) {
1251                                 ex_badaddr(sp, ecp->cmd, A_ZERO, NUM_OK);
1252                                 goto err;
1253                         }
1254                 } else if (!db_exist(sp, ecp->addr2.lno))
1255                         if (FL_ISSET(ecp->iflags, E_C_COUNT)) {
1256                                 if (db_last(sp, &lno))
1257                                         goto err;
1258                                 ecp->addr2.lno = lno;
1259                         } else {
1260                                 ex_badaddr(sp, NULL, A_EOF, NUM_OK);
1261                                 goto err;
1262                         }
1263                 /* FALLTHROUGH */
1264         case 1:
1265                 if (ecp->addr1.lno == 0) {
1266                         if (!F_ISSET(ecp, E_ADDR_ZERO) &&
1267                             (F_ISSET(sp, SC_EX) ||
1268                             !F_ISSET(ecp, E_USELASTCMD))) {
1269                                 ex_badaddr(sp, ecp->cmd, A_ZERO, NUM_OK);
1270                                 goto err;
1271                         }
1272                 } else if (!db_exist(sp, ecp->addr1.lno)) {
1273                         ex_badaddr(sp, NULL, A_EOF, NUM_OK);
1274                         goto err;
1275                 }
1276                 break;
1277         }
1278
1279         /*
1280          * If doing a default command and there's nothing left on the line,
1281          * vi just moves to the line.  For example, ":3" and ":'a,'b" just
1282          * move to line 3 and line 'b, respectively, but ":3|" prints line 3.
1283          *
1284          * !!!
1285          * In addition, IF THE LINE CHANGES, move to the first nonblank of
1286          * the line.
1287          *
1288          * !!!
1289          * This is done before the absolute mark gets set; historically,
1290          * "/a/,/b/" did NOT set vi's absolute mark, but "/a/,/b/d" did.
1291          */
1292         if ((F_ISSET(sp, SC_VI) || F_ISSET(ecp, E_NOPRDEF)) &&
1293             F_ISSET(ecp, E_USELASTCMD) && vi_address == 0) {
1294                 switch (ecp->addrcnt) {
1295                 case 2:
1296                         if (sp->lno !=
1297                             (ecp->addr2.lno ? ecp->addr2.lno : 1)) {
1298                                 sp->lno =
1299                                     ecp->addr2.lno ? ecp->addr2.lno : 1;
1300                                 sp->cno = 0;
1301                                 (void)nonblank(sp, sp->lno, &sp->cno);
1302                         }
1303                         break;
1304                 case 1:
1305                         if (sp->lno !=
1306                             (ecp->addr1.lno ? ecp->addr1.lno : 1)) {
1307                                 sp->lno =
1308                                     ecp->addr1.lno ? ecp->addr1.lno : 1;
1309                                 sp->cno = 0;
1310                                 (void)nonblank(sp, sp->lno, &sp->cno);
1311                         }
1312                         break;
1313                 }
1314                 ecp->cp = ecp->save_cmd;
1315                 ecp->clen = ecp->save_cmdlen;
1316                 goto loop;
1317         }
1318
1319         /*
1320          * Set the absolute mark -- we have to set it for vi here, in case
1321          * it's a compound command, e.g. ":5p|6" should set the absolute
1322          * mark for vi.
1323          */
1324         if (F_ISSET(ecp, E_ABSMARK)) {
1325                 cur.lno = sp->lno;
1326                 cur.cno = sp->cno;
1327                 F_CLR(ecp, E_ABSMARK);
1328                 if (mark_set(sp, ABSMARK1, &cur, 1))
1329                         goto err;
1330         }
1331
1332 #if defined(DEBUG) && defined(COMLOG)
1333         ex_comlog(sp, ecp);
1334 #endif
1335         /* Increment the command count if not called from vi. */
1336         if (F_ISSET(sp, SC_EX))
1337                 ++sp->ccnt;
1338
1339         /*
1340          * If file state available, and not doing a global command,
1341          * log the start of an action.
1342          */
1343         if (sp->ep != NULL && !F_ISSET(sp, SC_EX_GLOBAL))
1344                 (void)log_cursor(sp);
1345
1346         /*
1347          * !!!
1348          * There are two special commands for the purposes of this code: the
1349          * default command (<carriage-return>) or the scrolling commands (^D
1350          * and <EOF>) as the first non-<blank> characters  in the line.
1351          *
1352          * If this is the first command in the command line, we received the
1353          * command from the ex command loop and we're talking to a tty, and
1354          * and there's nothing else on the command line, and it's one of the
1355          * special commands, we move back up to the previous line, and erase
1356          * the prompt character with the output.  Since ex runs in canonical
1357          * mode, we don't have to do anything else, a <newline> has already
1358          * been echoed by the tty driver.  It's OK if vi calls us -- we won't
1359          * be in ex mode so we'll do nothing.
1360          */
1361         if (F_ISSET(ecp, E_NRSEP)) {
1362                 if (sp->ep != NULL &&
1363                     F_ISSET(sp, SC_EX) && !F_ISSET(gp, G_SCRIPTED) &&
1364                     (F_ISSET(ecp, E_USELASTCMD) || ecp->cmd == &cmds[C_SCROLL]))
1365                         gp->scr_ex_adjust(sp, EX_TERM_SCROLL);
1366                 F_CLR(ecp, E_NRSEP);
1367         }
1368
1369         /*
1370          * Call the underlying function for the ex command.
1371          *
1372          * XXX
1373          * Interrupts behave like errors, for now.
1374          */
1375         if (ecp->cmd->fn(sp, ecp) || INTERRUPTED(sp)) {
1376                 if (F_ISSET(gp, G_SCRIPTED))
1377                         F_SET(sp, SC_EXIT_FORCE);
1378                 goto err;
1379         }
1380
1381 #ifdef DEBUG
1382         /* Make sure no function left global temporary space locked. */
1383         if (F_ISSET(gp, G_TMP_INUSE)) {
1384                 F_CLR(gp, G_TMP_INUSE);
1385                 msgq(sp, M_ERR, "087|%s: temporary buffer not released",
1386                     ecp->cmd->name);
1387         }
1388 #endif
1389         /*
1390          * Ex displayed the number of lines modified immediately after each
1391          * command, so the command "1,10d|1,10d" would display:
1392          *
1393          *      10 lines deleted
1394          *      10 lines deleted
1395          *      <autoprint line>
1396          *
1397          * Executing ex commands from vi only reported the final modified
1398          * lines message -- that's wrong enough that we don't match it.
1399          */
1400         if (F_ISSET(sp, SC_EX))
1401                 mod_rpt(sp);
1402
1403         /*
1404          * Integrate any offset parsed by the underlying command, and make
1405          * sure the referenced line exists.
1406          *
1407          * XXX
1408          * May not match historic practice (which I've never been able to
1409          * completely figure out.)  For example, the '=' command from vi
1410          * mode often got the offset wrong, and complained it was too large,
1411          * but didn't seem to have a problem with the cursor.  If anyone
1412          * complains, ask them how it's supposed to work, they might know.
1413          */
1414         if (sp->ep != NULL && ecp->flagoff) {
1415                 if (ecp->flagoff < 0) {
1416                         if (sp->lno <= -ecp->flagoff) {
1417                                 msgq(sp, M_ERR,
1418                                     "088|Flag offset to before line 1");
1419                                 goto err;
1420                         }
1421                 } else {
1422                         if (!NPFITS(MAX_REC_NUMBER, sp->lno, ecp->flagoff)) {
1423                                 ex_badaddr(sp, NULL, A_NOTSET, NUM_OVER);
1424                                 goto err;
1425                         }
1426                         if (!db_exist(sp, sp->lno + ecp->flagoff)) {
1427                                 msgq(sp, M_ERR,
1428                                     "089|Flag offset past end-of-file");
1429                                 goto err;
1430                         }
1431                 }
1432                 sp->lno += ecp->flagoff;
1433         }
1434
1435         /*
1436          * If the command executed successfully, we may want to display a line
1437          * based on the autoprint option or an explicit print flag.  (Make sure
1438          * that there's a line to display.)  Also, the autoprint edit option is
1439          * turned off for the duration of global commands.
1440          */
1441         if (F_ISSET(sp, SC_EX) && sp->ep != NULL && sp->lno != 0) {
1442                 /*
1443                  * The print commands have already handled the `print' flags.
1444                  * If so, clear them.
1445                  */
1446                 if (FL_ISSET(ecp->iflags, E_CLRFLAG))
1447                         FL_CLR(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT);
1448
1449                 /* If hash set only because of the number option, discard it. */
1450                 if (F_ISSET(ecp, E_OPTNUM))
1451                         FL_CLR(ecp->iflags, E_C_HASH);
1452
1453                 /*
1454                  * If there was an explicit flag to display the new cursor line,
1455                  * or autoprint is set and a change was made, display the line.
1456                  * If any print flags were set use them, else default to print.
1457                  */
1458                 LF_INIT(FL_ISSET(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT));
1459                 if (!LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT | E_NOAUTO) &&
1460                     !F_ISSET(sp, SC_EX_GLOBAL) &&
1461                     O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT))
1462                         LF_INIT(E_C_PRINT);
1463
1464                 if (LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT)) {
1465                         cur.lno = sp->lno;
1466                         cur.cno = 0;
1467                         (void)ex_print(sp, ecp, &cur, &cur, flags);
1468                 }
1469         }
1470
1471         /*
1472          * If the command had an associated "+cmd", it has to be executed
1473          * before we finish executing any more of this ex command.  For
1474          * example, consider a .exrc file that contains the following lines:
1475          *
1476          *      :set all
1477          *      :edit +25 file.c|s/abc/ABC/|1
1478          *      :3,5 print
1479          *
1480          * This can happen more than once -- the historic vi simply hung or
1481          * dropped core, of course.  Prepend the + command back into the
1482          * current command and continue.  We may have to add an additional
1483          * <literal next> character.  We know that it will fit because we
1484          * discarded at least one space and the + character.
1485          */
1486         if (arg1_len != 0) {
1487                 /*
1488                  * If the last character of the + command was a <literal next>
1489                  * character, it would be treated differently because of the
1490                  * append.  Quote it, if necessary.
1491                  */
1492                 if (IS_ESCAPE(sp, ecp, arg1[arg1_len - 1])) {
1493                         *--ecp->save_cmd = CH_LITERAL;
1494                         ++ecp->save_cmdlen;
1495                 }
1496
1497                 ecp->save_cmd -= arg1_len;
1498                 ecp->save_cmdlen += arg1_len;
1499                 memcpy(ecp->save_cmd, arg1, arg1_len);
1500
1501                 /*
1502                  * Any commands executed from a +cmd are executed starting at
1503                  * the first column of the last line of the file -- NOT the
1504                  * first nonblank.)  The main file startup code doesn't know
1505                  * that a +cmd was set, however, so it may have put us at the
1506                  * top of the file.  (Note, this is safe because we must have
1507                  * switched files to get here.)
1508                  */
1509                 F_SET(ecp, E_MOVETOEND);
1510         }
1511
1512         /* Update the current command. */
1513         ecp->cp = ecp->save_cmd;
1514         ecp->clen = ecp->save_cmdlen;
1515
1516         /*
1517          * !!!
1518          * If we've changed screens or underlying files, any pending global or
1519          * v command, or @ buffer that has associated addresses, has to be
1520          * discarded.  This is historic practice for globals, and necessary for
1521          * @ buffers that had associated addresses.
1522          *
1523          * Otherwise, if we've changed underlying files, it's not a problem,
1524          * we continue with the rest of the ex command(s), operating on the
1525          * new file.  However, if we switch screens (either by exiting or by
1526          * an explicit command), we have no way of knowing where to put output
1527          * messages, and, since we don't control screens here, we could screw
1528          * up the upper layers, (e.g. we could exit/reenter a screen multiple
1529          * times).  So, return and continue after we've got a new screen.
1530          */
1531         if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE | SC_FSWITCH | SC_SSWITCH)) {
1532                 at_found = gv_found = 0;
1533                 for (ecp = sp->gp->ecq.lh_first;
1534                     ecp != NULL; ecp = ecp->q.le_next)
1535                         switch (ecp->agv_flags) {
1536                         case 0:
1537                         case AGV_AT_NORANGE:
1538                                 break;
1539                         case AGV_AT:
1540                                 if (!at_found) {
1541                                         at_found = 1;
1542                                         msgq(sp, M_ERR,
1543                 "090|@ with range running when the file/screen changed");
1544                                 }
1545                                 break;
1546                         case AGV_GLOBAL:
1547                         case AGV_V:
1548                                 if (!gv_found) {
1549                                         gv_found = 1;
1550                                         msgq(sp, M_ERR,
1551                 "091|Global/v command running when the file/screen changed");
1552                                 }
1553                                 break;
1554                         default:
1555                                 abort();
1556                         }
1557                 if (at_found || gv_found)
1558                         goto discard;
1559                 if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE | SC_SSWITCH))
1560                         goto rsuccess;
1561         }
1562
1563         goto loop;
1564         /* NOTREACHED */
1565
1566 err:    /*
1567          * On command failure, we discard keys and pending commands remaining,
1568          * as well as any keys that were mapped and waiting.  The save_cmdlen
1569          * test is not necessarily correct.  If we fail early enough we don't
1570          * know if the entire string was a single command or not.  Guess, as
1571          * it's useful to know if commands other than the current one are being
1572          * discarded.
1573          */
1574         if (ecp->save_cmdlen == 0)
1575                 for (; ecp->clen; --ecp->clen) {
1576                         ch = *ecp->cp++;
1577                         if (IS_ESCAPE(sp, ecp, ch) && ecp->clen > 1) {
1578                                 --ecp->clen;
1579                                 ++ecp->cp;
1580                         } else if (ch == '\n' || ch == '|') {
1581                                 if (ecp->clen > 1)
1582                                         ecp->save_cmdlen = 1;
1583                                 break;
1584                         }
1585                 }
1586         if (ecp->save_cmdlen != 0 || gp->ecq.lh_first != &gp->excmd) {
1587 discard:        msgq(sp, M_BERR,
1588                     "092|Ex command failed: pending commands discarded");
1589                 ex_discard(sp);
1590         }
1591         if (v_event_flush(sp, CH_MAPPED))
1592                 msgq(sp, M_BERR,
1593                     "093|Ex command failed: mapped keys discarded");
1594
1595 rfail:  tmp = 1;
1596         if (0)
1597 rsuccess:       tmp = 0;
1598
1599         /* Turn off any file name error information. */
1600         gp->if_name = NULL;
1601
1602         /* Turn off the global bit. */
1603         F_CLR(sp, SC_EX_GLOBAL);
1604
1605         return (tmp);
1606 }
1607
1608 /*
1609  * ex_range --
1610  *      Get a line range for ex commands, or perform a vi ex address search.
1611  *
1612  * PUBLIC: int ex_range __P((SCR *, EXCMD *, int *));
1613  */
1614 int
1615 ex_range(sp, ecp, errp)
1616         SCR *sp;
1617         EXCMD *ecp;
1618         int *errp;
1619 {
1620         enum { ADDR_FOUND, ADDR_NEED, ADDR_NONE } addr;
1621         GS *gp;
1622         EX_PRIVATE *exp;
1623         MARK m;
1624         int isaddr;
1625
1626         *errp = 0;
1627
1628         /*
1629          * Parse comma or semi-colon delimited line specs.
1630          *
1631          * Semi-colon delimiters update the current address to be the last
1632          * address.  For example, the command
1633          *
1634          *      :3;/pattern/ecp->cp
1635          *
1636          * will search for pattern from line 3.  In addition, if ecp->cp
1637          * is not a valid command, the current line will be left at 3, not
1638          * at the original address.
1639          *
1640          * Extra addresses are discarded, starting with the first.
1641          *
1642          * !!!
1643          * If any addresses are missing, they default to the current line.
1644          * This was historically true for both leading and trailing comma
1645          * delimited addresses as well as for trailing semicolon delimited
1646          * addresses.  For consistency, we make it true for leading semicolon
1647          * addresses as well.
1648          */
1649         gp = sp->gp;
1650         exp = EXP(sp);
1651         for (addr = ADDR_NONE, ecp->addrcnt = 0; ecp->clen > 0;)
1652                 switch (*ecp->cp) {
1653                 case '%':               /* Entire file. */
1654                         /* Vi ex address searches didn't permit % signs. */
1655                         if (F_ISSET(ecp, E_VISEARCH))
1656                                 goto ret;
1657
1658                         /* It's an error if the file is empty. */
1659                         if (sp->ep == NULL) {
1660                                 ex_badaddr(sp, NULL, A_EMPTY, NUM_OK);
1661                                 *errp = 1;
1662                                 return (0);
1663                         }
1664                         /*
1665                          * !!!
1666                          * A percent character addresses all of the lines in
1667                          * the file.  Historically, it couldn't be followed by
1668                          * any other address.  We do it as a text substitution
1669                          * for simplicity.  POSIX 1003.2 is expected to follow
1670                          * this practice.
1671                          *
1672                          * If it's an empty file, the first line is 0, not 1.
1673                          */
1674                         if (addr == ADDR_FOUND) {
1675                                 ex_badaddr(sp, NULL, A_COMBO, NUM_OK);
1676                                 *errp = 1;
1677                                 return (0);
1678                         }
1679                         if (db_last(sp, &ecp->addr2.lno))
1680                                 return (1);
1681                         ecp->addr1.lno = ecp->addr2.lno == 0 ? 0 : 1;
1682                         ecp->addr1.cno = ecp->addr2.cno = 0;
1683                         ecp->addrcnt = 2;
1684                         addr = ADDR_FOUND;
1685                         ++ecp->cp;
1686                         --ecp->clen;
1687                         break;
1688                 case ',':               /* Comma delimiter. */
1689                         /* Vi ex address searches didn't permit commas. */
1690                         if (F_ISSET(ecp, E_VISEARCH))
1691                                 goto ret;
1692                         /* FALLTHROUGH */
1693                 case ';':               /* Semi-colon delimiter. */
1694                         if (sp->ep == NULL) {
1695                                 ex_badaddr(sp, NULL, A_EMPTY, NUM_OK);
1696                                 *errp = 1;
1697                                 return (0);
1698                         }
1699                         if (addr != ADDR_FOUND)
1700                                 switch (ecp->addrcnt) {
1701                                 case 0:
1702                                         ecp->addr1.lno = sp->lno;
1703                                         ecp->addr1.cno = sp->cno;
1704                                         ecp->addrcnt = 1;
1705                                         break;
1706                                 case 2:
1707                                         ecp->addr1 = ecp->addr2;
1708                                         /* FALLTHROUGH */
1709                                 case 1:
1710                                         ecp->addr2.lno = sp->lno;
1711                                         ecp->addr2.cno = sp->cno;
1712                                         ecp->addrcnt = 2;
1713                                         break;
1714                                 }
1715                         if (*ecp->cp == ';')
1716                                 switch (ecp->addrcnt) {
1717                                 case 0:
1718                                         abort();
1719                                         /* NOTREACHED */
1720                                 case 1:
1721                                         sp->lno = ecp->addr1.lno;
1722                                         sp->cno = ecp->addr1.cno;
1723                                         break;
1724                                 case 2:
1725                                         sp->lno = ecp->addr2.lno;
1726                                         sp->cno = ecp->addr2.cno;
1727                                         break;
1728                                 }
1729                         addr = ADDR_NEED;
1730                         /* FALLTHROUGH */
1731                 case ' ':               /* Whitespace. */
1732                 case '\t':              /* Whitespace. */
1733                         ++ecp->cp;
1734                         --ecp->clen;
1735                         break;
1736                 default:
1737                         /* Get a line specification. */
1738                         if (ex_line(sp, ecp, &m, &isaddr, errp))
1739                                 return (1);
1740                         if (*errp)
1741                                 return (0);
1742                         if (!isaddr)
1743                                 goto ret;
1744                         if (addr == ADDR_FOUND) {
1745                                 ex_badaddr(sp, NULL, A_COMBO, NUM_OK);
1746                                 *errp = 1;
1747                                 return (0);
1748                         }
1749                         switch (ecp->addrcnt) {
1750                         case 0:
1751                                 ecp->addr1 = m;
1752                                 ecp->addrcnt = 1;
1753                                 break;
1754                         case 1:
1755                                 ecp->addr2 = m;
1756                                 ecp->addrcnt = 2;
1757                                 break;
1758                         case 2:
1759                                 ecp->addr1 = ecp->addr2;
1760                                 ecp->addr2 = m;
1761                                 break;
1762                         }
1763                         addr = ADDR_FOUND;
1764                         break;
1765                 }
1766
1767         /*
1768          * !!!
1769          * Vi ex address searches are indifferent to order or trailing
1770          * semi-colons.
1771          */
1772 ret:    if (F_ISSET(ecp, E_VISEARCH))
1773                 return (0);
1774
1775         if (addr == ADDR_NEED)
1776                 switch (ecp->addrcnt) {
1777                 case 0:
1778                         ecp->addr1.lno = sp->lno;
1779                         ecp->addr1.cno = sp->cno;
1780                         ecp->addrcnt = 1;
1781                         break;
1782                 case 2:
1783                         ecp->addr1 = ecp->addr2;
1784                         /* FALLTHROUGH */
1785                 case 1:
1786                         ecp->addr2.lno = sp->lno;
1787                         ecp->addr2.cno = sp->cno;
1788                         ecp->addrcnt = 2;
1789                         break;
1790                 }
1791
1792         if (ecp->addrcnt == 2 && ecp->addr2.lno < ecp->addr1.lno) {
1793                 msgq(sp, M_ERR,
1794                     "094|The second address is smaller than the first");
1795                 *errp = 1;
1796         }
1797         return (0);
1798 }
1799
1800 /*
1801  * ex_line --
1802  *      Get a single line address specifier.
1803  *
1804  * The way the "previous context" mark worked was that any "non-relative"
1805  * motion set it.  While ex/vi wasn't totally consistent about this, ANY
1806  * numeric address, search pattern, '$', or mark reference in an address
1807  * was considered non-relative, and set the value.  Which should explain
1808  * why we're hacking marks down here.  The problem was that the mark was
1809  * only set if the command was called, i.e. we have to set a flag and test
1810  * it later.
1811  *
1812  * XXX
1813  * This is probably still not exactly historic practice, although I think
1814  * it's fairly close.
1815  */
1816 static int
1817 ex_line(sp, ecp, mp, isaddrp, errp)
1818         SCR *sp;
1819         EXCMD *ecp;
1820         MARK *mp;
1821         int *isaddrp, *errp;
1822 {
1823         enum nresult nret;
1824         EX_PRIVATE *exp;
1825         GS *gp;
1826         long total, val;
1827         int isneg;
1828         int (*sf) __P((SCR *, MARK *, MARK *, char *, size_t, char **, u_int));
1829         char *endp;
1830
1831         gp = sp->gp;
1832         exp = EXP(sp);
1833
1834         *isaddrp = *errp = 0;
1835         F_CLR(ecp, E_DELTA);
1836
1837         /* No addresses permitted until a file has been read in. */
1838         if (sp->ep == NULL && strchr("$0123456789'\\/?.+-^", *ecp->cp)) {
1839                 ex_badaddr(sp, NULL, A_EMPTY, NUM_OK);
1840                 *errp = 1;
1841                 return (0);
1842         }
1843
1844         switch (*ecp->cp) {
1845         case '$':                               /* Last line in the file. */
1846                 *isaddrp = 1;
1847                 F_SET(ecp, E_ABSMARK);
1848
1849                 mp->cno = 0;
1850                 if (db_last(sp, &mp->lno))
1851                         return (1);
1852                 ++ecp->cp;
1853                 --ecp->clen;
1854                 break;                          /* Absolute line number. */
1855         case '0': case '1': case '2': case '3': case '4':
1856         case '5': case '6': case '7': case '8': case '9':
1857                 *isaddrp = 1;
1858                 F_SET(ecp, E_ABSMARK);
1859
1860                 if ((nret = nget_slong(&val, ecp->cp, &endp, 10)) != NUM_OK) {
1861                         ex_badaddr(sp, NULL, A_NOTSET, nret);
1862                         *errp = 1;
1863                         return (0);
1864                 }
1865                 if (!NPFITS(MAX_REC_NUMBER, 0, val)) {
1866                         ex_badaddr(sp, NULL, A_NOTSET, NUM_OVER);
1867                         *errp = 1;
1868                         return (0);
1869                 }
1870                 mp->lno = val;
1871                 mp->cno = 0;
1872                 ecp->clen -= (endp - ecp->cp);
1873                 ecp->cp = endp;
1874                 break;
1875         case '\'':                              /* Use a mark. */
1876                 *isaddrp = 1;
1877                 F_SET(ecp, E_ABSMARK);
1878
1879                 if (ecp->clen == 1) {
1880                         msgq(sp, M_ERR, "095|No mark name supplied");
1881                         *errp = 1;
1882                         return (0);
1883                 }
1884                 if (mark_get(sp, ecp->cp[1], mp, M_ERR)) {
1885                         *errp = 1;
1886                         return (0);
1887                 }
1888                 ecp->cp += 2;
1889                 ecp->clen -= 2;
1890                 break;
1891         case '\\':                              /* Search: forward/backward. */
1892                 /*
1893                  * !!!
1894                  * I can't find any difference between // and \/ or between
1895                  * ?? and \?.  Mark Horton doesn't remember there being any
1896                  * difference.  C'est la vie.
1897                  */
1898                 if (ecp->clen < 2 ||
1899                     ecp->cp[1] != '/' && ecp->cp[1] != '?') {
1900                         msgq(sp, M_ERR, "096|\\ not followed by / or ?");
1901                         *errp = 1;
1902                         return (0);
1903                 }
1904                 ++ecp->cp;
1905                 --ecp->clen;
1906                 sf = ecp->cp[0] == '/' ? f_search : b_search;
1907                 goto search;
1908         case '/':                               /* Search forward. */
1909                 sf = f_search;
1910                 goto search;
1911         case '?':                               /* Search backward. */
1912                 sf = b_search;
1913
1914 search:         mp->lno = sp->lno;
1915                 mp->cno = sp->cno;
1916                 if (sf(sp, mp, mp, ecp->cp, ecp->clen, &endp,
1917                     SEARCH_MSG | SEARCH_PARSE | SEARCH_SET |
1918                     (F_ISSET(ecp, E_SEARCH_WMSG) ? SEARCH_WMSG : 0))) {
1919                         *errp = 1;
1920                         return (0);
1921                 }
1922
1923                 /* Fix up the command pointers. */
1924                 ecp->clen -= (endp - ecp->cp);
1925                 ecp->cp = endp;
1926
1927                 *isaddrp = 1;
1928                 F_SET(ecp, E_ABSMARK);
1929                 break;
1930         case '.':                               /* Current position. */
1931                 *isaddrp = 1;
1932                 mp->cno = sp->cno;
1933
1934                 /* If an empty file, then '.' is 0, not 1. */
1935                 if (sp->lno == 1) {
1936                         if (db_last(sp, &mp->lno))
1937                                 return (1);
1938                         if (mp->lno != 0)
1939                                 mp->lno = 1;
1940                 } else
1941                         mp->lno = sp->lno;
1942
1943                 /*
1944                  * !!!
1945                  * Historically, .<number> was the same as .+<number>, i.e.
1946                  * the '+' could be omitted.  (This feature is found in ed
1947                  * as well.)
1948                  */
1949                 if (ecp->clen > 1 && isdigit(ecp->cp[1]))
1950                         *ecp->cp = '+';
1951                 else {
1952                         ++ecp->cp;
1953                         --ecp->clen;
1954                 }
1955                 break;
1956         }
1957
1958         /* Skip trailing <blank>s. */
1959         for (; ecp->clen > 0 &&
1960             isblank(ecp->cp[0]); ++ecp->cp, --ecp->clen);
1961
1962         /*
1963          * Evaluate any offset.  If no address yet found, the offset
1964          * is relative to ".".
1965          */
1966         total = 0;
1967         if (ecp->clen != 0 && (isdigit(ecp->cp[0]) ||
1968             ecp->cp[0] == '+' || ecp->cp[0] == '-' ||
1969             ecp->cp[0] == '^')) {
1970                 if (!*isaddrp) {
1971                         *isaddrp = 1;
1972                         mp->lno = sp->lno;
1973                         mp->cno = sp->cno;
1974                 }
1975                 /*
1976                  * Evaluate an offset, defined as:
1977                  *
1978                  *              [+-^<blank>]*[<blank>]*[0-9]*
1979                  *
1980                  * The rough translation is any number of signs, optionally
1981                  * followed by numbers, or a number by itself, all <blank>
1982                  * separated.
1983                  *
1984                  * !!!
1985                  * All address offsets were additive, e.g. "2 2 3p" was the
1986                  * same as "7p", or, "/ZZZ/ 2" was the same as "/ZZZ/+2".
1987                  * Note, however, "2 /ZZZ/" was an error.  It was also legal
1988                  * to insert signs without numbers, so "3 - 2" was legal, and
1989                  * equal to 4.
1990                  *
1991                  * !!!
1992                  * Offsets were historically permitted for any line address,
1993                  * e.g. the command "1,2 copy 2 2 2 2" copied lines 1,2 after
1994                  * line 8.
1995                  *
1996                  * !!!
1997                  * Offsets were historically permitted for search commands,
1998                  * and handled as addresses: "/pattern/2 2 2" was legal, and
1999                  * referenced the 6th line after pattern.
2000                  */
2001                 F_SET(ecp, E_DELTA);
2002                 for (;;) {
2003                         for (; ecp->clen > 0 && isblank(ecp->cp[0]);
2004                             ++ecp->cp, --ecp->clen);
2005                         if (ecp->clen == 0 || !isdigit(ecp->cp[0]) &&
2006                             ecp->cp[0] != '+' && ecp->cp[0] != '-' &&
2007                             ecp->cp[0] != '^')
2008                                 break;
2009                         if (!isdigit(ecp->cp[0]) &&
2010                             !isdigit(ecp->cp[1])) {
2011                                 total += ecp->cp[0] == '+' ? 1 : -1;
2012                                 --ecp->clen;
2013                                 ++ecp->cp;
2014                         } else {
2015                                 if (ecp->cp[0] == '-' ||
2016                                     ecp->cp[0] == '^') {
2017                                         ++ecp->cp;
2018                                         --ecp->clen;
2019                                         isneg = 1;
2020                                 } else
2021                                         isneg = 0;
2022
2023                                 /* Get a signed long, add it to the total. */
2024                                 if ((nret = nget_slong(&val,
2025                                     ecp->cp, &endp, 10)) != NUM_OK ||
2026                                     (nret = NADD_SLONG(sp,
2027                                     total, val)) != NUM_OK) {
2028                                         ex_badaddr(sp, NULL, A_NOTSET, nret);
2029                                         *errp = 1;
2030                                         return (0);
2031                                 }
2032                                 total += isneg ? -val : val;
2033                                 ecp->clen -= (endp - ecp->cp);
2034                                 ecp->cp = endp;
2035                         }
2036                 }
2037         }
2038
2039         /*
2040          * Any value less than 0 is an error.  Make sure that the new value
2041          * will fit into a recno_t.
2042          */
2043         if (*isaddrp && total != 0) {
2044                 if (total < 0) {
2045                         if (-total > mp->lno) {
2046                                 msgq(sp, M_ERR,
2047                             "097|Reference to a line number less than 0");
2048                                 *errp = 1;
2049                                 return (0);
2050                         }
2051                 } else
2052                         if (!NPFITS(MAX_REC_NUMBER, mp->lno, total)) {
2053                                 ex_badaddr(sp, NULL, A_NOTSET, NUM_OVER);
2054                                 *errp = 1;
2055                                 return (0);
2056                         }
2057                 mp->lno += total;
2058         }
2059         return (0);
2060 }
2061
2062
2063 /*
2064  * ex_load --
2065  *      Load up the next command, which may be an @ buffer or global command.
2066  */
2067 static int
2068 ex_load(sp)
2069         SCR *sp;
2070 {
2071         GS *gp;
2072         EXCMD *ecp;
2073         RANGE *rp;
2074
2075         F_CLR(sp, SC_EX_GLOBAL);
2076
2077         /*
2078          * Lose any exhausted commands.  We know that the first command
2079          * can't be an AGV command, which makes things a bit easier.
2080          */
2081         for (gp = sp->gp;;) {
2082                 /*
2083                  * If we're back to the original structure, leave it around,
2084                  * but discard any allocated source name, we've returned to
2085                  * the beginning of the command stack.
2086                  */
2087                 if ((ecp = gp->ecq.lh_first) == &gp->excmd) {
2088                         if (F_ISSET(ecp, E_NAMEDISCARD)) {
2089                                 free(ecp->if_name);
2090                                 ecp->if_name = NULL;
2091                         }
2092                         return (0);
2093                 }
2094
2095                 /*
2096                  * ecp->clen will be 0 for the first discarded command, but
2097                  * may not be 0 for subsequent ones, e.g. if the original
2098                  * command was ":g/xx/@a|s/b/c/", then when we discard the
2099                  * command pushed on the stack by the @a, we have to resume
2100                  * the global command which included the substitute command.
2101                  */
2102                 if (ecp->clen != 0)
2103                         return (0);
2104
2105                 /*
2106                  * If it's an @, global or v command, we may need to continue
2107                  * the command on a different line.
2108                  */
2109                 if (FL_ISSET(ecp->agv_flags, AGV_ALL)) {
2110                         /* Discard any exhausted ranges. */
2111                         while ((rp = ecp->rq.cqh_first) != (void *)&ecp->rq)
2112                                 if (rp->start > rp->stop) {
2113                                         CIRCLEQ_REMOVE(&ecp->rq, rp, q);
2114                                         free(rp);
2115                                 } else
2116                                         break;
2117
2118                         /* If there's another range, continue with it. */
2119                         if (rp != (void *)&ecp->rq)
2120                                 break;
2121
2122                         /* If it's a global/v command, fix up the last line. */
2123                         if (FL_ISSET(ecp->agv_flags,
2124                             AGV_GLOBAL | AGV_V) && ecp->range_lno != OOBLNO)
2125                                 if (db_exist(sp, ecp->range_lno))
2126                                         sp->lno = ecp->range_lno;
2127                                 else {
2128                                         if (db_last(sp, &sp->lno))
2129                                                 return (1);
2130                                         if (sp->lno == 0)
2131                                                 sp->lno = 1;
2132                                 }
2133                         free(ecp->o_cp);
2134                 }
2135
2136                 /* Discard the EXCMD. */
2137                 LIST_REMOVE(ecp, q);
2138                 free(ecp);
2139         }
2140
2141         /*
2142          * We only get here if it's an active @, global or v command.  Set
2143          * the current line number, and get a new copy of the command for
2144          * the parser.  Note, the original pointer almost certainly moved,
2145          * so we have play games.
2146          */
2147         ecp->cp = ecp->o_cp;
2148         memcpy(ecp->cp, ecp->cp + ecp->o_clen, ecp->o_clen);
2149         ecp->clen = ecp->o_clen;
2150         ecp->range_lno = sp->lno = rp->start++;
2151
2152         if (FL_ISSET(ecp->agv_flags, AGV_GLOBAL | AGV_V))
2153                 F_SET(sp, SC_EX_GLOBAL);
2154         return (0);
2155 }
2156
2157 /*
2158  * ex_discard --
2159  *      Discard any pending ex commands.
2160  */
2161 static int
2162 ex_discard(sp)
2163         SCR *sp;
2164 {
2165         GS *gp;
2166         EXCMD *ecp;
2167         RANGE *rp;
2168
2169         /*
2170          * We know the first command can't be an AGV command, so we don't
2171          * process it specially.  We do, however, nail the command itself.
2172          */
2173         for (gp = sp->gp; (ecp = gp->ecq.lh_first) != &gp->excmd;) {
2174                 if (FL_ISSET(ecp->agv_flags, AGV_ALL)) {
2175                         while ((rp = ecp->rq.cqh_first) != (void *)&ecp->rq) {
2176                                 CIRCLEQ_REMOVE(&ecp->rq, rp, q);
2177                                 free(rp);
2178                         }
2179                         free(ecp->o_cp);
2180                 }
2181                 LIST_REMOVE(ecp, q);
2182                 free(ecp);
2183         }
2184         gp->ecq.lh_first->clen = 0;
2185         return (0);
2186 }
2187
2188 /*
2189  * ex_unknown --
2190  *      Display an unknown command name.
2191  */
2192 static void
2193 ex_unknown(sp, cmd, len)
2194         SCR *sp;
2195         char *cmd;
2196         size_t len;
2197 {
2198         size_t blen;
2199         char *bp;
2200
2201         GET_SPACE_GOTO(sp, bp, blen, len + 1);
2202         bp[len] = '\0';
2203         memcpy(bp, cmd, len);
2204         msgq_str(sp, M_ERR, bp, "098|The %s command is unknown");
2205         FREE_SPACE(sp, bp, blen);
2206
2207 alloc_err:
2208         return;
2209 }
2210
2211 /*
2212  * ex_is_abbrev -
2213  *      The vi text input routine needs to know if ex thinks this is an
2214  *      [un]abbreviate command, so it can turn off abbreviations.  See
2215  *      the usual ranting in the vi/v_txt_ev.c:txt_abbrev() routine.
2216  *
2217  * PUBLIC: int ex_is_abbrev __P((char *, size_t));
2218  */
2219 int
2220 ex_is_abbrev(name, len)
2221         char *name;
2222         size_t len;
2223 {
2224         EXCMDLIST const *cp;
2225
2226         return ((cp = ex_comm_search(name, len)) != NULL &&
2227             (cp == &cmds[C_ABBR] || cp == &cmds[C_UNABBREVIATE]));
2228 }
2229
2230 /*
2231  * ex_is_unmap -
2232  *      The vi text input routine needs to know if ex thinks this is an
2233  *      unmap command, so it can turn off input mapping.  See the usual
2234  *      ranting in the vi/v_txt_ev.c:txt_unmap() routine.
2235  *
2236  * PUBLIC: int ex_is_unmap __P((char *, size_t));
2237  */
2238 int
2239 ex_is_unmap(name, len)
2240         char *name;
2241         size_t len;
2242 {
2243         EXCMDLIST const *cp;
2244
2245         /*
2246          * The command the vi input routines are really interested in
2247          * is "unmap!", not just unmap.
2248          */
2249         if (name[len - 1] != '!')
2250                 return (0);
2251         --len;
2252         return ((cp = ex_comm_search(name, len)) != NULL &&
2253             cp == &cmds[C_UNMAP]);
2254 }
2255
2256 /*
2257  * ex_comm_search --
2258  *      Search for a command name.
2259  */
2260 static EXCMDLIST const *
2261 ex_comm_search(name, len)
2262         char *name;
2263         size_t len;
2264 {
2265         EXCMDLIST const *cp;
2266
2267         for (cp = cmds; cp->name != NULL; ++cp) {
2268                 if (cp->name[0] > name[0])
2269                         return (NULL);
2270                 if (cp->name[0] != name[0])
2271                         continue;
2272                 if (!memcmp(name, cp->name, len))
2273                         return (cp);
2274         }
2275         return (NULL);
2276 }
2277
2278 /*
2279  * ex_badaddr --
2280  *      Display a bad address message.
2281  *
2282  * PUBLIC: void ex_badaddr
2283  * PUBLIC:    __P((SCR *, EXCMDLIST const *, enum badaddr, enum nresult));
2284  */
2285 void
2286 ex_badaddr(sp, cp, ba, nret)
2287         SCR *sp;
2288         EXCMDLIST const *cp;
2289         enum badaddr ba;
2290         enum nresult nret;
2291 {
2292         recno_t lno;
2293
2294         switch (nret) {
2295         case NUM_OK:
2296                 break;
2297         case NUM_ERR:
2298                 msgq(sp, M_SYSERR, NULL);
2299                 return;
2300         case NUM_OVER:
2301                 msgq(sp, M_ERR, "099|Address value overflow");
2302                 return;
2303         case NUM_UNDER:
2304                 msgq(sp, M_ERR, "100|Address value underflow");
2305                 return;
2306         }
2307
2308         /*
2309          * When encountering an address error, tell the user if there's no
2310          * underlying file, that's the real problem.
2311          */
2312         if (sp->ep == NULL) {
2313                 ex_emsg(sp, cp ? cp->name : NULL, EXM_NOFILEYET);
2314                 return;
2315         }
2316
2317         switch (ba) {
2318         case A_COMBO:
2319                 msgq(sp, M_ERR, "101|Illegal address combination");
2320                 break;
2321         case A_EOF:
2322                 if (db_last(sp, &lno))
2323                         return;
2324                 if (lno != 0) {
2325                         msgq(sp, M_ERR,
2326                             "102|Illegal address: only %lu lines in the file",
2327                             lno);
2328                         break;
2329                 }
2330                 /* FALLTHROUGH */
2331         case A_EMPTY:
2332                 msgq(sp, M_ERR, "103|Illegal address: the file is empty");
2333                 break;
2334         case A_NOTSET:
2335                 abort();
2336                 /* NOTREACHED */
2337         case A_ZERO:
2338                 msgq(sp, M_ERR,
2339                     "104|The %s command doesn't permit an address of 0",
2340                     cp->name);
2341                 break;
2342         }
2343         return;
2344 }
2345
2346 #if defined(DEBUG) && defined(COMLOG)
2347 /*
2348  * ex_comlog --
2349  *      Log ex commands.
2350  */
2351 static void
2352 ex_comlog(sp, ecp)
2353         SCR *sp;
2354         EXCMD *ecp;
2355 {
2356         TRACE(sp, "ecmd: %s", ecp->cmd->name);
2357         if (ecp->addrcnt > 0) {
2358                 TRACE(sp, " a1 %d", ecp->addr1.lno);
2359                 if (ecp->addrcnt > 1)
2360                         TRACE(sp, " a2: %d", ecp->addr2.lno);
2361         }
2362         if (ecp->lineno)
2363                 TRACE(sp, " line %d", ecp->lineno);
2364         if (ecp->flags)
2365                 TRACE(sp, " flags 0x%x", ecp->flags);
2366         if (F_ISSET(&exc, E_BUFFER))
2367                 TRACE(sp, " buffer %c", ecp->buffer);
2368         if (ecp->argc)
2369                 for (cnt = 0; cnt < ecp->argc; ++cnt)
2370                         TRACE(sp, " arg %d: {%s}", cnt, ecp->argv[cnt]->bp);
2371         TRACE(sp, "\n");
2372 }
2373 #endif