diff -ru nvi-1.81.6/common/common.h nvi-git/common/common.h --- nvi-1.81.6/common/common.h 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/common.h 2011-10-16 18:36:37.000000000 +0200 @@ -57,7 +57,7 @@ typedef struct _win WIN; /* Autoindent state. */ -typedef enum { C_NOTSET, C_CARATSET, C_NOCHANGE, C_ZEROSET } carat_t; +typedef enum { C_NOTSET, C_CARATSET, C_ZEROSET } carat_t; /* Busy message types. */ typedef enum { BUSY_ON = 1, BUSY_OFF, BUSY_UPDATE } busy_t; diff -ru nvi-1.81.6/common/conv.c nvi-git/common/conv.c --- nvi-1.81.6/common/conv.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/conv.c 2011-10-16 18:36:37.000000000 +0200 @@ -89,7 +89,7 @@ default_char2int(SCR *sp, const char * str, ssize_t len, CONVWIN *cw, size_t *tolen, CHAR_T **dst, char *enc) { - int i = 0, j; + size_t i = 0, j; CHAR_T **tostr = (CHAR_T **)&cw->bp1; size_t *blen = &cw->blen1; mbstate_t mbs; @@ -210,7 +210,7 @@ default_int2char(SCR *sp, const CHAR_T * str, ssize_t len, CONVWIN *cw, size_t *tolen, char **pdst, char *enc) { - int i, j, offset = 0; + size_t i, j, offset = 0; char **tostr = (char **)&cw->bp1; size_t *blen = &cw->blen1; mbstate_t mbs; diff -ru nvi-1.81.6/common/cut.c nvi-git/common/cut.c --- nvi-1.81.6/common/cut.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/cut.c 2011-10-16 18:36:37.000000000 +0200 @@ -101,15 +101,15 @@ copy_one = 1; cb_rotate(sp); } - if ((append = isupper(name)) == 1) { + if ((append = isupper(name))) { if (!copy_one) copy_def = 1; - name = tolower(name); + name = TOLOWER(name); } namecb: CBNAME(sp, cbp, name); } else if (LF_ISSET(CUT_NUMREQ) || LF_ISSET(CUT_NUMOPT) && (LF_ISSET(CUT_LINEMODE) || fm->lno != tm->lno)) { - name = '1'; + name = L('1'); cb_rotate(sp); goto namecb; } else @@ -163,7 +163,7 @@ sp->wp->dcbp = cbp; /* Repoint the default buffer on each pass. */ if (copy_one) { /* Copy into numeric buffer 1. */ - name = '1'; + name = L('1'); CBNAME(sp, cbp, name); copy_one = 0; goto copyloop; @@ -194,31 +194,31 @@ del_cbp = NULL; for (cbp = sp->wp->cutq.lh_first; cbp != NULL; cbp = cbp->q.le_next) switch(cbp->name) { - case '1': - cbp->name = '2'; + case L('1'): + cbp->name = L('2'); break; - case '2': - cbp->name = '3'; + case L('2'): + cbp->name = L('3'); break; - case '3': - cbp->name = '4'; + case L('3'): + cbp->name = L('4'); break; - case '4': - cbp->name = '5'; + case L('4'): + cbp->name = L('5'); break; - case '5': - cbp->name = '6'; + case L('5'): + cbp->name = L('6'); break; - case '6': - cbp->name = '7'; + case L('6'): + cbp->name = L('7'); break; - case '7': - cbp->name = '8'; + case L('7'): + cbp->name = L('8'); break; - case '8': - cbp->name = '9'; + case L('8'): + cbp->name = L('9'); break; - case '9': + case L('9'): del_cbp = cbp; break; } diff -ru nvi-1.81.6/common/cut.h nvi-git/common/cut.h --- nvi-1.81.6/common/cut.h 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/cut.h 2011-10-16 18:36:37.000000000 +0200 @@ -65,7 +65,7 @@ */ #define CBNAME(sp, cbp, nch) { \ CHAR_T L__name; \ - L__name = isupper(nch) ? tolower(nch) : (nch); \ + L__name = ISUPPER(nch) ? TOLOWER(nch) : (nch); \ for (cbp = sp->wp->cutq.lh_first; \ cbp != NULL; cbp = cbp->q.le_next) \ if (cbp->name == L__name) \ diff -ru nvi-1.81.6/common/key.h nvi-git/common/key.h --- nvi-1.81.6/common/key.h 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/key.h 2011-10-16 18:36:37.000000000 +0200 @@ -51,6 +51,8 @@ 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 @@ 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 -ru nvi-1.81.6/common/multibyte.h nvi-git/common/multibyte.h --- nvi-1.81.6/common/multibyte.h 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/multibyte.h 2011-10-16 18:36:37.000000000 +0200 @@ -12,12 +12,15 @@ typedef u_int UCHAR_T; #define RCHAR_BIT 24 +#define ISUPPER iswupper #define STRLEN wcslen #define STRTOL wcstol #define STRTOUL wcstoul #define SPRINTF swprintf +#define STRCHR wcschr #define STRCMP wcscmp #define STRPBRK wcspbrk +#define TOLOWER towlower #define TOUPPER towupper #define STRSET wmemset @@ -31,12 +34,15 @@ typedef u_char UCHAR_T; #define RCHAR_BIT CHAR_BIT +#define ISUPPER isupper #define STRLEN strlen #define STRTOL strtol #define STRTOUL strtoul #define SPRINTF snprintf +#define STRCHR strchr #define STRCMP strcmp #define STRPBRK strpbrk +#define TOLOWER tolower #define TOUPPER toupper #define STRSET memset @@ -48,6 +54,12 @@ memcmp(to, from, (n) * sizeof(*(to))) #define MEMMOVE(p, t, len) memmove(p, t, (len) * sizeof(*(p))) #define MEMCPY(p, t, len) memcpy(p, t, (len) * sizeof(*(p))) +/* + * Like MEMCPY but return a pointer to the end of the copied bytes. + * Glibc has a function mempcpy with the same purpose. + */ +#define MEMPCPY(p, t, len) \ + ((void *)((char *)MEMCPY(p, t, len) + (len) * sizeof(*(p)))) #define SIZE(w) (sizeof(w)/sizeof(*w)) #endif diff -ru nvi-1.81.6/common/recover.c nvi-git/common/recover.c --- nvi-1.81.6/common/recover.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/recover.c 2011-10-16 18:36:37.000000000 +0200 @@ -565,7 +565,7 @@ next: (void)fclose(fp); } if (found == 0) - (void)printf("vi: no files to recover.\n"); + (void)printf("%s: No files to recover\n", sp->gp->progname); (void)closedir(dirp); return (0); } diff -ru nvi-1.81.6/common/search.c nvi-git/common/search.c --- nvi-1.81.6/common/search.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/search.c 2011-10-16 18:36:37.000000000 +0200 @@ -117,8 +117,8 @@ /* Compile the RE. */ if (re_compile(sp, ptrn, plen, &sp->re, &sp->re_len, &sp->re_c, - SEARCH_CSEARCH | LF_ISSET(SEARCH_CSCOPE | SEARCH_IC | - SEARCH_LITERAL | SEARCH_MSG | SEARCH_TAG))) + SEARCH_CSEARCH | LF_ISSET(SEARCH_CSCOPE | SEARCH_EXTEND | + SEARCH_IC | SEARCH_LITERAL | SEARCH_MSG | SEARCH_TAG))) return (1); /* Set the search direction. */ diff -ru nvi-1.81.6/common/util.c nvi-git/common/util.c --- nvi-1.81.6/common/util.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/common/util.c 2011-10-16 18:36:37.000000000 +0200 @@ -92,7 +92,7 @@ return (0); for (cnt = off, p = &p[off], - len -= off; len && isblank(*p); ++cnt, ++p, --len); + len -= off; len && ISBLANK(*p); ++cnt, ++p, --len); /* Set the return. */ *cnop = len ? cnt : cnt - 1; diff -ru nvi-1.81.6/ex/ex_argv.c nvi-git/ex/ex_argv.c --- nvi-1.81.6/ex/ex_argv.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_argv.c 2011-10-16 18:36:37.000000000 +0200 @@ -105,7 +105,7 @@ /* If it's empty, we're done. */ if (len != 0) { for (p = bp, t = bp + len; p < t; ++p) - if (!isblank(*p)) + if (!ISBLANK(*p)) break; if (p == t) goto ret; @@ -186,7 +186,7 @@ break; } else for (; n > 0; --n, ++p) - if (!isblank(*p) && + if (!ISBLANK(*p) && !isalnum(*p) && strchr(mp, *p) != NULL) break; } @@ -739,7 +739,7 @@ rval = SEXP_EXPANSION_ERR; for (p = bp; len; ++p, --len) - if (!isblank(*p)) + if (!ISBLANK(*p)) break; if (len == 0) rval = SEXP_EXPANSION_ERR; diff -ru nvi-1.81.6/ex/ex_display.c nvi-git/ex/ex_display.c --- nvi-1.81.6/ex/ex_display.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_display.c 2011-10-16 18:36:37.000000000 +0200 @@ -25,6 +25,7 @@ #include "../common/common.h" #include "tag.h" +static int is_prefix __P((ARGS *, CHAR_T *)); static int bdisplay __P((SCR *)); static void db __P((SCR *, CB *, u_char *)); @@ -38,33 +39,25 @@ int ex_display(SCR *sp, EXCMD *cmdp) { - switch (cmdp->argv[0]->bp[0]) { - case 'b': -#undef ARG -#define ARG "buffers" - if (cmdp->argv[0]->len >= sizeof(ARG) || - memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len)) + ARGS *arg; + + arg = cmdp->argv[0]; + + switch (arg->bp[0]) { + case L('b'): + if (!is_prefix(arg, L("buffers"))) break; return (bdisplay(sp)); - case 'c': -#undef ARG -#define ARG "connections" - if (cmdp->argv[0]->len >= sizeof(ARG) || - memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len)) + case L('c'): + if (!is_prefix(arg, L("connections"))) break; return (cscope_display(sp)); - case 's': -#undef ARG -#define ARG "screens" - if (cmdp->argv[0]->len >= sizeof(ARG) || - memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len)) + case L('s'): + if (!is_prefix(arg, L("screens"))) break; return (ex_sdisplay(sp)); - case 't': -#undef ARG -#define ARG "tags" - if (cmdp->argv[0]->len >= sizeof(ARG) || - memcmp(cmdp->argv[0]->bp, ARG, cmdp->argv[0]->len)) + case L('t'): + if (!is_prefix(arg, L("tags"))) break; return (ex_tag_display(sp)); } @@ -73,6 +66,17 @@ } /* + * is_prefix -- + * + * Check that a command argument matches a prefix of a given string. + */ +static int +is_prefix(ARGS *arg, CHAR_T *str) +{ + return arg->len <= STRLEN(str) && !MEMCMP(arg->bp, str, arg->len); +} + +/* * bdisplay -- * * Display buffers. diff -ru nvi-1.81.6/ex/ex_join.c nvi-git/ex/ex_join.c --- nvi-1.81.6/ex/ex_join.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_join.c 2011-10-16 18:36:37.000000000 +0200 @@ -36,9 +36,10 @@ { db_recno_t from, to; size_t blen, clen, len, tlen; - int echar, extra, first; + int extra, first; CHAR_T *bp, *tbp; CHAR_T *p; + CHAR_T echar; NEEDFILE(sp, cmdp); @@ -103,8 +104,8 @@ */ extra = 0; if (!first && !FL_ISSET(cmdp->iflags, E_C_FORCE)) { - if (isblank(echar)) - for (; len && isblank(*p); --len, ++p); + if (ISBLANK(echar)) + for (; len && ISBLANK(*p); --len, ++p); else if (p[0] != ')') { if (strchr(".?!", echar)) { *tbp++ = ' '; @@ -113,7 +114,7 @@ } *tbp++ = ' '; ++clen; - for (; len && isblank(*p); --len, ++p); + for (; len && ISBLANK(*p); --len, ++p); } } diff -ru nvi-1.81.6/ex/ex_perl.c nvi-git/ex/ex_perl.c --- nvi-1.81.6/ex/ex_perl.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_perl.c 2011-10-16 18:36:37.000000000 +0200 @@ -51,7 +51,7 @@ if (cmdp->argc != 0) for (p = cmdp->argv[0]->bp, len = cmdp->argv[0]->len; len > 0; --len, ++p) - if (!isblank(*p)) + if (!ISBLANK(*p)) break; if (cmdp->argc == 0 || len == 0) { ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE); diff -ru nvi-1.81.6/ex/ex_subst.c nvi-git/ex/ex_subst.c --- nvi-1.81.6/ex/ex_subst.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_subst.c 2011-10-16 18:36:37.000000000 +0200 @@ -71,7 +71,7 @@ goto subagain; for (p = cmdp->argv[0]->bp, len = cmdp->argv[0]->len; len > 0; --len, ++p) { - if (!isblank(*p)) + if (!ISBLANK(*p)) break; } if (len == 0) diff -ru nvi-1.81.6/ex/ex_txt.c nvi-git/ex/ex_txt.c --- nvi-1.81.6/ex/ex_txt.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_txt.c 2011-10-16 18:36:37.000000000 +0200 @@ -62,6 +62,7 @@ carat_t carat_st; size_t cnt; int rval; + int nochange; rval = 0; @@ -110,7 +111,7 @@ txt_prompt(sp, tp, prompt, flags); } - for (carat_st = C_NOTSET;;) { + for (carat_st = C_NOTSET, nochange = 0;;) { if (v_event_get(sp, &ev, 0, 0)) goto err; @@ -206,7 +207,8 @@ * erased. */ if (LF_ISSET(TXT_AUTOINDENT)) { - if (carat_st == C_NOCHANGE) { + if (nochange) { + nochange = 0; if (v_txt_auto(sp, OOBLNO, &ait, ait.ai, ntp)) goto err; @@ -244,7 +246,7 @@ */ if (LF_ISSET(TXT_CNTRLD)) { for (cnt = 0; cnt < tp->len; ++cnt) - if (!isblank(tp->lb[cnt])) + if (!ISBLANK(tp->lb[cnt])) break; if (cnt == tp->len) { tp->len = 1; @@ -293,7 +295,8 @@ MEMCPYW(ait.lb, tp->lb, tp->ai); ait.ai = ait.len = tp->ai; - carat_st = C_NOCHANGE; + carat_st = C_NOTSET; + nochange = 1; goto leftmargin; case C_ZEROSET: /* 0^D */ if (tp->len > tp->ai + 1) diff -ru nvi-1.81.6/ex/ex_write.c nvi-git/ex/ex_write.c --- nvi-1.81.6/ex/ex_write.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/ex/ex_write.c 2011-10-16 18:36:37.000000000 +0200 @@ -142,7 +142,7 @@ /* Skip any leading whitespace. */ if (cmdp->argc != 0) - for (p = cmdp->argv[0]->bp; *p != '\0' && isblank(*p); ++p); + for (p = cmdp->argv[0]->bp; *p != '\0' && ISBLANK(*p); ++p); /* If "write !" it's a pipe to a utility. */ if (cmdp->argc != 0 && cmd == WRITE && *p == '!') { @@ -153,7 +153,7 @@ } /* Expand the argument. */ - for (++p; *p && isblank(*p); ++p); + for (++p; *p && ISBLANK(*p); ++p); if (*p == '\0') { ex_emsg(sp, cmdp->cmd->usage, EXM_USAGE); return (1); @@ -194,7 +194,7 @@ LF_SET(FS_APPEND); /* Skip ">>" and whitespace. */ - for (p += 2; *p && isblank(*p); ++p); + for (p += 2; *p && ISBLANK(*p); ++p); } /* If no other arguments, just write the file back. */ diff -ru nvi-1.81.6/regex/regcomp.c nvi-git/regex/regcomp.c --- nvi-1.81.6/regex/regcomp.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/regex/regcomp.c 2011-10-16 18:36:37.000000000 +0200 @@ -818,7 +818,7 @@ NEXT(); len = p->next - sp; for (cp = cclasses; cp->name != NULL; cp++) - if (STRLEN(cp->name) == len && MEMCMP(cp->name, sp, len)) + if (STRLEN(cp->name) == len && !MEMCMP(cp->name, sp, len)) break; if (cp->name == NULL) { /* oops, didn't find it */ diff -ru nvi-1.81.6/vi/getc.c nvi-git/vi/getc.c --- nvi-1.81.6/vi/getc.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/getc.c 2011-10-16 18:36:37.000000000 +0200 @@ -121,12 +121,12 @@ int cs_fspace(SCR *sp, VCS *csp) { - if (csp->cs_flags != 0 || !isblank(csp->cs_ch)) + if (csp->cs_flags != 0 || !ISBLANK(csp->cs_ch)) return (0); for (;;) { if (cs_next(sp, csp)) return (1); - if (csp->cs_flags != 0 || !isblank(csp->cs_ch)) + if (csp->cs_flags != 0 || !ISBLANK(csp->cs_ch)) break; } return (0); @@ -145,7 +145,7 @@ if (cs_next(sp, csp)) return (1); if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP || - csp->cs_flags == 0 && isblank(csp->cs_ch)) + csp->cs_flags == 0 && ISBLANK(csp->cs_ch)) continue; break; } @@ -214,7 +214,7 @@ if (cs_prev(sp, csp)) return (1); if (csp->cs_flags == CS_EOL || csp->cs_flags == CS_EMP || - csp->cs_flags == 0 && isblank(csp->cs_ch)) + csp->cs_flags == 0 && ISBLANK(csp->cs_ch)) continue; break; } diff -ru nvi-1.81.6/vi/vi.c nvi-git/vi/vi.c --- nvi-1.81.6/vi/vi.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/vi.c 2011-10-16 18:36:37.000000000 +0200 @@ -1050,7 +1050,7 @@ /* * v_curword -- - * Get the word (or non-word) the cursor is on. + * Get the word (tagstring, actually) the cursor is on. * * PUBLIC: int v_curword __P((SCR *)); */ @@ -1059,7 +1059,7 @@ { VI_PRIVATE *vip; size_t beg, end, len; - int moved, state; + int moved; CHAR_T *p; if (db_get(sp, sp->lno, DBG_FATAL, &p, &len)) @@ -1081,7 +1081,7 @@ * follow the same rule. */ for (moved = 0, - beg = sp->cno; beg < len && isspace(p[beg]); moved = 1, ++beg); + beg = sp->cno; beg < len && ISSPACE(p[beg]); moved = 1, ++beg); if (beg >= len) { msgq(sp, M_BERR, "212|Cursor not in a word"); return (1); @@ -1091,15 +1091,20 @@ (void)vs_refresh(sp, 0); } - /* Find the end of the word. */ - for (state = inword(p[beg]), - end = beg; ++end < len && state == inword(p[end]);); + /* + * Find the end of the word. + * + * !!! + * Historically, vi accepted any non-blank as initial character + * when building up a tagstring. Required by IEEE 1003.1-2001. + */ + for (end = beg; ++end < len && inword(p[end]);); vip = VIP(sp); - len = (end - beg); - BINC_RETW(sp, vip->keyw, vip->klen, len+1); + vip->klen = len = end - beg; + BINC_RETW(sp, vip->keyw, vip->keywlen, len+1); MEMMOVEW(vip->keyw, p + beg, len); - vip->keyw[len] = '\0'; /* XXX */ + vip->keyw[len] = L('\0'); /* XXX */ return (0); } diff -ru nvi-1.81.6/vi/v_increment.c nvi-git/vi/v_increment.c --- nvi-1.81.6/vi/v_increment.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_increment.c 2011-10-16 18:36:37.000000000 +0200 @@ -28,17 +28,17 @@ #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 @@ 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 @@ * 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 @@ } #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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ /* 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 @@ 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. */ diff -ru nvi-1.81.6/vi/v_match.c nvi-git/vi/v_match.c --- nvi-1.81.6/vi/v_match.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_match.c 2011-10-16 18:36:37.000000000 +0200 @@ -161,7 +161,7 @@ if (db_get(sp, mp->lno, DBG_FATAL, &p, &len)) return (1); for (p += mp->cno + 1, len -= mp->cno; --len; ++p) - if (!isblank(*p)) + if (!ISBLANK(*p)) return (0); F_SET(vp, VM_LMODE); return (0); diff -ru nvi-1.81.6/vi/v_replace.c nvi-git/vi/v_replace.c --- nvi-1.81.6/vi/v_replace.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_replace.c 2011-10-16 18:36:37.000000000 +0200 @@ -172,7 +172,7 @@ p += vp->m_start.cno + cnt; len -= vp->m_start.cno + cnt; if (len != 0 && O_ISSET(sp, O_AUTOINDENT)) - for (; len && isblank(*p); --len, ++p); + for (; len && ISBLANK(*p); --len, ++p); if ((tp = text_init(sp, p, len, len)) == NULL) goto err_ret; diff -ru nvi-1.81.6/vi/v_search.c nvi-git/vi/v_search.c --- nvi-1.81.6/vi/v_search.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_search.c 2011-10-16 18:36:37.000000000 +0200 @@ -313,6 +313,32 @@ } /* + * is_especial -- + * Test if the character is special in an extended RE. + */ +static int +is_especial(CHAR_T c) +{ + /* + * !!! + * Right-brace is not an ERE special according to IEEE 1003.1-2001. + * Right-parenthesis is a special character (so quoting doesn't hurt), + * though it has no special meaning in this context, viz. at the + * beginning of the string. So we need not quote it. Then again, + * see the BUGS section in regex/re_format.7. + * The tilde is vi-specific, of course. + */ + return (STRCHR(L(".[\\()*+?{|^$~"), c) && c); +} + +/* + * Rear delimiter for word search when the keyword ends in + * (i.e., consists of) a non-word character. See v_searchw below. + */ +#define RE_NWSTOP L("([^[:alnum:]_]|$)") +#define RE_NWSTOP_LEN (SIZE(RE_NWSTOP) - 1) + +/* * v_searchw -- [count]^A * Search for the word under the cursor. * @@ -321,19 +347,36 @@ int v_searchw(SCR *sp, VICMD *vp) { - size_t blen, len; + size_t blen; + /* An upper bound for the SIZE of the RE under construction. */ + size_t len = VIP(sp)->klen + MAX(RE_WSTART_LEN, 1) + + MAX(RE_WSTOP_LEN, RE_NWSTOP_LEN); int rval; CHAR_T *bp, *p; - len = VIP(sp)->klen + RE_WSTART_LEN + RE_WSTOP_LEN; GET_SPACE_RETW(sp, bp, blen, len); - MEMCPY(bp, RE_WSTART, RE_WSTART_LEN); - p = bp + RE_WSTART_LEN; - MEMCPY(p, VIP(sp)->keyw, VIP(sp)->klen); - p += VIP(sp)->klen; - MEMCPY(p, RE_WSTOP, RE_WSTOP_LEN); + p = bp; + + /* Only the first character can be non-word, see v_curword. */ + if (inword(VIP(sp)->keyw[0])) + p = MEMPCPY(p, RE_WSTART, RE_WSTART_LEN); + else if (is_especial(VIP(sp)->keyw[0])) + p = MEMPCPY(p, L("\\"), 1); + + p = MEMPCPY(p, VIP(sp)->keyw, VIP(sp)->klen); + + if (inword(p[-1])) + p = MEMPCPY(p, RE_WSTOP, RE_WSTOP_LEN); + else + /* + * The keyword is a single non-word character. + * We want it to stay the same when typing ^A several times + * in a row, just the way the other cases behave. + */ + p = MEMPCPY(p, RE_NWSTOP, RE_NWSTOP_LEN); - rval = v_search(sp, vp, bp, len, SEARCH_SET, FORWARD); + len = p - bp; + rval = v_search(sp, vp, bp, len, SEARCH_SET | SEARCH_EXTEND, FORWARD); FREE_SPACEW(sp, bp, blen); return (rval); diff -ru nvi-1.81.6/vi/v_sentence.c nvi-git/vi/v_sentence.c --- nvi-1.81.6/vi/v_sentence.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_sentence.c 2011-10-16 18:36:37.000000000 +0200 @@ -72,7 +72,7 @@ * This may not handle " . " correctly, but it's real unclear * what correctly means in that case. */ - if (cs.cs_flags == CS_EMP || cs.cs_flags == 0 && isblank(cs.cs_ch)) { + if (cs.cs_flags == CS_EMP || cs.cs_flags == 0 && ISBLANK(cs.cs_ch)) { if (cs_fblank(sp, &cs)) return (1); if (--cnt == 0) { @@ -93,7 +93,7 @@ if (cs_next(sp, &cs)) return (1); if (cs.cs_flags == 0 && - isblank(cs.cs_ch) && cs_fblank(sp, &cs)) + ISBLANK(cs.cs_ch) && cs_fblank(sp, &cs)) return (1); goto okret; } @@ -233,11 +233,11 @@ if (cs.cs_flags != CS_EOL) break; } - } else if (cs.cs_flags == 0 && !isblank(cs.cs_ch)) + } else if (cs.cs_flags == 0 && !ISBLANK(cs.cs_ch)) for (;;) { if (cs_prev(sp, &cs)) return (1); - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; } @@ -280,7 +280,7 @@ } while (!cs.cs_flags && (cs.cs_ch == ')' || cs.cs_ch == ']' || cs.cs_ch == '"' || cs.cs_ch == '\'')); - if ((cs.cs_flags || isblank(cs.cs_ch)) && + if ((cs.cs_flags || ISBLANK(cs.cs_ch)) && cs_fblank(sp, &cs)) return (1); @@ -303,7 +303,7 @@ return (1); if (cs.cs_flags == CS_EOL) continue; - if (cs.cs_flags == 0 && isblank(cs.cs_ch)) + if (cs.cs_flags == 0 && ISBLANK(cs.cs_ch)) continue; break; } @@ -321,7 +321,7 @@ break; default: last = - cs.cs_flags == CS_EOL || isblank(cs.cs_ch) || + cs.cs_flags == CS_EOL || ISBLANK(cs.cs_ch) || cs.cs_ch == ')' || cs.cs_ch == ']' || cs.cs_ch == '"' || cs.cs_ch == '\'' ? 1 : 0; } diff -ru nvi-1.81.6/vi/vs_smap.c nvi-git/vi/vs_smap.c --- nvi-1.81.6/vi/vs_smap.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/vs_smap.c 2011-10-16 18:36:37.000000000 +0200 @@ -224,6 +224,16 @@ top: HMAP->lno = lno; HMAP->coff = 0; HMAP->soff = 1; + } else { + /* + * If number of lines HMAP->lno (top line) spans + * changed due to, say reformatting, and now is + * fewer than HMAP->soff, reset so the line is + * redrawn at the top of the screen. + */ + cnt = vs_screens(sp, HMAP->lno, NULL); + if (cnt < HMAP->soff) + HMAP->soff = 1; } /* If we fail, just punt. */ for (p = HMAP, cnt = sp->t_rows; --cnt; ++p) diff -ru nvi-1.81.6/vi/v_txt.c nvi-git/vi/v_txt.c --- nvi-1.81.6/vi/v_txt.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_txt.c 2011-10-16 18:36:37.000000000 +0200 @@ -275,6 +275,7 @@ int showmatch; /* Showmatch set on this character. */ int wm_set, wm_skip; /* Wrapmargin happened, blank skip flags. */ int max, tmp; + int nochange; CHAR_T *p; gp = sp->gp; @@ -458,6 +459,7 @@ /* Other text input mode setup. */ quote = Q_NOTSET; carat = C_NOTSET; + nochange = 0; FL_INIT(is_flags, LF_ISSET(TXT_SEARCHINCR) ? IS_RESTART | IS_RUNNING : 0); filec_redraw = hexcnt = showmatch = 0; @@ -748,16 +750,16 @@ owrite = tp->owrite; insert = tp->insert; if (LF_ISSET(TXT_REPLACE) && owrite != 0) { - for (p = tp->lb + tp->cno; owrite > 0 && isblank(*p); + for (p = tp->lb + tp->cno; owrite > 0 && ISBLANK(*p); ++p, --owrite, ++tp->R_erase); if (owrite == 0) - for (; insert > 0 && isblank(*p); + for (; insert > 0 && ISBLANK(*p); ++p, ++tp->R_erase, --insert); } else { p = tp->lb + tp->cno + owrite; if (O_ISSET(sp, O_AUTOINDENT)) for (; insert > 0 && - isblank(*p); ++p, --insert); + ISBLANK(*p); ++p, --insert); owrite = 0; } @@ -785,7 +787,8 @@ * characters may have been erased. */ if (LF_ISSET(TXT_AUTOINDENT)) { - if (carat == C_NOCHANGE) { + if (nochange) { + nochange = 0; if (v_txt_auto(sp, OOBLNO, &ait, ait.ai, ntp)) goto err; FREE_SPACEW(sp, ait.lb, ait.lb_len); @@ -958,7 +961,8 @@ MEMMOVEW(ait.lb, tp->lb, tp->ai); ait.ai = ait.len = tp->ai; - carat = C_NOCHANGE; + carat = C_NOTSET; + nochange = 1; goto leftmargin; case C_ZEROSET: /* 0^D */ if (tp->ai == 0 || tp->cno > tp->ai + tp->offset + 1) @@ -1075,7 +1079,7 @@ } /* Skip over trailing space characters. */ - while (tp->cno > max && isblank(tp->lb[tp->cno - 1])) { + while (tp->cno > max && ISBLANK(tp->lb[tp->cno - 1])) { --tp->cno; ++tp->owrite; } @@ -1108,7 +1112,7 @@ ++tp->owrite; if (FL_ISSET(is_flags, IS_RUNNING)) tp->lb[tp->cno] = ' '; - if (isblank(tp->lb[tp->cno - 1])) + if (ISBLANK(tp->lb[tp->cno - 1])) break; } else { @@ -1117,7 +1121,7 @@ ++tp->owrite; if (FL_ISSET(is_flags, IS_RUNNING)) tp->lb[tp->cno] = ' '; - if (isblank(tp->lb[tp->cno - 1])) + if (ISBLANK(tp->lb[tp->cno - 1])) break; } if (tp->cno > max) @@ -1128,7 +1132,7 @@ if (FL_ISSET(is_flags, IS_RUNNING)) tp->lb[tp->cno] = ' '; if (tmp != inword(tp->lb[tp->cno - 1]) - || isblank(tp->lb[tp->cno - 1])) + || ISBLANK(tp->lb[tp->cno - 1])) break; } } @@ -1287,7 +1291,7 @@ goto resolve; } } - if (isblank(evp->e_c) && UNMAP_TST) + if (ISBLANK(evp->e_c) && UNMAP_TST) txt_unmap(sp, tp, &ec_flags); } if (abb != AB_NOTSET) @@ -1337,7 +1341,7 @@ if (txt_margin(sp, tp, &wmt, &tmp, flags)) goto err; if (tmp) { - if (isblank(evp->e_c)) + if (ISBLANK(evp->e_c)) wm_skip = 1; wm_set = 1; goto k_cr; @@ -1503,7 +1507,7 @@ off = tp->cno - 1; /* Previous character. */ p = tp->lb + off; len = 1; /* One character test. */ - if (off == tp->offset || isblank(p[-1])) + if (off == tp->offset || ISBLANK(p[-1])) goto search; if (inword(p[-1])) /* Move backward to change. */ for (;;) { @@ -1515,7 +1519,7 @@ for (;;) { --off; --p; ++len; if (off == tp->offset || - inword(p[-1]) || isblank(p[-1])) + inword(p[-1]) || ISBLANK(p[-1])) break; } @@ -1639,7 +1643,7 @@ /* Find the beginning of this "word". */ for (off = tp->cno - 1, p = tp->lb + off, len = 0;; --p, --off) { - if (isblank(*p)) { + if (ISBLANK(*p)) { ++p; break; } @@ -1706,7 +1710,7 @@ /* Figure out the last screen column. */ for (p = tp->lb, scno = 0, len = tp->len, - spaces = tab_after_sp = 0; len-- && isblank(*p); ++p) + spaces = tab_after_sp = 0; len-- && ISBLANK(*p); ++p) if (*p == '\t') { if (spaces) tab_after_sp = 1; @@ -1781,7 +1785,7 @@ /* Count whitespace characters. */ for (p = t; len > 0; ++p, --len) - if (!isblank(*p)) + if (!ISBLANK(*p)) break; /* Set count, check for no indentation. */ @@ -2008,7 +2012,7 @@ } else retry: for (len = 0, off = tp->cno - 1, p = tp->lb + off;; --off, --p) { - if (isblank(*p)) { + if (ISBLANK(*p)) { ++p; break; } @@ -2783,7 +2787,7 @@ /* Find the nearest previous blank. */ for (off = tp->cno - 1, p = tp->lb + off, len = 0;; --off, --p, ++len) { - if (isblank(*p)) { + if (ISBLANK(*p)) { wp = p + 1; break; } @@ -2835,7 +2839,7 @@ * Delete any trailing whitespace from the current line. */ for (;; --p, --off) { - if (!isblank(*p)) + if (!ISBLANK(*p)) break; --tp->cno; --tp->len; diff -ru nvi-1.81.6/vi/v_util.c nvi-git/vi/v_util.c --- nvi-1.81.6/vi/v_util.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_util.c 2011-10-16 18:36:37.000000000 +0200 @@ -123,7 +123,7 @@ v_isempty(CHAR_T *p, size_t len) { for (; len--; ++p) - if (!isblank(*p)) + if (!ISBLANK(*p)) return (0); return (1); } diff -ru nvi-1.81.6/vi/v_word.c nvi-git/vi/v_word.c --- nvi-1.81.6/vi/v_word.c 2007-11-18 17:41:42.000000000 +0100 +++ nvi-git/vi/v_word.c 2011-10-16 18:36:37.000000000 +0200 @@ -118,7 +118,7 @@ * counts as a single word move. If it's a motion command, * don't move off the end of the line. */ - if (cs.cs_flags == CS_EMP || cs.cs_flags == 0 && isblank(cs.cs_ch)) { + if (cs.cs_flags == CS_EMP || cs.cs_flags == 0 && ISBLANK(cs.cs_ch)) { if (ISMOTION(vp) && cs.cs_flags != CS_EMP && cnt == 1) { if (ISCMD(vp->rkp, 'c')) return (0); @@ -146,7 +146,7 @@ return (1); if (cs.cs_flags == CS_EOF) goto ret; - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; } /* @@ -178,7 +178,7 @@ return (1); if (cs.cs_flags == CS_EOF) goto ret; - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; if (state == INWORD) { if (!inword(cs.cs_ch)) @@ -197,7 +197,7 @@ } /* Eat whitespace characters. */ - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) if (cs_fblank(sp, &cs)) return (1); if (cs.cs_flags == CS_EOF) @@ -277,10 +277,10 @@ * it. (This doesn't count as a word move.) Stay at the character * past the current one, it sets word "state" for the 'e' command. */ - if (cs.cs_flags == 0 && !isblank(cs.cs_ch)) { + if (cs.cs_flags == 0 && !ISBLANK(cs.cs_ch)) { if (cs_next(sp, &cs)) return (1); - if (cs.cs_flags == 0 && !isblank(cs.cs_ch)) + if (cs.cs_flags == 0 && !ISBLANK(cs.cs_ch)) goto start; } if (cs_fblank(sp, &cs)) @@ -299,7 +299,7 @@ return (1); if (cs.cs_flags == CS_EOF) goto ret; - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; } /* @@ -328,7 +328,7 @@ return (1); if (cs.cs_flags == CS_EOF) goto ret; - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; if (state == INWORD) { if (!inword(cs.cs_ch)) @@ -345,7 +345,7 @@ } /* Eat whitespace characters. */ - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) if (cs_fblank(sp, &cs)) return (1); if (cs.cs_flags == CS_EOF) @@ -424,10 +424,10 @@ * character before the current one, it sets word "state" for the * 'b' command. */ - if (cs.cs_flags == 0 && !isblank(cs.cs_ch)) { + if (cs.cs_flags == 0 && !ISBLANK(cs.cs_ch)) { if (cs_prev(sp, &cs)) return (1); - if (cs.cs_flags == 0 && !isblank(cs.cs_ch)) + if (cs.cs_flags == 0 && !ISBLANK(cs.cs_ch)) goto start; } if (cs_bblank(sp, &cs)) @@ -446,7 +446,7 @@ return (1); if (cs.cs_flags == CS_SOF) goto ret; - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; } /* @@ -475,7 +475,7 @@ return (1); if (cs.cs_flags == CS_SOF) goto ret; - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) break; if (state == INWORD) { if (!inword(cs.cs_ch)) @@ -492,7 +492,7 @@ } /* Eat whitespace characters. */ - if (cs.cs_flags != 0 || isblank(cs.cs_ch)) + if (cs.cs_flags != 0 || ISBLANK(cs.cs_ch)) if (cs_bblank(sp, &cs)) return (1); if (cs.cs_flags == CS_SOF)