diff options
author | michaels <michaels@cvs.openbsd.org> | 1996-08-16 17:58:49 +0000 |
---|---|---|
committer | michaels <michaels@cvs.openbsd.org> | 1996-08-16 17:58:49 +0000 |
commit | 418c0bbade1dcb322b7abdbed4064993de8086c2 (patch) | |
tree | 4bad4d39a1f432f68cae3d673074f4b724aba879 /usr.bin/vi/ex | |
parent | 445816164da4c953591f89549fdd9bc8825aa8c8 (diff) |
nvi 1.73
Diffstat (limited to 'usr.bin/vi/ex')
-rw-r--r-- | usr.bin/vi/ex/ex.c | 61 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_args.c | 12 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_argv.c | 169 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_cmd.c | 4 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_cscope.c | 99 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_file.c | 4 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_init.c | 11 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_perl.c | 130 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_read.c | 4 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_shell.c | 10 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_source.c | 4 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_subst.c | 18 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_version.c | 4 | ||||
-rw-r--r-- | usr.bin/vi/ex/ex_write.c | 6 | ||||
-rw-r--r-- | usr.bin/vi/ex/version.h | 2 |
15 files changed, 307 insertions, 231 deletions
diff --git a/usr.bin/vi/ex/ex.c b/usr.bin/vi/ex/ex.c index f4a5bfb3a47..ca6872b332b 100644 --- a/usr.bin/vi/ex/ex.c +++ b/usr.bin/vi/ex/ex.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex.c 10.50 (Berkeley) 6/30/96"; +static const char sccsid[] = "@(#)ex.c 10.53 (Berkeley) 8/11/96"; #endif /* not lint */ #include <sys/types.h> @@ -617,15 +617,9 @@ skip_srch: if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI)) * :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. + * since "parser" implies some regularity of syntax) delimited the RE's + * based on its delimiter and not anything so irretrievably vulgar as a + * command syntax. * * Anyhow, the following code makes this all work. First, for the * special cases we move past their special argument(s). Then, we @@ -657,9 +651,8 @@ skip_srch: if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI)) * 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. + * first whitespace character that isn't escaped. The escaping + * characters are stripped as no longer useful. */ if (ecp->clen > 0 && *ecp->cp == '+') { ++ecp->cp; @@ -667,8 +660,8 @@ skip_srch: if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI)) for (arg1 = p = ecp->cp; ecp->clen > 0; --ecp->clen, ++ecp->cp) { ch = *ecp->cp; - if (IS_ESCAPE(sp, - ecp, ch) && ecp->clen > 1) { + if (IS_ESCAPE(sp, ecp, ch) && + ecp->clen > 1) { --ecp->clen; ch = *++ecp->cp; } else if (isblank(ch)) @@ -682,22 +675,30 @@ skip_srch: if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI)) } } else if (ecp->cmd == &cmds[C_BANG] || ecp->cmd == &cmds[C_GLOBAL] || ecp->cmd == &cmds[C_V]) { - ecp->cp += ecp->clen; - ecp->clen = 0; + for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) + if (ecp->cp[0] == '\n') + break; } else if (ecp->cmd == &cmds[C_READ] || ecp->cmd == &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 write commands, if the next character is a <blank>, and + * the next non-blank character is a '!', it's a filter command + * and we want to eat everything up to the <newline>. For read + * commands, if the next non-blank character is a '!', it's a + * filter command and we want to eat everything up to the next + * <newline>. Otherwise, we're done. */ - for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) { + for (tmp = 0; ecp->clen > 0; --ecp->clen, ++ecp->cp) { ch = *ecp->cp; - if (!isblank(ch)) + if (isblank(ch)) + tmp = 1; + else break; } - if (ecp->clen > 0 && ch == '!') { - ecp->cp += ecp->clen; - ecp->clen = 0; - } + if (ecp->clen > 0 && ch == '!' && + (ecp->cmd == &cmds[C_READ] || tmp)) + for (; ecp->clen > 0; --ecp->clen, ++ecp->cp) + if (ecp->cp[0] == '\n') + break; } else if (ecp->cmd == &cmds[C_SUBSTITUTE]) { /* * Move to the next non-whitespace character, we'll use it as @@ -812,7 +813,7 @@ skip_srch: if (ecp->cmd == &cmds[C_VISUAL_EX] && F_ISSET(sp, SC_VI)) * 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 + * (ex: z) care if the user specified an address or if we just used * the current cursor. */ switch (F_ISSET(ecp, E_ADDR1 | E_ADDR2 | E_ADDR2_ALL | E_ADDR2_NONE)) { @@ -1202,7 +1203,7 @@ usage: msgq(sp, M_ERR, "086|Usage: %s", ecp->cmd->usage); /* * Verify that the addresses are legal. Check the addresses here, * because this is a place where all ex addresses pass through. - * (They don't all pass through ep_line(), for instance.) We're + * (They don't all pass through ex_line(), for instance.) We're * assuming that any non-existent line doesn't exist because it's * past the end-of-file. That's a pretty good guess. * @@ -1408,9 +1409,9 @@ addr_verify: } /* - * If the command was successful may want to display a line based on - * the autoprint option or an explicit print flag. (Make sure that - * there's a line to display.) Also, the autoprint edit option is + * If the command executed successfully, we may want to display a line + * based on the autoprint option or an explicit print flag. (Make sure + * that there's a line to display.) Also, the autoprint edit option is * turned off for the duration of global commands. */ if (F_ISSET(sp, SC_EX) && sp->ep != NULL && sp->lno != 0) { diff --git a/usr.bin/vi/ex/ex_args.c b/usr.bin/vi/ex/ex_args.c index ba3e7801549..bc37109fc13 100644 --- a/usr.bin/vi/ex/ex_args.c +++ b/usr.bin/vi/ex/ex_args.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_args.c 10.14 (Berkeley) 4/27/96"; +static const char sccsid[] = "@(#)ex_args.c 10.16 (Berkeley) 7/13/96"; #endif /* not lint */ #include <sys/types.h> @@ -99,6 +99,9 @@ ex_next(sp, cmdp) if ((frp = file_add(sp, *sp->cargv)) == NULL) return (1); noargs = 0; + + /* Display a file count with the welcome message. */ + F_SET(sp, SC_STATUS_CNT); } else { if ((frp = file_add(sp, sp->cargv[1])) == NULL) return (1); @@ -149,6 +152,9 @@ ex_N_next(sp, cmdp) /* The arguments are a replacement file list. */ new->cargv = new->argv = ex_buildargv(sp, cmdp, NULL); + /* Display a file count with the welcome message. */ + F_SET(new, SC_STATUS_CNT); + /* Set up the switch. */ sp->nextdisp = new; F_SET(sp, SC_SSWITCH); @@ -237,7 +243,9 @@ ex_rew(sp, cmdp) (FL_ISSET(cmdp->iflags, E_C_FORCE) ? FS_FORCE : 0))) return (1); - F_SET(sp, SC_FSWITCH); + /* Switch and display a file count with the welcome message. */ + F_SET(sp, SC_FSWITCH | SC_STATUS_CNT); + return (0); } diff --git a/usr.bin/vi/ex/ex_argv.c b/usr.bin/vi/ex/ex_argv.c index f62b081eb40..e2cbfd61246 100644 --- a/usr.bin/vi/ex/ex_argv.c +++ b/usr.bin/vi/ex/ex_argv.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_argv.c 10.19 (Berkeley) 3/30/96"; +static const char sccsid[] = "@(#)ex_argv.c 10.23 (Berkeley) 8/11/96"; #endif /* not lint */ #include <sys/types.h> @@ -18,6 +18,7 @@ static const char sccsid[] = "@(#)ex_argv.c 10.19 (Berkeley) 3/30/96"; #include <bitstring.h> #include <ctype.h> +#include <dirent.h> #include <errno.h> #include <limits.h> #include <stdio.h> @@ -29,7 +30,9 @@ static const char sccsid[] = "@(#)ex_argv.c 10.19 (Berkeley) 3/30/96"; static int argv_alloc __P((SCR *, size_t)); static int argv_fexp __P((SCR *, EXCMD *, - char *, size_t, char *, size_t *, char **, size_t *, int)); + char *, size_t, char *, size_t *, char **, size_t *, int)); +static int argv_prefix __P((SCR *, + char *, char *, char **, size_t *, size_t *)); static int argv_sexp __P((SCR *, char **, size_t *, size_t *)); /* @@ -183,25 +186,58 @@ argv_exp2(sp, excp, cmd, cmdlen) for (p = mp = O_STR(sp, O_SHELLMETA); *p != '\0'; ++p) if (isblank(*p) || isalnum(*p)) break; + p = bp + SHELLOFFSET; + n = len - SHELLOFFSET; if (*p != '\0') { - for (p = bp, n = len; n > 0; --n, ++p) + for (; n > 0; --n, ++p) if (strchr(mp, *p) != NULL) break; } else - for (p = bp, n = len; n > 0; --n, ++p) + for (; n > 0; --n, ++p) if (!isblank(*p) && !isalnum(*p) && strchr(mp, *p) != NULL) break; } - if (n > 0) { + + /* + * If we found a meta character in the string, fork a shell to expand + * it. Unfortunately, this is comparatively slow. Historically, it + * didn't matter much, since users don't enter meta characters as part + * of pathnames that frequently. The addition of filename completion + * broke that assumption because it's easy to use. As a result, lots + * folks have complained that the expansion code is too slow. So, we + * detect filename completion as a special case, and do it internally. + * Note that this code assumes that the <asterisk> character is the + * match-anything meta character. That feels safe -- if anyone writes + * a shell that doesn't follow that convention, I'd suggest giving them + * a festive hot-lead enema. + */ + switch (n) { + case 0: + p = bp + SHELLOFFSET; + len -= SHELLOFFSET; + break; + case 1: + if (*p == '*') { + *p++ = '\0'; + n = p - bp; + if (argv_prefix(sp, + bp + SHELLOFFSET, p, &bp, &blen, &len)) { + rval = 1; + goto err; + } + p = bp + n; + len -= n; + break; + } + /* FALLTHROUGH */ + default: if (argv_sexp(sp, &bp, &blen, &len)) { rval = 1; goto err; } p = bp; - } else { - p = bp + SHELLOFFSET; - len -= SHELLOFFSET; + break; } #if defined(DEBUG) && 0 @@ -472,6 +508,116 @@ argv_free(sp) } /* + * argv_prefix -- + * Find all file names matching the prefix and append them to the + * buffer. + */ +static int +argv_prefix(sp, path, wp, bpp, blenp, lenp) + SCR *sp; + char *path, *wp, **bpp; + size_t *blenp, *lenp; +{ + DIR *dirp; + struct dirent *dp; + size_t blen, clen, dlen, doffset, len, nlen; + char *bp, *dname, *name, *p; + + /* + * Open the directory, set up the name and length for comparison, + * the prepended directory and length. + */ + if ((p = strrchr(path, '/')) == NULL) { + dlen = 0; + dname = "."; + name = path; + } else { + if (p == path) { + dname = "/"; + dlen = 0; + } else { + *p = '\0'; + dname = path; + dlen = strlen(path); + } + name = p + 1; + } + nlen = strlen(name); + + if ((dirp = opendir(dname)) == NULL) { + msgq_str(sp, M_SYSERR, dname, "%s"); + return (1); + } + + /* Local copies of the buffer variables. */ + bp = *bpp; + blen = *blenp; + + /* + * We're passed a pointer to the name (after the echo command at + * the start of the buffer) and a pointer to the place to start + * writing. Set a pointer to the start of the write area, and a + * value for the amount of space we have to write. + */ + p = wp; + len = wp - bp; + blen -= len; + + /* + * Read the directory, checking for files with a matching prefix. + * + * XXX + * We don't use the d_namlen field, it's not portable enough; we + * assume that d_name is nul terminated, instead. + */ + while ((dp = readdir(dirp)) != NULL) { + clen = strlen(dp->d_name); + if (nlen == 0 || + (clen >= nlen && !memcmp(dp->d_name, name, nlen))) { + if (blen < clen + dlen + 5) { + doffset = dname - bp; + ADD_SPACE_GOTO(sp, bp, *blenp, + *blenp * 2 + clen + dlen + 5); + p = bp + len; + blen = *blenp - len; + if (dname == path) + dname = bp + doffset; + } + if (dlen != 0) { + memcpy(p, dname, dlen); + p += dlen; + *p++ = '/'; + len += dlen + 1; + blen -= dlen + 1; + } + memcpy(p, dp->d_name, clen); + p += clen; + *p++ = ' '; + len += clen + 1; + blen -= clen + 1; + } + } + (void)closedir(dirp); + + /* + * If we didn't find a match, complain that the expansion failed. We + * can't know for certain that's the error, but it's a good guess, and + * it matches historic practice. + */ + if (p == wp) { + msgq(sp, M_ERR, "304|Shell expansion failed"); +alloc_err: return (1); + } + + /* Delete the final <space>, nul terminate the string. */ + *--p = '\0'; + *lenp = len - 1; + *bpp = bp; /* *blenp is already updated. */ + + return (0); +} + +/* * argv_sexp -- * Fork a shell, pipe a command through it, and read the output into * a buffer. @@ -502,6 +648,7 @@ argv_sexp(sp, bpp, blenp, lenp) else ++sh; + /* Local copies of the buffer variables. */ bp = *bpp; blen = *blenp; @@ -581,10 +728,10 @@ err: if (ifp != NULL) /* Delete the final newline, nul terminate the string. */ if (p > bp && (p[-1] == '\n' || p[-1] == '\r')) { + --p; --len; - *--p = '\0'; - } else - *p = '\0'; + } + *p = '\0'; *lenp = len; *bpp = bp; /* *blenp is already updated. */ diff --git a/usr.bin/vi/ex/ex_cmd.c b/usr.bin/vi/ex/ex_cmd.c index af8151117e6..88a1ea660c9 100644 --- a/usr.bin/vi/ex/ex_cmd.c +++ b/usr.bin/vi/ex/ex_cmd.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_cmd.c 10.18 (Berkeley) 6/29/96"; +static const char sccsid[] = "@(#)ex_cmd.c 10.19 (Berkeley) 7/12/96"; #endif /* not lint */ #include <sys/types.h> @@ -256,7 +256,7 @@ EXCMDLIST const cmds[] = { "pe[rl] cmd", "run the perl interpreter with the command"}, /* C_PERLDOCMD */ - {"perldo", ex_perldo, E_ADDR2_ALL|E_ADDR_ZERO| + {"perldo", ex_perl, E_ADDR2_ALL|E_ADDR_ZERO| E_ADDR_ZERODEF|E_SECURE, "s", "perld[o] cmd", diff --git a/usr.bin/vi/ex/ex_cscope.c b/usr.bin/vi/ex/ex_cscope.c index c5fca718cb8..2676e104ac6 100644 --- a/usr.bin/vi/ex/ex_cscope.c +++ b/usr.bin/vi/ex/ex_cscope.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_cscope.c 10.8 (Berkeley) 6/30/96"; +static const char sccsid[] = "@(#)ex_cscope.c 10.12 (Berkeley) 8/11/96"; #endif /* not lint */ #include <sys/param.h> @@ -34,6 +34,7 @@ static const char sccsid[] = "@(#)ex_cscope.c 10.8 (Berkeley) 6/30/96"; #include <unistd.h> #include "../common/common.h" +#include "pathnames.h" #include "tag.h" #define CSCOPE_DBFILE "cscope.out" @@ -77,7 +78,7 @@ typedef struct _cc { static CC const cscope_cmds[] = { { "add", cscope_add, - "Add a new cscope database", "add db-name" }, + "Add a new cscope database", "add file | directory" }, { "find", cscope_find, "Query the databases for a pattern", FINDHELP }, { "help", cscope_help, @@ -97,7 +98,7 @@ static int get_paths __P((SCR *, CSC *)); static CC const *lookup_ccmd __P((char *)); static int parse __P((SCR *, CSC *, TAGQ *, int *)); static int read_prompt __P((SCR *, CSC *)); -static int run_cscope __P((SCR *, CSC *)); +static int run_cscope __P((SCR *, CSC *, char *)); static int start_cscopes __P((SCR *, EXCMD *)); static int terminate __P((SCR *, CSC *, int)); @@ -158,7 +159,7 @@ start_cscopes(sp, cmdp) EXCMD *cmdp; { size_t blen, len; - char *bp, *cscopes, *p; + char *bp, *cscopes, *p, *t; /* * EXTENSION #1: @@ -178,9 +179,11 @@ start_cscopes(sp, cmdp) GET_SPACE_RET(sp, bp, blen, len); memcpy(bp, cscopes, len + 1); - for (cscopes = bp; (p = strsep(&bp, "\t ")) != NULL;) + for (cscopes = t = bp; (p = strsep(&t, "\t :")) != NULL;) if (*p != '\0') (void)cscope_add(sp, cmdp, p); + + FREE_SPACE(sp, bp, blen); return (0); } @@ -198,43 +201,51 @@ cscope_add(sp, cmdp, dname) EX_PRIVATE *exp; CSC *csc; size_t len; - char path[MAXPATHLEN]; + int cur_argc; + char *dbname, path[MAXPATHLEN]; exp = EXP(sp); - if (argv_exp2(sp, cmdp, dname, strlen(dname))) - return (1); /* - * 0 args: impossible. - * 1 args: usage. - * 2 args: matched a directory. - * >2 args: object, too many args. - * - * The 1 args case depends on the argv_sexp() function refusing - * to return success without at least one non-blank character. + * 0 additional args: usage. + * 1 additional args: matched a file. + * >1 additional args: object, too many args. */ - switch (cmdp->argc) { - case 0: - abort(); - /* NOTREACHED */ - case 1: + cur_argc = cmdp->argc; + if (argv_exp2(sp, cmdp, dname, strlen(dname))) + return (1); + if (cmdp->argc == cur_argc) { (void)csc_help(sp, "add"); return (1); - case 2: - dname = cmdp->argv[1]->bp; - break; - default: + } + if (cmdp->argc == cur_argc + 1) + dname = cmdp->argv[cur_argc]->bp; + else { ex_emsg(sp, dname, EXM_FILECOUNT); return (1); } - /* If the database file doesn't exist, we're done. */ - (void)snprintf(path, sizeof(path), - "%s/%s", cmdp->argv[1]->bp, CSCOPE_DBFILE); - if (stat(path, &sb)) { - msgq(sp, M_SYSERR, path); + /* + * The user can specify a specific file (so they can have multiple + * Cscope databases in a single directory) or a directory. If the + * file doesn't exist, we're done. If it's a directory, append the + * standard database file name and try again. Store the directory + * name regardless so that we can use it as a base for searches. + */ + if (stat(dname, &sb)) { + msgq(sp, M_SYSERR, dname); return (1); } + if (S_ISDIR(sb.st_mode)) { + (void)snprintf(path, sizeof(path), + "%s/%s", dname, CSCOPE_DBFILE); + if (stat(path, &sb)) { + msgq(sp, M_SYSERR, path); + return (1); + } + dbname = CSCOPE_DBFILE; + } else if ((dbname = strrchr(dname, '/')) != NULL) + *dbname++ = '\0'; /* Allocate a cscope connection structure and initialize its fields. */ len = strlen(dname); @@ -249,7 +260,7 @@ cscope_add(sp, cmdp, dname) goto err; /* Start the cscope process. */ - if (run_cscope(sp, csc)) + if (run_cscope(sp, csc, dbname)) goto err; /* @@ -352,9 +363,10 @@ alloc_err: * Fork off the cscope process. */ static int -run_cscope(sp, csc) +run_cscope(sp, csc, dbname) SCR *sp; CSC *csc; + char *dbname; { int to_cs[2], from_cs[2]; char cmd[MAXPATHLEN * 2]; @@ -390,9 +402,10 @@ err: if (to_cs[0] != -1) (void)close(from_cs[0]); /* Run the cscope command. */ -#define CSCOPE_CMD_FMT "cd '%s' && exec cscope -dl" - (void)snprintf(cmd, sizeof(cmd), CSCOPE_CMD_FMT, csc->dname); - (void)execl("/bin/sh", "sh", "-c", cmd, NULL); +#define CSCOPE_CMD_FMT "cd '%s' && exec cscope -dl -f %s" + (void)snprintf(cmd, sizeof(cmd), + CSCOPE_CMD_FMT, csc->dname, dbname); + (void)execl(_PATH_BSHELL, "sh", "-c", cmd, NULL); msgq_str(sp, M_SYSERR, cmd, "execl: %s"); _exit (127); /* NOTREACHED */ @@ -648,7 +661,7 @@ parse(sp, csc, tqp, matchesp) TAG *tp; recno_t slno; size_t dlen, nlen, slen; - int ch, i, isnewer, nlines; + int ch, i, isolder, nlines; char *dname, *name, *search, *p, *t, dummy[2], buf[2048]; for (;;) { @@ -709,14 +722,14 @@ parse(sp, csc, tqp, matchesp) slen = strlen(p); /* Resolve the file name. */ - csc_file(sp, csc, name, &dname, &dlen, &isnewer); + csc_file(sp, csc, name, &dname, &dlen, &isolder); /* - * If the file was modified more recently than the cscope - * database, or there wasn't a search string, use the line - * number. + * If the file is older than the cscope database, that is, + * the database was built since the file was last modified, + * or there wasn't a search string, use the line number. */ - if (isnewer || strcmp(search, "<unknown>") == 0) { + if (isolder || strcmp(search, "<unknown>") == 0) { search = NULL; slen = 0; } @@ -760,12 +773,12 @@ io_err: if (feof(csc->from_fp)) * Search for the right path to this file. */ static void -csc_file(sp, csc, name, dirp, dlenp, isnewerp) +csc_file(sp, csc, name, dirp, dlenp, isolderp) SCR *sp; CSC *csc; char *name, **dirp; size_t *dlenp; - int *isnewerp; + int *isolderp; { struct stat sb; char **pp, buf[MAXPATHLEN]; @@ -782,7 +795,7 @@ csc_file(sp, csc, name, dirp, dlenp, isnewerp) if (stat(buf, &sb) == 0) { *dirp = *pp; *dlenp = strlen(*pp); - *isnewerp = sb.st_mtime > csc->mtime; + *isolderp = sb.st_mtime < csc->mtime; return; } } diff --git a/usr.bin/vi/ex/ex_file.c b/usr.bin/vi/ex/ex_file.c index 503f11bd1d4..3492f9c7bf0 100644 --- a/usr.bin/vi/ex/ex_file.c +++ b/usr.bin/vi/ex/ex_file.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_file.c 10.11 (Berkeley) 5/2/96"; +static const char sccsid[] = "@(#)ex_file.c 10.12 (Berkeley) 7/12/96"; #endif /* not lint */ #include <sys/types.h> @@ -70,7 +70,7 @@ ex_file(sp, cmdp) F_SET(frp, FR_NAMECHANGE); /* Notify the screen. */ - (void)sp->gp->scr_rename(sp); + (void)sp->gp->scr_rename(sp, sp->frp->name, 1); break; default: abort(); diff --git a/usr.bin/vi/ex/ex_init.c b/usr.bin/vi/ex/ex_init.c index 4aeffc26831..31bcb2a176f 100644 --- a/usr.bin/vi/ex/ex_init.c +++ b/usr.bin/vi/ex/ex_init.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_init.c 10.24 (Berkeley) 6/30/96"; +static const char sccsid[] = "@(#)ex_init.c 10.25 (Berkeley) 7/10/96"; #endif /* not lint */ #include <sys/param.h> @@ -186,6 +186,12 @@ ex_exrc(sp) break; } + /* Run the commands. */ + if (EXCMD_RUNNING(sp->gp)) + (void)ex_cmd(sp); + if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) + return (0); + if ((p = getenv("NEXINIT")) != NULL) { if (ex_run_str(sp, "NEXINIT", p, strlen(p), 1, 0)) return (1); @@ -211,12 +217,13 @@ ex_exrc(sp) } } - /* Run the commands, they may set the exrc edit option. */ + /* Run the commands. */ if (EXCMD_RUNNING(sp->gp)) (void)ex_cmd(sp); if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) return (0); + /* Previous commands may have set the exrc option. */ if (O_ISSET(sp, O_EXRC)) { switch (exrc_isok(sp, &lsb, _PATH_NEXRC, 0, 0)) { case NOEXIST: diff --git a/usr.bin/vi/ex/ex_perl.c b/usr.bin/vi/ex/ex_perl.c index bdafcac4d59..501bb53f6fc 100644 --- a/usr.bin/vi/ex/ex_perl.c +++ b/usr.bin/vi/ex/ex_perl.c @@ -14,7 +14,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_perl.c 8.6 (Berkeley) 3/18/96"; +static const char sccsid[] = "@(#)ex_perl.c 8.9 (Berkeley) 7/19/96"; #endif /* not lint */ #include <sys/types.h> @@ -32,106 +32,23 @@ static const char sccsid[] = "@(#)ex_perl.c 8.6 (Berkeley) 3/18/96"; #include "../common/common.h" -#ifdef HAVE_PERL_INTERP -#include <EXTERN.h> -#include <perl.h> -#include <XSUB.h> - -static int perl_eval(string) - char *string; -{ - char *argv[2]; - - argv[0] = string; - argv[1] = NULL; - perl_call_argv("_eval_", G_EVAL | G_DISCARD | G_KEEPERR, argv); -} -#else - -static void -noperl(scrp) - SCR *scrp; -{ - msgq(scrp, M_ERR, "306|Vi was not loaded with a Perl interpreter"); -} -#endif - /* * ex_perl -- :[line [,line]] perl [command] * Run a command through the perl interpreter. * - * PUBLIC: int ex_perl __P((SCR*, EXCMD *)); - */ -int -ex_perl(scrp, cmdp) - SCR *scrp; - EXCMD *cmdp; -{ -#ifdef HAVE_PERL_INTERP - CHAR_T *p; - GS *gp; - STRLEN length; - size_t len; - char *err, buf[64]; - - /* Initialize the interpreter. */ - gp = scrp->gp; - if (gp->perl_interp == NULL && perl_init(gp)) - return (1); - - /* Skip leading white space. */ - if (cmdp->argc != 0) - for (p = cmdp->argv[0]->bp, - len = cmdp->argv[0]->len; len > 0; --len, ++p) - if (!isblank(*p)) - break; - if (cmdp->argc == 0 || len == 0) { - ex_emsg(scrp, cmdp->cmd->usage, EXM_USAGE); - return (1); - } - - (void)snprintf(buf, sizeof(buf), - "$VI::ScreenId=%d;$VI::StartLine=%lu;$VI::StopLine=%lu", - scrp->id, cmdp->addr1.lno, cmdp->addr2.lno); - perl_eval(buf); - perl_eval(cmdp->argv[0]->bp); - err = SvPV(GvSV(errgv),length); - if (!length) - return (0); - - err[length - 1] = '\0'; - msgq(scrp, M_ERR, "perl: %s", err); - return (1); -#else - noperl(scrp); - return (1); -#endif /* HAVE_PERL_INTERP */ -} - -/* - * ex_perldo -- :[line [,line]] perl [command] + * ex_perldo -- :[line [,line]] perldo [command] * Run a set of lines through the perl interpreter. * - * PUBLIC: int ex_perldo __P((SCR*, EXCMD *)); + * PUBLIC: int ex_perl __P((SCR*, EXCMD *)); */ int -ex_perldo(scrp, cmdp) - SCR *scrp; +ex_perl(sp, cmdp) + SCR *sp; EXCMD *cmdp; { #ifdef HAVE_PERL_INTERP CHAR_T *p; - GS *gp; - STRLEN length; size_t len; - int i; - char *str, *argv[2]; - dSP; - - /* Initialize the interpreter. */ - gp = scrp->gp; - if (gp->perl_interp == NULL && perl_init(gp)) - return (1); /* Skip leading white space. */ if (cmdp->argc != 0) @@ -140,39 +57,14 @@ ex_perldo(scrp, cmdp) if (!isblank(*p)) break; if (cmdp->argc == 0 || len == 0) { - ex_emsg(scrp, cmdp->cmd->usage, EXM_USAGE); + ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE); return (1); } - - argv[0] = cmdp->argv[0]->bp; - argv[1] = NULL; - - ENTER; - SAVETMPS; - for (i = cmdp->addr1.lno; i <= cmdp->addr2.lno; i++) { - /*api_gline(scrp, i, argv+1, &len);*/ - api_gline(scrp, i, &str, &len); - sv_setpvn(perl_get_sv("_", FALSE),str,len); - perl_call_argv("_eval_", G_SCALAR | G_EVAL | G_KEEPERR, argv); - str = SvPV(GvSV(errgv),length); - if (length) break; - SPAGAIN; - if(SvTRUEx(POPs)) { - str = SvPV(perl_get_sv("_", FALSE),len); - api_sline(scrp, i, str, len); - } - PUTBACK; - } - FREETMPS; - LEAVE; - if (!length) - return (0); - - str[length - 1] = '\0'; - msgq(scrp, M_ERR, "perl: %s", str); - return (1); + return (cmdp->cmd == &cmds[C_PERLCMD] ? + perl_ex_perl(sp, p, len, cmdp->addr1.lno, cmdp->addr2.lno) : + perl_ex_perldo(sp, p, len, cmdp->addr1.lno, cmdp->addr2.lno)); #else - noperl(scrp); + msgq(sp, M_ERR, "306|Vi was not loaded with a Perl interpreter"); return (1); -#endif /* HAVE_PERL_INTERP */ +#endif } diff --git a/usr.bin/vi/ex/ex_read.c b/usr.bin/vi/ex/ex_read.c index 7d4e43f63c8..6e6afa8ebcf 100644 --- a/usr.bin/vi/ex/ex_read.c +++ b/usr.bin/vi/ex/ex_read.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_read.c 10.36 (Berkeley) 6/28/96"; +static const char sccsid[] = "@(#)ex_read.c 10.37 (Berkeley) 7/12/96"; #endif /* not lint */ #include <sys/types.h> @@ -229,7 +229,7 @@ ex_read(sp, cmdp) F_SET(sp->frp, FR_NAMECHANGE | FR_EXNAMED); /* Notify the screen. */ - (void)gp->scr_rename(sp); + (void)sp->gp->scr_rename(sp, sp->frp->name, 1); } else set_alt_name(sp, name); break; diff --git a/usr.bin/vi/ex/ex_shell.c b/usr.bin/vi/ex/ex_shell.c index 070d6d54706..5848baee0b3 100644 --- a/usr.bin/vi/ex/ex_shell.c +++ b/usr.bin/vi/ex/ex_shell.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_shell.c 10.35 (Berkeley) 6/28/96"; +static const char sccsid[] = "@(#)ex_shell.c 10.37 (Berkeley) 8/11/96"; #endif /* not lint */ #include <sys/param.h> @@ -55,9 +55,15 @@ ex_shell(sp, cmdp) */ (void)snprintf(buf, sizeof(buf), "%s -i", O_STR(sp, O_SHELL)); - /* If we're stil in a vi screen, move out explicitly. */ + /* Restore the window name. */ + (void)cl_rename(sp, NULL, 0); + + /* If we're still in a vi screen, move out explicitly. */ rval = ex_exec_proc(sp, cmdp, buf, NULL, !F_ISSET(sp, SC_SCR_EXWROTE)); + /* Set the window name. */ + (void)cl_rename(sp, sp->frp->name, 1); + /* * !!! * Historically, vi didn't require a continue message after the diff --git a/usr.bin/vi/ex/ex_source.c b/usr.bin/vi/ex/ex_source.c index 468fd79ee2c..b52c527716f 100644 --- a/usr.bin/vi/ex/ex_source.c +++ b/usr.bin/vi/ex/ex_source.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_source.c 10.11 (Berkeley) 6/30/96"; +static const char sccsid[] = "@(#)ex_source.c 10.12 (Berkeley) 8/10/96"; #endif /* not lint */ #include <sys/types.h> @@ -62,7 +62,7 @@ ex_source(sp, cmdp) goto err; } - MALLOC(sp, bp, char *, (size_t)sb.st_size); + MALLOC(sp, bp, char *, (size_t)sb.st_size + 1); if (bp == NULL) { (void)close(fd); return (1); diff --git a/usr.bin/vi/ex/ex_subst.c b/usr.bin/vi/ex/ex_subst.c index c935d92c248..52fef271698 100644 --- a/usr.bin/vi/ex/ex_subst.c +++ b/usr.bin/vi/ex/ex_subst.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_subst.c 10.32 (Berkeley) 6/30/96"; +static const char sccsid[] = "@(#)ex_subst.c 10.35 (Berkeley) 8/11/96"; #endif /* not lint */ #include <sys/types.h> @@ -91,7 +91,7 @@ subagain: return (ex_subagain(sp, cmdp)); sp->c_suffix = sp->g_suffix = 0; /* - * Get the pattern string, toss escaped characters. + * Get the pattern string, toss escaping characters. * * !!! * Historic vi accepted any of the following forms: @@ -103,10 +103,10 @@ subagain: return (ex_subagain(sp, cmdp)); * * QUOTING NOTE: * - * Only toss an escape character if it escapes a delimiter. + * Only toss an escaping 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 + * escaping a single escaping character is removed, but that's * not how the historic vi worked. */ for (ptrn = t = p;;) { @@ -179,7 +179,7 @@ subagain: return (ex_subagain(sp, cmdp)); * * QUOTING NOTE: * - * Only toss an escape character if it escapes a delimiter or + * Only toss an escaping character if it escapes a delimiter or * if O_MAGIC is set and it escapes a tilde. * * !!! @@ -1208,8 +1208,10 @@ re_tag_conv(sp, ptrnp, plenp, replacedp) } /* If the first or second character is a '^', it's magic. */ - if (p[0] == '^') + if (p[0] == '^') { *t++ = *p++; + --len; + } /* * Escape every other magic character we can find, meanwhile stripping @@ -1278,7 +1280,7 @@ re_cscope_conv(sp, ptrnp, plenp, replacedp) memcpy(t, CSCOPE_RE_SPACE, sizeof(CSCOPE_RE_SPACE) - 1); t += sizeof(CSCOPE_RE_SPACE) - 1; } else { - if (strchr("\\^.[]$*", *p)) + if (strchr("\\^.[]$*+?()|{}", *p)) *t++ = '\\'; *t++ = *p; } @@ -1358,7 +1360,7 @@ re_sub(sp, ip, lbp, lbclenp, lblenp, match) * \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. + * all escaping characters. This (hopefully) matches historic practice. */ #define OUTCH(ch, nltrans) { \ CHAR_T __ch = (ch); \ diff --git a/usr.bin/vi/ex/ex_version.c b/usr.bin/vi/ex/ex_version.c index bc92b680c64..5e279bdaca0 100644 --- a/usr.bin/vi/ex/ex_version.c +++ b/usr.bin/vi/ex/ex_version.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_version.c 10.27 (Berkeley) 6/9/96"; +static const char sccsid[] = "@(#)ex_version.c 10.28 (Berkeley) 7/14/96"; #endif /* not lint */ #include <sys/types.h> @@ -36,7 +36,7 @@ business and technical computing environments, the worldwide customer \ acceptance of BSD-based technology, the know-how of BSDI's leading \ computer scientists, and BSDI's focus on delivering and supporting \ industrial-strength software for computing platforms. BSDI may be \ -contacted at info@bsdi.com or 1-800-800-4273." +contacted at http://www.bsdi.com/, info@bsdi.com or 1-800-800-4273." /* * ex_version -- :version diff --git a/usr.bin/vi/ex/ex_write.c b/usr.bin/vi/ex/ex_write.c index 5ab94480229..b3122e35356 100644 --- a/usr.bin/vi/ex/ex_write.c +++ b/usr.bin/vi/ex/ex_write.c @@ -10,7 +10,7 @@ #include "config.h" #ifndef lint -static const char sccsid[] = "@(#)ex_write.c 10.28 (Berkeley) 6/28/96"; +static const char sccsid[] = "@(#)ex_write.c 10.30 (Berkeley) 7/12/96"; #endif /* not lint */ #include <sys/types.h> @@ -193,7 +193,7 @@ exwr(sp, cmdp, cmd) } /* Set the FS_ALL flag if we're writing the entire file. */ - if (cmdp->addr1.lno == 1 && !db_exist(sp, cmdp->addr2.lno + 1)) + if (cmdp->addr1.lno <= 1 && !db_exist(sp, cmdp->addr2.lno + 1)) LF_SET(FS_ALL); /* If "write >>" it's an append to a file. */ @@ -256,7 +256,7 @@ exwr(sp, cmdp, cmd) F_SET(sp->frp, FR_NAMECHANGE | FR_EXNAMED); /* Notify the screen. */ - (void)sp->gp->scr_rename(sp); + (void)sp->gp->scr_rename(sp, sp->frp->name, 1); } else set_alt_name(sp, name); break; diff --git a/usr.bin/vi/ex/version.h b/usr.bin/vi/ex/version.h index 96884b40dbb..9586ba7942a 100644 --- a/usr.bin/vi/ex/version.h +++ b/usr.bin/vi/ex/version.h @@ -1,2 +1,2 @@ #define VI_VERSION \ - "Version 1.71 (7/1/96) The CSRG, University of California, Berkeley." + "Version 1.73 (8/12/96) The CSRG, University of California, Berkeley." |