2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: ex.c,v 8.89 1994/01/08 13:16:01 bostic Exp $ (Berkeley) $Date: 1994/01/08 13:16:01 $";
12 #include <sys/types.h>
25 static inline EXCMDLIST
const *
26 ex_comm_search
__P((char *, size_t));
27 static int ep_line
__P((SCR
*, EXF
*, MARK
*, char **, size_t *, int *));
28 static int ep_range
__P((SCR
*, EXF
*, EXCMDARG
*, char **, size_t *));
34 * Read an ex command and execute it.
44 char defcom
[sizeof(DEFCOM
)];
49 if (sp
->s_refresh(sp
, ep
))
52 /* If reading from a file, messages should have line info. */
53 if (!F_ISSET(sp
->gp
, G_ISFROMTTY
)) {
55 sp
->if_name
= strdup("input");
57 for (eval
= 0;; ++sp
->if_lno
) {
58 /* Get the next command. */
59 switch (sp
->s_get(sp
, ep
, &sp
->tiq
, ':', TXT_CR
| TXT_PROMPT
)) {
63 F_SET(sp
, S_EXIT_FORCE
);
69 saved_mode
= F_ISSET(sp
, S_SCREENS
| S_MAJOR_CHANGE
);
70 tp
= sp
->tiq
.cqh_first
;
72 if (F_ISSET(sp
->gp
, G_ISFROMTTY
)) {
73 (void)fputc('\r', stdout
);
76 memmove(defcom
, DEFCOM
, sizeof(DEFCOM
));
77 (void)ex_icmd(sp
, ep
, defcom
, sizeof(DEFCOM
) - 1);
79 if (F_ISSET(sp
->gp
, G_ISFROMTTY
))
80 (void)fputc('\n', stdout
);
81 (void)ex_icmd(sp
, ep
, tp
->lb
, tp
->len
);
85 if (saved_mode
!= F_ISSET(sp
, S_SCREENS
| S_MAJOR_CHANGE
))
88 if (sp
->s_refresh(sp
, ep
)) {
93 ret
: if (sp
->if_name
!= NULL
) {
94 FREE(sp
->if_name
, strlen(sp
->if_name
) + 1);
97 return (ex_end(sp
) || eval
);
102 * Execute ex commands from a file.
105 ex_cfile(sp
, ep
, filename
)
115 if ((fd
= open(filename
, O_RDONLY
, 0)) < 0 || fstat(fd
, &sb
))
120 * We'd like to test if the file is too big to malloc. Since we don't
121 * know what size or type off_t's or size_t's are, what the largest
122 * unsigned integral type is, or what random insanity the local C
123 * compiler will perpetrate, doing the comparison in a portable way
124 * is flatly impossible. Hope that malloc fails if the file is too
127 MALLOC(sp
, bp
, char *, (size_t)sb
.st_size
+ 1);
131 len
= read(fd
, bp
, (int)sb
.st_size
);
132 if (len
== -1 || len
!= sb
.st_size
) {
133 if (len
!= sb
.st_size
)
136 msgq(sp
, M_SYSERR
, filename
);
138 bp
[sb
.st_size
] = '\0'; /* XXX */
140 /* Run the command. Messages include file/line information. */
142 sp
->if_name
= strdup(filename
);
143 rval
= ex_icmd(sp
, ep
, bp
, len
);
144 FREE(sp
->if_name
, strlen(sp
->if_name
) + 1);
150 * THE UNDERLYING EXF MAY HAVE CHANGED.
153 FREE(bp
, sb
.st_size
);
161 * Call ex_cmd() after turning off interruptible bits.
164 ex_icmd(sp
, ep
, cmd
, len
)
171 * Ex goes through here for each vi :colon command and for each ex
172 * command, however, globally executed commands don't go through
173 * here, instead, they call ex_cmd directly. So, reset all of the
174 * interruptible flags now.
176 F_CLR(sp
, S_INTERRUPTED
| S_INTERRUPTIBLE
);
178 return (ex_cmd(sp
, ep
, cmd
, len
));
181 /* Special command structure for :s as a repeat substitution command. */
182 static EXCMDLIST
const cmd_subagain
=
183 {"s", ex_subagain
, E_ADDR2
|E_NORC
,
185 "[line [,line]] s [cgr] [count] [#lp]",
186 "repeat the last subsitution"};
190 * Parse and execute a string containing ex commands.
193 ex_cmd(sp
, ep
, cmd
, cmdlen
)
205 size_t arg1_len
, len
, save_cmdlen
;
208 int ch
, cnt
, delim
, flags
, namelen
, nl
, uselastcmd
, tmp
;
209 char *arg1
, *save_cmd
, *p
, *t
;
221 * It's possible that we've been interrupted during a
224 if (F_ISSET(sp
, S_INTERRUPTED
))
227 /* Skip whitespace, separators, newlines. */
228 for (; cmdlen
> 0; ++cmd
, --cmdlen
)
229 if ((ch
= *cmd
) == '\n')
231 else if (!isblank(ch
))
236 /* Command lines that start with a double-quote are comments. */
238 while (--cmdlen
> 0 && *++cmd
!= '\n');
249 * Permit extra colons at the start of the line. Historically,
250 * ex/vi allowed a single extra one. It's simpler not to count.
251 * The stripping is done here because, historically, any command
252 * could have preceding colons, e.g. ":g/pattern/:p" worked.
255 while (--cmdlen
> 0 && *++cmd
== ':');
257 /* Skip whitespace. */
258 for (; cmdlen
> 0; ++cmd
, --cmdlen
) {
264 /* The last point at which an empty line means do nothing. */
268 /* Initialize the structure passed to underlying functions. */
269 memset(&exc
, 0, sizeof(EXCMDARG
));
271 if (argv_init(sp
, ep
, &exc
))
274 /* Parse command addresses. */
275 if (ep_range(sp
, ep
, &exc
, &cmd
, &cmdlen
))
278 /* Skip whitespace. */
279 for (; cmdlen
> 0; ++cmd
, --cmdlen
) {
286 * If no command, ex does the last specified of p, l, or #, and vi
287 * moves to the line. Otherwise, determine the length of the command
288 * name by looking for the first non-alphabetic character. (There
289 * are a few non-alphabetic characters in command names, but they're
290 * all single character commands.) This isn't a great test, because
291 * it means that, for the command ":e +cut.c file", we'll report that
292 * the command "cut" wasn't known. However, it makes ":e+35 file" work
295 #define SINGLE_CHAR_COMMANDS "!#&<=>@~"
296 if (cmdlen
!= 0 && cmd
[0] != '|' && cmd
[0] != '\n') {
297 if (strchr(SINGLE_CHAR_COMMANDS
, *cmd
)) {
303 for (p
= cmd
; cmdlen
> 0; --cmdlen
, ++cmd
)
306 if ((namelen
= cmd
- p
) == 0) {
307 msgq(sp
, M_ERR
, "Unknown command name.");
313 * Search the table for the command.
316 * Historic vi permitted the mark to immediately follow the
317 * 'k' in the 'k' command. Make it work.
320 * Historic vi permitted pretty much anything to follow the
321 * substitute command, e.g. "s/e/E/|s|sgc3p" was fine. Make
324 * Use of msgq below is safe, command names are all alphabetics.
326 if ((cp
= ex_comm_search(p
, namelen
)) == NULL
)
327 if (p
[0] == 'k' && p
[1] && !p
[2]) {
329 cmdlen
+= namelen
- 1;
331 } else if (p
[0] == 's') {
333 cmdlen
+= namelen
- 1;
337 "The %.*s command is unknown.", namelen
, p
);
341 /* Some commands are either not implemented or turned off. */
342 if (F_ISSET(cp
, E_NOPERM
)) {
344 "The %s command is not currently supported.",
349 /* Some commands aren't okay in globals. */
350 if (F_ISSET(sp
, S_GLOBAL
) && F_ISSET(cp
, E_NOGLOBAL
)) {
352 "The %s command can't be used as part of a global command.",
358 * Multiple < and > characters; another "feature". Note,
359 * The string passed to the underlying function may not be
360 * nul terminated in this case.
362 if ((cp
== &cmds
[C_SHIFTL
] && *p
== '<') ||
363 (cp
== &cmds
[C_SHIFTR
] && *p
== '>')) {
364 for (ch
= *p
; cmdlen
> 0; --cmdlen
, ++cmd
)
367 if (argv_exp0(sp
, ep
, &exc
, p
, cmd
- p
))
372 * The visual command has a different syntax when called
373 * from ex than when called from a vi colon command. FMH.
375 if (cp
== &cmds
[C_VISUAL_EX
] && IN_VI_MODE(sp
))
376 cp
= &cmds
[C_VISUAL_VI
];
384 /* Initialize local flags to the command flags. */
388 * File state must be checked throughout this code, because it is
389 * called when reading the .exrc file and similar things. There's
390 * this little chicken and egg problem -- if we read the file first,
391 * we won't know how to display it. If we read/set the exrc stuff
392 * first, we can't allow any command that requires file state.
393 * Historic vi generally took the easy way out and dropped core.
395 if (LF_ISSET(E_NORC
) && ep
== NULL
) {
397 "The %s command requires that a file already have been read in.",
403 * There are three normal termination cases for an ex command. They
404 * are the end of the string (cmdlen), or unescaped (by literal next
405 * characters) newline or '|' characters. As we're past any addresses,
406 * we can now determine how long the command is, so we don't have to
407 * look for all the possible terminations. There are three exciting
410 * 1: The bang, global, vglobal and the filter versions of the read and
411 * write commands are delimited by newlines (they can contain shell
413 * 2: The ex, edit and visual in vi mode commands take ex commands as
414 * their first arguments.
415 * 3: The substitute command takes an RE as its first argument, and
416 * wants it to be specially delimited.
418 * Historically, '|' characters in the first argument of the ex, edit,
419 * and substitute commands did not delimit the command. And, in the
420 * filter cases for read and write, and the bang, global and vglobal
421 * commands, they did not delimit the command at all.
423 * For example, the following commands were legal:
425 * :edit +25|s/abc/ABC/ file.c
426 * :substitute s/|/PIPE/
427 * :read !spell % | columnate
428 * :global/pattern/p|l
430 * It's not quite as simple as it sounds, however. The command:
432 * :substitute s/a/b/|s/c/d|set
434 * was also legal, i.e. the historic ex parser (using the word loosely,
435 * since "parser" implies some regularity) delimited the RE's based on
436 * its delimiter and not anything so irretrievably vulgar as a command
439 * One thing that makes this easier is that we can ignore most of the
440 * command termination conditions for the commands that want to take
441 * the command up to the next newline. None of them are legal in .exrc
442 * files, so if we're here, we only dealing with a single line, and we
445 * Anyhow, the following code makes this all work. First, for the
446 * special cases we move past their special argument. Then, we do
447 * normal command processing on whatever is left. Barf-O-Rama.
451 (void)term_key_ch(sp
, K_VLNEXT
, &vlit
);
452 if (cp
== &cmds
[C_EDIT
] ||
453 cp
== &cmds
[C_EX
] || cp
== &cmds
[C_VISUAL_VI
]) {
455 * Move to the next non-whitespace character. As '+' must
456 * be the character after the command name, if there isn't
459 for (; cmdlen
> 0; --cmdlen
, ++cmd
) {
467 * The historic implementation ignored all escape characters
468 * so there was no way to put a space or newline into the +cmd
469 * field. We do a simplistic job of fixing it by moving to the
470 * first whitespace character that isn't escaped by a literal
471 * next character. The literal next characters are stripped
472 * as they're no longer useful.
474 if (cmdlen
> 0 && ch
== '+') {
477 for (arg1
= p
= cmd
; cmdlen
> 0; --cmdlen
, ++cmd
) {
478 if ((ch
= *cmd
) == vlit
&& cmdlen
> 1) {
481 } else if (isblank(ch
))
485 arg1_len
= cmd
- arg1
;
487 /* Reset, so the first argument isn't reparsed. */
490 } else if (cp
== &cmds
[C_BANG
] ||
491 cp
== &cmds
[C_GLOBAL
] || cp
== &cmds
[C_VGLOBAL
]) {
494 } else if (cp
== &cmds
[C_READ
] || cp
== &cmds
[C_WRITE
]) {
496 * Move to the next character. If it's a '!', it's a filter
497 * command and we want to eat it all, otherwise, we're done.
499 for (; cmdlen
> 0; --cmdlen
, ++cmd
) {
504 if (cmdlen
> 0 && ch
== '!') {
508 } else if (cp
== &cmds
[C_SUBSTITUTE
]) {
510 * Move to the next non-whitespace character, we'll use it as
511 * the delimiter. If the character isn't an alphanumeric or
512 * a '|', it's the delimiter, so parse it. Otherwise, we're
513 * into something like ":s g", so use the special substitute
516 for (; cmdlen
> 0; --cmdlen
, ++cmd
)
517 if (!isblank(cmd
[0]))
520 if (isalnum(cmd
[0]) || cmd
[0] == '|')
522 else if (cmdlen
> 0) {
526 * Backslashes quote delimiter characters for RE's.
527 * The backslashes are NOT removed since they'll be
528 * used by the RE code. Move to the third delimiter
529 * that's not escaped (or the end of the command).
534 for (cnt
= 2; cmdlen
> 0 && cnt
; --cmdlen
, ++cmd
)
535 if (cmd
[0] == '\\' && cmdlen
> 1) {
538 } else if (cmd
[0] == delim
)
543 * Use normal quoting and termination rules to find the end
548 * Historically, vi permitted ^V's to escape <newline>'s in the .exrc
549 * file. It was almost certainly a bug, but that's what bug-for-bug
550 * compatibility means, Grasshopper. Also, ^V's escape the command
551 * delimiters. Literal next quote characters in front of the newlines,
552 * '|' characters or literal next characters are stripped as as they're
555 for (p
= cmd
, cnt
= 0; cmdlen
> 0; --cmdlen
, ++cmd
) {
556 if ((ch
= cmd
[0]) == vlit
&& cmdlen
> 1) {
558 if (ch
== '\n' || ch
== '|') {
566 } else if (ch
== '\n' || ch
== '|') {
576 * Save off the next command information, go back to the
577 * original start of the command.
582 save_cmdlen
= cmdlen
;
583 cmdlen
= ((save_cmd
- cmd
) - 1) - cnt
;
587 * The "set tags" command historically used a backslash, not the
588 * user's literal next character, to escape whitespace. Handle
589 * it here instead of complicating the argv_exp3() code. Note,
590 * this isn't a particularly complex trap, and if backslashes were
591 * legal in set commands, this would have to be much more complicated.
593 if (cp
== &cmds
[C_SET
])
594 for (p
= cmd
, len
= cmdlen
; len
> 0; --len
, ++p
)
599 * Set the default addresses. It's an error to specify an address for
600 * a command that doesn't take them. If two addresses are specified
601 * for a command that only takes one, lose the first one. Two special
602 * cases here, some commands take 0 or 2 addresses. For most of them
603 * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one
604 * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
606 * Also, if the file is empty, some commands want to use an address of
607 * 0, i.e. the entire file is 0 to 0, and the default first address is
608 * 0. Otherwise, an entire file is 1 to N and the default line is 1.
609 * Note, we also add the E_ZERO flag to the command flags, for the case
610 * where the 0 address is only valid if it's a default address.
612 * Also, set a flag if we set the default addresses. Some commands
613 * (ex: z) care if the user specified an address of if we just used
614 * the current cursor.
616 switch (LF_ISSET(E_ADDR1
|E_ADDR2
|E_ADDR2_ALL
|E_ADDR2_NONE
)) {
617 case E_ADDR1
: /* One address: */
618 switch (exc
.addrcnt
) {
619 case 0: /* Default cursor/empty file. */
621 F_SET(&exc
, E_ADDRDEF
);
622 if (LF_ISSET(E_ZERODEF
)) {
623 if (file_lline(sp
, ep
, &lno
))
629 exc
.addr1
.lno
= sp
->lno
;
631 exc
.addr1
.lno
= sp
->lno
;
632 exc
.addr1
.cno
= sp
->cno
;
636 case 2: /* Lose the first address. */
638 exc
.addr1
= exc
.addr2
;
641 case E_ADDR2_NONE
: /* Zero/two addresses: */
642 if (exc
.addrcnt
== 0) /* Default to nothing. */
645 case E_ADDR2_ALL
: /* Zero/two addresses: */
646 if (exc
.addrcnt
== 0) { /* Default entire/empty file. */
648 F_SET(&exc
, E_ADDRDEF
);
649 if (file_lline(sp
, ep
, &exc
.addr2
.lno
))
651 if (LF_ISSET(E_ZERODEF
) && exc
.addr2
.lno
== 0) {
656 exc
.addr1
.cno
= exc
.addr2
.cno
= 0;
657 F_SET(&exc
, E_ADDR2_ALL
);
661 case E_ADDR2
: /* Two addresses: */
662 two
: switch (exc
.addrcnt
) {
663 case 0: /* Default cursor/empty file. */
665 F_SET(&exc
, E_ADDRDEF
);
666 if (LF_ISSET(E_ZERODEF
) && sp
->lno
== 1) {
667 if (file_lline(sp
, ep
, &lno
))
670 exc
.addr1
.lno
= exc
.addr2
.lno
= 0;
673 exc
.addr1
.lno
= exc
.addr2
.lno
= sp
->lno
;
675 exc
.addr1
.lno
= exc
.addr2
.lno
= sp
->lno
;
676 exc
.addr1
.cno
= exc
.addr2
.cno
= sp
->cno
;
678 case 1: /* Default to first address. */
680 exc
.addr2
= exc
.addr1
;
687 if (exc
.addrcnt
) /* Error. */
692 for (p
= cp
->syntax
; *p
!= '\0'; ++p
) {
694 * The write command is sensitive to leading whitespace, e.g.
695 * "write !" is different from "write!". If not the write
696 * command, skip leading whitespace.
698 if (cp
!= &cmds
[C_WRITE
])
699 for (; cmdlen
> 0; --cmdlen
, ++cmd
) {
706 * Quit when reach the end of the command, unless it's a
707 * command that does its own parsing, in which case we want
708 * to build a reasonable argv for it. This code guarantees
709 * that there will be an argv when the function gets called,
710 * so the correct test is for a length of 0, not for the
713 if (cmdlen
== 0 && *p
!= '!' && *p
!= 'S' && *p
!= 's')
721 F_SET(&exc
, E_FORCE
);
724 case '1': /* +, -, #, l, p */
727 * Historically, some flags were ignored depending
728 * on where they occurred in the command line. For
729 * example, in the command, ":3+++p--#", historic vi
730 * acted on the '#' flag, but ignored the '-' flags.
731 * It's unambiguous what the flags mean, so we just
732 * handle them regardless of the stupidity of their
735 for (; cmdlen
; --cmdlen
, ++cmd
)
744 F_SET(&exc
, E_F_HASH
);
747 F_SET(&exc
, E_F_LIST
);
750 F_SET(&exc
, E_F_PRINT
);
756 case '2': /* -, ., +, ^ */
757 case '3': /* -, ., +, ^, = */
758 for (; cmdlen
; --cmdlen
, ++cmd
)
761 F_SET(&exc
, E_F_DASH
);
764 F_SET(&exc
, E_F_DOT
);
767 F_SET(&exc
, E_F_PLUS
);
770 F_SET(&exc
, E_F_CARAT
);
774 F_SET(&exc
, E_F_EQUAL
);
782 case 'b': /* buffer */
784 * Digits can't be buffer names in ex commands, or the
785 * command "d2" would be a delete into buffer '2', and
786 * not a two-line deletion.
788 if (!isdigit(cmd
[0])) {
792 F_SET(&exc
, E_BUFFER
);
795 case 'c': /* count [01+a] */
797 if (!isdigit(*cmd
) &&
798 (*p
!= '+' || (*cmd
!= '+' && *cmd
!= '-')))
800 /* 8-bit XXX */ if ((lno
= strtol(cmd
, &t
, 10)) == 0 && *p
!= '0') {
801 msgq(sp
, M_ERR
, "Count may not be zero.");
807 * Count as address offsets occur in commands taking
808 * two addresses. Historic vi practice was to use
809 * the count as an offset from the *second* address.
811 * Set a count flag; some underlying commands (see
812 * join) do different things with counts than with
816 exc
.addr1
= exc
.addr2
;
817 exc
.addr2
.lno
= exc
.addr1
.lno
+ lno
- 1;
820 F_SET(&exc
, E_COUNT
);
823 if (argv_exp2(sp
, ep
,
824 &exc
, cmd
, cmdlen
, cp
== &cmds
[C_BANG
]))
828 if (ep_line(sp
, ep
, &cur
, &cmd
, &cmdlen
, &tmp
))
830 /* Line specifications are always required. */
833 "%s: bad line specification", cmd
);
836 exc
.lineno
= cur
.lno
;
838 case 'S': /* string, file exp. */
839 if (argv_exp1(sp
, ep
,
840 &exc
, cmd
, cmdlen
, cp
== &cmds
[C_BANG
]))
843 case 's': /* string */
844 if (argv_exp0(sp
, ep
, &exc
, cmd
, cmdlen
))
847 case 'W': /* word string */
851 * Literal next characters escape the following
852 * character. Quoting characters are stripped
853 * here since they are no longer useful.
855 * First there was the word.
857 for (p
= t
= cmd
; cmdlen
> 0; --cmdlen
, ++cmd
) {
858 if ((ch
= *cmd
) == vlit
&& cmdlen
> 1) {
861 } else if (isblank(ch
)) {
868 if (argv_exp0(sp
, ep
, &exc
, t
, p
- t
))
871 /* Delete intervening whitespace. */
872 for (; cmdlen
> 0; --cmdlen
, ++cmd
) {
880 /* Followed by the string. */
881 for (p
= t
= cmd
; cmdlen
> 0; --cmdlen
, ++cmd
, ++p
)
882 if ((ch
= *cmd
) == vlit
&& cmdlen
> 1) {
887 if (argv_exp0(sp
, ep
, &exc
, t
, p
- t
))
891 if (argv_exp3(sp
, ep
, &exc
, cmd
, cmdlen
))
893 countchk
: if (*++p
!= 'N') { /* N */
895 * If a number is specified, must either be
896 * 0 or that number, if optional, and that
897 * number, if required.
900 if ((*++p
!= 'o' || exp
->argsoff
!= 0) &&
907 "Internal syntax table error (%s: %c).",
912 /* Skip trailing whitespace. */
913 for (; cmdlen
; --cmdlen
) {
920 * There shouldn't be anything left, and no more required
921 * fields, i.e neither 'l' or 'r' in the syntax string.
923 if (cmdlen
|| strpbrk(p
, "lr")) {
924 usage
: msgq(sp
, M_ERR
, "Usage: %s.", cp
->usage
);
928 /* Verify that the addresses are legal. */
929 addr2
: switch (exc
.addrcnt
) {
931 if (file_lline(sp
, ep
, &lno
))
934 * Historic ex/vi permitted commands with counts to go past
935 * EOF. So, for example, if the file only had 5 lines, the
936 * ex command "1,6>" would fail, but the command ">300"
937 * would succeed. Since we don't want to have to make all
938 * of the underlying commands handle random line numbers,
941 if (exc
.addr2
.lno
> lno
)
942 if (F_ISSET(&exc
, E_COUNT
))
946 msgq(sp
, M_ERR
, "The file is empty.");
949 "Only %lu line%s in the file",
950 lno
, lno
> 1 ? "s" : "");
957 * If it's a "default vi command", zero is okay. Historic
958 * vi allowed this, note, it's also the hack that allows
959 * "vi + nonexistent_file" to work.
961 if (num
== 0 && (!IN_VI_MODE(sp
) || uselastcmd
!= 1) &&
964 "The %s command doesn't permit an address of 0.",
968 if (file_lline(sp
, ep
, &lno
))
972 msgq(sp
, M_ERR
, "The file is empty.");
974 msgq(sp
, M_ERR
, "Only %lu line%s in the file",
975 lno
, lno
> 1 ? "s" : "");
981 /* If doing a default command, vi just moves to the line. */
982 if (IN_VI_MODE(sp
) && uselastcmd
) {
983 switch (exc
.addrcnt
) {
985 sp
->lno
= exc
.addr2
.lno
? exc
.addr2
.lno
: 1;
986 sp
->cno
= exc
.addr2
.cno
;
989 sp
->lno
= exc
.addr1
.lno
? exc
.addr1
.lno
: 1;
990 sp
->cno
= exc
.addr1
.cno
;
994 cmdlen
= save_cmdlen
;
998 /* Reset "last" command. */
999 if (LF_ISSET(E_SETLAST
))
1002 /* Final setup for the command. */
1005 #if defined(DEBUG) && 0
1006 TRACE(sp
, "ex_cmd: %s", exc
.cmd
->name
);
1007 if (exc
.addrcnt
> 0) {
1008 TRACE(sp
, "\taddr1 %d", exc
.addr1
.lno
);
1009 if (exc
.addrcnt
> 1)
1010 TRACE(sp
, " addr2: %d", exc
.addr2
.lno
);
1014 TRACE(sp
, "\tlineno %d", exc
.lineno
);
1016 TRACE(sp
, "\tflags %0x", exc
.flags
);
1017 if (F_ISSET(&exc
, E_BUFFER
))
1018 TRACE(sp
, "\tbuffer %c", exc
.buffer
);
1021 for (cnt
= 0; cnt
< exc
.argc
; ++cnt
)
1022 TRACE(sp
, "\targ %d: {%s}", cnt
, exc
.argv
[cnt
]);
1026 /* Clear autoprint flag. */
1027 F_CLR(exp
, EX_AUTOPRINT
);
1029 /* Increment the command count if not called from vi. */
1030 if (!IN_VI_MODE(sp
))
1034 * If file state and not doing a global command, log the start of
1037 if (ep
!= NULL
&& !F_ISSET(sp
, S_GLOBAL
))
1038 (void)log_cursor(sp
, ep
);
1040 /* Save the current mode. */
1041 saved_mode
= F_ISSET(sp
, S_SCREENS
| S_MAJOR_CHANGE
);
1043 /* Do the command. */
1044 if ((cp
->fn
)(sp
, ep
, &exc
))
1048 /* Make sure no function left the temporary space locked. */
1049 if (F_ISSET(sp
->gp
, G_TMP_INUSE
)) {
1050 F_CLR(sp
->gp
, G_TMP_INUSE
);
1051 msgq(sp
, M_ERR
, "Error: ex: temporary buffer not released.");
1055 if (saved_mode
!= F_ISSET(sp
, S_SCREENS
| S_MAJOR_CHANGE
)) {
1057 * Only here if the mode of the underlying file changed, e.g.
1058 * the user switched files or is exiting. There are two things
1059 * that we might have to save. First, any "+cmd" field set up
1060 * for an ex/edit command will have to be saved for later, also,
1061 * any not yet executed part of the current ex command.
1063 * :edit +25 file.c|s/abc/ABC/|1
1067 * The historic vi just hung, of course; we handle by
1068 * pushing the keys onto the tty queue. If we're
1069 * switching modes to vi, since the commands are intended
1070 * as ex commands, add the extra characters to make it
1073 * For the fun of it, if you want to see if a vi clone got
1074 * the ex argument parsing right, try:
1076 * echo 'foo|bar' > file1; echo 'foo/bar' > file2;
1078 * :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq
1080 if (arg1_len
== NULL
&& save_cmdlen
== 0)
1082 if (IN_VI_MODE(sp
) && term_push(sp
, "\n", 1, 0, 0))
1084 if (save_cmdlen
!= 0)
1085 if (term_push(sp
, save_cmd
, save_cmdlen
, 0, 0))
1088 if (IN_VI_MODE(sp
) && save_cmdlen
!= 0 &&
1089 term_push(sp
, "|", 1, 0, 0))
1091 if (term_push(sp
, arg1
, arg1_len
, 0, 0))
1094 if (IN_VI_MODE(sp
) && term_push(sp
, ":", 1, 0, 0))
1099 if (IN_EX_MODE(sp
) && ep
!= NULL
) {
1101 * The print commands have already handled the `print' flags.
1102 * If so, clear them. Don't return, autoprint may still have
1103 * stuff to print out.
1105 if (LF_ISSET(E_F_PRCLEAR
))
1106 F_CLR(&exc
, E_F_HASH
| E_F_LIST
| E_F_PRINT
);
1109 * If the command was successful, and there was an explicit
1110 * flag to display the new cursor line, or we're in ex mode,
1111 * autoprint is set, and a change was made, display the line.
1115 if (sp
->lno
< -flagoff
) {
1117 "Flag offset before line 1.");
1121 if (file_lline(sp
, ep
, &lno
))
1123 if (sp
->lno
+ flagoff
> lno
) {
1125 "Flag offset past end-of-file.");
1132 if (O_ISSET(sp
, O_AUTOPRINT
) &&
1133 (F_ISSET(exp
, EX_AUTOPRINT
) || F_ISSET(cp
, E_AUTOPRINT
)))
1136 LF_INIT(F_ISSET(&exc
, E_F_HASH
| E_F_LIST
| E_F_PRINT
));
1138 memset(&exc
, 0, sizeof(EXCMDARG
));
1140 exc
.addr1
.lno
= exc
.addr2
.lno
= sp
->lno
;
1141 exc
.addr1
.cno
= exc
.addr2
.cno
= sp
->cno
;
1142 switch (LF_ISSET(E_F_HASH
| E_F_LIST
| E_F_PRINT
)) {
1144 exc
.cmd
= &cmds
[C_HASH
];
1145 ex_number(sp
, ep
, &exc
);
1148 exc
.cmd
= &cmds
[C_LIST
];
1149 ex_list(sp
, ep
, &exc
);
1152 exc
.cmd
= &cmds
[C_PRINT
];
1153 ex_pr(sp
, ep
, &exc
);
1159 cmdlen
= save_cmdlen
;
1164 * On error, we discard any keys we have left, as well as any keys
1165 * that were mapped. The test of save_cmdlen isn't necessarily
1166 * correct. If we fail early enough we don't know if the entire
1167 * string was a single command or not. Try and guess, it's useful
1168 * to know if part of the command was discarded.
1170 if (save_cmdlen
== 0)
1171 for (; cmdlen
; --cmdlen
)
1172 if ((ch
= *cmd
++) == vlit
&& cmdlen
> 1) {
1175 } else if (ch
== '\n' || ch
== '|') {
1180 if (save_cmdlen
!= 0)
1182 "Ex command failed: remaining command input discarded.");
1183 err
: term_map_flush(sp
, "Ex command failed");
1189 * Get a line range for ex commands.
1192 ep_range(sp
, ep
, excp
, cmdp
, cmdlenp
)
1199 MARK cur
, savecursor
;
1201 int savecursor_set
, tmp
;
1204 /* Percent character is all lines in the file. */
1208 excp
->addr1
.lno
= 1;
1209 if (file_lline(sp
, ep
, &excp
->addr2
.lno
))
1212 /* If an empty file, then the first line is 0, not 1. */
1213 if (excp
->addr2
.lno
== 0)
1214 excp
->addr1
.lno
= 0;
1215 excp
->addr1
.cno
= excp
->addr2
.cno
= 0;
1223 /* Parse comma or semi-colon delimited line specs. */
1224 for (savecursor_set
= 0, excp
->addrcnt
= 0; cmdlen
> 0;)
1226 case ';': /* Semi-colon delimiter. */
1228 * Comma delimiters delimit; semi-colon delimiters
1229 * change the current address for the 2nd address
1230 * to be the first address. Trailing or multiple
1231 * delimiters are discarded.
1233 if (excp
->addrcnt
== 0)
1235 if (!savecursor_set
) {
1236 savecursor
.lno
= sp
->lno
;
1237 savecursor
.cno
= sp
->cno
;
1238 sp
->lno
= excp
->addr1
.lno
;
1239 sp
->cno
= excp
->addr1
.cno
;
1245 case ',': /* Comma delimiter. */
1246 /* If no addresses yet, defaults to ".". */
1247 if (excp
->addrcnt
== 0) {
1248 excp
->addr1
.lno
= sp
->lno
;
1249 excp
->addr1
.cno
= sp
->cno
;
1253 case ' ': /* Whitespace. */
1254 case '\t': /* Whitespace. */
1259 if (ep_line(sp
, ep
, &cur
, &cmd
, &cmdlen
, &tmp
))
1265 * Extra addresses are discarded, starting with
1268 switch (excp
->addrcnt
) {
1278 excp
->addr1
= excp
->addr2
;
1287 * This is probably not right behavior for savecursor -- need
1288 * to figure out what the historical ex did for ";,;,;5p" or
1289 * similar stupidity.
1291 done
: if (savecursor_set
) {
1292 sp
->lno
= savecursor
.lno
;
1293 sp
->cno
= savecursor
.cno
;
1295 if (excp
->addrcnt
== 2 &&
1296 (excp
->addr2
.lno
< excp
->addr1
.lno
||
1297 excp
->addr2
.lno
== excp
->addr1
.lno
&&
1298 excp
->addr2
.cno
< excp
->addr1
.cno
)) {
1300 "The second address is smaller than the first.");
1309 * Get a single line address specifier.
1312 ep_line(sp
, ep
, cur
, cmdp
, cmdlenp
, addr_found
)
1331 case '$': /* Last line in the file. */
1334 if (file_lline(sp
, ep
, &cur
->lno
))
1338 break; /* Absolute line number. */
1339 case '0': case '1': case '2': case '3': case '4':
1340 case '5': case '6': case '7': case '8': case '9':
1343 * The way the vi "previous context" mark worked was that
1344 * "non-relative" motions set it. While vi wasn't totally
1345 * consistent about this, ANY numeric address was considered
1346 * non-relative, and set the value. Which is why we're
1347 * hacking marks down here.
1349 if (IN_VI_MODE(sp
)) {
1352 if (mark_set(sp
, ep
, ABSMARK1
, &m
, 1))
1356 /* 8-bit XXX */ cur
->lno
= strtol(cmd
, &endp
, 10);
1357 cmdlen
-= (endp
- cmd
);
1360 case '\'': /* Use a mark. */
1363 msgq(sp
, M_ERR
, "No mark name supplied.");
1366 if ((mp
= mark_get(sp
, ep
, cmd
[1])) == NULL
)
1372 case '\\': /* Search: forward/backward. */
1375 * I can't find any difference between // and \/ or
1376 * between ?? and \?. Mark Horton doesn't remember
1377 * there being any difference. C'est la vie.
1379 if (cmdlen
< 2 || cmd
[1] != '/' && cmd
[1] != '?') {
1380 msgq(sp
, M_ERR
, "\\ not followed by / or ?.");
1390 case '/': /* Search forward. */
1391 forward
: *addr_found
= 1;
1394 flags
= SEARCH_MSG
| SEARCH_PARSE
| SEARCH_SET
;
1395 if (f_search(sp
, ep
, &m
, &m
, cmd
, &endp
, &flags
))
1399 cmdlen
-= (endp
- cmd
);
1402 case '?': /* Search backward. */
1403 backward
: *addr_found
= 1;
1406 flags
= SEARCH_MSG
| SEARCH_PARSE
| SEARCH_SET
;
1407 if (b_search(sp
, ep
, &m
, &m
, cmd
, &endp
, &flags
))
1411 cmdlen
-= (endp
- cmd
);
1414 case '.': /* Current position. */
1418 /* If an empty file, then '.' is 0, not 1. */
1420 if (file_lline(sp
, ep
, &cur
->lno
))
1432 * Evaluate any offset. Offsets are +/- any number, or any number
1433 * of +/- signs, or any combination thereof. If no address found
1434 * yet, offset is relative to ".".
1436 for (total
= 0; cmdlen
> 0 && (cmd
[0] == '-' || cmd
[0] == '+');) {
1443 if (cmdlen
> 1 && isdigit(cmd
[1])) {
1444 /* 8-bit XXX */ total
+= strtol(cmd
, &endp
, 10);
1445 cmdlen
-= (endp
- cmd
);
1448 total
+= cmd
[0] == '-' ? -1 : 1;
1453 if (total
< 0 && -total
> cur
->lno
) {
1454 msgq(sp
, M_ERR
, "Reference to a line number less than 0.");
1466 * The vi text input routine needs to know if ex thinks this is
1467 * an [un]abbreviate command, so it can turn off abbreviations.
1468 * Usual ranting in the vi/v_ntext:txt_abbrev() routine.
1471 ex_is_abbrev(name
, len
)
1475 EXCMDLIST
const *cp
;
1477 return ((cp
= ex_comm_search(name
, len
)) != NULL
&&
1478 (cp
== &cmds
[C_ABBR
] || cp
== &cmds
[C_UNABBREVIATE
]));
1481 static inline EXCMDLIST
const *
1482 ex_comm_search(name
, len
)
1486 EXCMDLIST
const *cp
;
1488 for (cp
= cmds
; cp
->name
!= NULL
; ++cp
) {
1489 if (cp
->name
[0] > name
[0])
1491 if (cp
->name
[0] != name
[0])
1493 if (!memcmp(name
, cp
->name
, len
))