NetBSD Problem Report #17546

Received: (qmail 18652 invoked by uid 605); 10 Jul 2002 15:16:28 -0000
Message-Id: <200207101512.g6AFCFp01589@snowdrop.l8s.co.uk>
Date: Wed, 10 Jul 2002 16:12:15 +0100 (BST)
From: dsl@l8s.co.uk
Sender: gnats-bugs-owner@netbsd.org
Reply-To: dsl@l8s.co.uk
To: gnats-bugs@gnats.netbsd.org
Subject: vi bug fixes and extensions
X-Send-Pr-Version: 3.95

>Number:         17546
>Category:       bin
>Synopsis:       vi bug fixes and extensions
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Jul 10 15:17:00 +0000 2002
>Closed-Date:    
>Last-Modified:  Sat Jun 23 09:40:01 +0000 2007
>Originator:     David Laight
>Release:        NetBSD 1.6B
>Organization:
	none
>Environment:
System: NetBSD snowdrop 1.6B NetBSD 1.6B (GENERIC) #17: Wed Jul 10 12:43:27 BST 2002
dsl@snowdrop:/oldroot/usr/bsd-current/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
	I've got rather annoyed with vi % treating <> as a bracket pair.
	- Added an option 'matchchars' to set the pairs of characters
	  that % will search for.

	I was also trying to edit a file with tab separated fields where
	some of the column widths varied by more than a single tab.

	Setting a very wide screen hits an arbitrary width limit of
	500 screen columns (real screen are too close to that one).
	- increased the limit to 4000.

	It seemed better to allow explicit positioning of tabs.
	- added options:
	    tabadd=col		adds tab at column 'col'
	    taddel=col		removes tab from column col
	    tablist=col_list	adds at +ve numbers, removes from -ve.
	  changes made by tabadd and tabdel affect the 'tablist' string.

	The errorbells and escapetime options were missorted.
	- fixed list.

>How-To-Repeat:
>Fix:
	Diffs below, changed files can be downloaded from:
	http://www.btinternet.com/~david.laight/netbsd/vi
	I think the catalog changes are ok - done by symmetry!

Index: catalog/dutch.base
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/catalog/dutch.base,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 dutch.base
--- dutch.base	2001/03/31 11:29:50	1.1.1.2
+++ dutch.base	2002/07/05 21:14:12
@@ -43,8 +43,7 @@
 044 "De lisp optie is niet ondersteund"
 045 "messages niet uitgeschakeld: %s"
 046 "messages niet geactiveerd: %s"
-048 "De paragraph optie moet karakter paren bevatten"
-049 "De section optie moet karakter paren bevatten"
+047 "set: de %s optie moet karakter paren bevatten"
 053 "De standaard buffer is leeg"
 054 "Buffer %s is leeg"
 055 "Bestanden met newlines in de naam kunnen niet hersteld worden"
Index: catalog/french.base
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/catalog/french.base,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 french.base
--- french.base	2001/03/31 11:29:50	1.1.1.1
+++ french.base	2002/07/05 21:14:18
@@ -43,8 +43,7 @@
 044 "L'option lisp n'est pas impl‚ment‚e"
 045 "Les messages ne sont pas d‚sactiv‚s : %s"
 046 "Les messages ne sont pas activ‚s : %s"
-048 "L'option de paragraphe doit ˆtre en groupe de deux caractŠres"
-049 "L'option de section doit ˆtre en groupe de deux caractŠres"
+047 "D‚finition : l'option de %s doit ˆtre en groupe de deux caractŠres"
 053 "Le tampon par d‚faut est vide"
 054 "Le tampon %s est vide"
 055 "Les fichiers dont le nom contient des caractŠres de saut de ligne sont irr‚cup‚rables"
Index: catalog/german.base
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/catalog/german.base,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 german.base
--- german.base	2001/03/31 11:29:50	1.1.1.2
+++ german.base	2002/07/05 21:14:24
@@ -43,8 +43,7 @@
 044 "Die lisp Option ist nicht implementiert"
 045 "Messages nicht abgeschalten: %s"
 046 "Messages nicht eingeschalten: %s"
-048 "Die paragraph Option muss Gruppen zu zwei Zeichen enthalten"
-049 "Die section Option muss Gruppen zu zwei Zeichen enthalten"
+047 "set: Die %s Option muss Gruppen zu zwei Zeichen enthalten"
 053 "Der Standardpuffer ist leer"
 054 "Puffer %s ist leer"
 055 "Dateien mit newlines im Namen sind nicht wiederherstellbar"
Index: catalog/ru_RU.KOI8-R.base
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/catalog/ru_RU.KOI8-R.base,v
retrieving revision 1.2
diff -u -r1.2 ru_RU.KOI8-R.base
--- ru_RU.KOI8-R.base	2001/03/31 11:37:44	1.2
+++ ru_RU.KOI8-R.base	2002/07/05 21:14:30
@@ -31,9 +31,7 @@
 044 "oPCIQ lisp OTSUTSTWUET"
 045 "sOOB]ENIQ NE WYKL@^ENY: %s"
 046 "sOOB]ENIQ NE WKL@^ENY: %s"
-047 "oPCIQ modeline(s) NE MOVET BYTX PEREUSTANOWLENA"
-048 "oPCIQ paragraph DOLVNA SOSTOQTX IZ GRUPP S DWUMQ SIMWOLAMI"
-049 "oPCIQ section DOLVNA SOSTOQTX IZ GRUPP S DWUMQ SIMWOLAMI"
+047 "set: oPCIQ %s DOLVNA SOSTOQTX IZ GRUPP S DWUMQ SIMWOLAMI"
 050 "oPCIQ shiftwidth NE MOVET BYTX USTANOWLENA NA 0"
 051 "oPCIQ sourceany NE MOVET BYTX USTANOWLENA"
 052 "tABULQCIQ NE MOVET BYTX USTANOWLENA NA 0"
Index: catalog/spanish.base
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/catalog/spanish.base,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 spanish.base
--- spanish.base	2001/03/31 11:29:49	1.1.1.1
+++ spanish.base	2002/07/05 21:14:36
@@ -43,8 +43,7 @@
 044 "La opci¢n lisp no est  implementada"
 045 "mensajes no desconectados: %s"
 046 "mensajes no conectados: %s"
-048 "La opci¢n de p rrafo debe estar en dos grupos de caracteres"
-049 "La opci¢n de secci¢n debe estar en dos grupos de caracteres"
+047 "determinar: La opci¢n de %s debe estar en dos grupos de caracteres"
 053 "El buffer por omisi¢n est  vac¡o"
 054 "El buffer %s est  vac¡o"
 055 "Los archivos con nuevas l¡neas en el nombre son irrecuperables"
Index: catalog/swedish.base
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/catalog/swedish.base,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 swedish.base
--- swedish.base	2001/03/31 11:29:50	1.1.1.2
+++ swedish.base	2002/07/05 21:14:42
@@ -43,8 +43,7 @@
 044 "Lisp flaggan är inte implementerad"
 045 "meddelanden är inte avslagna: %s"
 046 "meddelanden är inte påslagna: %s"
-048 "Paragraph flaggan måste ges i teckengrupper om två"
-049 "Section flaggan måste ges i teckengrupper om två"
+047 "set: %s flaggan måste ges i teckengrupper om två"
 053 "Standardbufferten är tom"
 054 "Buffer %s är tom"
 055 "Filer med radmatning i namnet kan inte återskapas"
Index: options.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/common/options.c,v
retrieving revision 1.6
diff -u -r1.6 options.c
--- options.c	2002/04/09 01:47:31	1.6
+++ options.c	2002/07/06 09:09:54
@@ -49,6 +49,8 @@
  *
  * HPUX noted options and abbreviations are from "The Ultimate Guide to the
  * VI and EX Text Editors", 1990.
+ *
+ * This list must be sorted...
  */
 OPTLIST const optlist[] = {
 /* O_ALTWERASE	  4.4BSD */
@@ -75,10 +77,10 @@
 	{"directory",	NULL,		OPT_STR,	0},
 /* O_EDCOMPATIBLE   4BSD */
 	{"edcompatible",NULL,		OPT_0BOOL,	0},
-/* O_ESCAPETIME	  4.4BSD */
-	{"escapetime",	NULL,		OPT_NUM,	0},
 /* O_ERRORBELLS	    4BSD */
 	{"errorbells",	NULL,		OPT_0BOOL,	0},
+/* O_ESCAPETIME	  4.4BSD */
+	{"escapetime",	NULL,		OPT_NUM,	0},
 /* O_EXRC	System V (undocumented) */
 	{"exrc",	NULL,		OPT_0BOOL,	0},
 /* O_EXTENDED	  4.4BSD */
@@ -119,6 +121,8 @@
 	{"lock",	NULL,		OPT_1BOOL,	0},
 /* O_MAGIC	    4BSD */
 	{"magic",	NULL,		OPT_1BOOL,	0},
+/* O_MATCHCHARS	  netbsd 1.6 */
+	{"matchchars",	NULL,		OPT_STR,	OPT_PAIRS},
 /* O_MATCHTIME	  4.4BSD */
 	{"matchtime",	NULL,		OPT_NUM,	0},
 /* O_MESG	    4BSD */
@@ -145,7 +149,7 @@
 /* O_OPTIMIZE	    4BSD */
 	{"optimize",	NULL,		OPT_1BOOL,	0},
 /* O_PARAGRAPHS	    4BSD */
-	{"paragraphs",	f_paragraph,	OPT_STR,	0},
+	{"paragraphs",	NULL,		OPT_STR,	OPT_PAIRS},
 /* O_PATH	  4.4BSD */
 	{"path",	NULL,		OPT_STR,	0},
 /* O_PRINT	  4.4BSD */
@@ -169,7 +173,7 @@
 /* O_SEARCHINCR	  4.4BSD */
 	{"searchincr",	NULL,		OPT_0BOOL,	0},
 /* O_SECTIONS	    4BSD */
-	{"sections",	f_section,	OPT_STR,	0},
+	{"sections",	NULL,		OPT_STR,	OPT_PAIRS},
 /* O_SECURE	  4.4BSD */
 	{"secure",	NULL,		OPT_0BOOL,	OPT_NOUNSET},
 /* O_SHELL	    4BSD */
@@ -195,8 +199,14 @@
  *	and we ignore the option.
  */
 	{"sourceany",	NULL,		OPT_0BOOL,	OPT_NOSET},
+/* O_TABADD	    netbsd 1.6 */
+	{"tabadd",	f_tabadd,	OPT_NUM,	OPT_NOZERO|OPT_NOSAVE},
+/* O_TABDEL	    netbsd 1.6 */
+	{"tabdel",	f_tabdel,	OPT_NUM,	OPT_NOZERO|OPT_NOSAVE},
+/* O_TABLIST	    netbsd 1.6 */
+	{"tablist",	f_tablist,	OPT_STR,	0},
 /* O_TABSTOP	    4BSD */
-	{"tabstop",	f_reformat,	OPT_NUM,	OPT_NOZERO},
+	{"tabstop",	f_tabstop,	OPT_NUM,	OPT_NOZERO},
 /* O_TAGLENGTH	    4BSD */
 	{"taglength",	NULL,		OPT_NUM,	0},
 /* O_TAGS	    4BSD */
@@ -376,6 +386,7 @@
 	OI(O_TABSTOP, "tabstop=8");
 	(void)snprintf(b1, sizeof(b1), "tags=%s", _PATH_TAGS);
 	OI(O_TAGS, b1);
+	OI(O_MATCHCHARS, "matchchars=()[]{}<>");

 	/*
 	 * XXX
@@ -705,6 +716,14 @@
 				if (!disp)
 					disp = SELECT_DISPLAY;
 				F_SET(spo, OPT_SELECTED);
+				break;
+			}
+
+			/* Check for strings that must have even length */
+			if (F_ISSET(op, OPT_PAIRS) && strlen(sep) & 1) {
+				msgq_str(sp, M_ERR, name,
+				    "047|set: the %s option must be in two character groups");
+				rval = 1;
 				break;
 			}

Index: common/options.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/common/options.h,v
retrieving revision 1.4
diff -u -r1.4 options.h
--- options.h	2001/03/31 11:37:46	1.4
+++ options.h	2002/07/05 21:14:55
@@ -30,6 +30,8 @@
 	(F_ISSET(&(sp)->opts[(o)], OPT_GLOBAL) ?			\
 	    (sp)->gp->opts[(sp)->opts[(o)].o_cur.val].fld :		\
 	    (sp)->opts[(o)].fld)
+/* if known to be local */
+#define	OL_V(sp, o, fld)	((sp)->opts[(o)].fld)

 /* Global option macros. */
 #define	OG_CLR(gp, o)		((gp)->opts[(o)].o_cur.val) = 0
@@ -59,6 +61,7 @@
 #define	O_SET(sp, o)		o_set(sp, o, 0, NULL, 1)
 #define	O_STR(sp, o)		O_V(sp, o, o_cur.str)
 #define	O_VAL(sp, o)		O_V(sp, o, o_cur.val)
+#define	OL_VAL(sp, o)		OL_V(sp, o, o_cur.val)
 #define	O_ISSET(sp, o)		O_VAL(sp, o)

 	union {
@@ -92,7 +95,8 @@
 #define	OPT_NOUNSET	0x020		/* Option may not be unset. */
 #define	OPT_NOZERO	0x040		/* Option may not be set to 0. */
 #define OPT_EARLYSET	0x080		/* Subsys called after value is set. */
-	u_int8_t flags;
+#define OPT_PAIRS	0x100		/* String with even length */
+	int flags;
 };

 /* Option argument to opts_dump(). */
Index: common/options_f.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/common/options_f.c,v
retrieving revision 1.4
diff -u -r1.4 options_f.c
--- options_f.c	2002/04/09 01:47:31	1.4
+++ options_f.c	2002/07/05 21:15:00
@@ -74,7 +74,7 @@
 	 * number of lines/columns for the screen, but at least we don't drop
 	 * core.
 	 */
-#define	MAXIMUM_SCREEN_COLS	500
+#define	MAXIMUM_SCREEN_COLS	4000
 	if (*valp > MAXIMUM_SCREEN_COLS) {
 		msgq(sp, M_ERR, "041|Screen columns too large, greater than %d",
 		    MAXIMUM_SCREEN_COLS);
@@ -108,7 +108,7 @@
 	 * number of lines/columns for the screen, but at least we don't drop
 	 * core.
 	 */
-#define	MAXIMUM_SCREEN_ROWS	500
+#define	MAXIMUM_SCREEN_ROWS	4000
 	if (*valp > MAXIMUM_SCREEN_ROWS) {
 		msgq(sp, M_ERR, "043|Screen lines too large, greater than %d",
 		    MAXIMUM_SCREEN_ROWS);
@@ -169,24 +169,6 @@
 }

 /*
- * PUBLIC: int f_paragraph __P((SCR *, OPTION *, char *, u_long *));
- */
-int
-f_paragraph(sp, op, str, valp)
-	SCR *sp;
-	OPTION *op;
-	char *str;
-	u_long *valp;
-{
-	if (strlen(str) & 1) {
-		msgq(sp, M_ERR,
-		    "048|The paragraph option must be in two character groups");
-		return (1);
-	}
-	return (0);
-}
-
-/*
  * PUBLIC: int f_print __P((SCR *, OPTION *, char *, u_long *));
  */
 int
@@ -261,24 +243,6 @@
 }

 /*
- * PUBLIC: int f_section __P((SCR *, OPTION *, char *, u_long *));
- */
-int
-f_section(sp, op, str, valp)
-	SCR *sp;
-	OPTION *op;
-	char *str;
-	u_long *valp;
-{
-	if (strlen(str) & 1) {
-		msgq(sp, M_ERR,
-		    "049|The section option must be in two character groups");
-		return (1);
-	}
-	return (0);
-}
-
-/*
  * PUBLIC: int f_ttywerase __P((SCR *, OPTION *, char *, u_long *));
  */
 int
@@ -370,4 +334,156 @@
 	    (*valp = O_VAL(sp, O_LINES) - 1) == 0)
 		*valp = 1;
 	return (0);
+}
+
+/*
+ * PUBLIC: int f_tabstop __P((SCR *, OPTION *, char *, u_long *));
+ */
+int
+f_tabstop(SCR *sp, OPTION *op, char *str, ulong *valp)
+{
+	char *tl;
+
+	if (*valp > 2048)
+		/* sanity */
+		return 1;
+
+	/* Hack tabstop value in for tabadd code... */
+	O_VAL(sp, O_TABSTOP) = *valp;
+
+	/* get modified tab positions */
+	tl = O_STR(sp, O_TABLIST);
+	if (tl && (tl = strdup(tl))) {
+		/* and reapply */
+		f_tablist(sp, op, tl, 0);
+		free(tl);
+	}
+	 
+	return f_reformat(sp, op, str, valp);
+}
+
+/*
+ * PUBLIC: int f_tabadd __P((SCR *, OPTION *, char *, u_long *));
+ */
+int
+f_tabadd(SCR *sp, OPTION *op, char *str, ulong *valp)
+{
+	int col = *valp;
+	size_t tc, ts = O_VAL(sp, O_TABSTOP);
+	size_t *tt;
+	char *as, *ns;
+	int i;
+
+	if (!col)
+		return 0;
+	/* force redraw */
+	f_reformat(sp, op, str, valp);
+
+	if (col < 0)
+		col = -col;
+
+	/* Make table large enough to include this tabstop */
+	tt = sp->tab_table;
+	if (col >= sp->tab_table_len) {
+		REALLOC(sp, tt, size_t *, (col + 1) * sizeof *sp->tab_table);
+		/* fill in default tabs */
+		for (i = sp->tab_table_len; i <= col; i++)
+			tt[i] = COL_OFF(i, ts);
+		sp->tab_table_len = col + 1;
+		sp->tab_table = tt;
+	}
+	/* overwrite offsets going back to previous tab position */
+	i = *(long *)valp < 0 ? tt[col] : 0;
+	do {
+		tt[--col] = ++i;
+	} while (col && tt[col-1] != 1);
+
+	/* finally generate equivalent 'string' tablist value */
+	as = 0;
+	for (tc = 0, col = 0; col < sp->tab_table_len; col++, tc--) {
+		if (!tc)
+			tc = ts;
+		if (tt[col] != 1) {
+			/* there isn't a tab here... */
+			if (tc != 1)
+				/* and we dont expect one */
+				continue;
+			i = -(col + 1);
+		} else {
+			/* there is a tab here */
+			if (tc == 1)
+				/* we expected it */
+				continue;
+			i = col + 1;
+		}
+		if (as) {
+			asprintf( &ns, "%s,%d", as, i );
+			free(as);
+		} else
+			asprintf( &ns, "%d", i );
+		as = ns;
+	}
+
+	if (!as) {
+		free(tt);
+		sp->tab_table_len = 0;
+		sp->tab_table = 0;
+	}
+
+	o_set(sp, O_TABLIST, OS_STRDUP, as ? as : "", 0);
+	free(as);
+
+	return 0;
+}
+
+/*
+ * PUBLIC: int f_tabdel __P((SCR *, OPTION *, char *, u_long *));
+ */
+int
+f_tabdel(SCR *sp, OPTION *op, char *str, ulong *valp)
+{
+	ulong col = -*valp;
+
+	return f_tabadd(sp, op, str, &col);
+}
+
+/*
+ * PUBLIC: int f_tablist __P((SCR *, OPTION *, char *, u_long *));
+ */
+int
+f_tablist(SCR *sp, OPTION *op, char *str, ulong *valp)
+{
+	char *cp, *ncp;
+	ulong col;
+
+	/* validate that string is comma separated numbers */
+	if (*str) {
+		for (cp = str; ; cp = ncp + 1) {
+			strtol( cp, &ncp, 0 );
+			if (!*ncp)
+				break;
+			if (*ncp != ',')
+				return 1;
+		}
+	}
+
+	/* Remove all old info */
+	if (sp->tab_table) {
+		free( sp->tab_table );
+		sp->tab_table = 0;
+		sp->tab_table_len = 0;
+	}
+
+	if (!*str)
+		return 0;
+
+	/* now add in one by one */
+	for (cp = str; ; cp = ncp + 1) {
+		col = strtol( cp, &ncp, 0 );
+		f_tabadd(sp, op, 0, &col);
+		if (!*ncp)
+			break;
+	}
+
+	return 0;
 }
Index: common/screen.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/common/screen.h,v
retrieving revision 1.3
diff -u -r1.3 screen.h
--- screen.h	2001/03/31 11:37:47	1.3
+++ screen.h	2002/07/05 21:15:05
@@ -136,6 +136,9 @@

 	OPTION	 opts[O_OPTIONCOUNT];	/* Ex/vi: Options. */

+	size_t	tab_table_len;		/* size of tab offset table */
+	size_t	*tab_table;		/* offsets of tabs */
+
 /*
  * Screen flags.
  *
Index: common/util.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/common/util.c,v
retrieving revision 1.4
diff -u -r1.4 util.c
--- util.c	2002/04/09 01:47:32	1.4
+++ util.c	2002/07/05 21:15:10
@@ -196,6 +196,22 @@
 	return (NUM_ERR);
 }

+
+/*
+ * PUBLIC: size_t tab_off( SCR *, size_t );
+ *
+ * Return number of characters to next tab stop.
+ */
+size_t
+tab_off( SCR *sp, size_t off )
+{
+	/* Has user been fiddling with the tabs? */
+	if (off < sp->tab_table_len)
+		return sp->tab_table[off];
+
+	return COL_OFF( off, OL_VAL( sp, O_TABSTOP ) );
+}
+
 #ifdef DEBUG
 #ifdef __STDC__
 #include <stdarg.h>
Index: ex/ex_txt.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/ex/ex_txt.c,v
retrieving revision 1.6
diff -u -r1.6 ex_txt.c
--- ex_txt.c	2002/04/09 01:47:34	1.6
+++ ex_txt.c	2002/07/05 21:15:16
@@ -393,16 +393,16 @@
 	SCR *sp;
 	TEXT *tp;
 {
-	u_long sw, ts;
+	u_long sw;
 	size_t cno, off, scno, spaces, tabs;
+	size_t nco;

-	ts = O_VAL(sp, O_TABSTOP);
 	sw = O_VAL(sp, O_SHIFTWIDTH);

 	/* Get the current screen column. */
 	for (off = scno = 0; off < tp->len; ++off)
 		if (tp->lb[off] == '\t')
-			scno += COL_OFF(scno, ts);
+			scno += tab_off(sp, scno);
 		else
 			++scno;

@@ -421,8 +421,8 @@
 	 *
 	 * Count up spaces/tabs needed to get to the target.
 	 */
-	for (cno = 0, tabs = 0; cno + COL_OFF(cno, ts) <= scno; ++tabs)
-		cno += COL_OFF(cno, ts);
+	for (cno = 0, tabs = 0; (nco = cno + tab_off(sp, cno)) <= scno; ++tabs)
+		cno = nco;
 	spaces = scno - cno;

 	/* Make sure there's enough room. */
Index: ex/ex_shift.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/ex/ex_shift.c,v
retrieving revision 1.9
diff -u -r1.9 ex_shift.c
--- ex_shift.c	2002/04/09 01:47:34	1.9
+++ ex_shift.c	2002/07/05 21:15:21
@@ -73,6 +73,7 @@
 {
 	recno_t from, to;
 	size_t blen, len, newcol, newidx, oldcol, oldidx, sw;
+	size_t col, nc;
 	int curset;
 	char *p, *bp, *tbp;

@@ -120,8 +121,7 @@
 			if (p[oldidx] == ' ')
 				++oldcol;
 			else if (p[oldidx] == '\t')
-				oldcol += O_VAL(sp, O_TABSTOP) -
-				    oldcol % O_VAL(sp, O_TABSTOP);
+				oldcol += tab_off(sp, oldcol);
 			else
 				break;

@@ -144,13 +144,13 @@
 		 * 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) {
+		for (col = 0, tbp = bp;
+		    (nc = col + tab_off(sp, col)) <= newcol; col = nc) {
 			*tbp++ = '\t';
-			newcol -= O_VAL(sp, O_TABSTOP);
 		}
-		for (; newcol > 0; --newcol, ++newidx)
+		for (; col < newcol; col++)
 			*tbp++ = ' ';
+		newidx = tbp - bp;

 		/* Add the original line. */
 		memcpy(tbp, p + oldidx, len - oldidx);
Index: include/com_extern.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/include/com_extern.h,v
retrieving revision 1.2
diff -u -r1.2 com_extern.h
--- com_extern.h	2001/03/31 11:37:51	1.2
+++ com_extern.h	2002/07/05 21:15:25
@@ -152,12 +152,14 @@
 int f_lines __P((SCR *, OPTION *, char *, u_long *));
 int f_lisp __P((SCR *, OPTION *, char *, u_long *));
 int f_msgcat __P((SCR *, OPTION *, char *, u_long *));
-int f_paragraph __P((SCR *, OPTION *, char *, u_long *));
 int f_print __P((SCR *, OPTION *, char *, u_long *));
 int f_readonly __P((SCR *, OPTION *, char *, u_long *));
 int f_recompile __P((SCR *, OPTION *, char *, u_long *));
 int f_reformat __P((SCR *, OPTION *, char *, u_long *));
-int f_section __P((SCR *, OPTION *, char *, u_long *));
+int f_tabadd __P((SCR *, OPTION *, char *, u_long *));
+int f_tabdel __P((SCR *, OPTION *, char *, u_long *));
+int f_tablist __P((SCR *, OPTION *, char *, u_long *));
+int f_tabstop __P((SCR *, OPTION *, char *, u_long *));
 int f_ttywerase __P((SCR *, OPTION *, char *, u_long *));
 int f_w300 __P((SCR *, OPTION *, char *, u_long *));
 int f_w1200 __P((SCR *, OPTION *, char *, u_long *));
@@ -194,3 +196,4 @@
 enum nresult nget_uslong __P((u_long *, const char *, char **, int));
 enum nresult nget_slong __P((long *, const char *, char **, int));
 void TRACE __P((SCR *, const char *, ...));
+size_t tab_off(SCR *, size_t);
Index: include/options_def.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/include/options_def.h,v
retrieving revision 1.4
diff -u -r1.4 options_def.h
--- options_def.h	2001/03/31 11:37:51	1.4
+++ options_def.h	2002/07/05 21:15:39
@@ -1,5 +1,3 @@
-/*	$NetBSD: options_def.h,v 1.4 2001/03/31 11:37:51 aymeric Exp $	*/
-
 #define O_ALTWERASE 0
 #define O_AUTOINDENT 1
 #define O_AUTOPRINT 2
@@ -29,54 +27,58 @@
 #define O_LIST 26
 #define O_LOCKFILES 27
 #define O_MAGIC 28
-#define O_MATCHTIME 29
-#define O_MESG 30
-#define O_MODELINE 31
-#define O_MSGCAT 32
-#define O_NOPRINT 33
-#define O_NUMBER 34
-#define O_OCTAL 35
-#define O_OPEN 36
-#define O_OPTIMIZE 37
-#define O_PARAGRAPHS 38
-#define O_PATH 39
-#define O_PRINT 40
-#define O_PROMPT 41
-#define O_READONLY 42
-#define O_RECDIR 43
-#define O_REDRAW 44
-#define O_REMAP 45
-#define O_REPORT 46
-#define O_RULER 47
-#define O_SCROLL 48
-#define O_SEARCHINCR 49
-#define O_SECTIONS 50
-#define O_SECURE 51
-#define O_SHELL 52
-#define O_SHELLMETA 53
-#define O_SHIFTWIDTH 54
-#define O_SHOWMATCH 55
-#define O_SHOWMODE 56
-#define O_SIDESCROLL 57
-#define O_SLOWOPEN 58
-#define O_SOURCEANY 59
-#define O_TABSTOP 60
-#define O_TAGLENGTH 61
-#define O_TAGS 62
-#define O_TERM 63
-#define O_TERSE 64
-#define O_TILDEOP 65
-#define O_TIMEOUT 66
-#define O_TTYWERASE 67
-#define O_VERBOSE 68
-#define O_W1200 69
-#define O_W300 70
-#define O_W9600 71
-#define O_WARN 72
-#define O_WINDOW 73
-#define O_WINDOWNAME 74
-#define O_WRAPLEN 75
-#define O_WRAPMARGIN 76
-#define O_WRAPSCAN 77
-#define O_WRITEANY 78
-#define O_OPTIONCOUNT 79
+#define O_MATCHCHARS 29
+#define O_MATCHTIME 30
+#define O_MESG 31
+#define O_MODELINE 32
+#define O_MSGCAT 33
+#define O_NOPRINT 34
+#define O_NUMBER 35
+#define O_OCTAL 36
+#define O_OPEN 37
+#define O_OPTIMIZE 38
+#define O_PARAGRAPHS 39
+#define O_PATH 40
+#define O_PRINT 41
+#define O_PROMPT 42
+#define O_READONLY 43
+#define O_RECDIR 44
+#define O_REDRAW 45
+#define O_REMAP 46
+#define O_REPORT 47
+#define O_RULER 48
+#define O_SCROLL 49
+#define O_SEARCHINCR 50
+#define O_SECTIONS 51
+#define O_SECURE 52
+#define O_SHELL 53
+#define O_SHELLMETA 54
+#define O_SHIFTWIDTH 55
+#define O_SHOWMATCH 56
+#define O_SHOWMODE 57
+#define O_SIDESCROLL 58
+#define O_SLOWOPEN 59
+#define O_SOURCEANY 60
+#define O_TABADD 61
+#define O_TABDEL 62
+#define O_TABLIST 63
+#define O_TABSTOP 64
+#define O_TAGLENGTH 65
+#define O_TAGS 66
+#define O_TERM 67
+#define O_TERSE 68
+#define O_TILDEOP 69
+#define O_TIMEOUT 70
+#define O_TTYWERASE 71
+#define O_VERBOSE 72
+#define O_W1200 73
+#define O_W300 74
+#define O_W9600 75
+#define O_WARN 76
+#define O_WINDOW 77
+#define O_WINDOWNAME 78
+#define O_WRAPLEN 79
+#define O_WRAPMARGIN 80
+#define O_WRAPSCAN 81
+#define O_WRITEANY 82
+#define O_OPTIONCOUNT 83
Index: vi/v_match.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/vi/v_match.c,v
retrieving revision 1.8
diff -u -r1.8 v_match.c
--- v_match.c	2002/04/09 01:47:35	1.8
+++ v_match.c	2002/07/05 21:15:43
@@ -48,7 +48,17 @@
 	size_t cno, len, off;
 	int cnt, isempty, matchc, startc, (*gc)__P((SCR *, VCS *));
 	char *p;
+	char *match_chars;

+	static int match_lno, match_col, match_dir;
+
+	/* Historically vi would match (), {} and [] however
+	   an update included <>.  This is ok for editing HTML
+	   but a pain in the butt for C source.
+	   Making it an option lets the user decide what is 'right'.
+	   Also fixed to do something sensible with "". */
+	match_chars = O_STR( sp, O_MATCHCHARS );
+
 	/*
 	 * !!!
 	 * Historic practice; ignore the count.
@@ -63,48 +73,33 @@
 		return (1);
 	}
 	for (off = vp->m_start.cno;; ++off) {
+		char *cp;
 		if (off >= len) {
 nomatch:		msgq(sp, M_BERR, "184|No match character on this line");
 			return (1);
 		}
-		switch (startc = p[off]) {
-		case '(':
-			matchc = ')';
-			gc = cs_next;
-			break;
-		case ')':
-			matchc = '(';
-			gc = cs_prev;
-			break;
-		case '[':
-			matchc = ']';
-			gc = cs_next;
-			break;
-		case ']':
-			matchc = '[';
-			gc = cs_prev;
-			break;
-		case '{':
-			matchc = '}';
-			gc = cs_next;
-			break;
-		case '}':
-			matchc = '{';
-			gc = cs_prev;
-			break;
-		case '<':
-			matchc = '>';
-			gc = cs_next;
-			break;
-		case '>':
-			matchc = '<';
-			gc = cs_prev;
-			break;
-		default:
-			continue;
-		}
+		startc = p[off];
+		cp = strchr( match_chars, startc );
+		if (!cp)
+		    continue;
+		cnt = cp - match_chars;
 		break;
 	}
+	matchc = match_chars[ cnt ^ 1 ];
+
+	/* Alternate back-forward search if startc and matchc the same */
+	if (startc == matchc) {
+		/* are we continuing from where last match finished? */
+		if (match_lno == vp->m_start.lno && match_col ==vp->m_start.cno)
+			/* yes - continue in sequence */
+			match_dir++;
+		else
+			/* no - go forward, back, back, forward */
+			match_dir = 1;
+		if (match_dir & 2)
+		    cnt++;
+	}
+	gc = cnt & 1 ? cs_prev : cs_next;

 	cs.cs_lno = vp->m_start.lno;
 	cs.cs_cno = off;
@@ -118,10 +113,10 @@
 				break;
 			continue;
 		}
+		if (cs.cs_ch == matchc && --cnt == 0)
+			break;
 		if (cs.cs_ch == startc)
 			++cnt;
-		else if (cs.cs_ch == matchc && --cnt == 0)
-			break;
 	}
 	if (cnt) {
 		msgq(sp, M_BERR, "185|Matching character not found");
@@ -147,6 +142,9 @@
 		vp->m_final = ISMOTION(vp) ? vp->m_start : vp->m_stop;
 	else
 		vp->m_final = vp->m_stop;
+
+	match_lno = vp->m_final.lno;
+	match_col = vp->m_final.cno;

 	/*
 	 * !!!
Index: vi/v_txt.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/vi/v_txt.c,v
retrieving revision 1.9
diff -u -r1.9 v_txt.c
--- v_txt.c	2002/04/09 01:47:36	1.9
+++ v_txt.c	2002/07/05 21:16:00
@@ -1698,9 +1698,9 @@
 	TEXT *tp;
 	int *changedp;
 {
-	u_long ts;
 	int del;
 	size_t cno, len, new, old, scno, spaces, tab_after_sp, tabs;
+	size_t nco;
 	char *p;

 	*changedp = 0;
@@ -1726,15 +1726,16 @@
 	 * in the line are resolved into the minimum number of characters.
 	 * Historic practice.
 	 */
-	ts = O_VAL(sp, O_TABSTOP);

 	/* Figure out the last <blank> screen column. */
 	for (p = tp->lb, scno = 0, len = tp->len,
-	    spaces = tab_after_sp = 0; len-- && isblank(*p); ++p)
+	    nco = spaces = tab_after_sp = 0; len-- && isblank(*p); ++p)
 		if (*p == '\t') {
 			if (spaces)
 				tab_after_sp = 1;
-			scno += COL_OFF(scno, ts);
+			scno += tab_off(sp, scno);
+			/* get spaces to next tab stop... */
+			nco = tab_off(sp, scno);
 		} else {
 			++spaces;
 			++scno;
@@ -1742,14 +1743,14 @@

 	/*
 	 * If there are no spaces, or no tabs after spaces and less than
-	 * ts spaces, it's already minimal.
+	 * nco spaces, it's already minimal.
 	 */
-	if (!spaces || !tab_after_sp && spaces < ts)
+	if (!spaces || !tab_after_sp && spaces < nco)
 		return;

 	/* Count up spaces/tabs needed to get to the target. */
-	for (cno = 0, tabs = 0; cno + COL_OFF(cno, ts) <= scno; ++tabs)
-		cno += COL_OFF(cno, ts);
+	for (cno = 0, tabs = 0; (nco = cno + tab_off(sp, cno)) <= scno; ++tabs)
+		cno = nco;
 	spaces = scno - cno;

 	/*
@@ -1922,11 +1923,11 @@
 	int isindent;
 {
 	CHAR_T ch;
-	u_long sw, ts;
+	u_long sw;
 	size_t cno, current, spaces, target, tabs;
+	size_t nco;
 	int ai_reset;

-	ts = O_VAL(sp, O_TABSTOP);
 	sw = O_VAL(sp, O_SHIFTWIDTH);

 	/*
@@ -1947,7 +1948,7 @@
 	 */
 	for (current = cno = 0; cno < tp->cno; ++cno)
 		current += tp->lb[cno] == '\t' ?
-		    COL_OFF(current, ts) : KEY_LEN(sp, tp->lb[cno]);
+		    tab_off(sp, current) : KEY_LEN(sp, tp->lb[cno]);

 	target = current;
 	if (isindent)
@@ -1977,7 +1978,7 @@
 	    --tp->cno, ++tp->owrite);
 	for (current = cno = 0; cno < tp->cno; ++cno)
 		current += tp->lb[cno] == '\t' ?
-		    COL_OFF(current, ts) : KEY_LEN(sp, tp->lb[cno]);
+		    tab_off(sp, current) : KEY_LEN(sp, tp->lb[cno]);

 	/*
 	 * If we didn't move up to or past the target, it's because there
@@ -1995,8 +1996,8 @@
 		spaces = tabs = 0;
 	else {
 		for (cno = current,
-		    tabs = 0; cno + COL_OFF(cno, ts) <= target; ++tabs)
-			cno += COL_OFF(cno, ts);
+		    tabs = 0; (nco = cno + tab_off(sp, cno)) <= target; ++tabs)
+			cno = nco;
 		spaces = target - cno;
 	}

Index: vi/vi.h
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/vi/vi/vi.h,v
retrieving revision 1.3
diff -u -r1.3 vi.h
--- vi.h	2001/03/31 11:37:52	1.3
+++ vi.h	2002/07/05 21:16:07
@@ -351,7 +351,7 @@
  * positions when <esc> is entered.  I believe that nvi does tabs correctly,
  * but there are some historical incompatibilities.
  */
-#define	TAB_OFF(c)	COL_OFF((c), O_VAL(sp, O_TABSTOP))
+#define	TAB_OFF(c)	tab_off(sp, c)

 /* If more than one screen being shown. */
 #define	IS_SPLIT(sp)							\
>Release-Note:
>Audit-Trail:

From: gabriel rosenkoetter <gr@eclipsed.net>
To: dsl@l8s.co.uk
Cc: gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/17546: vi bug fixes and extensions
Date: Wed, 10 Jul 2002 13:14:19 -0400

 --kHRd/tpU31Zn62xO
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable

 On Wed, Jul 10, 2002 at 04:12:15PM +0100, dsl@l8s.co.uk wrote:
 >   I've got rather annoyed with vi % treating <> as a bracket pair.
 >   - Added an option 'matchchars' to set the pairs of characters
 >     that % will search for.
 [...]
 >   It seemed better to allow explicit positioning of tabs.
 >   - added options:
 >       tabadd=3Dcol    adds tab at column 'col'
 >       taddel=3Dcol    removes tab from column col
 >       tablist=3Dcol_list  adds at +ve numbers, removes from -ve.
 >     changes made by tabadd and tabdel affect the 'tablist' string.

 Isn't our vi(1) actually nvi? If so, shouldn't feature additions=20
 like this go through the original authors?
  =20
 Imho, adding features to vi(1) is not appropriate. If you want a=20
 more featureful vi-like editor, use pkgsrc/editors/vim. As it=20
 stands, nvi is a (nearly) bug-for-bug copy of real (encumbered)
 vi(1).
  =20
 --=20
 gabriel rosenkoetter
 gr@eclipsed.net

 --kHRd/tpU31Zn62xO
 Content-Type: application/pgp-signature
 Content-Disposition: inline

 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.7 (NetBSD)

 iD8DBQE9LGtr9ehacAz5CRoRAoKXAJ4sp9xeaoEco/eiVdryjN9P+dahWgCeKK7+
 7KoVoPxPkP85qCqTVJVIxqQ=
 =SZx1
 -----END PGP SIGNATURE-----

 --kHRd/tpU31Zn62xO--

From: itojun@iijlab.net
To: gabriel rosenkoetter <gr@eclipsed.net>
Cc: dsl@l8s.co.uk, gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/17546: vi bug fixes and extensions 
Date: Thu, 11 Jul 2002 05:43:54 +0900

 >Isn't our vi(1) actually nvi? If so, shouldn't feature additions=20
 >like this go through the original authors?
 > =20
 >Imho, adding features to vi(1) is not appropriate. If you want a=20
 >more featureful vi-like editor, use pkgsrc/editors/vim. As it=20

 	yes, you should contact nvi/vim authors instead.

 >stands, nvi is a (nearly) bug-for-bug copy of real (encumbered)
 >vi(1).

 	btw, what happened to AT&T license source code made public under
 	BSD license?  I would like to see REAL vi (with lisp mode) in the
 	system if possible :-)

 itojun

From: gabriel rosenkoetter <gr@eclipsed.net>
To: itojun@iijlab.net
Cc: dsl@l8s.co.uk, gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/17546: vi bug fixes and extensions
Date: Wed, 10 Jul 2002 16:47:47 -0400

 --ZfOjI3PrQbgiZnxM
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 Content-Transfer-Encoding: quoted-printable

 [Replies to this should probably remove gnats-bugs from the
 recipient list unless it's something that really ought to be in the
 GNATS DB. Yes, I think the first thing here should.]

 On Thu, Jul 11, 2002 at 05:43:54AM +0900, itojun@iijlab.net wrote:
 > 	yes, you should contact nvi/vim authors instead.

 The actual bugfix in this PR should, of course, probably be
 committed. (It's just the feature additions I was taking issue with.)

 > 	btw, what happened to AT&T license source code made public under
 > 	BSD license?  I would like to see REAL vi (with lisp mode) in the
 > 	system if possible :-)

 As I recall, vi has encumberments outside of AT&T, but I don't
 remember the details and could be remembering wrong.

 --=20
 gabriel rosenkoetter
 gr@eclipsed.net

 --ZfOjI3PrQbgiZnxM
 Content-Type: application/pgp-signature
 Content-Disposition: inline

 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.7 (NetBSD)

 iD8DBQE9LJ1y9ehacAz5CRoRAnQiAKCK5fqD0xYZ+zT8jrTT3JkToAJVHwCgjbCK
 nt2/XvGlRr3prWj/ceRCVrg=
 =ocYL
 -----END PGP SIGNATURE-----

 --ZfOjI3PrQbgiZnxM--

From: cgd@broadcom.com
To: gr@eclipsed.net
Cc: dsl@l8s.co.uk, gnats-bugs@gnats.netbsd.org, netbsd-bugs@netbsd.org
Subject: Re: bin/17546: vi bug fixes and extensions
Date: 10 Jul 2002 18:06:49 -0700

 At Wed, 10 Jul 2002 17:14:30 +0000 (UTC), "gabriel rosenkoetter" wrote:
 > Imho, adding features to vi(1) is not appropriate. If you want a
 > more featureful vi-like editor, use pkgsrc/editors/vim. As it
 > stands, nvi is a (nearly) bug-for-bug copy of real (encumbered)
 > vi(1).

 nvi has _lots_ of features over and above traditional vi.  (tildeop is
 the one that i use the most...)

 IMO, it's quite alright to add features... just don't enable them by
 default and make sure they don't conflict with existing
 behaviour/options.

 (My problem with vim is that it's too bloody hard to make it act
 "mostly" like real vi, and even when you do get it to do that there
 are still some very annoying differences.  On the other hand, nvi has
 enough features over and above real vi that, while I'll use real vi in
 a pinch, I try to keep a copy of nvi around...)


 But anyway, yes, this should probably be run by the folks maintaining
 nvi...


 cgd


From: David Laight <david@l8s.co.uk>
To: cgd@broadcom.com
Cc: gr@eclipsed.net, dsl@l8s.co.uk, gnats-bugs@gnats.netbsd.org,
  netbsd-bugs@netbsd.org
Subject: Re: bin/17546: vi bug fixes and extensions
Date: Thu, 11 Jul 2002 08:58:26 +0100

 On Wed, Jul 10, 2002 at 06:06:49PM -0700, cgd@broadcom.com wrote:
 > At Wed, 10 Jul 2002 17:14:30 +0000 (UTC), "gabriel rosenkoetter" wrote:
 > > Imho, adding features to vi(1) is not appropriate. If you want a
 > > more featureful vi-like editor, use pkgsrc/editors/vim. As it
 > > stands, nvi is a (nearly) bug-for-bug copy of real (encumbered)
 > > vi(1).
 > 
 > nvi has _lots_ of features over and above traditional vi.  (tildeop is
 > the one that i use the most...)

 nvi behaves the same way ALMOST all the time, I've spotted a few
 differences - generally the nvi behaviour is better.
 OTOH I sort of prefer the undo-redo - used to see what you've just
 changed.
 > 
 > IMO, it's quite alright to add features... just don't enable them by
 > default and make sure they don't conflict with existing
 > behaviour/options.

 Absolutely - my 'matchchras' for % is adding an option so that the
 traditional; behaviour will work.
 > 
 > But anyway, yes, this should probably be run by the folks maintaining
 > nvi...

 Yes - but a netbsd bug isn't a bad placeholder for the information.
 I compared thenetbsd 'nvi' source with the 1.79 that can be downloaded
 - there are quite a few changes, many because netbsd is much more
 particular about fixing compiler warning.
 However there are a few bug fixes lurking.

 	David

 -- 
 David Laight: david@l8s.co.uk
Responsible-Changed-From-To: bin-bug-people->pooka 
Responsible-Changed-By: pooka 
Responsible-Changed-When: Sun Jul 28 22:36:13 EEST 2002 
Responsible-Changed-Why:  
I'll contact nvi maintainers 
Responsible-Changed-From-To: pooka->bin-bug-people
Responsible-Changed-By: pooka@netbsd.org
Responsible-Changed-When: Thu, 21 Jun 2007 17:18:39 +0300
Responsible-Changed-Why:
Let's face it - I'm not fixing this anytime soon


From: David Laight <david@l8s.co.uk>
To: gnats-bugs@NetBSD.org
Cc: 
Subject: Re: bin/17546 (vi bug fixes and extensions)
Date: Thu, 21 Jun 2007 20:24:00 +0100

 On Thu, Jun 21, 2007 at 02:18:43PM +0000, pooka@netbsd.org wrote:
 > Synopsis: vi bug fixes and extensions
 > 
 > Responsible-Changed-From-To: pooka->bin-bug-people
 > Responsible-Changed-By: pooka@netbsd.org
 > Responsible-Changed-When: Thu, 21 Jun 2007 17:18:39 +0300
 > Responsible-Changed-Why:
 > Let's face it - I'm not fixing this anytime soon

 I might though!

 The 'matchchars' option got submitted ages ago.
 I need the tab columns to edit one file (a club address list), and if
 I upgrade that system from 1.6W I'll need the vi changes!

 	David

 -- 
 David Laight: david@l8s.co.uk

From: David Laight <david@l8s.co.uk>
To: Aymeric Vincent <vincent@labri.fr>
Cc: gnats-bugs@netbsd.org
Subject: Re: bin/17546 (vi bug fixes and extensions)
Date: Sat, 23 Jun 2007 08:37:45 +0100

 On Sat, Jun 23, 2007 at 12:05:27AM +0200, Aymeric Vincent wrote:
 > 
 >        Hi David,
 > 
 > David Laight <david@l8s.co.uk> writes:
 > 
 > >  > Let's face it - I'm not fixing this anytime soon
 > >  
 > >  I might though!
 > 
 > May I ask that you either commit this "very quickly" (~1 or 2 weeks)
 > or wait after I import nvi 1.81.x?
 > 
 > Regards,
 >  Aymeric

 I'm unlikely to do it any time soon - since I've not done it
 during the last 4 years :-)

 	David

 -- 
 David Laight: david@l8s.co.uk

>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.