end of line terminates as well as alphabets
[nvi.git] / ex / ex.c
blob41347820e0bcfaa66a11f7ad25fec3865287710f
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.57 1993/11/22 18:33:24 bostic Exp $ (Berkeley) $Date: 1993/11/22 18:33:24 $";
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 for (eval = 0;;) {
54 /* Get the next command. */
55 switch (sp->s_get(sp, ep, &sp->tiq, ':', TXT_CR | TXT_PROMPT)) {
56 case INP_OK:
57 break;
58 case INP_EOF:
59 F_SET(sp, S_EXIT_FORCE);
60 goto ret;
61 case INP_ERR:
62 continue;
65 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
66 tp = sp->tiq.cqh_first;
67 if (tp->len == 0) {
68 if (F_ISSET(sp->gp, G_ISFROMTTY)) {
69 (void)fputc('\r', stdout);
70 (void)fflush(stdout);
72 memmove(defcom, DEFCOM, sizeof(DEFCOM));
73 (void)ex_cstring(sp, ep, defcom, sizeof(DEFCOM) - 1);
74 } else {
75 if (F_ISSET(sp->gp, G_ISFROMTTY))
76 (void)fputc('\n', stdout);
77 (void)ex_cstring(sp, ep, tp->lb, tp->len);
79 (void)msg_rpt(sp, 0);
81 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
82 break;
84 if (sp->s_refresh(sp, ep)) {
85 eval = 1;
86 break;
89 ret: return (ex_end(sp) || eval);
93 * ex_cfile --
94 * Execute ex commands from a file.
96 int
97 ex_cfile(sp, ep, filename)
98 SCR *sp;
99 EXF *ep;
100 char *filename;
102 struct stat sb;
103 int fd, len, rval;
104 char *bp;
106 if ((fd = open(filename, O_RDONLY, 0)) < 0)
107 goto e1;
108 if (fstat(fd, &sb))
109 goto e2;
112 * XXX
113 * We'd like to test if the file is too big to malloc. Since we don't
114 * know what size or type off_t's or size_t's are, what the largest
115 * unsigned integral type is, or what random insanity the local C
116 * compiler will perpetrate, doing the comparison in a portable way
117 * is flatly impossible. Hope that malloc fails if the file is too
118 * large.
120 if ((bp = malloc((size_t)sb.st_size)) == NULL)
121 goto e2;
123 len = read(fd, bp, (int)sb.st_size);
124 if (len == -1 || len != sb.st_size) {
125 if (len != sb.st_size)
126 errno = EIO;
127 goto e3;
129 bp[sb.st_size] = '\0';
131 rval = ex_cstring(sp, ep, bp, len);
133 * XXX
134 * THE UNDERLYING EXF MAY HAVE CHANGED (but we don't care).
136 free(bp);
137 (void)close(fd);
138 return (rval);
140 e3: free(bp);
141 e2: (void)close(fd);
142 e1: msgq(sp, M_SYSERR, filename);
143 return (1);
147 * ex_cstring --
148 * Execute EX commands from a string.
151 ex_cstring(sp, ep, cmd, len)
152 SCR *sp;
153 EXF *ep;
154 char *cmd;
155 int len;
157 u_int saved_mode;
158 int ch, arg1_len;
159 char *p, *t, *arg1;
162 * Ex goes through here for each vi :colon command and for each ex
163 * command, however, globally executed commands don't go through
164 * here, instead, they call ex_cmd directly. So, reset all of the
165 * interruptible flags now.
167 F_CLR(sp, S_INTERRUPTED | S_INTERRUPTIBLE);
169 /* This is probably not necessary, but it's worth being safe. */
170 if (len == 0)
171 return (0);
174 * QUOTING NOTE:
176 * Commands may be separated by newline or '|' characters, and may
177 * be escaped by literal next characters. The quote characters are
178 * stripped here since they are no longer useful.
180 * There are seven exceptions to this. The filter versions of read
181 * and write are delimited by newlines (the filter command can contain
182 * shell pipes) ex and edit take ex commands as arguments, and global,
183 * vglobal and substitute take RE's as arguments and want their first
184 * argument be specially delimited, not necessarily by '|' characters.
185 * See ep_comm(), ep_re() and ep_rw() below for details.
187 arg1 = NULL;
188 arg1_len = 0;
189 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
190 for (p = t = cmd;;) {
191 if (p == cmd) {
192 /* Skip leading whitespace, literals, newlines. */
193 for (; len > 0; ++t, --len) {
194 ch = *t;
195 if (isblank(ch) || ch == '|')
196 continue;
197 if (sp->special[ch] == K_CR ||
198 sp->special[ch] == K_NL ||
199 sp->special[ch] == K_VLNEXT)
200 continue;
201 break;
205 * Skip leading address. The command starts with
206 * the first alphabetic character.
208 for (; len > 0; ++p, ++t, --len) {
209 ch = *p = *t;
210 if (isalpha(ch) ||
211 sp->special[ch] == K_CR ||
212 sp->special[ch] == K_NL)
213 break;
216 /* Special case read/write, ex/edit, RE commands. */
217 if (len > 0 &&
218 strchr("egrvws", t[0] == ':' ? t[1] : t[0]))
219 switch (t[0] == ':' ? t[1] : t[0]) {
220 case 'e':
221 ep_comm(sp,
222 &p, &t, &len, &arg1, &arg1_len);
223 break;
224 case 'r':
225 case 'w':
226 ep_rw(sp, &p, &t, &len);
227 break;
228 case 'g':
229 case 'v':
230 case 's':
231 ep_re(sp, &p, &t, &len);
232 break;
234 if (len == 0)
235 goto cend;
238 ch = *t++;
239 --len; /* Characters remaining. */
242 * Historically, vi permitted ^V's to escape <newline>'s in
243 * the .exrc file. It was almost certainly a bug, but that's
244 * what bug-for-bug compatibility means, Grasshopper.
246 if (sp->special[ch] == K_VLNEXT && len > 0 &&
247 (t[0] == '|' || sp->special[t[0]] == K_NL)) {
248 --len;
249 *p++ = *t++;
250 continue;
252 if (len == 0 || ch == '|' || sp->special[ch] == K_NL) {
253 if (len == 0 && ch != '|' && sp->special[ch] != K_NL)
254 *p++ = ch;
255 cend: if (p > cmd) {
256 *p = '\0'; /* XXX: 8BIT */
257 if (ex_cmd(sp, ep, cmd, arg1_len)) {
258 if (len || TERM_MORE(sp->gp->key)) {
259 TERM_FLUSH(sp->gp->key);
260 msgq(sp, M_ERR,
261 "Ex command failed, remaining command input discarded.");
263 return (1);
265 p = cmd;
267 if (saved_mode !=
268 F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
269 break;
270 if (len == 0)
271 return (0);
272 } else
273 *p++ = ch;
276 * Only here if the mode of the underlying file changed, the user
277 * switched files or is exiting. There are two things that we may
278 * have to save. First, any "+cmd" field that ep_comm() set up will
279 * have to be saved for later. Also, there may be part of the
280 * current ex command which we haven't executed:
282 * :edit +25 file.c|s/abc/ABC/|1
284 * for example.
286 * The historic vi just hung, of course; we handle by pushing the
287 * keys onto the SCR's tty buffer. If we're switching modes to
288 * vi, since the commands are intended as ex commands, add the extra
289 * characters to make it work.
291 * For the fun of it, if you want to see if a vi clone got the ex
292 * argument parsing right, try:
294 * echo 'foo|bar' > file1; echo 'foo/bar' > file2;
295 * vi
296 * :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq
298 if (arg1 == NULL && len == 0)
299 return (0);
300 if (IN_VI_MODE(sp) && term_push(sp, sp->gp->tty, "\n", 1))
301 goto err;
302 if (len != 0)
303 if (term_push(sp, sp->gp->tty, t, len))
304 goto err;
305 if (arg1 != NULL) {
306 if (IN_VI_MODE(sp) && len != 0 &&
307 term_push(sp, sp->gp->tty, "|", 1))
308 goto err;
309 if (term_push(sp, sp->gp->tty, arg1, arg1_len))
310 goto err;
312 if (IN_VI_MODE(sp) && term_push(sp, sp->gp->tty, ":", 1)) {
313 err: msgq(sp, M_SYSERR, "remaining command input discarded");
314 TERM_FLUSH(sp->gp->key);
316 return (0);
320 * ex_cmd --
321 * Parse and execute an ex command.
324 ex_cmd(sp, ep, exc, arg1_len)
325 SCR *sp;
326 EXF *ep;
327 char *exc;
328 int arg1_len;
330 EX_PRIVATE *exp;
331 EXCMDARG cmd;
332 EXCMDLIST const *cp;
333 MARK cur;
334 recno_t lcount, lno, num;
335 long flagoff;
336 u_int saved_mode;
337 int ch, cmdlen, esc, flags, uselastcmd;
338 char *p, *t, *endp;
340 #if defined(DEBUG) && 0
341 TRACE(sp, "ex: {%s}\n", exc);
342 #endif
344 * !!!
345 * Permit extra colons at the start of the line. Historically,
346 * ex/vi allowed a single extra one. It's simpler not to count.
347 * The stripping is done here because, historically, any command
348 * could have preceding colons, e.g. ":g/pattern/:p" worked.
350 for (; *exc == ':'; ++exc);
352 /* Ignore command lines that start with a double-quote. */
353 if (*exc == '"')
354 return (0);
356 /* Skip whitespace. */
357 for (; isblank(*exc); ++exc);
359 /* Initialize the argument structure. */
360 memset(&cmd, 0, sizeof(EXCMDARG));
361 exp = EXP(sp);
362 exp->ex_argv[0] = "";
363 exp->ex_argv[1] = NULL;
364 cmd.argc = 0;
365 cmd.argv = exp->ex_argv;
368 * Parse line specifiers if the command uses addresses.
369 * New command line position is returned, or NULL on error.
371 if ((exc = ep_range(sp, ep, exc, &cmd)) == NULL)
372 return (1);
374 /* Skip whitespace. */
375 for (; isblank(*exc); ++exc);
378 * If no command, ex does the last specified of p, l, or #, and vi
379 * moves to the line. Otherwise, find out how long the command name
380 * is. There are a few commands that aren't alphabetic, but they
381 * are all single character commands.
383 #define SINGLE_CHAR_COMMANDS "!#&<=>@~"
384 if (*exc) {
385 if (strchr(SINGLE_CHAR_COMMANDS, *exc)) {
386 p = exc;
387 exc++;
388 cmdlen = 1;
389 } else {
390 for (p = exc; isalpha(*exc); ++exc);
391 cmdlen = exc - p;
392 if (cmdlen == 0) {
393 msgq(sp, M_ERR, "Unknown command name.");
394 return (1);
397 for (cp = cmds; cp->name && memcmp(p, cp->name, cmdlen); ++cp);
400 * !!!
401 * Historic vi permitted the mark to immediately follow the 'k'
402 * in the 'k' command. Make it work.
404 * Use of msgq below is safe, command names are all alphabetics.
406 if (cp->name == NULL)
407 if (p[0] == 'k' && p[1] && !p[2]) {
408 exc = p + 1;
409 cp = &cmds[C_K];
410 } else {
411 msgq(sp, M_ERR,
412 "The %.*s command is unknown.", cmdlen, p);
413 return (1);
415 uselastcmd = 0;
417 /* Some commands are turned off. */
418 if (F_ISSET(cp, E_NOPERM)) {
419 msgq(sp, M_ERR,
420 "The %.*s command is not currently supported.",
421 cmdlen, p);
422 return (1);
425 /* Some commands aren't okay in globals. */
426 if (F_ISSET(sp, S_GLOBAL) && F_ISSET(cp, E_NOGLOBAL)) {
427 msgq(sp, M_ERR,
428 "The %.*s command can't be used as part of a global command.", cmdlen, p);
429 return (1);
433 * Multiple < and > characters; another "special" feature.
434 * NOTE: The string may not be nul terminated in this case.
436 if ((cp == &cmds[C_SHIFTL] && *p == '<') ||
437 (cp == &cmds[C_SHIFTR] && *p == '>')) {
438 exp->ex_argv[0] = p;
439 exp->ex_argv[1] = NULL;
440 cmd.argc = 1;
441 cmd.argv = exp->ex_argv;
442 for (ch = *p, exc = p; *++exc == ch;);
446 * The visual command has a different syntax when called
447 * from ex than when called from a vi colon command. FMH.
449 if (cp == &cmds[C_VISUAL_EX] && IN_VI_MODE(sp))
450 cp = &cmds[C_VISUAL_VI];
451 } else {
452 cp = exp->lastcmd;
453 uselastcmd = 1;
455 LF_INIT(cp->flags);
458 * File state must be checked throughout this code, because it is
459 * called when reading the .exrc file and similar things. There's
460 * this little chicken and egg problem -- if we read the file first,
461 * we won't know how to display it. If we read/set the exrc stuff
462 * first, we can't allow any command that requires file state.
463 * Historic vi generally took the easy way out and dropped core.
465 if (LF_ISSET(E_NORC) && ep == NULL) {
466 msgq(sp, M_ERR,
467 "The %s command requires a file to already have been read in.",
468 cp->name);
469 return (1);
473 * Set the default addresses. It's an error to specify an address for
474 * a command that doesn't take them. If two addresses are specified
475 * for a command that only takes one, lose the first one. Two special
476 * cases here, some commands take 0 or 2 addresses. For most of them
477 * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one
478 * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
480 * Also, if the file is empty, some commands want to use an address of
481 * 0, i.e. the entire file is 0 to 0, and the default first address is
482 * 0. Otherwise, an entire file is 1 to N and the default line is 1.
483 * Note, we also add the E_ZERO flag to the command flags, for the case
484 * where the 0 address is only valid if it's a default address.
486 * Also, set a flag if we set the default addresses. Some commands
487 * (ex: z) care if the user specified an address of if we just used
488 * the current cursor.
490 flagoff = 0;
491 switch (flags & (E_ADDR1|E_ADDR2|E_ADDR2_ALL|E_ADDR2_NONE)) {
492 case E_ADDR1: /* One address: */
493 switch (cmd.addrcnt) {
494 case 0: /* Default cursor/empty file. */
495 cmd.addrcnt = 1;
496 F_SET(&cmd, E_ADDRDEF);
497 if (LF_ISSET(E_ZERODEF)) {
498 if (file_lline(sp, ep, &lno))
499 return (1);
500 if (lno == 0) {
501 cmd.addr1.lno = 0;
502 LF_SET(E_ZERO);
503 } else
504 cmd.addr1.lno = sp->lno;
505 } else
506 cmd.addr1.lno = sp->lno;
507 cmd.addr1.cno = sp->cno;
508 break;
509 case 1:
510 break;
511 case 2: /* Lose the first address. */
512 cmd.addrcnt = 1;
513 cmd.addr1 = cmd.addr2;
515 break;
516 case E_ADDR2_NONE: /* Zero/two addresses: */
517 if (cmd.addrcnt == 0) /* Default to nothing. */
518 break;
519 goto two;
520 case E_ADDR2_ALL: /* Zero/two addresses: */
521 if (cmd.addrcnt == 0) { /* Default entire/empty file. */
522 cmd.addrcnt = 2;
523 F_SET(&cmd, E_ADDRDEF);
524 if (file_lline(sp, ep, &cmd.addr2.lno))
525 return (1);
526 if (LF_ISSET(E_ZERODEF) && cmd.addr2.lno == 0) {
527 cmd.addr1.lno = 0;
528 LF_SET(E_ZERO);
529 } else
530 cmd.addr1.lno = 1;
531 cmd.addr1.cno = cmd.addr2.cno = 0;
532 F_SET(&cmd, E_ADDR2_ALL);
533 break;
535 /* FALLTHROUGH */
536 case E_ADDR2: /* Two addresses: */
537 two: switch (cmd.addrcnt) {
538 case 0: /* Default cursor/empty file. */
539 cmd.addrcnt = 2;
540 F_SET(&cmd, E_ADDRDEF);
541 if (LF_ISSET(E_ZERODEF) && sp->lno == 1) {
542 if (file_lline(sp, ep, &lno))
543 return (1);
544 if (lno == 0) {
545 cmd.addr1.lno = cmd.addr2.lno = 0;
546 LF_SET(E_ZERO);
547 } else
548 cmd.addr1.lno = cmd.addr2.lno = sp->lno;
549 } else
550 cmd.addr1.lno = cmd.addr2.lno = sp->lno;
551 cmd.addr1.cno = cmd.addr2.cno = sp->cno;
552 break;
553 case 1: /* Default to first address. */
554 cmd.addrcnt = 2;
555 cmd.addr2 = cmd.addr1;
556 break;
557 case 2:
558 break;
560 break;
561 default:
562 if (cmd.addrcnt) /* Error. */
563 goto usage;
567 * YASC. The "set tags" command historically used a backslash, not
568 * the user's literal next character, to escape whitespace. Handle
569 * it here instead of complicating the argv_exp3() code. Note, this
570 * isn't a particularly complex trap, and if backslashes were legal
571 * in set commands, this would have to be much more complicated.
573 if (cp == &cmds[C_SET]) {
574 esc = sp->gp->original_termios.c_cc[VLNEXT];
575 for (p = exc; (ch = *p) != '\0'; ++p)
576 if (ch == '\\')
577 *p = esc;
580 for (lcount = 0, p = cp->syntax; *p != '\0'; ++p) {
582 * The write command is sensitive to leading whitespace,
583 * i.e. "write !" is different from "write!". If not write,
584 * skip leading whitespace.
586 if (cp != &cmds[C_WRITE])
587 for (; isblank(*exc); ++exc);
590 * When reach the end of the command, quit, unless it's
591 * a command that does its own parsing, in which case we
592 * want to build a reasonable argv for it.
594 if (*p != 's' && *p != 'S' && *exc == '\0')
595 break;
597 switch (*p) {
598 case '!': /* ! */
599 if (*exc == '!') {
600 ++exc;
601 F_SET(&cmd, E_FORCE);
603 break;
604 case '+': /* +cmd */
605 if (*exc != '+')
606 break;
607 exc += arg1_len + 1;
608 if (*exc)
609 *exc++ = '\0';
610 break;
611 case '1': /* +, -, #, l, p */
613 * !!!
614 * Historically, some flags were ignored depending
615 * on where they occurred in the command line. For
616 * example, in the command, ":3+++p--#", historic vi
617 * acted on the '#' flag, but ignored the '-' flags.
618 * It's unambiguous what the flags mean, so we just
619 * handle them regardless of the stupidity of their
620 * location.
622 for (;; ++exc)
623 switch (*exc) {
624 case '+':
625 ++flagoff;
626 break;
627 case '-':
628 --flagoff;
629 break;
630 case '#':
631 F_SET(&cmd, E_F_HASH);
632 break;
633 case 'l':
634 F_SET(&cmd, E_F_LIST);
635 break;
636 case 'p':
637 F_SET(&cmd, E_F_PRINT);
638 break;
639 default:
640 goto end1;
642 end1: break;
643 case '2': /* -, ., +, ^ */
644 case '3': /* -, ., +, ^, = */
645 for (;; ++exc)
646 switch (*exc) {
647 case '-':
648 F_SET(&cmd, E_F_DASH);
649 break;
650 case '.':
651 F_SET(&cmd, E_F_DOT);
652 break;
653 case '+':
654 F_SET(&cmd, E_F_PLUS);
655 break;
656 case '^':
657 F_SET(&cmd, E_F_CARAT);
658 break;
659 case '=':
660 if (*p == '3') {
661 F_SET(&cmd, E_F_EQUAL);
662 break;
664 /* FALLTHROUGH */
665 default:
666 goto end2;
668 end2: break;
669 case 'b': /* buffer */
670 cmd.buffer = *exc++;
671 F_SET(&cmd, E_BUFFER);
672 break;
673 case 'C': /* count */
674 case 'n':
675 case 'c': /* count (address) */
676 if (!isdigit(*exc) &&
677 (*p != 'n' || (*exc != '+' && *exc != '-')))
678 break;
679 lcount = strtol(exc, &endp, 10);
680 if (lcount == 0) {
681 msgq(sp, M_ERR,
682 "Count may not be zero.");
683 return (1);
685 exc = endp;
687 * Count as address offsets occur in commands taking
688 * two addresses. Historic vi practice was to use
689 * the count as an offset from the *second* address.
691 * Set the count flag; some underlying commands (see
692 * join) do different things with counts than with
693 * line addresses.
695 if (*p == 'C' || *p == 'n')
696 cmd.count = lcount;
697 else {
698 cmd.addr1 = cmd.addr2;
699 cmd.addr2.lno = cmd.addr1.lno + lcount - 1;
701 F_SET(&cmd, E_COUNT);
702 break;
703 case 'f': /* file */
704 if (argv_exp2(sp, ep, &cmd, exc, cp == &cmds[C_BANG]))
705 return (1);
706 goto countchk;
707 case 'l': /* line */
708 endp = ep_line(sp, ep, exc, &cur);
709 if (endp == NULL || exc == endp) {
710 msgq(sp, M_ERR,
711 "%s: bad line specification", exc);
712 return (1);
713 } else {
714 cmd.lineno = cur.lno;
715 exc = endp;
717 break;
718 case 'S': /* string, file exp. */
719 if (argv_exp1(sp, ep, &cmd, exc, cp == &cmds[C_BANG]))
720 return (1);
721 goto addr2;
722 case 's': /* string */
723 exp->ex_argv[0] = exc;
724 exp->ex_argv[1] = NULL;
725 cmd.argc = 1;
726 cmd.argv = exp->ex_argv;
727 goto addr2;
728 case 'W': /* word string */
730 * QUOTING NOTE:
732 * Literal next characters escape the following
733 * character. The quote characters are stripped
734 * here since they are no longer useful.
736 * Word.
738 for (p = t = exc; (ch = *p) != '\0'; *t++ = ch, ++p)
739 if (sp->special[ch] == K_VLNEXT && p[1] != '\0')
740 ch = *++p;
741 else if (isblank(ch))
742 break;
743 if (*p == '\0')
744 goto usage;
745 exp->ex_argv[0] = exc;
747 /* Delete leading whitespace. */
748 for (*t++ = '\0'; (ch = *++p) != '\0' && isblank(ch););
750 /* String. */
751 exp->ex_argv[1] = p;
752 for (t = p; (ch = *p++) != '\0'; *t++ = ch)
753 if (sp->special[ch] == K_VLNEXT && p[0] != '\0')
754 ch = *p++;
755 *t = '\0';
756 exp->ex_argv[2] = NULL;
757 cmd.argc = 2;
758 cmd.argv = exp->ex_argv;
759 goto addr2;
760 case 'w': /* word */
761 if (argv_exp3(sp, ep, &cmd, exc))
762 return (1);
763 countchk: if (*++p != 'N') { /* N */
765 * If a number is specified, must either be
766 * 0 or that number, if optional, and that
767 * number, if required.
769 num = *p - '0';
770 if ((*++p != 'o' || cmd.argc != 0) &&
771 cmd.argc != num)
772 goto usage;
774 goto addr2;
775 default:
776 msgq(sp, M_ERR,
777 "Internal syntax table error (%s).", cp->name);
782 * Shouldn't be anything left, and no more required fields.
783 * That means neither 'l' or 'r' in the syntax.
785 for (; *exc && isblank(*exc); ++exc);
786 if (*exc || strpbrk(p, "lr")) {
787 usage: msgq(sp, M_ERR, "Usage: %s.", cp->usage);
788 return (1);
791 /* Verify that the addresses are legal. */
792 addr2: switch (cmd.addrcnt) {
793 case 2:
794 if (file_lline(sp, ep, &lcount))
795 return (1);
797 * Historic ex/vi permitted commands with counts to go past
798 * EOF. So, for example, if the file only had 5 lines, the
799 * ex command "1,6>" would fail, but the command ">300"
800 * would succeed. Since we don't want to have to make all
801 * of the underlying commands handle random line numbers,
802 * fix it here.
804 if (cmd.addr2.lno > lcount)
805 if (F_ISSET(&cmd, E_COUNT))
806 cmd.addr2.lno = lcount;
807 else {
808 if (lcount == 0)
809 msgq(sp, M_ERR, "The file is empty.");
810 else
811 msgq(sp, M_ERR,
812 "Only %lu line%s in the file",
813 lcount, lcount > 1 ? "s" : "");
814 return (1);
816 /* FALLTHROUGH */
817 case 1:
818 num = cmd.addr1.lno;
820 * If it's a "default vi command", zero is okay. Historic
821 * vi allowed this, note, it's also the hack that allows
822 * "vi + nonexistent_file" to work.
824 if (num == 0 && (!IN_VI_MODE(sp) || uselastcmd != 1) &&
825 !LF_ISSET(E_ZERO)) {
826 msgq(sp, M_ERR,
827 "The %s command doesn't permit an address of 0.",
828 cp->name);
829 return (1);
831 if (file_lline(sp, ep, &lcount))
832 return (1);
833 if (num > lcount) {
834 if (lcount == 0)
835 msgq(sp, M_ERR, "The file is empty.");
836 else
837 msgq(sp, M_ERR, "Only %lu line%s in the file",
838 lcount, lcount > 1 ? "s" : "");
839 return (1);
841 break;
844 /* If doing a default command, vi just moves to the line. */
845 if (IN_VI_MODE(sp) && uselastcmd) {
846 switch (cmd.addrcnt) {
847 case 2:
848 sp->lno = cmd.addr2.lno ? cmd.addr2.lno : 1;
849 sp->cno = cmd.addr2.cno;
850 break;
851 case 1:
852 sp->lno = cmd.addr1.lno ? cmd.addr1.lno : 1;
853 sp->cno = cmd.addr1.cno;
854 break;
856 return (0);
859 /* Reset "last" command. */
860 if (LF_ISSET(E_SETLAST))
861 exp->lastcmd = cp;
863 cmd.cmd = cp;
864 #if defined(DEBUG) && 0
866 int __cnt;
868 TRACE(sp, "ex_cmd: %s", cmd.cmd->name);
869 if (cmd.addrcnt > 0) {
870 TRACE(sp, "\taddr1 %d", cmd.addr1.lno);
871 if (cmd.addrcnt > 1)
872 TRACE(sp, " addr2: %d", cmd.addr2.lno);
873 TRACE(sp, "\n");
875 if (cmd.lineno)
876 TRACE(sp, "\tlineno %d", cmd.lineno);
877 if (cmd.flags)
878 TRACE(sp, "\tflags %0x", cmd.flags);
879 if (F_ISSET(&cmd, E_BUFFER))
880 TRACE(sp, "\tbuffer %c", cmd.buffer);
881 TRACE(sp, "\n");
882 if (cmd.argc) {
883 for (__cnt = 0; __cnt < cmd.argc; ++__cnt)
884 TRACE(sp, "\targ %d: {%s}", __cnt, cmd.argv[__cnt]);
885 TRACE(sp, "\n");
888 #endif
889 /* Clear autoprint. */
890 F_CLR(sp, S_AUTOPRINT);
893 * If file state and not doing a global command, log the start of
894 * an action.
896 if (ep != NULL && !F_ISSET(sp, S_GLOBAL))
897 (void)log_cursor(sp, ep);
899 /* Save the current mode. */
900 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
902 /* Increment the command count if not called from vi. */
903 if (!IN_VI_MODE(sp))
904 ++sp->ccnt;
906 /* Do the command. */
907 if ((cp->fn)(sp, ep, &cmd))
908 return (1);
910 #ifdef DEBUG
911 /* Make sure no function left the temporary space locked. */
912 if (F_ISSET(sp->gp, G_TMP_INUSE)) {
913 msgq(sp, M_ERR, "Error: ex: temporary buffer not released.");
914 return (1);
916 #endif
918 /* If the world changed, we're done. */
919 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
920 return (0);
922 /* If just starting up, or not in ex mode, we're done. */
923 if (ep == NULL || !IN_EX_MODE(sp))
924 return (0);
927 * The print commands have already handled the `print' flags.
928 * If so, clear them. Don't return, autoprint may still have
929 * stuff to print out.
931 if (LF_ISSET(E_F_PRCLEAR))
932 F_CLR(&cmd, E_F_HASH | E_F_LIST | E_F_PRINT);
935 * If the command was successful, and there was an explicit flag to
936 * display the new cursor line, or we're in ex mode, autoprint is set,
937 * and a change was made, display the line.
939 if (flagoff) {
940 if (flagoff < 0) {
941 if (sp->lno < -flagoff) {
942 msgq(sp, M_ERR, "Flag offset before line 1.");
943 return (1);
945 } else {
946 if (file_lline(sp, ep, &lno))
947 return (1);
948 if (sp->lno + flagoff > lno) {
949 msgq(sp, M_ERR,
950 "Flag offset past end-of-file.");
951 return (1);
954 sp->lno += flagoff;
957 if (F_ISSET(sp, S_AUTOPRINT) && O_ISSET(sp, O_AUTOPRINT))
958 LF_INIT(E_F_PRINT);
959 else
960 LF_INIT(F_ISSET(&cmd, E_F_HASH | E_F_LIST | E_F_PRINT));
962 memset(&cmd, 0, sizeof(EXCMDARG));
963 cmd.addrcnt = 2;
964 cmd.addr1.lno = cmd.addr2.lno = sp->lno;
965 cmd.addr1.cno = cmd.addr2.cno = sp->cno;
966 if (flags) {
967 switch (flags) {
968 case E_F_HASH:
969 cmd.cmd = &cmds[C_HASH];
970 ex_number(sp, ep, &cmd);
971 break;
972 case E_F_LIST:
973 cmd.cmd = &cmds[C_LIST];
974 ex_list(sp, ep, &cmd);
975 break;
976 case E_F_PRINT:
977 cmd.cmd = &cmds[C_PRINT];
978 ex_pr(sp, ep, &cmd);
979 break;
982 return (0);
986 * ep_comm, ep_re, ep_rw --
988 * Historically, '|' characters in the first argument of the ex, edit,
989 * global, vglobal and substitute commands did not separate commands.
990 * And, in the filter cases for read and write, they did not delimit
991 * the command at all.
993 * For example, the following commands were legal:
995 * :edit +25|s/abc/ABC/ file.c
996 * :substitute s/|/PIPE/
997 * :read !spell % | columnate
999 * It's not quite as simple as it looks, however. The command:
1001 * :substitute s/a/b/|s/c/d|set
1003 * was also legal, i.e. the historic ex parser (and I use the word loosely,
1004 * since "parser" implies some regularity of syntax) delimited the RE's
1005 * based on its delimiter and not anything so vulgar as a command syntax.
1007 * The ep_comm(), ep_re(), and ep_rw routines make this work. They're passed
1008 * the state from ex_cstring(), and, if it's a special case, they parse the
1009 * first (or entire) argument and return the new state. For the +cmd field,
1010 * since we don't want to parse the line more than once, a pointer to, and the
1011 * length of, the first argument is returned to ex_cstring(), which passes it
1012 * to ex_cmd(). Barf-O-Rama.
1014 static void
1015 ep_comm(sp, pp, tp, lenp, arg1p, arg1_lenp)
1016 SCR *sp;
1017 char **pp, **tp, **arg1p;
1018 int *lenp, *arg1_lenp;
1020 char *cp, *p, *t;
1021 int ch, cnt, len;
1023 /* Copy the state to local variables. */
1024 p = *pp;
1025 cp = t = *tp;
1026 len = *lenp;
1029 * Move to the next non-lower-case, alphabetic character. We can
1030 * do this fairly brutally because we know that the command names
1031 * are all lower-case alphabetics, and there has to be a '+' to
1032 * start the arguments. If there isn't one, we're done.
1034 if (*t == ':') {
1035 ++cp;
1036 *p++ = *t++;
1037 --len;
1039 for (; len && islower(*p = *t); ++p, ++t, --len);
1040 if (len == 0)
1041 goto ret;
1044 * Make sure it's the ex or edit command. Note, 'e' has
1045 * to map to the edit command or the strncmp's aren't right.
1047 cnt = t - cp;
1048 if (strncmp(cp, "ex", cnt) && strncmp(cp, "edit", cnt))
1049 goto ret;
1052 * Move to the '+'. We don't check syntax here, if it's not
1053 * there, we're done.
1055 while (len--) {
1056 ch = *++p = *++t;
1057 if (!isblank(ch))
1058 break;
1060 if (len == 0 || *p != '+')
1061 goto ret;
1064 * QUOTING NOTE:
1066 * The historic implementation of this "feature" ignored any escape
1067 * characters so there was no way to put a space or newline into the
1068 * +cmd field. We do a simplistic job of handling it by moving to
1069 * the first whitespace character that isn't escaped by a literal next
1070 * character. The literal next quote characters are stripped here
1071 * since they are no longer useful.
1073 * Move to the first non-escaped space.
1075 for (cp = p; len;) {
1076 ch = *++p = *++t;
1077 --len;
1078 if (sp->special[ch] == K_VLNEXT && len > 0) {
1079 *p = *++t;
1080 if (--len == 0)
1081 break;
1082 } else if (isblank(ch))
1083 break;
1086 /* Return information about the first argument. */
1087 *arg1p = cp + 1;
1088 *arg1_lenp = (p - cp) - 1;
1090 /* Restore the state. */
1091 ret: *pp = p;
1092 *tp = t;
1093 *lenp = len;
1096 static void
1097 ep_re(sp, pp, tp, lenp)
1098 SCR *sp;
1099 char **pp, **tp;
1100 int *lenp;
1102 char *cp, *p, *t;
1103 int ch, cnt, delim, len;
1105 /* Copy the state to local variables. */
1106 p = *pp;
1107 cp = t = *tp;
1108 len = *lenp;
1111 * Move to the next non-lower-case, alphabetic character. We can
1112 * do this fairly brutally because we know that the command names
1113 * are all lower-case alphabetics, and there has to be a delimiter
1114 * to start the arguments. If there isn't one, we're done.
1116 if (*t == ':') {
1117 ++cp;
1118 *p++ = *t++;
1119 --len;
1121 for (; len; ++p, ++t, --len) {
1122 ch = *p = *t;
1123 if (!islower(ch))
1124 break;
1126 if (len == 0)
1127 goto ret;
1130 * Make sure it's the substitute, global or vglobal command.
1131 * Note, 's', 'g and 'v' have to map to these commands or the
1132 * strncmp's aren't right.
1134 cnt = t - cp;
1135 if (strncmp(cp, "substitute", cnt) &&
1136 strncmp(cp, "global", cnt) && strncmp(cp, "vglobal", cnt))
1137 goto ret;
1140 * Move to the delimiter. (The first character; if it's an illegal
1141 * one, the RE code will catch it.)
1143 if (isblank(ch))
1144 while (len--) {
1145 ch = *++p = *++t;
1146 if (!isblank(ch))
1147 break;
1149 delim = ch;
1150 if (len == 0)
1151 goto ret;
1154 * QUOTING NOTE:
1156 * Backslashes quote delimiter characters for regular expressions.
1157 * The backslashes are left here since they'll be needed by the RE
1158 * code.
1160 * Move to the third (non-escaped) delimiter.
1162 for (cnt = 2; len && cnt;) {
1163 ch = *++p = *++t;
1164 --len;
1165 if (ch == '\\' && len > 0) {
1166 *++p = *++t;
1167 if (--len == 0)
1168 break;
1169 } else if (ch == delim)
1170 --cnt;
1173 /* Move past the delimiter if it's possible. */
1174 if (len > 0) {
1175 ++t;
1176 ++p;
1177 --len;
1180 /* Restore the state. */
1181 ret: *pp = p;
1182 *tp = t;
1183 *lenp = len;
1186 static void
1187 ep_rw(sp, pp, tp, lenp)
1188 SCR *sp;
1189 char **pp, **tp;
1190 int *lenp;
1192 char *cp, *p, *t;
1193 int ch, cnt, len;
1195 /* Copy the state to local variables. */
1196 p = *pp;
1197 cp = t = *tp;
1198 len = *lenp;
1201 * Move to the next non-lower-case, alphabetic character. We can
1202 * do this fairly brutally because we know that the command names
1203 * are all lower-case alphabetics, and there has to be a delimiter
1204 * to start the arguments. If there isn't one, we're done.
1206 if (*t == ':') {
1207 ++cp;
1208 *p++ = *t++;
1209 --len;
1211 for (; len; ++p, ++t, --len) {
1212 ch = *p = *t;
1213 if (!islower(ch))
1214 break;
1216 if (len == 0)
1217 goto ret;
1220 * Make sure it's the read or write command. Note, 'r' and 'w'
1221 * have to map to these commands or the strncmp's aren't right.
1223 cnt = t - cp;
1224 if (strncmp(cp, "read", cnt) && strncmp(cp, "write", cnt))
1225 goto ret;
1228 * Move to the next character. If it's a '!', it's a filter
1229 * command we want to eat it all, otherwise, we're done.
1231 if (isblank(ch))
1232 while (len--) {
1233 ch = *++p = *++t;
1234 if (!isblank(ch))
1235 break;
1237 if (ch != '!')
1238 goto ret;
1240 for (; len; --len)
1241 *++p = *++t;
1243 /* Restore the state. */
1244 ret: *pp = p;
1245 *tp = t;
1246 *lenp = len;
1250 * ep_range --
1251 * Get a line range for ex commands.
1253 static char *
1254 ep_range(sp, ep, cmd, cp)
1255 SCR *sp;
1256 EXF *ep;
1257 char *cmd;
1258 EXCMDARG *cp;
1260 MARK cur, savecursor;
1261 int savecursor_set;
1262 char *endp;
1264 /* Percent character is all lines in the file. */
1265 if (*cmd == '%') {
1266 cp->addr1.lno = 1;
1267 if (file_lline(sp, ep, &cp->addr2.lno))
1268 return (NULL);
1269 /* If an empty file, then the first line is 0, not 1. */
1270 if (cp->addr2.lno == 0)
1271 cp->addr1.lno = 0;
1272 cp->addr1.cno = cp->addr2.cno = 0;
1273 cp->addrcnt = 2;
1274 return (++cmd);
1277 /* Parse comma or semi-colon delimited line specs. */
1278 for (savecursor_set = 0, cp->addrcnt = 0;;)
1279 switch (*cmd) {
1280 case ';': /* Semi-colon delimiter. */
1282 * Comma delimiters delimit; semi-colon delimiters
1283 * change the current address for the 2nd address
1284 * to be the first address. Trailing or multiple
1285 * delimiters are discarded.
1287 if (cp->addrcnt == 0)
1288 goto done;
1289 if (!savecursor_set) {
1290 savecursor.lno = sp->lno;
1291 savecursor.cno = sp->cno;
1292 sp->lno = cp->addr1.lno;
1293 sp->cno = cp->addr1.cno;
1294 savecursor_set = 1;
1296 /* FALLTHROUGH */
1297 case ' ':
1298 case '\t':
1299 case ',': /* Comma delimiter. */
1300 ++cmd;
1301 break;
1302 default:
1303 if ((endp = ep_line(sp, ep, cmd, &cur)) == NULL)
1304 return (NULL);
1305 if (cmd != endp) {
1306 cmd = endp;
1309 * Extra addresses are discarded, starting with
1310 * the first.
1312 switch (cp->addrcnt) {
1313 case 0:
1314 cp->addr1 = cur;
1315 cp->addrcnt = 1;
1316 break;
1317 case 1:
1318 cp->addr2 = cur;
1319 cp->addrcnt = 2;
1320 break;
1321 case 2:
1322 cp->addr1 = cp->addr2;
1323 cp->addr2 = cur;
1324 break;
1326 break;
1328 /* FALLTHROUGH */
1329 case '\0':
1330 goto done;
1334 * XXX
1335 * This is probably not right for treatment of savecursor -- figure
1336 * out what the historical ex did for ";,;,;5p" or similar stupidity.
1338 done: if (savecursor_set) {
1339 sp->lno = savecursor.lno;
1340 sp->cno = savecursor.cno;
1342 if (cp->addrcnt == 2 &&
1343 (cp->addr2.lno < cp->addr1.lno ||
1344 cp->addr2.lno == cp->addr1.lno && cp->addr2.cno < cp->addr1.cno)) {
1345 msgq(sp, M_ERR,
1346 "The second address is smaller than the first.");
1347 return (NULL);
1349 return (cmd);
1353 * Get a single line address specifier.
1355 static char *
1356 ep_line(sp, ep, cmd, cur)
1357 SCR *sp;
1358 EXF *ep;
1359 char *cmd;
1360 MARK *cur;
1362 MARK m, *mp;
1363 long num, total;
1364 u_int flags;
1365 char *endp;
1367 for (;;) {
1368 switch (*cmd) {
1369 case '$': /* Last line. */
1370 if (file_lline(sp, ep, &cur->lno))
1371 return (NULL);
1372 cur->cno = 0;
1373 ++cmd;
1374 break; /* Absolute line number. */
1375 case '0': case '1': case '2': case '3': case '4':
1376 case '5': case '6': case '7': case '8': case '9':
1378 * The way the vi "previous context" mark worked was
1379 * that "non-relative" motions set it. While vi was
1380 * not completely consistent about this, ANY numeric
1381 * address was considered non-relative, and set the
1382 * value.
1384 if (IN_VI_MODE(sp)) {
1385 m.lno = sp->lno;
1386 m.cno = sp->cno;
1387 if (mark_set(sp, ep, ABSMARK1, &m, 1))
1388 return (NULL);
1390 cur->lno = strtol(cmd, &endp, 10);
1391 cur->cno = 0;
1392 cmd = endp;
1393 break;
1394 case '\'': /* Set mark. */
1395 if (cmd[1] == '\0') {
1396 msgq(sp, M_ERR,
1397 "No mark name; use 'a' to 'z'.");
1398 return (NULL);
1400 if ((mp = mark_get(sp, ep, cmd[1])) == NULL)
1401 return (NULL);
1402 *cur = *mp;
1403 cmd += 2;
1404 break;
1405 case '/': /* Search forward. */
1406 m.lno = sp->lno;
1407 m.cno = sp->cno;
1408 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1409 if (f_search(sp, ep, &m, &m, cmd, &endp, &flags))
1410 return (NULL);
1411 cur->lno = m.lno;
1412 cur->cno = m.cno;
1413 cmd = endp;
1414 break;
1415 case '?': /* Search backward. */
1416 m.lno = sp->lno;
1417 m.cno = sp->cno;
1418 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1419 if (b_search(sp, ep, &m, &m, cmd, &endp, &flags))
1420 return (NULL);
1421 cur->lno = m.lno;
1422 cur->cno = m.cno;
1423 cmd = endp;
1424 break;
1425 case '.': /* Current position. */
1426 ++cmd;
1427 /* FALLTHROUGH */
1428 case '+': /* Increment. */
1429 case '-': /* Decrement. */
1430 /* If an empty file, then '.' is 0, not 1. */
1431 if (sp->lno == 1) {
1432 if (file_lline(sp, ep, &cur->lno))
1433 return (NULL);
1434 if (cur->lno != 0)
1435 cur->lno = 1;
1436 } else
1437 cur->lno = sp->lno;
1438 cur->cno = sp->cno;
1439 break;
1440 default:
1441 return (cmd);
1445 * Evaluate any offset. Offsets are +/- any number, or,
1446 * any number of +/- signs, or any combination thereof.
1448 for (total = 0; *cmd == '-' || *cmd == '+'; total += num) {
1449 num = *cmd == '-' ? -1 : 1;
1450 if (isdigit(*++cmd)) {
1451 num *= strtol(cmd, &endp, 10);
1452 cmd = endp;
1455 if (total < 0 && -total > cur->lno) {
1456 msgq(sp, M_ERR,
1457 "Reference to a line number less than 0.");
1458 return (NULL);
1460 cur->lno += total;