update to 1.01
[nvi.git] / ex / ex.c
blob9daf1c9bd45c5a271707bb6e34adf386ec419758
1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: ex.c,v 8.89 1994/01/08 13:16:01 bostic Exp $ (Berkeley) $Date: 1994/01/08 13:16:01 $";
10 #endif /* not lint */
12 #include <sys/types.h>
13 #include <sys/stat.h>
15 #include <ctype.h>
16 #include <errno.h>
17 #include <fcntl.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
22 #include "vi.h"
23 #include "excmd.h"
25 static inline EXCMDLIST const *
26 ex_comm_search __P((char *, size_t));
27 static int ep_line __P((SCR *, EXF *, MARK *, char **, size_t *, int *));
28 static int ep_range __P((SCR *, EXF *, EXCMDARG *, char **, size_t *));
30 #define DEFCOM ".+1"
33 * ex --
34 * Read an ex command and execute it.
36 int
37 ex(sp, ep)
38 SCR *sp;
39 EXF *ep;
41 TEXT *tp;
42 u_int saved_mode;
43 int eval;
44 char defcom[sizeof(DEFCOM)];
46 if (ex_init(sp, ep))
47 return (1);
49 if (sp->s_refresh(sp, ep))
50 return (ex_end(sp));
52 /* If reading from a file, messages should have line info. */
53 if (!F_ISSET(sp->gp, G_ISFROMTTY)) {
54 sp->if_lno = 1;
55 sp->if_name = strdup("input");
57 for (eval = 0;; ++sp->if_lno) {
58 /* Get the next command. */
59 switch (sp->s_get(sp, ep, &sp->tiq, ':', TXT_CR | TXT_PROMPT)) {
60 case INP_OK:
61 break;
62 case INP_EOF:
63 F_SET(sp, S_EXIT_FORCE);
64 goto ret;
65 case INP_ERR:
66 continue;
69 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
70 tp = sp->tiq.cqh_first;
71 if (tp->len == 0) {
72 if (F_ISSET(sp->gp, G_ISFROMTTY)) {
73 (void)fputc('\r', stdout);
74 (void)fflush(stdout);
76 memmove(defcom, DEFCOM, sizeof(DEFCOM));
77 (void)ex_icmd(sp, ep, defcom, sizeof(DEFCOM) - 1);
78 } else {
79 if (F_ISSET(sp->gp, G_ISFROMTTY))
80 (void)fputc('\n', stdout);
81 (void)ex_icmd(sp, ep, tp->lb, tp->len);
83 (void)msg_rpt(sp, 0);
85 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
86 break;
88 if (sp->s_refresh(sp, ep)) {
89 eval = 1;
90 break;
93 ret: if (sp->if_name != NULL) {
94 FREE(sp->if_name, strlen(sp->if_name) + 1);
95 sp->if_name = NULL;
97 return (ex_end(sp) || eval);
101 * ex_cfile --
102 * Execute ex commands from a file.
105 ex_cfile(sp, ep, filename)
106 SCR *sp;
107 EXF *ep;
108 char *filename;
110 struct stat sb;
111 int fd, len, rval;
112 char *bp;
114 bp = NULL;
115 if ((fd = open(filename, O_RDONLY, 0)) < 0 || fstat(fd, &sb))
116 goto err;
119 * XXX
120 * We'd like to test if the file is too big to malloc. Since we don't
121 * know what size or type off_t's or size_t's are, what the largest
122 * unsigned integral type is, or what random insanity the local C
123 * compiler will perpetrate, doing the comparison in a portable way
124 * is flatly impossible. Hope that malloc fails if the file is too
125 * large.
127 MALLOC(sp, bp, char *, (size_t)sb.st_size + 1);
128 if (bp == NULL)
129 goto err;
131 len = read(fd, bp, (int)sb.st_size);
132 if (len == -1 || len != sb.st_size) {
133 if (len != sb.st_size)
134 errno = EIO;
135 err: rval = 1;
136 msgq(sp, M_SYSERR, filename);
137 } else {
138 bp[sb.st_size] = '\0'; /* XXX */
140 /* Run the command. Messages include file/line information. */
141 sp->if_lno = 1;
142 sp->if_name = strdup(filename);
143 rval = ex_icmd(sp, ep, bp, len);
144 FREE(sp->if_name, strlen(sp->if_name) + 1);
145 sp->if_name = NULL;
149 * !!!
150 * THE UNDERLYING EXF MAY HAVE CHANGED.
152 if (bp != NULL)
153 FREE(bp, sb.st_size);
154 if (fd >= 0)
155 (void)close(fd);
156 return (rval);
160 * ex_icmd --
161 * Call ex_cmd() after turning off interruptible bits.
164 ex_icmd(sp, ep, cmd, len)
165 SCR *sp;
166 EXF *ep;
167 char *cmd;
168 size_t len;
171 * Ex goes through here for each vi :colon command and for each ex
172 * command, however, globally executed commands don't go through
173 * here, instead, they call ex_cmd directly. So, reset all of the
174 * interruptible flags now.
176 F_CLR(sp, S_INTERRUPTED | S_INTERRUPTIBLE);
178 return (ex_cmd(sp, ep, cmd, len));
181 /* Special command structure for :s as a repeat substitution command. */
182 static EXCMDLIST const cmd_subagain =
183 {"s", ex_subagain, E_ADDR2|E_NORC,
184 "s",
185 "[line [,line]] s [cgr] [count] [#lp]",
186 "repeat the last subsitution"};
189 * ex_cmd --
190 * Parse and execute a string containing ex commands.
193 ex_cmd(sp, ep, cmd, cmdlen)
194 SCR *sp;
195 EXF *ep;
196 char *cmd;
197 size_t cmdlen;
199 CHAR_T vlit;
200 EX_PRIVATE *exp;
201 EXCMDARG exc;
202 EXCMDLIST const *cp;
203 MARK cur;
204 recno_t lno, num;
205 size_t arg1_len, len, save_cmdlen;
206 long flagoff;
207 u_int saved_mode;
208 int ch, cnt, delim, flags, namelen, nl, uselastcmd, tmp;
209 char *arg1, *save_cmd, *p, *t;
211 /* Init. */
212 nl = 0;
213 loop: if (nl) {
214 nl = 0;
215 ++sp->if_lno;
217 arg1 = NULL;
218 save_cmdlen = 0;
221 * It's possible that we've been interrupted during a
222 * command.
224 if (F_ISSET(sp, S_INTERRUPTED))
225 return (0);
227 /* Skip whitespace, separators, newlines. */
228 for (; cmdlen > 0; ++cmd, --cmdlen)
229 if ((ch = *cmd) == '\n')
230 ++sp->if_lno;
231 else if (!isblank(ch))
232 break;
233 if (cmdlen == 0)
234 return (0);
236 /* Command lines that start with a double-quote are comments. */
237 if (ch == '"') {
238 while (--cmdlen > 0 && *++cmd != '\n');
239 if (*cmd == '\n') {
240 ++cmd;
241 --cmdlen;
242 ++sp->if_lno;
244 goto loop;
248 * !!!
249 * Permit extra colons at the start of the line. Historically,
250 * ex/vi allowed a single extra one. It's simpler not to count.
251 * The stripping is done here because, historically, any command
252 * could have preceding colons, e.g. ":g/pattern/:p" worked.
254 if (ch == ':')
255 while (--cmdlen > 0 && *++cmd == ':');
257 /* Skip whitespace. */
258 for (; cmdlen > 0; ++cmd, --cmdlen) {
259 ch = *cmd;
260 if (!isblank(ch))
261 break;
264 /* The last point at which an empty line means do nothing. */
265 if (cmdlen == 0)
266 return (0);
268 /* Initialize the structure passed to underlying functions. */
269 memset(&exc, 0, sizeof(EXCMDARG));
270 exp = EXP(sp);
271 if (argv_init(sp, ep, &exc))
272 goto err;
274 /* Parse command addresses. */
275 if (ep_range(sp, ep, &exc, &cmd, &cmdlen))
276 goto err;
278 /* Skip whitespace. */
279 for (; cmdlen > 0; ++cmd, --cmdlen) {
280 ch = *cmd;
281 if (!isblank(ch))
282 break;
286 * If no command, ex does the last specified of p, l, or #, and vi
287 * moves to the line. Otherwise, determine the length of the command
288 * name by looking for the first non-alphabetic character. (There
289 * are a few non-alphabetic characters in command names, but they're
290 * all single character commands.) This isn't a great test, because
291 * it means that, for the command ":e +cut.c file", we'll report that
292 * the command "cut" wasn't known. However, it makes ":e+35 file" work
293 * correctly.
295 #define SINGLE_CHAR_COMMANDS "!#&<=>@~"
296 if (cmdlen != 0 && cmd[0] != '|' && cmd[0] != '\n') {
297 if (strchr(SINGLE_CHAR_COMMANDS, *cmd)) {
298 p = cmd;
299 ++cmd;
300 --cmdlen;
301 namelen = 1;
302 } else {
303 for (p = cmd; cmdlen > 0; --cmdlen, ++cmd)
304 if (!isalpha(*cmd))
305 break;
306 if ((namelen = cmd - p) == 0) {
307 msgq(sp, M_ERR, "Unknown command name.");
308 goto err;
313 * Search the table for the command.
315 * !!!
316 * Historic vi permitted the mark to immediately follow the
317 * 'k' in the 'k' command. Make it work.
319 * !!!
320 * Historic vi permitted pretty much anything to follow the
321 * substitute command, e.g. "s/e/E/|s|sgc3p" was fine. Make
322 * it work.
324 * Use of msgq below is safe, command names are all alphabetics.
326 if ((cp = ex_comm_search(p, namelen)) == NULL)
327 if (p[0] == 'k' && p[1] && !p[2]) {
328 cmd -= namelen - 1;
329 cmdlen += namelen - 1;
330 cp = &cmds[C_K];
331 } else if (p[0] == 's') {
332 cmd -= namelen - 1;
333 cmdlen += namelen - 1;
334 cp = &cmd_subagain;
335 } else {
336 msgq(sp, M_ERR,
337 "The %.*s command is unknown.", namelen, p);
338 goto err;
341 /* Some commands are either not implemented or turned off. */
342 if (F_ISSET(cp, E_NOPERM)) {
343 msgq(sp, M_ERR,
344 "The %s command is not currently supported.",
345 cp->name);
346 goto err;
349 /* Some commands aren't okay in globals. */
350 if (F_ISSET(sp, S_GLOBAL) && F_ISSET(cp, E_NOGLOBAL)) {
351 msgq(sp, M_ERR,
352 "The %s command can't be used as part of a global command.",
353 cp->name);
354 goto err;
358 * Multiple < and > characters; another "feature". Note,
359 * The string passed to the underlying function may not be
360 * nul terminated in this case.
362 if ((cp == &cmds[C_SHIFTL] && *p == '<') ||
363 (cp == &cmds[C_SHIFTR] && *p == '>')) {
364 for (ch = *p; cmdlen > 0; --cmdlen, ++cmd)
365 if (*cmd != ch)
366 break;
367 if (argv_exp0(sp, ep, &exc, p, cmd - p))
368 goto err;
372 * The visual command has a different syntax when called
373 * from ex than when called from a vi colon command. FMH.
375 if (cp == &cmds[C_VISUAL_EX] && IN_VI_MODE(sp))
376 cp = &cmds[C_VISUAL_VI];
378 uselastcmd = 0;
379 } else {
380 cp = exp->lastcmd;
381 uselastcmd = 1;
384 /* Initialize local flags to the command flags. */
385 LF_INIT(cp->flags);
388 * File state must be checked throughout this code, because it is
389 * called when reading the .exrc file and similar things. There's
390 * this little chicken and egg problem -- if we read the file first,
391 * we won't know how to display it. If we read/set the exrc stuff
392 * first, we can't allow any command that requires file state.
393 * Historic vi generally took the easy way out and dropped core.
395 if (LF_ISSET(E_NORC) && ep == NULL) {
396 msgq(sp, M_ERR,
397 "The %s command requires that a file already have been read in.",
398 cp->name);
399 goto err;
403 * There are three normal termination cases for an ex command. They
404 * are the end of the string (cmdlen), or unescaped (by literal next
405 * characters) newline or '|' characters. As we're past any addresses,
406 * we can now determine how long the command is, so we don't have to
407 * look for all the possible terminations. There are three exciting
408 * special cases:
410 * 1: The bang, global, vglobal and the filter versions of the read and
411 * write commands are delimited by newlines (they can contain shell
412 * pipes).
413 * 2: The ex, edit and visual in vi mode commands take ex commands as
414 * their first arguments.
415 * 3: The substitute command takes an RE as its first argument, and
416 * wants it to be specially delimited.
418 * Historically, '|' characters in the first argument of the ex, edit,
419 * and substitute commands did not delimit the command. And, in the
420 * filter cases for read and write, and the bang, global and vglobal
421 * commands, they did not delimit the command at all.
423 * For example, the following commands were legal:
425 * :edit +25|s/abc/ABC/ file.c
426 * :substitute s/|/PIPE/
427 * :read !spell % | columnate
428 * :global/pattern/p|l
430 * It's not quite as simple as it sounds, however. The command:
432 * :substitute s/a/b/|s/c/d|set
434 * was also legal, i.e. the historic ex parser (using the word loosely,
435 * since "parser" implies some regularity) delimited the RE's based on
436 * its delimiter and not anything so irretrievably vulgar as a command
437 * syntax.
439 * One thing that makes this easier is that we can ignore most of the
440 * command termination conditions for the commands that want to take
441 * the command up to the next newline. None of them are legal in .exrc
442 * files, so if we're here, we only dealing with a single line, and we
443 * can just eat it.
445 * Anyhow, the following code makes this all work. First, for the
446 * special cases we move past their special argument. Then, we do
447 * normal command processing on whatever is left. Barf-O-Rama.
449 arg1_len = 0;
450 save_cmd = cmd;
451 (void)term_key_ch(sp, K_VLNEXT, &vlit);
452 if (cp == &cmds[C_EDIT] ||
453 cp == &cmds[C_EX] || cp == &cmds[C_VISUAL_VI]) {
455 * Move to the next non-whitespace character. As '+' must
456 * be the character after the command name, if there isn't
457 * one, we're done.
459 for (; cmdlen > 0; --cmdlen, ++cmd) {
460 ch = *cmd;
461 if (!isblank(ch))
462 break;
465 * QUOTING NOTE:
467 * The historic implementation ignored all escape characters
468 * so there was no way to put a space or newline into the +cmd
469 * field. We do a simplistic job of fixing it by moving to the
470 * first whitespace character that isn't escaped by a literal
471 * next character. The literal next characters are stripped
472 * as they're no longer useful.
474 if (cmdlen > 0 && ch == '+') {
475 ++cmd;
476 --cmdlen;
477 for (arg1 = p = cmd; cmdlen > 0; --cmdlen, ++cmd) {
478 if ((ch = *cmd) == vlit && cmdlen > 1) {
479 --cmdlen;
480 ch = *++cmd;
481 } else if (isblank(ch))
482 break;
483 *p++ = ch;
485 arg1_len = cmd - arg1;
487 /* Reset, so the first argument isn't reparsed. */
488 save_cmd = cmd;
490 } else if (cp == &cmds[C_BANG] ||
491 cp == &cmds[C_GLOBAL] || cp == &cmds[C_VGLOBAL]) {
492 cmd += cmdlen;
493 cmdlen = 0;
494 } else if (cp == &cmds[C_READ] || cp == &cmds[C_WRITE]) {
496 * Move to the next character. If it's a '!', it's a filter
497 * command and we want to eat it all, otherwise, we're done.
499 for (; cmdlen > 0; --cmdlen, ++cmd) {
500 ch = *cmd;
501 if (!isblank(ch))
502 break;
504 if (cmdlen > 0 && ch == '!') {
505 cmd += cmdlen;
506 cmdlen = 0;
508 } else if (cp == &cmds[C_SUBSTITUTE]) {
510 * Move to the next non-whitespace character, we'll use it as
511 * the delimiter. If the character isn't an alphanumeric or
512 * a '|', it's the delimiter, so parse it. Otherwise, we're
513 * into something like ":s g", so use the special substitute
514 * command.
516 for (; cmdlen > 0; --cmdlen, ++cmd)
517 if (!isblank(cmd[0]))
518 break;
520 if (isalnum(cmd[0]) || cmd[0] == '|')
521 cp = &cmd_subagain;
522 else if (cmdlen > 0) {
524 * QUOTING NOTE:
526 * Backslashes quote delimiter characters for RE's.
527 * The backslashes are NOT removed since they'll be
528 * used by the RE code. Move to the third delimiter
529 * that's not escaped (or the end of the command).
531 delim = *cmd;
532 ++cmd;
533 --cmdlen;
534 for (cnt = 2; cmdlen > 0 && cnt; --cmdlen, ++cmd)
535 if (cmd[0] == '\\' && cmdlen > 1) {
536 ++cmd;
537 --cmdlen;
538 } else if (cmd[0] == delim)
539 --cnt;
543 * Use normal quoting and termination rules to find the end
544 * of this command.
546 * QUOTING NOTE:
548 * Historically, vi permitted ^V's to escape <newline>'s in the .exrc
549 * file. It was almost certainly a bug, but that's what bug-for-bug
550 * compatibility means, Grasshopper. Also, ^V's escape the command
551 * delimiters. Literal next quote characters in front of the newlines,
552 * '|' characters or literal next characters are stripped as as they're
553 * no longer useful.
555 for (p = cmd, cnt = 0; cmdlen > 0; --cmdlen, ++cmd) {
556 if ((ch = cmd[0]) == vlit && cmdlen > 1) {
557 ch = cmd[1];
558 if (ch == '\n' || ch == '|') {
559 if (ch == '\n')
560 ++sp->if_lno;
561 --cmdlen;
562 ++cmd;
563 ++cnt;
564 } else
565 ch = vlit;
566 } else if (ch == '\n' || ch == '|') {
567 if (ch == '\n')
568 nl = 1;
569 --cmdlen;
570 break;
572 *p++ = ch;
576 * Save off the next command information, go back to the
577 * original start of the command.
579 p = cmd + 1;
580 cmd = save_cmd;
581 save_cmd = p;
582 save_cmdlen = cmdlen;
583 cmdlen = ((save_cmd - cmd) - 1) - cnt;
586 * !!!
587 * The "set tags" command historically used a backslash, not the
588 * user's literal next character, to escape whitespace. Handle
589 * it here instead of complicating the argv_exp3() code. Note,
590 * this isn't a particularly complex trap, and if backslashes were
591 * legal in set commands, this would have to be much more complicated.
593 if (cp == &cmds[C_SET])
594 for (p = cmd, len = cmdlen; len > 0; --len, ++p)
595 if (*p == '\\')
596 *p = vlit;
599 * Set the default addresses. It's an error to specify an address for
600 * a command that doesn't take them. If two addresses are specified
601 * for a command that only takes one, lose the first one. Two special
602 * cases here, some commands take 0 or 2 addresses. For most of them
603 * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one
604 * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
606 * Also, if the file is empty, some commands want to use an address of
607 * 0, i.e. the entire file is 0 to 0, and the default first address is
608 * 0. Otherwise, an entire file is 1 to N and the default line is 1.
609 * Note, we also add the E_ZERO flag to the command flags, for the case
610 * where the 0 address is only valid if it's a default address.
612 * Also, set a flag if we set the default addresses. Some commands
613 * (ex: z) care if the user specified an address of if we just used
614 * the current cursor.
616 switch (LF_ISSET(E_ADDR1|E_ADDR2|E_ADDR2_ALL|E_ADDR2_NONE)) {
617 case E_ADDR1: /* One address: */
618 switch (exc.addrcnt) {
619 case 0: /* Default cursor/empty file. */
620 exc.addrcnt = 1;
621 F_SET(&exc, E_ADDRDEF);
622 if (LF_ISSET(E_ZERODEF)) {
623 if (file_lline(sp, ep, &lno))
624 goto err;
625 if (lno == 0) {
626 exc.addr1.lno = 0;
627 LF_SET(E_ZERO);
628 } else
629 exc.addr1.lno = sp->lno;
630 } else
631 exc.addr1.lno = sp->lno;
632 exc.addr1.cno = sp->cno;
633 break;
634 case 1:
635 break;
636 case 2: /* Lose the first address. */
637 exc.addrcnt = 1;
638 exc.addr1 = exc.addr2;
640 break;
641 case E_ADDR2_NONE: /* Zero/two addresses: */
642 if (exc.addrcnt == 0) /* Default to nothing. */
643 break;
644 goto two;
645 case E_ADDR2_ALL: /* Zero/two addresses: */
646 if (exc.addrcnt == 0) { /* Default entire/empty file. */
647 exc.addrcnt = 2;
648 F_SET(&exc, E_ADDRDEF);
649 if (file_lline(sp, ep, &exc.addr2.lno))
650 goto err;
651 if (LF_ISSET(E_ZERODEF) && exc.addr2.lno == 0) {
652 exc.addr1.lno = 0;
653 LF_SET(E_ZERO);
654 } else
655 exc.addr1.lno = 1;
656 exc.addr1.cno = exc.addr2.cno = 0;
657 F_SET(&exc, E_ADDR2_ALL);
658 break;
660 /* FALLTHROUGH */
661 case E_ADDR2: /* Two addresses: */
662 two: switch (exc.addrcnt) {
663 case 0: /* Default cursor/empty file. */
664 exc.addrcnt = 2;
665 F_SET(&exc, E_ADDRDEF);
666 if (LF_ISSET(E_ZERODEF) && sp->lno == 1) {
667 if (file_lline(sp, ep, &lno))
668 goto err;
669 if (lno == 0) {
670 exc.addr1.lno = exc.addr2.lno = 0;
671 LF_SET(E_ZERO);
672 } else
673 exc.addr1.lno = exc.addr2.lno = sp->lno;
674 } else
675 exc.addr1.lno = exc.addr2.lno = sp->lno;
676 exc.addr1.cno = exc.addr2.cno = sp->cno;
677 break;
678 case 1: /* Default to first address. */
679 exc.addrcnt = 2;
680 exc.addr2 = exc.addr1;
681 break;
682 case 2:
683 break;
685 break;
686 default:
687 if (exc.addrcnt) /* Error. */
688 goto usage;
691 flagoff = 0;
692 for (p = cp->syntax; *p != '\0'; ++p) {
694 * The write command is sensitive to leading whitespace, e.g.
695 * "write !" is different from "write!". If not the write
696 * command, skip leading whitespace.
698 if (cp != &cmds[C_WRITE])
699 for (; cmdlen > 0; --cmdlen, ++cmd) {
700 ch = *cmd;
701 if (!isblank(ch))
702 break;
706 * Quit when reach the end of the command, unless it's a
707 * command that does its own parsing, in which case we want
708 * to build a reasonable argv for it. This code guarantees
709 * that there will be an argv when the function gets called,
710 * so the correct test is for a length of 0, not for the
711 * argc > 0.
713 if (cmdlen == 0 && *p != '!' && *p != 'S' && *p != 's')
714 break;
716 switch (*p) {
717 case '!': /* ! */
718 if (*cmd == '!') {
719 ++cmd;
720 --cmdlen;
721 F_SET(&exc, E_FORCE);
723 break;
724 case '1': /* +, -, #, l, p */
726 * !!!
727 * Historically, some flags were ignored depending
728 * on where they occurred in the command line. For
729 * example, in the command, ":3+++p--#", historic vi
730 * acted on the '#' flag, but ignored the '-' flags.
731 * It's unambiguous what the flags mean, so we just
732 * handle them regardless of the stupidity of their
733 * location.
735 for (; cmdlen; --cmdlen, ++cmd)
736 switch (*cmd) {
737 case '+':
738 ++flagoff;
739 break;
740 case '-':
741 --flagoff;
742 break;
743 case '#':
744 F_SET(&exc, E_F_HASH);
745 break;
746 case 'l':
747 F_SET(&exc, E_F_LIST);
748 break;
749 case 'p':
750 F_SET(&exc, E_F_PRINT);
751 break;
752 default:
753 goto end1;
755 end1: break;
756 case '2': /* -, ., +, ^ */
757 case '3': /* -, ., +, ^, = */
758 for (; cmdlen; --cmdlen, ++cmd)
759 switch (*cmd) {
760 case '-':
761 F_SET(&exc, E_F_DASH);
762 break;
763 case '.':
764 F_SET(&exc, E_F_DOT);
765 break;
766 case '+':
767 F_SET(&exc, E_F_PLUS);
768 break;
769 case '^':
770 F_SET(&exc, E_F_CARAT);
771 break;
772 case '=':
773 if (*p == '3') {
774 F_SET(&exc, E_F_EQUAL);
775 break;
777 /* FALLTHROUGH */
778 default:
779 goto end2;
781 end2: break;
782 case 'b': /* buffer */
784 * Digits can't be buffer names in ex commands, or the
785 * command "d2" would be a delete into buffer '2', and
786 * not a two-line deletion.
788 if (!isdigit(cmd[0])) {
789 exc.buffer = *cmd;
790 ++cmd;
791 --cmdlen;
792 F_SET(&exc, E_BUFFER);
794 break;
795 case 'c': /* count [01+a] */
796 ++p;
797 if (!isdigit(*cmd) &&
798 (*p != '+' || (*cmd != '+' && *cmd != '-')))
799 break;
800 /* 8-bit XXX */ if ((lno = strtol(cmd, &t, 10)) == 0 && *p != '0') {
801 msgq(sp, M_ERR, "Count may not be zero.");
802 goto err;
804 cmdlen -= (t - cmd);
805 cmd = t;
807 * Count as address offsets occur in commands taking
808 * two addresses. Historic vi practice was to use
809 * the count as an offset from the *second* address.
811 * Set a count flag; some underlying commands (see
812 * join) do different things with counts than with
813 * line addresses.
815 if (*p == 'a') {
816 exc.addr1 = exc.addr2;
817 exc.addr2.lno = exc.addr1.lno + lno - 1;
818 } else
819 exc.count = lno;
820 F_SET(&exc, E_COUNT);
821 break;
822 case 'f': /* file */
823 if (argv_exp2(sp, ep,
824 &exc, cmd, cmdlen, cp == &cmds[C_BANG]))
825 goto err;
826 goto countchk;
827 case 'l': /* line */
828 if (ep_line(sp, ep, &cur, &cmd, &cmdlen, &tmp))
829 goto err;
830 /* Line specifications are always required. */
831 if (!tmp) {
832 msgq(sp, M_ERR,
833 "%s: bad line specification", cmd);
834 goto err;
836 exc.lineno = cur.lno;
837 break;
838 case 'S': /* string, file exp. */
839 if (argv_exp1(sp, ep,
840 &exc, cmd, cmdlen, cp == &cmds[C_BANG]))
841 goto err;
842 goto addr2;
843 case 's': /* string */
844 if (argv_exp0(sp, ep, &exc, cmd, cmdlen))
845 goto err;
846 goto addr2;
847 case 'W': /* word string */
849 * QUOTING NOTE:
851 * Literal next characters escape the following
852 * character. Quoting characters are stripped
853 * here since they are no longer useful.
855 * First there was the word.
857 for (p = t = cmd; cmdlen > 0; --cmdlen, ++cmd) {
858 if ((ch = *cmd) == vlit && cmdlen > 1) {
859 --cmdlen;
860 *p++ = *++cmd;
861 } else if (isblank(ch)) {
862 ++cmd;
863 --cmdlen;
864 break;
865 } else
866 *p++ = ch;
868 if (argv_exp0(sp, ep, &exc, t, p - t))
869 goto err;
871 /* Delete intervening whitespace. */
872 for (; cmdlen > 0; --cmdlen, ++cmd) {
873 ch = *cmd;
874 if (!isblank(ch))
875 break;
877 if (cmdlen == 0)
878 goto usage;
880 /* Followed by the string. */
881 for (p = t = cmd; cmdlen > 0; --cmdlen, ++cmd, ++p)
882 if ((ch = *cmd) == vlit && cmdlen > 1) {
883 --cmdlen;
884 *p = *++cmd;
885 } else
886 *p = ch;
887 if (argv_exp0(sp, ep, &exc, t, p - t))
888 goto err;
889 goto addr2;
890 case 'w': /* word */
891 if (argv_exp3(sp, ep, &exc, cmd, cmdlen))
892 goto err;
893 countchk: if (*++p != 'N') { /* N */
895 * If a number is specified, must either be
896 * 0 or that number, if optional, and that
897 * number, if required.
899 num = *p - '0';
900 if ((*++p != 'o' || exp->argsoff != 0) &&
901 exp->argsoff != num)
902 goto usage;
904 goto addr2;
905 default:
906 msgq(sp, M_ERR,
907 "Internal syntax table error (%s: %c).",
908 cp->name, *p);
912 /* Skip trailing whitespace. */
913 for (; cmdlen; --cmdlen) {
914 ch = *cmd++;
915 if (!isblank(ch))
916 break;
920 * There shouldn't be anything left, and no more required
921 * fields, i.e neither 'l' or 'r' in the syntax string.
923 if (cmdlen || strpbrk(p, "lr")) {
924 usage: msgq(sp, M_ERR, "Usage: %s.", cp->usage);
925 goto err;
928 /* Verify that the addresses are legal. */
929 addr2: switch (exc.addrcnt) {
930 case 2:
931 if (file_lline(sp, ep, &lno))
932 goto err;
934 * Historic ex/vi permitted commands with counts to go past
935 * EOF. So, for example, if the file only had 5 lines, the
936 * ex command "1,6>" would fail, but the command ">300"
937 * would succeed. Since we don't want to have to make all
938 * of the underlying commands handle random line numbers,
939 * fix it here.
941 if (exc.addr2.lno > lno)
942 if (F_ISSET(&exc, E_COUNT))
943 exc.addr2.lno = lno;
944 else {
945 if (lno == 0)
946 msgq(sp, M_ERR, "The file is empty.");
947 else
948 msgq(sp, M_ERR,
949 "Only %lu line%s in the file",
950 lno, lno > 1 ? "s" : "");
951 goto err;
953 /* FALLTHROUGH */
954 case 1:
955 num = exc.addr1.lno;
957 * If it's a "default vi command", zero is okay. Historic
958 * vi allowed this, note, it's also the hack that allows
959 * "vi + nonexistent_file" to work.
961 if (num == 0 && (!IN_VI_MODE(sp) || uselastcmd != 1) &&
962 !LF_ISSET(E_ZERO)) {
963 msgq(sp, M_ERR,
964 "The %s command doesn't permit an address of 0.",
965 cp->name);
966 goto err;
968 if (file_lline(sp, ep, &lno))
969 goto err;
970 if (num > lno) {
971 if (lno == 0)
972 msgq(sp, M_ERR, "The file is empty.");
973 else
974 msgq(sp, M_ERR, "Only %lu line%s in the file",
975 lno, lno > 1 ? "s" : "");
976 goto err;
978 break;
981 /* If doing a default command, vi just moves to the line. */
982 if (IN_VI_MODE(sp) && uselastcmd) {
983 switch (exc.addrcnt) {
984 case 2:
985 sp->lno = exc.addr2.lno ? exc.addr2.lno : 1;
986 sp->cno = exc.addr2.cno;
987 break;
988 case 1:
989 sp->lno = exc.addr1.lno ? exc.addr1.lno : 1;
990 sp->cno = exc.addr1.cno;
991 break;
993 cmd = save_cmd;
994 cmdlen = save_cmdlen;
995 goto loop;
998 /* Reset "last" command. */
999 if (LF_ISSET(E_SETLAST))
1000 exp->lastcmd = cp;
1002 /* Final setup for the command. */
1003 exc.cmd = cp;
1005 #if defined(DEBUG) && 0
1006 TRACE(sp, "ex_cmd: %s", exc.cmd->name);
1007 if (exc.addrcnt > 0) {
1008 TRACE(sp, "\taddr1 %d", exc.addr1.lno);
1009 if (exc.addrcnt > 1)
1010 TRACE(sp, " addr2: %d", exc.addr2.lno);
1011 TRACE(sp, "\n");
1013 if (exc.lineno)
1014 TRACE(sp, "\tlineno %d", exc.lineno);
1015 if (exc.flags)
1016 TRACE(sp, "\tflags %0x", exc.flags);
1017 if (F_ISSET(&exc, E_BUFFER))
1018 TRACE(sp, "\tbuffer %c", exc.buffer);
1019 TRACE(sp, "\n");
1020 if (exc.argc) {
1021 for (cnt = 0; cnt < exc.argc; ++cnt)
1022 TRACE(sp, "\targ %d: {%s}", cnt, exc.argv[cnt]);
1023 TRACE(sp, "\n");
1025 #endif
1026 /* Clear autoprint flag. */
1027 F_CLR(exp, EX_AUTOPRINT);
1029 /* Increment the command count if not called from vi. */
1030 if (!IN_VI_MODE(sp))
1031 ++sp->ccnt;
1034 * If file state and not doing a global command, log the start of
1035 * an action.
1037 if (ep != NULL && !F_ISSET(sp, S_GLOBAL))
1038 (void)log_cursor(sp, ep);
1040 /* Save the current mode. */
1041 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
1043 /* Do the command. */
1044 if ((cp->fn)(sp, ep, &exc))
1045 goto err;
1047 #ifdef DEBUG
1048 /* Make sure no function left the temporary space locked. */
1049 if (F_ISSET(sp->gp, G_TMP_INUSE)) {
1050 F_CLR(sp->gp, G_TMP_INUSE);
1051 msgq(sp, M_ERR, "Error: ex: temporary buffer not released.");
1052 goto err;
1054 #endif
1055 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE)) {
1057 * Only here if the mode of the underlying file changed, e.g.
1058 * the user switched files or is exiting. There are two things
1059 * that we might have to save. First, any "+cmd" field set up
1060 * for an ex/edit command will have to be saved for later, also,
1061 * any not yet executed part of the current ex command.
1063 * :edit +25 file.c|s/abc/ABC/|1
1065 * for example.
1067 * The historic vi just hung, of course; we handle by
1068 * pushing the keys onto the tty queue. If we're
1069 * switching modes to vi, since the commands are intended
1070 * as ex commands, add the extra characters to make it
1071 * work.
1073 * For the fun of it, if you want to see if a vi clone got
1074 * the ex argument parsing right, try:
1076 * echo 'foo|bar' > file1; echo 'foo/bar' > file2;
1077 * vi
1078 * :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq
1080 if (arg1_len == NULL && save_cmdlen == 0)
1081 return (0);
1082 if (IN_VI_MODE(sp) && term_push(sp, "\n", 1, 0, 0))
1083 goto err;
1084 if (save_cmdlen != 0)
1085 if (term_push(sp, save_cmd, save_cmdlen, 0, 0))
1086 goto err;
1087 if (arg1 != NULL) {
1088 if (IN_VI_MODE(sp) && save_cmdlen != 0 &&
1089 term_push(sp, "|", 1, 0, 0))
1090 goto err;
1091 if (term_push(sp, arg1, arg1_len, 0, 0))
1092 goto err;
1094 if (IN_VI_MODE(sp) && term_push(sp, ":", 1, 0, 0))
1095 goto err;
1096 return (0);
1099 if (IN_EX_MODE(sp) && ep != NULL) {
1101 * The print commands have already handled the `print' flags.
1102 * If so, clear them. Don't return, autoprint may still have
1103 * stuff to print out.
1105 if (LF_ISSET(E_F_PRCLEAR))
1106 F_CLR(&exc, E_F_HASH | E_F_LIST | E_F_PRINT);
1109 * If the command was successful, and there was an explicit
1110 * flag to display the new cursor line, or we're in ex mode,
1111 * autoprint is set, and a change was made, display the line.
1113 if (flagoff) {
1114 if (flagoff < 0) {
1115 if (sp->lno < -flagoff) {
1116 msgq(sp, M_ERR,
1117 "Flag offset before line 1.");
1118 goto err;
1120 } else {
1121 if (file_lline(sp, ep, &lno))
1122 goto err;
1123 if (sp->lno + flagoff > lno) {
1124 msgq(sp, M_ERR,
1125 "Flag offset past end-of-file.");
1126 goto err;
1129 sp->lno += flagoff;
1132 if (O_ISSET(sp, O_AUTOPRINT) &&
1133 (F_ISSET(exp, EX_AUTOPRINT) || F_ISSET(cp, E_AUTOPRINT)))
1134 LF_INIT(E_F_PRINT);
1135 else
1136 LF_INIT(F_ISSET(&exc, E_F_HASH | E_F_LIST | E_F_PRINT));
1138 memset(&exc, 0, sizeof(EXCMDARG));
1139 exc.addrcnt = 2;
1140 exc.addr1.lno = exc.addr2.lno = sp->lno;
1141 exc.addr1.cno = exc.addr2.cno = sp->cno;
1142 switch (LF_ISSET(E_F_HASH | E_F_LIST | E_F_PRINT)) {
1143 case E_F_HASH:
1144 exc.cmd = &cmds[C_HASH];
1145 ex_number(sp, ep, &exc);
1146 break;
1147 case E_F_LIST:
1148 exc.cmd = &cmds[C_LIST];
1149 ex_list(sp, ep, &exc);
1150 break;
1151 case E_F_PRINT:
1152 exc.cmd = &cmds[C_PRINT];
1153 ex_pr(sp, ep, &exc);
1154 break;
1158 cmd = save_cmd;
1159 cmdlen = save_cmdlen;
1160 goto loop;
1161 /* NOTREACHED */
1164 * On error, we discard any keys we have left, as well as any keys
1165 * that were mapped. The test of save_cmdlen isn't necessarily
1166 * correct. If we fail early enough we don't know if the entire
1167 * string was a single command or not. Try and guess, it's useful
1168 * to know if part of the command was discarded.
1170 if (save_cmdlen == 0)
1171 for (; cmdlen; --cmdlen)
1172 if ((ch = *cmd++) == vlit && cmdlen > 1) {
1173 --cmdlen;
1174 ++cmd;
1175 } else if (ch == '\n' || ch == '|') {
1176 if (cmdlen > 1)
1177 save_cmdlen = 1;
1178 break;
1180 if (save_cmdlen != 0)
1181 msgq(sp, M_ERR,
1182 "Ex command failed: remaining command input discarded.");
1183 err: term_map_flush(sp, "Ex command failed");
1184 return (1);
1188 * ep_range --
1189 * Get a line range for ex commands.
1191 static int
1192 ep_range(sp, ep, excp, cmdp, cmdlenp)
1193 SCR *sp;
1194 EXF *ep;
1195 EXCMDARG *excp;
1196 char **cmdp;
1197 size_t *cmdlenp;
1199 MARK cur, savecursor;
1200 size_t cmdlen;
1201 int savecursor_set, tmp;
1202 char *cmd;
1204 /* Percent character is all lines in the file. */
1205 cmd = *cmdp;
1206 cmdlen = *cmdlenp;
1207 if (*cmd == '%') {
1208 excp->addr1.lno = 1;
1209 if (file_lline(sp, ep, &excp->addr2.lno))
1210 return (1);
1212 /* If an empty file, then the first line is 0, not 1. */
1213 if (excp->addr2.lno == 0)
1214 excp->addr1.lno = 0;
1215 excp->addr1.cno = excp->addr2.cno = 0;
1216 excp->addrcnt = 2;
1218 ++*cmdp;
1219 --*cmdlenp;
1220 return (0);
1223 /* Parse comma or semi-colon delimited line specs. */
1224 for (savecursor_set = 0, excp->addrcnt = 0; cmdlen > 0;)
1225 switch (*cmd) {
1226 case ';': /* Semi-colon delimiter. */
1228 * Comma delimiters delimit; semi-colon delimiters
1229 * change the current address for the 2nd address
1230 * to be the first address. Trailing or multiple
1231 * delimiters are discarded.
1233 if (excp->addrcnt == 0)
1234 goto done;
1235 if (!savecursor_set) {
1236 savecursor.lno = sp->lno;
1237 savecursor.cno = sp->cno;
1238 sp->lno = excp->addr1.lno;
1239 sp->cno = excp->addr1.cno;
1240 savecursor_set = 1;
1242 ++cmd;
1243 --cmdlen;
1244 break;
1245 case ',': /* Comma delimiter. */
1246 /* If no addresses yet, defaults to ".". */
1247 if (excp->addrcnt == 0) {
1248 excp->addr1.lno = sp->lno;
1249 excp->addr1.cno = sp->cno;
1250 excp->addrcnt = 1;
1252 /* FALLTHROUGH */
1253 case ' ': /* Whitespace. */
1254 case '\t': /* Whitespace. */
1255 ++cmd;
1256 --cmdlen;
1257 break;
1258 default:
1259 if (ep_line(sp, ep, &cur, &cmd, &cmdlen, &tmp))
1260 return (1);
1261 if (!tmp)
1262 goto done;
1265 * Extra addresses are discarded, starting with
1266 * the first.
1268 switch (excp->addrcnt) {
1269 case 0:
1270 excp->addr1 = cur;
1271 excp->addrcnt = 1;
1272 break;
1273 case 1:
1274 excp->addr2 = cur;
1275 excp->addrcnt = 2;
1276 break;
1277 case 2:
1278 excp->addr1 = excp->addr2;
1279 excp->addr2 = cur;
1280 break;
1282 break;
1286 * XXX
1287 * This is probably not right behavior for savecursor -- need
1288 * to figure out what the historical ex did for ";,;,;5p" or
1289 * similar stupidity.
1291 done: if (savecursor_set) {
1292 sp->lno = savecursor.lno;
1293 sp->cno = savecursor.cno;
1295 if (excp->addrcnt == 2 &&
1296 (excp->addr2.lno < excp->addr1.lno ||
1297 excp->addr2.lno == excp->addr1.lno &&
1298 excp->addr2.cno < excp->addr1.cno)) {
1299 msgq(sp, M_ERR,
1300 "The second address is smaller than the first.");
1301 return (1);
1303 *cmdp = cmd;
1304 *cmdlenp = cmdlen;
1305 return (0);
1309 * Get a single line address specifier.
1311 static int
1312 ep_line(sp, ep, cur, cmdp, cmdlenp, addr_found)
1313 SCR *sp;
1314 EXF *ep;
1315 MARK *cur;
1316 char **cmdp;
1317 size_t *cmdlenp;
1318 int *addr_found;
1320 MARK m, *mp;
1321 long total;
1322 u_int flags;
1323 size_t cmdlen;
1324 char *cmd, *endp;
1326 *addr_found = 0;
1328 cmd = *cmdp;
1329 cmdlen = *cmdlenp;
1330 switch (*cmd) {
1331 case '$': /* Last line in the file. */
1332 *addr_found = 1;
1333 cur->cno = 0;
1334 if (file_lline(sp, ep, &cur->lno))
1335 return (1);
1336 ++cmd;
1337 --cmdlen;
1338 break; /* Absolute line number. */
1339 case '0': case '1': case '2': case '3': case '4':
1340 case '5': case '6': case '7': case '8': case '9':
1341 *addr_found = 1;
1343 * The way the vi "previous context" mark worked was that
1344 * "non-relative" motions set it. While vi wasn't totally
1345 * consistent about this, ANY numeric address was considered
1346 * non-relative, and set the value. Which is why we're
1347 * hacking marks down here.
1349 if (IN_VI_MODE(sp)) {
1350 m.lno = sp->lno;
1351 m.cno = sp->cno;
1352 if (mark_set(sp, ep, ABSMARK1, &m, 1))
1353 return (1);
1355 cur->cno = 0;
1356 /* 8-bit XXX */ cur->lno = strtol(cmd, &endp, 10);
1357 cmdlen -= (endp - cmd);
1358 cmd = endp;
1359 break;
1360 case '\'': /* Use a mark. */
1361 *addr_found = 1;
1362 if (cmdlen == 1) {
1363 msgq(sp, M_ERR, "No mark name supplied.");
1364 return (1);
1366 if ((mp = mark_get(sp, ep, cmd[1])) == NULL)
1367 return (1);
1368 *cur = *mp;
1369 cmd += 2;
1370 cmdlen -= 2;
1371 break;
1372 case '\\': /* Search: forward/backward. */
1374 * !!!
1375 * I can't find any difference between // and \/ or
1376 * between ?? and \?. Mark Horton doesn't remember
1377 * there being any difference. C'est la vie.
1379 if (cmdlen < 2 || cmd[1] != '/' && cmd[1] != '?') {
1380 msgq(sp, M_ERR, "\\ not followed by / or ?.");
1381 return (1);
1383 ++cmd;
1384 --cmdlen;
1385 if (cmd[0] == '/')
1386 goto forward;
1387 if (cmd[0] == '?')
1388 goto backward;
1389 /* NOTREACHED */
1390 case '/': /* Search forward. */
1391 forward: *addr_found = 1;
1392 m.lno = sp->lno;
1393 m.cno = sp->cno;
1394 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1395 if (f_search(sp, ep, &m, &m, cmd, &endp, &flags))
1396 return (1);
1397 cur->lno = m.lno;
1398 cur->cno = m.cno;
1399 cmdlen -= (endp - cmd);
1400 cmd = endp;
1401 break;
1402 case '?': /* Search backward. */
1403 backward: *addr_found = 1;
1404 m.lno = sp->lno;
1405 m.cno = sp->cno;
1406 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1407 if (b_search(sp, ep, &m, &m, cmd, &endp, &flags))
1408 return (1);
1409 cur->lno = m.lno;
1410 cur->cno = m.cno;
1411 cmdlen -= (endp - cmd);
1412 cmd = endp;
1413 break;
1414 case '.': /* Current position. */
1415 *addr_found = 1;
1416 cur->cno = sp->cno;
1418 /* If an empty file, then '.' is 0, not 1. */
1419 if (sp->lno == 1) {
1420 if (file_lline(sp, ep, &cur->lno))
1421 return (1);
1422 if (cur->lno != 0)
1423 cur->lno = 1;
1424 } else
1425 cur->lno = sp->lno;
1426 ++cmd;
1427 --cmdlen;
1428 break;
1432 * Evaluate any offset. Offsets are +/- any number, or any number
1433 * of +/- signs, or any combination thereof. If no address found
1434 * yet, offset is relative to ".".
1436 for (total = 0; cmdlen > 0 && (cmd[0] == '-' || cmd[0] == '+');) {
1437 if (!*addr_found) {
1438 cur->lno = sp->lno;
1439 cur->cno = sp->cno;
1440 *addr_found = 1;
1443 if (cmdlen > 1 && isdigit(cmd[1])) {
1444 /* 8-bit XXX */ total += strtol(cmd, &endp, 10);
1445 cmdlen -= (endp - cmd);
1446 cmd = endp;
1447 } else {
1448 total += cmd[0] == '-' ? -1 : 1;
1449 --cmdlen;
1450 ++cmd;
1453 if (total < 0 && -total > cur->lno) {
1454 msgq(sp, M_ERR, "Reference to a line number less than 0.");
1455 return (1);
1457 cur->lno += total;
1459 *cmdp = cmd;
1460 *cmdlenp = cmdlen;
1461 return (0);
1465 * ex_is_abbrev -
1466 * The vi text input routine needs to know if ex thinks this is
1467 * an [un]abbreviate command, so it can turn off abbreviations.
1468 * Usual ranting in the vi/v_ntext:txt_abbrev() routine.
1471 ex_is_abbrev(name, len)
1472 char *name;
1473 size_t len;
1475 EXCMDLIST const *cp;
1477 return ((cp = ex_comm_search(name, len)) != NULL &&
1478 (cp == &cmds[C_ABBR] || cp == &cmds[C_UNABBREVIATE]));
1481 static inline EXCMDLIST const *
1482 ex_comm_search(name, len)
1483 char *name;
1484 size_t len;
1486 EXCMDLIST const *cp;
1488 for (cp = cmds; cp->name != NULL; ++cp) {
1489 if (cp->name[0] > name[0])
1490 return (NULL);
1491 if (cp->name[0] != name[0])
1492 continue;
1493 if (!memcmp(name, cp->name, len))
1494 return (cp);
1496 return (NULL);