summaryrefslogtreecommitdiffstats
path: root/contrib/nvi/vi/v_match.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/nvi/vi/v_match.c')
-rw-r--r--contrib/nvi/vi/v_match.c91
1 files changed, 49 insertions, 42 deletions
diff --git a/contrib/nvi/vi/v_match.c b/contrib/nvi/vi/v_match.c
index 3996560..2fae58e 100644
--- a/contrib/nvi/vi/v_match.c
+++ b/contrib/nvi/vi/v_match.c
@@ -10,7 +10,7 @@
#include "config.h"
#ifndef lint
-static const char sccsid[] = "@(#)v_match.c 10.8 (Berkeley) 3/6/96";
+static const char sccsid[] = "$Id: v_match.c,v 10.11 2012/02/11 00:33:46 zy Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -18,8 +18,10 @@ static const char sccsid[] = "@(#)v_match.c 10.8 (Berkeley) 3/6/96";
#include <sys/time.h>
#include <bitstring.h>
+#include <ctype.h>
#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "../common/common.h"
@@ -32,15 +34,23 @@ static const char sccsid[] = "@(#)v_match.c 10.8 (Berkeley) 3/6/96";
* PUBLIC: int v_match __P((SCR *, VICMD *));
*/
int
-v_match(sp, vp)
- SCR *sp;
- VICMD *vp;
+v_match(SCR *sp, VICMD *vp)
{
VCS cs;
MARK *mp;
size_t cno, len, off;
int cnt, isempty, matchc, startc, (*gc)__P((SCR *, VCS *));
- char *p;
+ CHAR_T *p;
+ CHAR_T *cp;
+ const CHAR_T *match_chars;
+
+ /*
+ * 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'.
+ */
+ match_chars = VIP(sp)->mcs;
/*
* !!!
@@ -60,43 +70,14 @@ v_match(sp, vp)
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;
+ startc = p[off];
+ cp = STRCHR(match_chars, startc);
+ if (cp != NULL) {
+ cnt = cp - match_chars;
+ matchc = match_chars[cnt ^ 1];
+ gc = cnt & 1 ? cs_prev : cs_next;
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;
}
- break;
}
cs.cs_lno = vp->m_start.lno;
@@ -135,8 +116,8 @@ nomatch: msgq(sp, M_BERR, "184|No match character on this line");
* starting cursor position when deleting to a match.
*/
if (vp->m_start.lno < vp->m_stop.lno ||
- vp->m_start.lno == vp->m_stop.lno &&
- vp->m_start.cno < vp->m_stop.cno)
+ (vp->m_start.lno == vp->m_stop.lno &&
+ vp->m_start.cno < vp->m_stop.cno))
vp->m_final = ISMOTION(vp) ? vp->m_start : vp->m_stop;
else
vp->m_final = vp->m_stop;
@@ -168,3 +149,29 @@ nomatch: msgq(sp, M_BERR, "184|No match character on this line");
F_SET(vp, VM_LMODE);
return (0);
}
+
+/*
+ * v_buildmcs --
+ * Build the match character list.
+ *
+ * PUBLIC: int v_buildmcs __P((SCR *, char *));
+ */
+int
+v_buildmcs(SCR *sp, char *str)
+{
+ CHAR_T **mp = &VIP(sp)->mcs;
+ size_t len = strlen(str) + 1;
+
+ if (*mp != NULL)
+ free(*mp);
+ MALLOC(sp, *mp, CHAR_T *, len * sizeof(CHAR_T));
+ if (*mp == NULL)
+ return (1);
+#ifdef USE_WIDECHAR
+ if (mbstowcs(*mp, str, len) == (size_t)-1)
+ return (1);
+#else
+ memcpy(*mp, str, len);
+#endif
+ return (0);
+}
OpenPOWER on IntegriCloud