summaryrefslogtreecommitdiffstats
path: root/usr.bin/vi/ex
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/vi/ex')
-rw-r--r--usr.bin/vi/ex/ex.c1866
-rw-r--r--usr.bin/vi/ex/ex_abbrev.c129
-rw-r--r--usr.bin/vi/ex/ex_append.c220
-rw-r--r--usr.bin/vi/ex/ex_args.c263
-rw-r--r--usr.bin/vi/ex/ex_argv.c609
-rw-r--r--usr.bin/vi/ex/ex_at.c118
-rw-r--r--usr.bin/vi/ex/ex_bang.c242
-rw-r--r--usr.bin/vi/ex/ex_cd.c223
-rw-r--r--usr.bin/vi/ex/ex_delete.c92
-rw-r--r--usr.bin/vi/ex/ex_digraph.c324
-rw-r--r--usr.bin/vi/ex/ex_display.c169
-rw-r--r--usr.bin/vi/ex/ex_edit.c122
-rw-r--r--usr.bin/vi/ex/ex_equal.c86
-rw-r--r--usr.bin/vi/ex/ex_exit.c79
-rw-r--r--usr.bin/vi/ex/ex_file.c103
-rw-r--r--usr.bin/vi/ex/ex_global.c400
-rw-r--r--usr.bin/vi/ex/ex_init.c202
-rw-r--r--usr.bin/vi/ex/ex_join.c200
-rw-r--r--usr.bin/vi/ex/ex_map.c160
-rw-r--r--usr.bin/vi/ex/ex_mark.c66
-rw-r--r--usr.bin/vi/ex/ex_mkexrc.c130
-rw-r--r--usr.bin/vi/ex/ex_move.c222
-rw-r--r--usr.bin/vi/ex/ex_open.c75
-rw-r--r--usr.bin/vi/ex/ex_preserve.c128
-rw-r--r--usr.bin/vi/ex/ex_print.c212
-rw-r--r--usr.bin/vi/ex/ex_put.c78
-rw-r--r--usr.bin/vi/ex/ex_read.c300
-rw-r--r--usr.bin/vi/ex/ex_screen.c155
-rw-r--r--usr.bin/vi/ex/ex_script.c582
-rw-r--r--usr.bin/vi/ex/ex_set.c70
-rw-r--r--usr.bin/vi/ex/ex_shell.c150
-rw-r--r--usr.bin/vi/ex/ex_shift.c204
-rw-r--r--usr.bin/vi/ex/ex_source.c66
-rw-r--r--usr.bin/vi/ex/ex_stop.c76
-rw-r--r--usr.bin/vi/ex/ex_subst.c1001
-rw-r--r--usr.bin/vi/ex/ex_tag.c905
-rw-r--r--usr.bin/vi/ex/ex_undo.c103
-rw-r--r--usr.bin/vi/ex/ex_usage.c197
-rw-r--r--usr.bin/vi/ex/ex_util.c189
-rw-r--r--usr.bin/vi/ex/ex_version.c71
-rw-r--r--usr.bin/vi/ex/ex_visual.c137
-rw-r--r--usr.bin/vi/ex/ex_write.c327
-rw-r--r--usr.bin/vi/ex/ex_yank.c69
-rw-r--r--usr.bin/vi/ex/ex_z.c180
-rw-r--r--usr.bin/vi/ex/excmd.awk6
-rw-r--r--usr.bin/vi/ex/excmd.c458
-rw-r--r--usr.bin/vi/ex/excmd.h.stub285
-rw-r--r--usr.bin/vi/ex/filter.c414
-rw-r--r--usr.bin/vi/ex/script.h45
-rw-r--r--usr.bin/vi/ex/tag.h58
50 files changed, 0 insertions, 12566 deletions
diff --git a/usr.bin/vi/ex/ex.c b/usr.bin/vi/ex/ex.c
deleted file mode 100644
index 77666ca0..0000000
--- a/usr.bin/vi/ex/ex.c
+++ /dev/null
@@ -1,1866 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex.c 8.157 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-static void badlno __P((SCR *, recno_t));
-static __inline EXCMDLIST const *
- ex_comm_search __P((char *, size_t));
-static int ep_line __P((SCR *, EXF *, MARK *, char **, size_t *, int *));
-static int ep_range __P((SCR *, EXF *, EXCMDARG *, char **, size_t *));
-
-/*
- * ex --
- * Read an ex command and execute it.
- */
-int
-ex(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- enum input irval;
- TEXT *tp;
- u_int flags, saved_mode;
- int eval;
-
- if (ex_init(sp, ep))
- return (1);
-
- if (sp->s_refresh(sp, ep))
- return (ex_end(sp));
-
- /* If reading from a file, messages should have line info. */
- if (!F_ISSET(sp->gp, G_STDIN_TTY)) {
- sp->if_lno = 1;
- sp->if_name = strdup("input");
- }
-
- /*
- * !!!
- * Historically, the beautify option applies to ex command input read
- * from a file. In addition, the first time a ^H was discarded from
- * the input, a message "^H discarded" was displayed. We don't bother.
- */
- LF_INIT(TXT_BACKSLASH | TXT_CNTRLD | TXT_CR | TXT_EXSUSPEND);
-
- for (eval = 0;; ++sp->if_lno) {
- /* Set the flags that the user can change. */
- if (O_ISSET(sp, O_BEAUTIFY))
- LF_SET(TXT_BEAUTIFY);
- else
- LF_CLR(TXT_BEAUTIFY);
- if (O_ISSET(sp, O_PROMPT))
- LF_SET(TXT_PROMPT);
- else
- LF_CLR(TXT_PROMPT);
-
- /*
- * Get the next command. Interrupt flag manipulation is
- * safe because ex_icmd clears them all.
- */
- CLR_INTERRUPT(sp);
- F_SET(sp, S_INTERRUPTIBLE);
- irval = sp->s_get(sp, ep, sp->tiqp, ':', flags);
- if (INTERRUPTED(sp)) {
- (void)fputc('\n', stdout);
- (void)fflush(stdout);
- goto refresh;
- }
- switch (irval) {
- case INP_OK:
- break;
- case INP_EOF:
- case INP_ERR:
- F_SET(sp, S_EXIT_FORCE);
- /* FALLTHROUGH */
- case INP_INTR:
- goto ret;
- }
-
- /*
- * If the user entered a carriage return, send ex_cmd()
- * a separator -- it discards single newlines.
- */
- tp = sp->tiqp->cqh_first;
- if (tp->len == 0) {
- tp->len = 1;
- tp->lb[0] = ' ';
- }
-
- saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
- if (ex_icmd(sp, ep,
- tp->lb, tp->len, 1) && !F_ISSET(sp->gp, G_STDIN_TTY))
- F_SET(sp, S_EXIT_FORCE);
- (void)msg_rpt(sp, 0);
- if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE))
- break;
-
-refresh: if (sp->s_refresh(sp, ep)) {
- eval = 1;
- break;
- }
- }
-ret: if (sp->if_name != NULL) {
- FREE(sp->if_name, strlen(sp->if_name) + 1);
- sp->if_name = NULL;
- }
- return (ex_end(sp) || eval);
-}
-
-/*
- * ex_cfile --
- * Execute ex commands from a file.
- */
-int
-ex_cfile(sp, ep, filename, needsep)
- SCR *sp;
- EXF *ep;
- char *filename;
- int needsep;
-{
- struct stat sb;
- int fd, len, rval;
- char *bp;
-
- bp = NULL;
- if ((fd = open(filename, O_RDONLY, 0)) < 0 || fstat(fd, &sb))
- goto err;
-
- /*
- * XXX
- * We'd like to test if the file is too big to malloc. Since we don't
- * know what size or type off_t's or size_t's are, what the largest
- * unsigned integral type is, or what random insanity the local C
- * compiler will perpetrate, doing the comparison in a portable way
- * is flatly impossible. Hope that malloc fails if the file is too
- * large.
- */
- MALLOC(sp, bp, char *, (size_t)sb.st_size + 1);
- if (bp == NULL)
- goto err;
-
- len = read(fd, bp, (int)sb.st_size);
- if (len == -1 || len != sb.st_size) {
- if (len != sb.st_size)
- errno = EIO;
-err: rval = 1;
- msgq(sp, M_SYSERR, filename);
- } else {
- bp[sb.st_size] = '\0'; /* XXX */
-
- /*
- * Run the command. Messages include file/line information,
- * but we don't care if we can't get space.
- */
- sp->if_lno = 1;
- sp->if_name = strdup(filename);
- F_SET(sp, S_VLITONLY);
- rval = ex_icmd(sp, ep, bp, len, needsep);
- F_CLR(sp, S_VLITONLY);
- free(sp->if_name);
- sp->if_name = NULL;
- }
-
- /*
- * !!!
- * THE UNDERLYING EXF MAY HAVE CHANGED.
- */
- if (bp != NULL)
- FREE(bp, sb.st_size);
- if (fd >= 0)
- (void)close(fd);
- return (rval);
-}
-
-/*
- * ex_icmd --
- * Call ex_cmd() after turning off interruptible bits.
- */
-int
-ex_icmd(sp, ep, cmd, len, needsep)
- SCR *sp;
- EXF *ep;
- char *cmd;
- size_t len;
- int needsep;
-{
- /*
- * Ex goes through here for each vi :colon command and for each ex
- * command, however, globally executed commands don't go through
- * here, instead, they call ex_cmd directly. So, reset all of the
- * interruptible flags now.
- *
- * !!!
- * Previous versions of nvi cleared mapped characters on error. This
- * feature was removed when users complained that it wasn't historic
- * practice.
- */
- CLR_INTERRUPT(sp);
- return (ex_cmd(sp, ep, cmd, len, needsep));
-}
-
-/* Special command structure for :s as a repeat substitution command. */
-static EXCMDLIST const cmd_subagain =
- {"s", ex_subagain, E_ADDR2|E_NORC,
- "s",
- "[line [,line]] s [cgr] [count] [#lp]",
- "repeat the last subsitution"};
-
-/* Special command structure for :d[flags]. */
-static EXCMDLIST const cmd_del2 =
- {"delete", ex_delete, E_ADDR2|E_AUTOPRINT|E_NORC,
- "1bca1",
- "[line [,line]] d[elete][flags] [buffer] [count] [flags]",
- "delete lines from the file"};
-
-/*
- * ex_cmd --
- * Parse and execute a string containing ex commands.
- */
-int
-ex_cmd(sp, ep, cmd, cmdlen, needsep)
- SCR *sp;
- EXF *ep;
- char *cmd;
- size_t cmdlen;
- int needsep;
-{
- enum { NOTSET, NEEDSEP_N, NEEDSEP_NR, NONE } sep;
- EX_PRIVATE *exp;
- EXCMDARG exc;
- EXCMDLIST const *cp;
- MARK cur;
- recno_t lno, num;
- size_t arg1_len, len, save_cmdlen;
- long flagoff;
- u_int saved_mode;
- int blank, ch, cnt, delim, flags, namelen, nl;
- int optnum, uselastcmd, tmp, vi_address;
- char *arg1, *save_cmd, *p, *s, *t;
-
- /* Init. */
- nl = 0;
- sep = needsep ? NOTSET : NONE;
-loop: if (nl) {
- nl = 0;
- ++sp->if_lno;
- }
- arg1 = NULL;
- save_cmdlen = 0;
-
- /* It's possible that we've been interrupted during a command. */
- if (INTERRUPTED(sp))
- return (0);
-
- /* Skip <blank>s, empty lines. */
- for (blank = 0; cmdlen > 0; ++cmd, --cmdlen)
- if ((ch = *cmd) == '\n')
- ++sp->if_lno;
- else if (isblank(ch))
- blank = 1;
- else
- break;
-
- /*
- * !!!
- * Permit extra colons at the start of the line. Historically,
- * ex/vi allowed a single extra one. It's simpler not to count.
- * The stripping is done here because, historically, any command
- * could have preceding colons, e.g. ":g/pattern/:p" worked.
- */
- if (cmdlen != 0 && ch == ':') {
- if (sep == NOTSET)
- sep = NEEDSEP_N;
- while (--cmdlen > 0 && (ch = *++cmd) == ':');
- }
-
- /*
- * Command lines that start with a double-quote are comments.
- *
- * !!!
- * Historically, there was no escape or delimiter for a comment,
- * e.g. :"foo|set was a single comment and nothing was output.
- * Since nvi permits users to escape <newline> characters into
- * command lines, we have to check for that case.
- */
- if (cmdlen != 0 && ch == '"') {
- while (--cmdlen > 0 && *++cmd != '\n');
- if (*cmd == '\n') {
- nl = 1;
- ++cmd;
- --cmdlen;
- }
- goto loop;
- }
-
- /* Skip whitespace. */
- for (; cmdlen > 0; ++cmd, --cmdlen) {
- ch = *cmd;
- if (!isblank(ch))
- break;
- }
-
- /*
- * The last point at which an empty line can mean do nothing.
- *
- * !!!
- * Historically, in ex mode, lines containing only <blank> characters
- * were the same as a single <carriage-return>, i.e. a default command.
- * In vi mode, they were ignored.
- *
- * In .exrc files this was a serious annoyance, as vi kept trying to
- * treat them as print commands. We ignore backward compatibility in
- * this case, and discard lines containing only <blank> characters from
- * .exrc files.
- */
- if (cmdlen == 0 && (!IN_EX_MODE(sp) || ep == NULL || !blank))
- return (0);
-
- /* Initialize the structure passed to underlying functions. */
- memset(&exc, 0, sizeof(EXCMDARG));
- exp = EXP(sp);
- if (argv_init(sp, ep, &exc))
- goto err;
-
- /*
- * Check to see if this is a command for which we may want to output
- * a \r separator instead of a \n. (The command :1<CR> puts out a \n,
- * but the command :<CR> puts out a \r.) If the line is empty except
- * for <blank>s, <carriage-return> or <eof>, we'll probably want to
- * output \r. I don't think there's any way to get <blank> characters
- * *after* the command character, but this is the ex parser, and I've
- * been wrong before.
- */
- if (sep == NOTSET)
- sep = cmdlen == 0 || cmdlen == 1 && cmd[0] == '\004' ?
- NEEDSEP_NR : NEEDSEP_N;
-
- /* Parse command addresses. */
- if (ep_range(sp, ep, &exc, &cmd, &cmdlen))
- goto err;
-
- /* Skip whitespace. */
- for (; cmdlen > 0; ++cmd, --cmdlen) {
- ch = *cmd;
- if (!isblank(ch))
- break;
- }
-
- /*
- * If no command, ex does the last specified of p, l, or #, and vi
- * moves to the line. Otherwise, determine the length of the command
- * name by looking for the first non-alphabetic character. (There
- * are a few non-alphabetic characters in command names, but they're
- * all single character commands.) This isn't a great test, because
- * it means that, for the command ":e +cut.c file", we'll report that
- * the command "cut" wasn't known. However, it makes ":e+35 file" work
- * correctly.
- *
- * !!!
- * Historically, lines with multiple adjacent (or <blank> separated)
- * command separators were very strange. For example, the command
- * |||<carriage-return>, when the cursor was on line 1, displayed
- * lines 2, 3 and 5 of the file. In addition, the command " | "
- * would only display the line after the next line, instead of the
- * next two lines. No ideas why. It worked reasonably when executed
- * from vi mode, and displayed lines 2, 3, and 4, so we do a default
- * command for each separator.
- */
-#define SINGLE_CHAR_COMMANDS "\004!#&*<=>@~"
- if (cmdlen != 0 && cmd[0] != '|' && cmd[0] != '\n') {
- if (strchr(SINGLE_CHAR_COMMANDS, *cmd)) {
- p = cmd;
- ++cmd;
- --cmdlen;
- namelen = 1;
- } else {
- for (p = cmd; cmdlen > 0; --cmdlen, ++cmd)
- if (!isalpha(*cmd))
- break;
- if ((namelen = cmd - p) == 0) {
- msgq(sp, M_ERR, "Unknown command name");
- goto err;
- }
- }
-
- /*
- * !!!
- * Historic vi permitted flags to immediately follow any
- * subset of the 'delete' command, but then did not permit
- * further arguments (flag, buffer, count). Make it work.
- * Permit further arguments for the few shreds of dignity
- * it offers.
- *
- * !!!
- * Note, adding commands that start with 'd', and match
- * "delete" up to a l, p, +, - or # character can break
- * this code.
- */
- if (p[0] == 'd') {
- for (s = p,
- t = cmds[C_DELETE].name; *s == *t; ++s, ++t);
- if (s[0] == 'l' || s[0] == 'p' ||
- s[0] == '+' || s[0] == '-' || s[0] == '#') {
- len = (cmd - p) - (s - p);
- cmd -= len;
- cmdlen += len;
- cp = &cmd_del2;
- goto skip;
- }
- }
-
- /*
- * Search the table for the command.
- *
- * !!!
- * Historic vi permitted the mark to immediately follow the
- * 'k' in the 'k' command. Make it work.
- *
- * !!!
- * Historic vi permitted pretty much anything to follow the
- * substitute command, e.g. "s/e/E/|s|sgc3p" was fine. Make
- * the command "sgc" work.
- */
- if ((cp = ex_comm_search(p, namelen)) == NULL)
- switch (p[0]) {
- case 's':
- cmd -= namelen - 1;
- cmdlen += namelen - 1;
- cp = &cmd_subagain;
- break;
- case 'k':
- if (p[1] && !p[2]) {
- cmd -= namelen - 1;
- cmdlen += namelen - 1;
- cp = &cmds[C_K];
- break;
- }
- /* FALLTHROUGH */
- default:
- msgq(sp, M_ERR,
- "The %.*s command is unknown", namelen, p);
- goto err;
- }
-
- /* Some commands are either not implemented or turned off. */
-skip: if (F_ISSET(cp, E_NOPERM)) {
- msgq(sp, M_ERR,
- "The %s command is not currently supported",
- cp->name);
- goto err;
- }
-
- /* Some commands aren't okay in globals. */
- if (F_ISSET(sp, S_GLOBAL) && F_ISSET(cp, E_NOGLOBAL)) {
- msgq(sp, M_ERR,
- "The %s command can't be used as part of a global command",
- cp->name);
- goto err;
- }
-
- /*
- * Multiple < and > characters; another "feature". Note,
- * The string passed to the underlying function may not be
- * nul terminated in this case.
- */
- if ((cp == &cmds[C_SHIFTL] && *p == '<') ||
- (cp == &cmds[C_SHIFTR] && *p == '>')) {
- for (ch = *p; cmdlen > 0; --cmdlen, ++cmd)
- if (*cmd != ch)
- break;
- if (argv_exp0(sp, ep, &exc, p, cmd - p))
- goto err;
- }
-
- /*
- * The visual command has a different syntax when called
- * from ex than when called from a vi colon command. FMH.
- */
- if (cp == &cmds[C_VISUAL_EX] && IN_VI_MODE(sp))
- cp = &cmds[C_VISUAL_VI];
-
- /* Set the format style flags for the next command. */
- if (cp == &cmds[C_HASH])
- exp->fdef = E_F_HASH;
- else if (cp == &cmds[C_LIST])
- exp->fdef = E_F_LIST;
- else if (cp == &cmds[C_PRINT])
- exp->fdef = E_F_PRINT;
- uselastcmd = 0;
- } else {
- /* Print is the default command. */
- cp = &cmds[C_PRINT];
-
- /* Set the saved format flags. */
- F_SET(&exc, exp->fdef);
-
- /*
- * !!!
- * If no address was specified, and it's not a global command,
- * we up the address by one. (I have not an idea why global
- * commands are exempted, but it's (ahem) historic practice.
- */
- if (exc.addrcnt == 0 && !F_ISSET(sp, S_GLOBAL)) {
- exc.addrcnt = 1;
- exc.addr1.lno = sp->lno + 1;
- exc.addr1.cno = sp->cno;
- }
-
- uselastcmd = 1;
- }
-
- /*
- * !!!
- * Historically, the number option applied to both ex and vi. One
- * strangeness was that ex didn't switch display formats until a
- * command was entered, e.g. <CR>'s after the set didn't change to
- * the new format, but :1p would.
- */
- if (O_ISSET(sp, O_NUMBER)) {
- optnum = 1;
- F_SET(&exc, E_F_HASH);
- } else
- optnum = 0;
-
- /* Initialize local flags to the command flags. */
- LF_INIT(cp->flags);
-
- /*
- * File state must be checked throughout this code, because it is
- * called when reading the .exrc file and similar things. There's
- * this little chicken and egg problem -- if we read the file first,
- * we won't know how to display it. If we read/set the exrc stuff
- * first, we can't allow any command that requires file state. We
- * don't have a "reading an rc" bit, because we want the commands
- * to work when the user source's the rc file later. Historic vi
- * generally took the easy way out and dropped core.
- */
- if (LF_ISSET(E_NORC) && ep == NULL) {
- msgq(sp, M_ERR,
- "The %s command requires that a file have already been read in",
- cp->name);
- goto err;
- }
-
- /*
- * There are three normal termination cases for an ex command. They
- * are the end of the string (cmdlen), or unescaped (by literal next
- * characters) newline or '|' characters. As we're past any addresses,
- * we can now determine how long the command is, so we don't have to
- * look for all the possible terminations. There are three exciting
- * special cases:
- *
- * 1: The bang, global, vglobal and the filter versions of the read and
- * write commands are delimited by newlines (they can contain shell
- * pipes).
- * 2: The ex, edit, next and visual in vi mode commands all take ex
- * commands as their first arguments.
- * 3: The substitute command takes an RE as its first argument, and
- * wants it to be specially delimited.
- *
- * Historically, '|' characters in the first argument of the ex, edit,
- * next, vi visual, and substitute commands didn't delimit the command.
- * And, in the filter cases for read and write, and the bang, global
- * and vglobal commands, they did not delimit the command at all.
- *
- * For example, the following commands were legal:
- *
- * :edit +25|s/abc/ABC/ file.c
- * :substitute s/|/PIPE/
- * :read !spell % | columnate
- * :global/pattern/p|l
- *
- * It's not quite as simple as it sounds, however. The command:
- *
- * :substitute s/a/b/|s/c/d|set
- *
- * was also legal, i.e. the historic ex parser (using the word loosely,
- * since "parser" implies some regularity) delimited the RE's based on
- * its delimiter and not anything so irretrievably vulgar as a command
- * syntax.
- *
- * One thing that makes this easier is that we can ignore most of the
- * command termination conditions for the commands that want to take
- * the command up to the next newline. None of them are legal in .exrc
- * files, so if we're here, we only dealing with a single line, and we
- * can just eat it.
- *
- * Anyhow, the following code makes this all work. First, for the
- * special cases we move past their special argument(s). Then, we
- * do normal command processing on whatever is left. Barf-O-Rama.
- */
- arg1_len = 0;
- save_cmd = cmd;
- if (cp == &cmds[C_EDIT] || cp == &cmds[C_EX] ||
- cp == &cmds[C_NEXT] || cp == &cmds[C_VISUAL_VI]) {
- /*
- * Move to the next non-whitespace character. A '!'
- * immediately following the command is eaten as a
- * force flag.
- */
- if (cmdlen > 0 && *cmd == '!') {
- ++cmd;
- --cmdlen;
- F_SET(&exc, E_FORCE);
-
- /* Reset, don't reparse. */
- save_cmd = cmd;
- }
- for (tmp = 0; cmdlen > 0; --cmdlen, ++cmd)
- if (!isblank(*cmd))
- break;
- /*
- * QUOTING NOTE:
- *
- * The historic implementation ignored all escape characters
- * so there was no way to put a space or newline into the +cmd
- * field. We do a simplistic job of fixing it by moving to the
- * first whitespace character that isn't escaped by a literal
- * next character. The literal next characters are stripped
- * as they're no longer useful.
- */
- if (cmdlen > 0 && *cmd == '+') {
- ++cmd;
- --cmdlen;
- for (arg1 = p = cmd; cmdlen > 0; --cmdlen, ++cmd) {
- ch = *cmd;
- if (IS_ESCAPE(sp, ch) && cmdlen > 1) {
- --cmdlen;
- ch = *++cmd;
- } else if (isblank(ch))
- break;
- *p++ = ch;
- }
- arg1_len = cmd - arg1;
-
- /* Reset, so the first argument isn't reparsed. */
- save_cmd = cmd;
- }
- } else if (cp == &cmds[C_BANG] ||
- cp == &cmds[C_GLOBAL] || cp == &cmds[C_VGLOBAL]) {
- cmd += cmdlen;
- cmdlen = 0;
- } else if (cp == &cmds[C_READ] || cp == &cmds[C_WRITE]) {
- /*
- * Move to the next character. If it's a '!', it's a filter
- * command and we want to eat it all, otherwise, we're done.
- */
- for (; cmdlen > 0; --cmdlen, ++cmd) {
- ch = *cmd;
- if (!isblank(ch))
- break;
- }
- if (cmdlen > 0 && ch == '!') {
- cmd += cmdlen;
- cmdlen = 0;
- }
- } else if (cp == &cmds[C_SUBSTITUTE]) {
- /*
- * Move to the next non-whitespace character, we'll use it as
- * the delimiter. If the character isn't an alphanumeric or
- * a '|', it's the delimiter, so parse it. Otherwise, we're
- * into something like ":s g", so use the special substitute
- * command.
- */
- for (; cmdlen > 0; --cmdlen, ++cmd)
- if (!isblank(cmd[0]))
- break;
-
- if (isalnum(cmd[0]) || cmd[0] == '|')
- cp = &cmd_subagain;
- else if (cmdlen > 0) {
- /*
- * QUOTING NOTE:
- *
- * Backslashes quote delimiter characters for RE's.
- * The backslashes are NOT removed since they'll be
- * used by the RE code. Move to the third delimiter
- * that's not escaped (or the end of the command).
- */
- delim = *cmd;
- ++cmd;
- --cmdlen;
- for (cnt = 2; cmdlen > 0 && cnt; --cmdlen, ++cmd)
- if (cmd[0] == '\\' && cmdlen > 1) {
- ++cmd;
- --cmdlen;
- } else if (cmd[0] == delim)
- --cnt;
- }
- }
- /*
- * Use normal quoting and termination rules to find the end of this
- * command.
- *
- * QUOTING NOTE:
- *
- * Historically, vi permitted ^V's to escape <newline>'s in the .exrc
- * file. It was almost certainly a bug, but that's what bug-for-bug
- * compatibility means, Grasshopper. Also, ^V's escape the command
- * delimiters. Literal next quote characters in front of the newlines,
- * '|' characters or literal next characters are stripped as as they're
- * no longer useful.
- */
- vi_address = cmdlen != 0 && cmd[0] != '\n';
- for (p = cmd, cnt = 0; cmdlen > 0; --cmdlen, ++cmd) {
- ch = cmd[0];
- if (IS_ESCAPE(sp, ch) && cmdlen > 1) {
- tmp = cmd[1];
- if (tmp == '\n' || tmp == '|') {
- if (tmp == '\n')
- ++sp->if_lno;
- --cmdlen;
- ++cmd;
- ++cnt;
- ch = tmp;
- }
- } else if (ch == '\n' || ch == '|') {
- if (ch == '\n')
- nl = 1;
- --cmdlen;
- break;
- }
- *p++ = ch;
- }
-
- /*
- * Save off the next command information, go back to the
- * original start of the command.
- */
- p = cmd + 1;
- cmd = save_cmd;
- save_cmd = p;
- save_cmdlen = cmdlen;
- cmdlen = ((save_cmd - cmd) - 1) - cnt;
-
- /*
- * !!!
- * The "set tags" command historically used a backslash, not the
- * user's literal next character, to escape whitespace. Handle
- * it here instead of complicating the argv_exp3() code. Note,
- * this isn't a particularly complex trap, and if backslashes were
- * legal in set commands, this would have to be much more complicated.
- */
- if (cp == &cmds[C_SET])
- for (p = cmd, len = cmdlen; len > 0; --len, ++p)
- if (*p == '\\')
- *p = CH_LITERAL;
-
- /*
- * Set the default addresses. It's an error to specify an address for
- * a command that doesn't take them. If two addresses are specified
- * for a command that only takes one, lose the first one. Two special
- * cases here, some commands take 0 or 2 addresses. For most of them
- * (the E_ADDR2_ALL flag), 0 defaults to the entire file. For one
- * (the `!' command, the E_ADDR2_NONE flag), 0 defaults to no lines.
- *
- * Also, if the file is empty, some commands want to use an address of
- * 0, i.e. the entire file is 0 to 0, and the default first address is
- * 0. Otherwise, an entire file is 1 to N and the default line is 1.
- * Note, we also add the E_ZERO flag to the command flags, for the case
- * where the 0 address is only valid if it's a default address.
- *
- * Also, set a flag if we set the default addresses. Some commands
- * (ex: z) care if the user specified an address of if we just used
- * the current cursor.
- */
- switch (LF_ISSET(E_ADDR1|E_ADDR2|E_ADDR2_ALL|E_ADDR2_NONE)) {
- case E_ADDR1: /* One address: */
- switch (exc.addrcnt) {
- case 0: /* Default cursor/empty file. */
- exc.addrcnt = 1;
- F_SET(&exc, E_ADDRDEF);
- if (LF_ISSET(E_ZERODEF)) {
- if (file_lline(sp, ep, &lno))
- goto err;
- if (lno == 0) {
- exc.addr1.lno = 0;
- LF_SET(E_ZERO);
- } else
- exc.addr1.lno = sp->lno;
- } else
- exc.addr1.lno = sp->lno;
- exc.addr1.cno = sp->cno;
- break;
- case 1:
- break;
- case 2: /* Lose the first address. */
- exc.addrcnt = 1;
- exc.addr1 = exc.addr2;
- }
- break;
- case E_ADDR2_NONE: /* Zero/two addresses: */
- if (exc.addrcnt == 0) /* Default to nothing. */
- break;
- goto two;
- case E_ADDR2_ALL: /* Zero/two addresses: */
- if (exc.addrcnt == 0) { /* Default entire/empty file. */
- exc.addrcnt = 2;
- F_SET(&exc, E_ADDRDEF);
- if (file_lline(sp, ep, &exc.addr2.lno))
- goto err;
- if (LF_ISSET(E_ZERODEF) && exc.addr2.lno == 0) {
- exc.addr1.lno = 0;
- LF_SET(E_ZERO);
- } else
- exc.addr1.lno = 1;
- exc.addr1.cno = exc.addr2.cno = 0;
- F_SET(&exc, E_ADDR2_ALL);
- break;
- }
- /* FALLTHROUGH */
- case E_ADDR2: /* Two addresses: */
-two: switch (exc.addrcnt) {
- case 0: /* Default cursor/empty file. */
- exc.addrcnt = 2;
- F_SET(&exc, E_ADDRDEF);
- if (LF_ISSET(E_ZERODEF) && sp->lno == 1) {
- if (file_lline(sp, ep, &lno))
- goto err;
- if (lno == 0) {
- exc.addr1.lno = exc.addr2.lno = 0;
- LF_SET(E_ZERO);
- } else
- exc.addr1.lno = exc.addr2.lno = sp->lno;
- } else
- exc.addr1.lno = exc.addr2.lno = sp->lno;
- exc.addr1.cno = exc.addr2.cno = sp->cno;
- break;
- case 1: /* Default to first address. */
- exc.addrcnt = 2;
- exc.addr2 = exc.addr1;
- break;
- case 2:
- break;
- }
- break;
- default:
- if (exc.addrcnt) /* Error. */
- goto usage;
- }
-
- /*
- * !!!
- * The ^D scroll command historically scrolled the value of the scroll
- * option or to EOF. It was an error if the cursor was already at EOF.
- * (Leading addresses were permitted, but were then ignored.)
- */
- if (cp == &cmds[C_SCROLL]) {
- exc.addrcnt = 2;
- exc.addr1.lno = sp->lno + 1;
- exc.addr2.lno = sp->lno + O_VAL(sp, O_SCROLL);
- exc.addr1.cno = exc.addr2.cno = sp->cno;
- if (file_lline(sp, ep, &lno))
- goto err;
- if (lno != 0 && lno > sp->lno && exc.addr2.lno > lno)
- exc.addr2.lno = lno;
- }
-
- flagoff = 0;
- for (p = cp->syntax; *p != '\0'; ++p) {
- /*
- * The force flag is sensitive to leading whitespace, i.e.
- * "next !" is different from "next!". Handle it before
- * skipping leading <blank>s.
- */
- if (*p == '!') {
- if (cmdlen > 0 && *cmd == '!') {
- ++cmd;
- --cmdlen;
- F_SET(&exc, E_FORCE);
- }
- continue;
- }
-
- /* Skip leading <blank>s. */
- for (; cmdlen > 0; --cmdlen, ++cmd)
- if (!isblank(*cmd))
- break;
-
- /*
- * Quit when reach the end of the command, unless it's a
- * command that does its own parsing, in which case we want
- * to build a reasonable argv for it. This code guarantees
- * that there will be an argv when the function gets called,
- * so the correct test is for a length of 0, not for the
- * argc > 0. Since '!' can precede commands that do their
- * own parsing, we have to have already handled it.
- */
- if (cmdlen == 0 && *p != 'S' && *p != 's')
- break;
-
- switch (*p) {
- case '1': /* +, -, #, l, p */
- /*
- * !!!
- * Historically, some flags were ignored depending
- * on where they occurred in the command line. For
- * example, in the command, ":3+++p--#", historic vi
- * acted on the '#' flag, but ignored the '-' flags.
- * It's unambiguous what the flags mean, so we just
- * handle them regardless of the stupidity of their
- * location.
- */
- for (; cmdlen; --cmdlen, ++cmd)
- switch (*cmd) {
- case '+':
- ++flagoff;
- break;
- case '-':
- --flagoff;
- break;
- case '#':
- optnum = 0;
- F_SET(&exc, E_F_HASH);
- exp->fdef |= E_F_HASH;
- break;
- case 'l':
- F_SET(&exc, E_F_LIST);
- exp->fdef |= E_F_LIST;
- break;
- case 'p':
- F_SET(&exc, E_F_PRINT);
- exp->fdef |= E_F_PRINT;
- break;
- default:
- goto end1;
- }
-end1: break;
- case '2': /* -, ., +, ^ */
- case '3': /* -, ., +, ^, = */
- for (; cmdlen; --cmdlen, ++cmd)
- switch (*cmd) {
- case '-':
- F_SET(&exc, E_F_DASH);
- break;
- case '.':
- F_SET(&exc, E_F_DOT);
- break;
- case '+':
- F_SET(&exc, E_F_PLUS);
- break;
- case '^':
- F_SET(&exc, E_F_CARAT);
- break;
- case '=':
- if (*p == '3') {
- F_SET(&exc, E_F_EQUAL);
- break;
- }
- /* FALLTHROUGH */
- default:
- goto end2;
- }
-end2: break;
- case 'b': /* buffer */
- /*
- * !!!
- * Historically, "d #" was a delete with a flag, not a
- * delete into the '#' buffer. If the current command
- * permits a flag, don't use one as a buffer. However,
- * the 'l' and 'p' flags were legal buffer names in the
- * historic ex, and were used as buffers, not flags.
- */
- if ((cmd[0] == '+' || cmd[0] == '-' || cmd[0] == '#') &&
- strchr(p, '1') != NULL)
- break;
- /*
- * !!!
- * Digits can't be buffer names in ex commands, or the
- * command "d2" would be a delete into buffer '2', and
- * not a two-line deletion.
- */
- if (!isdigit(cmd[0])) {
- exc.buffer = *cmd;
- ++cmd;
- --cmdlen;
- F_SET(&exc, E_BUFFER);
- }
- break;
- case 'c': /* count [01+a] */
- ++p;
- /* Validate any signed value. */
- if (!isdigit(*cmd) &&
- (*p != '+' || (*cmd != '+' && *cmd != '-')))
- break;
- /* If a signed value, set appropriate flags. */
- if (*cmd == '-')
- F_SET(&exc, E_COUNT_NEG);
- else if (*cmd == '+')
- F_SET(&exc, E_COUNT_POS);
-/* 8-bit XXX */ if ((lno = strtol(cmd, &t, 10)) == 0 && *p != '0') {
- msgq(sp, M_ERR, "Count may not be zero");
- goto err;
- }
- cmdlen -= (t - cmd);
- cmd = t;
- /*
- * Count as address offsets occur in commands taking
- * two addresses. Historic vi practice was to use
- * the count as an offset from the *second* address.
- *
- * Set a count flag; some underlying commands (see
- * join) do different things with counts than with
- * line addresses.
- */
- if (*p == 'a') {
- exc.addr1 = exc.addr2;
- exc.addr2.lno = exc.addr1.lno + lno - 1;
- } else
- exc.count = lno;
- F_SET(&exc, E_COUNT);
- break;
- case 'f': /* file */
- if (argv_exp2(sp, ep,
- &exc, cmd, cmdlen, cp == &cmds[C_BANG]))
- goto err;
- goto countchk;
- case 'l': /* line */
- if (ep_line(sp, ep, &cur, &cmd, &cmdlen, &tmp))
- goto err;
- /* Line specifications are always required. */
- if (!tmp) {
- msgq(sp, M_ERR,
- "%s: bad line specification", cmd);
- goto err;
- }
- /* The line must exist for these commands. */
- if (file_lline(sp, ep, &lno))
- goto err;
- if (cur.lno > lno) {
- badlno(sp, lno);
- goto err;
- }
- exc.lineno = cur.lno;
- break;
- case 'S': /* string, file exp. */
- if (argv_exp1(sp, ep,
- &exc, cmd, cmdlen, cp == &cmds[C_BANG]))
- goto err;
- goto addr2;
- case 's': /* string */
- if (argv_exp0(sp, ep, &exc, cmd, cmdlen))
- goto err;
- goto addr2;
- case 'W': /* word string */
- /*
- * QUOTING NOTE:
- *
- * Literal next characters escape the following
- * character. Quoting characters are stripped
- * here since they are no longer useful.
- *
- * First there was the word.
- */
- for (p = t = cmd; cmdlen > 0; --cmdlen, ++cmd) {
- ch = *cmd;
- if (IS_ESCAPE(sp, ch) && cmdlen > 1) {
- --cmdlen;
- *p++ = *++cmd;
- } else if (isblank(ch)) {
- ++cmd;
- --cmdlen;
- break;
- } else
- *p++ = ch;
- }
- if (argv_exp0(sp, ep, &exc, t, p - t))
- goto err;
-
- /* Delete intervening whitespace. */
- for (; cmdlen > 0; --cmdlen, ++cmd) {
- ch = *cmd;
- if (!isblank(ch))
- break;
- }
- if (cmdlen == 0)
- goto usage;
-
- /* Followed by the string. */
- for (p = t = cmd; cmdlen > 0; --cmdlen, ++cmd, ++p) {
- ch = *cmd;
- if (IS_ESCAPE(sp, ch) && cmdlen > 1) {
- --cmdlen;
- *p = *++cmd;
- } else
- *p = ch;
- }
- if (argv_exp0(sp, ep, &exc, t, p - t))
- goto err;
- goto addr2;
- case 'w': /* word */
- if (argv_exp3(sp, ep, &exc, cmd, cmdlen))
- goto err;
-countchk: if (*++p != 'N') { /* N */
- /*
- * If a number is specified, must either be
- * 0 or that number, if optional, and that
- * number, if required.
- */
- num = *p - '0';
- if ((*++p != 'o' || exp->argsoff != 0) &&
- exp->argsoff != num)
- goto usage;
- }
- goto addr2;
- default:
- msgq(sp, M_ERR,
- "Internal syntax table error (%s: %c)",
- cp->name, *p);
- }
- }
-
- /* Skip trailing whitespace. */
- for (; cmdlen; --cmdlen) {
- ch = *cmd++;
- if (!isblank(ch))
- break;
- }
-
- /*
- * There shouldn't be anything left, and no more required
- * fields, i.e neither 'l' or 'r' in the syntax string.
- */
- if (cmdlen || strpbrk(p, "lr")) {
-usage: msgq(sp, M_ERR, "Usage: %s", cp->usage);
- goto err;
- }
-
- /* Verify that the addresses are legal. */
-addr2: switch (exc.addrcnt) {
- case 2:
- if (file_lline(sp, ep, &lno))
- goto err;
- /*
- * Historic ex/vi permitted commands with counts to go past
- * EOF. So, for example, if the file only had 5 lines, the
- * ex command "1,6>" would fail, but the command ">300"
- * would succeed. Since we don't want to have to make all
- * of the underlying commands handle random line numbers,
- * fix it here.
- */
- if (exc.addr2.lno > lno)
- if (F_ISSET(&exc, E_COUNT))
- exc.addr2.lno = lno;
- else {
- badlno(sp, lno);
- goto err;
- }
- /* FALLTHROUGH */
- case 1:
- num = exc.addr1.lno;
- /*
- * If it's a "default vi command", zero is okay. Historic
- * vi allowed this, note, it's also the hack that allows
- * "vi +100 nonexistent_file" to work.
- */
- if (num == 0 && (IN_EX_MODE(sp) || uselastcmd != 1) &&
- !LF_ISSET(E_ZERO)) {
- msgq(sp, M_ERR,
- "The %s command doesn't permit an address of 0",
- cp->name);
- goto err;
- }
- if (file_lline(sp, ep, &lno))
- goto err;
- if (num > lno) {
- badlno(sp, lno);
- goto err;
- }
- break;
- }
-
- /*
- * If doing a default command and there's nothing left on the line,
- * vi just moves to the line. For example, ":3" and ":'a,'b" just
- * move to line 3 and line 'b, respectively, but ":3|" prints line 3.
- *
- * !!!
- * This is done before the absolute mark gets set; historically,
- * "/a/,/b/" did NOT set vi's absolute mark, but "/a/,/b/d" did.
- */
- if (IN_VI_MODE(sp) && uselastcmd && vi_address == 0) {
- switch (exc.addrcnt) {
- case 2:
- sp->lno = exc.addr2.lno ? exc.addr2.lno : 1;
- sp->cno = exc.addr2.cno;
- break;
- case 1:
- sp->lno = exc.addr1.lno ? exc.addr1.lno : 1;
- sp->cno = exc.addr1.cno;
- break;
- }
- cmd = save_cmd;
- cmdlen = save_cmdlen;
- goto loop;
- }
-
- /*
- * Set the absolute mark -- we have to set it for vi here, in case
- * it's a compound command, e.g. ":5p|6" should set the absolute
- * mark for vi.
- */
- if (F_ISSET(exp, EX_ABSMARK)) {
- cur.lno = sp->lno;
- cur.cno = sp->cno;
- F_CLR(exp, EX_ABSMARK);
- if (mark_set(sp, ep, ABSMARK1, &cur, 1))
- goto err;
- }
-
- /* Final setup for the command. */
- exc.cmd = cp;
-
-#if defined(DEBUG) && 0
- TRACE(sp, "ex_cmd: %s", exc.cmd->name);
- if (exc.addrcnt > 0) {
- TRACE(sp, "\taddr1 %d", exc.addr1.lno);
- if (exc.addrcnt > 1)
- TRACE(sp, " addr2: %d", exc.addr2.lno);
- TRACE(sp, "\n");
- }
- if (exc.lineno)
- TRACE(sp, "\tlineno %d", exc.lineno);
- if (exc.flags)
- TRACE(sp, "\tflags %0x", exc.flags);
- if (F_ISSET(&exc, E_BUFFER))
- TRACE(sp, "\tbuffer %c", exc.buffer);
- TRACE(sp, "\n");
- if (exc.argc) {
- for (cnt = 0; cnt < exc.argc; ++cnt)
- TRACE(sp, "\targ %d: {%s}", cnt, exc.argv[cnt]);
- TRACE(sp, "\n");
- }
-#endif
- /* Clear autoprint flag. */
- F_CLR(exp, EX_AUTOPRINT);
-
- /* Increment the command count if not called from vi. */
- if (IN_EX_MODE(sp))
- ++sp->ccnt;
-
- /*
- * If file state available, and not doing a global command,
- * log the start of an action.
- */
- if (ep != NULL && !F_ISSET(sp, S_GLOBAL))
- (void)log_cursor(sp, ep);
-
- /*
- * !!!
- * There are two special commands for the purposes of this code: the
- * default command (<carriage-return>) or the scrolling commands (^D
- * and <EOF>) as the first non-<blank> characters in the line.
- *
- * If this is the first command in the command line, we received the
- * command from the ex command loop and we're talking to a tty, and
- * and there's nothing else on the command line, and it's one of the
- * special commands, we erase the prompt character with a '\r'. Else,
- * we put out a newline character to separate the command from the
- * output from the command. It's OK if vi calls us -- we won't be in
- * ex mode so we'll do nothing.
- *
- * !!!
- * Historically, ex only put out a \r, so, if the displayed line was
- * only a single character long, and <eof> was represented as ^D, the
- * output wouldn't overwrite the user's input. Sex currently doesn't
- * display the <eof> character if it's going to be the scroll command,
- * i.e. if it's the first non-<blank> character in the line. If sex
- * is changed to run in cooked mode, i.e. <eof> is displayed, this code
- * will have to overwrite it. We also don't treat lines with extra
- * prompt characters as empty -- it's not worth the effort since we'd
- * have to overwrite some indeterminate number of columns with spaces
- * to clean up. For now, put out enough spaces to overwrite the prompt.
- */
- if (sep != NONE) {
- if (ep != NULL &&
- IN_EX_MODE(sp) && F_ISSET(sp->gp, G_STDIN_TTY))
- if (sep == NEEDSEP_NR &&
- (uselastcmd || cp == &cmds[C_SCROLL])) {
- (void)putchar('\r');
- for (len = KEY_LEN(sp, PROMPTCHAR); len--;)
- (void)putchar(' ');
- (void)putchar('\r');
- } else
- (void)putchar('\n');
- sep = NONE;
- }
-
- /* Save the current mode. */
- saved_mode = F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE);
-
- /* Do the command. */
- if (cp->fn(sp, ep, &exc))
- goto err;
-
-#ifdef DEBUG
- /* Make sure no function left the temporary space locked. */
- if (F_ISSET(sp->gp, G_TMP_INUSE)) {
- F_CLR(sp->gp, G_TMP_INUSE);
- msgq(sp, M_ERR, "Error: ex: temporary buffer not released");
- goto err;
- }
-#endif
- if (saved_mode != F_ISSET(sp, S_SCREENS | S_MAJOR_CHANGE)) {
- /*
- * Only here if the mode of the underlying file changed, e.g.
- * the user switched files or is exiting. Two things that we
- * might have to save: first, any "+cmd" field set up for an
- * ex/edit command will have to be saved for later, also, any
- * part of the current ex command that hasn't been executed
- * yet. For example:
- *
- * :edit +25 file.c|s/abc/ABC/|1
- *
- * !!!
- * The historic vi just hung, of course; nvi handles it by
- * pushing the keys onto the tty queue. Since the commands
- * are intended as ex commands, add additional characters
- * to make it all work if we're switching modes to vi. Also,
- * + commands were oriented to the last line in the file,
- * historically, make the cursor start out there.
- *
- * For the fun of it, if you want to see if a vi clone got the
- * ex argument parsing right, try:
- *
- * echo 'foo|bar' > file1; echo 'foo/bar' > file2;
- * vi
- * :edit +1|s/|/PIPE/|w file1| e file2|1 | s/\//SLASH/|wq
- */
- if (arg1_len == 0 && save_cmdlen == 0)
- return (0);
- if (term_push(sp, "\n", 1, 0))
- goto err;
- if (save_cmdlen != 0)
- if (term_push(sp, save_cmd, save_cmdlen, 0))
- goto err;
- if (arg1 != NULL) {
- if (IN_VI_MODE(sp) && save_cmdlen != 0 &&
- term_push(sp, "|", 1, 0))
- goto err;
- if (term_push(sp, arg1, arg1_len, 0))
- goto err;
- if (file_lline(sp, ep, &sp->frp->lno))
- goto err;
- F_SET(sp->frp, FR_CURSORSET);
- }
- if (IN_VI_MODE(sp) && term_push(sp, ":", 1, 0))
- goto err;
- return (0);
- }
-
- /*
- * Integrate any offset parsed by the underlying command, and make
- * sure the referenced line exists.
- *
- * XXX
- * May not match historic practice (I've never been able to completely
- * figure it out.) For example, the '=' command from vi mode often
- * got the offset wrong, and complained it was too large, but didn't
- * seem to have a problem with the cursor. If anyone complains, ask
- * them how it's supposed to work, they probably know.
- */
- if (ep != NULL && (flagoff += exc.flagoff)) {
- if (flagoff < 0) {
- if (sp->lno <= -flagoff) {
- msgq(sp, M_ERR, "Flag offset before line 1");
- goto err;
- }
- } else {
- if (file_lline(sp, ep, &lno))
- goto err;
- if (sp->lno + flagoff > lno) {
- msgq(sp, M_ERR, "Flag offset past end-of-file");
- goto err;
- }
- }
- sp->lno += flagoff;
- }
-
- /*
- * If the command was successful and we're in ex command mode, we
- * may want to display a line. Make sure there's a line to display.
- */
- if (ep != NULL &&
- IN_EX_MODE(sp) && !F_ISSET(sp, S_GLOBAL) && sp->lno != 0) {
- /*
- * The print commands have already handled the `print' flags.
- * If so, clear them.
- */
- if (LF_ISSET(E_F_PRCLEAR))
- F_CLR(&exc, E_F_HASH | E_F_LIST | E_F_PRINT);
-
- /* If hash only set because of the number option, discard it. */
- if (optnum)
- F_CLR(&exc, E_F_HASH);
-
- /*
- * If there was an explicit flag to display the new cursor
- * line, or we're in ex mode, autoprint is set, and a change
- * was made, display the line. If any print flags set use
- * them, otherwise default to print.
- */
- LF_INIT(F_ISSET(&exc, E_F_HASH | E_F_LIST | E_F_PRINT));
- if (!LF_ISSET(E_F_HASH | E_F_LIST | E_F_PRINT) &&
- O_ISSET(sp, O_AUTOPRINT) &&
- (F_ISSET(exp, EX_AUTOPRINT) || F_ISSET(cp, E_AUTOPRINT)))
- LF_INIT(E_F_PRINT);
-
- if (LF_ISSET(E_F_HASH | E_F_LIST | E_F_PRINT)) {
- memset(&exc, 0, sizeof(EXCMDARG));
- exc.addrcnt = 2;
- exc.addr1.lno = exc.addr2.lno = sp->lno;
- exc.addr1.cno = exc.addr2.cno = sp->cno;
- (void)ex_print(sp, ep, &exc.addr1, &exc.addr2, flags);
- }
- }
-
- cmd = save_cmd;
- cmdlen = save_cmdlen;
- goto loop;
- /* NOTREACHED */
-
- /*
- * If we haven't put out a separator line, do it now. For more
- * detailed comments, see above.
- */
-err: if (sep != NONE &&
- ep != NULL && IN_EX_MODE(sp) && F_ISSET(sp->gp, G_STDIN_TTY))
- (void)fputc('\n', stdout);
- /*
- * On error, we discard any keys we have left, as well as any keys
- * that were mapped. The test of save_cmdlen isn't necessarily
- * correct. If we fail early enough we don't know if the entire
- * string was a single command or not. Try and guess, it's useful
- * to know if part of the command was discarded.
- */
- if (save_cmdlen == 0)
- for (; cmdlen; --cmdlen) {
- ch = *cmd++;
- if (IS_ESCAPE(sp, ch) && cmdlen > 1) {
- --cmdlen;
- ++cmd;
- } else if (ch == '\n' || ch == '|') {
- if (cmdlen > 1)
- save_cmdlen = 1;
- break;
- }
- }
- if (save_cmdlen != 0)
- msgq(sp, M_ERR,
- "Ex command failed: remaining command input discarded");
- /*
- * !!!
- * Previous versions of nvi cleared mapped characters on error. This
- * feature was removed when users complained that it wasn't historic
- * practice.
- */
- return (1);
-}
-
-/*
- * ep_range --
- * Get a line range for ex commands.
- */
-static int
-ep_range(sp, ep, excp, cmdp, cmdlenp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *excp;
- char **cmdp;
- size_t *cmdlenp;
-{
- MARK cur, savecursor;
- size_t cmdlen;
- int savecursor_set, tmp;
- char *cmd;
-
- /* Percent character is all lines in the file. */
- cmd = *cmdp;
- cmdlen = *cmdlenp;
- if (*cmd == '%') {
- excp->addr1.lno = 1;
- if (file_lline(sp, ep, &excp->addr2.lno))
- return (1);
-
- /* If an empty file, then the first line is 0, not 1. */
- if (excp->addr2.lno == 0)
- excp->addr1.lno = 0;
- excp->addr1.cno = excp->addr2.cno = 0;
- excp->addrcnt = 2;
-
- ++*cmdp;
- --*cmdlenp;
- return (0);
- }
-
- /* Parse comma or semi-colon delimited line specs. */
- for (savecursor_set = 0, excp->addrcnt = 0; cmdlen > 0;)
- switch (*cmd) {
- case ';': /* Semi-colon delimiter. */
- /*
- * Comma delimiters delimit; semi-colon delimiters
- * change the current address for the 2nd address
- * to be the first address. Trailing or multiple
- * delimiters are discarded.
- */
- if (excp->addrcnt == 0)
- goto done;
- if (!savecursor_set) {
- savecursor.lno = sp->lno;
- savecursor.cno = sp->cno;
- sp->lno = excp->addr1.lno;
- sp->cno = excp->addr1.cno;
- savecursor_set = 1;
- }
- ++cmd;
- --cmdlen;
- break;
- case ',': /* Comma delimiter. */
- /* If no addresses yet, defaults to ".". */
- if (excp->addrcnt == 0) {
- excp->addr1.lno = sp->lno;
- excp->addr1.cno = sp->cno;
- excp->addrcnt = 1;
- }
- /* FALLTHROUGH */
- case ' ': /* Whitespace. */
- case '\t': /* Whitespace. */
- ++cmd;
- --cmdlen;
- break;
- default:
- if (ep_line(sp, ep, &cur, &cmd, &cmdlen, &tmp))
- return (1);
- if (!tmp)
- goto done;
-
- /*
- * Extra addresses are discarded, starting with
- * the first.
- */
- switch (excp->addrcnt) {
- case 0:
- excp->addr1 = cur;
- excp->addrcnt = 1;
- break;
- case 1:
- excp->addr2 = cur;
- excp->addrcnt = 2;
- break;
- case 2:
- excp->addr1 = excp->addr2;
- excp->addr2 = cur;
- break;
- }
- break;
- }
-
- /*
- * XXX
- * This is probably not the right behavior for savecursor --
- * need to figure out what the historical ex did for ";,;,;5p"
- * or similar stupidity.
- */
-done: if (savecursor_set) {
- sp->lno = savecursor.lno;
- sp->cno = savecursor.cno;
- }
- if (excp->addrcnt == 2 && excp->addr2.lno < excp->addr1.lno) {
- msgq(sp, M_ERR,
- "The second address is smaller than the first");
- return (1);
- }
- *cmdp = cmd;
- *cmdlenp = cmdlen;
- return (0);
-}
-
-/*
- * Get a single line address specifier.
- *
- * The way the "previous context" mark worked was that any "non-relative"
- * motion set it. While ex/vi wasn't totally consistent about this, ANY
- * numeric address, search pattern, '$', or mark reference in an address
- * was considered non-relative, and set the value. Which should explain
- * why we're hacking marks down here. The problem was that the mark was
- * only set if the command was called, i.e. we have to set a flag and test
- * it later.
- *
- * XXX
- * This is not exactly historic practice, although it's fairly close.
- */
-static int
-ep_line(sp, ep, cur, cmdp, cmdlenp, addr_found)
- SCR *sp;
- EXF *ep;
- MARK *cur;
- char **cmdp;
- size_t *cmdlenp;
- int *addr_found;
-{
- EX_PRIVATE *exp;
- MARK m;
- long total;
- u_int flags;
- size_t cmdlen;
- int (*sf) __P((SCR *, EXF *, MARK *, MARK *, char *, char **, u_int *));
- char *cmd, *endp;
-
- exp = EXP(sp);
- *addr_found = 0;
-
- cmd = *cmdp;
- cmdlen = *cmdlenp;
- switch (*cmd) {
- case '$': /* Last line in the file. */
- *addr_found = 1;
- F_SET(exp, EX_ABSMARK);
-
- cur->cno = 0;
- if (file_lline(sp, ep, &cur->lno))
- return (1);
- ++cmd;
- --cmdlen;
- break; /* Absolute line number. */
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- *addr_found = 1;
- F_SET(exp, EX_ABSMARK);
-
- cur->cno = 0;
-/* 8-bit XXX */ cur->lno = strtol(cmd, &endp, 10);
- cmdlen -= (endp - cmd);
- cmd = endp;
- break;
- case '\'': /* Use a mark. */
- *addr_found = 1;
- F_SET(exp, EX_ABSMARK);
-
- if (cmdlen == 1) {
- msgq(sp, M_ERR, "No mark name supplied");
- return (1);
- }
- if (mark_get(sp, ep, cmd[1], cur))
- return (1);
- cmd += 2;
- cmdlen -= 2;
- break;
- case '\\': /* Search: forward/backward. */
- /*
- * !!!
- * I can't find any difference between // and \/ or between
- * ?? and \?. Mark Horton doesn't remember there being any
- * difference. C'est la vie.
- */
- if (cmdlen < 2 || cmd[1] != '/' && cmd[1] != '?') {
- msgq(sp, M_ERR, "\\ not followed by / or ?");
- return (1);
- }
- ++cmd;
- --cmdlen;
- sf = cmd[0] == '/' ? f_search : b_search;
- goto search;
- case '/': /* Search forward. */
- sf = f_search;
- goto search;
- case '?': /* Search backward. */
- sf = b_search;
-search: F_SET(exp, EX_ABSMARK);
-
- if (ep == NULL) {
- msgq(sp, M_ERR,
- "A search address requires that a file have already been read in");
- return (1);
- }
- *addr_found = 1;
- m.lno = sp->lno;
- m.cno = sp->cno;
- flags = SEARCH_MSG | SEARCH_PARSE | SEARCH_SET;
- if (sf(sp, ep, &m, &m, cmd, &endp, &flags))
- return (1);
- cur->lno = m.lno;
- cur->cno = m.cno;
- cmdlen -= (endp - cmd);
- cmd = endp;
- break;
- case '.': /* Current position. */
- *addr_found = 1;
- cur->cno = sp->cno;
-
- /* If an empty file, then '.' is 0, not 1. */
- if (sp->lno == 1) {
- if (file_lline(sp, ep, &cur->lno))
- return (1);
- if (cur->lno != 0)
- cur->lno = 1;
- } else
- cur->lno = sp->lno;
- ++cmd;
- --cmdlen;
- break;
- }
-
- /*
- * Evaluate any offset. Offsets are +/- any number, or any number
- * of +/- signs, or any combination thereof. If no address found
- * yet, offset is relative to ".".
- */
- for (total = 0; cmdlen > 0 && (cmd[0] == '-' || cmd[0] == '+');) {
- if (!*addr_found) {
- cur->lno = sp->lno;
- cur->cno = sp->cno;
- *addr_found = 1;
- }
-
- if (cmdlen > 1 && isdigit(cmd[1])) {
-/* 8-bit XXX */ total += strtol(cmd, &endp, 10);
- cmdlen -= (endp - cmd);
- cmd = endp;
- } else {
- total += cmd[0] == '-' ? -1 : 1;
- --cmdlen;
- ++cmd;
- }
- }
-
- if (*addr_found) {
- if (total < 0 && -total > cur->lno) {
- msgq(sp, M_ERR,
- "Reference to a line number less than 0");
- return (1);
- }
- cur->lno += total;
-
- *cmdp = cmd;
- *cmdlenp = cmdlen;
- }
- return (0);
-}
-
-/*
- * ex_is_abbrev -
- * The vi text input routine needs to know if ex thinks this is
- * an [un]abbreviate command, so it can turn off abbreviations.
- * Usual ranting in the vi/v_ntext:txt_abbrev() routine.
- */
-int
-ex_is_abbrev(name, len)
- char *name;
- size_t len;
-{
- EXCMDLIST const *cp;
-
- return ((cp = ex_comm_search(name, len)) != NULL &&
- (cp == &cmds[C_ABBR] || cp == &cmds[C_UNABBREVIATE]));
-}
-
-/*
- * ex_is_unmap -
- * The vi text input routine needs to know if ex thinks this is
- * an unmap command, so it can turn off input mapping. Usual
- * ranting in the vi/v_ntext:txt_unmap() routine.
- */
-int
-ex_is_unmap(name, len)
- char *name;
- size_t len;
-{
- EXCMDLIST const *cp;
-
- /*
- * The command the vi input routines are really interested in
- * is "unmap!", not just unmap.
- */
- if (name[len - 1] != '!')
- return (0);
- --len;
- return ((cp = ex_comm_search(name, len)) != NULL &&
- cp == &cmds[C_UNMAP]);
-}
-
-static __inline EXCMDLIST const *
-ex_comm_search(name, len)
- char *name;
- size_t len;
-{
- EXCMDLIST const *cp;
-
- for (cp = cmds; cp->name != NULL; ++cp) {
- if (cp->name[0] > name[0])
- return (NULL);
- if (cp->name[0] != name[0])
- continue;
- if (!memcmp(name, cp->name, len))
- return (cp);
- }
- return (NULL);
-}
-
-static void
-badlno(sp, lno)
- SCR *sp;
- recno_t lno;
-{
- if (lno == 0)
- msgq(sp, M_ERR, "Illegal address: the file is empty");
- else
- msgq(sp, M_ERR, "Illegal address: only %lu line%s in the file",
- lno, lno > 1 ? "s" : "");
-}
diff --git a/usr.bin/vi/ex/ex_abbrev.c b/usr.bin/vi/ex/ex_abbrev.c
deleted file mode 100644
index 1360030..0000000
--- a/usr.bin/vi/ex/ex_abbrev.c
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_abbrev.c 8.14 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "../vi/vcmd.h"
-
-/*
- * ex_abbr -- :abbreviate [key replacement]
- * Create an abbreviation or display abbreviations.
- */
-int
-ex_abbr(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- CHAR_T *p;
- size_t len;
-
- switch (cmdp->argc) {
- case 0:
- if (seq_dump(sp, SEQ_ABBREV, 0) == 0)
- msgq(sp, M_INFO, "No abbreviations to display");
- return (0);
- case 2:
- break;
- default:
- abort();
- }
-
- /* Check for illegal characters. */
- for (p = cmdp->argv[0]->bp, len = cmdp->argv[0]->len; len--; ++p)
- if (!inword(*p)) {
- msgq(sp, M_ERR,
- "%s may not be part of an abbreviated word",
- KEY_NAME(sp, *p));
- return (1);
- }
-
- if (seq_set(sp, NULL, 0, cmdp->argv[0]->bp, cmdp->argv[0]->len,
- cmdp->argv[1]->bp, cmdp->argv[1]->len, SEQ_ABBREV, SEQ_USERDEF))
- return (1);
-
- F_SET(sp->gp, G_ABBREV);
- return (0);
-}
-
-/*
- * ex_unabbr -- :unabbreviate key
- * Delete an abbreviation.
- */
-int
-ex_unabbr(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- ARGS *ap;
-
- ap = cmdp->argv[0];
- if (!F_ISSET(sp->gp, G_ABBREV) ||
- seq_delete(sp, ap->bp, ap->len, SEQ_ABBREV)) {
- msgq(sp, M_ERR, "\"%s\" is not an abbreviation", ap->bp);
- return (1);
- }
- return (0);
-}
-
-/*
- * abbr_save --
- * Save the abbreviation sequences to a file.
- */
-int
-abbr_save(sp, fp)
- SCR *sp;
- FILE *fp;
-{
- return (seq_save(sp, fp, "abbreviate ", SEQ_ABBREV));
-}
diff --git a/usr.bin/vi/ex/ex_append.c b/usr.bin/vi/ex/ex_append.c
deleted file mode 100644
index b819f5a..0000000
--- a/usr.bin/vi/ex/ex_append.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_append.c 8.24 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "../sex/sex_screen.h"
-
-enum which {APPEND, CHANGE, INSERT};
-
-static int aci __P((SCR *, EXF *, EXCMDARG *, enum which));
-
-/*
- * ex_append -- :[line] a[ppend][!]
- * Append one or more lines of new text after the specified line,
- * or the current line if no address is specified.
- */
-int
-ex_append(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (aci(sp, ep, cmdp, APPEND));
-}
-
-/*
- * ex_change -- :[line[,line]] c[hange][!] [count]
- * Change one or more lines to the input text.
- */
-int
-ex_change(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (aci(sp, ep, cmdp, CHANGE));
-}
-
-/*
- * ex_insert -- :[line] i[nsert][!]
- * Insert one or more lines of new text before the specified line,
- * or the current line if no address is specified.
- */
-int
-ex_insert(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (aci(sp, ep, cmdp, INSERT));
-}
-
-static int
-aci(sp, ep, cmdp, cmd)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
- enum which cmd;
-{
- MARK m;
- TEXTH *sv_tiqp, tiq;
- TEXT *tp;
- struct termios t;
- u_int flags;
- int rval;
-
- rval = 0;
-
- /*
- * Set input flags; the ! flag turns off autoindent for append,
- * change and insert.
- */
- LF_INIT(TXT_DOTTERM | TXT_NLECHO);
- if (!F_ISSET(cmdp, E_FORCE) && O_ISSET(sp, O_AUTOINDENT))
- LF_SET(TXT_AUTOINDENT);
- if (O_ISSET(sp, O_BEAUTIFY))
- LF_SET(TXT_BEAUTIFY);
-
- /* Input is interruptible. */
- F_SET(sp, S_INTERRUPTIBLE);
-
- /*
- * If this code is called by vi, the screen TEXTH structure (sp->tiqp)
- * may already be in use, e.g. ":append|s/abc/ABC/" would fail as we're
- * only halfway through the line when the append code fires. Use the
- * local structure instead.
- *
- * If this code is called by vi, we want to reset the terminal and use
- * ex's s_get() routine. It actually works fine if we use vi's s_get()
- * routine, but it doesn't look as nice. Maybe if we had a separate
- * window or something, but getting a line at a time looks awkward.
- */
- if (IN_VI_MODE(sp)) {
- memset(&tiq, 0, sizeof(TEXTH));
- CIRCLEQ_INIT(&tiq);
- sv_tiqp = sp->tiqp;
- sp->tiqp = &tiq;
-
- if (F_ISSET(sp->gp, G_STDIN_TTY))
- SEX_RAW(t);
- (void)write(STDOUT_FILENO, "\n", 1);
- LF_SET(TXT_NLECHO);
-
- }
-
- /* Set the line number, so that autoindent works correctly. */
- sp->lno = cmdp->addr1.lno;
-
- if (sex_get(sp, ep, sp->tiqp, 0, flags) != INP_OK)
- goto err;
-
- /*
- * If doing a change, replace lines for as long as possible. Then,
- * append more lines or delete remaining lines. Changes to an empty
- * file are just appends, and inserts are the same as appends to the
- * previous line.
- *
- * !!!
- * Adjust the current line number for the commands to match historic
- * practice if the user doesn't enter anything, and set the address
- * to which we'll append. This is safe because an address of 0 is
- * illegal for change and insert.
- */
- m = cmdp->addr1;
- switch (cmd) {
- case INSERT:
- --m.lno;
- /* FALLTHROUGH */
- case APPEND:
- if (sp->lno == 0)
- sp->lno = 1;
- break;
- case CHANGE:
- --m.lno;
- if (sp->lno != 1)
- --sp->lno;
- break;
- }
-
- /*
- * !!!
- * Cut into the unnamed buffer.
- */
- if (cmd == CHANGE &&
- (cut(sp, ep, NULL, &cmdp->addr1, &cmdp->addr2, CUT_LINEMODE) ||
- delete(sp, ep, &cmdp->addr1, &cmdp->addr2, 1)))
- goto err;
-
- for (tp = sp->tiqp->cqh_first;
- tp != (TEXT *)sp->tiqp; tp = tp->q.cqe_next) {
- if (file_aline(sp, ep, 1, m.lno, tp->lb, tp->len)) {
-err: rval = 1;
- break;
- }
- sp->lno = ++m.lno;
- }
-
- if (IN_VI_MODE(sp)) {
- sp->tiqp = sv_tiqp;
- text_lfree(&tiq);
-
- /* Reset the terminal state. */
- if (F_ISSET(sp->gp, G_STDIN_TTY)) {
- if (SEX_NORAW(t))
- rval = 1;
- F_SET(sp, S_REFRESH);
- }
- }
- return (rval);
-}
diff --git a/usr.bin/vi/ex/ex_args.c b/usr.bin/vi/ex/ex_args.c
deleted file mode 100644
index 74f94f3..0000000
--- a/usr.bin/vi/ex/ex_args.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_args.c 8.29 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_next -- :next [+cmd] [files]
- * Edit the next file, optionally setting the list of files.
- *
- * !!!
- * The :next command behaved differently from the :rewind command in
- * historic vi. See nvi/docs/autowrite for details, but the basic
- * idea was that it ignored the force flag if the autowrite flag was
- * set. This implementation handles them all identically.
- */
-int
-ex_next(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- ARGS **argv, **pc;
- FREF *frp;
- int noargs;
- char **ap;
-
- if (file_m1(sp, ep, F_ISSET(cmdp, E_FORCE), FS_ALL | FS_POSSIBLE))
- return (1);
-
- /*
- * If the first argument is a plus sign, '+', it's an initial
- * ex command.
- */
- argv = cmdp->argv;
- if (cmdp->argc && argv[0]->bp[0] == '+') {
- --cmdp->argc;
- pc = argv++;
- } else
- pc = NULL;
-
- /* Any other arguments are a replacement file list. */
- if (cmdp->argc) {
- /* Free the current list. */
- if (!F_ISSET(sp, S_ARGNOFREE) && sp->argv != NULL) {
- for (ap = sp->argv; *ap != NULL; ++ap)
- free(*ap);
- free(sp->argv);
- }
- F_CLR(sp, S_ARGNOFREE | S_ARGRECOVER);
- sp->cargv = NULL;
-
- /* Create a new list. */
- CALLOC_RET(sp,
- sp->argv, char **, cmdp->argc + 1, sizeof(char *));
- for (ap = sp->argv,
- argv = cmdp->argv; argv[0]->len != 0; ++ap, ++argv)
- if ((*ap =
- v_strdup(sp, argv[0]->bp, argv[0]->len)) == NULL)
- return (1);
- *ap = NULL;
-
- /* Switch to the first one. */
- sp->cargv = sp->argv;
- if ((frp = file_add(sp, *sp->cargv)) == NULL)
- return (1);
- noargs = 0;
- } else {
- if (sp->cargv == NULL || sp->cargv[1] == NULL) {
- msgq(sp, M_ERR, "No more files to edit");
- return (1);
- }
- if ((frp = file_add(sp, sp->cargv[1])) == NULL)
- return (1);
- if (F_ISSET(sp, S_ARGRECOVER))
- F_SET(frp, FR_RECOVER);
- noargs = 1;
- }
-
- if (file_init(sp, frp, NULL, F_ISSET(cmdp, E_FORCE)))
- return (1);
- if (noargs)
- ++sp->cargv;
-
- /* Push the initial command onto the stack. */
- if (pc != NULL)
- if (IN_EX_MODE(sp))
- (void)term_push(sp, pc[0]->bp, pc[0]->len, 0);
- else if (IN_VI_MODE(sp)) {
- (void)term_push(sp, "\n", 1, 0);
- (void)term_push(sp, pc[0]->bp, pc[0]->len, 0);
- (void)term_push(sp, ":", 1, 0);
- (void)file_lline(sp, sp->ep, &sp->frp->lno);
- F_SET(sp->frp, FR_CURSORSET);
- }
-
- F_SET(sp, S_FSWITCH);
- return (0);
-}
-
-/*
- * ex_prev -- :prev
- * Edit the previous file.
- */
-int
-ex_prev(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- FREF *frp;
-
- if (file_m1(sp, ep, F_ISSET(cmdp, E_FORCE), FS_ALL | FS_POSSIBLE))
- return (1);
-
- if (sp->cargv == sp->argv) {
- msgq(sp, M_ERR, "No previous files to edit");
- return (1);
- }
- if ((frp = file_add(sp, sp->cargv[-1])) == NULL)
- return (1);
-
- if (file_init(sp, frp, NULL, F_ISSET(cmdp, E_FORCE)))
- return (1);
-
- --sp->cargv;
- F_SET(sp, S_FSWITCH);
- return (0);
-}
-
-/*
- * ex_rew -- :rew
- * Re-edit the list of files.
- */
-int
-ex_rew(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- FREF *frp;
-
- /*
- * !!!
- * Historic practice -- you can rewind to the current file.
- */
- if (sp->argv == NULL) {
- msgq(sp, M_ERR, "No previous files to rewind");
- return (1);
- }
-
- if (file_m1(sp, ep, F_ISSET(cmdp, E_FORCE), FS_ALL | FS_POSSIBLE))
- return (1);
-
- /*
- * !!!
- * Historic practice, start at the beginning of the file.
- */
- for (frp = sp->frefq.cqh_first;
- frp != (FREF *)&sp->frefq; frp = frp->q.cqe_next)
- F_CLR(frp, FR_CURSORSET | FR_FNONBLANK);
-
- /* Switch to the first one. */
- sp->cargv = sp->argv;
- if ((frp = file_add(sp, *sp->cargv)) == NULL)
- return (1);
- if (file_init(sp, frp, NULL, F_ISSET(cmdp, E_FORCE)))
- return (1);
-
- F_SET(sp, S_FSWITCH);
- return (0);
-}
-
-/*
- * ex_args -- :args
- * Display the list of files.
- */
-int
-ex_args(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- int cnt, col, len, sep;
- char **ap;
-
- if (sp->argv == NULL) {
- (void)ex_printf(EXCOOKIE, "No file list to display.\n");
- return (0);
- }
-
- col = len = sep = 0;
- for (cnt = 1, ap = sp->argv; *ap != NULL; ++ap) {
- col += len = strlen(*ap) + sep + (ap == sp->cargv ? 2 : 0);
- if (col >= sp->cols - 1) {
- col = len;
- sep = 0;
- (void)ex_printf(EXCOOKIE, "\n");
- } else if (cnt != 1) {
- sep = 1;
- (void)ex_printf(EXCOOKIE, " ");
- }
- ++cnt;
-
- if (ap == sp->cargv)
- (void)ex_printf(EXCOOKIE, "[%s]", *ap);
- else
- (void)ex_printf(EXCOOKIE, "%s", *ap);
- }
- (void)ex_printf(EXCOOKIE, "\n");
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_argv.c b/usr.bin/vi/ex/ex_argv.c
deleted file mode 100644
index bb033e2..0000000
--- a/usr.bin/vi/ex/ex_argv.c
+++ /dev/null
@@ -1,609 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_argv.c 8.38 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-static int argv_alloc __P((SCR *, size_t));
-static int argv_fexp __P((SCR *, EXCMDARG *,
- char *, size_t, char *, size_t *, char **, size_t *, int));
-static int argv_sexp __P((SCR *, char **, size_t *, size_t *));
-
-/*
- * argv_init --
- * Build a prototype arguments list.
- */
-int
-argv_init(sp, ep, excp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *excp;
-{
- EX_PRIVATE *exp;
-
- exp = EXP(sp);
- exp->argsoff = 0;
- argv_alloc(sp, 1);
-
- excp->argv = exp->args;
- excp->argc = exp->argsoff;
- return (0);
-}
-
-/*
- * argv_exp0 --
- * Append a string to the argument list.
- */
-int
-argv_exp0(sp, ep, excp, cmd, cmdlen)
- SCR *sp;
- EXF *ep;
- EXCMDARG *excp;
- char *cmd;
- size_t cmdlen;
-{
- EX_PRIVATE *exp;
-
- exp = EXP(sp);
- argv_alloc(sp, cmdlen);
- memmove(exp->args[exp->argsoff]->bp, cmd, cmdlen);
- exp->args[exp->argsoff]->bp[cmdlen] = '\0';
- exp->args[exp->argsoff]->len = cmdlen;
- ++exp->argsoff;
- excp->argv = exp->args;
- excp->argc = exp->argsoff;
- return (0);
-}
-
-/*
- * argv_exp1 --
- * Do file name expansion on a string, and append it to the
- * argument list.
- */
-int
-argv_exp1(sp, ep, excp, cmd, cmdlen, is_bang)
- SCR *sp;
- EXF *ep;
- EXCMDARG *excp;
- char *cmd;
- size_t cmdlen;
- int is_bang;
-{
- EX_PRIVATE *exp;
- size_t blen, len;
- char *bp, *p, *t;
-
- GET_SPACE_RET(sp, bp, blen, 512);
-
- len = 0;
- exp = EXP(sp);
- if (argv_fexp(sp, excp, cmd, cmdlen, bp, &len, &bp, &blen, is_bang)) {
- FREE_SPACE(sp, bp, blen);
- return (1);
- }
-
- /* If it's empty, we're done. */
- if (len != 0) {
- for (p = bp, t = bp + len; p < t; ++p)
- if (!isblank(*p))
- break;
- if (p == t)
- goto ret;
- } else
- goto ret;
-
- (void)argv_exp0(sp, ep, excp, bp, len);
-
-ret: FREE_SPACE(sp, bp, blen);
- return (0);
-}
-
-/*
- * argv_exp2 --
- * Do file name and shell expansion on a string, and append it to
- * the argument list.
- */
-int
-argv_exp2(sp, ep, excp, cmd, cmdlen, is_bang)
- SCR *sp;
- EXF *ep;
- EXCMDARG *excp;
- char *cmd;
- size_t cmdlen;
- int is_bang;
-{
- size_t blen, len, n;
- int rval;
- char *bp, *mp, *p;
-
- GET_SPACE_RET(sp, bp, blen, 512);
-
-#define SHELLECHO "echo "
-#define SHELLOFFSET (sizeof(SHELLECHO) - 1)
- memmove(bp, SHELLECHO, SHELLOFFSET);
- p = bp + SHELLOFFSET;
- len = SHELLOFFSET;
-
-#if defined(DEBUG) && 0
- TRACE(sp, "file_argv: {%.*s}\n", (int)cmdlen, cmd);
-#endif
-
- if (argv_fexp(sp, excp, cmd, cmdlen, p, &len, &bp, &blen, is_bang)) {
- rval = 1;
- goto err;
- }
-
-#if defined(DEBUG) && 0
- TRACE(sp, "before shell: %d: {%s}\n", len, bp);
-#endif
-
- /*
- * Do shell word expansion -- it's very, very hard to figure out what
- * magic characters the user's shell expects. Historically, it was a
- * union of v7 shell and csh meta characters. We match that practice
- * by default, so ":read \%" tries to read a file named '%'. It would
- * make more sense to pass any special characters through the shell,
- * but then, if your shell was csh, the above example will behave
- * differently in nvi than in vi. If you want to get other characters
- * passed through to your shell, change the "meta" option.
- *
- * To avoid a function call per character, we do a first pass through
- * the meta characters looking for characters that aren't expected
- * to be there.
- */
- for (p = mp = O_STR(sp, O_META); *p != '\0'; ++p)
- if (isblank(*p) || isalnum(*p))
- break;
- if (*p != '\0') {
- for (p = bp, n = len; n > 0; --n, ++p)
- if (strchr(mp, *p) != NULL)
- break;
- } else
- for (p = bp, n = len; n > 0; --n, ++p)
- if (!isblank(*p) &&
- !isalnum(*p) && strchr(mp, *p) != NULL)
- break;
- if (n > 0) {
- if (argv_sexp(sp, &bp, &blen, &len)) {
- rval = 1;
- goto err;
- }
- p = bp;
- } else {
- p = bp + SHELLOFFSET;
- len -= SHELLOFFSET;
- }
-
-#if defined(DEBUG) && 0
- TRACE(sp, "after shell: %d: {%s}\n", len, bp);
-#endif
-
- rval = argv_exp3(sp, ep, excp, p, len);
-
-err: FREE_SPACE(sp, bp, blen);
- return (rval);
-}
-
-/*
- * argv_exp3 --
- * Take a string and break it up into an argv, which is appended
- * to the argument list.
- */
-int
-argv_exp3(sp, ep, excp, cmd, cmdlen)
- SCR *sp;
- EXF *ep;
- EXCMDARG *excp;
- char *cmd;
- size_t cmdlen;
-{
- EX_PRIVATE *exp;
- size_t len;
- int ch, off;
- char *ap, *p;
-
- for (exp = EXP(sp); cmdlen > 0; ++exp->argsoff) {
- /* Skip any leading whitespace. */
- for (; cmdlen > 0; --cmdlen, ++cmd) {
- ch = *cmd;
- if (!isblank(ch))
- break;
- }
- if (cmdlen == 0)
- break;
-
- /*
- * Determine the length of this whitespace delimited
- * argument.
- *
- * QUOTING NOTE:
- *
- * Skip any character preceded by the user's quoting
- * character.
- */
- for (ap = cmd, len = 0; cmdlen > 0; ++cmd, --cmdlen, ++len) {
- ch = *cmd;
- if (IS_ESCAPE(sp, ch) && cmdlen > 1) {
- ++cmd;
- --cmdlen;
- } else if (isblank(ch))
- break;
- }
-
- /*
- * Copy the argument into place.
- *
- * QUOTING NOTE:
- *
- * Lose quote chars.
- */
- argv_alloc(sp, len);
- off = exp->argsoff;
- exp->args[off]->len = len;
- for (p = exp->args[off]->bp; len > 0; --len, *p++ = *ap++)
- if (IS_ESCAPE(sp, *ap))
- ++ap;
- *p = '\0';
- }
- excp->argv = exp->args;
- excp->argc = exp->argsoff;
-
-#if defined(DEBUG) && 0
- for (cnt = 0; cnt < exp->argsoff; ++cnt)
- TRACE(sp, "arg %d: {%s}\n", cnt, exp->argv[cnt]);
-#endif
- return (0);
-}
-
-/*
- * argv_fexp --
- * Do file name and bang command expansion.
- */
-static int
-argv_fexp(sp, excp, cmd, cmdlen, p, lenp, bpp, blenp, is_bang)
- SCR *sp;
- EXCMDARG *excp;
- char *cmd, *p, **bpp;
- size_t cmdlen, *lenp, *blenp;
- int is_bang;
-{
- EX_PRIVATE *exp;
- char *bp, *t;
- size_t blen, len, tlen;
-
- /* Replace file name characters. */
- for (bp = *bpp, blen = *blenp, len = *lenp; cmdlen > 0; --cmdlen, ++cmd)
- switch (*cmd) {
- case '!':
- if (!is_bang)
- goto ins_ch;
- exp = EXP(sp);
- if (exp->lastbcomm == NULL) {
- msgq(sp, M_ERR,
- "No previous command to replace \"!\"");
- return (1);
- }
- len += tlen = strlen(exp->lastbcomm);
- ADD_SPACE_RET(sp, bp, blen, len);
- memmove(p, exp->lastbcomm, tlen);
- p += tlen;
- F_SET(excp, E_MODIFY);
- break;
- case '%':
- if ((t = sp->frp->name) == NULL) {
- msgq(sp, M_ERR,
- "No filename to substitute for %%");
- return (1);
- }
- tlen = strlen(t);
- len += tlen;
- ADD_SPACE_RET(sp, bp, blen, len);
- memmove(p, t, tlen);
- p += tlen;
- F_SET(excp, E_MODIFY);
- break;
- case '#':
- if ((t = sp->alt_name) == NULL) {
- msgq(sp, M_ERR,
- "No filename to substitute for #");
- return (1);
- }
- len += tlen = strlen(t);
- ADD_SPACE_RET(sp, bp, blen, len);
- memmove(p, t, tlen);
- p += tlen;
- F_SET(excp, E_MODIFY);
- break;
- case '\\':
- /*
- * QUOTING NOTE:
- *
- * Strip any backslashes that protected the file
- * expansion characters.
- */
- if (cmdlen > 1 && (cmd[1] == '%' || cmd[1] == '#')) {
- ++cmd;
- --cmdlen;
- }
- /* FALLTHROUGH */
- default:
-ins_ch: ++len;
- ADD_SPACE_RET(sp, bp, blen, len);
- *p++ = *cmd;
- }
-
- /* Nul termination. */
- ++len;
- ADD_SPACE_RET(sp, bp, blen, len);
- *p = '\0';
-
- /* Return the new string length, buffer, buffer length. */
- *lenp = len - 1;
- *bpp = bp;
- *blenp = blen;
- return (0);
-}
-
-/*
- * argv_alloc --
- * Make more space for arguments.
- */
-static int
-argv_alloc(sp, len)
- SCR *sp;
- size_t len;
-{
- ARGS *ap;
- EX_PRIVATE *exp;
- int cnt, off;
-
- /*
- * Allocate room for another argument, always leaving
- * enough room for an ARGS structure with a length of 0.
- */
-#define INCREMENT 20
- exp = EXP(sp);
- off = exp->argsoff;
- if (exp->argscnt == 0 || off + 2 >= exp->argscnt - 1) {
- cnt = exp->argscnt + INCREMENT;
- REALLOC(sp, exp->args, ARGS **, cnt * sizeof(ARGS *));
- if (exp->args == NULL) {
- (void)argv_free(sp);
- goto mem;
- }
- memset(&exp->args[off], 0, INCREMENT * sizeof(ARGS *));
- exp->argscnt = cnt;
- }
-
- /* First argument. */
- if (exp->args[off] == NULL) {
- CALLOC(sp, exp->args[off], ARGS *, 1, sizeof(ARGS));
- if (exp->args[off] == NULL)
- goto mem;
- }
-
- /* First argument buffer. */
- ap = exp->args[off];
- ap->len = 0;
- if (ap->blen < len + 1) {
- ap->blen = len + 1;
- REALLOC(sp, ap->bp, CHAR_T *, ap->blen * sizeof(CHAR_T));
- if (ap->bp == NULL) {
- ap->bp = NULL;
- ap->blen = 0;
- F_CLR(ap, A_ALLOCATED);
-mem: msgq(sp, M_SYSERR, NULL);
- return (1);
- }
- F_SET(ap, A_ALLOCATED);
- }
-
- /* Second argument. */
- if (exp->args[++off] == NULL) {
- CALLOC(sp, exp->args[off], ARGS *, 1, sizeof(ARGS));
- if (exp->args[off] == NULL)
- goto mem;
- }
- /* 0 length serves as end-of-argument marker. */
- exp->args[off]->len = 0;
- return (0);
-}
-
-/*
- * argv_free --
- * Free up argument structures.
- */
-int
-argv_free(sp)
- SCR *sp;
-{
- EX_PRIVATE *exp;
- int off;
-
- exp = EXP(sp);
- if (exp->args != NULL) {
- for (off = 0; off < exp->argscnt; ++off) {
- if (exp->args[off] == NULL)
- continue;
- if (F_ISSET(exp->args[off], A_ALLOCATED))
- free(exp->args[off]->bp);
- FREE(exp->args[off], sizeof(ARGS));
- }
- FREE(exp->args, exp->argscnt * sizeof(ARGS *));
- }
- exp->args = NULL;
- exp->argscnt = 0;
- exp->argsoff = 0;
- return (0);
-}
-
-/*
- * argv_sexp --
- * Fork a shell, pipe a command through it, and read the output into
- * a buffer.
- */
-static int
-argv_sexp(sp, bpp, blenp, lenp)
- SCR *sp;
- char **bpp;
- size_t *blenp, *lenp;
-{
- FILE *ifp;
- pid_t pid;
- size_t blen, len;
- int ch, rval, output[2];
- char *bp, *p, *sh, *sh_path;
-
- bp = *bpp;
- blen = *blenp;
-
- sh_path = O_STR(sp, O_SHELL);
- if ((sh = strrchr(sh_path, '/')) == NULL)
- sh = sh_path;
- else
- ++sh;
-
- /*
- * There are two different processes running through this code.
- * They are named the utility and the parent. The utility reads
- * from standard input and writes to the parent. The parent reads
- * from the utility and writes into the buffer. The parent reads
- * from output[0], and the utility writes to output[1].
- */
- if (pipe(output) < 0) {
- msgq(sp, M_SYSERR, "pipe");
- return (1);
- }
- if ((ifp = fdopen(output[0], "r")) == NULL) {
- msgq(sp, M_SYSERR, "fdopen");
- goto err;
- }
-
- /*
- * Do the minimal amount of work possible, the shell is going
- * to run briefly and then exit. Hopefully.
- */
- SIGBLOCK(sp->gp);
- switch (pid = vfork()) {
- case -1: /* Error. */
- SIGUNBLOCK(sp->gp);
-
- msgq(sp, M_SYSERR, "vfork");
-err: (void)close(output[0]);
- (void)close(output[1]);
- return (1);
- case 0: /* Utility. */
- /* The utility has default signal behavior. */
- sig_end();
-
- /* Redirect stdout/stderr to the write end of the pipe. */
- (void)dup2(output[1], STDOUT_FILENO);
- (void)dup2(output[1], STDERR_FILENO);
-
- /* Close the utility's file descriptors. */
- (void)close(output[0]);
- (void)close(output[1]);
-
- /* Assumes that all shells have -c. */
- execl(sh_path, sh, "-c", bp, NULL);
- msgq(sp, M_ERR,
- "Error: execl: %s: %s", sh_path, strerror(errno));
- _exit(127);
- default: /* Parent. */
- SIGUNBLOCK(sp->gp);
-
- /* Close the pipe end the parent won't use. */
- (void)close(output[1]);
- break;
- }
-
- rval = 0;
-
- /*
- * Copy process output into a buffer.
- *
- * !!!
- * Historic vi apparently discarded leading \n and \r's from
- * the shell output stream. We don't on the grounds that any
- * shell that does that is broken.
- */
- for (p = bp, len = 0, ch = EOF;
- (ch = getc(ifp)) != EOF; *p++ = ch, --blen, ++len)
- if (blen < 5) {
- ADD_SPACE_GOTO(sp, bp, blen, *blenp * 2);
- p = bp + len;
- blen = *blenp - len;
- }
-
- /* Delete the final newline, nul terminate the string. */
- if (p > bp && (p[-1] == '\n' || p[-1] == '\r')) {
- --len;
- *--p = '\0';
- } else
- *p = '\0';
- *lenp = len;
-
- if (ferror(ifp)) {
- msgq(sp, M_ERR, "I/O error: %s", sh);
-binc_err: rval = 1;
- }
- (void)fclose(ifp);
-
- *bpp = bp; /* *blenp is already updated. */
-
- /* Wait for the process. */
- return (proc_wait(sp, (long)pid, sh, 0) || rval);
-}
diff --git a/usr.bin/vi/ex/ex_at.c b/usr.bin/vi/ex/ex_at.c
deleted file mode 100644
index 147261d..0000000
--- a/usr.bin/vi/ex/ex_at.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_at.c 8.27 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_at -- :@[@ | buffer]
- * :*[* | buffer]
- *
- * Execute the contents of the buffer.
- */
-int
-ex_at(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- CB *cbp;
- EX_PRIVATE *exp;
- TEXT *tp;
- int name;
-
- exp = EXP(sp);
-
- /*
- * !!!
- * Historically, [@*]<carriage-return> and [@*][@*] executed the most
- * recently executed buffer in ex mode. In vi mode, only @@ repeated
- * the last buffer. We change historic practice and make @* work from
- * vi mode as well, it's simpler and more consistent.
- */
- name = F_ISSET(cmdp, E_BUFFER) ? cmdp->buffer : '@';
- if (name == '@' || name == '*') {
- if (!exp->at_lbuf_set) {
- msgq(sp, M_ERR, "No previous buffer to execute");
- return (1);
- }
- name = exp->at_lbuf;
- }
-
- CBNAME(sp, cbp, name);
- if (cbp == NULL) {
- msgq(sp, M_ERR, "Buffer %s is empty", KEY_NAME(sp, name));
- return (1);
- }
-
- /* Save for reuse. */
- exp->at_lbuf = name;
- exp->at_lbuf_set = 1;
-
- /*
- * !!!
- * Historic practice is that if the buffer was cut in line mode,
- * <newlines> were appended to each line as it was pushed onto
- * the stack. If the buffer was cut in character mode, <newlines>
- * were appended to all lines but the last one.
- */
- for (tp = cbp->textq.cqh_last;
- tp != (void *)&cbp->textq; tp = tp->q.cqe_prev)
- if ((F_ISSET(cbp, CB_LMODE) ||
- tp->q.cqe_next != (void *)&cbp->textq) &&
- term_push(sp, "\n", 1, 0) ||
- term_push(sp, tp->lb, tp->len, 0))
- return (1);
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_bang.c b/usr.bin/vi/ex/ex_bang.c
deleted file mode 100644
index d2ffaa4..0000000
--- a/usr.bin/vi/ex/ex_bang.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_bang.c 8.35 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "../sex/sex_screen.h"
-
-/*
- * ex_bang -- :[line [,line]] ! command
- *
- * Pass the rest of the line after the ! character to the program named by
- * the O_SHELL option.
- *
- * Historical vi did NOT do shell expansion on the arguments before passing
- * them, only file name expansion. This means that the O_SHELL program got
- * "$t" as an argument if that is what the user entered. Also, there's a
- * special expansion done for the bang command. Any exclamation points in
- * the user's argument are replaced by the last, expanded ! command.
- *
- * There's some fairly amazing slop in this routine to make the different
- * ways of getting here display the right things. It took a long time to
- * get it right (wrong?), so be careful.
- */
-int
-ex_bang(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- enum filtertype ftype;
- ARGS *ap;
- EX_PRIVATE *exp;
- MARK rm;
- recno_t lno;
- size_t blen;
- int rval;
- char *bp, *msg;
-
- ap = cmdp->argv[0];
- if (ap->len == 0) {
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
-
- /* Set the last bang command. */
- exp = EXP(sp);
- if (exp->lastbcomm != NULL)
- free(exp->lastbcomm);
- if ((exp->lastbcomm = strdup(ap->bp)) == NULL) {
- msgq(sp, M_SYSERR, NULL);
- return (1);
- }
-
- /*
- * If the command was modified by the expansion, we redisplay it.
- * Redisplaying it in vi mode is tricky, and handled separately
- * in each case below. If we're in ex mode, it's easy, so we just
- * do it here.
- */
- bp = NULL;
- if (F_ISSET(cmdp, E_MODIFY) && !F_ISSET(sp, S_EXSILENT)) {
- if (IN_EX_MODE(sp)) {
- (void)ex_printf(EXCOOKIE, "!%s\n", ap->bp);
- (void)ex_fflush(EXCOOKIE);
- }
- /*
- * Vi: Display the command if modified. Historic vi displayed
- * the command if it was modified due to file name and/or bang
- * expansion. If piping lines, it was immediately overwritten
- * by any error or line change reporting. We don't the user to
- * have to page through the responses, so we only post it until
- * it's erased by something else. Otherwise, pass it on to the
- * ex_exec_proc routine to display after the screen has been
- * cleaned up.
- */
- if (IN_VI_MODE(sp)) {
- GET_SPACE_RET(sp, bp, blen, ap->len + 3);
- bp[0] = '!';
- memmove(bp + 1, ap->bp, ap->len);
- bp[ap->len + 1] = '\n';
- bp[ap->len + 2] = '\0';
- }
- }
-
- /*
- * If addresses were specified, pipe lines from the file through the
- * command.
- *
- * Historically, vi lines were replaced by both the stdout and stderr
- * lines of the command, but ex by only the stdout lines. This makes
- * no sense to me, so nvi makes it consistent for both, and matches
- * vi's historic behavior.
- */
- if (cmdp->addrcnt != 0) {
- /* Autoprint is set historically, even if the command fails. */
- F_SET(exp, EX_AUTOPRINT);
-
- /* Vi gets a busy message. */
- if (bp != NULL)
- (void)sp->s_busy(sp, bp);
-
- /*
- * !!!
- * Historical vi permitted "!!" in an empty file. When it
- * happens, we get called with two addresses of 1,1 and a
- * bad attitude. The simple solution is to turn it into a
- * FILTER_READ operation, but that means that we don't put
- * an empty line into the default cut buffer as did historic
- * vi. Tough.
- */
- ftype = FILTER;
- if (cmdp->addr1.lno == 1 && cmdp->addr2.lno == 1) {
- if (file_lline(sp, ep, &lno))
- return (1);
- if (lno == 0) {
- cmdp->addr1.lno = cmdp->addr2.lno = 0;
- ftype = FILTER_READ;
- }
- }
- rval = filtercmd(sp, ep,
- &cmdp->addr1, &cmdp->addr2, &rm, ap->bp, ftype);
-
- /*
- * If in vi mode, move to the first nonblank.
- *
- * !!!
- * Historic vi wasn't consistent in this area -- if you used
- * a forward motion it moved to the first nonblank, but if you
- * did a backward motion it didn't. And, if you followed a
- * backward motion with a forward motion, it wouldn't move to
- * the nonblank for either. Going to the nonblank generally
- * seems more useful, so we do it.
- */
- if (rval == 0) {
- sp->lno = rm.lno;
- if (IN_VI_MODE(sp)) {
- sp->cno = 0;
- (void)nonblank(sp, ep, sp->lno, &sp->cno);
- }
- }
- goto ret2;
- }
-
- /*
- * If no addresses were specified, run the command. If the file
- * has been modified and autowrite is set, write the file back.
- * If the file has been modified, autowrite is not set and the
- * warn option is set, tell the user about the file.
- */
- msg = NULL;
- if (F_ISSET(ep, F_MODIFIED))
- if (O_ISSET(sp, O_AUTOWRITE)) {
- if (file_write(sp, ep, NULL, NULL, NULL, FS_ALL)) {
- rval = 1;
- goto ret1;
- }
- } else if (O_ISSET(sp, O_WARN) && !F_ISSET(sp, S_EXSILENT))
- msg = "File modified since last write.\n";
-
- /* Run the command. */
- rval = ex_exec_proc(sp, ap->bp, bp, msg);
-
- /* Vi requires user permission to continue. */
- if (IN_VI_MODE(sp))
- F_SET(sp, S_CONTINUE);
-
-ret2: if (IN_EX_MODE(sp)) {
- /*
- * Put ex error messages out so they aren't confused with
- * the autoprint output.
- */
- if (rval)
- (void)sex_refresh(sp, sp->ep);
-
- /* Ex terminates with a bang, even if the command fails. */
- if (!F_ISSET(sp, S_EXSILENT))
- (void)write(STDOUT_FILENO, "!\n", 2);
- }
-
- /* Free the extra space. */
-ret1: if (bp != NULL)
- FREE_SPACE(sp, bp, blen);
-
- /*
- * XXX
- * The ! commands never return an error, so that autoprint always
- * happens in the ex parser.
- */
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_cd.c b/usr.bin/vi/ex/ex_cd.c
deleted file mode 100644
index 8a3d0f1b..0000000
--- a/usr.bin/vi/ex/ex_cd.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_cd.c 8.18 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <pwd.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_cd -- :cd[!] [directory]
- * Change directories.
- */
-int
-ex_cd(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- struct passwd *pw;
- ARGS *ap;
- CDPATH *cdp;
- char *dir; /* XXX END OF THE STACK, DON'T TRUST GETCWD. */
- char buf[MAXPATHLEN * 2];
-
- /*
- * !!!
- * Historic practice is that the cd isn't attempted if the file has
- * been modified, unless its name begins with a leading '/' or the
- * force flag is set.
- */
- if (F_ISSET(ep, F_MODIFIED) &&
- !F_ISSET(cmdp, E_FORCE) && sp->frp->name[0] != '/') {
- msgq(sp, M_ERR,
- "File modified since last complete write; write or use ! to override");
- return (1);
- }
-
- switch (cmdp->argc) {
- case 0:
- /* If no argument, change to the user's home directory. */
- if ((dir = getenv("HOME")) == NULL) {
- if ((pw = getpwuid(getuid())) == NULL ||
- pw->pw_dir == NULL || pw->pw_dir[0] == '\0') {
- msgq(sp, M_ERR,
- "Unable to find home directory location");
- return (1);
- }
- dir = pw->pw_dir;
- }
- break;
- case 1:
- dir = cmdp->argv[0]->bp;
- break;
- default:
- abort();
- }
-
- /* Try the current directory first. */
- if (!chdir(dir))
- goto ret;
-
- /*
- * If moving to the user's home directory, or, the path begins with
- * "/", "./" or "../", it's the only place we try.
- */
- if (cmdp->argc == 0 ||
- (ap = cmdp->argv[0])->bp[0] == '/' ||
- ap->len == 1 && ap->bp[0] == '.' ||
- ap->len >= 2 && ap->bp[0] == '.' && ap->bp[1] == '.' &&
- (ap->bp[2] == '/' || ap->bp[2] == '\0'))
- goto err;
-
- /* If the user has a CDPATH variable, try its elements. */
- for (cdp = EXP(sp)->cdq.tqh_first; cdp != NULL; cdp = cdp->q.tqe_next) {
- (void)snprintf(buf, sizeof(buf), "%s/%s", cdp->path, dir);
- if (!chdir(buf)) {
-ret: if (getcwd(buf, sizeof(buf)) != NULL)
- msgq(sp, M_INFO, "New directory: %s", buf);
- return (0);
- }
- }
-err: msgq(sp, M_SYSERR, "%s", dir);
- return (1);
-}
-
-#define FREE_CDPATH(cdp) { \
- TAILQ_REMOVE(&exp->cdq, (cdp), q); \
- free((cdp)->path); \
- FREE((cdp), sizeof(CDPATH)); \
-}
-/*
- * ex_cdalloc --
- * Create a new list of cd paths.
- */
-int
-ex_cdalloc(sp, str)
- SCR *sp;
- char *str;
-{
- EX_PRIVATE *exp;
- CDPATH *cdp;
- size_t len;
- int founddot;
- char *p, *t;
-
- /* Free current queue. */
- exp = EXP(sp);
- while ((cdp = exp->cdq.tqh_first) != NULL)
- FREE_CDPATH(cdp);
-
- /*
- * Create new queue. The CDPATH environmental variable (and the
- * user's manual entry) are delimited by colon characters.
- */
- for (p = t = str, founddot = 0;; ++p) {
- if (*p == '\0' || *p == ':') {
- /*
- * Empty strings specify ".". The only way to get an
- * empty string is a leading colon, colons in a row,
- * or a trailing colon. Or, to put it the other way,
- * if the the length is zero, then it's either ":XXX",
- * "XXX::XXXX" , "XXX:", or "", and the only failure
- * mode is the last one. Note, the string ":" gives
- * us two entries of '.', so we only include one of
- * them.
- */
- if ((len = p - t) == 0) {
- if (p == str && *p == '\0')
- break;
- if (founddot) {
- if (*p == '\0')
- break;
- continue;
- }
- len = 1;
- t = ".";
- founddot = 1;
- }
- MALLOC_RET(sp, cdp, CDPATH *, sizeof(CDPATH));
- MALLOC(sp, cdp->path, char *, len + 1);
- if (cdp->path == NULL) {
- free(cdp);
- return (1);
- }
- memmove(cdp->path, t, len);
- cdp->path[len] = '\0';
- TAILQ_INSERT_TAIL(&exp->cdq, cdp, q);
- t = p + 1;
- }
- if (*p == '\0')
- break;
- }
- return (0);
-}
- /* Free previous queue. */
-/*
- * ex_cdfree --
- * Free the cd path list.
- */
-int
-ex_cdfree(sp)
- SCR *sp;
-{
- EX_PRIVATE *exp;
- CDPATH *cdp;
-
- /* Free up cd path information. */
- exp = EXP(sp);
- while ((cdp = exp->cdq.tqh_first) != NULL)
- FREE_CDPATH(cdp);
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_delete.c b/usr.bin/vi/ex/ex_delete.c
deleted file mode 100644
index 4e1d241..0000000
--- a/usr.bin/vi/ex/ex_delete.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_delete.c 8.14 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_delete: [line [,line]] d[elete] [buffer] [count] [flags]
- *
- * Delete lines from the file.
- */
-int
-ex_delete(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- recno_t lno;
-
- /*
- * !!!
- * Historically, lines deleted in ex were not placed in the numeric
- * buffers. We follow historic practice so that we don't overwrite
- * vi buffers accidentally.
- */
- if (cut(sp, ep,
- F_ISSET(cmdp, E_BUFFER) ? &cmdp->buffer : NULL,
- &cmdp->addr1, &cmdp->addr2, CUT_LINEMODE))
- return (1);
-
- /* Delete the lines. */
- if (delete(sp, ep, &cmdp->addr1, &cmdp->addr2, 1))
- return (1);
-
- /* Set the cursor to the line after the last line deleted. */
- sp->lno = cmdp->addr1.lno;
-
- /* Or the last line in the file if deleted to the end of the file. */
- if (file_lline(sp, ep, &lno))
- return (1);
- if (sp->lno > lno)
- sp->lno = lno;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_digraph.c b/usr.bin/vi/ex/ex_digraph.c
deleted file mode 100644
index 0db20bb..0000000
--- a/usr.bin/vi/ex/ex_digraph.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_digraph.c 8.8 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#ifndef NO_DIGRAPH
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <curses.h>
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-static void do_digraph __P((SCR *, EXF *, int, u_char *));
-
-/* This stuff is used to build the default digraphs table. */
-static u_char digtable[][4] = {
-# ifdef CS_IBMPC
- "C,\200", "u\"\1", "e'\2", "a^\3",
- "a\"\4", "a`\5", "a@\6", "c,\7",
- "e^\10", "e\"\211", "e`\12", "i\"\13",
- "i^\14", "i`\15", "A\"\16", "A@\17",
- "E'\20", "ae\21", "AE\22", "o^\23",
- "o\"\24", "o`\25", "u^\26", "u`\27",
- "y\"\30", "O\"\31", "U\"\32", "a'\240",
- "i'!", "o'\"", "u'#", "n~$",
- "N~%", "a-&", "o-'", "~?(",
- "~!-", "\"<.", "\">/",
-# ifdef CS_SPECIAL
- "2/+", "4/,", "^+;", "^q<",
- "^c=", "^r>", "^t?", "pp]",
- "^^^", "oo_", "*a`", "*ba",
- "*pc", "*Sd", "*se", "*uf",
- "*tg", "*Ph", "*Ti", "*Oj",
- "*dk", "*Hl", "*hm", "*En",
- "*No", "eqp", "pmq", "ger",
- "les", "*It", "*iu", "*/v",
- "*=w", "sq{", "^n|", "^2}",
- "^3~", "^_\377",
-# endif /* CS_SPECIAL */
-# endif /* CS_IBMPC */
-# ifdef CS_LATIN1
- "~!!", "a-*", "\">+", "o-:",
- "\"<>", "~??",
-
- "A`@", "A'A", "A^B", "A~C",
- "A\"D", "A@E", "AEF", "C,G",
- "E`H", "E'I", "E^J", "E\"K",
- "I`L", "I'M", "I^N", "I\"O",
- "-DP", "N~Q", "O`R", "O'S",
- "O^T", "O~U", "O\"V", "O/X",
- "U`Y", "U'Z", "U^[", "U\"\\",
- "Y'_",
-
- "a``", "a'a", "a^b", "a~c",
- "a\"d", "a@e", "aef", "c,g",
- "e`h", "e'i", "e^j", "e\"k",
- "i`l", "i'm", "i^n", "i\"o",
- "-dp", "n~q", "o`r", "o's",
- "o^t", "o~u", "o\"v", "o/x",
- "u`y", "u'z", "u^{", "u\"|",
- "y'~",
-# endif /* CS_LATIN1 */
- ""
-};
-
-int
-digraph_init(sp)
- SCR *sp;
-{
- int i;
-
- for (i = 0; *digtable[i]; i++)
- do_digraph(sp, NULL, 0, digtable[i]);
- do_digraph(sp, NULL, 0, NULL);
- return (0);
-}
-
-int
-ex_digraph(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- do_digraph(sp, ep, F_ISSET(cmdp, E_FORCE), cmdp->argv[0]->bp);
- return (0);
-}
-
-static struct _DIG
-{
- struct _DIG *next;
- char key1;
- char key2;
- char dig;
- char save;
-} *digs;
-
-int
-digraph(sp, key1, key2)
- SCR *sp;
- char key1; /* the underlying character */
- char key2; /* the second character */
-{
- int new_key;
- register struct _DIG *dp;
-
- /* if digraphs are disabled, then just return the new char */
- if (O_ISSET(sp, O_DIGRAPH))
- {
- return key2;
- }
-
- /* remember the new key, so we can return it if this isn't a digraph */
- new_key = key2;
-
- /* sort key1 and key2, so that their original order won't matter */
- if (key1 > key2)
- {
- key2 = key1;
- key1 = new_key;
- }
-
- /* scan through the digraph chart */
- for (dp = digs;
- dp && (dp->key1 != key1 || dp->key2 != key2);
- dp = dp->next)
- {
- }
-
- /* if this combination isn't in there, just use the new key */
- if (!dp)
- {
- return new_key;
- }
-
- /* else use the digraph key */
- return dp->dig;
-}
-
-/* this function lists or defines digraphs */
-static void
-do_digraph(sp, ep, bang, extra)
- SCR *sp;
- EXF *ep;
- int bang;
- u_char *extra;
-{
- int dig;
- register struct _DIG *dp;
- struct _DIG *prev;
- static int user_defined = 0; /* boolean: are all later digraphs user-defined? */
- char listbuf[8];
-
- /* if "extra" is NULL, then we've reached the end of the built-ins */
- if (!extra)
- {
- user_defined = 1;
- return;
- }
-
- /* if no args, then display the existing digraphs */
- if (*extra < ' ')
- {
- listbuf[0] = listbuf[1] = listbuf[2] = listbuf[5] = ' ';
- listbuf[7] = '\0';
- for (dig = 0, dp = digs; dp; dp = dp->next)
- {
- if (dp->save || bang)
- {
- dig += 7;
- if (dig >= sp->cno)
- {
- addch('\n');
- refresh();
- dig = 7;
- }
- listbuf[3] = dp->key1;
- listbuf[4] = dp->key2;
- listbuf[6] = dp->dig;
- addstr(listbuf);
- }
- }
- addch('\n');
- refresh();
- return;
- }
-
- /* make sure we have at least two characters */
- if (!extra[1])
- {
- msgq(sp, M_ERR,
- "Digraphs must be composed of two characters");
- return;
- }
-
- /* sort key1 and key2, so that their original order won't matter */
- if (extra[0] > extra[1])
- {
- dig = extra[0];
- extra[0] = extra[1];
- extra[1] = dig;
- }
-
- /* locate the new digraph character */
- for (dig = 2; extra[dig] == ' ' || extra[dig] == '\t'; dig++)
- {
- }
- dig = extra[dig];
- if (!bang && dig)
- {
- dig |= 0x80;
- }
-
- /* search for the digraph */
- for (prev = (struct _DIG *)0, dp = digs;
- dp && (dp->key1 != extra[0] || dp->key2 != extra[1]);
- prev = dp, dp = dp->next)
- {
- }
-
- /* deleting the digraph? */
- if (!dig)
- {
- if (!dp)
- {
-#ifndef CRUNCH
- msgq(sp, M_ERR,
- "%c%c not a digraph", extra[0], extra[1]);
-#endif
- return;
- }
- if (prev)
- prev->next = dp->next;
- else
- digs = dp->next;
- free(dp);
- return;
- }
-
- /* if necessary, create a new digraph struct for the new digraph */
- if (dig && !dp)
- {
- MALLOC(sp, dp, struct _DIG *, sizeof(struct _DIG));
- if (dp == NULL)
- return;
- if (prev)
- prev->next = dp;
- else
- digs = dp;
- dp->next = (struct _DIG *)0;
- }
-
- /* assign it the new digraph value */
- dp->key1 = extra[0];
- dp->key2 = extra[1];
- dp->dig = dig;
- dp->save = user_defined;
-}
-
-void
-digraph_save(sp, fd)
- SCR *sp;
- int fd;
-{
- static char buf[] = "digraph! XX Y\n";
- register struct _DIG *dp;
-
- for (dp = digs; dp; dp = dp->next)
- {
- if (dp->save)
- {
- buf[9] = dp->key1;
- buf[10] = dp->key2;
- buf[12] = dp->dig;
- write(fd, buf, (unsigned)14);
- }
- }
-}
-#endif
diff --git a/usr.bin/vi/ex/ex_display.c b/usr.bin/vi/ex/ex_display.c
deleted file mode 100644
index 7f90ef2..0000000
--- a/usr.bin/vi/ex/ex_display.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_display.c 8.23 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "tag.h"
-#include "excmd.h"
-
-static int bdisplay __P((SCR *, EXF *));
-static void db __P((SCR *, CB *, CHAR_T *));
-
-/*
- * ex_display -- :display b[uffers] | s[creens] | t[ags]
- *
- * Display buffers, tags or screens.
- */
-int
-ex_display(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- switch (cmdp->argv[0]->bp[0]) {
- case 'b':
-#undef ARG
-#define ARG "buffers"
- if (cmdp->argv[0]->len >= sizeof(ARG) ||
- memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len))
- break;
- return (bdisplay(sp, ep));
- case 's':
-#undef ARG
-#define ARG "screens"
- if (cmdp->argv[0]->len >= sizeof(ARG) ||
- memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len))
- break;
- return (ex_sdisplay(sp, ep));
- case 't':
-#undef ARG
-#define ARG "tags"
- if (cmdp->argv[0]->len >= sizeof(ARG) ||
- memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len))
- break;
- return (ex_tagdisplay(sp, ep));
- }
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
-}
-
-/*
- * bdisplay --
- *
- * Display buffers.
- */
-static int
-bdisplay(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- CB *cbp;
-
- if (sp->gp->cutq.lh_first == NULL && sp->gp->dcbp == NULL) {
- (void)ex_printf(EXCOOKIE, "No cut buffers to display.\n");
- return (0);
- }
-
- /* Buffers can be infinitely long, make it interruptible. */
- F_SET(sp, S_INTERRUPTIBLE);
-
- /* Display regular cut buffers. */
- for (cbp = sp->gp->cutq.lh_first; cbp != NULL; cbp = cbp->q.le_next) {
- if (isdigit(cbp->name))
- continue;
- if (cbp->textq.cqh_first != (void *)&cbp->textq)
- db(sp, cbp, NULL);
- if (INTERRUPTED(sp))
- return (0);
- }
- /* Display numbered buffers. */
- for (cbp = sp->gp->cutq.lh_first; cbp != NULL; cbp = cbp->q.le_next) {
- if (!isdigit(cbp->name))
- continue;
- if (cbp->textq.cqh_first != (void *)&cbp->textq)
- db(sp, cbp, NULL);
- if (INTERRUPTED(sp))
- return (0);
- }
- /* Display default buffer. */
- if ((cbp = sp->gp->dcbp) != NULL)
- db(sp, cbp, "default buffer");
- return (0);
-}
-
-/*
- * db --
- * Display a buffer.
- */
-static void
-db(sp, cbp, name)
- SCR *sp;
- CB *cbp;
- CHAR_T *name;
-{
- CHAR_T *p;
- TEXT *tp;
- size_t len;
-
- (void)ex_printf(EXCOOKIE, "********** %s%s\n",
- name == NULL ? KEY_NAME(sp, cbp->name) : name,
- F_ISSET(cbp, CB_LMODE) ? " (line mode)" : " (character mode)");
- for (tp = cbp->textq.cqh_first;
- tp != (void *)&cbp->textq; tp = tp->q.cqe_next) {
- for (len = tp->len, p = tp->lb; len--; ++p) {
- (void)ex_printf(EXCOOKIE, "%s", KEY_NAME(sp, *p));
- if (INTERRUPTED(sp))
- return;
- }
- (void)ex_printf(EXCOOKIE, "\n");
- }
-}
diff --git a/usr.bin/vi/ex/ex_edit.c b/usr.bin/vi/ex/ex_edit.c
deleted file mode 100644
index 5a54e73..0000000
--- a/usr.bin/vi/ex/ex_edit.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_edit.c 8.20 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_edit -- :e[dit][!] [+cmd] [file]
- * :vi[sual][!] [+cmd] [file]
- *
- * Edit a file; if none specified, re-edit the current file. The second
- * form of the command can only be executed while in vi mode. See the
- * hack in ex.c:ex_cmd().
- *
- * !!!
- * Historic vi didn't permit the '+' command form without specifying
- * a file name as well.
- */
-int
-ex_edit(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- ARGS *ap;
- FREF *frp;
-
- frp = sp->frp;
- switch (cmdp->argc) {
- case 0:
- /*
- * If the name has been changed, we edit that file, not the
- * original name. If the user was editing a temporary file,
- * create another one. The reason for this is that we do
- * special exit processing of temporary files, and reusing
- * them is tricky.
- */
- if (F_ISSET(frp, FR_TMPFILE)) {
- if ((frp = file_add(sp, NULL)) == NULL)
- return (1);
- } else {
- if ((frp = file_add(sp, frp->name)) == NULL)
- return (1);
- set_alt_name(sp, sp->frp->name);
- }
- break;
- case 1:
- ap = cmdp->argv[0];
- if ((frp = file_add(sp, ap->bp)) == NULL)
- return (1);
- set_alt_name(sp, ap->bp);
- break;
- default:
- abort();
- }
-
- /*
- * Check for modifications.
- *
- * !!!
- * Contrary to POSIX 1003.2-1992, autowrite did not affect :edit.
- */
- if (file_m2(sp, ep, F_ISSET(cmdp, E_FORCE)))
- return (1);
-
- /* Switch files. */
- if (file_init(sp, frp, NULL, F_ISSET(cmdp, E_FORCE)))
- return (1);
- F_SET(sp, S_FSWITCH);
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_equal.c b/usr.bin/vi/ex/ex_equal.c
deleted file mode 100644
index ec979a0..0000000
--- a/usr.bin/vi/ex/ex_equal.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_equal.c 8.8 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_equal -- :address =
- */
-int
-ex_equal(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- recno_t lno;
-
- /*
- * Print out the line number matching the specified address,
- * or the number of the last line in the file if no address
- * specified.
- *
- * !!!
- * Historically, ":0=" displayed 0, and ":=" or ":1=" in an
- * empty file displayed 1. Until somebody complains loudly,
- * we're going to do it right. The tables in excmd.c permit
- * lno to get away with any address from 0 to the end of the
- * file, which, in an empty file, is 0.
- */
- if (F_ISSET(cmdp, E_ADDRDEF)) {
- if (file_lline(sp, ep, &lno))
- return (1);
- } else
- lno = cmdp->addr1.lno;
-
- (void)ex_printf(EXCOOKIE, "%ld\n", lno);
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_exit.c b/usr.bin/vi/ex/ex_exit.c
deleted file mode 100644
index 79c4039..0000000
--- a/usr.bin/vi/ex/ex_exit.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_exit.c 8.15 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_quit -- :quit[!]
- * Quit.
- */
-int
-ex_quit(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- int force;
-
- force = F_ISSET(cmdp, E_FORCE);
-
- /* Check for modifications. */
- if (file_m2(sp, ep, force))
- return (1);
-
- /* Check for more files to edit. */
- if (ex_ncheck(sp, force))
- return (1);
-
- F_SET(sp, force ? S_EXIT_FORCE : S_EXIT);
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_file.c b/usr.bin/vi/ex/ex_file.c
deleted file mode 100644
index cf5f329..0000000
--- a/usr.bin/vi/ex/ex_file.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_file.c 8.12 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_file -- :f[ile] [name]
- * Change the file's name and display the status line.
- */
-int
-ex_file(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- CHAR_T *p;
- FREF *frp;
-
- switch (cmdp->argc) {
- case 0:
- break;
- case 1:
- frp = sp->frp;
-
- /* Make sure can allocate enough space. */
- if ((p = v_strdup(sp,
- cmdp->argv[0]->bp, cmdp->argv[0]->len)) == NULL)
- return (1);
-
- /* If already have a file name, it becomes the alternate. */
- if (!F_ISSET(frp, FR_TMPFILE))
- set_alt_name(sp, frp->name);
-
- /* Free the previous name. */
- free(frp->name);
- frp->name = p;
-
- /*
- * The read-only bit follows the file name; clear it.
- * The file has a real name, it's no longer a temporary.
- */
- F_CLR(frp, FR_RDONLY | FR_TMPFILE);
-
- /* Have to force a write if the file exists, next time. */
- F_SET(frp, FR_NAMECHANGE);
- break;
- default:
- abort();
- }
- return (msg_status(sp, ep, sp->lno, 1));
-}
diff --git a/usr.bin/vi/ex/ex_global.c b/usr.bin/vi/ex/ex_global.c
deleted file mode 100644
index 5fb134d..0000000
--- a/usr.bin/vi/ex/ex_global.c
+++ /dev/null
@@ -1,400 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_global.c 8.43 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-enum which {GLOBAL, VGLOBAL};
-
-static int global __P((SCR *, EXF *, EXCMDARG *, enum which));
-
-/*
- * ex_global -- [line [,line]] g[lobal][!] /pattern/ [commands]
- * Exec on lines matching a pattern.
- */
-int
-ex_global(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (global(sp, ep,
- cmdp, F_ISSET(cmdp, E_FORCE) ? VGLOBAL : GLOBAL));
-}
-
-/*
- * ex_vglobal -- [line [,line]] v[global] /pattern/ [commands]
- * Exec on lines not matching a pattern.
- */
-int
-ex_vglobal(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (global(sp, ep, cmdp, VGLOBAL));
-}
-
-static int
-global(sp, ep, cmdp, cmd)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
- enum which cmd;
-{
- MARK abs;
- RANGE *rp;
- EX_PRIVATE *exp;
- recno_t elno, lno;
- regmatch_t match[1];
- regex_t *re, lre;
- size_t clen, len;
- int delim, eval, reflags, replaced, rval;
- char *cb, *ptrn, *p, *t;
-
- /*
- * Skip leading white space. Historic vi allowed any non-
- * alphanumeric to serve as the global command delimiter.
- */
- for (p = cmdp->argv[0]->bp; isblank(*p); ++p);
- if (*p == '\0' || isalnum(*p)) {
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
- delim = *p++;
-
- /*
- * Get the pattern string, toss escaped characters.
- *
- * QUOTING NOTE:
- * Only toss an escaped character if it escapes a delimiter.
- */
- for (ptrn = t = p;;) {
- if (p[0] == '\0' || p[0] == delim) {
- if (p[0] == delim)
- ++p;
- /*
- * !!!
- * Nul terminate the pattern string -- it's passed
- * to regcomp which doesn't understand anything else.
- */
- *t = '\0';
- break;
- }
- if (p[0] == '\\' && p[1] == delim)
- ++p;
- *t++ = *p++;
- }
-
- /* If the pattern string is empty, use the last one. */
- if (*ptrn == '\0') {
- if (!F_ISSET(sp, S_SRE_SET)) {
- msgq(sp, M_ERR, "No previous regular expression");
- return (1);
- }
- re = &sp->sre;
- } else {
- /* Set RE flags. */
- reflags = 0;
- if (O_ISSET(sp, O_EXTENDED))
- reflags |= REG_EXTENDED;
- if (O_ISSET(sp, O_IGNORECASE))
- reflags |= REG_ICASE;
-
- /* Convert vi-style RE's to POSIX 1003.2 RE's. */
- if (re_conv(sp, &ptrn, &replaced))
- return (1);
-
- /* Compile the RE. */
- re = &lre;
- eval = regcomp(re, ptrn, reflags);
-
- /* Free up any allocated memory. */
- if (replaced)
- FREE_SPACE(sp, ptrn, 0);
-
- if (eval) {
- re_error(sp, eval, re);
- return (1);
- }
-
- /*
- * Set saved RE. Historic practice is that
- * globals set direction as well as the RE.
- */
- sp->sre = lre;
- sp->searchdir = FORWARD;
- F_SET(sp, S_SRE_SET);
- }
-
- /*
- * Get a copy of the command string; the default command is print.
- * Don't worry about a set of <blank>s with no command, that will
- * default to print in the ex parser.
- */
- if ((clen = strlen(p)) == 0) {
- p = "p";
- clen = 1;
- }
- MALLOC_RET(sp, cb, char *, clen);
- memmove(cb, p, clen);
-
- /*
- * The global commands sets the substitute RE as well as
- * the everything-else RE.
- */
- sp->subre = sp->sre;
- F_SET(sp, S_SUBRE_SET);
-
- /* Set the global flag. */
- F_SET(sp, S_GLOBAL);
-
- /* The global commands always set the previous context mark. */
- abs.lno = sp->lno;
- abs.cno = sp->cno;
- if (mark_set(sp, ep, ABSMARK1, &abs, 1))
- goto err;
-
- /*
- * For each line... The semantics of global matching are that we first
- * have to decide which lines are going to get passed to the command,
- * and then pass them to the command, ignoring other changes. There's
- * really no way to do this in a single pass, since arbitrary line
- * creation, deletion and movement can be done in the ex command. For
- * example, a good vi clone test is ":g/X/mo.-3", or "g/X/.,.+1d".
- * What we do is create linked list of lines that are tracked through
- * each ex command. There's a callback routine which the DB interface
- * routines call when a line is created or deleted. This doesn't help
- * the layering much.
- */
- exp = EXP(sp);
- for (rval = 0, lno = cmdp->addr1.lno,
- elno = cmdp->addr2.lno; lno <= elno; ++lno) {
- /* Someone's unhappy, time to stop. */
- if (INTERRUPTED(sp))
- goto interrupted;
-
- /* Get the line and search for a match. */
- if ((t = file_gline(sp, ep, lno, &len)) == NULL) {
- GETLINE_ERR(sp, lno);
- goto err;
- }
- match[0].rm_so = 0;
- match[0].rm_eo = len;
- switch(eval = regexec(re, t, 1, match, REG_STARTEND)) {
- case 0:
- if (cmd == VGLOBAL)
- continue;
- break;
- case REG_NOMATCH:
- if (cmd == GLOBAL)
- continue;
- break;
- default:
- re_error(sp, eval, re);
- goto err;
- }
-
- /* If follows the last entry, extend the last entry's range. */
- if ((rp = exp->rangeq.cqh_last) != (void *)&exp->rangeq &&
- rp->stop == lno - 1) {
- ++rp->stop;
- continue;
- }
-
- /* Allocate a new range, and append it to the list. */
- CALLOC(sp, rp, RANGE *, 1, sizeof(RANGE));
- if (rp == NULL)
- goto err;
- rp->start = rp->stop = lno;
- CIRCLEQ_INSERT_TAIL(&exp->rangeq, rp, q);
- }
-
- exp = EXP(sp);
- exp->range_lno = OOBLNO;
- for (;;) {
- /*
- * Start at the beginning of the range each time, it may have
- * been changed (or exhausted) if lines were inserted/deleted.
- */
- if ((rp = exp->rangeq.cqh_first) == (void *)&exp->rangeq)
- break;
- if (rp->start > rp->stop) {
- CIRCLEQ_REMOVE(&exp->rangeq, exp->rangeq.cqh_first, q);
- free(rp);
- continue;
- }
-
- /*
- * Execute the command, setting the cursor to the line so that
- * relative addressing works. This means that the cursor moves
- * to the last line sent to the command, by default, even if
- * the command fails.
- */
- exp->range_lno = sp->lno = rp->start++;
- if (ex_cmd(sp, ep, cb, clen, 0))
- goto err;
-
- /* Someone's unhappy, time to stop. */
- if (INTERRUPTED(sp)) {
-interrupted: msgq(sp, M_INFO, "Interrupted");
- break;
- }
- }
-
- /* Set the cursor to the new value, making sure it exists. */
- if (exp->range_lno != OOBLNO) {
- if (file_lline(sp, ep, &lno))
- return (1);
- sp->lno =
- lno < exp->range_lno ? (lno ? lno : 1) : exp->range_lno;
- }
- if (0) {
-err: rval = 1;
- }
-
- /* Command we ran may have set the autoprint flag, clear it. */
- F_CLR(exp, EX_AUTOPRINT);
-
- /* Clear the global flag. */
- F_CLR(sp, S_GLOBAL);
-
- /* Free any remaining ranges and the command buffer. */
- while ((rp = exp->rangeq.cqh_first) != (void *)&exp->rangeq) {
- CIRCLEQ_REMOVE(&exp->rangeq, exp->rangeq.cqh_first, q);
- free(rp);
- }
- free(cb);
- return (rval);
-}
-
-/*
- * global_insdel --
- * Update the ranges based on an insertion or deletion.
- */
-void
-global_insdel(sp, ep, op, lno)
- SCR *sp;
- EXF *ep;
- enum operation op;
- recno_t lno;
-{
- EX_PRIVATE *exp;
- RANGE *nrp, *rp;
-
- exp = EXP(sp);
-
- switch (op) {
- case LINE_APPEND:
- return;
- case LINE_DELETE:
- for (rp = exp->rangeq.cqh_first;
- rp != (void *)&exp->rangeq; rp = nrp) {
- nrp = rp->q.cqe_next;
- /* If range less than the line, ignore it. */
- if (rp->stop < lno)
- continue;
- /* If range greater than the line, decrement range. */
- if (rp->start > lno) {
- --rp->start;
- --rp->stop;
- continue;
- }
- /* Lno is inside the range, decrement the end point. */
- if (rp->start > --rp->stop) {
- CIRCLEQ_REMOVE(&exp->rangeq, rp, q);
- free(rp);
- }
- }
- break;
- case LINE_INSERT:
- for (rp = exp->rangeq.cqh_first;
- rp != (void *)&exp->rangeq; rp = rp->q.cqe_next) {
- /* If range less than the line, ignore it. */
- if (rp->stop < lno)
- continue;
- /* If range greater than the line, increment range. */
- if (rp->start >= lno) {
- ++rp->start;
- ++rp->stop;
- continue;
- }
- /*
- * Lno is inside the range, so the range must be split.
- * Since we're inserting a new element, neither range
- * can be exhausted.
- */
- CALLOC(sp, nrp, RANGE *, 1, sizeof(RANGE));
- if (nrp == NULL) {
- F_SET(sp, S_INTERRUPTED);
- return;
- }
- nrp->start = lno + 1;
- nrp->stop = rp->stop + 1;
- rp->stop = lno - 1;
- CIRCLEQ_INSERT_AFTER(&exp->rangeq, rp, nrp, q);
- rp = nrp;
- }
- break;
- case LINE_RESET:
- return;
- }
- /*
- * If the command deleted/inserted lines, the cursor moves to
- * the line after the deleted/inserted line.
- */
- exp->range_lno = lno;
-}
diff --git a/usr.bin/vi/ex/ex_init.c b/usr.bin/vi/ex/ex_init.c
deleted file mode 100644
index 46f9c37..0000000
--- a/usr.bin/vi/ex/ex_init.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_init.c 8.18 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "tag.h"
-
-/*
- * ex_screen_copy --
- * Copy ex screen.
- */
-int
-ex_screen_copy(orig, sp)
- SCR *orig, *sp;
-{
- EX_PRIVATE *oexp, *nexp;
-
- /* Create the private ex structure. */
- CALLOC_RET(orig, nexp, EX_PRIVATE *, 1, sizeof(EX_PRIVATE));
- sp->ex_private = nexp;
-
- /* Initialize queues. */
- TAILQ_INIT(&nexp->tagq);
- TAILQ_INIT(&nexp->tagfq);
- TAILQ_INIT(&nexp->cdq);
- CIRCLEQ_INIT(&nexp->rangeq);
-
- if (orig == NULL) {
- nexp->at_lbuf_set = 0;
- } else {
- oexp = EXP(orig);
-
- nexp->at_lbuf = oexp->at_lbuf;
- nexp->at_lbuf_set = oexp->at_lbuf_set;
-
- if (oexp->lastbcomm != NULL &&
- (nexp->lastbcomm = strdup(oexp->lastbcomm)) == NULL) {
- msgq(sp, M_SYSERR, NULL);
- return(1);
- }
-
- if (ex_tagcopy(orig, sp))
- return (1);
- }
- return (0);
-}
-
-/*
- * ex_screen_end --
- * End a vi screen.
- */
-int
-ex_screen_end(sp)
- SCR *sp;
-{
- EX_PRIVATE *exp;
- int rval;
-
- rval = 0;
- exp = EXP(sp);
-
- if (argv_free(sp))
- rval = 1;
-
- if (exp->ibp != NULL)
- FREE(exp->ibp, exp->ibp_len);
-
- if (exp->lastbcomm != NULL)
- FREE(exp->lastbcomm, strlen(exp->lastbcomm) + 1);
-
- if (ex_tagfree(sp))
- rval = 1;
-
- if (ex_cdfree(sp))
- rval = 1;
-
- /* Free private memory. */
- FREE(exp, sizeof(EX_PRIVATE));
- sp->ex_private = NULL;
-
- return (rval);
-}
-
-/*
- * ex_init --
- * Initialize ex.
- */
-int
-ex_init(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- size_t len;
-
- /*
- * The default address is the last line of the file. If the address
- * set bit is on for this file, load the address, ensuring that it
- * exists.
- */
- if (F_ISSET(sp->frp, FR_CURSORSET)) {
- sp->lno = sp->frp->lno;
- sp->cno = sp->frp->cno;
-
- if (file_gline(sp, ep, sp->lno, &len) == NULL) {
- if (file_lline(sp, ep, &sp->lno))
- return (1);
- if (sp->lno == 0)
- sp->lno = 1;
- sp->cno = 0;
- } else if (sp->cno >= len)
- sp->cno = 0;
- } else {
- if (file_lline(sp, ep, &sp->lno))
- return (1);
- if (sp->lno == 0)
- sp->lno = 1;
- sp->cno = 0;
- }
-
- /* Display the status line. */
- return (msg_status(sp, ep, sp->lno, 0));
-}
-
-/*
- * ex_end --
- * End ex session.
- */
-int
-ex_end(sp)
- SCR *sp;
-{
- return (0);
-}
-
-/*
- * ex_optchange --
- * Handle change of options for vi.
- */
-int
-ex_optchange(sp, opt)
- SCR *sp;
- int opt;
-{
- switch (opt) {
- case O_CDPATH:
- return (ex_cdalloc(sp, O_STR(sp, O_CDPATH)));
- case O_TAGS:
- return (ex_tagalloc(sp, O_STR(sp, O_TAGS)));
- }
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_join.c b/usr.bin/vi/ex/ex_join.c
deleted file mode 100644
index 4ac045b..0000000
--- a/usr.bin/vi/ex/ex_join.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_join.c 8.14 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_join -- :[line [,line]] j[oin][!] [count] [flags]
- * Join lines.
- */
-int
-ex_join(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- recno_t from, to;
- size_t blen, clen, len, tlen;
- int echar, extra, first;
- char *bp, *p, *tbp;
-
- from = cmdp->addr1.lno;
- to = cmdp->addr2.lno;
-
- /* Check for no lines to join. */
- if ((p = file_gline(sp, ep, from + 1, &len)) == NULL) {
- msgq(sp, M_ERR, "No following lines to join");
- return (1);
- }
-
- GET_SPACE_RET(sp, bp, blen, 256);
-
- /*
- * The count for the join command was off-by-one,
- * historically, to other counts for other commands.
- */
- if (F_ISSET(cmdp, E_COUNT))
- ++cmdp->addr2.lno;
-
- /*
- * If only a single address specified, or, the same address
- * specified twice, the from/two addresses will be the same.
- */
- if (cmdp->addr1.lno == cmdp->addr2.lno)
- ++cmdp->addr2.lno;
-
- clen = tlen = 0;
- for (first = 1,
- from = cmdp->addr1.lno, to = cmdp->addr2.lno; from <= to; ++from) {
- /*
- * Get next line. Historic versions of vi allowed "10J" while
- * less than 10 lines from the end-of-file, so we do too.
- */
- if ((p = file_gline(sp, ep, from, &len)) == NULL) {
- cmdp->addr2.lno = from - 1;
- break;
- }
-
- /* Empty lines just go away. */
- if (len == 0)
- continue;
-
- /*
- * Get more space if necessary. Note, tlen isn't the length
- * of the new line, it's roughly the amount of space needed.
- * tbp - bp is the length of the new line.
- */
- tlen += len + 2;
- ADD_SPACE_RET(sp, bp, blen, tlen);
- tbp = bp + clen;
-
- /*
- * Historic practice:
- *
- * If force specified, join without modification.
- * If the current line ends with whitespace, strip leading
- * whitespace from the joined line.
- * If the next line starts with a ), do nothing.
- * If the current line ends with ., ? or !, insert two spaces.
- * Else, insert one space.
- *
- * Echar is the last character in the last line joined.
- */
- extra = 0;
- if (!first && !F_ISSET(cmdp, E_FORCE)) {
- if (isblank(echar))
- for (; len && isblank(*p); --len, ++p);
- else if (p[0] != ')') {
- if (strchr(".?!", echar)) {
- *tbp++ = ' ';
- ++clen;
- extra = 1;
- }
- *tbp++ = ' ';
- ++clen;
- for (; len && isblank(*p); --len, ++p);
- }
- }
-
- if (len != 0) {
- memmove(tbp, p, len);
- tbp += len;
- clen += len;
- echar = p[len - 1];
- } else
- echar = ' ';
-
- /*
- * Historic practice for vi was to put the cursor at the first
- * inserted whitespace character, if there was one, or the
- * first character of the joined line, if there wasn't, or the
- * last character of the line if joined to an empty line. If
- * a count was specified, the cursor was moved as described
- * for the first line joined, ignoring subsequent lines. If
- * the join was a ':' command, the cursor was placed at the
- * first non-blank character of the line unless the cursor was
- * "attracted" to the end of line when the command was executed
- * in which case it moved to the new end of line. There are
- * probably several more special cases, but frankly, my dear,
- * I don't give a damn. This implementation puts the cursor
- * on the first inserted whitespace character, the first
- * character of the joined line, or the last character of the
- * line regardless. Note, if the cursor isn't on the joined
- * line (possible with : commands), it is reset to the starting
- * line.
- */
- if (first) {
- sp->cno = (tbp - bp) - (1 + extra);
- first = 0;
- } else
- sp->cno = (tbp - bp) - len - (1 + extra);
- }
- sp->lno = cmdp->addr1.lno;
-
- /* Delete the joined lines. */
- for (from = cmdp->addr1.lno, to = cmdp->addr2.lno; to > from; --to)
- if (file_dline(sp, ep, to))
- goto err;
-
- /* If the original line changed, reset it. */
- if (!first && file_sline(sp, ep, from, bp, tbp - bp)) {
-err: FREE_SPACE(sp, bp, blen);
- return (1);
- }
- FREE_SPACE(sp, bp, blen);
-
- sp->rptlines[L_JOINED] += (cmdp->addr2.lno - cmdp->addr1.lno) + 1;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_map.c b/usr.bin/vi/ex/ex_map.c
deleted file mode 100644
index ec67dbd..0000000
--- a/usr.bin/vi/ex/ex_map.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_map.c 8.19 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <curses.h>
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_map -- :map[!] [input] [replacement]
- * Map a key/string or display mapped keys.
- *
- * Historical note:
- * Historic vi maps were fairly bizarre, and likely to differ in
- * very subtle and strange ways from this implementation. Two
- * things worth noting are that vi would often hang or drop core
- * if the map was strange enough (ex: map X "xy$@x^V), or, simply
- * not work. One trick worth remembering is that if you put a
- * mark at the start of the map, e.g. map X mx"xy ...), or if you
- * put the map in a .exrc file, things would often work much better.
- * No clue why.
- */
-int
-ex_map(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- enum seqtype stype;
- CHAR_T *input, *p;
-
- stype = F_ISSET(cmdp, E_FORCE) ? SEQ_INPUT : SEQ_COMMAND;
-
- switch (cmdp->argc) {
- case 0:
- if (seq_dump(sp, stype, 1) == 0)
- msgq(sp, M_INFO, "No %s map entries",
- stype == SEQ_INPUT ? "input" : "command");
- return (0);
- case 2:
- input = cmdp->argv[0]->bp;
- break;
- default:
- abort();
- }
-
- /*
- * If the mapped string is #[0-9]* (and wasn't quoted) then store
- * the function key mapping, and call the screen specific routine.
- * Note, if the screen specific routine is able to create the
- * mapping, the SEQ_FUNCMAP type stays around, maybe the next screen
- * type can get it right.
- */
- if (input[0] == '#') {
- for (p = input + 1; isdigit(*p); ++p);
- if (p[0] != '\0')
- goto nofunc;
-
- if (seq_set(sp, NULL, 0, input, cmdp->argv[0]->len,
- cmdp->argv[1]->bp, cmdp->argv[1]->len, stype, SEQ_FUNCMAP))
- return (1);
- return (sp->s_fmap(sp, stype, input, cmdp->argv[0]->len,
- cmdp->argv[1]->bp, cmdp->argv[1]->len));
- }
-
- /* Some single keys may not be remapped in command mode. */
-nofunc: if (stype == SEQ_COMMAND && input[1] == '\0')
- switch (KEY_VAL(sp, input[0])) {
- case K_COLON:
- case K_ESCAPE:
- case K_NL:
- msgq(sp, M_ERR, "The %s character may not be remapped",
- KEY_NAME(sp, input[0]));
- return (1);
- }
- return (seq_set(sp, NULL, 0, input, cmdp->argv[0]->len,
- cmdp->argv[1]->bp, cmdp->argv[1]->len, stype, SEQ_USERDEF));
-}
-
-/*
- * ex_unmap -- (:unmap[!] key)
- * Unmap a key.
- */
-int
-ex_unmap(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (seq_delete(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len,
- F_ISSET(cmdp, E_FORCE) ? SEQ_INPUT : SEQ_COMMAND)) {
- msgq(sp, M_INFO, "\"%s\" isn't mapped", cmdp->argv[0]->bp);
- return (1);
- }
- return (0);
-}
-
-/*
- * map_save --
- * Save the mapped sequences to a file.
- */
-int
-map_save(sp, fp)
- SCR *sp;
- FILE *fp;
-{
- if (seq_save(sp, fp, "map ", SEQ_COMMAND))
- return (1);
- return (seq_save(sp, fp, "map! ", SEQ_INPUT));
-}
diff --git a/usr.bin/vi/ex/ex_mark.c b/usr.bin/vi/ex/ex_mark.c
deleted file mode 100644
index b74bfb1..0000000
--- a/usr.bin/vi/ex/ex_mark.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_mark.c 8.8 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-int
-ex_mark(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (cmdp->argv[0]->len != 1) {
- msgq(sp, M_ERR, "Mark names must be a single character");
- return (1);
- }
- return (mark_set(sp, ep, cmdp->argv[0]->bp[0], &cmdp->addr1, 1));
-}
diff --git a/usr.bin/vi/ex/ex_mkexrc.c b/usr.bin/vi/ex/ex_mkexrc.c
deleted file mode 100644
index 158fb23..0000000
--- a/usr.bin/vi/ex/ex_mkexrc.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_mkexrc.c 8.14 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-#include <pathnames.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_mkexrc -- :mkexrc[!] [file]
- *
- * Create (or overwrite) a .exrc file with the current info.
- */
-int
-ex_mkexrc(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- struct stat sb;
- FILE *fp;
- int fd, sverrno;
- char *fname;
-
- switch (cmdp->argc) {
- case 0:
- fname = _PATH_EXRC;
- break;
- case 1:
- fname = cmdp->argv[0]->bp;
- set_alt_name(sp, fname);
- break;
- default:
- abort();
- }
-
- if (!F_ISSET(cmdp, E_FORCE) && !stat(fname, &sb)) {
- msgq(sp, M_ERR,
- "%s exists, not written; use ! to override", fname);
- return (1);
- }
-
- /* Create with max permissions of rw-r--r--. */
- if ((fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
- msgq(sp, M_SYSERR, fname);
- return (1);
- }
-
- if ((fp = fdopen(fd, "w")) == NULL) {
- sverrno = errno;
- (void)close(fd);
- errno = sverrno;
- goto e2;
- }
-
- if (abbr_save(sp, fp) || ferror(fp))
- goto e1;
- if (map_save(sp, fp) || ferror(fp))
- goto e1;
- if (opts_save(sp, fp) || ferror(fp))
- goto e1;
-#ifndef NO_DIGRAPH
- digraph_save(sp, fd);
-#endif
- if (fclose(fp))
- goto e2;
-
- msgq(sp, M_INFO, "New .exrc file: %s. ", fname);
- return (0);
-
-e1: sverrno = errno;
- (void)fclose(fp);
- errno = sverrno;
-e2: msgq(sp, M_ERR, "%s: incomplete: %s", fname, strerror(errno));
- return (1);
-}
diff --git a/usr.bin/vi/ex/ex_move.c b/usr.bin/vi/ex/ex_move.c
deleted file mode 100644
index 52a8f53..0000000
--- a/usr.bin/vi/ex/ex_move.c
+++ /dev/null
@@ -1,222 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_move.c 8.19 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_copy -- :[line [,line]] co[py] line [flags]
- * Copy selected lines.
- */
-int
-ex_copy(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- CB cb;
- MARK fm1, fm2, m, tm;
- recno_t cnt;
- int rval;
-
- rval = 0;
-
- /*
- * It's possible to copy things into the area that's being
- * copied, e.g. "2,5copy3" is legitimate. Save the text to
- * a cut buffer.
- */
- fm1 = cmdp->addr1;
- fm2 = cmdp->addr2;
- memset(&cb, 0, sizeof(cb));
- CIRCLEQ_INIT(&cb.textq);
- for (cnt = fm1.lno; cnt <= fm2.lno; ++cnt)
- if (cut_line(sp, ep, cnt, 0, 0, &cb)) {
- rval = 1;
- goto err;
- }
- cb.flags |= CB_LMODE;
-
- /* Put the text into place. */
- tm.lno = cmdp->lineno;
- tm.cno = 0;
- if (put(sp, ep, &cb, NULL, &tm, &m, 1))
- rval = 1;
- else {
- /*
- * Copy puts the cursor on the last line copied. The cursor
- * returned by the put routine is the first line put, not the
- * last, because that's the historic semantic of vi.
- */
- cnt = (fm2.lno - fm1.lno) + 1;
- sp->lno = m.lno + (cnt - 1);
- sp->cno = 0;
- }
-err: text_lfree(&cb.textq);
- return (rval);
-}
-
-/*
- * ex_move -- :[line [,line]] mo[ve] line
- * Move selected lines.
- */
-int
-ex_move(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- LMARK *lmp;
- MARK fm1, fm2;
- recno_t cnt, diff, fl, tl, mfl, mtl;
- size_t blen, len;
- int mark_reset;
- char *bp, *p;
-
- /*
- * It's not possible to move things into the area that's being
- * moved.
- */
- fm1 = cmdp->addr1;
- fm2 = cmdp->addr2;
- if (cmdp->lineno >= fm1.lno && cmdp->lineno <= fm2.lno) {
- msgq(sp, M_ERR, "Destination line is inside move range");
- return (1);
- }
-
- /*
- * Log the positions of any marks in the to-be-deleted lines. This
- * has to work with the logging code. What happens is that we log
- * the old mark positions, make the changes, then log the new mark
- * positions. Then the marks end up in the right positions no matter
- * which way the log is traversed.
- *
- * XXX
- * Reset the MARK_USERSET flag so that the log can undo the mark.
- * This isn't very clean, and should probably be fixed.
- */
- fl = fm1.lno;
- tl = cmdp->lineno;
-
- /* Log the old positions of the marks. */
- mark_reset = 0;
- for (lmp = ep->marks.lh_first; lmp != NULL; lmp = lmp->q.le_next)
- if (lmp->name != ABSMARK1 &&
- lmp->lno >= fl && lmp->lno <= tl) {
- mark_reset = 1;
- F_CLR(lmp, MARK_USERSET);
- (void)log_mark(sp, ep, lmp);
- }
-
- /* Get memory for the copy. */
- GET_SPACE_RET(sp, bp, blen, 256);
-
- /* Move the lines. */
- diff = (fm2.lno - fm1.lno) + 1;
- if (tl > fl) { /* Destination > source. */
- mfl = tl - diff;
- mtl = tl;
- for (cnt = diff; cnt--;) {
- if ((p = file_gline(sp, ep, fl, &len)) == NULL)
- return (1);
- BINC_RET(sp, bp, blen, len);
- memmove(bp, p, len);
- if (file_aline(sp, ep, 1, tl, bp, len))
- return (1);
- if (mark_reset)
- for (lmp = ep->marks.lh_first;
- lmp != NULL; lmp = lmp->q.le_next)
- if (lmp->name != ABSMARK1 &&
- lmp->lno == fl)
- lmp->lno = tl + 1;
- if (file_dline(sp, ep, fl))
- return (1);
- }
- } else { /* Destination < source. */
- mfl = tl;
- mtl = tl + diff;
- for (cnt = diff; cnt--;) {
- if ((p = file_gline(sp, ep, fl, &len)) == NULL)
- return (1);
- BINC_RET(sp, bp, blen, len);
- memmove(bp, p, len);
- if (file_aline(sp, ep, 1, tl++, bp, len))
- return (1);
- if (mark_reset)
- for (lmp = ep->marks.lh_first;
- lmp != NULL; lmp = lmp->q.le_next)
- if (lmp->name != ABSMARK1 &&
- lmp->lno == fl)
- lmp->lno = tl;
- ++fl;
- if (file_dline(sp, ep, fl))
- return (1);
- }
- }
- FREE_SPACE(sp, bp, blen);
-
- sp->lno = tl; /* Last line moved. */
- sp->cno = 0;
-
- /* Log the new positions of the marks. */
- if (mark_reset)
- for (lmp = ep->marks.lh_first;
- lmp != NULL; lmp = lmp->q.le_next)
- if (lmp->name != ABSMARK1 &&
- lmp->lno >= mfl && lmp->lno <= mtl)
- (void)log_mark(sp, ep, lmp);
-
-
- sp->rptlines[L_MOVED] += diff;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_open.c b/usr.bin/vi/ex/ex_open.c
deleted file mode 100644
index 187a29b..0000000
--- a/usr.bin/vi/ex/ex_open.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_open.c 8.6 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_open -- :[line] o[pen] [/pattern/] [flags]
- *
- * Switch to single line "open" mode.
- */
-int
-ex_open(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- /* If open option off, disallow open command. */
- if (!O_ISSET(sp, O_OPEN)) {
- msgq(sp, M_ERR,
- "The open command requires that the open option be set");
- return (1);
- }
-
- msgq(sp, M_ERR, "The open command is not yet implemented");
- return (1);
-}
diff --git a/usr.bin/vi/ex/ex_preserve.c b/usr.bin/vi/ex/ex_preserve.c
deleted file mode 100644
index 7bef07e..0000000
--- a/usr.bin/vi/ex/ex_preserve.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_preserve.c 8.14 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_preserve -- :pre[serve]
- * Push the file to recovery.
- */
-int
-ex_preserve(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- recno_t lno;
-
- if (!F_ISSET(ep, F_RCV_ON)) {
- msgq(sp, M_ERR, "Preservation of this file not possible");
- return (1);
- }
-
- /* If recovery not initialized, do so. */
- if (F_ISSET(ep, F_FIRSTMODIFY) && rcv_init(sp, ep))
- return (1);
-
- /* Force the file to be read in, in case it hasn't yet. */
- if (file_lline(sp, ep, &lno))
- return (1);
-
- /* Sync to disk. */
- if (rcv_sync(sp, ep, RCV_SNAPSHOT))
- return (1);
-
- msgq(sp, M_INFO, "File preserved");
- return (0);
-}
-
-/*
- * ex_recover -- :rec[over][!] file
- *
- * Recover the file.
- */
-int
-ex_recover(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- ARGS *ap;
- FREF *frp;
-
- ap = cmdp->argv[0];
-
- /* Set the alternate file name. */
- set_alt_name(sp, ap->bp);
-
- /*
- * Check for modifications. Autowrite did not historically
- * affect :recover.
- */
- if (file_m2(sp, ep, F_ISSET(cmdp, E_FORCE)))
- return (1);
-
- /* Get a file structure for the file. */
- if ((frp = file_add(sp, ap->bp)) == NULL)
- return (1);
-
- /* Set the recover bit. */
- F_SET(frp, FR_RECOVER);
-
- /* Switch files. */
- if (file_init(sp, frp, NULL, F_ISSET(cmdp, E_FORCE)))
- return (1);
- F_SET(sp, S_FSWITCH);
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_print.c b/usr.bin/vi/ex/ex_print.c
deleted file mode 100644
index 6bcab28..0000000
--- a/usr.bin/vi/ex/ex_print.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_print.c 8.16 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_list -- :[line [,line]] l[ist] [count] [flags]
- *
- * Display the addressed lines such that the output is unambiguous.
- */
-int
-ex_list(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (ex_print(sp, ep,
- &cmdp->addr1, &cmdp->addr2, cmdp->flags | E_F_LIST))
- return (1);
- sp->lno = cmdp->addr2.lno;
- sp->cno = cmdp->addr2.cno;
- return (0);
-}
-
-/*
- * ex_number -- :[line [,line]] nu[mber] [count] [flags]
- *
- * Display the addressed lines with a leading line number.
- */
-int
-ex_number(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (ex_print(sp, ep,
- &cmdp->addr1, &cmdp->addr2, cmdp->flags | E_F_HASH))
- return (1);
- sp->lno = cmdp->addr2.lno;
- sp->cno = cmdp->addr2.cno;
- return (0);
-}
-
-/*
- * ex_pr -- :[line [,line]] p[rint] [count] [flags]
- *
- * Display the addressed lines.
- */
-int
-ex_pr(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (ex_print(sp, ep, &cmdp->addr1, &cmdp->addr2, cmdp->flags))
- return (1);
- sp->lno = cmdp->addr2.lno;
- sp->cno = cmdp->addr2.cno;
- return (0);
-}
-
-/*
- * ex_print --
- * Print the selected lines.
- */
-int
-ex_print(sp, ep, fp, tp, flags)
- SCR *sp;
- EXF *ep;
- MARK *fp, *tp;
- register int flags;
-{
- recno_t from, to;
- size_t col, len;
- char *p;
-
- F_SET(sp, S_INTERRUPTIBLE);
- for (from = fp->lno, to = tp->lno; from <= to; ++from) {
- /*
- * Display the line number. The %6 format is specified
- * by POSIX 1003.2, and is almost certainly large enough.
- * Check, though, just in case.
- */
- if (LF_ISSET(E_F_HASH))
- if (from <= 999999)
- col = ex_printf(EXCOOKIE, "%6ld ", from);
- else
- col = ex_printf(EXCOOKIE, "TOOBIG ");
- else
- col = 0;
-
- /*
- * Display the line. The format for E_F_PRINT isn't very good,
- * especially in handling end-of-line tabs, but they're almost
- * backward compatible.
- */
- if ((p = file_gline(sp, ep, from, &len)) == NULL) {
- GETLINE_ERR(sp, from);
- return (1);
- }
-
- if (len == 0 && !LF_ISSET(E_F_LIST))
- (void)ex_printf(EXCOOKIE, "\n");
- else if (ex_ldisplay(sp, p, len, col, flags))
- return (1);
-
- if (INTERRUPTED(sp))
- break;
- }
-
- return (0);
-}
-
-/*
- * ex_ldisplay --
- * Display a line.
- */
-int
-ex_ldisplay(sp, lp, len, col, flags)
- SCR *sp;
- CHAR_T *lp;
- size_t len, col;
- u_int flags;
-{
- CHAR_T ch, *kp;
- u_long ts;
- size_t tlen;
-
- ts = O_VAL(sp, O_TABSTOP);
- for (;; --len) {
- if (len > 0)
- ch = *lp++;
- else if (LF_ISSET(E_F_LIST))
- ch = '$';
- else
- break;
- if (ch == '\t' && !LF_ISSET(E_F_LIST))
- for (tlen = ts - col % ts;
- col < sp->cols && tlen--; ++col)
- (void)ex_printf(EXCOOKIE, " ");
- else {
- kp = KEY_NAME(sp, ch);
- tlen = KEY_LEN(sp, ch);
- if (col + tlen < sp->cols) {
- (void)ex_printf(EXCOOKIE, "%s", kp);
- col += tlen;
- } else
- for (; tlen--; ++kp, ++col) {
- if (col == sp->cols) {
- col = 0;
- (void)ex_printf(EXCOOKIE, "\n");
- }
- (void)ex_printf(EXCOOKIE, "%c", *kp);
- }
- }
- if (len == 0)
- break;
- }
- (void)ex_printf(EXCOOKIE, "\n");
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_put.c b/usr.bin/vi/ex/ex_put.c
deleted file mode 100644
index a947d85..0000000
--- a/usr.bin/vi/ex/ex_put.c
+++ /dev/null
@@ -1,78 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_put.c 8.8 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_put -- [line] pu[t] [buffer]
- *
- * Append a cut buffer into the file.
- */
-int
-ex_put(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- MARK m;
-
- m.lno = sp->lno;
- m.cno = sp->cno;
- if (put(sp, ep, NULL, F_ISSET(cmdp, E_BUFFER) ? &cmdp->buffer : NULL,
- &cmdp->addr1, &m, 1))
- return (1);
- sp->lno = m.lno;
- sp->cno = m.cno;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_read.c b/usr.bin/vi/ex/ex_read.c
deleted file mode 100644
index cef1e3a..0000000
--- a/usr.bin/vi/ex/ex_read.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_read.c 8.41 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_read -- :read [file]
- * :read [!cmd]
- * Read from a file or utility.
- *
- * !!!
- * Historical vi wouldn't undo a filter read, for no apparent reason.
- */
-int
-ex_read(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- struct stat sb;
- CHAR_T *arg, *name;
- EX_PRIVATE *exp;
- FILE *fp;
- MARK rm;
- recno_t nlines;
- size_t arglen, blen, len;
- int btear, farg, rval;
- char *p;
-
- /*
- * 0 args: we're done.
- * 1 args: check for "read !arg".
- * 2 args: check for "read ! arg".
- * >2 args: object, too many args.
- */
- farg = 0;
- switch (cmdp->argc) {
- case 0:
- break;
- case 1:
- arg = cmdp->argv[0]->bp;
- arglen = cmdp->argv[0]->len;
- if (*arg == '!') {
- ++arg;
- --arglen;
- farg = 1;
- }
- break;
- case 2:
- if (cmdp->argv[0]->len == 1 && cmdp->argv[0]->bp[0] == '!') {
- arg = cmdp->argv[1]->bp;
- arglen = cmdp->argv[1]->len;
- farg = 2;
- break;
- }
- /* FALLTHROUGH */
- default:
- goto badarg;
- }
-
- if (farg != 0) {
- /* File name and bang expand the user's argument. */
- if (argv_exp1(sp, ep, cmdp, arg, arglen, 1))
- return (1);
-
- /* If argc unchanged, there wasn't anything to expand. */
- if (cmdp->argc == farg)
- goto usage;
-
- /* Set the last bang command. */
- exp = EXP(sp);
- if (exp->lastbcomm != NULL)
- free(exp->lastbcomm);
- if ((exp->lastbcomm = strdup(cmdp->argv[farg]->bp)) == NULL) {
- msgq(sp, M_SYSERR, NULL);
- return (1);
- }
-
- /* Redisplay the user's argument if it's changed. */
- if (F_ISSET(cmdp, E_MODIFY) && IN_VI_MODE(sp)) {
- len = cmdp->argv[farg]->len;
- GET_SPACE_RET(sp, p, blen, len + 2);
- p[0] = '!';
- memmove(p + 1,
- cmdp->argv[farg]->bp, cmdp->argv[farg]->len + 1);
- (void)sp->s_busy(sp, p);
- FREE_SPACE(sp, p, blen);
- }
-
- if (filtercmd(sp, ep, &cmdp->addr1,
- NULL, &rm, cmdp->argv[farg]->bp, FILTER_READ))
- return (1);
-
- /* The filter version of read set the autoprint flag. */
- F_SET(EXP(sp), EX_AUTOPRINT);
-
- /* If in vi mode, move to the first nonblank. */
- sp->lno = rm.lno;
- if (IN_VI_MODE(sp)) {
- sp->cno = 0;
- (void)nonblank(sp, ep, sp->lno, &sp->cno);
- }
- return (0);
- }
-
- /* Shell and file name expand the user's argument. */
- if (argv_exp2(sp, ep, cmdp, arg, arglen, 0))
- return (1);
-
- /*
- * 0 args: no arguments, read the current file, don't set the
- * alternate file name.
- * 1 args: read it, switching to it or settgin the alternate file
- * name.
- * >1 args: object, too many args.
- */
- switch (cmdp->argc) {
- case 1:
- name = sp->frp->name;
- break;
- case 2:
- name = cmdp->argv[1]->bp;
- /*
- * !!!
- * Historically, if you had an "unnamed" file, the read command
- * renamed the file.
- */
- if (F_ISSET(sp->frp, FR_TMPFILE) &&
- !F_ISSET(sp->frp, FR_READNAMED)) {
- if ((p = v_strdup(sp,
- cmdp->argv[1]->bp, cmdp->argv[1]->len)) != NULL) {
- free(sp->frp->name);
- sp->frp->name = p;
- }
- F_SET(sp->frp, FR_NAMECHANGE | FR_READNAMED);
- } else
- set_alt_name(sp, name);
- break;
- default:
-badarg: msgq(sp, M_ERR,
- "%s expanded into too many file names", cmdp->argv[0]->bp);
-usage: msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
-
- /*
- * !!!
- * Historically, vi did not permit reads from non-regular files,
- * nor did it distinguish between "read !" and "read!", so there
- * was no way to "force" it.
- */
- if ((fp = fopen(name, "r")) == NULL || fstat(fileno(fp), &sb)) {
- msgq(sp, M_SYSERR, "%s", name);
- return (1);
- }
- if (!S_ISREG(sb.st_mode)) {
- (void)fclose(fp);
- msgq(sp, M_ERR, "Only regular files may be read");
- return (1);
- }
-
- /* Turn on busy message. */
- btear = F_ISSET(sp, S_EXSILENT) ? 0 : !busy_on(sp, "Reading...");
- rval = ex_readfp(sp, ep, name, fp, &cmdp->addr1, &nlines, 1);
- if (btear)
- busy_off(sp);
-
- /*
- * Set the cursor to the first line read in, if anything read
- * in, otherwise, the address. (Historic vi set it to the
- * line after the address regardless, but since that line may
- * not exist we don't bother.)
- */
- sp->lno = cmdp->addr1.lno;
- if (nlines)
- ++sp->lno;
-
- return (rval);
-}
-
-/*
- * ex_readfp --
- * Read lines into the file.
- */
-int
-ex_readfp(sp, ep, name, fp, fm, nlinesp, success_msg)
- SCR *sp;
- EXF *ep;
- char *name;
- FILE *fp;
- MARK *fm;
- recno_t *nlinesp;
- int success_msg;
-{
- EX_PRIVATE *exp;
- recno_t lcnt, lno;
- size_t len;
- u_long ccnt; /* XXX: can't print off_t portably. */
- int rval;
-
- rval = 0;
- exp = EXP(sp);
-
- /*
- * Add in the lines from the output. Insertion starts at the line
- * following the address.
- */
- ccnt = 0;
- lcnt = 0;
- for (lno = fm->lno; !ex_getline(sp, fp, &len); ++lno, ++lcnt) {
- if (INTERRUPTED(sp)) {
- if (!success_msg)
- msgq(sp, M_INFO, "Interrupted");
- break;
- }
- if (file_aline(sp, ep, 1, lno, exp->ibp, len)) {
- rval = 1;
- break;
- }
- ccnt += len;
- }
-
- if (ferror(fp)) {
- msgq(sp, M_SYSERR, "%s", name);
- rval = 1;
- }
-
- if (fclose(fp)) {
- msgq(sp, M_SYSERR, "%s", name);
- return (1);
- }
-
- if (rval)
- return (1);
-
- /* Return the number of lines read in. */
- if (nlinesp != NULL)
- *nlinesp = lcnt;
-
- if (success_msg)
- msgq(sp, M_INFO, "%s%s: %lu line%s, %lu characters",
- INTERRUPTED(sp) ? "Interrupted read: " : "",
- name, lcnt, lcnt == 1 ? "" : "s", ccnt);
-
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_screen.c b/usr.bin/vi/ex/ex_screen.c
deleted file mode 100644
index e190588..0000000
--- a/usr.bin/vi/ex/ex_screen.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_screen.c 8.15 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_split -- :s[plit] [file ...]
- * Split the screen, optionally setting the file list.
- */
-int
-ex_split(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (sp->s_split(sp, cmdp->argc ? cmdp->argv : NULL, cmdp->argc));
-}
-
-/*
- * ex_bg -- :bg
- * Hide the screen.
- */
-int
-ex_bg(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (sp->s_bg(sp));
-}
-
-/*
- * ex_fg -- :fg [file]
- * Show the screen.
- */
-int
-ex_fg(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (sp->s_fg(sp, cmdp->argc ? cmdp->argv[0]->bp : NULL));
-}
-
-/*
- * ex_resize -- :resize [+-]rows
- * Change the screen size.
- */
-int
-ex_resize(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- enum adjust adj;
-
- if (!F_ISSET(cmdp, E_COUNT)) {
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
- if (F_ISSET(cmdp, E_COUNT_NEG))
- adj = A_DECREASE;
- else if (F_ISSET(cmdp, E_COUNT_POS))
- adj = A_INCREASE;
- else
- adj = A_SET;
- return (sp->s_rabs(sp, cmdp->count, adj));
-}
-
-/*
- * ex_sdisplay --
- * Display the list of screens.
- */
-int
-ex_sdisplay(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- SCR *tsp;
- int cnt, col, len, sep;
-
- if ((tsp = sp->gp->hq.cqh_first) == (void *)&sp->gp->hq) {
- (void)ex_printf(EXCOOKIE,
- "No backgrounded screens to display.\n");
- return (0);
- }
-
- col = len = sep = 0;
- for (cnt = 1; tsp != (void *)&sp->gp->hq; tsp = tsp->q.cqe_next) {
- col += len = strlen(tsp->frp->name) + sep;
- if (col >= sp->cols - 1) {
- col = len;
- sep = 0;
- (void)ex_printf(EXCOOKIE, "\n");
- } else if (cnt != 1) {
- sep = 1;
- (void)ex_printf(EXCOOKIE, " ");
- }
- (void)ex_printf(EXCOOKIE, "%s", tsp->frp->name);
- ++cnt;
- }
- (void)ex_printf(EXCOOKIE, "\n");
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_script.c b/usr.bin/vi/ex/ex_script.c
deleted file mode 100644
index a364e2b..0000000
--- a/usr.bin/vi/ex/ex_script.c
+++ /dev/null
@@ -1,582 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_script.c 8.19 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "script.h"
-
-/*
- * XXX
- */
-int openpty __P((int *, int *, char *, struct termios *, struct winsize *));
-
-static int sscr_getprompt __P((SCR *, EXF *));
-static int sscr_init __P((SCR *, EXF *));
-static int sscr_matchprompt __P((SCR *, char *, size_t, size_t *));
-static int sscr_setprompt __P((SCR *, char *, size_t));
-
-/*
- * ex_script -- : sc[ript][!] [file]
- *
- * Switch to script mode.
- */
-int
-ex_script(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- /* Vi only command. */
- if (!IN_VI_MODE(sp)) {
- msgq(sp, M_ERR,
- "The script command is only available in vi mode");
- return (1);
- }
-
- /* Switch to the new file. */
- if (cmdp->argc != 0 && ex_edit(sp, ep, cmdp))
- return (1);
-
- /*
- * Create the shell, figure out the prompt.
- *
- * !!!
- * The files just switched, use sp->ep.
- */
- if (sscr_init(sp, sp->ep))
- return (1);
-
- return (0);
-}
-
-/*
- * sscr_init --
- * Create a pty setup for a shell.
- */
-static int
-sscr_init(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- SCRIPT *sc;
- char *sh, *sh_path;
-
- MALLOC_RET(sp, sc, SCRIPT *, sizeof(SCRIPT));
- sp->script = sc;
- sc->sh_prompt = NULL;
- sc->sh_prompt_len = 0;
-
- /*
- * There are two different processes running through this code.
- * They are the shell and the parent.
- */
- sc->sh_master = sc->sh_slave = -1;
-
- if (tcgetattr(STDIN_FILENO, &sc->sh_term) == -1) {
- msgq(sp, M_SYSERR, "tcgetattr");
- goto err;
- }
-
- /*
- * Turn off output postprocessing and echo.
- */
- sc->sh_term.c_oflag &= ~OPOST;
- sc->sh_term.c_cflag &= ~(ECHO|ECHOE|ECHONL|ECHOK);
-
- if (ioctl(STDIN_FILENO, TIOCGWINSZ, &sc->sh_win) == -1) {
- msgq(sp, M_SYSERR, "tcgetattr");
- goto err;
- }
-
- if (openpty(&sc->sh_master,
- &sc->sh_slave, sc->sh_name, &sc->sh_term, &sc->sh_win) == -1) {
- msgq(sp, M_SYSERR, "openpty");
- goto err;
- }
-
- /*
- * Don't use vfork() here, because the signal semantics differ from
- * implementation to implementation.
- */
- SIGBLOCK(sp->gp);
- switch (sc->sh_pid = fork()) {
- case -1: /* Error. */
- SIGUNBLOCK(sp->gp);
-
- msgq(sp, M_SYSERR, "fork");
-err: if (sc->sh_master != -1)
- (void)close(sc->sh_master);
- if (sc->sh_slave != -1)
- (void)close(sc->sh_slave);
- return (1);
- case 0: /* Utility. */
- /* The utility has default signal behavior. */
- sig_end();
-
- /*
- * XXX
- * So that shells that do command line editing turn it off.
- */
- (void)putenv("TERM=emacs");
- (void)putenv("TERMCAP=emacs:");
- (void)putenv("EMACS=t");
-
- (void)setsid();
-#ifdef TIOCSCTTY
- /*
- * 4.4BSD allocates a controlling terminal using the TIOCSCTTY
- * ioctl, not by opening a terminal device file. POSIX 1003.1
- * doesn't define a portable way to do this. If TIOCSCTTY is
- * not available, hope that the open does it.
- */
- (void)ioctl(sc->sh_slave, TIOCSCTTY, 0);
-#endif
- (void)close(sc->sh_master);
- (void)dup2(sc->sh_slave, STDIN_FILENO);
- (void)dup2(sc->sh_slave, STDOUT_FILENO);
- (void)dup2(sc->sh_slave, STDERR_FILENO);
- (void)close(sc->sh_slave);
-
- /* Assumes that all shells have -i. */
- sh_path = O_STR(sp, O_SHELL);
- if ((sh = strrchr(sh_path, '/')) == NULL)
- sh = sh_path;
- else
- ++sh;
- execl(sh_path, sh, "-i", NULL);
- msgq(sp, M_ERR,
- "Error: execl: %s: %s", sh_path, strerror(errno));
- _exit(127);
- default: /* Parent. */
- SIGUNBLOCK(sp->gp);
- break;
- }
-
- if (sscr_getprompt(sp, ep))
- return (1);
-
- F_SET(sp, S_REDRAW | S_SCRIPT);
- return (0);
-
-}
-
-/*
- * sscr_getprompt --
- * Eat lines printed by the shell until a line with no trailing
- * carriage return comes; set the prompt from that line.
- */
-static int
-sscr_getprompt(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- struct timeval tv;
- CHAR_T *endp, *p, *t, buf[1024];
- SCRIPT *sc;
- fd_set fdset;
- recno_t lline;
- size_t llen, len;
- u_int value;
- int nr;
-
- FD_ZERO(&fdset);
- endp = buf;
- len = sizeof(buf);
-
- /* Wait up to a second for characters to read. */
- tv.tv_sec = 5;
- tv.tv_usec = 0;
- sc = sp->script;
- FD_SET(sc->sh_master, &fdset);
- switch (select(sc->sh_master + 1, &fdset, NULL, NULL, &tv)) {
- case -1: /* Error or interrupt. */
- msgq(sp, M_SYSERR, "select");
- goto prompterr;
- case 0: /* Timeout */
- msgq(sp, M_ERR, "Error: timed out");
- goto prompterr;
- case 1: /* Characters to read. */
- break;
- }
-
- /* Read the characters. */
-more: len = sizeof(buf) - (endp - buf);
- switch (nr = read(sc->sh_master, endp, len)) {
- case 0: /* EOF. */
- msgq(sp, M_ERR, "Error: shell: EOF");
- goto prompterr;
- case -1: /* Error or interrupt. */
- msgq(sp, M_SYSERR, "shell");
- goto prompterr;
- default:
- endp += nr;
- break;
- }
-
- /* If any complete lines, push them into the file. */
- for (p = t = buf; p < endp; ++p) {
- value = KEY_VAL(sp, *p);
- if (value == K_CR || value == K_NL) {
- if (file_lline(sp, ep, &lline) ||
- file_aline(sp, ep, 0, lline, t, p - t))
- goto prompterr;
- t = p + 1;
- }
- }
- if (p > buf) {
- memmove(buf, t, endp - t);
- endp = buf + (endp - t);
- }
- if (endp == buf)
- goto more;
-
- /* Wait up 1/10 of a second to make sure that we got it all. */
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- switch (select(sc->sh_master + 1, &fdset, NULL, NULL, &tv)) {
- case -1: /* Error or interrupt. */
- msgq(sp, M_SYSERR, "select");
- goto prompterr;
- case 0: /* Timeout */
- break;
- case 1: /* Characters to read. */
- goto more;
- }
-
- /* Timed out, so theoretically we have a prompt. */
- llen = endp - buf;
- endp = buf;
-
- /* Append the line into the file. */
- if (file_lline(sp, ep, &lline) ||
- file_aline(sp, ep, 0, lline, buf, llen)) {
-prompterr: sscr_end(sp);
- return (1);
- }
-
- return (sscr_setprompt(sp, buf, llen));
-}
-
-/*
- * sscr_exec --
- * Take a line and hand it off to the shell.
- */
-int
-sscr_exec(sp, ep, lno)
- SCR *sp;
- EXF *ep;
- recno_t lno;
-{
- SCRIPT *sc;
- recno_t last_lno;
- size_t blen, len, last_len, tlen;
- int matchprompt, nw, rval;
- char *bp, *p;
-
- /* If there's a prompt on the last line, append the command. */
- if (file_lline(sp, ep, &last_lno))
- return (1);
- if ((p = file_gline(sp, ep, last_lno, &last_len)) == NULL) {
- GETLINE_ERR(sp, last_lno);
- return (1);
- }
- if (sscr_matchprompt(sp, p, last_len, &tlen) && tlen == 0) {
- matchprompt = 1;
- GET_SPACE_RET(sp, bp, blen, last_len + 128);
- memmove(bp, p, last_len);
- } else
- matchprompt = 0;
-
- /* Get something to execute. */
- if ((p = file_gline(sp, ep, lno, &len)) == NULL) {
- if (file_lline(sp, ep, &lno))
- goto err1;
- if (lno == 0)
- goto empty;
- else
- GETLINE_ERR(sp, lno);
- goto err1;
- }
-
- /* Empty lines aren't interesting. */
- if (len == 0)
- goto empty;
-
- /* Delete any prompt. */
- if (sscr_matchprompt(sp, p, len, &tlen)) {
- if (tlen == len) {
-empty: msgq(sp, M_BERR, "Nothing to execute");
- goto err1;
- }
- p += (len - tlen);
- len = tlen;
- }
-
- /* Push the line to the shell. */
- sc = sp->script;
- if ((nw = write(sc->sh_master, p, len)) != len)
- goto err2;
- rval = 0;
- if (write(sc->sh_master, "\n", 1) != 1) {
-err2: if (nw == 0)
- errno = EIO;
- msgq(sp, M_SYSERR, "shell");
- goto err1;
- }
-
- if (matchprompt) {
- ADD_SPACE_RET(sp, bp, blen, last_len + len);
- memmove(bp + last_len, p, len);
- if (file_sline(sp, ep, last_lno, bp, last_len + len))
-err1: rval = 1;
- }
- if (matchprompt)
- FREE_SPACE(sp, bp, blen);
- return (rval);
-}
-
-/*
- * sscr_input --
- * Take a line from the shell and insert it into the file.
- */
-int
-sscr_input(sp)
- SCR *sp;
-{
- struct timeval tv;
- CHAR_T *endp, *p, *t;
- EXF *ep;
- SCRIPT *sc;
- recno_t lno;
- size_t blen, len, tlen;
- u_int value;
- int nr, rval;
- char *bp;
-
- /* Find out where the end of the file is. */
- ep = sp->ep;
- if (file_lline(sp, ep, &lno))
- return (1);
-
-#define MINREAD 1024
- GET_SPACE_RET(sp, bp, blen, MINREAD);
- endp = bp;
-
- /* Read the characters. */
- rval = 1;
- sc = sp->script;
-more: switch (nr = read(sc->sh_master, endp, MINREAD)) {
- case 0: /* EOF; shell just exited. */
- sscr_end(sp);
- F_CLR(sp, S_SCRIPT);
- rval = 0;
- goto ret;
- case -1: /* Error or interrupt. */
- msgq(sp, M_SYSERR, "shell");
- goto ret;
- default:
- endp += nr;
- break;
- }
-
- /* Append the lines into the file. */
- for (p = t = bp; p < endp; ++p) {
- value = KEY_VAL(sp, *p);
- if (value == K_CR || value == K_NL) {
- len = p - t;
- if (file_aline(sp, ep, 1, lno++, t, len))
- goto ret;
- t = p + 1;
- }
- }
- if (p > t) {
- len = p - t;
- /*
- * If the last thing from the shell isn't another prompt, wait
- * up to 1/10 of a second for more stuff to show up, so that
- * we don't break the output into two separate lines. Don't
- * want to hang indefinitely because some program is hanging,
- * confused the shell, or whatever.
- */
- if (!sscr_matchprompt(sp, t, len, &tlen) || tlen != 0) {
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- FD_SET(sc->sh_master, &sp->rdfd);
- FD_CLR(STDIN_FILENO, &sp->rdfd);
- if (select(sc->sh_master + 1,
- &sp->rdfd, NULL, NULL, &tv) == 1) {
- memmove(bp, t, len);
- endp = bp + len;
- goto more;
- }
- }
- if (sscr_setprompt(sp, t, len))
- return (1);
- if (file_aline(sp, ep, 1, lno++, t, len))
- goto ret;
- }
-
- /* The cursor moves to EOF. */
- sp->lno = lno;
- sp->cno = len ? len - 1 : 0;
- rval = sp->s_refresh(sp, ep);
-
-ret: FREE_SPACE(sp, bp, blen);
- return (rval);
-}
-
-/*
- * sscr_setprompt --
- *
- * Set the prompt to the last line we got from the shell.
- *
- */
-static int
-sscr_setprompt(sp, buf, len)
- SCR *sp;
- char* buf;
- size_t len;
-{
- SCRIPT *sc;
-
- sc = sp->script;
- if (sc->sh_prompt)
- FREE(sc->sh_prompt, sc->sh_prompt_len);
- MALLOC(sp, sc->sh_prompt, char *, len + 1);
- if (sc->sh_prompt == NULL) {
- sscr_end(sp);
- return (1);
- }
- memmove(sc->sh_prompt, buf, len);
- sc->sh_prompt_len = len;
- sc->sh_prompt[len] = '\0';
- return (0);
-}
-
-/*
- * sscr_matchprompt --
- * Check to see if a line matches the prompt. Nul's indicate
- * parts that can change, in both content and size.
- */
-static int
-sscr_matchprompt(sp, lp, line_len, lenp)
- SCR *sp;
- char *lp;
- size_t line_len, *lenp;
-{
- SCRIPT *sc;
- size_t prompt_len;
- char *pp;
-
- sc = sp->script;
- if (line_len < (prompt_len = sc->sh_prompt_len))
- return (0);
-
- for (pp = sc->sh_prompt;
- prompt_len && line_len; --prompt_len, --line_len) {
- if (*pp == '\0') {
- for (; prompt_len && *pp == '\0'; --prompt_len, ++pp);
- if (!prompt_len)
- return (0);
- for (; line_len && *lp != *pp; --line_len, ++lp);
- if (!line_len)
- return (0);
- }
- if (*pp++ != *lp++)
- break;
- }
-
- if (prompt_len)
- return (0);
- if (lenp != NULL)
- *lenp = line_len;
- return (1);
-}
-
-/*
- * sscr_end --
- * End the pipe to a shell.
- */
-int
-sscr_end(sp)
- SCR *sp;
-{
- SCRIPT *sc;
- int rval;
-
- if ((sc = sp->script) == NULL)
- return (0);
-
- /* Turn off the script flag. */
- F_CLR(sp, S_SCRIPT);
-
- /* Close down the parent's file descriptors. */
- if (sc->sh_master != -1)
- (void)close(sc->sh_master);
- if (sc->sh_slave != -1)
- (void)close(sc->sh_slave);
-
- /* This should have killed the child. */
- rval = proc_wait(sp, (long)sc->sh_pid, "script-shell", 0);
-
- /* Free memory. */
- FREE(sc->sh_prompt, sc->sh_prompt_len);
- FREE(sc, sizeof(SCRIPT));
- sp->script = NULL;
-
- return (rval);
-}
diff --git a/usr.bin/vi/ex/ex_set.c b/usr.bin/vi/ex/ex_set.c
deleted file mode 100644
index a2abb08..0000000
--- a/usr.bin/vi/ex/ex_set.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_set.c 8.6 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-int
-ex_set(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- switch(cmdp->argc) {
- case 0:
- opts_dump(sp, CHANGED_DISPLAY);
- break;
- default:
- opts_set(sp, cmdp->cmd->usage, cmdp->argv);
- break;
- }
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_shell.c b/usr.bin/vi/ex/ex_shell.c
deleted file mode 100644
index b6f9aed..0000000
--- a/usr.bin/vi/ex/ex_shell.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_shell.c 8.26 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "../svi/svi_screen.h"
-
-/*
- * ex_shell -- :sh[ell]
- * Invoke the program named in the SHELL environment variable
- * with the argument -i.
- */
-int
-ex_shell(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- char buf[MAXPATHLEN];
-
- (void)snprintf(buf, sizeof(buf), "%s -i", O_STR(sp, O_SHELL));
- return (ex_exec_proc(sp, buf, "\n", NULL));
-}
-
-/*
- * ex_exec_proc --
- * Run a separate process.
- */
-int
-ex_exec_proc(sp, cmd, p1, p2)
- SCR *sp;
- char *cmd, *p1, *p2;
-{
- const char *name;
- pid_t pid;
- int rval, teardown;
-
- /* Clear the rest of the screen. */
- if (sp->s_clear(sp))
- return (1);
-
- /* Save ex/vi terminal settings, and restore the original ones. */
- teardown = !ex_sleave(sp);
-
- /*
- * Flush waiting messages (autowrite, for example) so the output
- * matches historic practice.
- */
- (void)sex_refresh(sp, sp->ep);
-
- /* Put out various messages. */
- if (p1 != NULL)
- (void)write(STDOUT_FILENO, p1, strlen(p1));
- if (p2 != NULL)
- (void)write(STDOUT_FILENO, p2, strlen(p2));
-
- SIGBLOCK(sp->gp);
- switch (pid = vfork()) {
- case -1: /* Error. */
- SIGUNBLOCK(sp->gp);
-
- msgq(sp, M_SYSERR, "vfork");
- rval = 1;
- break;
- case 0: /* Utility. */
- /* The utility has default signal behavior. */
- sig_end();
-
- if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
- name = O_STR(sp, O_SHELL);
- else
- ++name;
- execl(O_STR(sp, O_SHELL), name, "-c", cmd, NULL);
- msgq(sp, M_ERR, "Error: execl: %s: %s",
- O_STR(sp, O_SHELL), strerror(errno));
- _exit(127);
- /* NOTREACHED */
- default: /* Parent. */
- SIGUNBLOCK(sp->gp);
-
- rval = proc_wait(sp, (long)pid, cmd, 0);
- break;
- }
-
- /* Restore ex/vi terminal settings. */
- if (teardown)
- ex_rleave(sp);
-
- /*
- * XXX
- * Stat of the tty structures (see ex_sleave, ex_rleave) only give
- * us 1-second resolution on the tty changes. A fast '!' command,
- * e.g. ":!pwd" can beat us to the refresh. When there's better
- * resolution from the stat(2) timers, this can go away.
- */
- F_SET(sp, S_REFRESH);
-
- return (rval);
-}
diff --git a/usr.bin/vi/ex/ex_shift.c b/usr.bin/vi/ex/ex_shift.c
deleted file mode 100644
index 61264c0..0000000
--- a/usr.bin/vi/ex/ex_shift.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_shift.c 8.16 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-enum which {LEFT, RIGHT};
-static int shift __P((SCR *, EXF *, EXCMDARG *, enum which));
-
-int
-ex_shiftl(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (shift(sp, ep, cmdp, LEFT));
-}
-
-int
-ex_shiftr(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (shift(sp, ep, cmdp, RIGHT));
-}
-
-static int
-shift(sp, ep, cmdp, rl)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
- enum which rl;
-{
- recno_t from, to;
- size_t blen, len, newcol, newidx, oldcol, oldidx, sw;
- int curset;
- char *p, *bp, *tbp;
-
- if (O_VAL(sp, O_SHIFTWIDTH) == 0) {
- msgq(sp, M_INFO, "shiftwidth option set to 0");
- return (0);
- }
-
- /*
- * The historic version of vi permitted the user to string any number
- * of '>' or '<' characters together, resulting in an indent of the
- * appropriate levels. There's a special hack in ex_cmd() so that
- * cmdp->argv[0] points to the string of '>' or '<' characters.
- *
- * Q: What's the difference between the people adding features
- * to vi and the Girl Scouts?
- * A: The Girl Scouts have mint cookies and adult supervision.
- */
- for (p = cmdp->argv[0]->bp, sw = 0; *p == '>' || *p == '<'; ++p)
- sw += O_VAL(sp, O_SHIFTWIDTH);
-
- GET_SPACE_RET(sp, bp, blen, 256);
-
- curset = 0;
- for (from = cmdp->addr1.lno, to = cmdp->addr2.lno; from <= to; ++from) {
- if ((p = file_gline(sp, ep, from, &len)) == NULL)
- goto err;
- if (!len) {
- if (sp->lno == from)
- curset = 1;
- continue;
- }
-
- /*
- * Calculate the old indent amount and the number of
- * characters it used.
- */
- for (oldidx = 0, oldcol = 0; oldidx < len; ++oldidx)
- if (p[oldidx] == ' ')
- ++oldcol;
- else if (p[oldidx] == '\t')
- oldcol += O_VAL(sp, O_TABSTOP) -
- oldcol % O_VAL(sp, O_TABSTOP);
- else
- break;
-
- /* Calculate the new indent amount. */
- if (rl == RIGHT)
- newcol = oldcol + sw;
- else {
- newcol = oldcol < sw ? 0 : oldcol - sw;
- if (newcol == oldcol) {
- if (sp->lno == from)
- curset = 1;
- continue;
- }
- }
-
- /* Get a buffer that will hold the new line. */
- ADD_SPACE_RET(sp, bp, blen, newcol + len);
-
- /*
- * Build a new indent string and count the number of
- * characters it uses.
- */
- for (tbp = bp, newidx = 0;
- newcol >= O_VAL(sp, O_TABSTOP); ++newidx) {
- *tbp++ = '\t';
- newcol -= O_VAL(sp, O_TABSTOP);
- }
- for (; newcol > 0; --newcol, ++newidx)
- *tbp++ = ' ';
-
- /* Add the original line. */
- memmove(tbp, p + oldidx, len - oldidx);
-
- /* Set the replacement line. */
- if (file_sline(sp, ep, from, bp, (tbp + (len - oldidx)) - bp)) {
-err: FREE_SPACE(sp, bp, blen);
- return (1);
- }
-
- /*
- * !!!
- * The shift command in historic vi had the usual bizarre
- * collection of cursor semantics. If called from vi, the
- * cursor was repositioned to the first non-blank character
- * of the lowest numbered line shifted. If called from ex,
- * the cursor was repositioned to the first non-blank of the
- * highest numbered line shifted. Here, if the cursor isn't
- * part of the set of lines that are moved, move it to the
- * first non-blank of the last line shifted. (This makes
- * ":3>>" in vi work reasonably.) If the cursor is part of
- * the shifted lines, it doesn't get moved at all. This
- * permits shifting of marked areas, i.e. ">'a." shifts the
- * marked area twice, something that couldn't be done with
- * historic vi.
- */
- if (sp->lno == from) {
- curset = 1;
- if (newidx > oldidx)
- sp->cno += newidx - oldidx;
- else if (sp->cno >= oldidx - newidx)
- sp->cno -= oldidx - newidx;
- }
- }
- if (!curset) {
- sp->lno = to;
- sp->cno = 0;
- (void)nonblank(sp, ep, to, &sp->cno);
- }
-
- FREE_SPACE(sp, bp, blen);
-
- sp->rptlines[rl == RIGHT ? L_RSHIFT : L_LSHIFT] +=
- cmdp->addr2.lno - cmdp->addr1.lno + 1;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_source.c b/usr.bin/vi/ex/ex_source.c
deleted file mode 100644
index b8af556..0000000
--- a/usr.bin/vi/ex/ex_source.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_source.c 8.7 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_source -- :source file
- * Execute ex commands from a file.
- */
-int
-ex_source(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (ex_cfile(sp, ep, cmdp->argv[0]->bp, 0));
-}
diff --git a/usr.bin/vi/ex/ex_stop.c b/usr.bin/vi/ex/ex_stop.c
deleted file mode 100644
index 543f649..0000000
--- a/usr.bin/vi/ex/ex_stop.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_stop.c 8.9 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "../sex/sex_screen.h"
-
-/*
- * ex_stop -- :stop[!]
- * :suspend[!]
- * Suspend execution.
- */
-int
-ex_stop(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- /* For some strange reason, the force flag turns off autowrite. */
- if (!F_ISSET(cmdp, E_FORCE) &&
- F_ISSET(ep, F_MODIFIED) && O_ISSET(sp, O_AUTOWRITE) &&
- file_write(sp, ep, NULL, NULL, NULL, FS_ALL))
- return (1);
- return (sp->s_suspend(sp));
-}
diff --git a/usr.bin/vi/ex/ex_subst.c b/usr.bin/vi/ex/ex_subst.c
deleted file mode 100644
index 5e52e79..0000000
--- a/usr.bin/vi/ex/ex_subst.c
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_subst.c 8.59 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-#define SUB_FIRST 0x01 /* The 'r' flag isn't reasonable. */
-#define SUB_MUSTSETR 0x02 /* The 'r' flag is required. */
-
-static __inline int regsub __P((SCR *, char *,
- char **, size_t *, size_t *, regmatch_t [10]));
-static int substitute __P((SCR *, EXF *,
- EXCMDARG *, char *, regex_t *, u_int));
-
-/*
- * ex_substitute --
- * [line [,line]] s[ubstitute] [[/;]pat[/;]/repl[/;] [cgr] [count] [#lp]]
- *
- * Substitute on lines matching a pattern.
- */
-int
-ex_substitute(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- regex_t *re, lre;
- size_t blen, len;
- u_int flags;
- int delim, eval, reflags, replaced;
- char *bp, *ptrn, *rep, *p, *t;
-
- /*
- * Skip leading white space.
- *
- * !!!
- * Historic vi allowed any non-alphanumeric to serve as the
- * substitution command delimiter.
- *
- * !!!
- * If the arguments are empty, it's the same as &, i.e. we
- * repeat the last substitution.
- */
- for (p = cmdp->argv[0]->bp,
- len = cmdp->argv[0]->len; len > 0; --len, ++p) {
- if (!isblank(*p))
- break;
- }
- if (len == 0)
- return (ex_subagain(sp, ep, cmdp));
- delim = *p++;
- if (isalnum(delim))
- return (substitute(sp, ep,
- cmdp, p, &sp->subre, SUB_MUSTSETR));
-
- /*
- * !!!
- * The full-blown substitute command reset the remembered
- * state of the 'c' and 'g' suffices.
- */
- sp->c_suffix = sp->g_suffix = 0;
-
- /*
- * Get the pattern string, toss escaped characters.
- *
- * !!!
- * Historic vi accepted any of the following forms:
- *
- * :s/abc/def/ change "abc" to "def"
- * :s/abc/def change "abc" to "def"
- * :s/abc/ delete "abc"
- * :s/abc delete "abc"
- *
- * QUOTING NOTE:
- *
- * Only toss an escape character if it escapes a delimiter.
- * This means that "s/A/\\\\f" replaces "A" with "\\f". It
- * would be nice to be more regular, i.e. for each layer of
- * escaping a single escape character is removed, but that's
- * not how the historic vi worked.
- */
- for (ptrn = t = p;;) {
- if (p[0] == '\0' || p[0] == delim) {
- if (p[0] == delim)
- ++p;
- /*
- * !!!
- * Nul terminate the pattern string -- it's passed
- * to regcomp which doesn't understand anything else.
- */
- *t = '\0';
- break;
- }
- if (p[0] == '\\')
- if (p[1] == delim)
- ++p;
- else if (p[1] == '\\')
- *t++ = *p++;
- *t++ = *p++;
- }
-
- /*
- * If the pattern string is empty, use the last RE (not just the
- * last substitution RE).
- */
- if (*ptrn == '\0') {
- if (!F_ISSET(sp, S_SRE_SET)) {
- msgq(sp, M_ERR, "No previous regular expression");
- return (1);
- }
- re = &sp->sre;
- flags = 0;
- } else {
- /* Set RE flags. */
- reflags = 0;
- if (O_ISSET(sp, O_EXTENDED))
- reflags |= REG_EXTENDED;
- if (O_ISSET(sp, O_IGNORECASE))
- reflags |= REG_ICASE;
-
- /* Convert vi-style RE's to POSIX 1003.2 RE's. */
- if (re_conv(sp, &ptrn, &replaced))
- return (1);
-
- /* Compile the RE. */
- eval = regcomp(&lre, (char *)ptrn, reflags);
-
- /* Free up any allocated memory. */
- if (replaced)
- FREE_SPACE(sp, ptrn, 0);
-
- if (eval) {
- re_error(sp, eval, &lre);
- return (1);
- }
-
- /*
- * Set saved RE.
- *
- * !!!
- * Historic practice is that substitutes set the search
- * direction as well as both substitute and search RE's.
- */
- sp->searchdir = FORWARD;
- sp->sre = lre;
- F_SET(sp, S_SRE_SET);
- sp->subre = lre;
- F_SET(sp, S_SUBRE_SET);
-
- re = &lre;
- flags = SUB_FIRST;
- }
-
- /*
- * Get the replacement string.
- *
- * The special character & (\& if O_MAGIC not set) matches the
- * entire RE. No handling of & is required here, it's done by
- * regsub().
- *
- * The special character ~ (\~ if O_MAGIC not set) inserts the
- * previous replacement string into this replacement string.
- * Count ~'s to figure out how much space we need. We could
- * special case nonexistent last patterns or whether or not
- * O_MAGIC is set, but it's probably not worth the effort.
- *
- * QUOTING NOTE:
- *
- * Only toss an escape character if it escapes a delimiter or
- * if O_MAGIC is set and it escapes a tilde.
- *
- * !!!
- * If the entire replacement pattern is "%", then use the last
- * replacement pattern. This semantic was added to vi in System
- * V and then percolated elsewhere, presumably around the time
- * that it was added to their version of ed(1).
- */
- if (p[0] == '\0' || p[0] == delim) {
- if (p[0] == delim)
- ++p;
- if (sp->repl != NULL)
- FREE(sp->repl, sp->repl_len);
- sp->repl = NULL;
- sp->repl_len = 0;
- } else if (p[0] == '%' && (p[1] == '\0' || p[1] == delim))
- p += p[1] == delim ? 2 : 1;
- else {
- for (rep = p, len = 0;
- p[0] != '\0' && p[0] != delim; ++p, ++len)
- if (p[0] == '~')
- len += sp->repl_len;
- GET_SPACE_RET(sp, bp, blen, len);
- for (t = bp, len = 0, p = rep;;) {
- if (p[0] == '\0' || p[0] == delim) {
- if (p[0] == delim)
- ++p;
- break;
- }
- if (p[0] == '\\') {
- if (p[1] == delim)
- ++p;
- else if (p[1] == '\\') {
- *t++ = *p++;
- ++len;
- } else if (p[1] == '~') {
- ++p;
- if (!O_ISSET(sp, O_MAGIC))
- goto tilde;
- }
- } else if (p[0] == '~' && O_ISSET(sp, O_MAGIC)) {
-tilde: ++p;
- memmove(t, sp->repl, sp->repl_len);
- t += sp->repl_len;
- len += sp->repl_len;
- continue;
- }
- *t++ = *p++;
- ++len;
- }
- if ((sp->repl_len = len) != 0) {
- if (sp->repl != NULL)
- free(sp->repl);
- if ((sp->repl = malloc(len)) == NULL) {
- msgq(sp, M_SYSERR, NULL);
- FREE_SPACE(sp, bp, blen);
- return (1);
- }
- memmove(sp->repl, bp, len);
- }
- FREE_SPACE(sp, bp, blen);
- }
- return (substitute(sp, ep, cmdp, p, re, flags));
-}
-
-/*
- * ex_subagain --
- * [line [,line]] & [cgr] [count] [#lp]]
- *
- * Substitute using the last substitute RE and replacement pattern.
- */
-int
-ex_subagain(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (!F_ISSET(sp, S_SUBRE_SET)) {
- msgq(sp, M_ERR, "No previous regular expression");
- return (1);
- }
- return (substitute(sp, ep, cmdp, cmdp->argv[0]->bp, &sp->subre, 0));
-}
-
-/*
- * ex_subtilde --
- * [line [,line]] ~ [cgr] [count] [#lp]]
- *
- * Substitute using the last RE and last substitute replacement pattern.
- */
-int
-ex_subtilde(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (!F_ISSET(sp, S_SRE_SET)) {
- msgq(sp, M_ERR, "No previous regular expression");
- return (1);
- }
- return (substitute(sp, ep, cmdp, cmdp->argv[0]->bp, &sp->sre, 0));
-}
-
-/*
- * The nasty part of the substitution is what happens when the replacement
- * string contains newlines. It's a bit tricky -- consider the information
- * that has to be retained for "s/f\(o\)o/^M\1^M\1/". The solution here is
- * to build a set of newline offsets which we use to break the line up later,
- * when the replacement is done. Don't change it unless you're pretty damned
- * confident.
- */
-#define NEEDNEWLINE(sp) { \
- if (sp->newl_len == sp->newl_cnt) { \
- sp->newl_len += 25; \
- REALLOC(sp, sp->newl, size_t *, \
- sp->newl_len * sizeof(size_t)); \
- if (sp->newl == NULL) { \
- sp->newl_len = 0; \
- return (1); \
- } \
- } \
-}
-
-#define BUILD(sp, l, len) { \
- if (lbclen + (len) > lblen) { \
- lblen += MAX(lbclen + (len), 256); \
- REALLOC(sp, lb, char *, lblen); \
- if (lb == NULL) { \
- lbclen = 0; \
- return (1); \
- } \
- } \
- memmove(lb + lbclen, l, len); \
- lbclen += len; \
-}
-
-#define NEEDSP(sp, len, pnt) { \
- if (lbclen + (len) > lblen) { \
- lblen += MAX(lbclen + (len), 256); \
- REALLOC(sp, lb, char *, lblen); \
- if (lb == NULL) { \
- lbclen = 0; \
- return (1); \
- } \
- pnt = lb + lbclen; \
- } \
-}
-
-/*
- * substitute --
- * Do the substitution. This stuff is *really* tricky. There are
- * lots of special cases, and general nastiness. Don't mess with it
- * unless you're pretty confident.
- */
-static int
-substitute(sp, ep, cmdp, s, re, flags)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
- char *s;
- regex_t *re;
- u_int flags;
-{
- MARK from, to;
- recno_t elno, lno;
- regmatch_t match[10];
- size_t blen, cnt, last, lbclen, lblen, len, llen, offset, saved_offset;
- int cflag, lflag, nflag, pflag, rflag;
- int didsub, do_eol_match, eflags, empty_ok, eval;
- int linechanged, matched, quit, rval;
- char *bp, *lb;
-
- /*
- * !!!
- * Historically, the 'g' and 'c' suffices were always toggled as flags,
- * so ":s/A/B/" was the same as ":s/A/B/ccgg". If O_EDCOMPATIBLE was
- * not set, they were initialized to 0 for all substitute commands. If
- * O_EDCOMPATIBLE was set, they were initialized to 0 only if the user
- * specified substitute/replacement patterns (see ex_substitute()).
- */
- if (!O_ISSET(sp, O_EDCOMPATIBLE))
- sp->c_suffix = sp->g_suffix = 0;
-
- /*
- * Historic vi permitted the '#', 'l' and 'p' options in vi mode, but
- * it only displayed the last change. I'd disallow them, but they are
- * useful in combination with the [v]global commands. In the current
- * model the problem is combining them with the 'c' flag -- the screen
- * would have to flip back and forth between the confirm screen and the
- * ex print screen, which would be pretty awful. We do display all
- * changes, though, for what that's worth.
- *
- * !!!
- * Historic vi was fairly strict about the order of "options", the
- * count, and "flags". I'm somewhat fuzzy on the difference between
- * options and flags, anyway, so this is a simpler approach, and we
- * just take it them in whatever order the user gives them. (The ex
- * usage statement doesn't reflect this.)
- */
- cflag = lflag = nflag = pflag = rflag = 0;
- for (lno = OOBLNO; *s != '\0'; ++s)
- switch (*s) {
- case ' ':
- case '\t':
- continue;
- case '+':
- ++cmdp->flagoff;
- break;
- case '-':
- --cmdp->flagoff;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (lno != OOBLNO)
- goto usage;
- errno = 0;
- lno = strtoul(s, &s, 10);
- if (*s == '\0') /* Loop increment correction. */
- --s;
- if (errno == ERANGE) {
- if (lno == LONG_MAX)
- msgq(sp, M_ERR, "Count overflow");
- else if (lno == LONG_MIN)
- msgq(sp, M_ERR, "Count underflow");
- else
- msgq(sp, M_SYSERR, NULL);
- return (1);
- }
- /*
- * In historic vi, the count was inclusive from the
- * second address.
- */
- cmdp->addr1.lno = cmdp->addr2.lno;
- cmdp->addr2.lno += lno - 1;
- break;
- case '#':
- nflag = 1;
- break;
- case 'c':
- sp->c_suffix = !sp->c_suffix;
- break;
- case 'g':
- sp->g_suffix = !sp->g_suffix;
- break;
- case 'l':
- lflag = 1;
- break;
- case 'p':
- pflag = 1;
- break;
- case 'r':
- if (LF_ISSET(SUB_FIRST)) {
- msgq(sp, M_ERR,
- "Regular expression specified; r flag meaningless");
- return (1);
- }
- if (!F_ISSET(sp, S_SRE_SET)) {
- msgq(sp, M_ERR,
- "No previous regular expression");
- return (1);
- }
- rflag = 1;
- re = &sp->sre;
- break;
- default:
- goto usage;
- }
-
- if (*s != '\0' || !rflag && LF_ISSET(SUB_MUSTSETR)) {
-usage: msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
-
- if (IN_VI_MODE(sp) && sp->c_suffix && (lflag || nflag || pflag)) {
- msgq(sp, M_ERR,
- "The #, l and p flags may not be combined with the c flag in vi mode");
- return (1);
- }
-
- /*
- * bp: if interactive, line cache
- * blen: if interactive, line cache length
- * lb: build buffer pointer.
- * lbclen: current length of built buffer.
- * lblen; length of build buffer.
- */
- bp = lb = NULL;
- blen = lbclen = lblen = 0;
-
- /* For each line... */
- for (matched = quit = 0, lno = cmdp->addr1.lno,
- elno = cmdp->addr2.lno; !quit && lno <= elno; ++lno) {
-
- /* Someone's unhappy, time to stop. */
- if (INTERRUPTED(sp)) {
- if (!F_ISSET(sp, S_GLOBAL))
- msgq(sp, M_INFO, "Interrupted");
- break;
- }
-
- /* Get the line. */
- if ((s = file_gline(sp, ep, lno, &llen)) == NULL) {
- GETLINE_ERR(sp, lno);
- goto ret1;
- }
-
- /*
- * Make a local copy if doing confirmation -- when calling
- * the confirm routine we're likely to lose the cached copy.
- */
- if (sp->c_suffix) {
- if (bp == NULL) {
- GET_SPACE_RET(sp, bp, blen, llen);
- } else
- ADD_SPACE_RET(sp, bp, blen, llen);
- memmove(bp, s, llen);
- s = bp;
- }
-
- /* Start searching from the beginning. */
- offset = 0;
- len = llen;
-
- /* Reset the build buffer offset. */
- lbclen = 0;
-
- /* Reset empty match flag. */
- empty_ok = 1;
-
- /*
- * We don't want to have to do a setline if the line didn't
- * change -- keep track of whether or not this line changed.
- * If doing confirmations, don't want to keep setting the
- * line if change is refused -- keep track of substitutions.
- */
- didsub = linechanged = 0;
-
- /* New line, do an EOL match. */
- do_eol_match = 1;
-
- /* It's not nul terminated, but we pretend it is. */
- eflags = REG_STARTEND;
-
- /*
- * The search area is from s + offset to the EOL.
- *
- * Generally, match[0].rm_so is the offset of the start
- * of the match from the start of the search, and offset
- * is the offset of the start of the last search.
- */
-nextmatch: match[0].rm_so = 0;
- match[0].rm_eo = len;
-
- /* Get the next match. */
- eval = regexec(re, (char *)s + offset, 10, match, eflags);
-
- /*
- * There wasn't a match or if there was an error, deal with
- * it. If there was a previous match in this line, resolve
- * the changes into the database. Otherwise, just move on.
- */
- if (eval == REG_NOMATCH)
- goto endmatch;
- if (eval != 0) {
- re_error(sp, eval, re);
- goto ret1;
- }
- matched = 1;
-
- /* Only the first search can match an anchored expression. */
- eflags |= REG_NOTBOL;
-
- /*
- * !!!
- * It's possible to match 0-length strings -- for example, the
- * command s;a*;X;, when matched against the string "aabb" will
- * result in "XbXbX", i.e. the matches are "aa", the space
- * between the b's and the space between the b's and the end of
- * the string. There is a similar space between the beginning
- * of the string and the a's. The rule that we use (because vi
- * historically used it) is that any 0-length match, occurring
- * immediately after a match, is ignored. Otherwise, the above
- * example would have resulted in "XXbXbX". Another example is
- * incorrectly using " *" to replace groups of spaces with one
- * space.
- *
- * The way we do this is that if we just had a successful match,
- * the starting offset does not skip characters, and the match
- * is empty, ignore the match and move forward. If there's no
- * more characters in the string, we were attempting to match
- * after the last character, so quit.
- */
- if (!empty_ok && match[0].rm_so == 0 && match[0].rm_eo == 0) {
- empty_ok = 1;
- if (len == 0)
- goto endmatch;
- BUILD(sp, s + offset, 1)
- ++offset;
- --len;
- goto nextmatch;
- }
-
- /* Confirm change. */
- if (sp->c_suffix) {
- /*
- * Set the cursor position for confirmation. Note,
- * if we matched on a '$', the cursor may be past
- * the end of line.
- *
- * XXX
- * We may want to "fix" this in the confirm routine,
- * if the confirm routine should be able to display
- * a cursor past EOL.
- */
- from.lno = to.lno = lno;
- from.cno = match[0].rm_so + offset;
- to.cno = match[0].rm_eo;
- if (llen == 0)
- from.cno = to.cno = 0;
- else {
- if (to.cno >= llen)
- to.cno = llen - 1;
- if (from.cno >= llen)
- from.cno = llen - 1;
- }
- switch (sp->s_confirm(sp, ep, &from, &to)) {
- case CONF_YES:
- break;
- case CONF_NO:
- didsub = 0;
- BUILD(sp, s +offset, match[0].rm_eo);
- goto skip;
- case CONF_QUIT:
- /* Set the quit flag. */
- quit = 1;
-
- /* If interruptible, pass the info back. */
- if (F_ISSET(sp, S_INTERRUPTIBLE))
- F_SET(sp, S_INTERRUPTED);
-
- /*
- * If any changes, resolve them, otherwise
- * return to the main loop.
- */
- goto endmatch;
- }
- }
-
- /* Copy the bytes before the match into the build buffer. */
- BUILD(sp, s + offset, match[0].rm_so);
-
- /* Substitute the matching bytes. */
- didsub = 1;
- if (regsub(sp, s + offset, &lb, &lbclen, &lblen, match))
- goto ret1;
-
- /* Set the change flag so we know this line was modified. */
- linechanged = 1;
-
- /* Move past the matched bytes. */
-skip: offset += match[0].rm_eo;
- len -= match[0].rm_eo;
-
- /* A match cannot be followed by an empty pattern. */
- empty_ok = 0;
-
- /*
- * If doing a global change with confirmation, we have to
- * update the screen. The basic idea is to store the line
- * so the screen update routines can find it, and restart.
- */
- if (didsub && sp->c_suffix && sp->g_suffix) {
- /*
- * The new search offset will be the end of the
- * modified line.
- */
- saved_offset = lbclen;
-
- /* Copy the rest of the line. */
- if (len)
- BUILD(sp, s + offset, len)
-
- /* Set the new offset. */
- offset = saved_offset;
-
- /* Store inserted lines, adjusting the build buffer. */
- last = 0;
- if (sp->newl_cnt) {
- for (cnt = 0;
- cnt < sp->newl_cnt; ++cnt, ++lno, ++elno) {
- if (file_iline(sp, ep, lno,
- lb + last, sp->newl[cnt] - last))
- goto ret1;
- last = sp->newl[cnt] + 1;
- ++sp->rptlines[L_ADDED];
- }
- lbclen -= last;
- offset -= last;
- sp->newl_cnt = 0;
- }
-
- /* Store and retrieve the line. */
- if (file_sline(sp, ep, lno, lb + last, lbclen))
- goto ret1;
- if ((s = file_gline(sp, ep, lno, &llen)) == NULL) {
- GETLINE_ERR(sp, lno);
- goto ret1;
- }
- ADD_SPACE_RET(sp, bp, blen, llen)
- memmove(bp, s, llen);
- s = bp;
- len = llen - offset;
-
- /* Restart the build. */
- lbclen = 0;
- BUILD(sp, s, offset);
-
- /*
- * If we haven't already done the after-the-string
- * match, do one. Set REG_NOTEOL so the '$' pattern
- * only matches once.
- */
- if (!do_eol_match)
- goto endmatch;
- if (offset == len) {
- do_eol_match = 0;
- eflags |= REG_NOTEOL;
- }
- goto nextmatch;
- }
-
- /*
- * If it's a global:
- *
- * If at the end of the string, do a test for the after
- * the string match. Set REG_NOTEOL so the '$' pattern
- * only matches once.
- */
- if (sp->g_suffix && do_eol_match) {
- if (len == 0) {
- do_eol_match = 0;
- eflags |= REG_NOTEOL;
- }
- goto nextmatch;
- }
-
-endmatch: if (!linechanged)
- continue;
-
- /* Copy any remaining bytes into the build buffer. */
- if (len)
- BUILD(sp, s + offset, len)
-
- /* Store inserted lines, adjusting the build buffer. */
- last = 0;
- if (sp->newl_cnt) {
- for (cnt = 0;
- cnt < sp->newl_cnt; ++cnt, ++lno, ++elno) {
- if (file_iline(sp, ep,
- lno, lb + last, sp->newl[cnt] - last))
- goto ret1;
- last = sp->newl[cnt] + 1;
- ++sp->rptlines[L_ADDED];
- }
- lbclen -= last;
- sp->newl_cnt = 0;
- }
-
- /* Store the changed line. */
- if (file_sline(sp, ep, lno, lb + last, lbclen))
- goto ret1;
-
- /* Update changed line counter. */
- if (sp->rptlchange != lno) {
- sp->rptlchange = lno;
- ++sp->rptlines[L_CHANGED];
- }
-
- /*
- * !!!
- * Display as necessary. Historic practice is to only
- * display the last line of a line split into multiple
- * lines.
- */
- if (lflag || nflag || pflag) {
- from.lno = to.lno = lno;
- from.cno = to.cno = 0;
- if (lflag)
- ex_print(sp, ep, &from, &to, E_F_LIST);
- if (nflag)
- ex_print(sp, ep, &from, &to, E_F_HASH);
- if (pflag)
- ex_print(sp, ep, &from, &to, E_F_PRINT);
- }
-
- if (!sp->c_suffix)
- sp->lno = lno;
-
- /*
- * !!!
- * Move the cursor to the last line changed.
- */
- if (!sp->c_suffix)
- sp->lno = lno;
- }
-
- /*
- * !!!
- * Move the cursor to the first non-blank of the last line change.
- *
- * XXX
- * This is NOT backward compatible with historic vi, which always
- * moved to the last line actually changed.
- */
- if (!sp->c_suffix) {
- sp->cno = 0;
- (void)nonblank(sp, ep, sp->lno, &sp->cno);
- }
-
- /*
- * If not in a global command, and nothing matched, say so.
- * Else, if none of the lines displayed, put something up.
- */
- if (!matched) {
- if (!F_ISSET(sp, S_GLOBAL))
- msgq(sp, M_INFO, "No match found");
- } else if (!lflag && !nflag && !pflag)
- F_SET(EXP(sp), EX_AUTOPRINT);
-
- rval = 0;
- if (0) {
-ret1: rval = 1;
- }
-
- if (bp != NULL)
- FREE_SPACE(sp, bp, blen);
- if (lb != NULL)
- free(lb);
- return (rval);
-}
-
-/*
- * regsub --
- * Do the substitution for a regular expression.
- */
-static __inline int
-regsub(sp, ip, lbp, lbclenp, lblenp, match)
- SCR *sp;
- char *ip; /* Input line. */
- char **lbp;
- size_t *lbclenp, *lblenp;
- regmatch_t match[10];
-{
- enum { C_NOTSET, C_LOWER, C_ONELOWER, C_ONEUPPER, C_UPPER } conv;
- size_t lbclen, lblen; /* Local copies. */
- size_t mlen; /* Match length. */
- size_t rpl; /* Remaining replacement length. */
- char *rp; /* Replacement pointer. */
- int ch;
- int no; /* Match replacement offset. */
- char *p, *t; /* Buffer pointers. */
- char *lb; /* Local copies. */
-
- lb = *lbp; /* Get local copies. */
- lbclen = *lbclenp;
- lblen = *lblenp;
-
- /*
- * QUOTING NOTE:
- *
- * There are some special sequences that vi provides in the
- * replacement patterns.
- * & string the RE matched (\& if nomagic set)
- * \# n-th regular subexpression
- * \E end \U, \L conversion
- * \e end \U, \L conversion
- * \l convert the next character to lower-case
- * \L convert to lower-case, until \E, \e, or end of replacement
- * \u convert the next character to upper-case
- * \U convert to upper-case, until \E, \e, or end of replacement
- *
- * Otherwise, since this is the lowest level of replacement, discard
- * all escape characters. This (hopefully) follows historic practice.
- */
-#define ADDCH(ch) { \
- CHAR_T __ch = (ch); \
- u_int __value = KEY_VAL(sp, __ch); \
- if (__value == K_CR || __value == K_NL) { \
- NEEDNEWLINE(sp); \
- sp->newl[sp->newl_cnt++] = lbclen; \
- } else if (conv != C_NOTSET) { \
- switch (conv) { \
- case C_ONELOWER: \
- conv = C_NOTSET; \
- /* FALLTHROUGH */ \
- case C_LOWER: \
- if (isupper(__ch)) \
- __ch = tolower(__ch); \
- break; \
- case C_ONEUPPER: \
- conv = C_NOTSET; \
- /* FALLTHROUGH */ \
- case C_UPPER: \
- if (islower(__ch)) \
- __ch = toupper(__ch); \
- break; \
- default: \
- abort(); \
- } \
- } \
- NEEDSP(sp, 1, p); \
- *p++ = __ch; \
- ++lbclen; \
-}
- conv = C_NOTSET;
- for (rp = sp->repl, rpl = sp->repl_len, p = lb + lbclen; rpl--;) {
- switch (ch = *rp++) {
- case '&':
- if (O_ISSET(sp, O_MAGIC)) {
- no = 0;
- goto subzero;
- }
- break;
- case '\\':
- if (rpl == 0)
- break;
- --rpl;
- switch (ch = *rp) {
- case '&':
- ++rp;
- if (!O_ISSET(sp, O_MAGIC)) {
- no = 0;
- goto subzero;
- }
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- no = *rp++ - '0';
-subzero: if (match[no].rm_so == -1 ||
- match[no].rm_eo == -1)
- break;
- mlen = match[no].rm_eo - match[no].rm_so;
- for (t = ip + match[no].rm_so; mlen--; ++t)
- ADDCH(*t);
- continue;
- case 'e':
- case 'E':
- ++rp;
- conv = C_NOTSET;
- continue;
- case 'l':
- ++rp;
- conv = C_ONELOWER;
- continue;
- case 'L':
- ++rp;
- conv = C_LOWER;
- continue;
- case 'u':
- ++rp;
- conv = C_ONEUPPER;
- continue;
- case 'U':
- ++rp;
- conv = C_UPPER;
- continue;
- default:
- ++rp;
- break;
- }
- }
- ADDCH(ch);
- }
-
- *lbp = lb; /* Update caller's information. */
- *lbclenp = lbclen;
- *lblenp = lblen;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_tag.c b/usr.bin/vi/ex/ex_tag.c
deleted file mode 100644
index 4378803..0000000
--- a/usr.bin/vi/ex/ex_tag.c
+++ /dev/null
@@ -1,905 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * David Hitz of Auspex Systems, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_tag.c 8.45 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/param.h>
-#include <sys/mman.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "tag.h"
-
-static char *binary_search __P((char *, char *, char *));
-static int compare __P((char *, char *, char *));
-static char *linear_search __P((char *, char *, char *));
-static int search __P((SCR *, char *, char *, char **));
-static int tag_get __P((SCR *, char *, char **, char **, char **));
-
-/*
- * ex_tagfirst --
- * The tag code can be entered from main, i.e. "vi -t tag".
- */
-int
-ex_tagfirst(sp, tagarg)
- SCR *sp;
- char *tagarg;
-{
- FREF *frp;
- MARK m;
- long tl;
- u_int flags;
- int sval;
- char *p, *tag, *name, *search;
-
- /* Taglength may limit the number of characters. */
- if ((tl = O_VAL(sp, O_TAGLENGTH)) != 0 && strlen(tagarg) > tl)
- tagarg[tl] = '\0';
-
- /* Get the tag information. */
- if (tag_get(sp, tagarg, &tag, &name, &search))
- return (1);
-
- /* Create the file entry. */
- if ((frp = file_add(sp, name)) == NULL)
- return (1);
- if (file_init(sp, frp, NULL, 0))
- return (1);
-
- /*
- * !!!
- * The historic tags file format (from a long, long time ago...)
- * used a line number, not a search string. I got complaints, so
- * people are still using the format.
- */
- if (isdigit(search[0])) {
- m.lno = atoi(search);
- m.cno = 0;
- } else {
- /*
- * Search for the tag; cheap fallback for C functions if
- * the name is the same but the arguments have changed.
- */
- m.lno = 1;
- m.cno = 0;
- flags = SEARCH_FILE | SEARCH_TAG | SEARCH_TERM;
- sval = f_search(sp, sp->ep, &m, &m, search, NULL, &flags);
- if (sval && (p = strrchr(search, '(')) != NULL) {
- p[1] = '\0';
- sval = f_search(sp, sp->ep,
- &m, &m, search, NULL, &flags);
- }
- if (sval)
- msgq(sp, M_ERR, "%s: search pattern not found", tag);
- }
-
- /* Set up the screen. */
- frp->lno = m.lno;
- frp->cno = m.cno;
- F_SET(frp, FR_CURSORSET);
-
- /* Might as well make this the default tag. */
- if ((EXP(sp)->tlast = strdup(tagarg)) == NULL) {
- msgq(sp, M_SYSERR, NULL);
- return (1);
- }
- return (0);
-}
-
-/* Free a tag or tagf structure from a queue. */
-#define FREETAG(tp) { \
- TAILQ_REMOVE(&exp->tagq, (tp), q); \
- if ((tp)->search != NULL) \
- free((tp)->search); \
- FREE((tp), sizeof(TAGF)); \
-}
-#define FREETAGF(tfp) { \
- TAILQ_REMOVE(&exp->tagfq, (tfp), q); \
- free((tfp)->name); \
- FREE((tfp), sizeof(TAGF)); \
-}
-
-/*
- * ex_tagpush -- :tag [file]
- * Move to a new tag.
- *
- * The tags stacks in nvi are a bit tricky. Each tag contains a file name,
- * search string, and line/column numbers. The search string is only used
- * for the first access and for user display. The first record on the stack
- * is the place where we first did a tag, so it has no search string. The
- * second record is the first tag, and so on. Note, this means that the
- * "current" tag is always on the stack. Each tag has a line/column which is
- * the location from which the user tagged the following TAG entry, and which
- * is used as the return location.
- */
-int
-ex_tagpush(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- enum {TC_CHANGE, TC_CURRENT} which;
- EX_PRIVATE *exp;
- FREF *frp;
- MARK m;
- TAG *tp;
- u_int flags;
- int sval;
- long tl;
- char *name, *p, *search, *tag;
-
- exp = EXP(sp);
- switch (cmdp->argc) {
- case 1:
- if (exp->tlast != NULL)
- FREE(exp->tlast, strlen(exp->tlast) + 1);
- if ((exp->tlast = strdup(cmdp->argv[0]->bp)) == NULL) {
- msgq(sp, M_SYSERR, NULL);
- return (1);
- }
- break;
- case 0:
- if (exp->tlast == NULL) {
- msgq(sp, M_ERR, "No previous tag entered");
- return (1);
- }
- break;
- default:
- abort();
- }
-
- /* Taglength may limit the number of characters. */
- if ((tl = O_VAL(sp, O_TAGLENGTH)) != 0 && strlen(exp->tlast) > tl)
- exp->tlast[tl] = '\0';
-
- /* Get the tag information. */
- if (tag_get(sp, exp->tlast, &tag, &name, &search))
- return (1);
-
- /* Get the (possibly new) FREF structure. */
- if ((frp = file_add(sp, name)) == NULL)
- goto err;
-
- if (sp->frp == frp)
- which = TC_CURRENT;
- else {
- if (file_m1(sp, sp->ep,
- F_ISSET(cmdp, E_FORCE), FS_ALL | FS_POSSIBLE))
- goto err;
- which = TC_CHANGE;
- }
-
- /*
- * Get a tag structure -- if this is the first tag, push it on the
- * stack as a placeholder and get another tag structure. Set the
- * line/column of the most recent element on the stack to be the
- * current values, including the file pointer. Then push the new
- * TAG onto the stack with the new file and search string for user
- * display.
- */
- CALLOC(sp, tp, TAG *, 1, sizeof(TAG));
- if (tp != NULL && exp->tagq.tqh_first == NULL) {
- TAILQ_INSERT_HEAD(&exp->tagq, tp, q);
- CALLOC(sp, tp, TAG *, 1, sizeof(TAG));
- }
- if (exp->tagq.tqh_first != NULL) {
- exp->tagq.tqh_first->frp = sp->frp;
- exp->tagq.tqh_first->lno = sp->lno;
- exp->tagq.tqh_first->cno = sp->cno;
- }
- if (tp != NULL) {
- if ((tp->search = strdup(search)) == NULL)
- msgq(sp, M_SYSERR, NULL);
- else
- tp->slen = strlen(search);
- tp->frp = frp;
- TAILQ_INSERT_HEAD(&exp->tagq, tp, q);
- }
-
- /* Switch files. */
- if (which == TC_CHANGE && file_init(sp, frp, NULL, 0)) {
- if (tp != NULL)
- FREETAG(tp);
- /* Handle special, first-tag case. */
- if (exp->tagq.tqh_first->q.tqe_next == NULL)
- TAILQ_REMOVE(&exp->tagq, exp->tagq.tqh_first, q);
-err: free(tag);
- return (1);
- }
-
- /*
- * !!!
- * Historic vi accepted a line number as well as a search
- * string, and people are apparently still using the format.
- */
- if (isdigit(search[0])) {
- m.lno = atoi(search);
- m.cno = 0;
- sval = 0;
- } else {
- /*
- * Search for the tag; cheap fallback for C functions
- * if the name is the same but the arguments have changed.
- */
- m.lno = 1;
- m.cno = 0;
- flags = SEARCH_FILE | SEARCH_TAG | SEARCH_TERM;
- sval = f_search(sp, sp->ep, &m, &m, search, NULL, &flags);
- if (sval && (p = strrchr(search, '(')) != NULL) {
- p[1] = '\0';
- sval = f_search(sp, sp->ep,
- &m, &m, search, NULL, &flags);
- p[1] = '(';
- }
- if (sval)
- msgq(sp, M_ERR, "%s: search pattern not found", tag);
- }
- free(tag);
-
- switch (which) {
- case TC_CHANGE:
- frp->lno = m.lno;
- frp->cno = m.cno;
- F_SET(frp, FR_CURSORSET);
- F_SET(sp, S_FSWITCH);
- break;
- case TC_CURRENT:
- if (sval)
- return (1);
- sp->lno = m.lno;
- sp->cno = m.cno;
- break;
- }
- return (0);
-}
-
-/*
- * ex_tagpop -- :tagp[op][!] [number | file]
- * Pop the tag stack.
- */
-int
-ex_tagpop(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- EX_PRIVATE *exp;
- TAG *ntp, *tp;
- long off;
- size_t arglen;
- char *arg, *p, *t;
-
- /* Check for an empty stack. */
- exp = EXP(sp);
- if (exp->tagq.tqh_first == NULL) {
- msgq(sp, M_INFO, "The tags stack is empty");
- return (1);
- }
-
- switch (cmdp->argc) {
- case 0: /* Pop one tag. */
- ntp = exp->tagq.tqh_first;
- break;
- case 1: /* Name or number. */
- arg = cmdp->argv[0]->bp;
- off = strtol(arg, &p, 10);
- if (*p == '\0') {
- if (off < 1)
- return (0);
- for (tp = exp->tagq.tqh_first;
- tp != NULL && --off > 1; tp = tp->q.tqe_next);
- if (tp == NULL) {
- msgq(sp, M_ERR,
-"Less than %s entries on the tags stack; use :display to see the tags stack",
- arg);
- return (1);
- }
- ntp = tp;
- } else {
- arglen = strlen(arg);
- for (tp = exp->tagq.tqh_first;
- tp != NULL; ntp = tp, tp = tp->q.tqe_next) {
- /* Use the user's original file name. */
- p = tp->frp->name;
- if ((t = strrchr(p, '/')) == NULL)
- t = p;
- else
- ++t;
- if (!strncmp(arg, t, arglen))
- break;
- }
- if (tp == NULL) {
- msgq(sp, M_ERR,
-"No file named %s on the tags stack; use :display to see the tags stack",
- arg);
- return (1);
- }
- }
- break;
- default:
- abort();
- }
-
- /* Update the cursor from the saved TAG information. */
- tp = ntp->q.tqe_next;
- if (tp->frp == sp->frp) {
- sp->lno = tp->lno;
- sp->cno = tp->cno;
- } else {
- if (file_m1(sp, ep,
- F_ISSET(cmdp, E_FORCE), FS_ALL | FS_POSSIBLE))
- return (1);
- if (file_init(sp, tp->frp, NULL, 0))
- return (1);
-
- tp->frp->lno = tp->lno;
- tp->frp->cno = tp->cno;
- F_SET(sp->frp, FR_CURSORSET);
-
- F_SET(sp, S_FSWITCH);
- }
-
- /* Pop entries off the queue up to ntp. */
- for (;;) {
- tp = exp->tagq.tqh_first;
- FREETAG(tp);
- if (tp == ntp)
- break;
- }
-
- /* If returning to the first tag, the stack is now empty. */
- if (exp->tagq.tqh_first->q.tqe_next == NULL)
- TAILQ_REMOVE(&exp->tagq, exp->tagq.tqh_first, q);
- return (0);
-}
-
-/*
- * ex_tagtop -- :tagt[op][!]
- * Clear the tag stack.
- */
-int
-ex_tagtop(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- EX_PRIVATE *exp;
- TAG *tp;
-
- /* Find oldest saved information. */
- exp = EXP(sp);
- for (tp = exp->tagq.tqh_first;
- tp != NULL && tp->q.tqe_next != NULL; tp = tp->q.tqe_next);
- if (tp == NULL) {
- msgq(sp, M_INFO, "The tags stack is empty");
- return (1);
- }
-
- /* If not switching files, it's easy; else do the work. */
- if (tp->frp == sp->frp) {
- sp->lno = tp->lno;
- sp->cno = tp->cno;
- } else {
- if (file_m1(sp, sp->ep,
- F_ISSET(cmdp, E_FORCE), FS_ALL | FS_POSSIBLE))
- return (1);
- if (file_init(sp, tp->frp, NULL, 0))
- return (1);
-
- tp->frp->lno = tp->lno;
- tp->frp->cno = tp->cno;
-
- F_SET(sp->frp, FR_CURSORSET);
- F_SET(sp, S_FSWITCH);
- }
-
- /* Empty out the queue. */
- while ((tp = exp->tagq.tqh_first) != NULL)
- FREETAG(tp);
- return (0);
-}
-
-/*
- * ex_tagdisplay --
- * Display the list of tags.
- */
-int
-ex_tagdisplay(sp, ep)
- SCR *sp;
- EXF *ep;
-{
- EX_PRIVATE *exp;
- TAG *tp;
- size_t len, maxlen;
- int cnt;
- char *name;
-
- exp = EXP(sp);
- if ((tp = exp->tagq.tqh_first) == NULL) {
- (void)ex_printf(EXCOOKIE, "No tags to display.\n");
- return (0);
- }
-
- /*
- * Figure out the formatting. MNOC is the maximum
- * number of file name columns before we split the line.
- */
-#define MNOC 15
- for (maxlen = 0,
- tp = exp->tagq.tqh_first; tp != NULL; tp = tp->q.tqe_next) {
- len = strlen(name = tp->frp->name); /* The original name. */
- if (maxlen < len && len < MNOC)
- maxlen = len;
- }
-
- for (cnt = 1, tp = exp->tagq.tqh_first; tp != NULL;
- ++cnt, tp = tp->q.tqe_next) {
- len = strlen(name = tp->frp->name); /* The original name. */
- if (len > maxlen || len + tp->slen > sp->cols)
- if (tp == NULL || tp->search == NULL)
- (void)ex_printf(EXCOOKIE,
- "%2d %s\n", cnt, name);
- else
- (void)ex_printf(EXCOOKIE,
- "%2d %s\n** %*.*s %s\n", cnt, name,
- (int)maxlen, (int)maxlen, "", tp->search);
- else
- if (tp == NULL || tp->search == NULL)
- (void)ex_printf(EXCOOKIE, "%2d %*.*s\n",
- cnt, (int)maxlen, (int)len, name);
- else
- (void)ex_printf(EXCOOKIE, "%2d %*.*s %s\n",
- cnt, (int)maxlen, (int)len, name,
- tp->search);
- }
- return (0);
-}
-
-/*
- * ex_tagalloc --
- * Create a new list of tag files.
- */
-int
-ex_tagalloc(sp, str)
- SCR *sp;
- char *str;
-{
- EX_PRIVATE *exp;
- TAGF *tp;
- size_t len;
- char *p, *t;
-
- /* Free current queue. */
- exp = EXP(sp);
- while ((tp = exp->tagfq.tqh_first) != NULL)
- FREETAGF(tp);
-
- /* Create new queue. */
- for (p = t = str;; ++p) {
- if (*p == '\0' || isblank(*p)) {
- if ((len = p - t) > 1) {
- MALLOC_RET(sp, tp, TAGF *, sizeof(TAGF));
- MALLOC(sp, tp->name, char *, len + 1);
- if (tp->name == NULL) {
- FREE(tp, sizeof(TAGF));
- return (1);
- }
- memmove(tp->name, t, len);
- tp->name[len] = '\0';
- tp->flags = 0;
- TAILQ_INSERT_TAIL(&exp->tagfq, tp, q);
- }
- t = p + 1;
- }
- if (*p == '\0')
- break;
- }
- return (0);
-}
- /* Free previous queue. */
-/*
- * ex_tagfree --
- * Free the tags file list.
- */
-int
-ex_tagfree(sp)
- SCR *sp;
-{
- EX_PRIVATE *exp;
- TAG *tp;
- TAGF *tfp;
-
- /* Free up tag information. */
- exp = EXP(sp);
- while ((tp = exp->tagq.tqh_first) != NULL)
- FREETAG(tp);
- while ((tfp = exp->tagfq.tqh_first) != NULL)
- FREETAGF(tfp);
- if (exp->tlast != NULL)
- free(exp->tlast);
- return (0);
-}
-
-/*
- * ex_tagcopy --
- * Copy a screen's tag structures.
- */
-int
-ex_tagcopy(orig, sp)
- SCR *orig, *sp;
-{
- EX_PRIVATE *oexp, *nexp;
- TAG *ap, *tp;
- TAGF *atfp, *tfp;
-
- /* Copy tag stack. */
- oexp = EXP(orig);
- nexp = EXP(sp);
- for (ap = oexp->tagq.tqh_first; ap != NULL; ap = ap->q.tqe_next) {
- MALLOC(sp, tp, TAG *, sizeof(TAG));
- if (tp == NULL)
- goto nomem;
- *tp = *ap;
- if (ap->search != NULL &&
- (tp->search = strdup(ap->search)) == NULL)
- goto nomem;
- TAILQ_INSERT_TAIL(&nexp->tagq, tp, q);
- }
-
- /* Copy list of tag files. */
- for (atfp = oexp->tagfq.tqh_first;
- atfp != NULL; atfp = atfp->q.tqe_next) {
- MALLOC(sp, tfp, TAGF *, sizeof(TAGF));
- if (tfp == NULL)
- goto nomem;
- *tfp = *atfp;
- if ((tfp->name = strdup(atfp->name)) == NULL)
- goto nomem;
- TAILQ_INSERT_TAIL(&nexp->tagfq, tfp, q);
- }
-
- /* Copy the last tag. */
- if (oexp->tlast != NULL &&
- (nexp->tlast = strdup(oexp->tlast)) == NULL) {
-nomem: msgq(sp, M_SYSERR, NULL);
- return (1);
- }
- return (0);
-}
-
-/*
- * tag_get --
- * Get a tag from the tags files.
- */
-static int
-tag_get(sp, tag, tagp, filep, searchp)
- SCR *sp;
- char *tag, **tagp, **filep, **searchp;
-{
- struct stat sb;
- EX_PRIVATE *exp;
- TAGF *tfp;
- size_t plen, slen, tlen;
- int dne;
- char *p, pbuf[MAXPATHLEN];
-
- /*
- * Find the tag, only display missing file messages once, and
- * then only if we didn't find the tag.
- */
- dne = 0;
- exp = EXP(sp);
- for (p = NULL, tfp = exp->tagfq.tqh_first;
- tfp != NULL && p == NULL; tfp = tfp->q.tqe_next) {
- errno = 0;
- F_CLR(tfp, TAGF_DNE);
- if (search(sp, tfp->name, tag, &p))
- if (errno == ENOENT) {
- if (!F_ISSET(tfp, TAGF_DNE_WARN)) {
- dne = 1;
- F_SET(tfp, TAGF_DNE);
- }
- } else
- msgq(sp, M_SYSERR, tfp->name);
- else
- if (p != NULL)
- break;
- }
-
- if (p == NULL) {
- msgq(sp, M_ERR, "%s: tag not found", tag);
- if (dne)
- for (tfp = exp->tagfq.tqh_first;
- tfp != NULL; tfp = tfp->q.tqe_next)
- if (F_ISSET(tfp, TAGF_DNE)) {
- errno = ENOENT;
- msgq(sp, M_SYSERR, tfp->name);
- F_SET(tfp, TAGF_DNE_WARN);
- }
- return (1);
- }
-
- /*
- * Set the return pointers; tagp points to the tag, and, incidentally
- * the allocated string, filep points to the file name, and searchp
- * points to the search string. All three are nul-terminated.
- */
- for (*tagp = p; *p && !isblank(*p); ++p);
- if (*p == '\0')
- goto malformed;
- for (*p++ = '\0'; isblank(*p); ++p);
- for (*filep = p; *p && !isblank(*p); ++p);
- if (*p == '\0')
- goto malformed;
- for (*p++ = '\0'; isblank(*p); ++p);
- *searchp = p;
- if (*p == '\0') {
-malformed: free(*tagp);
- msgq(sp, M_ERR, "%s: corrupted tag in %s", tag, tfp->name);
- return (1);
- }
-
- /*
- * !!!
- * If the tag file path is a relative path, see if it exists. If it
- * doesn't, look relative to the tags file path. It's okay for a tag
- * file to not exist, and, historically, vi simply displayed a "new"
- * file. However, if the path exists relative to the tag file, it's
- * pretty clear what's happening, so we may as well do it right.
- */
- if ((*filep)[0] != '/'
- && stat(*filep, &sb) && (p = strrchr(tfp->name, '/')) != NULL) {
- *p = '\0';
- plen = snprintf(pbuf, sizeof(pbuf), "%s/%s", tfp->name, *filep);
- *p = '/';
- if (stat(pbuf, &sb) == 0) {
- slen = strlen(*searchp);
- tlen = strlen(*tagp);
- MALLOC(sp, p, char *, plen + slen + tlen + 5);
- if (p != NULL) {
- memmove(p, *tagp, tlen);
- free(*tagp);
- *tagp = p;
- *(p += tlen) = '\0';
- memmove(++p, pbuf, plen);
- *filep = p;
- *(p += plen) = '\0';
- memmove(++p, *searchp, slen);
- *searchp = p;
- *(p += slen) = '\0';
- }
- }
- }
- return (0);
-}
-
-#define EQUAL 0
-#define GREATER 1
-#define LESS (-1)
-
-/*
- * search --
- * Search a file for a tag.
- */
-static int
-search(sp, name, tname, tag)
- SCR *sp;
- char *name, *tname, **tag;
-{
- struct stat sb;
- int fd, len;
- char *endp, *back, *front, *map, *p;
-
- if ((fd = open(name, O_RDONLY, 0)) < 0)
- return (1);
-
- /*
- * XXX
- * We'd like to test if the file is too big to mmap. Since we don't
- * know what size or type off_t's or size_t's are, what the largest
- * unsigned integral type is, or what random insanity the local C
- * compiler will perpetrate, doing the comparison in a portable way
- * is flatly impossible. Hope that malloc fails if the file is too
- * large.
- */
- if (fstat(fd, &sb) || (map = mmap(NULL, (size_t)sb.st_size,
- PROT_READ, MAP_PRIVATE, fd, (off_t)0)) == (caddr_t)-1) {
- (void)close(fd);
- return (1);
- }
- front = map;
- back = front + sb.st_size;
-
- front = binary_search(tname, front, back);
- front = linear_search(tname, front, back);
-
- if (front == NULL || (endp = strchr(front, '\n')) == NULL) {
- *tag = NULL;
- goto done;
- }
-
- len = endp - front;
- MALLOC(sp, p, char *, len + 1);
- if (p == NULL) {
- *tag = NULL;
- goto done;
- }
- memmove(p, front, len);
- p[len] = '\0';
- *tag = p;
-
-done: if (munmap(map, (size_t)sb.st_size))
- msgq(sp, M_SYSERR, "munmap");
- if (close(fd))
- msgq(sp, M_SYSERR, "close");
- return (0);
-}
-
-/*
- * Binary search for "string" in memory between "front" and "back".
- *
- * This routine is expected to return a pointer to the start of a line at
- * *or before* the first word matching "string". Relaxing the constraint
- * this way simplifies the algorithm.
- *
- * Invariants:
- * front points to the beginning of a line at or before the first
- * matching string.
- *
- * back points to the beginning of a line at or after the first
- * matching line.
- *
- * Base of the Invariants.
- * front = NULL;
- * back = EOF;
- *
- * Advancing the Invariants:
- *
- * p = first newline after halfway point from front to back.
- *
- * If the string at "p" is not greater than the string to match,
- * p is the new front. Otherwise it is the new back.
- *
- * Termination:
- *
- * The definition of the routine allows it return at any point,
- * since front is always at or before the line to print.
- *
- * In fact, it returns when the chosen "p" equals "back". This
- * implies that there exists a string is least half as long as
- * (back - front), which in turn implies that a linear search will
- * be no more expensive than the cost of simply printing a string or two.
- *
- * Trying to continue with binary search at this point would be
- * more trouble than it's worth.
- */
-#define SKIP_PAST_NEWLINE(p, back) while (p < back && *p++ != '\n');
-
-static char *
-binary_search(string, front, back)
- register char *string, *front, *back;
-{
- register char *p;
-
- p = front + (back - front) / 2;
- SKIP_PAST_NEWLINE(p, back);
-
- while (p != back) {
- if (compare(string, p, back) == GREATER)
- front = p;
- else
- back = p;
- p = front + (back - front) / 2;
- SKIP_PAST_NEWLINE(p, back);
- }
- return (front);
-}
-
-/*
- * Find the first line that starts with string, linearly searching from front
- * to back.
- *
- * Return NULL for no such line.
- *
- * This routine assumes:
- *
- * o front points at the first character in a line.
- * o front is before or at the first line to be printed.
- */
-static char *
-linear_search(string, front, back)
- char *string, *front, *back;
-{
- while (front < back) {
- switch (compare(string, front, back)) {
- case EQUAL: /* Found it. */
- return (front);
- case LESS: /* No such string. */
- return (NULL);
- case GREATER: /* Keep going. */
- break;
- }
- SKIP_PAST_NEWLINE(front, back);
- }
- return (NULL);
-}
-
-/*
- * Return LESS, GREATER, or EQUAL depending on how the string1 compares
- * with string2 (s1 ??? s2).
- *
- * o Matches up to len(s1) are EQUAL.
- * o Matches up to len(s2) are GREATER.
- *
- * The string "s1" is null terminated. The string s2 is '\t', space, (or
- * "back") terminated.
- *
- * !!!
- * Reasonably modern ctags programs use tabs as separators, not spaces.
- * However, historic programs did use spaces, and, I got complaints.
- */
-static int
-compare(s1, s2, back)
- register char *s1, *s2, *back;
-{
- for (; *s1 && s2 < back && (*s2 != '\t' && *s2 != ' '); ++s1, ++s2)
- if (*s1 != *s2)
- return (*s1 < *s2 ? LESS : GREATER);
- return (*s1 ? GREATER : s2 < back &&
- (*s2 != '\t' && *s2 != ' ') ? LESS : EQUAL);
-}
diff --git a/usr.bin/vi/ex/ex_undo.c b/usr.bin/vi/ex/ex_undo.c
deleted file mode 100644
index 1b8ba69..0000000
--- a/usr.bin/vi/ex/ex_undo.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_undo.c 8.9 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_undo -- u
- * Undo the last change.
- */
-int
-ex_undo(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- MARK m;
-
- /*
- * !!!
- * Historic undo always set the previous context mark.
- */
- m.lno = sp->lno;
- m.cno = sp->cno;
- if (mark_set(sp, ep, ABSMARK1, &m, 1))
- return (1);
-
- /*
- * !!!
- * Multiple undo isn't available in ex, as there's no '.' command.
- * Whether 'u' is undo or redo is toggled each time, unless there
- * was a change since the last undo, in which case it's an undo.
- */
- if (!F_ISSET(ep, F_UNDO)) {
- F_SET(ep, F_UNDO);
- ep->lundo = FORWARD;
- }
- switch (ep->lundo) {
- case BACKWARD:
- if (log_forward(sp, ep, &m))
- return (1);
- ep->lundo = FORWARD;
- break;
- case FORWARD:
- if (log_backward(sp, ep, &m))
- return (1);
- ep->lundo = BACKWARD;
- break;
- case NOTSET:
- abort();
- }
- sp->lno = m.lno;
- sp->cno = m.cno;
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_usage.c b/usr.bin/vi/ex/ex_usage.c
deleted file mode 100644
index 424b79b..0000000
--- a/usr.bin/vi/ex/ex_usage.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_usage.c 8.21 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-#include "../vi/vcmd.h"
-
-/*
- * ex_help -- :help
- * Display help message.
- */
-int
-ex_help(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- (void)ex_printf(EXCOOKIE,
- "To see the list of vi commands, enter \":viusage<CR>\"\n");
- (void)ex_printf(EXCOOKIE,
- "To see the list of ex commands, enter \":exusage<CR>\"\n");
- (void)ex_printf(EXCOOKIE,
- "For an ex command usage statement enter \":exusage [cmd]<CR>\"\n");
- (void)ex_printf(EXCOOKIE,
- "For a vi key usage statement enter \":viusage [key]<CR>\"\n");
- (void)ex_printf(EXCOOKIE, "To exit, enter \":q!\"\n");
- return (0);
-}
-
-/*
- * ex_usage -- :exusage [cmd]
- * Display ex usage strings.
- */
-int
-ex_usage(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- ARGS *ap;
- EXCMDLIST const *cp;
- char *name;
-
- switch (cmdp->argc) {
- case 1:
- ap = cmdp->argv[0];
- for (cp = cmds; cp->name != NULL &&
- memcmp(ap->bp, cp->name, ap->len); ++cp);
- if (cp->name == NULL)
- (void)ex_printf(EXCOOKIE,
- "The %.*s command is unknown",
- (int)ap->len, ap->bp);
- else {
- (void)ex_printf(EXCOOKIE,
- "Command: %s\n Usage: %s\n", cp->help, cp->usage);
- /*
- * !!!
- * The "visual" command has two modes, one from ex,
- * one from the vi colon line. Don't ask.
- */
- if (cp != &cmds[C_VISUAL_EX] &&
- cp != &cmds[C_VISUAL_VI])
- break;
- if (cp == &cmds[C_VISUAL_EX])
- cp = &cmds[C_VISUAL_VI];
- else
- cp = &cmds[C_VISUAL_EX];
- (void)ex_printf(EXCOOKIE,
- "Command: %s\n Usage: %s\n", cp->help, cp->usage);
- }
- break;
- case 0:
- F_SET(sp, S_INTERRUPTIBLE);
- for (cp = cmds; cp->name != NULL; ++cp) {
- /* The ^D command has an unprintable name. */
- if (cp == &cmds[C_SCROLL])
- name = "^D";
- else
- name = cp->name;
- (void)ex_printf(EXCOOKIE,
- "%*s: %s\n", MAXCMDNAMELEN, name, cp->help);
- }
- break;
- default:
- abort();
- }
- return (0);
-}
-
-/*
- * ex_viusage -- :viusage [key]
- * Display vi usage strings.
- */
-int
-ex_viusage(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- VIKEYS const *kp;
- int key;
-
- switch (cmdp->argc) {
- case 1:
- if (cmdp->argv[0]->len != 1) {
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
- key = cmdp->argv[0]->bp[0];
- if (key > MAXVIKEY)
- goto nokey;
-
- /* Special case: '[' and ']' commands. */
- if ((key == '[' || key == ']') && cmdp->argv[0]->bp[1] != key)
- goto nokey;
-
- /* Special case: ~ command. */
- if (key == '~' && O_ISSET(sp, O_TILDEOP))
- kp = &tmotion;
- else
- kp = &vikeys[key];
-
- if (kp->func == NULL)
-nokey: (void)ex_printf(EXCOOKIE,
- "The %s key has no current meaning",
- KEY_NAME(sp, key));
- else
- (void)ex_printf(EXCOOKIE,
- " Key:%s%s\nUsage: %s\n",
- isblank(*kp->help) ? "" : " ", kp->help, kp->usage);
- break;
- case 0:
- F_SET(sp, S_INTERRUPTIBLE);
- for (key = 0; key <= MAXVIKEY; ++key) {
- /* Special case: ~ command. */
- if (key == '~' && O_ISSET(sp, O_TILDEOP))
- kp = &tmotion;
- else
- kp = &vikeys[key];
- if (kp->help != NULL)
- (void)ex_printf(EXCOOKIE, "%s\n", kp->help);
- }
- break;
- default:
- abort();
- }
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_util.c b/usr.bin/vi/ex/ex_util.c
deleted file mode 100644
index 67c1039..0000000
--- a/usr.bin/vi/ex/ex_util.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_util.c 8.14 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_getline --
- * Return a line from the terminal.
- */
-int
-ex_getline(sp, fp, lenp)
- SCR *sp;
- FILE *fp;
- size_t *lenp;
-{
- EX_PRIVATE *exp;
- size_t off;
- int ch;
- char *p;
-
- exp = EXP(sp);
- for (errno = 0, off = 0, p = exp->ibp;;) {
- if (off >= exp->ibp_len) {
- BINC_RET(sp, exp->ibp, exp->ibp_len, off + 1);
- p = exp->ibp + off;
- }
- if ((ch = getc(fp)) == EOF && !feof(fp)) {
- if (errno == EINTR) {
- errno = 0;
- clearerr(fp);
- continue;
- }
- return (1);
- }
- if (ch == EOF || ch == '\n') {
- if (ch == EOF && !off)
- return (1);
- *lenp = off;
- return (0);
- }
- *p++ = ch;
- ++off;
- }
- /* NOTREACHED */
-}
-
-/*
- * ex_sleave --
- * Save the terminal/signal state, screen modification time.
- * Specific to ex/filter.c and ex/ex_shell.c.
- */
-int
-ex_sleave(sp)
- SCR *sp;
-{
- struct stat sb;
- EX_PRIVATE *exp;
-
- /* Ignore sessions not using tty's. */
- if (!F_ISSET(sp->gp, G_STDIN_TTY))
- return (1);
-
- exp = EXP(sp);
- if (tcgetattr(STDIN_FILENO, &exp->leave_term)) {
- msgq(sp, M_SYSERR, "tcgetattr");
- return (1);
- }
- if (tcsetattr(STDIN_FILENO,
- TCSANOW | TCSASOFT, &sp->gp->original_termios)) {
- msgq(sp, M_SYSERR, "tcsetattr");
- return (1);
- }
- /*
- * The process may write to the terminal. Save the access time
- * (read) and modification time (write) of the tty; if they have
- * changed when we restore the modes, will have to refresh the
- * screen.
- */
- if (fstat(STDIN_FILENO, &sb)) {
- msgq(sp, M_SYSERR, "stat: stdin");
- exp->leave_atime = exp->leave_mtime = 0;
- } else {
- exp->leave_atime = sb.st_atime;
- exp->leave_mtime = sb.st_mtime;
- }
- return (0);
-}
-
-/*
- * ex_rleave --
- * Return the terminal/signal state, not screen modification time.
- * Specific to ex/filter.c and ex/ex_shell.c.
- */
-void
-ex_rleave(sp)
- SCR *sp;
-{
- EX_PRIVATE *exp;
- struct stat sb;
-
- exp = EXP(sp);
-
- /* Restore the terminal modes. */
- if (tcsetattr(STDIN_FILENO, TCSANOW | TCSASOFT, &exp->leave_term))
- msgq(sp, M_SYSERR, "tcsetattr");
-
- /* If the terminal was used, refresh the screen. */
- if (fstat(STDIN_FILENO, &sb) || exp->leave_atime == 0 ||
- exp->leave_atime != sb.st_atime || exp->leave_mtime != sb.st_mtime)
- F_SET(sp, S_REFRESH);
-}
-
-/*
- * ex_ncheck --
- * Check for more files to edit.
- */
-int
-ex_ncheck(sp, force)
- SCR *sp;
- int force;
-{
- /*
- * !!!
- * Historic practice: quit! or two quit's done in succession
- * (where ZZ counts as a quit) didn't check for other files.
- */
- if (!force && sp->ccnt != sp->q_ccnt + 1 &&
- sp->cargv != NULL && sp->cargv[1] != NULL) {
- sp->q_ccnt = sp->ccnt;
- msgq(sp, M_ERR,
- "More files to edit; use n[ext] to go to the next file, q[uit]! to quit");
- return (1);
- }
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_version.c b/usr.bin/vi/ex/ex_version.c
deleted file mode 100644
index 011c257..0000000
--- a/usr.bin/vi/ex/ex_version.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_version.c 8.66 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_version -- :version
- * Display the program version.
- */
-int
-ex_version(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- static const time_t then = 777148668;
-
- (void)ex_printf(EXCOOKIE,
-"Version 1.34, %sThe CSRG, University of California, Berkeley.\n",
- ctime(&then));
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_visual.c b/usr.bin/vi/ex/ex_visual.c
deleted file mode 100644
index acfd537..0000000
--- a/usr.bin/vi/ex/ex_visual.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_visual.c 8.15 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_visual -- :[line] vi[sual] [^-.+] [window_size] [flags]
- *
- * Switch to visual mode.
- */
-int
-ex_visual(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- size_t len;
- int pos;
- char buf[256];
-
- /* If open option off, disallow visual command. */
- if (!O_ISSET(sp, O_OPEN)) {
- msgq(sp, M_ERR,
- "The visual command requires that the open option be set");
- return (1);
- }
-
- /* If a line specified, move to that line. */
- if (cmdp->addrcnt)
- sp->lno = cmdp->addr1.lno;
-
- /*
- * Push a command based on the line position flags. If no
- * flag specified, the line goes at the top of the screen.
- */
- switch (F_ISSET(cmdp, E_F_CARAT | E_F_DASH | E_F_DOT | E_F_PLUS)) {
- case E_F_CARAT:
- pos = '^';
- break;
- case E_F_DASH:
- pos = '-';
- break;
- case E_F_DOT:
- pos = '.';
- break;
- case E_F_PLUS:
- pos = '+';
- break;
- default:
- sp->frp->lno = sp->lno;
- sp->frp->cno = 0;
- F_SET(sp->frp, FR_CURSORSET | FR_FNONBLANK);
- goto nopush;
- }
-
- if (F_ISSET(cmdp, E_COUNT))
- len = snprintf(buf, sizeof(buf),
- "%luz%c%lu", sp->lno, pos, cmdp->count);
- else
- len = snprintf(buf, sizeof(buf), "%luz%c", sp->lno, pos);
- (void)term_push(sp, buf, len, CH_NOMAP | CH_QUOTED);
-
- /*
- * !!!
- * Historically, if no line address was specified, the [p#l] flags
- * caused the cursor to be moved to the last line of the file, which
- * was then positioned as described above. This seems useless, so
- * I haven't implemented it.
- */
- switch (F_ISSET(cmdp, E_F_HASH | E_F_LIST | E_F_PRINT)) {
- case E_F_HASH:
- O_SET(sp, O_NUMBER);
- break;
- case E_F_LIST:
- O_SET(sp, O_LIST);
- break;
- case E_F_PRINT:
- break;
- }
-
- /* Switch modes. */
-nopush: F_CLR(sp, S_SCREENS);
- F_SET(sp, sp->saved_vi_mode);
-
- return (0);
-}
diff --git a/usr.bin/vi/ex/ex_write.c b/usr.bin/vi/ex/ex_write.c
deleted file mode 100644
index e5273e4..0000000
--- a/usr.bin/vi/ex/ex_write.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_write.c 8.38 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-enum which {WN, WQ, WRITE, XIT};
-
-static int exwr __P((SCR *, EXF *, EXCMDARG *, enum which));
-
-/*
- * ex_wn -- :wn[!] [>>] [file]
- * Write to a file and switch to the next one.
- */
-int
-ex_wn(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- if (exwr(sp, ep, cmdp, WN))
- return (1);
- if (file_m3(sp, ep, 0))
- return (1);
-
- /* The file name isn't a new file to edit. */
- cmdp->argc = 0;
-
- return (ex_next(sp, ep, cmdp));
-}
-
-/*
- * ex_wq -- :wq[!] [>>] [file]
- * Write to a file and quit.
- */
-int
-ex_wq(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- int force;
-
- if (exwr(sp, ep, cmdp, WQ))
- return (1);
- if (file_m3(sp, ep, 0))
- return (1);
-
- force = F_ISSET(cmdp, E_FORCE);
-
- if (ex_ncheck(sp, force))
- return (1);
-
- F_SET(sp, force ? S_EXIT_FORCE : S_EXIT);
- return (0);
-}
-
-/*
- * ex_write -- :write[!] [>>] [file]
- * :write [!] [cmd]
- * Write to a file.
- */
-int
-ex_write(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (exwr(sp, ep, cmdp, WRITE));
-}
-
-
-/*
- * ex_xit -- :x[it]! [file]
- *
- * Write out any modifications and quit.
- */
-int
-ex_xit(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- int force;
-
- if (F_ISSET((ep), F_MODIFIED) && exwr(sp, ep, cmdp, XIT))
- return (1);
- if (file_m3(sp, ep, 0))
- return (1);
-
- force = F_ISSET(cmdp, E_FORCE);
-
- if (ex_ncheck(sp, force))
- return (1);
-
- F_SET(sp, force ? S_EXIT_FORCE : S_EXIT);
- return (0);
-}
-
-/*
- * exwr --
- * The guts of the ex write commands.
- */
-static int
-exwr(sp, ep, cmdp, cmd)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
- enum which cmd;
-{
- EX_PRIVATE *exp;
- MARK rm;
- int flags;
- char *name, *p;
-
- /* All write commands can have an associated '!'. */
- LF_INIT(FS_POSSIBLE);
- if (F_ISSET(cmdp, E_FORCE))
- LF_SET(FS_FORCE);
-
- /* Skip any leading whitespace. */
- if (cmdp->argc != 0)
- for (p = cmdp->argv[0]->bp; *p && isblank(*p); ++p);
-
- /* If no arguments, just write the file back. */
- if (cmdp->argc == 0 || *p == '\0') {
- if (F_ISSET(cmdp, E_ADDR2_ALL))
- LF_SET(FS_ALL);
- return (file_write(sp, ep,
- &cmdp->addr1, &cmdp->addr2, NULL, flags));
- }
-
- /* If "write !" it's a pipe to a utility. */
- exp = EXP(sp);
- if (cmd == WRITE && *p == '!') {
- for (++p; *p && isblank(*p); ++p);
- if (*p == '\0') {
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
- /* Expand the argument. */
- if (argv_exp1(sp, ep, cmdp, p, strlen(p), 0))
- return (1);
- if (filtercmd(sp, ep, &cmdp->addr1, &cmdp->addr2,
- &rm, cmdp->argv[1]->bp, FILTER_WRITE))
- return (1);
- sp->lno = rm.lno;
- return (0);
- }
-
- /* If "write >>" it's an append to a file. */
- if (cmd != XIT && p[0] == '>' && p[1] == '>') {
- LF_SET(FS_APPEND);
-
- /* Skip ">>" and whitespace. */
- for (p += 2; *p && isblank(*p); ++p);
- }
-
- /* Build an argv so we get an argument count and file expansion. */
- if (argv_exp2(sp, ep, cmdp, p, strlen(p), 0))
- return (1);
-
- switch (cmdp->argc) {
- case 1:
- /*
- * Nothing to expand, write the current file.
- * XXX
- * Should never happen, already checked this case.
- */
- name = NULL;
- break;
- case 2:
- /* One new argument, write it. */
- name = cmdp->argv[exp->argsoff - 1]->bp;
- set_alt_name(sp, name);
- break;
- default:
- /* If expanded to more than one argument, object. */
- msgq(sp, M_ERR, "%s expanded into too many file names",
- cmdp->argv[0]->bp);
- msgq(sp, M_ERR, "Usage: %s", cmdp->cmd->usage);
- return (1);
- }
-
- if (F_ISSET(cmdp, E_ADDR2_ALL))
- LF_SET(FS_ALL);
- return (file_write(sp, ep, &cmdp->addr1, &cmdp->addr2, name, flags));
-}
-
-/*
- * ex_writefp --
- * Write a range of lines to a FILE *.
- */
-int
-ex_writefp(sp, ep, name, fp, fm, tm, nlno, nch)
- SCR *sp;
- EXF *ep;
- char *name;
- FILE *fp;
- MARK *fm, *tm;
- u_long *nlno, *nch;
-{
- struct stat sb;
- u_long ccnt; /* XXX: can't print off_t portably. */
- recno_t fline, tline, lcnt;
- size_t len;
- int sv_errno;
- char *p;
-
- fline = fm->lno;
- tline = tm->lno;
-
- if (nlno != NULL) {
- *nch = 0;
- *nlno = 0;
- }
-
- /*
- * The vi filter code has multiple processes running simultaneously,
- * and one of them calls ex_writefp(). The "unsafe" function calls
- * in this code are to file_gline() and msgq(). File_gline() is safe,
- * see the comment in filter.c:filtercmd() for details. We don't call
- * msgq if the multiple process bit in the EXF is set.
- *
- * !!!
- * Historic vi permitted files of 0 length to be written. However,
- * since the way vi got around dealing with "empty" files was to
- * always have a line in the file no matter what, it wrote them as
- * files of a single, empty line. We write empty files.
- *
- * "Alex, I'll take vi trivia for $1000."
- */
- ccnt = 0;
- lcnt = 0;
- if (tline != 0) {
- for (; fline <= tline; ++fline, ++lcnt) {
- /* Caller has to provide any interrupt message. */
- if (INTERRUPTED(sp))
- break;
- if ((p = file_gline(sp, ep, fline, &len)) == NULL)
- break;
- if (fwrite(p, 1, len, fp) != len) {
- msgq(sp, M_SYSERR, name);
- (void)fclose(fp);
- return (1);
- }
- ccnt += len;
- if (putc('\n', fp) != '\n')
- break;
- ++ccnt;
- }
- }
-
- /* If it's a regular file, sync it so that NFS is forced to flush. */
- if (!fstat(fileno(fp), &sb) &&
- S_ISREG(sb.st_mode) && fsync(fileno(fp))) {
- sv_errno = errno;
- (void)fclose(fp);
- errno = sv_errno;
- goto err;
- }
- if (fclose(fp))
- goto err;
- if (nlno != NULL) {
- *nch = ccnt;
- *nlno = lcnt;
- }
- return (0);
-
-err: if (!F_ISSET(ep, F_MULTILOCK))
- msgq(sp, M_SYSERR, name);
- return (1);
-}
diff --git a/usr.bin/vi/ex/ex_yank.c b/usr.bin/vi/ex/ex_yank.c
deleted file mode 100644
index aa44d2b..0000000
--- a/usr.bin/vi/ex/ex_yank.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_yank.c 8.7 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_yank -- :[line [,line]] ya[nk] [buffer] [count]
- *
- * Yank the lines into a buffer.
- */
-int
-ex_yank(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- return (cut(sp, ep,
- F_ISSET(cmdp, E_BUFFER) ? &cmdp->buffer : NULL,
- &cmdp->addr1, &cmdp->addr2, CUT_LINEMODE));
-}
diff --git a/usr.bin/vi/ex/ex_z.c b/usr.bin/vi/ex/ex_z.c
deleted file mode 100644
index d130646..0000000
--- a/usr.bin/vi/ex/ex_z.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ex_z.c 8.8 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * ex_z -- :[line] z [^-.+=] [count] [flags]
- *
- * Adjust window.
- */
-int
-ex_z(sp, ep, cmdp)
- SCR *sp;
- EXF *ep;
- EXCMDARG *cmdp;
-{
- MARK abs;
- recno_t cnt, equals, lno;
- int eofcheck;
-
- /*
- * !!!
- * If no count specified, use either two times the size of the
- * scrolling region, or the size of the window option. POSIX
- * 1003.2 claims that the latter is correct, but historic ex/vi
- * documentation and practice appear to use the scrolling region.
- * I'm using the window size as it means that the entire screen
- * is used instead of losing a line to roundoff. Note, we drop
- * a line from the cnt if using the window size to leave room for
- * the next ex prompt.
- */
- if (F_ISSET(cmdp, E_COUNT))
- cnt = cmdp->count;
- else
-#ifdef HISTORIC_PRACTICE
- cnt = O_VAL(sp, O_SCROLL) * 2;
-#else
- cnt = O_VAL(sp, O_WINDOW) - 1;
-#endif
-
- equals = 0;
- eofcheck = 0;
- lno = cmdp->addr1.lno;
-
- switch (F_ISSET(cmdp,
- E_F_CARAT | E_F_DASH | E_F_DOT | E_F_EQUAL | E_F_PLUS)) {
- case E_F_CARAT: /* Display cnt * 2 before the line. */
- eofcheck = 1;
- if (lno > cnt * 2)
- cmdp->addr1.lno = (lno - cnt * 2) + 1;
- else
- cmdp->addr1.lno = 1;
- cmdp->addr2.lno = (cmdp->addr1.lno + cnt) - 1;
- break;
- case E_F_DASH: /* Line goes at the bottom of the screen. */
- cmdp->addr1.lno = lno > cnt ? (lno - cnt) + 1 : 1;
- cmdp->addr2.lno = lno;
- break;
- case E_F_DOT: /* Line goes in the middle of the screen. */
- /*
- * !!!
- * Historically, the "middleness" of the line overrode the
- * count, so that "3z.19" or "3z.20" would display the first
- * 12 lines of the file, i.e. (N - 1) / 2 lines before and
- * after the specified line.
- */
- eofcheck = 1;
- cnt = (cnt - 1) / 2;
- cmdp->addr1.lno = lno > cnt ? lno - cnt : 1;
- cmdp->addr2.lno = lno + cnt;
-
- /*
- * !!!
- * Historically, z. set the absolute cursor mark.
- */
- abs.lno = sp->lno;
- abs.cno = sp->cno;
- (void)mark_set(sp, ep, ABSMARK1, &abs, 1);
- break;
- case E_F_EQUAL: /* Center with hyphens. */
- /*
- * !!!
- * Strangeness. The '=' flag is like the '.' flag (see the
- * above comment, it applies here as well) but with a special
- * little hack. Print out lines of hyphens before and after
- * the specified line. Additionally, the cursor remains set
- * on that line.
- */
- eofcheck = 1;
- cnt = (cnt - 1) / 2;
- cmdp->addr1.lno = lno > cnt ? lno - cnt : 1;
- cmdp->addr2.lno = lno - 1;
- if (ex_pr(sp, ep, cmdp))
- return (1);
- (void)ex_printf(EXCOOKIE,
- "%s", "----------------------------------------\n");
- cmdp->addr2.lno = cmdp->addr1.lno = equals = lno;
- if (ex_pr(sp, ep, cmdp))
- return (1);
- (void)ex_printf(EXCOOKIE,
- "%s", "----------------------------------------\n");
- cmdp->addr1.lno = lno + 1;
- cmdp->addr2.lno = (lno + cnt) - 1;
- break;
- default:
- /* If no line specified, move to the next one. */
- if (F_ISSET(cmdp, E_ADDRDEF))
- ++lno;
- /* FALLTHROUGH */
- case E_F_PLUS: /* Line goes at the top of the screen. */
- eofcheck = 1;
- cmdp->addr1.lno = lno;
- cmdp->addr2.lno = (lno + cnt) - 1;
- break;
- }
-
- if (eofcheck) {
- if (file_lline(sp, ep, &lno))
- return (1);
- if (cmdp->addr2.lno > lno)
- cmdp->addr2.lno = lno;
- }
-
- if (ex_pr(sp, ep, cmdp))
- return (1);
- if (equals)
- sp->lno = equals;
- return (0);
-}
diff --git a/usr.bin/vi/ex/excmd.awk b/usr.bin/vi/ex/excmd.awk
deleted file mode 100644
index 2890220..0000000
--- a/usr.bin/vi/ex/excmd.awk
+++ /dev/null
@@ -1,6 +0,0 @@
-# @(#)excmd.awk 8.1 (Berkeley) 4/17/94
-
-/^\/\* C_[0-9A-Z_]* \*\/$/ {
- printf("#define %s %d\n", $2, cnt++);
- next;
-}
diff --git a/usr.bin/vi/ex/excmd.c b/usr.bin/vi/ex/excmd.c
deleted file mode 100644
index 422578a..0000000
--- a/usr.bin/vi/ex/excmd.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)excmd.c 8.60 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-
-#include <bitstring.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <termios.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-/*
- * This array maps ex command names to command functions.
- *
- * The order in which command names are listed below is important --
- * ambiguous abbreviations are resolved to be the first possible match,
- * e.g. "r" means "read", not "rewind", because "read" is listed before
- * "rewind".
- *
- * The syntax of the ex commands is unbelievably irregular, and a special
- * case from beginning to end. Each command has an associated "syntax
- * script" which describes the "arguments" that are possible. The script
- * syntax is as follows:
- *
- * ! -- ! flag
- * 1 -- flags: [+-]*[pl#][+-]*
- * 2 -- flags: [-.+^]
- * 3 -- flags: [-.+^=]
- * b -- buffer
- * c[01+a] -- count (0-N, 1-N, signed 1-N, address offset)
- * f[N#][or] -- file (a number or N, optional or required)
- * l -- line
- * S -- string with file name expansion
- * s -- string
- * W -- word string
- * w[N#][or] -- word (a number or N, optional or required)
- */
-EXCMDLIST const cmds[] = {
-/* C_SCROLL */
- {"\004", ex_pr, E_ADDR2|E_NORC,
- "",
- "^D",
- "scroll lines"},
-/* C_BANG */
- {"!", ex_bang, E_ADDR2_NONE|E_NORC,
- "S",
- "[line [,line]] ! command",
- "filter lines through commands or run commands"},
-/* C_HASH */
- {"#", ex_number, E_ADDR2|E_F_PRCLEAR|E_NORC,
- "ca1",
- "[line [,line]] # [count] [l]",
- "display numbered lines"},
-/* C_SUBAGAIN */
- {"&", ex_subagain, E_ADDR2|E_NORC,
- "s",
- "[line [,line]] & [cgr] [count] [#lp]",
- "repeat the last subsitution"},
-/* C_STAR */
- {"*", ex_at, 0,
- "b",
- "* [buffer]",
- "execute a buffer"},
-/* C_SHIFTL */
- {"<", ex_shiftl, E_ADDR2|E_AUTOPRINT|E_NORC,
- "ca1",
- "[line [,line]] <[<...] [count] [flags]",
- "shift lines left"},
-/* C_EQUAL */
- {"=", ex_equal, E_ADDR1|E_NORC|E_ZERO|E_ZERODEF,
- "1",
- "[line] = [flags]",
- "display line number"},
-/* C_SHIFTR */
- {">", ex_shiftr, E_ADDR2|E_AUTOPRINT|E_NORC,
- "ca1",
- "[line [,line]] >[>...] [count] [flags]",
- "shift lines right"},
-/* C_AT */
- {"@", ex_at, 0,
- "b",
- "@ [buffer]",
- "execute a buffer"},
-/* C_APPEND */
- {"append", ex_append, E_ADDR1|E_NORC|E_ZERO|E_ZERODEF,
- "!",
- "[line] a[ppend][!]",
- "append input to a line"},
-/* C_ABBR */
- {"abbreviate", ex_abbr, E_NOGLOBAL,
- "W",
- "ab[brev] [word replace]",
- "specify an input abbreviation"},
-/* C_ARGS */
- {"args", ex_args, E_NOGLOBAL|E_NORC,
- "",
- "ar[gs]",
- "display file argument list"},
-/* C_BG */
- {"bg", ex_bg, E_NOGLOBAL|E_NORC,
- "",
- "bg",
- "background the current screen"},
-/* C_CHANGE */
- {"change", ex_change, E_ADDR2|E_NORC|E_ZERODEF,
- "!ca",
- "[line [,line]] c[hange][!] [count]",
- "change lines to input"},
-/* C_CD */
- {"cd", ex_cd, E_NOGLOBAL,
- "!f1o",
- "cd[!] [directory]",
- "change the current directory"},
-/* C_CHDIR */
- {"chdir", ex_cd, E_NOGLOBAL,
- "!f1o",
- "chd[ir][!] [directory]",
- "change the current directory"},
-/* C_COPY */
- {"copy", ex_copy, E_ADDR2|E_AUTOPRINT|E_NORC,
- "l1",
- "[line [,line]] co[py] line [flags]",
- "copy lines elsewhere in the file"},
-/*
- * !!!
- * Adding new commands starting with 'd' may break the delete command code
- * in ex_cmd() (the ex parser). Read through the comments there, first.
- */
-/* C_DELETE */
- {"delete", ex_delete, E_ADDR2|E_AUTOPRINT|E_NORC,
- "bca1",
- "[line [,line]] d[elete][flags] [buffer] [count] [flags]",
- "delete lines from the file"},
-/* C_DISPLAY */
- {"display", ex_display, E_NOGLOBAL|E_NORC,
- "w1r",
- "display b[uffers] | s[creens] | t[ags]",
- "display buffers, screens or tags"},
-/* C_DIGRAPH */
- {"digraph", ex_digraph, E_NOGLOBAL|E_NOPERM|E_NORC,
- "",
- "digraph",
- "specify digraphs (not implemented)"},
-/* C_EDIT */
- {"edit", ex_edit, E_NOGLOBAL|E_NORC,
- "f1o",
- "e[dit][!] [+cmd] [file]",
- "begin editing another file"},
-/* C_EX */
- {"ex", ex_edit, E_NOGLOBAL|E_NORC,
- "f1o",
- "ex[!] [+cmd] [file]",
- "begin editing another file"},
-/* C_EXUSAGE */
- {"exusage", ex_usage, E_NOGLOBAL|E_NORC,
- "w1o",
- "[exu]sage [command]",
- "display ex command usage statement"},
-/* C_FILE */
- {"file", ex_file, E_NOGLOBAL|E_NORC,
- "f1o",
- "f[ile] [name]",
- "display (and optionally set) file name"},
-/* C_FG */
- {"fg", ex_fg, E_NOGLOBAL|E_NORC,
- "f1o",
- "fg [file]",
- "switch the current screen and a backgrounded screen"},
-/* C_GLOBAL */
- {"global", ex_global, E_ADDR2_ALL|E_NOGLOBAL|E_NORC,
- "!s",
- "[line [,line]] g[lobal][!] [;/]RE[;/] [commands]",
- "execute a global command on lines matching an RE"},
-/* C_HELP */
- {"help", ex_help, E_NOGLOBAL|E_NORC,
- "",
- "he[lp]",
- "display help statement"},
-/* C_INSERT */
- {"insert", ex_insert, E_ADDR1|E_NORC,
- "!",
- "[line] i[nsert][!]",
- "insert input before a line"},
-/* C_JOIN */
- {"join", ex_join, E_ADDR2|E_AUTOPRINT|E_NORC,
- "!ca1",
- "[line [,line]] j[oin][!] [count] [flags]",
- "join lines into a single line"},
-/* C_K */
- {"k", ex_mark, E_ADDR1|E_NORC,
- "w1r",
- "[line] k key",
- "mark a line position"},
-/* C_LIST */
- {"list", ex_list, E_ADDR2|E_F_PRCLEAR|E_NORC,
- "ca1",
- "[line [,line]] l[ist] [count] [#]",
- "display lines in an unambiguous form"},
-/* C_MOVE */
- {"move", ex_move, E_ADDR2|E_AUTOPRINT|E_NORC,
- "l",
- "[line [,line]] m[ove] line",
- "move lines elsewhere in the file"},
-/* C_MARK */
- {"mark", ex_mark, E_ADDR1|E_NORC,
- "w1r",
- "[line] ma[rk] key",
- "mark a line position"},
-/* C_MAP */
- {"map", ex_map, 0,
- "!W",
- "map[!] [keys replace]",
- "map input or commands to one or more keys"},
-/* C_MKEXRC */
- {"mkexrc", ex_mkexrc, E_NOGLOBAL|E_NORC,
- "!f1r",
- "mkexrc[!] file",
- "write a .exrc file"},
-/* C_NEXT */
- {"next", ex_next, E_NOGLOBAL|E_NORC,
- "!fN",
- "n[ext][!] [+cmd] [file ...]",
- "edit (and optionally specify) the next file"},
-/* C_NUMBER */
- {"number", ex_number, E_ADDR2|E_F_PRCLEAR|E_NORC,
- "ca1",
- "[line [,line]] nu[mber] [count] [l]",
- "change display to number lines"},
-/* C_OPEN */
- {"open", ex_open, E_ADDR1,
- "s",
- "[line] o[pen] [/RE/] [flags]",
- "enter \"open\" mode (not implemented)"},
-/* C_PRINT */
- {"print", ex_pr, E_ADDR2|E_F_PRCLEAR|E_NORC,
- "ca1",
- "[line [,line]] p[rint] [count] [#l]",
- "display lines"},
-/* C_PRESERVE */
- {"preserve", ex_preserve, E_NOGLOBAL|E_NORC,
- "",
- "pre[serve]",
- "preserve an edit session for recovery"},
-/* C_PREVIOUS */
- {"previous", ex_prev, E_NOGLOBAL|E_NORC,
- "!",
- "prev[ious][!]",
- "edit the previous file in the file argument list"},
-/* C_PUT */
- {"put", ex_put, E_ADDR1|E_AUTOPRINT|E_NORC|E_ZERO,
- "b",
- "[line] pu[t] [buffer]",
- "append a cut buffer to the line"},
-/* C_QUIT */
- {"quit", ex_quit, E_NOGLOBAL|E_NORC,
- "!",
- "q[uit][!]",
- "exit ex/vi"},
-/* C_READ */
- {"read", ex_read, E_ADDR1|E_NORC|E_ZERO|E_ZERODEF,
- "s",
- "[line] r[ead] [!cmd | [file]]",
- "append input from a command or file to the line"},
-/* C_RECOVER */
- {"recover", ex_recover, E_NOGLOBAL|E_NORC,
- "!f1r",
- "recover[!] file",
- "recover a saved file"},
-/* C_RESIZE */
- {"resize", ex_resize, E_NOGLOBAL|E_NORC,
- "c+",
- "resize [+-]rows",
- "grow or shrink the current screen"},
-/* C_REWIND */
- {"rewind", ex_rew, E_NOGLOBAL|E_NORC,
- "!",
- "rew[ind][!]",
- "re-edit all the files in the file argument list"},
-/* C_SUBSTITUTE */
- {"substitute", ex_substitute, E_ADDR2|E_NORC,
- "s",
-"[line [,line]] s[ubstitute] [[/;]RE[/;]/repl[/;] [cgr] [count] [#lp]]",
- "substitute on lines matching an RE"},
-/* C_SCRIPT */
- {"script", ex_script, E_NOGLOBAL|E_NORC,
- "!f1o",
- "sc[ript][!] [file]",
- "run a shell in a screen"},
-/* C_SET */
- {"set", ex_set, E_NOGLOBAL,
- "wN",
- "se[t] [option[=[value]]...] [nooption ...] [option? ...] [all]",
- "set options (use \":set all\" to see all options)"},
-/* C_SHELL */
- {"shell", ex_shell, E_NOGLOBAL|E_NORC,
- "",
- "sh[ell]",
- "suspend editing and run a shell"},
-/* C_SOURCE */
- {"source", ex_source, E_NOGLOBAL,
- "f1r",
- "so[urce] file",
- "read a file of ex commands"},
-/* C_SPLIT */
- {"split", ex_split, E_NOGLOBAL|E_NORC,
- "fNo",
- "sp[lit] [file ...]",
- "split the current screen into two screens"},
-/* C_STOP */
- {"stop", ex_stop, E_NOGLOBAL|E_NORC,
- "!",
- "st[op][!]",
- "suspend the edit session"},
-/* C_SUSPEND */
- {"suspend", ex_stop, E_NOGLOBAL|E_NORC,
- "!",
- "su[spend][!]",
- "suspend the edit session"},
-/* C_T */
- {"t", ex_copy, E_ADDR2|E_AUTOPRINT|E_NORC,
- "l1",
- "[line [,line]] t line [flags]",
- "copy lines elsewhere in the file"},
-/* C_TAG */
- {"tag", ex_tagpush, E_NOGLOBAL,
- "!w1o",
- "ta[g][!] [string]",
- "edit the file containing the tag"},
-/* C_TAGPOP */
- {"tagpop", ex_tagpop, E_NOGLOBAL|E_NORC,
- "!w1o",
- "tagp[op][!] [number | file]",
- "return to a previous tag"},
-/* C_TAGTOP */
- {"tagtop", ex_tagtop, E_NOGLOBAL|E_NORC,
- "!",
- "tagt[op][!]",
- "return to the first tag"},
-/* C_UNDO */
- {"undo", ex_undo, E_AUTOPRINT|E_NOGLOBAL|E_NORC,
- "",
- "u[ndo]",
- "undo the most recent change"},
-/* C_UNABBREVIATE */
- {"unabbreviate",ex_unabbr, E_NOGLOBAL,
- "w1r",
- "una[bbrev] word",
- "delete an abbreviation"},
-/* C_UNMAP */
- {"unmap", ex_unmap, E_NOGLOBAL,
- "!w1r",
- "unm[ap][!] word",
- "delete an input or command map"},
-/* C_VGLOBAL */
- {"vglobal", ex_vglobal, E_ADDR2_ALL|E_NOGLOBAL|E_NORC,
- "s",
- "[line [,line]] v[global] [;/]RE[;/] [commands]",
- "execute a global command on lines NOT matching an RE"},
-/* C_VERSION */
- {"version", ex_version, E_NOGLOBAL|E_NORC,
- "",
- "version",
- "display the program version information"},
-/* C_VISUAL_EX */
- {"visual", ex_visual, E_ADDR1|E_NOGLOBAL|E_NORC|E_ZERODEF,
- "2c11",
- "[line] vi[sual] [-|.|+|^] [window_size] [flags]",
- "enter visual (vi) mode from ex mode"},
-/* C_VISUAL_VI */
- {"visual", ex_edit, E_NOGLOBAL|E_NORC,
- "f1o",
- "vi[sual][!] [+cmd] [file]",
- "edit another file (from vi mode only)"},
-/* C_VIUSAGE */
- {"viusage", ex_viusage, E_NOGLOBAL|E_NORC,
- "w1o",
- "[viu]sage [key]",
- "display vi key usage statement"},
-/* C_WRITE */
- {"write", ex_write, E_ADDR2_ALL|E_NOGLOBAL|E_NORC|E_ZERODEF,
- "!s",
- "[line [,line]] w[rite][!] [!cmd | [>>] [file]]",
- "write the file"},
-/* C_WN */
- {"wn", ex_wn, E_ADDR2_ALL|E_NOGLOBAL|E_NORC|E_ZERODEF,
- "!s",
- "[line [,line]] wn[!] [>>] [file]",
- "write the file and switch to the next file"},
-/* C_WQ */
- {"wq", ex_wq, E_ADDR2_ALL|E_NOGLOBAL|E_NORC|E_ZERODEF,
- "!s",
- "[line [,line]] wq[!] [>>] [file]",
- "write the file and exit"},
-/* C_XIT */
- {"xit", ex_xit, E_ADDR2_ALL|E_NOGLOBAL|E_NORC|E_ZERODEF,
- "!f1o",
- "[line [,line]] x[it][!] [file]",
- "exit"},
-/* C_YANK */
- {"yank", ex_yank, E_ADDR2|E_NORC,
- "bca",
- "[line [,line]] ya[nk] [buffer] [count]",
- "copy lines to a cut buffer"},
-/* C_Z */
- {"z", ex_z, E_ADDR1|E_NOGLOBAL|E_NORC,
- "3c01",
- "[line] z [-|.|+|^|=] [count] [flags]",
- "display different screens of the file"},
-/* C_SUBTILDE */
- {"~", ex_subtilde, E_ADDR2|E_NORC,
- "s",
- "[line [,line]] ~ [cgr] [count] [#lp]",
- "replace previous RE with previous replacement string,"},
- {NULL},
-};
diff --git a/usr.bin/vi/ex/excmd.h.stub b/usr.bin/vi/ex/excmd.h.stub
deleted file mode 100644
index 3b4051b..0000000
--- a/usr.bin/vi/ex/excmd.h.stub
+++ /dev/null
@@ -1,285 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)excmd.h.stub 8.73 (Berkeley) 8/9/94
- */
-
-#define PROMPTCHAR ':' /* Prompt character. */
-
-/* Ex command structure. */
-typedef struct _excmdlist {
- char *name; /* Command name. */
- /* Underlying function. */
- int (*fn) __P((SCR *, EXF *, EXCMDARG *));
-
-#define E_ADDR1 0x0000001 /* One address. */
-#define E_ADDR2 0x0000002 /* Two address. */
-#define E_ADDR2_ALL 0x0000004 /* Zero/two addresses; zero == all. */
-#define E_ADDR2_NONE 0x0000008 /* Zero/two addresses; zero == none. */
-#define E_ADDRDEF 0x0000010 /* Default addresses used. */
-#define E_AUTOPRINT 0x0000020 /* Command always sets autoprint. */
-#define E_BUFFER 0x0000040 /* Buffer name supplied. */
-#define E_COUNT 0x0000080 /* Count supplied. */
-#define E_COUNT_NEG 0x0000100 /* Count was signed negative. */
-#define E_COUNT_POS 0x0000200 /* Count was signed positive. */
-#define E_FORCE 0x0000400 /* ! */
-
-#define E_F_CARAT 0x0000800 /* ^ flag. */
-#define E_F_DASH 0x0001000 /* - flag. */
-#define E_F_DOT 0x0002000 /* . flag. */
-#define E_F_EQUAL 0x0004000 /* = flag. */
-#define E_F_HASH 0x0008000 /* # flag. */
-#define E_F_LIST 0x0010000 /* l flag. */
-#define E_F_PLUS 0x0020000 /* + flag. */
-#define E_F_PRINT 0x0040000 /* p flag. */
-
-#define E_F_PRCLEAR 0x0080000 /* Clear the print (#, l, p) flags. */
-#define E_MODIFY 0x0100000 /* File name expansion modified arg. */
-#define E_NOGLOBAL 0x0200000 /* Not in a global. */
-#define E_NOPERM 0x0400000 /* Permission denied for now. */
-#define E_NORC 0x0800000 /* Not from a .exrc or EXINIT. */
-#define E_ZERO 0x1000000 /* 0 is a legal addr1. */
-#define E_ZERODEF 0x2000000 /* 0 is default addr1 of empty files. */
- u_int32_t flags;
- char *syntax; /* Syntax script. */
- char *usage; /* Usage line. */
- char *help; /* Help line. */
-} EXCMDLIST;
-#define MAXCMDNAMELEN 12 /* Longest command name. */
-extern EXCMDLIST const cmds[]; /* List of ex commands. */
-
-/*
- * Structure passed around to functions implementing ex commands.
- * There are several commands in vi that build one of these and
- * call ex directly. See vi/v_ex.c for details.
- */
-struct _excmdarg {
- EXCMDLIST const *cmd; /* Command entry in command table. */
- CHAR_T buffer; /* Named buffer. */
- recno_t lineno; /* Line number. */
- long count; /* Signed, specified count. */
- long flagoff; /* Signed, flag offset parsed by command. */
- int addrcnt; /* Number of addresses (0, 1 or 2). */
- MARK addr1; /* 1st address. */
- MARK addr2; /* 2nd address. */
- ARGS **argv; /* Array of arguments. */
- int argc; /* Count of arguments. */
- u_int32_t flags; /* Selected flags from EXCMDLIST. */
-};
-
-/* Global ranges. */
-typedef struct _range RANGE;
-struct _range {
- CIRCLEQ_ENTRY(_range) q; /* Linked list of ranges. */
- recno_t start, stop; /* Start/stop of the range. */
-};
-
-/* Cd paths. */
-typedef struct _cdpath CDPATH;
-struct _cdpath {
- TAILQ_ENTRY(_cdpath) q; /* Linked list of cd paths. */
- char *path; /* Path. */
-};
-
-/* Ex private, per-screen memory. */
-typedef struct _ex_private {
- ARGS **args; /* Arguments. */
- int argscnt; /* Argument count. */
- int argsoff; /* Offset into arguments. */
-
- CHAR_T at_lbuf; /* Last executed at buffer's name. */
- int at_lbuf_set; /* If at_lbuf is set. */
-
- char *ibp; /* Line input buffer. */
- size_t ibp_len; /* Line input buffer length. */
-
- u_int32_t fdef; /* Default command flags. */
-
- CHAR_T *lastbcomm; /* Last bang command. */
-
- struct termios leave_term; /* ex_[sr]leave tty state. */
- /* XXX: Should be struct timespec's, but time_t is more portable. */
- time_t leave_atime; /* ex_[sr]leave old access time. */
- time_t leave_mtime; /* ex_[sr]leave old mod time. */
-
- TAILQ_HEAD(_tagh, _tag) tagq; /* Tag list (stack). */
- TAILQ_HEAD(_tagfh, _tagf) tagfq;/* Tag file list. */
- char *tlast; /* Saved last tag. */
-
- TAILQ_HEAD(_cdh, _cdpath) cdq; /* Cd path list. */
-
- /* Linked list of ranges. */
- CIRCLEQ_HEAD(_rangeh, _range) rangeq;
- recno_t range_lno; /* Range set line number. */
-
-#define EX_ABSMARK 0x01 /* Set the absolute mark. */
-#define EX_AUTOPRINT 0x02 /* Autoprint flag. */
- u_int8_t flags;
-} EX_PRIVATE;
-#define EXP(sp) ((EX_PRIVATE *)((sp)->ex_private))
-
-/*
- * !!!
- * Historically, .exrc files and EXINIT variables could only use ^V
- * as an escape character, neither ^Q or a user specified character
- * worked. We enforce that here, just in case someone depends on it.
- */
-#define IS_ESCAPE(sp, ch) \
- (F_ISSET(sp, S_VLITONLY) ? \
- (ch) == CH_LITERAL : KEY_VAL(sp, ch) == K_VLNEXT)
-
-/*
- * Filter actions:
- *
- * FILTER Filter text through the utility.
- * FILTER_READ Read from the utility into the file.
- * FILTER_WRITE Write to the utility, display its output.
- */
-enum filtertype { FILTER, FILTER_READ, FILTER_WRITE };
-int filtercmd __P((SCR *, EXF *,
- MARK *, MARK *, MARK *, char *, enum filtertype));
-
-/* Argument expansion routines. */
-int argv_init __P((SCR *, EXF *, EXCMDARG *));
-int argv_exp0 __P((SCR *, EXF *, EXCMDARG *, char *, size_t));
-int argv_exp1 __P((SCR *, EXF *, EXCMDARG *, char *, size_t, int));
-int argv_exp2 __P((SCR *, EXF *, EXCMDARG *, char *, size_t, int));
-int argv_exp3 __P((SCR *, EXF *, EXCMDARG *, char *, size_t));
-int argv_free __P((SCR *));
-
-/* Ex function prototypes. */
-int ex __P((SCR *, EXF *));
-int ex_cfile __P((SCR *, EXF *, char *, int));
-int ex_cmd __P((SCR *, EXF *, char *, size_t, int));
-int ex_cdalloc __P((SCR *, char *));
-int ex_cdfree __P((SCR *));
-int ex_end __P((SCR *));
-int ex_exec_proc __P((SCR *, char *, char *, char *));
-int ex_gb __P((SCR *, EXF *, TEXTH *, int, u_int));
-int ex_getline __P((SCR *, FILE *, size_t *));
-int ex_icmd __P((SCR *, EXF *, char *, size_t, int));
-int ex_init __P((SCR *, EXF *));
-int ex_is_abbrev __P((char *, size_t));
-int ex_is_unmap __P((char *, size_t));
-int ex_ldisplay __P((SCR *, CHAR_T *, size_t, size_t, u_int));
-int ex_ncheck __P((SCR *, int));
-int ex_optchange __P((SCR *, int));
-int ex_print __P((SCR *, EXF *, MARK *, MARK *, int));
-int ex_readfp __P((SCR *, EXF *, char *, FILE *, MARK *, recno_t *, int));
-void ex_refresh __P((SCR *, EXF *));
-void ex_rleave __P((SCR *));
-int ex_screen_copy __P((SCR *, SCR *));
-int ex_screen_end __P((SCR *));
-int ex_sdisplay __P((SCR *, EXF *));
-int ex_sleave __P((SCR *));
-int ex_suspend __P((SCR *));
-int ex_tdisplay __P((SCR *, EXF *));
-int ex_writefp __P((SCR *, EXF *,
- char *, FILE *, MARK *, MARK *, u_long *, u_long *));
-void global_insdel __P((SCR *, EXF *, enum operation, recno_t));
-int proc_wait __P((SCR *, long, const char *, int));
-int sscr_end __P((SCR *));
-int sscr_exec __P((SCR *, EXF *, recno_t));
-int sscr_input __P((SCR *));
-
-int abbr_save __P((SCR *, FILE *));
-int map_save __P((SCR *, FILE *));
-
-#define EXPROTO(name) int name __P((SCR *, EXF *, EXCMDARG *))
-EXPROTO(ex_abbr);
-EXPROTO(ex_append);
-EXPROTO(ex_args);
-EXPROTO(ex_at);
-EXPROTO(ex_bang);
-EXPROTO(ex_bg);
-EXPROTO(ex_cd);
-EXPROTO(ex_change);
-EXPROTO(ex_color);
-EXPROTO(ex_copy);
-EXPROTO(ex_debug);
-EXPROTO(ex_delete);
-EXPROTO(ex_digraph);
-EXPROTO(ex_display);
-EXPROTO(ex_edit);
-EXPROTO(ex_equal);
-EXPROTO(ex_fg);
-EXPROTO(ex_file);
-EXPROTO(ex_global);
-EXPROTO(ex_help);
-EXPROTO(ex_insert);
-EXPROTO(ex_join);
-EXPROTO(ex_list);
-EXPROTO(ex_map);
-EXPROTO(ex_mark);
-EXPROTO(ex_mkexrc);
-EXPROTO(ex_move);
-EXPROTO(ex_next);
-EXPROTO(ex_number);
-EXPROTO(ex_open);
-EXPROTO(ex_pr);
-EXPROTO(ex_preserve);
-EXPROTO(ex_prev);
-EXPROTO(ex_put);
-EXPROTO(ex_quit);
-EXPROTO(ex_read);
-EXPROTO(ex_recover);
-EXPROTO(ex_resize);
-EXPROTO(ex_rew);
-EXPROTO(ex_script);
-EXPROTO(ex_set);
-EXPROTO(ex_shell);
-EXPROTO(ex_shiftl);
-EXPROTO(ex_shiftr);
-EXPROTO(ex_source);
-EXPROTO(ex_split);
-EXPROTO(ex_stop);
-EXPROTO(ex_subagain);
-EXPROTO(ex_substitute);
-EXPROTO(ex_subtilde);
-EXPROTO(ex_tagpop);
-EXPROTO(ex_tagpush);
-EXPROTO(ex_tagtop);
-EXPROTO(ex_unabbr);
-EXPROTO(ex_undo);
-EXPROTO(ex_unmap);
-EXPROTO(ex_usage);
-EXPROTO(ex_validate);
-EXPROTO(ex_version);
-EXPROTO(ex_vglobal);
-EXPROTO(ex_visual);
-EXPROTO(ex_viusage);
-EXPROTO(ex_wn);
-EXPROTO(ex_wq);
-EXPROTO(ex_write);
-EXPROTO(ex_xit);
-EXPROTO(ex_yank);
-EXPROTO(ex_z);
diff --git a/usr.bin/vi/ex/filter.c b/usr.bin/vi/ex/filter.c
deleted file mode 100644
index abe7ca1..0000000
--- a/usr.bin/vi/ex/filter.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*-
- * Copyright (c) 1991, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)filter.c 8.45 (Berkeley) 8/17/94";
-#endif /* not lint */
-
-#include <sys/types.h>
-#include <sys/queue.h>
-#include <sys/time.h>
-#include <sys/wait.h>
-
-#include <bitstring.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <termios.h>
-#include <unistd.h>
-
-#include "compat.h"
-#include <db.h>
-#include <regex.h>
-#include <pathnames.h>
-
-#include "vi.h"
-#include "excmd.h"
-
-static int filter_ldisplay __P((SCR *, FILE *));
-
-/*
- * filtercmd --
- * Run a range of lines through a filter utility and optionally
- * replace the original text with the stdout/stderr output of
- * the utility.
- */
-int
-filtercmd(sp, ep, fm, tm, rp, cmd, ftype)
- SCR *sp;
- EXF *ep;
- MARK *fm, *tm, *rp;
- char *cmd;
- enum filtertype ftype;
-{
- FILE *ifp, *ofp;
- pid_t parent_writer_pid, utility_pid;
- recno_t nread;
- int input[2], output[2], rval, teardown;
- char *name;
-
- /* Set return cursor position; guard against a line number of zero. */
- *rp = *fm;
- if (fm->lno == 0)
- rp->lno = 1;
-
- /*
- * There are three different processes running through this code.
- * They are the utility, the parent-writer and the parent-reader.
- * The parent-writer is the process that writes from the file to
- * the utility, the parent reader is the process that reads from
- * the utility.
- *
- * Input and output are named from the utility's point of view.
- * The utility reads from input[0] and the parent(s) write to
- * input[1]. The parent(s) read from output[0] and the utility
- * writes to output[1].
- *
- * In the FILTER_READ case, the utility isn't expected to want
- * input. Redirect its input from /dev/null. Otherwise open
- * up utility input pipe.
- */
- teardown = 0;
- ofp = NULL;
- input[0] = input[1] = output[0] = output[1] = -1;
- if (ftype == FILTER_READ) {
- if ((input[0] = open(_PATH_DEVNULL, O_RDONLY, 0)) < 0) {
- msgq(sp, M_ERR,
- "filter: %s: %s", _PATH_DEVNULL, strerror(errno));
- return (1);
- }
- } else
- if (pipe(input) < 0) {
- msgq(sp, M_SYSERR, "pipe");
- goto err;
- }
-
- /* Open up utility output pipe. */
- if (pipe(output) < 0) {
- msgq(sp, M_SYSERR, "pipe");
- goto err;
- }
- if ((ofp = fdopen(output[0], "r")) == NULL) {
- msgq(sp, M_SYSERR, "fdopen");
- goto err;
- }
-
- /*
- * Save ex/vi terminal settings, and restore the original ones.
- * Restoration so that users can do things like ":r! cat /dev/tty".
- */
- teardown = ftype != FILTER_WRITE && !ex_sleave(sp);
-
- /* Fork off the utility process. */
- SIGBLOCK(sp->gp);
- switch (utility_pid = vfork()) {
- case -1: /* Error. */
- SIGUNBLOCK(sp->gp);
-
- msgq(sp, M_SYSERR, "vfork");
-err: if (input[0] != -1)
- (void)close(input[0]);
- if (input[1] != -1)
- (void)close(input[1]);
- if (ofp != NULL)
- (void)fclose(ofp);
- else if (output[0] != -1)
- (void)close(output[0]);
- if (output[1] != -1)
- (void)close(output[1]);
- rval = 1;
- goto ret;
- case 0: /* Utility. */
- /* The utility has default signal behavior. */
- sig_end();
-
- /*
- * Redirect stdin from the read end of the input pipe, and
- * redirect stdout/stderr to the write end of the output pipe.
- *
- * !!!
- * Historically, ex only directed stdout into the input pipe,
- * letting stderr come out on the terminal as usual. Vi did
- * not, directing both stdout and stderr into the input pipe.
- * We match that practice for both ex and vi for consistency.
- */
- (void)dup2(input[0], STDIN_FILENO);
- (void)dup2(output[1], STDOUT_FILENO);
- (void)dup2(output[1], STDERR_FILENO);
-
- /* Close the utility's file descriptors. */
- (void)close(input[0]);
- (void)close(input[1]);
- (void)close(output[0]);
- (void)close(output[1]);
-
- if ((name = strrchr(O_STR(sp, O_SHELL), '/')) == NULL)
- name = O_STR(sp, O_SHELL);
- else
- ++name;
-
- execl(O_STR(sp, O_SHELL), name, "-c", cmd, NULL);
- msgq(sp, M_ERR, "Error: execl: %s: %s",
- O_STR(sp, O_SHELL), strerror(errno));
- _exit (127);
- /* NOTREACHED */
- default: /* Parent-reader, parent-writer. */
- SIGUNBLOCK(sp->gp);
-
- /* Close the pipe ends neither parent will use. */
- (void)close(input[0]);
- (void)close(output[1]);
- break;
- }
-
- /*
- * FILTER_READ:
- *
- * Reading is the simple case -- we don't need a parent writer,
- * so the parent reads the output from the read end of the output
- * pipe until it finishes, then waits for the child. Ex_readfp
- * appends to the MARK, and closes ofp.
- *
- * !!!
- * Set the return cursor to the last line read in. Historically,
- * this behaves differently from ":r file" command, which leaves
- * the cursor at the first line read in. Check to make sure that
- * it's not past EOF because we were reading into an empty file.
- */
- if (ftype == FILTER_READ) {
- rval = ex_readfp(sp, ep, "filter", ofp, fm, &nread, 0);
- sp->rptlines[L_ADDED] += nread;
- if (fm->lno == 0)
- rp->lno = nread;
- else
- rp->lno += nread;
- goto uwait;
- }
-
- /*
- * FILTER, FILTER_WRITE
- *
- * Here we need both a reader and a writer. Temporary files are
- * expensive and we'd like to avoid disk I/O. Using pipes has the
- * obvious starvation conditions. It's done as follows:
- *
- * fork
- * child
- * write lines out
- * exit
- * parent
- * FILTER:
- * read lines into the file
- * delete old lines
- * FILTER_WRITE
- * read and display lines
- * wait for child
- *
- * XXX
- * We get away without locking the underlying database because we know
- * that none of the records that we're reading will be modified until
- * after we've read them. This depends on the fact that the current
- * B+tree implementation doesn't balance pages or similar things when
- * it inserts new records. When the DB code has locking, we should
- * treat vi as if it were multiple applications sharing a database, and
- * do the required locking. If necessary a work-around would be to do
- * explicit locking in the line.c:file_gline() code, based on the flag
- * set here.
- */
- rval = 0;
- F_SET(ep, F_MULTILOCK);
-
- SIGBLOCK(sp->gp);
- switch (parent_writer_pid = fork()) {
- case -1: /* Error. */
- SIGUNBLOCK(sp->gp);
-
- msgq(sp, M_SYSERR, "fork");
- (void)close(input[1]);
- (void)close(output[0]);
- rval = 1;
- break;
- case 0: /* Parent-writer. */
- /*
- * Write the selected lines to the write end of the input
- * pipe. This instance of ifp is closed by ex_writefp.
- */
- (void)close(output[0]);
- if ((ifp = fdopen(input[1], "w")) == NULL)
- _exit (1);
- _exit(ex_writefp(sp, ep, "filter", ifp, fm, tm, NULL, NULL));
-
- /* NOTREACHED */
- default: /* Parent-reader. */
- SIGUNBLOCK(sp->gp);
-
- (void)close(input[1]);
- if (ftype == FILTER_WRITE)
- /*
- * Read the output from the read end of the output
- * pipe and display it. Filter_ldisplay closes ofp.
- */
- rval = filter_ldisplay(sp, ofp);
- else {
- /*
- * Read the output from the read end of the output
- * pipe. Ex_readfp appends to the MARK and closes
- * ofp.
- */
- rval = ex_readfp(sp, ep, "filter", ofp, tm, &nread, 0);
- sp->rptlines[L_ADDED] += nread;
- }
-
- /* Wait for the parent-writer. */
- rval |= proc_wait(sp,
- (long)parent_writer_pid, "parent-writer", 1);
-
- /* Delete any lines written to the utility. */
- if (rval == 0 && ftype == FILTER &&
- (cut(sp, ep, NULL, fm, tm, CUT_LINEMODE) ||
- delete(sp, ep, fm, tm, 1))) {
- rval = 1;
- break;
- }
-
- /*
- * If the filter had no output, we may have just deleted
- * the cursor. Don't do any real error correction, we'll
- * try and recover later.
- */
- if (rp->lno > 1 && file_gline(sp, ep, rp->lno, NULL) == NULL)
- --rp->lno;
- break;
- }
- F_CLR(ep, F_MULTILOCK);
-
-uwait: rval |= proc_wait(sp, (long)utility_pid, cmd, 0);
-
- /* Restore ex/vi terminal settings. */
-ret: if (teardown)
- ex_rleave(sp);
- return (rval);
-}
-
-/*
- * proc_wait --
- * Wait for one of the processes.
- *
- * !!!
- * The pid_t type varies in size from a short to a long depending on the
- * system. It has to be cast into something or the standard promotion
- * rules get you. I'm using a long based on the belief that nobody is
- * going to make it unsigned and it's unlikely to be a quad.
- */
-int
-proc_wait(sp, pid, cmd, okpipe)
- SCR *sp;
- long pid;
- const char *cmd;
- int okpipe;
-{
- extern const char *const sys_siglist[];
- size_t len;
- int pstat;
-
- /*
- * Wait for the utility to finish. We can get interrupted
- * by SIGALRM, just ignore it.
- */
- for (;;) {
- errno = 0;
- if (waitpid((pid_t)pid, &pstat, 0) != -1)
- break;
- if (errno != EINTR) {
- msgq(sp, M_SYSERR, "wait error");
- return (1);
- }
- }
-
- /*
- * Display the utility's exit status. Ignore SIGPIPE from the
- * parent-writer, as that only means that the utility chose to
- * exit before reading all of its input.
- */
- if (WIFSIGNALED(pstat) && (!okpipe || WTERMSIG(pstat) != SIGPIPE)) {
- for (; isblank(*cmd); ++cmd);
- len = strlen(cmd);
- msgq(sp, M_ERR, "%.*s%s: received signal: %s%s",
- MIN(len, 20), cmd, len > 20 ? "..." : "",
- sys_siglist[WTERMSIG(pstat)],
- WCOREDUMP(pstat) ? "; core dumped" : "");
- return (1);
- }
- if (WIFEXITED(pstat) && WEXITSTATUS(pstat)) {
- for (; isblank(*cmd); ++cmd);
- len = strlen(cmd);
- msgq(sp, M_ERR, "%.*s%s: exited with status %d",
- MIN(len, 20), cmd, len > 20 ? "..." : "",
- WEXITSTATUS(pstat));
- return (1);
- }
- return (0);
-}
-
-/*
- * filter_ldisplay --
- * Display output from a utility.
- *
- * !!!
- * Historically, the characters were passed unmodified to the terminal.
- * We use the ex print routines to make sure they're printable.
- */
-static int
-filter_ldisplay(sp, fp)
- SCR *sp;
- FILE *fp;
-{
- size_t len;
-
- EX_PRIVATE *exp;
-
- F_SET(sp, S_INTERRUPTIBLE);
- for (exp = EXP(sp); !ex_getline(sp, fp, &len);) {
- if (ex_ldisplay(sp, exp->ibp, len, 0, 0))
- break;
- if (INTERRUPTED(sp))
- break;
- }
- if (ferror(fp))
- msgq(sp, M_SYSERR, "filter input");
- (void)fclose(fp);
- return (0);
-}
diff --git a/usr.bin/vi/ex/script.h b/usr.bin/vi/ex/script.h
deleted file mode 100644
index b21c63a..0000000
--- a/usr.bin/vi/ex/script.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*-
- * Copyright (c) 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)script.h 8.2 (Berkeley) 4/17/94
- */
-
-struct _script {
- pid_t sh_pid; /* Shell pid. */
- int sh_master; /* Master pty fd. */
- int sh_slave; /* Slave pty fd. */
- char *sh_prompt; /* Prompt. */
- size_t sh_prompt_len; /* Prompt length. */
- char sh_name[64]; /* Pty name */
- struct winsize sh_win; /* Window size. */
- struct termios sh_term; /* Terminal information. */
-};
diff --git a/usr.bin/vi/ex/tag.h b/usr.bin/vi/ex/tag.h
deleted file mode 100644
index a9fd59d..0000000
--- a/usr.bin/vi/ex/tag.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*-
- * Copyright (c) 1992, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)tag.h 8.13 (Berkeley) 7/17/94
- */
-
-struct _tagf { /* Tag file. */
- TAILQ_ENTRY(_tagf) q; /* Linked list of tag files. */
- char *name; /* Tag file name. */
-
-#define TAGF_DNE 0x01 /* Didn't exist. */
-#define TAGF_DNE_WARN 0x02 /* DNE error reported. */
- u_int8_t flags;
-};
-
-struct _tag { /* Tag stack. */
- TAILQ_ENTRY(_tag) q; /* Linked list of tags. */
- FREF *frp; /* Saved file name. */
- recno_t lno; /* Saved line number. */
- size_t cno; /* Saved column number. */
- char *search; /* Search string. */
- size_t slen; /* Search string length. */
-};
-
-int ex_tagalloc __P((SCR *, char *));
-int ex_tagcopy __P((SCR *, SCR *));
-int ex_tagdisplay __P((SCR *, EXF *));
-int ex_tagfirst __P((SCR *, char *));
-int ex_tagfree __P((SCR *));
OpenPOWER on IntegriCloud