rework ARGS structures as part of ex parser rework
[nvi.git] / ex / ex.c
blob32b4bc0093609fae467692f96ee17352fcef4701
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.68 1993/11/30 15:47:38 bostic Exp $ (Berkeley) $Date: 1993/11/30 15:47:38 $";
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 + 1)) == 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.
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, cmd, arg1_len)
375 SCR *sp;
376 EXF *ep;
377 char *cmd;
378 int arg1_len;
380 CHAR_T esc;
381 EX_PRIVATE *exp;
382 EXCMDARG exc;
383 EXCMDLIST const *cp;
384 MARK cur;
385 recno_t lcount, lno, num;
386 long flagoff;
387 u_int saved_mode;
388 int ch, cnamelen, flags, uselastcmd;
389 char *p, *t, *endp;
391 #if defined(DEBUG) && 0
392 TRACE(sp, "ex: {%s}\n", cmd);
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 (; *cmd == ':'; ++cmd);
403 /* Ignore command lines that start with a double-quote. */
404 if (*cmd == '"')
405 return (0);
407 /* Skip whitespace. */
408 for (; isblank(*cmd); ++cmd);
410 /* Initialize the argument structure. */
411 memset(&exc, 0, sizeof(EXCMDARG));
412 exp = EXP(sp);
413 exp->ex_argv[0] = "";
414 exp->ex_argv[1] = NULL;
415 exc.argc = 0;
416 exc.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 ((cmd = ep_range(sp, ep, cmd, &exc)) == NULL)
423 return (1);
425 /* Skip whitespace. */
426 for (; isblank(*cmd); ++cmd);
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 (*cmd) {
436 if (strchr(SINGLE_CHAR_COMMANDS, *cmd)) {
437 p = cmd;
438 cmd++;
439 cnamelen = 1;
440 } else {
441 for (p = cmd; isalpha(*cmd); ++cmd);
442 cnamelen = cmd - p;
443 if (cnamelen == 0) {
444 msgq(sp, M_ERR, "Unknown command name.");
445 return (1);
448 for (cp = cmds;
449 cp->name && memcmp(p, cp->name, cnamelen); ++cp);
452 * !!!
453 * Historic vi permitted the mark to immediately follow the 'k'
454 * in the 'k' command. Make it work.
456 * Use of msgq below is safe, command names are all alphabetics.
458 if (cp->name == NULL)
459 if (p[0] == 'k' && p[1] && !p[2]) {
460 cmd = p + 1;
461 cp = &cmds[C_K];
462 } else {
463 msgq(sp, M_ERR, "The %.*s command is unknown.",
464 cnamelen, p);
465 return (1);
467 uselastcmd = 0;
469 /* Some commands are turned off. */
470 if (F_ISSET(cp, E_NOPERM)) {
471 msgq(sp, M_ERR,
472 "The %.*s command is not currently supported.",
473 cnamelen, p);
474 return (1);
477 /* Some commands aren't okay in globals. */
478 if (F_ISSET(sp, S_GLOBAL) && F_ISSET(cp, E_NOGLOBAL)) {
479 msgq(sp, M_ERR,
480 "The %.*s command can't be used as part of a global command.", cnamelen, p);
481 return (1);
485 * Multiple < and > characters; another "special" feature.
486 * NOTE: The string may not be nul terminated in this case.
488 if ((cp == &cmds[C_SHIFTL] && *p == '<') ||
489 (cp == &cmds[C_SHIFTR] && *p == '>')) {
490 exp->ex_argv[0] = p;
491 exp->ex_argv[1] = NULL;
492 exc.argc = 1;
493 exc.argv = exp->ex_argv;
494 for (ch = *p, cmd = p; *++cmd == ch;);
498 * The visual command has a different syntax when called
499 * from ex than when called from a vi colon command. FMH.
501 if (cp == &cmds[C_VISUAL_EX] && IN_VI_MODE(sp))
502 cp = &cmds[C_VISUAL_VI];
503 } else {
504 cp = exp->lastcmd;
505 uselastcmd = 1;
507 LF_INIT(cp->flags);
510 * File state must be checked throughout this code, because it is
511 * called when reading the .exrc file and similar things. There's
512 * this little chicken and egg problem -- if we read the file first,
513 * we won't know how to display it. If we read/set the exrc stuff
514 * first, we can't allow any command that requires file state.
515 * Historic vi generally took the easy way out and dropped core.
517 if (LF_ISSET(E_NORC) && ep == NULL) {
518 msgq(sp, M_ERR,
519 "The %s command requires a file to already have been read in.",
520 cp->name);
521 return (1);
525 * Set the default addresses. It's an error to specify an address for
526 * a command that doesn't take them. If two addresses are specified
527 * for a command that only takes one, lose the first one. Two special
528 * cases here, some commands take 0 or 2 addresses. For most of them
529 * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one
530 * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
532 * Also, if the file is empty, some commands want to use an address of
533 * 0, i.e. the entire file is 0 to 0, and the default first address is
534 * 0. Otherwise, an entire file is 1 to N and the default line is 1.
535 * Note, we also add the E_ZERO flag to the command flags, for the case
536 * where the 0 address is only valid if it's a default address.
538 * Also, set a flag if we set the default addresses. Some commands
539 * (ex: z) care if the user specified an address of if we just used
540 * the current cursor.
542 flagoff = 0;
543 switch (flags & (E_ADDR1|E_ADDR2|E_ADDR2_ALL|E_ADDR2_NONE)) {
544 case E_ADDR1: /* One address: */
545 switch (exc.addrcnt) {
546 case 0: /* Default cursor/empty file. */
547 exc.addrcnt = 1;
548 F_SET(&exc, E_ADDRDEF);
549 if (LF_ISSET(E_ZERODEF)) {
550 if (file_lline(sp, ep, &lno))
551 return (1);
552 if (lno == 0) {
553 exc.addr1.lno = 0;
554 LF_SET(E_ZERO);
555 } else
556 exc.addr1.lno = sp->lno;
557 } else
558 exc.addr1.lno = sp->lno;
559 exc.addr1.cno = sp->cno;
560 break;
561 case 1:
562 break;
563 case 2: /* Lose the first address. */
564 exc.addrcnt = 1;
565 exc.addr1 = exc.addr2;
567 break;
568 case E_ADDR2_NONE: /* Zero/two addresses: */
569 if (exc.addrcnt == 0) /* Default to nothing. */
570 break;
571 goto two;
572 case E_ADDR2_ALL: /* Zero/two addresses: */
573 if (exc.addrcnt == 0) { /* Default entire/empty file. */
574 exc.addrcnt = 2;
575 F_SET(&exc, E_ADDRDEF);
576 if (file_lline(sp, ep, &exc.addr2.lno))
577 return (1);
578 if (LF_ISSET(E_ZERODEF) && exc.addr2.lno == 0) {
579 exc.addr1.lno = 0;
580 LF_SET(E_ZERO);
581 } else
582 exc.addr1.lno = 1;
583 exc.addr1.cno = exc.addr2.cno = 0;
584 F_SET(&exc, E_ADDR2_ALL);
585 break;
587 /* FALLTHROUGH */
588 case E_ADDR2: /* Two addresses: */
589 two: switch (exc.addrcnt) {
590 case 0: /* Default cursor/empty file. */
591 exc.addrcnt = 2;
592 F_SET(&exc, E_ADDRDEF);
593 if (LF_ISSET(E_ZERODEF) && sp->lno == 1) {
594 if (file_lline(sp, ep, &lno))
595 return (1);
596 if (lno == 0) {
597 exc.addr1.lno = exc.addr2.lno = 0;
598 LF_SET(E_ZERO);
599 } else
600 exc.addr1.lno = exc.addr2.lno = sp->lno;
601 } else
602 exc.addr1.lno = exc.addr2.lno = sp->lno;
603 exc.addr1.cno = exc.addr2.cno = sp->cno;
604 break;
605 case 1: /* Default to first address. */
606 exc.addrcnt = 2;
607 exc.addr2 = exc.addr1;
608 break;
609 case 2:
610 break;
612 break;
613 default:
614 if (exc.addrcnt) /* Error. */
615 goto usage;
619 * YASC. The "set tags" command historically used a backslash, not
620 * the user's literal next character, to escape whitespace. Handle
621 * it here instead of complicating the argv_exp3() code. Note, this
622 * isn't a particularly complex trap, and if backslashes were legal
623 * in set commands, this would have to be much more complicated.
625 if (cp == &cmds[C_SET]) {
626 (void)term_key_ch(sp, K_VLNEXT, &esc);
627 for (p = cmd; (ch = *p) != '\0'; ++p)
628 if (ch == '\\')
629 *p = esc;
632 for (lcount = 0, p = cp->syntax; *p != '\0'; ++p) {
634 * The write command is sensitive to leading whitespace,
635 * i.e. "write !" is different from "write!". If not write,
636 * skip leading whitespace.
638 if (cp != &cmds[C_WRITE])
639 for (; isblank(*cmd); ++cmd);
642 * When reach the end of the command, quit, unless it's
643 * a command that does its own parsing, in which case we
644 * want to build a reasonable argv for it.
646 if (*p != 's' && *p != 'S' && *cmd == '\0')
647 break;
649 switch (*p) {
650 case '!': /* ! */
651 if (*cmd == '!') {
652 ++cmd;
653 F_SET(&exc, E_FORCE);
655 break;
656 case '+': /* +cmd */
657 if (*cmd != '+')
658 break;
659 cmd += arg1_len + 1;
660 if (*cmd)
661 *cmd++ = '\0';
662 break;
663 case '1': /* +, -, #, l, p */
665 * !!!
666 * Historically, some flags were ignored depending
667 * on where they occurred in the command line. For
668 * example, in the command, ":3+++p--#", historic vi
669 * acted on the '#' flag, but ignored the '-' flags.
670 * It's unambiguous what the flags mean, so we just
671 * handle them regardless of the stupidity of their
672 * location.
674 for (;; ++cmd)
675 switch (*cmd) {
676 case '+':
677 ++flagoff;
678 break;
679 case '-':
680 --flagoff;
681 break;
682 case '#':
683 F_SET(&exc, E_F_HASH);
684 break;
685 case 'l':
686 F_SET(&exc, E_F_LIST);
687 break;
688 case 'p':
689 F_SET(&exc, E_F_PRINT);
690 break;
691 default:
692 goto end1;
694 end1: break;
695 case '2': /* -, ., +, ^ */
696 case '3': /* -, ., +, ^, = */
697 for (;; ++cmd)
698 switch (*cmd) {
699 case '-':
700 F_SET(&exc, E_F_DASH);
701 break;
702 case '.':
703 F_SET(&exc, E_F_DOT);
704 break;
705 case '+':
706 F_SET(&exc, E_F_PLUS);
707 break;
708 case '^':
709 F_SET(&exc, E_F_CARAT);
710 break;
711 case '=':
712 if (*p == '3') {
713 F_SET(&exc, E_F_EQUAL);
714 break;
716 /* FALLTHROUGH */
717 default:
718 goto end2;
720 end2: break;
721 case 'b': /* buffer */
722 exc.buffer = *cmd++;
723 F_SET(&exc, E_BUFFER);
724 break;
725 case 'C': /* count */
726 case 'n':
727 case 'c': /* count (address) */
728 if (!isdigit(*cmd) &&
729 (*p != 'n' || (*cmd != '+' && *cmd != '-')))
730 break;
731 lcount = strtol(cmd, &endp, 10);
732 if (lcount == 0) {
733 msgq(sp, M_ERR,
734 "Count may not be zero.");
735 return (1);
737 cmd = endp;
739 * Count as address offsets occur in commands taking
740 * two addresses. Historic vi practice was to use
741 * the count as an offset from the *second* address.
743 * Set the count flag; some underlying commands (see
744 * join) do different things with counts than with
745 * line addresses.
747 if (*p == 'C' || *p == 'n')
748 exc.count = lcount;
749 else {
750 exc.addr1 = exc.addr2;
751 exc.addr2.lno = exc.addr1.lno + lcount - 1;
753 F_SET(&exc, E_COUNT);
754 break;
755 case 'f': /* file */
756 if (argv_exp2(sp, ep, &exc, cmd, cp == &cmds[C_BANG]))
757 return (1);
758 goto countchk;
759 case 'l': /* line */
760 endp = ep_line(sp, ep, cmd, &cur);
761 if (endp == NULL || cmd == endp) {
762 msgq(sp, M_ERR,
763 "%s: bad line specification", cmd);
764 return (1);
765 } else {
766 exc.lineno = cur.lno;
767 cmd = endp;
769 break;
770 case 'S': /* string, file exp. */
771 if (argv_exp1(sp, ep, &exc, cmd, cp == &cmds[C_BANG]))
772 return (1);
773 goto addr2;
774 case 's': /* string */
775 exp->ex_argv[0] = cmd;
776 exp->ex_argv[1] = NULL;
777 exc.argc = 1;
778 exc.argv = exp->ex_argv;
779 goto addr2;
780 case 'W': /* word string */
782 * QUOTING NOTE:
784 * Literal next characters escape the following
785 * character. The quote characters are stripped
786 * here since they are no longer useful.
788 * Word.
790 for (p = t = cmd; (ch = *p) != '\0'; *t++ = ch, ++p)
791 if (term_key_val(sp, ch) == K_VLNEXT &&
792 p[1] != '\0')
793 ch = *++p;
794 else if (isblank(ch))
795 break;
796 if (*p == '\0')
797 goto usage;
798 exp->ex_argv[0] = cmd;
800 /* Delete leading whitespace. */
801 for (*t++ = '\0'; (ch = *++p) != '\0' && isblank(ch););
803 /* String. */
804 exp->ex_argv[1] = p;
805 for (t = p; (ch = *p++) != '\0'; *t++ = ch)
806 if (term_key_val(sp, ch) == K_VLNEXT &&
807 p[0] != '\0')
808 ch = *p++;
809 *t = '\0';
810 exp->ex_argv[2] = NULL;
811 exc.argc = 2;
812 exc.argv = exp->ex_argv;
813 goto addr2;
814 case 'w': /* word */
815 if (argv_exp3(sp, ep, &exc, cmd))
816 return (1);
817 countchk: if (*++p != 'N') { /* N */
819 * If a number is specified, must either be
820 * 0 or that number, if optional, and that
821 * number, if required.
823 num = *p - '0';
824 if ((*++p != 'o' || exc.argc != 0) &&
825 exc.argc != num)
826 goto usage;
828 goto addr2;
829 default:
830 msgq(sp, M_ERR,
831 "Internal syntax table error (%s).", cp->name);
836 * Shouldn't be anything left, and no more required fields.
837 * That means neither 'l' or 'r' in the syntax.
839 for (; *cmd && isblank(*cmd); ++cmd);
840 if (*cmd || strpbrk(p, "lr")) {
841 usage: msgq(sp, M_ERR, "Usage: %s.", cp->usage);
842 return (1);
845 /* Verify that the addresses are legal. */
846 addr2: switch (exc.addrcnt) {
847 case 2:
848 if (file_lline(sp, ep, &lcount))
849 return (1);
851 * Historic ex/vi permitted commands with counts to go past
852 * EOF. So, for example, if the file only had 5 lines, the
853 * ex command "1,6>" would fail, but the command ">300"
854 * would succeed. Since we don't want to have to make all
855 * of the underlying commands handle random line numbers,
856 * fix it here.
858 if (exc.addr2.lno > lcount)
859 if (F_ISSET(&exc, E_COUNT))
860 exc.addr2.lno = lcount;
861 else {
862 if (lcount == 0)
863 msgq(sp, M_ERR, "The file is empty.");
864 else
865 msgq(sp, M_ERR,
866 "Only %lu line%s in the file",
867 lcount, lcount > 1 ? "s" : "");
868 return (1);
870 /* FALLTHROUGH */
871 case 1:
872 num = exc.addr1.lno;
874 * If it's a "default vi command", zero is okay. Historic
875 * vi allowed this, note, it's also the hack that allows
876 * "vi + nonexistent_file" to work.
878 if (num == 0 && (!IN_VI_MODE(sp) || uselastcmd != 1) &&
879 !LF_ISSET(E_ZERO)) {
880 msgq(sp, M_ERR,
881 "The %s command doesn't permit an address of 0.",
882 cp->name);
883 return (1);
885 if (file_lline(sp, ep, &lcount))
886 return (1);
887 if (num > lcount) {
888 if (lcount == 0)
889 msgq(sp, M_ERR, "The file is empty.");
890 else
891 msgq(sp, M_ERR, "Only %lu line%s in the file",
892 lcount, lcount > 1 ? "s" : "");
893 return (1);
895 break;
898 /* If doing a default command, vi just moves to the line. */
899 if (IN_VI_MODE(sp) && uselastcmd) {
900 switch (exc.addrcnt) {
901 case 2:
902 sp->lno = exc.addr2.lno ? exc.addr2.lno : 1;
903 sp->cno = exc.addr2.cno;
904 break;
905 case 1:
906 sp->lno = exc.addr1.lno ? exc.addr1.lno : 1;
907 sp->cno = exc.addr1.cno;
908 break;
910 return (0);
913 /* Reset "last" command. */
914 if (LF_ISSET(E_SETLAST))
915 exp->lastcmd = cp;
917 exc.cmd = cp;
918 #if defined(DEBUG) && 0
920 int __cnt;
922 TRACE(sp, "ex_cmd: %s", exc.cmd->name);
923 if (exc.addrcnt > 0) {
924 TRACE(sp, "\taddr1 %d", exc.addr1.lno);
925 if (exc.addrcnt > 1)
926 TRACE(sp, " addr2: %d", exc.addr2.lno);
927 TRACE(sp, "\n");
929 if (exc.lineno)
930 TRACE(sp, "\tlineno %d", exc.lineno);
931 if (exc.flags)
932 TRACE(sp, "\tflags %0x", exc.flags);
933 if (F_ISSET(&exc, E_BUFFER))
934 TRACE(sp, "\tbuffer %c", exc.buffer);
935 TRACE(sp, "\n");
936 if (exc.argc) {
937 for (__cnt = 0; __cnt < exc.argc; ++__cnt)
938 TRACE(sp, "\targ %d: {%s}", __cnt, exc.argv[__cnt]);
939 TRACE(sp, "\n");
942 #endif
943 /* Clear autoprint. */
944 F_CLR(sp, S_AUTOPRINT);
947 * If file state and not doing a global command, log the start of
948 * an action.
950 if (ep != NULL && !F_ISSET(sp, S_GLOBAL))
951 (void)log_cursor(sp, ep);
953 /* Save the current mode. */
954 saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
956 /* Increment the command count if not called from vi. */
957 if (!IN_VI_MODE(sp))
958 ++sp->ccnt;
960 /* Do the command. */
961 if ((cp->fn)(sp, ep, &exc))
962 return (1);
964 #ifdef DEBUG
965 /* Make sure no function left the temporary space locked. */
966 if (F_ISSET(sp->gp, G_TMP_INUSE)) {
967 msgq(sp, M_ERR, "Error: ex: temporary buffer not released.");
968 return (1);
970 #endif
972 /* If the world changed, we're done. */
973 if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
974 return (0);
976 /* If just starting up, or not in ex mode, we're done. */
977 if (ep == NULL || !IN_EX_MODE(sp))
978 return (0);
981 * The print commands have already handled the `print' flags.
982 * If so, clear them. Don't return, autoprint may still have
983 * stuff to print out.
985 if (LF_ISSET(E_F_PRCLEAR))
986 F_CLR(&exc, E_F_HASH | E_F_LIST | E_F_PRINT);
989 * If the command was successful, and there was an explicit flag to
990 * display the new cursor line, or we're in ex mode, autoprint is set,
991 * and a change was made, display the line.
993 if (flagoff) {
994 if (flagoff < 0) {
995 if (sp->lno < -flagoff) {
996 msgq(sp, M_ERR, "Flag offset before line 1.");
997 return (1);
999 } else {
1000 if (file_lline(sp, ep, &lno))
1001 return (1);
1002 if (sp->lno + flagoff > lno) {
1003 msgq(sp, M_ERR,
1004 "Flag offset past end-of-file.");
1005 return (1);
1008 sp->lno += flagoff;
1011 if (F_ISSET(sp, S_AUTOPRINT) && O_ISSET(sp, O_AUTOPRINT))
1012 LF_INIT(E_F_PRINT);
1013 else
1014 LF_INIT(F_ISSET(&exc, E_F_HASH | E_F_LIST | E_F_PRINT));
1016 memset(&exc, 0, sizeof(EXCMDARG));
1017 exc.addrcnt = 2;
1018 exc.addr1.lno = exc.addr2.lno = sp->lno;
1019 exc.addr1.cno = exc.addr2.cno = sp->cno;
1020 if (flags) {
1021 switch (flags) {
1022 case E_F_HASH:
1023 exc.cmd = &cmds[C_HASH];
1024 ex_number(sp, ep, &exc);
1025 break;
1026 case E_F_LIST:
1027 exc.cmd = &cmds[C_LIST];
1028 ex_list(sp, ep, &exc);
1029 break;
1030 case E_F_PRINT:
1031 exc.cmd = &cmds[C_PRINT];
1032 ex_pr(sp, ep, &exc);
1033 break;
1036 return (0);
1040 * ep_comm, ep_re, ep_rw --
1042 * Historically, '|' characters in the first argument of the ex, edit,
1043 * global, vglobal and substitute commands did not separate commands.
1044 * And, in the filter cases for read and write, they did not delimit
1045 * the command at all.
1047 * For example, the following commands were legal:
1049 * :edit +25|s/abc/ABC/ file.c
1050 * :substitute s/|/PIPE/
1051 * :read !spell % | columnate
1053 * It's not quite as simple as it looks, however. The command:
1055 * :substitute s/a/b/|s/c/d|set
1057 * was also legal, i.e. the historic ex parser (and I use the word loosely,
1058 * since "parser" implies some regularity of syntax) delimited the RE's
1059 * based on its delimiter and not anything so vulgar as a command syntax.
1061 * The ep_comm(), ep_re(), and ep_rw routines make this work. They're passed
1062 * the state from ex_cstring(), and, if it's a special case, they parse the
1063 * first (or entire) argument and return the new state. For the +cmd field,
1064 * since we don't want to parse the line more than once, a pointer to, and the
1065 * length of, the first argument is returned to ex_cstring(), which passes it
1066 * to ex_cmd(). Barf-O-Rama.
1068 static void
1069 ep_comm(sp, pp, tp, lenp, arg1p, arg1_lenp)
1070 SCR *sp;
1071 char **pp, **tp, **arg1p;
1072 int *lenp, *arg1_lenp;
1074 char *cp, *p, *t;
1075 int ch, cnt, len;
1077 /* Copy the state to local variables. */
1078 p = *pp;
1079 cp = t = *tp;
1080 len = *lenp;
1083 * Move to the next non-lower-case, alphabetic character. We can
1084 * do this fairly brutally because we know that the command names
1085 * are all lower-case alphabetics, and there has to be a '+' to
1086 * start the arguments. If there isn't one, we're done.
1088 if (*t == ':') {
1089 ++cp;
1090 *p++ = *t++;
1091 --len;
1093 for (; len && islower(*p = *t); ++p, ++t, --len);
1094 if (len == 0)
1095 goto ret;
1098 * Make sure it's the ex or edit command. Note, 'e' has
1099 * to map to the edit command or the strncmp's aren't right.
1101 cnt = t - cp;
1102 if (strncmp(cp, "ex", cnt) && strncmp(cp, "edit", cnt))
1103 goto ret;
1106 * Move to the '+'. We don't check syntax here, if it's not
1107 * there, we're done.
1109 while (len--) {
1110 ch = *++p = *++t;
1111 if (!isblank(ch))
1112 break;
1114 if (len == 0 || *p != '+')
1115 goto ret;
1118 * QUOTING NOTE:
1120 * The historic implementation of this "feature" ignored any escape
1121 * characters so there was no way to put a space or newline into the
1122 * +cmd field. We do a simplistic job of handling it by moving to
1123 * the first whitespace character that isn't escaped by a literal next
1124 * character. The literal next quote characters are stripped here
1125 * since they are no longer useful.
1127 * Move to the first non-escaped space.
1129 for (cp = p; len;) {
1130 ch = *++p = *++t;
1131 --len;
1132 if (term_key_val(sp, ch) == K_VLNEXT && len > 0) {
1133 *p = *++t;
1134 if (--len == 0)
1135 break;
1136 } else if (isblank(ch))
1137 break;
1140 /* Return information about the first argument. */
1141 *arg1p = cp + 1;
1142 *arg1_lenp = (p - cp) - 1;
1144 /* Restore the state. */
1145 ret: *pp = p;
1146 *tp = t;
1147 *lenp = len;
1150 static void
1151 ep_re(sp, pp, tp, lenp)
1152 SCR *sp;
1153 char **pp, **tp;
1154 int *lenp;
1156 char *cp, *p, *t;
1157 int ch, cnt, delim, len;
1159 /* Copy the state to local variables. */
1160 p = *pp;
1161 cp = t = *tp;
1162 len = *lenp;
1165 * Move to the next non-lower-case, alphabetic character. We can
1166 * do this fairly brutally because we know that the command names
1167 * are all lower-case alphabetics, and there has to be a delimiter
1168 * to start the arguments. If there isn't one, we're done.
1170 if (*t == ':') {
1171 ++cp;
1172 *p++ = *t++;
1173 --len;
1175 for (; len; ++p, ++t, --len) {
1176 ch = *p = *t;
1177 if (!islower(ch))
1178 break;
1180 if (len == 0)
1181 goto ret;
1184 * Make sure it's the substitute, global or vglobal command.
1185 * Note, 's', 'g and 'v' have to map to these commands or the
1186 * strncmp's aren't right.
1188 cnt = t - cp;
1189 if (strncmp(cp, "substitute", cnt) &&
1190 strncmp(cp, "global", cnt) && strncmp(cp, "vglobal", cnt))
1191 goto ret;
1194 * Move to the delimiter. (The first character; if it's an illegal
1195 * one, the RE code will catch it.)
1197 if (isblank(ch))
1198 while (len--) {
1199 ch = *++p = *++t;
1200 if (!isblank(ch))
1201 break;
1203 delim = ch;
1204 if (len == 0)
1205 goto ret;
1208 * QUOTING NOTE:
1210 * Backslashes quote delimiter characters for regular expressions.
1211 * The backslashes are left here since they'll be needed by the RE
1212 * code.
1214 * Move to the third (non-escaped) delimiter.
1216 for (cnt = 2; len && cnt;) {
1217 ch = *++p = *++t;
1218 --len;
1219 if (ch == '\\' && len > 0) {
1220 *++p = *++t;
1221 if (--len == 0)
1222 break;
1223 } else if (ch == delim)
1224 --cnt;
1227 /* Move past the delimiter if it's possible. */
1228 if (len > 0) {
1229 ++t;
1230 ++p;
1231 --len;
1234 /* Restore the state. */
1235 ret: *pp = p;
1236 *tp = t;
1237 *lenp = len;
1240 static void
1241 ep_rw(sp, pp, tp, lenp)
1242 SCR *sp;
1243 char **pp, **tp;
1244 int *lenp;
1246 char *cp, *p, *t;
1247 int ch, cnt, len;
1249 /* Copy the state to local variables. */
1250 p = *pp;
1251 cp = t = *tp;
1252 len = *lenp;
1255 * Move to the next non-lower-case, alphabetic character. We can
1256 * do this fairly brutally because we know that the command names
1257 * are all lower-case alphabetics, and there has to be a delimiter
1258 * to start the arguments. If there isn't one, we're done.
1260 if (*t == ':') {
1261 ++cp;
1262 *p++ = *t++;
1263 --len;
1265 for (; len; ++p, ++t, --len) {
1266 ch = *p = *t;
1267 if (!islower(ch))
1268 break;
1270 if (len == 0)
1271 goto ret;
1274 * Make sure it's the read or write command. Note, 'r' and 'w'
1275 * have to map to these commands or the strncmp's aren't right.
1277 cnt = t - cp;
1278 if (strncmp(cp, "read", cnt) && strncmp(cp, "write", cnt))
1279 goto ret;
1282 * Move to the next character. If it's a '!', it's a filter
1283 * command we want to eat it all, otherwise, we're done.
1285 if (isblank(ch))
1286 while (len--) {
1287 ch = *++p = *++t;
1288 if (!isblank(ch))
1289 break;
1291 if (ch != '!')
1292 goto ret;
1294 for (; len; --len)
1295 *++p = *++t;
1297 /* Restore the state. */
1298 ret: *pp = p;
1299 *tp = t;
1300 *lenp = len;
1304 * ep_range --
1305 * Get a line range for ex commands.
1307 static char *
1308 ep_range(sp, ep, cmd, cp)
1309 SCR *sp;
1310 EXF *ep;
1311 char *cmd;
1312 EXCMDARG *cp;
1314 MARK cur, savecursor;
1315 int savecursor_set;
1316 char *endp;
1318 /* Percent character is all lines in the file. */
1319 if (*cmd == '%') {
1320 cp->addr1.lno = 1;
1321 if (file_lline(sp, ep, &cp->addr2.lno))
1322 return (NULL);
1323 /* If an empty file, then the first line is 0, not 1. */
1324 if (cp->addr2.lno == 0)
1325 cp->addr1.lno = 0;
1326 cp->addr1.cno = cp->addr2.cno = 0;
1327 cp->addrcnt = 2;
1328 return (++cmd);
1331 /* Parse comma or semi-colon delimited line specs. */
1332 for (savecursor_set = 0, cp->addrcnt = 0;;)
1333 switch (*cmd) {
1334 case ';': /* Semi-colon delimiter. */
1336 * Comma delimiters delimit; semi-colon delimiters
1337 * change the current address for the 2nd address
1338 * to be the first address. Trailing or multiple
1339 * delimiters are discarded.
1341 if (cp->addrcnt == 0)
1342 goto done;
1343 if (!savecursor_set) {
1344 savecursor.lno = sp->lno;
1345 savecursor.cno = sp->cno;
1346 sp->lno = cp->addr1.lno;
1347 sp->cno = cp->addr1.cno;
1348 savecursor_set = 1;
1350 /* FALLTHROUGH */
1351 case ' ':
1352 case '\t':
1353 case ',': /* Comma delimiter. */
1354 ++cmd;
1355 break;
1356 default:
1357 if ((endp = ep_line(sp, ep, cmd, &cur)) == NULL)
1358 return (NULL);
1359 if (cmd != endp) {
1360 cmd = endp;
1363 * Extra addresses are discarded, starting with
1364 * the first.
1366 switch (cp->addrcnt) {
1367 case 0:
1368 cp->addr1 = cur;
1369 cp->addrcnt = 1;
1370 break;
1371 case 1:
1372 cp->addr2 = cur;
1373 cp->addrcnt = 2;
1374 break;
1375 case 2:
1376 cp->addr1 = cp->addr2;
1377 cp->addr2 = cur;
1378 break;
1380 break;
1382 /* FALLTHROUGH */
1383 case '\0':
1384 goto done;
1388 * XXX
1389 * This is probably not right for treatment of savecursor -- figure
1390 * out what the historical ex did for ";,;,;5p" or similar stupidity.
1392 done: if (savecursor_set) {
1393 sp->lno = savecursor.lno;
1394 sp->cno = savecursor.cno;
1396 if (cp->addrcnt == 2 &&
1397 (cp->addr2.lno < cp->addr1.lno ||
1398 cp->addr2.lno == cp->addr1.lno && cp->addr2.cno < cp->addr1.cno)) {
1399 msgq(sp, M_ERR,
1400 "The second address is smaller than the first.");
1401 return (NULL);
1403 return (cmd);
1407 * Get a single line address specifier.
1409 static char *
1410 ep_line(sp, ep, cmd, cur)
1411 SCR *sp;
1412 EXF *ep;
1413 char *cmd;
1414 MARK *cur;
1416 MARK m, *mp;
1417 long num, total;
1418 u_int flags;
1419 char *endp;
1421 for (;;) {
1422 switch (*cmd) {
1423 case '$': /* Last line. */
1424 if (file_lline(sp, ep, &cur->lno))
1425 return (NULL);
1426 cur->cno = 0;
1427 ++cmd;
1428 break; /* Absolute line number. */
1429 case '0': case '1': case '2': case '3': case '4':
1430 case '5': case '6': case '7': case '8': case '9':
1432 * The way the vi "previous context" mark worked was
1433 * that "non-relative" motions set it. While vi was
1434 * not completely consistent about this, ANY numeric
1435 * address was considered non-relative, and set the
1436 * value.
1438 if (IN_VI_MODE(sp)) {
1439 m.lno = sp->lno;
1440 m.cno = sp->cno;
1441 if (mark_set(sp, ep, ABSMARK1, &m, 1))
1442 return (NULL);
1444 cur->lno = strtol(cmd, &endp, 10);
1445 cur->cno = 0;
1446 cmd = endp;
1447 break;
1448 case '\'': /* Set mark. */
1449 if (cmd[1] == '\0') {
1450 msgq(sp, M_ERR,
1451 "No mark name; use 'a' to 'z'.");
1452 return (NULL);
1454 if ((mp = mark_get(sp, ep, cmd[1])) == NULL)
1455 return (NULL);
1456 *cur = *mp;
1457 cmd += 2;
1458 break;
1459 case '/': /* Search forward. */
1460 m.lno = sp->lno;
1461 m.cno = sp->cno;
1462 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1463 if (f_search(sp, ep, &m, &m, cmd, &endp, &flags))
1464 return (NULL);
1465 cur->lno = m.lno;
1466 cur->cno = m.cno;
1467 cmd = endp;
1468 break;
1469 case '?': /* Search backward. */
1470 m.lno = sp->lno;
1471 m.cno = sp->cno;
1472 flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
1473 if (b_search(sp, ep, &m, &m, cmd, &endp, &flags))
1474 return (NULL);
1475 cur->lno = m.lno;
1476 cur->cno = m.cno;
1477 cmd = endp;
1478 break;
1479 case '.': /* Current position. */
1480 ++cmd;
1481 /* FALLTHROUGH */
1482 case '+': /* Increment. */
1483 case '-': /* Decrement. */
1484 /* If an empty file, then '.' is 0, not 1. */
1485 if (sp->lno == 1) {
1486 if (file_lline(sp, ep, &cur->lno))
1487 return (NULL);
1488 if (cur->lno != 0)
1489 cur->lno = 1;
1490 } else
1491 cur->lno = sp->lno;
1492 cur->cno = sp->cno;
1493 break;
1494 default:
1495 return (cmd);
1499 * Evaluate any offset. Offsets are +/- any number, or,
1500 * any number of +/- signs, or any combination thereof.
1502 for (total = 0; *cmd == '-' || *cmd == '+'; total += num) {
1503 num = *cmd == '-' ? -1 : 1;
1504 if (isdigit(*++cmd)) {
1505 num *= strtol(cmd, &endp, 10);
1506 cmd = endp;
1509 if (total < 0 && -total > cur->lno) {
1510 msgq(sp, M_ERR,
1511 "Reference to a line number less than 0.");
1512 return (NULL);
1514 cur->lno += total;