From 7bdd574d4225d2047c24b266f835b3f1036e83b3 Mon Sep 17 00:00:00 2001 From: Wolfgang Jenkner Date: Mon, 7 Apr 2008 01:55:26 +0200 Subject: [PATCH] vi/v_increment.c: v_increment: fix support for wide characters Without this change, the vi commands `#+' `#-' and `##' don't work: the number under the cursor disappears, vi hangs or dumps core. --- common/key.h | 4 ++++ common/multibyte.h | 2 ++ vi/v_increment.c | 55 +++++++++++++++++++++++++++--------------------------- 3 files changed, 33 insertions(+), 28 deletions(-) diff --git a/common/key.h b/common/key.h index 0988bdea..7ddf2e35 100644 --- a/common/key.h +++ b/common/key.h @@ -51,6 +51,8 @@ typedef u_int ARG_CHAR_T; iswalpha((ch)) #define ISALNUM(ch) \ iswalnum((ch)) +#define ISSPACE(ch) \ + iswspace((ch)) #define CHAR_WIDTH(sp, ch) wcwidth(ch) #define INTISWIDE(c) (!!(c >> 8)) /* XXX wrong name */ #define WS "%ls" @@ -82,6 +84,8 @@ typedef u_int ARG_CHAR_T; isalpha((ch)) #define ISALNUM(ch) \ isalnum((ch)) +#define ISSPACE(ch) \ + isspace((ch)) #define INTISWIDE(c) 0 #define CHAR_WIDTH(sp, ch) 1 #define WS "%s" diff --git a/common/multibyte.h b/common/multibyte.h index 83e7abdb..245edce7 100644 --- a/common/multibyte.h +++ b/common/multibyte.h @@ -16,6 +16,7 @@ typedef u_int UCHAR_T; #define STRTOL wcstol #define STRTOUL wcstoul #define SPRINTF swprintf +#define STRCHR wcschr #define STRCMP wcscmp #define STRPBRK wcspbrk #define TOUPPER towupper @@ -35,6 +36,7 @@ typedef u_char UCHAR_T; #define STRTOL strtol #define STRTOUL strtoul #define SPRINTF snprintf +#define STRCHR strchr #define STRCMP strcmp #define STRPBRK strpbrk #define TOUPPER toupper diff --git a/vi/v_increment.c b/vi/v_increment.c index e9b20dbb..8b21985d 100644 --- a/vi/v_increment.c +++ b/vi/v_increment.c @@ -28,17 +28,17 @@ static const char sccsid[] = "$Id: v_increment.c,v 10.16 2001/06/25 15:19:31 ski #include "../common/common.h" #include "vi.h" -static char * const fmt[] = { +static CHAR_T * const fmt[] = { #define DEC 0 - "%ld", + L("%ld"), #define SDEC 1 - "%+ld", + L("%+ld"), #define HEXC 2 - "0X%0*lX", + L("0X%0*lX"), #define HEXL 3 - "0x%0*lx", + L("0x%0*lx"), #define OCTAL 4 - "%#0*lo", + L("%#0*lo"), }; static void inc_err __P((SCR *, enum nresult)); @@ -57,13 +57,12 @@ v_increment(SCR *sp, VICMD *vp) long change, ltmp, lval; size_t beg, blen, end, len, nlen, wlen; int base, isempty, rval; - char *ntype, nbuf[100]; - CHAR_T *bp, *p, *t; + CHAR_T *bp, *p, *t, *ntype, nbuf[100]; /* Validate the operator. */ - if (vp->character == '#') - vp->character = '+'; - if (vp->character != '+' && vp->character != '-') { + if (vp->character == L('#')) + vp->character = L('+'); + if (vp->character != L('+') && vp->character != L('-')) { v_emsg(sp, vp->kp->usage, VIM_USAGE); return (1); } @@ -90,7 +89,7 @@ v_increment(SCR *sp, VICMD *vp) * implies moving the cursor to its beginning, if we moved, refresh * now. */ - for (beg = vp->m_start.cno; beg < len && isspace(p[beg]); ++beg); + for (beg = vp->m_start.cno; beg < len && ISSPACE(p[beg]); ++beg); if (beg >= len) goto nonum; if (beg != vp->m_start.cno) { @@ -99,9 +98,9 @@ v_increment(SCR *sp, VICMD *vp) } #undef ishex -#define ishex(c) (isdigit(c) || strchr("abcdefABCDEF", c)) +#define ishex(c) (ISDIGIT(c) || STRCHR(L("abcdefABCDEF"), c)) #undef isoctal -#define isoctal(c) (isdigit(c) && (c) != '8' && (c) != '9') +#define isoctal(c) (ISDIGIT(c) && (c) != L('8') && (c) != L('9')) /* * Look for 0[Xx], or leading + or - signs, guess at the base. @@ -110,30 +109,30 @@ v_increment(SCR *sp, VICMD *vp) * the number. */ wlen = len - beg; - if (p[beg] == '0' && wlen > 2 && - (p[beg + 1] == 'X' || p[beg + 1] == 'x')) { + if (p[beg] == L('0') && wlen > 2 && + (p[beg + 1] == L('X') || p[beg + 1] == L('x'))) { base = 16; end = beg + 2; if (!ishex(p[end])) goto decimal; - ntype = p[beg + 1] == 'X' ? fmt[HEXC] : fmt[HEXL]; - } else if (p[beg] == '0' && wlen > 1) { + ntype = p[beg + 1] == L('X') ? fmt[HEXC] : fmt[HEXL]; + } else if (p[beg] == L('0') && wlen > 1) { base = 8; end = beg + 1; if (!isoctal(p[end])) goto decimal; ntype = fmt[OCTAL]; - } else if (wlen >= 1 && (p[beg] == '+' || p[beg] == '-')) { + } else if (wlen >= 1 && (p[beg] == L('+') || p[beg] == L('-'))) { base = 10; end = beg + 1; ntype = fmt[SDEC]; - if (!isdigit(p[end])) + if (!ISDIGIT(p[end])) goto nonum; } else { decimal: base = 10; end = beg; ntype = fmt[DEC]; - if (!isdigit(p[end])) { + if (!ISDIGIT(p[end])) { nonum: msgq(sp, M_ERR, "181|Cursor not in a number"); return (1); } @@ -145,14 +144,14 @@ nonum: msgq(sp, M_ERR, "181|Cursor not in a number"); case 8: if (isoctal(p[end])) continue; - if (p[end] == '8' || p[end] == '9') { + if (p[end] == L('8') || p[end] == L('9')) { base = 10; ntype = fmt[DEC]; continue; } break; case 10: - if (isdigit(p[end])) + if (ISDIGIT(p[end])) continue; break; case 16: @@ -177,7 +176,7 @@ nonum: msgq(sp, M_ERR, "181|Cursor not in a number"); GET_SPACE_RETW(sp, bp, blen, len + 50); if (end == len) { MEMMOVEW(bp, &p[beg], wlen); - bp[wlen] = '\0'; + bp[wlen] = L('\0'); t = bp; } else t = &p[beg]; @@ -189,7 +188,7 @@ nonum: msgq(sp, M_ERR, "181|Cursor not in a number"); if (base == 10) { if ((nret = nget_slong(sp, &lval, t, NULL, 10)) != NUM_OK) goto err; - ltmp = vp->character == '-' ? -change : change; + ltmp = vp->character == L('-') ? -change : change; if (lval > 0 && ltmp > 0 && !NPFITS(LONG_MAX, lval, ltmp)) { nret = NUM_OVER; goto err; @@ -202,11 +201,11 @@ nonum: msgq(sp, M_ERR, "181|Cursor not in a number"); /* If we cross 0, signed numbers lose their sign. */ if (lval == 0 && ntype == fmt[SDEC]) ntype = fmt[DEC]; - nlen = snprintf(nbuf, sizeof(nbuf), ntype, lval); + nlen = SPRINTF(nbuf, SIZE(nbuf), ntype, lval); } else { if ((nret = nget_uslong(sp, &ulval, t, NULL, base)) != NUM_OK) goto err; - if (vp->character == '+') { + if (vp->character == L('+')) { if (!NPFITS(ULONG_MAX, ulval, change)) { nret = NUM_OVER; goto err; @@ -224,7 +223,7 @@ nonum: msgq(sp, M_ERR, "181|Cursor not in a number"); if (base == 16) wlen -= 2; - nlen = snprintf(nbuf, sizeof(nbuf), ntype, wlen, ulval); + nlen = SPRINTF(nbuf, SIZE(nbuf), ntype, wlen, ulval); } /* Build the new line. */ -- 2.11.4.GIT