aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2023-09-26 07:08:15 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2023-09-26 07:08:15 +0000
commit16c0a3151e5fa4958711f64bbc2f172cfe781743 (patch)
treec5d9c0587848d7f5e5393f8d5c70e22763b619b8
parent8e6e1224184eb6cd3dfa05b2ecd9515c59f4f425 (diff)
downloadsrc-vendor/nvi.tar.gz
src-vendor/nvi.zip
nvi: import version 2.2.1vendor/nvi/2.2.1vendor/nvi
-rw-r--r--CMakeLists.txt4
-rw-r--r--INSTALL.md47
-rw-r--r--README26
-rw-r--r--common/key.c95
-rw-r--r--common/main.c3
-rw-r--r--common/options.c2
-rw-r--r--common/options_f.c2
-rw-r--r--common/search.c11
-rw-r--r--ex/ex.c13
-rw-r--r--ex/ex_argv.c6
-rw-r--r--ex/ex_subst.c7
-rw-r--r--man/vi.14
-rw-r--r--regex/regex.h10
-rw-r--r--vi/v_paragraph.c11
-rw-r--r--vi/v_redraw.c1
15 files changed, 222 insertions, 20 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 66d3ca2aafb0..0c935b3c2a19 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -37,6 +37,7 @@ if (NOT APPLE)
endif()
add_compile_options($<$<CONFIG:Release>:-Wuninitialized>)
add_compile_options($<$<CONFIG:Release>:-Wno-dangling-else>)
+add_compile_options(-Wno-string-compare)
add_compile_options(-Wstack-protector -fstack-protector)
add_compile_options(-Wstrict-aliasing -fstrict-aliasing)
@@ -148,6 +149,9 @@ if(USE_WIDECHAR)
target_sources(regex PRIVATE ${REGEX_SRCS})
target_include_directories(regex PUBLIC regex)
target_compile_definitions(regex PUBLIC __REGEX_PRIVATE)
+ # The macro _XOPEN_SOURCE_EXTENDED is needed to get the waddnwstr()
+ # definition on at least FreeBSD and recent macOS.
+ target_compile_definitions(nvi PRIVATE _XOPEN_SOURCE_EXTENDED)
target_link_libraries(nvi PRIVATE regex)
else()
find_library(CURSES_LIBRARY NAMES ncurses curses HINTS /usr/lib)
diff --git a/INSTALL.md b/INSTALL.md
new file mode 100644
index 000000000000..7b2fd35b7c60
--- /dev/null
+++ b/INSTALL.md
@@ -0,0 +1,47 @@
+# Install from source
+
+For instructions to bring nvi2 as a part of your operating system's base system, see [Porting](https://github.com/lichray/nvi2/wiki/Porting) in the Wiki. This document is an overview of the build process that allows you to give nvi2 a try.
+
+## Prerequisites
+
+- CMake >= 3.17;
+- Ninja build system;
+- libiconv (for `USE_ICONV`);
+- libncursesw (for `USE_WIDECHAR`);
+
+Anything required by a minimal nvi, notably:
+
+- Berkeley DB1 in libc;
+- /var/tmp/vi.recover/ with mode 41777.
+
+## Building
+
+Nvi2 uses CMake build system generator. By specifying "Ninja Multi-Config" as the build system to generate, you can compile the project in both Debug and Release modes without re-running CMake. Under the project root directory, run
+
+```sh
+cmake -G "Ninja Multi-Config" -B build
+```
+
+Now `build` becomes your build directory to hold the artifacts. To build nvi2 in Debug mode, run
+
+```sh
+ninja -C build
+```
+
+Upon finishing, the nvi2 executable will be available as `build/Debug/nvi`. To launch it in `ex` mode, you can create a symlink
+
+```sh
+ln -s nvi build/Debug/ex
+```
+
+and run `./build/Debug/ex` rather than `./build/Debug/nvi`.
+
+To build nvi2 in Release mode, use the following command instead:
+
+```sh
+ninja -C build -f build-Release.ninja
+```
+
+Upon finishing, you will be able to edit files with `./build/Release/nvi`.
+
+To change configure-time options, such as disabling wide character support, use `ccmake build`.
diff --git a/README b/README
index 8f61a97144be..9e638d952444 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-This is version 2.2.0 (2020-08-01) of nex/nvi, a reimplementation of the ex/vi
+This is version 2.2.1 (2023-09-25) of nex/nvi, a reimplementation of the ex/vi
text editors originally distributed as part of the Fourth Berkeley
Software Distribution (4BSD), by the University of California, Berkeley.
@@ -24,6 +24,30 @@ o Nvi was written by Keith Bostic, and the last version is 1.79. After that,
Jun-ichiro itojun Hagino developed the file encoding detection
techniques in his nvi-m17n.
+o In nvi2, Zhihao Yuan incorporated the multibyte encoding support onto DB1.
+
+ It was not possible without great support from Alexander Leidinger,
+ Peter Wemm, and the FreeBSD community.
+
+ Last but not least, money from Google Summer of Code.
+
+o Since then,
+
+ Todd C. Miller and Craig Leres adopted and refined the NetBSD-style
+ expandtab option.
+
+ Yamamoto Takashi, Matija Skala, and Jessica Clarke ported the
+ software to macOS and Linux.
+
+ Anthony J. Bentley made heroic efforts to modernize the code base
+ and documentation, leveraging experience from OpenBSD to improve the
+ quality of the project.
+
+ ...and many others, including Michael McConville, Marc Simpson,
+ Jeffrey H. Johnson, Bosco GarcĂ­a, Anton Konyahin, Walter Alejandro
+ Iglesias, and those who tried hard to keep anonymous on GitHub :)
+ Their insights render the software usable, secure, and sustainable.
+
The following acknowledgments were written by Keith Bostic:
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
diff --git a/common/key.c b/common/key.c
index e71396893fd4..1ccfb61ee0a1 100644
--- a/common/key.c
+++ b/common/key.c
@@ -31,6 +31,7 @@ static int v_event_grow(SCR *, int);
static int v_key_cmp(const void *, const void *);
static void v_keyval(SCR *, int, scr_keyval_t);
static void v_sync(SCR *, int);
+static const char *alt_key_notation(int ch);
/*
* !!!
@@ -252,6 +253,10 @@ v_key_name(SCR *sp, ARG_CHAR_T ach)
* followed by the character offset from the '@' character in the ASCII
* character set. Del (0x7f) is represented as '^' followed by '?'.
*
+ * If set O_ALTNOTATION, control characters less than 0x20 are
+ * represented in <C-char> notations. Carriage feed, escape, and
+ * delete are marked as <Enter>, <Esc>, and <Del>, respectively.
+ *
* XXX
* The following code depends on the current locale being identical to
* the ASCII map from 0x40 to 0x5f (since 0x1f + 0x40 == 0x5f). I'm
@@ -264,9 +269,14 @@ v_key_name(SCR *sp, ARG_CHAR_T ach)
if (CAN_PRINT(sp, ach))
goto done;
nopr: if (iscntrl(ch) && (ch < 0x20 || ch == 0x7f)) {
- sp->cname[0] = '^';
- sp->cname[1] = ch == 0x7f ? '?' : '@' + ch;
- len = 2;
+ if (O_ISSET(sp, O_ALTNOTATION)) {
+ const char *notation = alt_key_notation(ch);
+ len = strlcpy(sp->cname, notation, sizeof(sp->cname));
+ } else {
+ sp->cname[0] = '^';
+ sp->cname[1] = ch == 0x7f ? '?' : '@' + ch;
+ len = 2;
+ }
goto done;
}
#ifdef USE_WIDECHAR
@@ -746,6 +756,85 @@ v_sync(SCR *sp, int flags)
}
/*
+ * alt_key_notation --
+ * Lookup for alternative notations of control characters.
+ */
+static const char*
+alt_key_notation(int ch)
+{
+ switch (ch) {
+ case 0x00:
+ return "<C-@>";
+ case 0x01:
+ return "<C-a>";
+ case 0x02:
+ return "<C-b>";
+ case 0x03:
+ return "<C-c>";
+ case 0x04:
+ return "<C-d>";
+ case 0x05:
+ return "<C-e>";
+ case 0x06:
+ return "<C-f>";
+ case 0x07:
+ return "<C-g>";
+ case 0x08:
+ return "<C-h>";
+ case 0x09:
+ return "<Tab>";
+ case 0x0A:
+ return "<NL>";
+ case 0x0B:
+ return "<C-k>";
+ case 0x0C:
+ return "<C-l>";
+ case 0x0D:
+ return "<Enter>";
+ case 0x0E:
+ return "<C-n>";
+ case 0x0F:
+ return "<C-o>";
+ case 0x10:
+ return "<C-p>";
+ case 0x11:
+ return "<C-q>";
+ case 0x12:
+ return "<C-r>";
+ case 0x13:
+ return "<C-s>";
+ case 0x14:
+ return "<C-t>";
+ case 0x15:
+ return "<C-u>";
+ case 0x16:
+ return "<C-v>";
+ case 0x17:
+ return "<C-w>";
+ case 0x18:
+ return "<C-x>";
+ case 0x19:
+ return "<C-y>";
+ case 0x1A:
+ return "<C-z>";
+ case 0x1B:
+ return "<Esc>";
+ case 0x1C:
+ return "<C-\\>";
+ case 0x1D:
+ return "<C-]>";
+ case 0x1E:
+ return "<C-^>";
+ case 0x1F:
+ return "<C-_>";
+ case 0x7f:
+ return "<Del>";
+ default:
+ __builtin_unreachable();
+ }
+}
+
+/*
* v_event_err --
* Unexpected event.
*
diff --git a/common/main.c b/common/main.c
index a7e60f1af806..807dbde3895c 100644
--- a/common/main.c
+++ b/common/main.c
@@ -419,8 +419,7 @@ err: rval = 1;
* PUBLIC: void v_end(GS *);
*/
void
-v_end(gp)
- GS *gp;
+v_end(GS *gp)
{
MSGS *mp;
SCR *sp;
diff --git a/common/options.c b/common/options.c
index d5c039f97228..c3d1f7343f9a 100644
--- a/common/options.c
+++ b/common/options.c
@@ -46,6 +46,8 @@ static int opts_print(SCR *, OPTLIST const *);
* VI and EX Text Editors", 1990.
*/
OPTLIST const optlist[] = {
+/* O_ALTNOTATION */
+ {L("altnotation"), f_print, OPT_0BOOL, 0},
/* O_ALTWERASE 4.4BSD */
{L("altwerase"), f_altwerase, OPT_0BOOL, 0},
/* O_AUTOINDENT 4BSD */
diff --git a/common/options_f.c b/common/options_f.c
index 45ab913c55ab..fe07e4989f05 100644
--- a/common/options_f.c
+++ b/common/options_f.c
@@ -147,7 +147,7 @@ f_print(SCR *sp, OPTION *op, char *str, u_long *valp)
int offset = op - sp->opts;
/* Preset the value, needed for reinitialization of lookup table. */
- if (offset == O_OCTAL) {
+ if (offset == O_OCTAL || offset == O_ALTNOTATION) {
if (*valp)
O_SET(sp, offset);
else
diff --git a/common/search.c b/common/search.c
index e8dcac431f51..c3f7291437ff 100644
--- a/common/search.c
+++ b/common/search.c
@@ -103,9 +103,14 @@ prev: if (sp->re == NULL) {
++p;
break;
}
- if (plen > 1 && p[0] == '\\' && p[1] == delim) {
- ++p;
- --plen;
+ if (plen > 1 && p[0] == '\\') {
+ if (p[1] == delim) {
+ ++p;
+ --plen;
+ } else if ( p[1] == '\\') {
+ *t++ = *p++;
+ --plen;
+ }
}
}
if (epp != NULL)
diff --git a/ex/ex.c b/ex/ex.c
index fd920a8df9a1..900678e942eb 100644
--- a/ex/ex.c
+++ b/ex/ex.c
@@ -154,6 +154,10 @@ ex(SCR **spp)
if (file_end(sp, NULL, F_ISSET(sp, SC_EXIT_FORCE)))
return (1);
*spp = screen_next(sp);
+ if (*spp) {
+ F_CLR(*spp, SC_SCR_VI);
+ F_SET(*spp, SC_SCR_EX);
+ }
return (screen_end(sp));
}
}
@@ -1463,8 +1467,13 @@ addr_verify:
LF_INIT(FL_ISSET(ecp->iflags, E_C_HASH | E_C_LIST | E_C_PRINT));
if (!LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT | E_NOAUTO) &&
!F_ISSET(sp, SC_EX_GLOBAL) &&
- O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT))
- LF_INIT(E_C_PRINT);
+ O_ISSET(sp, O_AUTOPRINT) && F_ISSET(ecp, E_AUTOPRINT)) {
+ /* Honor the number option if autoprint is set. */
+ if (F_ISSET(ecp, E_OPTNUM))
+ LF_INIT(E_C_HASH);
+ else
+ LF_INIT(E_C_PRINT);
+ }
if (LF_ISSET(E_C_HASH | E_C_LIST | E_C_PRINT)) {
cur.lno = sp->lno;
diff --git a/ex/ex_argv.c b/ex/ex_argv.c
index 8b1fd7858fb1..dd37fe1f69e2 100644
--- a/ex/ex_argv.c
+++ b/ex/ex_argv.c
@@ -764,11 +764,11 @@ err: if (ifp != NULL)
* shell that does that is broken.
*/
for (p = bp, len = 0, ch = EOF;
- (ch = GETC(ifp)) != EOF; *p++ = ch, blen-=sizeof(CHAR_T), ++len)
+ (ch = GETC(ifp)) != EOF; *p++ = ch, blen -= sizeof(CHAR_T), ++len)
if (blen < 5) {
- ADD_SPACE_GOTOW(sp, bp, *blenp, *blenp * 2);
+ ADD_SPACE_GOTO(sp, CHAR_T, bp, *blenp, *blenp * 2);
p = bp + len;
- blen = *blenp - len;
+ blen = *blenp - len * sizeof(CHAR_T);
}
/* Delete the final newline, nul terminate the string. */
diff --git a/ex/ex_subst.c b/ex/ex_subst.c
index bf03e4417e91..3113ac5ca360 100644
--- a/ex/ex_subst.c
+++ b/ex/ex_subst.c
@@ -643,7 +643,9 @@ nextmatch: match[0].rm_so = 0;
goto lquit;
}
} else {
- if (ex_print(sp, cmdp, &from, &to, 0) ||
+ const int flags =
+ O_ISSET(sp, O_NUMBER) ? E_C_HASH : 0;
+ if (ex_print(sp, cmdp, &from, &to, flags) ||
ex_scprint(sp, &from, &to))
goto lquit;
if (ex_txt(sp, tiq, 0, TXT_CR))
@@ -1195,7 +1197,8 @@ re_tag_conv(SCR *sp, CHAR_T **ptrnp, size_t *plenp, int *replacedp)
for (; len > 0; --len) {
if (p[0] == '\\' && (p[1] == '/' || p[1] == '?')) {
++p;
- --len;
+ if (len > 1)
+ --len;
} else if (STRCHR(L("^.[]$*"), p[0]))
*t++ = '\\';
*t++ = *p++;
diff --git a/man/vi.1 b/man/vi.1
index 62f28d72569c..0fa49224353f 100644
--- a/man/vi.1
+++ b/man/vi.1
@@ -2282,6 +2282,10 @@ and
.Nm vi
modes, unless otherwise specified.
.Bl -tag -width Ds
+.It Cm altnotation Bq off
+Display control characters less than 0x20 in <C-char> notations.
+Carriage feed, escape, and delete are marked as <Enter>, <Esc>, and <Del>,
+respectively.
.It Cm altwerase Bq off
.Nm vi
only.
diff --git a/regex/regex.h b/regex/regex.h
index 20ea7865c0a0..7d788514a54c 100644
--- a/regex/regex.h
+++ b/regex/regex.h
@@ -96,6 +96,16 @@ typedef struct {
#define REG_LARGE 01000 /* force large representation */
#define REG_BACKR 02000 /* force use of backref code */
+#ifdef USE_WIDECHAR
+/*
+ * Avoid function name conflicts with the system regex functions.
+ * This is needed e.g. to build with AddressSanitizer.
+ */
+#define regcomp nvi_regcomp
+#define regerror nvi_regerror
+#define regexec nvi_regexec
+#define regfree nvi_regfree
+#endif
int regcomp(regex_t *, const RCHAR_T *, int);
size_t regerror(int, const regex_t *, char *, size_t);
int regexec(const regex_t *,
diff --git a/vi/v_paragraph.c b/vi/v_paragraph.c
index abe8d9cf50e0..2d7f07569b79 100644
--- a/vi/v_paragraph.c
+++ b/vi/v_paragraph.c
@@ -39,15 +39,20 @@
if (p[0] == '\014') { \
if (!--cnt) \
goto found; \
+ if (pstate == P_INTEXT && !--cnt) \
+ goto found; \
continue; \
} \
if (p[0] != '.' || len < 2) \
continue; \
for (lp = VIP(sp)->ps; *lp != '\0'; lp += 2) \
if (lp[0] == p[1] && \
- (lp[1] == ' ' && len == 2 || lp[1] == p[2]) && \
- !--cnt) \
- goto found; \
+ (lp[1] == ' ' && len == 2 || lp[1] == p[2])) { \
+ if (!--cnt) \
+ goto found; \
+ if (pstate == P_INTEXT && !--cnt) \
+ goto found; \
+ } \
} while (0)
/*
diff --git a/vi/v_redraw.c b/vi/v_redraw.c
index de6ed0079701..046fcf15c1b4 100644
--- a/vi/v_redraw.c
+++ b/vi/v_redraw.c
@@ -29,5 +29,6 @@
int
v_redraw(SCR *sp, VICMD *vp)
{
+ F_SET(sp, SC_SCR_REFORMAT);
return (sp->gp->scr_refresh(sp, 1));
}