add S_EXSILENT flag, for ex batch scripts
[nvi.git] / ex / ex.c
bloba50651f94c80ba54c8c5ce47af25faf77cf69d12
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.65 1993/11/30 10:30:09 bostic Exp $ (Berkeley) $Date: 1993/11/30 10:30:09 $";
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 void ep_comm __P((SCR *, char **, char **, int *, char **, int *));
26 static char *ep_line __P((SCR *, EXF *, char *, MARK *));
27 static char *ep_range __P((SCR *, EXF *, char *, EXCMDARG *));
28 static void ep_re __P((SCR *, char **, char **, int *));
29 static void ep_rw __P((SCR *, char **, char **, int *));
31 #define DEFCOM ".+1"
34 * ex --
35 * Read an ex command and execute it.
37 int
38 ex(sp, ep)
39 SCR *sp;
40 EXF *ep;
42 TEXT *tp;
43 u_int saved_mode;
44 int eval;
45 char defcom[sizeof(DEFCOM)];
47 if (ex_init(sp, ep))
48 return (1);
50 if (sp->s_refresh(sp, ep))
51 return (ex_end(sp));
53 /* If reading from a file, messages should have line info. */
54 if (!F_ISSET(sp->gp, G_ISFROMTTY)) {
55 sp->if_lno = 1;
56 sp->if_name = strdup("input");
58 for (eval = 0;; ++sp->if_lno) {
59 /* Get the next command. */
60 switch (sp->s_get(sp, ep, &sp->tiq, ':', TXT_CR | TXT_PROMPT)) {
61 case INP_OK:
62 break;
63 case INP_EOF:
64 F_SET(sp, S_EXIT_FORCE);
65 goto ret;
66 case INP_ERR:
67 continue;
70 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
71 tp = sp->tiq.cqh_first;
72 if (tp->len == 0) {
73 if (F_ISSET(sp->gp, G_ISFROMTTY)) {
74 (void)fputc('\r', stdout);
75 (void)fflush(stdout);
77 memmove(defcom, DEFCOM, sizeof(DEFCOM));
78 (void)ex_cstring(sp, ep, defcom, sizeof(DEFCOM) - 1);
79 } else {
80 if (F_ISSET(sp->gp, G_ISFROMTTY))
81 (void)fputc('\n', stdout);
82 (void)ex_cstring(sp, ep, tp->lb, tp->len);
84 (void)msg_rpt(sp, 0);
86 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
87 break;
89 if (sp->s_refresh(sp, ep)) {
90 eval = 1;
91 break;
94 ret: if (sp->if_name != NULL) {
95 FREE(sp->if_name, strlen(sp->if_name) + 1);
96 sp->if_name = NULL;
98 return (ex_end(sp) || eval);
102 * ex_cfile --
103 * Execute ex commands from a file.
106 ex_cfile(sp, ep, filename)
107 SCR *sp;
108 EXF *ep;
109 char *filename;
111 struct stat sb;
112 int fd, len, rval;
113 char *bp;
115 bp = NULL;
116 if ((fd = open(filename, O_RDONLY, 0)) < 0 || fstat(fd, &sb))
117 goto err;
120 * XXX
121 * We'd like to test if the file is too big to malloc. Since we don't
122 * know what size or type off_t's or size_t's are, what the largest
123 * unsigned integral type is, or what random insanity the local C
124 * compiler will perpetrate, doing the comparison in a portable way
125 * is flatly impossible. Hope that malloc fails if the file is too
126 * large.
128 if ((bp = malloc((size_t)sb.st_size)) == 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 = 0;
142 sp->if_name = strdup(filename);
143 rval = ex_cstring(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 (but we don't care).
152 if (bp != NULL)
153 FREE(bp, sb.st_size);
154 if (fd >= 0)
155 (void)close(fd);
156 return (rval);
160 * ex_cstring --
161 * Execute EX commands from a string.
164 ex_cstring(sp, ep, cmd, len)
165 SCR *sp;
166 EXF *ep;
167 char *cmd;
168 int len;
170 u_int saved_mode;
171 int ch, arg1_len;
172 char *p, *t, *arg1;
175 * Ex goes through here for each vi :colon command and for each ex
176 * command, however, globally executed commands don't go through
177 * here, instead, they call ex_cmd directly. So, reset all of the
178 * interruptible flags now.
180 F_CLR(sp, S_INTERRUPTED | S_INTERRUPTIBLE);
182 /* This is probably not necessary, but it's worth being safe. */
183 if (len == 0)
184 return (0);
187 * QUOTING NOTE:
189 * Commands may be separated by newline or '|' characters, and may
190 * be escaped by literal next characters. The quote characters are
191 * stripped here since they are no longer useful.
193 * There are seven exceptions to this. The filter versions of read
194 * and write are delimited by newlines (the filter command can contain
195 * shell pipes) ex and edit take ex commands as arguments, and global,
196 * vglobal and substitute take RE's as arguments and want their first
197 * argument be specially delimited, not necessarily by '|' characters.
198 * See ep_comm(), ep_re() and ep_rw() below for the horrifying details.
200 arg1 = NULL;
201 arg1_len = 0;
202 for (p = t = cmd;;) {
203 /* The beginning of a line. */
204 if (p == cmd) {
205 /* Skip leading "\t |\n". */
206 for (; len > 0; ++t, --len) {
207 ch = *t;
208 if (isblank(ch) || ch == '|')
209 continue;
210 if (term_key_val(sp, ch) == K_NL) {
211 ++sp->if_lno;
212 continue;
214 break;
218 * Special case comments, because the upcoming special
219 * cases are looking at the command syntax. A comment
220 * line could match a syntax, leading to all sorts of
221 * strangeness.
223 if (ch == '"') {
224 for (; len > 0; ++t, --len) {
225 if (term_key_val(sp, *t) == K_NL)
226 break;
228 p = cmd;
229 goto cend;
233 * Special case read/write, ex/edit, RE commands. We
234 * have to identify the command, so skip the leading
235 * address. Addresses are complex, so skip forward
236 * until reach the start of the command, i.e. the first
237 * alphabetic character. Copy the command up to then,
238 * just in case it's not an address at all.
240 for (; len > 0; ++p, ++t, --len) {
241 ch = *p = *t;
242 if (isalpha(ch) || term_key_val(sp, ch) == K_NL)
243 break;
245 if (len > 0 &&
246 strchr("egrvws", t[0] == ':' ? t[1] : t[0]))
247 switch (t[0] == ':' ? t[1] : t[0]) {
248 case 'e':
249 ep_comm(sp,
250 &p, &t, &len, &arg1, &arg1_len);
251 break;
252 case 'r':
253 case 'w':
254 ep_rw(sp, &p, &t, &len);
255 break;
256 case 'g':
257 case 'v':
258 case 's':
259 ep_re(sp, &p, &t, &len);
260 break;
262 if (len == 0)
263 goto cend;
266 ch = *t++; /* Get the next character. */
267 --len; /* Characters remaining. */
270 * Historically, vi permitted ^V's to escape <newline>'s in
271 * the .exrc file. It was almost certainly a bug, but that's
272 * what bug-for-bug compatibility means, Grasshopper. Also,
273 * escape command separators.
275 if (term_key_val(sp, ch) == K_VLNEXT && len > 0 &&
276 (t[0] == '|' || term_key_val(sp, t[0]) == K_NL)) {
277 --len;
278 *p++ = *t++;
279 if (term_key_val(sp, t[0]) == K_NL)
280 ++sp->if_lno;
281 continue;
284 /* Increment line counter. */
285 if (term_key_val(sp, ch) == K_NL)
286 ++sp->if_lno;
289 * If the end of the string, or a command separator, run
290 * the command.
292 if (len == 0 || ch == '|' || term_key_val(sp, ch) == K_NL) {
294 * If we got here because we ran out of line, not
295 * because we ran into a separator, put the last
296 * character into the command buffer.
298 if (len == 0 && ch != '|' &&
299 term_key_val(sp, ch) != K_NL)
300 *p++ = ch;
303 * If we actually got a command, run it. If it
304 * errors or the modes change, we're outta here.
306 cend: if (p > cmd) {
307 saved_mode =
308 F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
309 *p = '\0';
310 if (ex_cmd(sp, ep, cmd, arg1_len)) {
311 if (len)
312 msgq(sp, M_ERR,
313 "Ex command failed: remaining command input discarded.");
314 term_map_flush(sp, "Ex command failed");
315 return (1);
317 p = cmd;
318 if (saved_mode !=
319 F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
320 break;
322 if (len == 0)
323 return (0);
324 } else
325 *p++ = ch;
328 * Only here if the mode of the underlying file changed, the user
329 * switched files or is exiting. There are two things that we may
330 * have to save. First, any "+cmd" field that ep_comm() set up will
331 * have to be saved for later. Also, there may be part of the
332 * current ex command which we haven't executed:
334 * :edit +25 file.c|s/abc/ABC/|1
336 * for example.
338 * The historic vi just hung, of course; we handle by pushing the
339 * keys onto the SCR's tty buffer. If we're switching modes to
340 * vi, since the commands are intended as ex commands, add the extra
341 * characters to make it work.
343 * For the fun of it, if you want to see if a vi clone got the ex
344 * argument parsing right, try:
346 * echo 'foo|bar' > file1; echo 'foo/bar' > file2;
347 * vi
348 * :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq
350 if (arg1 == NULL && len == 0)
351 return (0);
352 if (IN_VI_MODE(sp) && term_push(sp, "\n", 1, 0, 0))
353 goto err;
354 if (len != 0)
355 if (term_push(sp, t, len, 0, 0))
356 goto err;
357 if (arg1 != NULL) {
358 if (IN_VI_MODE(sp) && len != 0 &&
359 term_push(sp, "|", 1, 0, 0))
360 goto err;
361 if (term_push(sp, arg1, arg1_len, 0, 0))
362 goto err;
364 if (IN_VI_MODE(sp) && term_push(sp, ":", 1, 0, 0))
365 err: term_map_flush(sp, "Error");
366 return (0);
370 * ex_cmd --
371 * Parse and execute an ex command.
374 ex_cmd(sp, ep, exc, arg1_len)
375 SCR *sp;
376 EXF *ep;
377 char *exc;
378 int arg1_len;
380 CHAR_T esc;
381 EX_PRIVATE *exp;
382 EXCMDARG cmd;
383 EXCMDLIST const *cp;
384 MARK cur;
385 recno_t lcount, lno, num;
386 long flagoff;
387 u_int saved_mode;
388 int ch, cmdlen, flags, uselastcmd;
389 char *p, *t, *endp;
391 #if defined(DEBUG) && 0
392 TRACE(sp, "ex: {%s}\n", exc);
393 #endif
395 * !!!
396 * Permit extra colons at the start of the line. Historically,
397 * ex/vi allowed a single extra one. It's simpler not to count.
398 * The stripping is done here because, historically, any command
399 * could have preceding colons, e.g. ":g/pattern/:p" worked.
401 for (; *exc == ':'; ++exc);
403 /* Ignore command lines that start with a double-quote. */
404 if (*exc == '"')
405 return (0);
407 /* Skip whitespace. */
408 for (; isblank(*exc); ++exc);
410 /* Initialize the argument structure. */
411 memset(&cmd, 0, sizeof(EXCMDARG));
412 exp = EXP(sp);
413 exp->ex_argv[0] = "";
414 exp->ex_argv[1] = NULL;
415 cmd.argc = 0;
416 cmd.argv = exp->ex_argv;
419 * Parse line specifiers if the command uses addresses.
420 * New command line position is returned, or NULL on error.
422 if ((exc = ep_range(sp, ep, exc, &cmd)) == NULL)
423 return (1);
425 /* Skip whitespace. */
426 for (; isblank(*exc); ++exc);
429 * If no command, ex does the last specified of p, l, or #, and vi
430 * moves to the line. Otherwise, find out how long the command name
431 * is. There are a few commands that aren't alphabetic, but they
432 * are all single character commands.
434 #define SINGLE_CHAR_COMMANDS "!#&<=>@~"
435 if (*exc) {
436 if (strchr(SINGLE_CHAR_COMMANDS, *exc)) {
437 p = exc;
438 exc++;
439 cmdlen = 1;
440 } else {
441 for (p = exc; isalpha(*exc); ++exc);
442 cmdlen = exc - p;
443 if (cmdlen == 0) {
444 msgq(sp, M_ERR, "Unknown command name.");
445 return (1);
448 for (cp = cmds; cp->name && memcmp(p, cp->name, cmdlen); ++cp);
451 * !!!
452 * Historic vi permitted the mark to immediately follow the 'k'
453 * in the 'k' command. Make it work.
455 * Use of msgq below is safe, command names are all alphabetics.
457 if (cp->name == NULL)
458 if (p[0] == 'k' && p[1] && !p[2]) {
459 exc = p + 1;
460 cp = &cmds[C_K];
461 } else {
462 msgq(sp, M_ERR,
463 "The %.*s command is unknown.", cmdlen, p);
464 return (1);
466 uselastcmd = 0;
468 /* Some commands are turned off. */
469 if (F_ISSET(cp, E_NOPERM)) {
470 msgq(sp, M_ERR,
471 "The %.*s command is not currently supported.",
472 cmdlen, p);
473 return (1);
476 /* Some commands aren't okay in globals. */
477 if (F_ISSET(sp, S_GLOBAL) && F_ISSET(cp, E_NOGLOBAL)) {
478 msgq(sp, M_ERR,
479 "The %.*s command can't be used as part of a global command.", cmdlen, p);
480 return (1);
484 * Multiple < and > characters; another "special" feature.
485 * NOTE: The string may not be nul terminated in this case.
487 if ((cp == &cmds[C_SHIFTL] && *p == '<') ||
488 (cp == &cmds[C_SHIFTR] && *p == '>')) {
489 exp->ex_argv[0] = p;
490 exp->ex_argv[1] = NULL;
491 cmd.argc = 1;
492 cmd.argv = exp->ex_argv;
493 for (ch = *p, exc = p; *++exc == ch;);
497 * The visual command has a different syntax when called
498 * from ex than when called from a vi colon command. FMH.
500 if (cp == &cmds[C_VISUAL_EX] && IN_VI_MODE(sp))
501 cp = &cmds[C_VISUAL_VI];
502 } else {
503 cp = exp->lastcmd;
504 uselastcmd = 1;
506 LF_INIT(cp->flags);
509 * File state must be checked throughout this code, because it is
510 * called when reading the .exrc file and similar things. There's
511 * this little chicken and egg problem -- if we read the file first,
512 * we won't know how to display it. If we read/set the exrc stuff
513 * first, we can't allow any command that requires file state.
514 * Historic vi generally took the easy way out and dropped core.
516 if (LF_ISSET(E_NORC) && ep == NULL) {
517 msgq(sp, M_ERR,
518 "The %s command requires a file to already have been read in.",
519 cp->name);
520 return (1);
524 * Set the default addresses. It's an error to specify an address for
525 * a command that doesn't take them. If two addresses are specified
526 * for a command that only takes one, lose the first one. Two special
527 * cases here, some commands take 0 or 2 addresses. For most of them
528 * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one
529 * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
531 * Also, if the file is empty, some commands want to use an address of
532 * 0, i.e. the entire file is 0 to 0, and the default first address is
533 * 0. Otherwise, an entire file is 1 to N and the default line is 1.
534 * Note, we also add the E_ZERO flag to the command flags, for the case
535 * where the 0 address is only valid if it's a default address.
537 * Also, set a flag if we set the default addresses. Some commands
538 * (ex: z) care if the user specified an address of if we just used
539 * the current cursor.
541 flagoff = 0;
542 switch (flags & (E_ADDR1|E_ADDR2|E_ADDR2_ALL|E_ADDR2_NONE)) {
543 case E_ADDR1: /* One address: */
544 switch (cmd.addrcnt) {
545 case 0: /* Default cursor/empty file. */
546 cmd.addrcnt = 1;
547 F_SET(&cmd, E_ADDRDEF);
548 if (LF_ISSET(E_ZERODEF)) {
549 if (file_lline(sp, ep, &lno))
550 return (1);
551 if (lno == 0) {
552 cmd.addr1.lno = 0;
553 LF_SET(E_ZERO);
554 } else
555 cmd.addr1.lno = sp->lno;
556 } else
557 cmd.addr1.lno = sp->lno;
558 cmd.addr1.cno = sp->cno;
559 break;
560 case 1:
561 break;
562 case 2: /* Lose the first address. */
563 cmd.addrcnt = 1;
564 cmd.addr1 = cmd.addr2;
566 break;
567 case E_ADDR2_NONE: /* Zero/two addresses: */
568 if (cmd.addrcnt == 0) /* Default to nothing. */
569 break;
570 goto two;
571 case E_ADDR2_ALL: /* Zero/two addresses: */
572 if (cmd.addrcnt == 0) { /* Default entire/empty file. */
573 cmd.addrcnt = 2;
574 F_SET(&cmd, E_ADDRDEF);
575 if (file_lline(sp, ep, &cmd.addr2.lno))
576 return (1);
577 if (LF_ISSET(E_ZERODEF) && cmd.addr2.lno == 0) {
578 cmd.addr1.lno = 0;
579 LF_SET(E_ZERO);
580 } else
581 cmd.addr1.lno = 1;
582 cmd.addr1.cno = cmd.addr2.cno = 0;
583 F_SET(&cmd, E_ADDR2_ALL);
584 break;
586 /* FALLTHROUGH */
587 case E_ADDR2: /* Two addresses: */
588 two: switch (cmd.addrcnt) {
589 case 0: /* Default cursor/empty file. */
590 cmd.addrcnt = 2;
591 F_SET(&cmd, E_ADDRDEF);
592 if (LF_ISSET(E_ZERODEF) && sp->lno == 1) {
593 if (file_lline(sp, ep, &lno))
594 return (1);
595 if (lno == 0) {
596 cmd.addr1.lno = cmd.addr2.lno = 0;
597 LF_SET(E_ZERO);
598 } else
599 cmd.addr1.lno = cmd.addr2.lno = sp->lno;
600 } else
601 cmd.addr1.lno = cmd.addr2.lno = sp->lno;
602 cmd.addr1.cno = cmd.addr2.cno = sp->cno;
603 break;
604 case 1: /* Default to first address. */
605 cmd.addrcnt = 2;
606 cmd.addr2 = cmd.addr1;
607 break;
608 case 2:
609 break;
611 break;
612 default:
613 if (cmd.addrcnt) /* Error. */
614 goto usage;
618 * YASC. The "set tags" command historically used a backslash, not
619 * the user's literal next character, to escape whitespace. Handle
620 * it here instead of complicating the argv_exp3() code. Note, this
621 * isn't a particularly complex trap, and if backslashes were legal
622 * in set commands, this would have to be much more complicated.
624 if (cp == &cmds[C_SET]) {
625 (void)term_key_ch(sp, K_VLNEXT, &esc);
626 for (p = exc; (ch = *p) != '\0'; ++p)
627 if (ch == '\\')
628 *p = esc;
631 for (lcount = 0, p = cp->syntax; *p != '\0'; ++p) {
633 * The write command is sensitive to leading whitespace,
634 * i.e. "write !" is different from "write!". If not write,
635 * skip leading whitespace.
637 if (cp != &cmds[C_WRITE])
638 for (; isblank(*exc); ++exc);
641 * When reach the end of the command, quit, unless it's
642 * a command that does its own parsing, in which case we
643 * want to build a reasonable argv for it.
645 if (*p != 's' && *p != 'S' && *exc == '\0')
646 break;
648 switch (*p) {
649 case '!': /* ! */
650 if (*exc == '!') {
651 ++exc;
652 F_SET(&cmd, E_FORCE);
654 break;
655 case '+': /* +cmd */
656 if (*exc != '+')
657 break;
658 exc += arg1_len + 1;
659 if (*exc)
660 *exc++ = '\0';
661 break;
662 case '1': /* +, -, #, l, p */
664 * !!!
665 * Historically, some flags were ignored depending
666 * on where they occurred in the command line. For
667 * example, in the command, ":3+++p--#", historic vi
668 * acted on the '#' flag, but ignored the '-' flags.
669 * It's unambiguous what the flags mean, so we just
670 * handle them regardless of the stupidity of their
671 * location.
673 for (;; ++exc)
674 switch (*exc) {
675 case '+':
676 ++flagoff;
677 break;
678 case '-':
679 --flagoff;
680 break;
681 case '#':
682 F_SET(&cmd, E_F_HASH);
683 break;
684 case 'l':
685 F_SET(&cmd, E_F_LIST);
686 break;
687 case 'p':
688 F_SET(&cmd, E_F_PRINT);
689 break;
690 default:
691 goto end1;
693 end1: break;
694 case '2': /* -, ., +, ^ */
695 case '3': /* -, ., +, ^, = */
696 for (;; ++exc)
697 switch (*exc) {
698 case '-':
699 F_SET(&cmd, E_F_DASH);
700 break;
701 case '.':
702 F_SET(&cmd, E_F_DOT);
703 break;
704 case '+':
705 F_SET(&cmd, E_F_PLUS);
706 break;
707 case '^':
708 F_SET(&cmd, E_F_CARAT);
709 break;
710 case '=':
711 if (*p == '3') {
712 F_SET(&cmd, E_F_EQUAL);
713 break;
715 /* FALLTHROUGH */
716 default:
717 goto end2;
719 end2: break;
720 case 'b': /* buffer */
721 cmd.buffer = *exc++;
722 F_SET(&cmd, E_BUFFER);
723 break;
724 case 'C': /* count */
725 case 'n':
726 case 'c': /* count (address) */
727 if (!isdigit(*exc) &&
728 (*p != 'n' || (*exc != '+' && *exc != '-')))
729 break;
730 lcount = strtol(exc, &endp, 10);
731 if (lcount == 0) {
732 msgq(sp, M_ERR,
733 "Count may not be zero.");
734 return (1);
736 exc = endp;
738 * Count as address offsets occur in commands taking
739 * two addresses. Historic vi practice was to use
740 * the count as an offset from the *second* address.
742 * Set the count flag; some underlying commands (see
743 * join) do different things with counts than with
744 * line addresses.
746 if (*p == 'C' || *p == 'n')
747 cmd.count = lcount;
748 else {
749 cmd.addr1 = cmd.addr2;
750 cmd.addr2.lno = cmd.addr1.lno + lcount - 1;
752 F_SET(&cmd, E_COUNT);
753 break;
754 case 'f': /* file */
755 if (argv_exp2(sp, ep, &cmd, exc, cp == &cmds[C_BANG]))
756 return (1);
757 goto countchk;
758 case 'l': /* line */
759 endp = ep_line(sp, ep, exc, &cur);
760 if (endp == NULL || exc == endp) {
761 msgq(sp, M_ERR,
762 "%s: bad line specification", exc);
763 return (1);
764 } else {
765 cmd.lineno = cur.lno;
766 exc = endp;
768 break;
769 case 'S': /* string, file exp. */
770 if (argv_exp1(sp, ep, &cmd, exc, cp == &cmds[C_BANG]))
771 return (1);
772 goto addr2;
773 case 's': /* string */
774 exp->ex_argv[0] = exc;
775 exp->ex_argv[1] = NULL;
776 cmd.argc = 1;
777 cmd.argv = exp->ex_argv;
778 goto addr2;
779 case 'W': /* word string */
781 * QUOTING NOTE:
783 * Literal next characters escape the following
784 * character. The quote characters are stripped
785 * here since they are no longer useful.
787 * Word.
789 for (p = t = exc; (ch = *p) != '\0'; *t++ = ch, ++p)
790 if (term_key_val(sp, ch) == K_VLNEXT &&
791 p[1] != '\0')
792 ch = *++p;
793 else if (isblank(ch))
794 break;
795 if (*p == '\0')
796 goto usage;
797 exp->ex_argv[0] = exc;
799 /* Delete leading whitespace. */
800 for (*t++ = '\0'; (ch = *++p) != '\0' && isblank(ch););
802 /* String. */
803 exp->ex_argv[1] = p;
804 for (t = p; (ch = *p++) != '\0'; *t++ = ch)
805 if (term_key_val(sp, ch) == K_VLNEXT &&
806 p[0] != '\0')
807 ch = *p++;
808 *t = '\0';
809 exp->ex_argv[2] = NULL;
810 cmd.argc = 2;
811 cmd.argv = exp->ex_argv;
812 goto addr2;
813 case 'w': /* word */
814 if (argv_exp3(sp, ep, &cmd, exc))
815 return (1);
816 countchk: if (*++p != 'N') { /* N */
818 * If a number is specified, must either be
819 * 0 or that number, if optional, and that
820 * number, if required.
822 num = *p - '0';
823 if ((*++p != 'o' || cmd.argc != 0) &&
824 cmd.argc != num)
825 goto usage;
827 goto addr2;
828 default:
829 msgq(sp, M_ERR,
830 "Internal syntax table error (%s).", cp->name);
835 * Shouldn't be anything left, and no more required fields.
836 * That means neither 'l' or 'r' in the syntax.
838 for (; *exc && isblank(*exc); ++exc);
839 if (*exc || strpbrk(p, "lr")) {
840 usage: msgq(sp, M_ERR, "Usage: %s.", cp->usage);
841 return (1);
844 /* Verify that the addresses are legal. */
845 addr2: switch (cmd.addrcnt) {
846 case 2:
847 if (file_lline(sp, ep, &lcount))
848 return (1);
850 * Historic ex/vi permitted commands with counts to go past
851 * EOF. So, for example, if the file only had 5 lines, the
852 * ex command "1,6>" would fail, but the command ">300"
853 * would succeed. Since we don't want to have to make all
854 * of the underlying commands handle random line numbers,
855 * fix it here.
857 if (cmd.addr2.lno > lcount)
858 if (F_ISSET(&cmd, E_COUNT))
859 cmd.addr2.lno = lcount;
860 else {
861 if (lcount == 0)
862 msgq(sp, M_ERR, "The file is empty.");
863 else
864 msgq(sp, M_ERR,
865 "Only %lu line%s in the file",
866 lcount, lcount > 1 ? "s" : "");
867 return (1);
869 /* FALLTHROUGH */
870 case 1:
871 num = cmd.addr1.lno;
873 * If it's a "default vi command", zero is okay. Historic
874 * vi allowed this, note, it's also the hack that allows
875 * "vi + nonexistent_file" to work.
877 if (num == 0 && (!IN_VI_MODE(sp) || uselastcmd != 1) &&
878 !LF_ISSET(E_ZERO)) {
879 msgq(sp, M_ERR,
880 "The %s command doesn't permit an address of 0.",
881 cp->name);
882 return (1);
884 if (file_lline(sp, ep, &lcount))
885 return (1);
886 if (num > lcount) {
887 if (lcount == 0)
888 msgq(sp, M_ERR, "The file is empty.");
889 else
890 msgq(sp, M_ERR, "Only %lu line%s in the file",
891 lcount, lcount > 1 ? "s" : "");
892 return (1);
894 break;
897 /* If doing a default command, vi just moves to the line. */
898 if (IN_VI_MODE(sp) && uselastcmd) {
899 switch (cmd.addrcnt) {
900 case 2:
901 sp->lno = cmd.addr2.lno ? cmd.addr2.lno : 1;
902 sp->cno = cmd.addr2.cno;
903 break;
904 case 1:
905 sp->lno = cmd.addr1.lno ? cmd.addr1.lno : 1;
906 sp->cno = cmd.addr1.cno;
907 break;
909 return (0);
912 /* Reset "last" command. */
913 if (LF_ISSET(E_SETLAST))
914 exp->lastcmd = cp;
916 cmd.cmd = cp;
917 #if defined(DEBUG) && 0
919 int __cnt;
921 TRACE(sp, "ex_cmd: %s", cmd.cmd->name);
922 if (cmd.addrcnt > 0) {
923 TRACE(sp, "\taddr1 %d", cmd.addr1.lno);
924 if (cmd.addrcnt > 1)
925 TRACE(sp, " addr2: %d", cmd.addr2.lno);
926 TRACE(sp, "\n");
928 if (cmd.lineno)
929 TRACE(sp, "\tlineno %d", cmd.lineno);
930 if (cmd.flags)
931 TRACE(sp, "\tflags %0x", cmd.flags);
932 if (F_ISSET(&cmd, E_BUFFER))
933 TRACE(sp, "\tbuffer %c", cmd.buffer);
934 TRACE(sp, "\n");
935 if (cmd.argc) {
936 for (__cnt = 0; __cnt < cmd.argc; ++__cnt)
937 TRACE(sp, "\targ %d: {%s}", __cnt, cmd.argv[__cnt]);
938 TRACE(sp, "\n");
941 #endif
942 /* Clear autoprint. */
943 F_CLR(sp, S_AUTOPRINT);
946 * If file state and not doing a global command, log the start of
947 * an action.
949 if (ep != NULL && !F_ISSET(sp, S_GLOBAL))
950 (void)log_cursor(sp, ep);
952 /* Save the current mode. */
953 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
955 /* Increment the command count if not called from vi. */
956 if (!IN_VI_MODE(sp))
957 ++sp->ccnt;
959 /* Do the command. */
960 if ((cp->fn)(sp, ep, &cmd))
961 return (1);
963 #ifdef DEBUG
964 /* Make sure no function left the temporary space locked. */
965 if (F_ISSET(sp->gp, G_TMP_INUSE)) {
966 msgq(sp, M_ERR, "Error: ex: temporary buffer not released.");
967 return (1);
969 #endif
971 /* If the world changed, we're done. */
972 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
973 return (0);
975 /* If just starting up, or not in ex mode, we're done. */
976 if (ep == NULL || !IN_EX_MODE(sp))
977 return (0);
980 * The print commands have already handled the `print' flags.
981 * If so, clear them. Don't return, autoprint may still have
982 * stuff to print out.
984 if (LF_ISSET(E_F_PRCLEAR))
985 F_CLR(&cmd, E_F_HASH | E_F_LIST | E_F_PRINT);
988 * If the command was successful, and there was an explicit flag to
989 * display the new cursor line, or we're in ex mode, autoprint is set,
990 * and a change was made, display the line.
992 if (flagoff) {
993 if (flagoff < 0) {
994 if (sp->lno < -flagoff) {
995 msgq(sp, M_ERR, "Flag offset before line 1.");
996 return (1);
998 } else {
999 if (file_lline(sp, ep, &lno))
1000 return (1);
1001 if (sp->lno + flagoff > lno) {
1002 msgq(sp, M_ERR,
1003 "Flag offset past end-of-file.");
1004 return (1);
1007 sp->lno += flagoff;
1010 if (F_ISSET(sp, S_AUTOPRINT) && O_ISSET(sp, O_AUTOPRINT))
1011 LF_INIT(E_F_PRINT);
1012 else
1013 LF_INIT(F_ISSET(&cmd, E_F_HASH | E_F_LIST | E_F_PRINT));
1015 memset(&cmd, 0, sizeof(EXCMDARG));
1016 cmd.addrcnt = 2;
1017 cmd.addr1.lno = cmd.addr2.lno = sp->lno;
1018 cmd.addr1.cno = cmd.addr2.cno = sp->cno;
1019 if (flags) {
1020 switch (flags) {
1021 case E_F_HASH:
1022 cmd.cmd = &cmds[C_HASH];
1023 ex_number(sp, ep, &cmd);
1024 break;
1025 case E_F_LIST:
1026 cmd.cmd = &cmds[C_LIST];
1027 ex_list(sp, ep, &cmd);
1028 break;
1029 case E_F_PRINT:
1030 cmd.cmd = &cmds[C_PRINT];
1031 ex_pr(sp, ep, &cmd);
1032 break;
1035 return (0);
1039 * ep_comm, ep_re, ep_rw --
1041 * Historically, '|' characters in the first argument of the ex, edit,
1042 * global, vglobal and substitute commands did not separate commands.
1043 * And, in the filter cases for read and write, they did not delimit
1044 * the command at all.
1046 * For example, the following commands were legal:
1048 * :edit +25|s/abc/ABC/ file.c
1049 * :substitute s/|/PIPE/
1050 * :read !spell % | columnate
1052 * It's not quite as simple as it looks, however. The command:
1054 * :substitute s/a/b/|s/c/d|set
1056 * was also legal, i.e. the historic ex parser (and I use the word loosely,
1057 * since "parser" implies some regularity of syntax) delimited the RE's
1058 * based on its delimiter and not anything so vulgar as a command syntax.
1060 * The ep_comm(), ep_re(), and ep_rw routines make this work. They're passed
1061 * the state from ex_cstring(), and, if it's a special case, they parse the
1062 * first (or entire) argument and return the new state. For the +cmd field,
1063 * since we don't want to parse the line more than once, a pointer to, and the
1064 * length of, the first argument is returned to ex_cstring(), which passes it
1065 * to ex_cmd(). Barf-O-Rama.
1067 static void
1068 ep_comm(sp, pp, tp, lenp, arg1p, arg1_lenp)
1069 SCR *sp;
1070 char **pp, **tp, **arg1p;
1071 int *lenp, *arg1_lenp;
1073 char *cp, *p, *t;
1074 int ch, cnt, len;
1076 /* Copy the state to local variables. */
1077 p = *pp;
1078 cp = t = *tp;
1079 len = *lenp;
1082 * Move to the next non-lower-case, alphabetic character. We can
1083 * do this fairly brutally because we know that the command names
1084 * are all lower-case alphabetics, and there has to be a '+' to
1085 * start the arguments. If there isn't one, we're done.
1087 if (*t == ':') {
1088 ++cp;
1089 *p++ = *t++;
1090 --len;
1092 for (; len && islower(*p = *t); ++p, ++t, --len);
1093 if (len == 0)
1094 goto ret;
1097 * Make sure it's the ex or edit command. Note, 'e' has
1098 * to map to the edit command or the strncmp's aren't right.
1100 cnt = t - cp;
1101 if (strncmp(cp, "ex", cnt) && strncmp(cp, "edit", cnt))
1102 goto ret;
1105 * Move to the '+'. We don't check syntax here, if it's not
1106 * there, we're done.
1108 while (len--) {
1109 ch = *++p = *++t;
1110 if (!isblank(ch))
1111 break;
1113 if (len == 0 || *p != '+')
1114 goto ret;
1117 * QUOTING NOTE:
1119 * The historic implementation of this "feature" ignored any escape
1120 * characters so there was no way to put a space or newline into the
1121 * +cmd field. We do a simplistic job of handling it by moving to
1122 * the first whitespace character that isn't escaped by a literal next
1123 * character. The literal next quote characters are stripped here
1124 * since they are no longer useful.
1126 * Move to the first non-escaped space.
1128 for (cp = p; len;) {
1129 ch = *++p = *++t;
1130 --len;
1131 if (term_key_val(sp, ch) == K_VLNEXT && len > 0) {
1132 *p = *++t;
1133 if (--len == 0)
1134 break;
1135 } else if (isblank(ch))
1136 break;
1139 /* Return information about the first argument. */
1140 *arg1p = cp + 1;
1141 *arg1_lenp = (p - cp) - 1;
1143 /* Restore the state. */
1144 ret: *pp = p;
1145 *tp = t;
1146 *lenp = len;
1149 static void
1150 ep_re(sp, pp, tp, lenp)
1151 SCR *sp;
1152 char **pp, **tp;
1153 int *lenp;
1155 char *cp, *p, *t;
1156 int ch, cnt, delim, len;
1158 /* Copy the state to local variables. */
1159 p = *pp;
1160 cp = t = *tp;
1161 len = *lenp;
1164 * Move to the next non-lower-case, alphabetic character. We can
1165 * do this fairly brutally because we know that the command names
1166 * are all lower-case alphabetics, and there has to be a delimiter
1167 * to start the arguments. If there isn't one, we're done.
1169 if (*t == ':') {
1170 ++cp;
1171 *p++ = *t++;
1172 --len;
1174 for (; len; ++p, ++t, --len) {
1175 ch = *p = *t;
1176 if (!islower(ch))
1177 break;
1179 if (len == 0)
1180 goto ret;
1183 * Make sure it's the substitute, global or vglobal command.
1184 * Note, 's', 'g and 'v' have to map to these commands or the
1185 * strncmp's aren't right.
1187 cnt = t - cp;
1188 if (strncmp(cp, "substitute", cnt) &&
1189 strncmp(cp, "global", cnt) && strncmp(cp, "vglobal", cnt))
1190 goto ret;
1193 * Move to the delimiter. (The first character; if it's an illegal
1194 * one, the RE code will catch it.)
1196 if (isblank(ch))
1197 while (len--) {
1198 ch = *++p = *++t;
1199 if (!isblank(ch))
1200 break;
1202 delim = ch;
1203 if (len == 0)
1204 goto ret;
1207 * QUOTING NOTE:
1209 * Backslashes quote delimiter characters for regular expressions.
1210 * The backslashes are left here since they'll be needed by the RE
1211 * code.
1213 * Move to the third (non-escaped) delimiter.
1215 for (cnt = 2; len && cnt;) {
1216 ch = *++p = *++t;
1217 --len;
1218 if (ch == '\\' && len > 0) {
1219 *++p = *++t;
1220 if (--len == 0)
1221 break;
1222 } else if (ch == delim)
1223 --cnt;
1226 /* Move past the delimiter if it's possible. */
1227 if (len > 0) {
1228 ++t;
1229 ++p;
1230 --len;
1233 /* Restore the state. */
1234 ret: *pp = p;
1235 *tp = t;
1236 *lenp = len;
1239 static void
1240 ep_rw(sp, pp, tp, lenp)
1241 SCR *sp;
1242 char **pp, **tp;
1243 int *lenp;
1245 char *cp, *p, *t;
1246 int ch, cnt, len;
1248 /* Copy the state to local variables. */
1249 p = *pp;
1250 cp = t = *tp;
1251 len = *lenp;
1254 * Move to the next non-lower-case, alphabetic character. We can
1255 * do this fairly brutally because we know that the command names
1256 * are all lower-case alphabetics, and there has to be a delimiter
1257 * to start the arguments. If there isn't one, we're done.
1259 if (*t == ':') {
1260 ++cp;
1261 *p++ = *t++;
1262 --len;
1264 for (; len; ++p, ++t, --len) {
1265 ch = *p = *t;
1266 if (!islower(ch))
1267 break;
1269 if (len == 0)
1270 goto ret;
1273 * Make sure it's the read or write command. Note, 'r' and 'w'
1274 * have to map to these commands or the strncmp's aren't right.
1276 cnt = t - cp;
1277 if (strncmp(cp, "read", cnt) && strncmp(cp, "write", cnt))
1278 goto ret;
1281 * Move to the next character. If it's a '!', it's a filter
1282 * command we want to eat it all, otherwise, we're done.
1284 if (isblank(ch))
1285 while (len--) {
1286 ch = *++p = *++t;
1287 if (!isblank(ch))
1288 break;
1290 if (ch != '!')
1291 goto ret;
1293 for (; len; --len)
1294 *++p = *++t;
1296 /* Restore the state. */
1297 ret: *pp = p;
1298 *tp = t;
1299 *lenp = len;
1303 * ep_range --
1304 * Get a line range for ex commands.
1306 static char *
1307 ep_range(sp, ep, cmd, cp)
1308 SCR *sp;
1309 EXF *ep;
1310 char *cmd;
1311 EXCMDARG *cp;
1313 MARK cur, savecursor;
1314 int savecursor_set;
1315 char *endp;
1317 /* Percent character is all lines in the file. */
1318 if (*cmd == '%') {
1319 cp->addr1.lno = 1;
1320 if (file_lline(sp, ep, &cp->addr2.lno))
1321 return (NULL);
1322 /* If an empty file, then the first line is 0, not 1. */
1323 if (cp->addr2.lno == 0)
1324 cp->addr1.lno = 0;
1325 cp->addr1.cno = cp->addr2.cno = 0;
1326 cp->addrcnt = 2;
1327 return (++cmd);
1330 /* Parse comma or semi-colon delimited line specs. */
1331 for (savecursor_set = 0, cp->addrcnt = 0;;)
1332 switch (*cmd) {
1333 case ';': /* Semi-colon delimiter. */
1335 * Comma delimiters delimit; semi-colon delimiters
1336 * change the current address for the 2nd address
1337 * to be the first address. Trailing or multiple
1338 * delimiters are discarded.
1340 if (cp->addrcnt == 0)
1341 goto done;
1342 if (!savecursor_set) {
1343 savecursor.lno = sp->lno;
1344 savecursor.cno = sp->cno;
1345 sp->lno = cp->addr1.lno;
1346 sp->cno = cp->addr1.cno;
1347 savecursor_set = 1;
1349 /* FALLTHROUGH */
1350 case ' ':
1351 case '\t':
1352 case ',': /* Comma delimiter. */
1353 ++cmd;
1354 break;
1355 default:
1356 if ((endp = ep_line(sp, ep, cmd, &cur)) == NULL)
1357 return (NULL);
1358 if (cmd != endp) {
1359 cmd = endp;
1362 * Extra addresses are discarded, starting with
1363 * the first.
1365 switch (cp->addrcnt) {
1366 case 0:
1367 cp->addr1 = cur;
1368 cp->addrcnt = 1;
1369 break;
1370 case 1:
1371 cp->addr2 = cur;
1372 cp->addrcnt = 2;
1373 break;
1374 case 2:
1375 cp->addr1 = cp->addr2;
1376 cp->addr2 = cur;
1377 break;
1379 break;
1381 /* FALLTHROUGH */
1382 case '\0':
1383 goto done;
1387 * XXX
1388 * This is probably not right for treatment of savecursor -- figure
1389 * out what the historical ex did for ";,;,;5p" or similar stupidity.
1391 done: if (savecursor_set) {
1392 sp->lno = savecursor.lno;
1393 sp->cno = savecursor.cno;
1395 if (cp->addrcnt == 2 &&
1396 (cp->addr2.lno < cp->addr1.lno ||
1397 cp->addr2.lno == cp->addr1.lno && cp->addr2.cno < cp->addr1.cno)) {
1398 msgq(sp, M_ERR,
1399 "The second address is smaller than the first.");
1400 return (NULL);
1402 return (cmd);
1406 * Get a single line address specifier.
1408 static char *
1409 ep_line(sp, ep, cmd, cur)
1410 SCR *sp;
1411 EXF *ep;
1412 char *cmd;
1413 MARK *cur;
1415 MARK m, *mp;
1416 long num, total;
1417 u_int flags;
1418 char *endp;
1420 for (;;) {
1421 switch (*cmd) {
1422 case '$': /* Last line. */
1423 if (file_lline(sp, ep, &cur->lno))
1424 return (NULL);
1425 cur->cno = 0;
1426 ++cmd;
1427 break; /* Absolute line number. */
1428 case '0': case '1': case '2': case '3': case '4':
1429 case '5': case '6': case '7': case '8': case '9':
1431 * The way the vi "previous context" mark worked was
1432 * that "non-relative" motions set it. While vi was
1433 * not completely consistent about this, ANY numeric
1434 * address was considered non-relative, and set the
1435 * value.
1437 if (IN_VI_MODE(sp)) {
1438 m.lno = sp->lno;
1439 m.cno = sp->cno;
1440 if (mark_set(sp, ep, ABSMARK1, &m, 1))
1441 return (NULL);
1443 cur->lno = strtol(cmd, &endp, 10);
1444 cur->cno = 0;
1445 cmd = endp;
1446 break;
1447 case '\'': /* Set mark. */
1448 if (cmd[1] == '\0') {
1449 msgq(sp, M_ERR,
1450 "No mark name; use 'a' to 'z'.");
1451 return (NULL);
1453 if ((mp = mark_get(sp, ep, cmd[1])) == NULL)
1454 return (NULL);
1455 *cur = *mp;
1456 cmd += 2;
1457 break;
1458 case '/': /* Search forward. */
1459 m.lno = sp->lno;
1460 m.cno = sp->cno;
1461 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1462 if (f_search(sp, ep, &m, &m, cmd, &endp, &flags))
1463 return (NULL);
1464 cur->lno = m.lno;
1465 cur->cno = m.cno;
1466 cmd = endp;
1467 break;
1468 case '?': /* Search backward. */
1469 m.lno = sp->lno;
1470 m.cno = sp->cno;
1471 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1472 if (b_search(sp, ep, &m, &m, cmd, &endp, &flags))
1473 return (NULL);
1474 cur->lno = m.lno;
1475 cur->cno = m.cno;
1476 cmd = endp;
1477 break;
1478 case '.': /* Current position. */
1479 ++cmd;
1480 /* FALLTHROUGH */
1481 case '+': /* Increment. */
1482 case '-': /* Decrement. */
1483 /* If an empty file, then '.' is 0, not 1. */
1484 if (sp->lno == 1) {
1485 if (file_lline(sp, ep, &cur->lno))
1486 return (NULL);
1487 if (cur->lno != 0)
1488 cur->lno = 1;
1489 } else
1490 cur->lno = sp->lno;
1491 cur->cno = sp->cno;
1492 break;
1493 default:
1494 return (cmd);
1498 * Evaluate any offset. Offsets are +/- any number, or,
1499 * any number of +/- signs, or any combination thereof.
1501 for (total = 0; *cmd == '-' || *cmd == '+'; total += num) {
1502 num = *cmd == '-' ? -1 : 1;
1503 if (isdigit(*++cmd)) {
1504 num *= strtol(cmd, &endp, 10);
1505 cmd = endp;
1508 if (total < 0 && -total > cur->lno) {
1509 msgq(sp, M_ERR,
1510 "Reference to a line number less than 0.");
1511 return (NULL);
1513 cur->lno += total;