#!/bin/sh -e
# Generated by patch2vi from unified diff
# Available separators: 0003-0010 0013-0014 0016-0037 0102-0104 0107-0110 0112 0115-0116 0120-0122 0124-0132 0136 0177-0377

# Pass any argument to use patch(1) instead of nextvi ex commands
if [ -n "$1" ]; then
    sed '1,/^=== PATCH2VI PATCH ===$/d' "$0" | patch -p1 --merge=diff3
    exit $?
fi

VI=${VI:-vi}
if ! $VI -? 2>&1 | grep -q 'Nextvi'; then
    echo "Error: $VI is not nextvi" >&2
    echo "Set VI environment variable to point to nextvi binary" >&2
    exit 1
fi

SEP="$(printf '\001')"
ESC="$(printf '\002')"
# Command that handles readability line breaks
LB="0?"
# Phase 1 (search/mark): errors disabled by default,
# DBG1=1 enables error reporting, QF1=1 quits on failure
# OK1: with DBG1=1 also report fallback anchor successes
[ "$DBG1" = "1" ] && OK1= || OK1="0?"
[ "$DBG1" = "1" ] && DBG1= || DBG1="0?"
[ "$QF1" = "1" ] && QF1="${ESC}${SEP}vis 2${ESC}${SEP}q!1" || QF1=
# Phase 2 (edits): DBG2=1 disables errors, QF2=1 ignores them
# OK2: with DBG2= also report fallback substitute successes
[ "$DBG2" = "1" ] && OK2="0?" || OK2=
[ "$DBG2" = "1" ] && DBG2="0?" || DBG2=
[ "$QF2" = "1" ] && QF2= || QF2="${ESC}${SEP}vis 2${ESC}${SEP}q!1"
# Enters vi at failing code line in this script
# Designed for state inspection mid execution
[ "$INTR" = "1" ] && INTR="${ESC}${SEP}|sc|${ESC}${SEP}vis 2:fr 0:e $0:83reg %@47:%f> %@112:&Q:b0:|sc! ${ESC}${ESC}${ESC}${SEP}|:vis 3${ESC}${SEP}q1" || INTR=

# Patch: led.c ren.c uc.c vi.c
# Body too large for EXINIT/argv: stage it in a file
( : > /tmp/p2vi.$$ ) 2>/dev/null && P2VIF=/tmp/p2vi.$$ || P2VIF=./p2vi.$$
trap 'rm -f "$P2VIF"' EXIT
printf '%s\n' "|sc! ${ESC}${SEP}|:vis 3${SEP}fr 98${SEP}b0${SEP}%ya 98${SEP}?${ESC}${SEP}${LB}
${ESC}${SEP}%f> 
int dstrlen\\(const char \\*s, char delim\\)
\\{
	register const char \\*i;
	for \\(i=s; \\*i && \\*i != delim; \\+\\+i\\);
	return i-s;${ESC}${SEP}1??${ESC}${SEP}${LB}
${ESC}${SEP}1??+2m 1${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}%f> 
int dstrlen\\(const char \\*s, char delim\\)
\\{${ESC}${SEP}3??${ESC}${SEP}${LB}
${ESC}${SEP}3??+2m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK led.c:6:a3${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}grp 1${ESC}${SEP}%f> .*?
int dstrlen\\(const char \\*s, char delim\\).*?
(\\{)${ESC}${SEP}7??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}7??m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK led.c:6:a7${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> static sbuf \\*suggestsb;
static sbuf \\*acsb;
sbuf \\*led_attsb;.*(	if \\(!\\*pattern\\))
		return 0;
	sbuf_cut\\(suggestsb, 0\\)${ESC}${SEP}8??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}8??-8m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK led.c:6:a8${ESC}${SEP}'0${SEP}${LB}
${SEP}1;3;7;8??!${DBG1:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL led.c:6${ESC}${SEP}pr${INTR}${QF1}}${SEP}${LB}
${SEP}?${ESC}${SEP}${LB}
${ESC}${SEP}%f+ 	register const char \\*i;
	for \\(i=s; \\*i && \\*i != delim; \\+\\+i\\);
	return i-s;
}

static int search\\(const char \\*pattern, int l\\)${ESC}${SEP}1??${ESC}${SEP}${LB}
${ESC}${SEP}1??+2m 2${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}%f+ 	register const char \\*i;
	for \\(i=s; \\*i && \\*i != delim; \\+\\+i\\);
	return i-s;${ESC}${SEP}3??${ESC}${SEP}${LB}
${ESC}${SEP}3??+2m 2${ESC}${ESC}${ESC}${SEP}${OK1}p OK led.c:9:a3${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}grp 1${ESC}${SEP}%f+ 	register const char \\*i;.*?
	for \\(i=s; \\*i && \\*i != delim; \\+\\+i\\);.*?
(	return i-s;)${ESC}${SEP}7??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}7??m 2${ESC}${ESC}${ESC}${SEP}${OK1}p OK led.c:9:a7${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> static sbuf \\*suggestsb;
static sbuf \\*acsb;
sbuf \\*led_attsb;.*(	if \\(!\\*pattern\\))
		return 0;
	sbuf_cut\\(suggestsb, 0\\)${ESC}${SEP}8??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}8??-5m 2${ESC}${ESC}${ESC}${SEP}${OK1}p OK led.c:9:a8${ESC}${SEP}'0${SEP}${LB}
${SEP}1;3;7;8??!${DBG1:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL led.c:9${ESC}${SEP}pr${INTR}${QF1}}${SEP}${LB}
${SEP}${LB}
${SEP}'1i #ifdef __SSE2__
	const char *i = s;
	/* scalar prefix until 16-byte aligned */
	while (((uintptr_t)i & 15) && *i && *i != delim)
		i++;
	if (!*i || *i == delim)
		return i - s;
	__m128i vd = _mm_set1_epi8(delim);
	__m128i vz = _mm_setzero_si128();
	for (;;) {
		__m128i c = _mm_load_si128((const __m128i *)i);
		int mask = _mm_movemask_epi8(
			_mm_or_si128(_mm_cmpeq_epi8(c, vd), _mm_cmpeq_epi8(c, vz)));
		if (mask)
			return i + __builtin_ctz(mask) - s;
		i += 16;
	}
#else
${SEP}??!${DBG2:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL led.c:6:m1${ESC}${SEP}pr${INTR}${QF2}}${SEP}${LB}
${SEP}'2i #endif
${SEP}??!${DBG2:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL led.c:9:m2${ESC}${SEP}pr${INTR}${QF2}}${SEP}b1${SEP}%ya 98${SEP}?${ESC}${SEP}${LB}
${ESC}${SEP}%f> 		rstate->holelen = uc_len\\(ss\\);
		memcpy\\(rstate->nullhole, ss, rstate->holelen\\);
		memset\\(ss, 0, rstate->holelen\\);
	} else
		for \\(n = 0; \\(l = uc_len\\(ss\\)\\); n\\+\\+\\)
			ss \\+= l;${ESC}${SEP}1??${ESC}${SEP}${LB}
${ESC}${SEP}1??+3m 1${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}%f> 	} else
		for \\(n = 0; \\(l = uc_len\\(ss\\)\\); n\\+\\+\\)
			ss \\+= l;${ESC}${SEP}2??${ESC}${SEP}${LB}
${ESC}${SEP}2??m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a2${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}%f> 		rstate->holelen = uc_len\\(ss\\);
		memcpy\\(rstate->nullhole, ss, rstate->holelen\\);
		memset\\(ss, 0, rstate->holelen\\);${ESC}${SEP}3??${ESC}${SEP}${LB}
${ESC}${SEP}3??+3m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a3${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}%f> 	} else
		for \\(n = 0; \\(l = uc_len\\(ss\\)\\); n\\+\\+\\)${ESC}${SEP}4??${ESC}${SEP}${LB}
${ESC}${SEP}4??m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a4${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP};0${ESC}${SEP}fr${ESC}${SEP}.,\$f> ^			ss \\+= l;\$${ESC}${SEP}5??${ESC}${SEP}${LB}
${ESC}${SEP}5??-2m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a5${ESC}${ESC}${ESC}${SEP}fr 98${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}fr 98${ESC}${SEP}${LB}
${ESC}${SEP}%f> ...s.a....h.....n = .._.e..ss\\).
..m..c......a.e.>n..l..l..........at.-.h....en..
	....s...... ................e...
.}....e
	.... \\(......... ...c.l.n....\\)..n.\\+\\)
.	.s......;${ESC}${SEP}6??${ESC}${SEP}${LB}
${ESC}${SEP}6??+3m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a6${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}grp 1${ESC}${SEP}%f> 		rstate->holelen = uc_len\\(ss\\);.*?
		memcpy\\(rstate->nullhole, ss, rstate->holelen\\);.*?
		memset\\(ss, 0, rstate->holelen\\);.*?
(	} else)${ESC}${SEP}7??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}7??m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a7${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> 		max = \\(unsigned int\\)xlim;
		for \\(n = 0; n < max && \\(l = uc_len\\(ss\\)\\); n\\+\\+\\)
			ss \\+= l;.*(	int \\*off = &pos\\[b];)
	char \\*\\*chrs = \\(char\\*\\*\\)&off\\[b];
	if \\(xorder && dir_reorder\\(s, ss, off, n, rstate->ctx\\)\\) \\{${ESC}${SEP}8??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}8??-6m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a8${ESC}${SEP}'0${ESC}${SEP}8??${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> 	unsigned int n, max, l;
	char \\*ss = s;
	if \\(xlim >= 0 && rstate == rstates\\+1\\) \\{.*(		for \\(i = 0; i < b; i\\+\\+\\) \\{)
			chrs\\[i] = s;
			s \\+= uc_len\\(s\\);${ESC}${SEP}9??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}9??-9m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:111:a9${ESC}${SEP}'0${SEP}${LB}
${SEP}1;2;3;4;5;6;7;8;9??!${DBG1:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL ren.c:111${ESC}${SEP}pr${INTR}${QF1}}${SEP}${LB}
${SEP}?${ESC}${SEP}${LB}
${ESC}${SEP}%f+ 			ss \\+= l;
	unsigned int b = n \\+ 1, c = 2, i;
	int cpos = 0, wid, \\*col;
	int \\*pos = emalloc\\(\\(b \\* 2 \\* sizeof\\(pos\\[0]\\)\\) \\+ b \\* sizeof\\(char\\*\\)\\);${ESC}${SEP}1??${ESC}${SEP}${LB}
${ESC}${SEP}1??m 2${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP};0${ESC}${SEP}fr${ESC}${SEP}.,\$f+ ^			ss \\+= l;\$${ESC}${SEP}3??${ESC}${SEP}${LB}
${ESC}${SEP}3??m 2${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:113:a3${ESC}${ESC}${ESC}${SEP}fr 98${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}fr 98${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> 		max = \\(unsigned int\\)xlim;
		for \\(n = 0; n < max && \\(l = uc_len\\(ss\\)\\); n\\+\\+\\)
			ss \\+= l;.*(	int \\*off = &pos\\[b];)
	char \\*\\*chrs = \\(char\\*\\*\\)&off\\[b];
	if \\(xorder && dir_reorder\\(s, ss, off, n, rstate->ctx\\)\\) \\{${ESC}${SEP}8??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}8??-4m 2${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:113:a8${ESC}${SEP}'0${ESC}${SEP}8??${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> 	unsigned int n, max, l;
	char \\*ss = s;
	if \\(xlim >= 0 && rstate == rstates\\+1\\) \\{.*(		for \\(i = 0; i < b; i\\+\\+\\) \\{)
			chrs\\[i] = s;
			s \\+= uc_len\\(s\\);${ESC}${SEP}9??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}9??-7m 2${ESC}${ESC}${ESC}${SEP}${OK1}p OK ren.c:113:a9${ESC}${SEP}'0${SEP}${LB}
${SEP}1;3;8;9??!${DBG1:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL ren.c:113${ESC}${SEP}pr${INTR}${QF1}}${SEP}${LB}
${SEP}${LB}
${SEP}'1,#+1c 	} else {
		n = 0;
#ifdef __SSE2__
		if (utf8_length[0xc0] != 1) {
			__m128i v_mask = _mm_set1_epi8((char)0xc0);
			__m128i v_cont = _mm_set1_epi8((char)0x80);
			__m128i v_zero = _mm_setzero_si128();
			/* align to 16 bytes for safe page-boundary loads */
			while ((uintptr_t)ss & 15) {
				l = uc_len(ss);
				if (!l)
					goto count_done;
				n++;
				ss += l;
			}
			for (;;) {
				__m128i chunk = _mm_load_si128((const __m128i*)ss);
				int null_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(chunk, v_zero));
				__m128i masked = _mm_and_si128(chunk, v_mask);
				int cont_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(masked, v_cont));
				if (null_mask) {
					int end = __builtin_ctz(null_mask);
					int valid = (1 << end) - 1;
					n += __builtin_popcount(~cont_mask & valid);
					ss += end;
					goto count_done;
				}
				n += 16 - __builtin_popcount(cont_mask);
				ss += 16;
			}
		} else
#endif
		for (; (l = uc_len(ss)); n++)
${SEP}??!${DBG2:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL ren.c:111:m1${ESC}${SEP}pr${INTR}${QF2}}${SEP}${LB}
${SEP}'2i count_done:;
	}
${SEP}??!${DBG2:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL ren.c:113:m2${ESC}${SEP}pr${INTR}${QF2}}${SEP}b2${SEP}%ya 98${SEP}?${ESC}${SEP}${LB}
${ESC}${SEP}%f> int uc_slen\\(char \\*s\\)
\\{
	int n = 0, l;
	for \\(; \\(l = uc_len\\(s\\)\\); n\\+\\+\\)
		s \\+= l;
	return n;${ESC}${SEP}1??${ESC}${SEP}${LB}
${ESC}${SEP}1??+2m 1${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}%f> int uc_slen\\(char \\*s\\)
\\{
	int n = 0, l;${ESC}${SEP}3??${ESC}${SEP}${LB}
${ESC}${SEP}3??+2m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK uc.c:24:a3${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}grp 1${ESC}${SEP}%f> int uc_slen\\(char \\*s\\).*?
\\{.*?
(	int n = 0, l;)${ESC}${SEP}7??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}7??m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK uc.c:24:a7${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> 	/\\* E \\*/ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
	/\\* F \\*/ 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1
};.*(/\\* find the beginning of the character at s\\[i] \\*/)
char \\*uc_beg\\(char \\*beg, char \\*s\\)
\\{${ESC}${SEP}8??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}8??-6m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK uc.c:24:a8${ESC}${SEP}'0${ESC}${SEP}8??${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP}m 0${ESC}${SEP}1;0${ESC}${SEP}grp 1${ESC}${SEP}%f> 	/\\* B \\*/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	/\\* C \\*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
	/\\* D \\*/ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,.*(	if \\(utf8_length\\[0xc0] == 1\\))
		return s;
	for \\(; s > beg && \\(\\(unsigned char\\)\\*s & 0xc0\\) == 0x80; s--\\);${ESC}${SEP}9??${ESC}${SEP}${LB}
${ESC}${SEP}grp 0${ESC}${SEP}9??-9m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK uc.c:24:a9${ESC}${SEP}'0${SEP}${LB}
${SEP}1;3;7;8;9??!${DBG1:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL uc.c:24${ESC}${SEP}pr${INTR}${QF1}}${SEP}${LB}
${SEP}${LB}
${SEP}'1i #ifdef __SSE2__
	if (utf8_length[0xc0] != 1) {
		__m128i v_mask = _mm_set1_epi8((char)0xc0);
		__m128i v_cont = _mm_set1_epi8((char)0x80);
		__m128i v_zero = _mm_setzero_si128();
		while ((uintptr_t)s & 15) {
			l = uc_len(s);
			if (!l)
				return n;
			n++;
			s += l;
		}
		for (;;) {
			__m128i chunk = _mm_load_si128((const __m128i*)s);
			int null_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(chunk, v_zero));
			__m128i masked = _mm_and_si128(chunk, v_mask);
			int cont_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(masked, v_cont));
			if (null_mask) {
				int end = __builtin_ctz(null_mask);
				int valid = (1 << end) - 1;
				return n + __builtin_popcount(~cont_mask & valid);
			}
			n += 16 - __builtin_popcount(cont_mask);
			s += 16;
		}
		return n;
	}
#endif
${SEP}??!${DBG2:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL uc.c:24:m1${ESC}${SEP}pr${INTR}${QF2}}${SEP}b3${SEP}%ya 98${SEP}?${ESC}${SEP}${LB}
${ESC}${SEP}%f> #include <ctype\\.h>
#include <fcntl\\.h>
#include <stdio\\.h>${ESC}${SEP}1??${ESC}${SEP}${LB}
${ESC}${SEP}1??m 1${ESC}${ESC}${ESC}${SEP}1q${ESC}${SEP}${LB}
${ESC}${SEP};0${ESC}${SEP}fr${ESC}${SEP}.,\$f> ^#include <ctype\\.h>\$${ESC}${SEP}3??${ESC}${SEP}${LB}
${ESC}${SEP}3??m 1${ESC}${ESC}${ESC}${SEP}${OK1}p OK vi.c:0:a3${ESC}${ESC}${ESC}${SEP}fr 98${ESC}${SEP}fr 98${SEP}${LB}
${SEP}1;3??!${DBG1:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL vi.c:0${ESC}${SEP}pr${INTR}${QF1}}${SEP}${LB}
${SEP}${LB}
${SEP}'1-1i #ifdef __SSE2__
#include <stdint.h>
#include <emmintrin.h>
#endif
${SEP}??!${DBG2:-ya!112${ESC}${SEP}prp${ESC}${SEP}p FAIL vi.c:0:m1${ESC}${SEP}pr${INTR}${QF2}}${SEP}vis 2${SEP}b0${SEP}w${SEP}b1${SEP}w${SEP}b2${SEP}w${SEP}b3${SEP}w${SEP}2q" > "$P2VIF"
EXINIT='%ya 97:? %@97' $VI -e 'led.c' 'ren.c' 'uc.c' 'vi.c' "$P2VIF"

exit 0
=== PATCH2VI DELTA ===
=== PATCH2VI PATCH ===
diff --git a/led.c b/led.c
index 96d2e3ba..838bcd9d 100644
--- a/led.c
+++ b/led.c
@@ -4,9 +4,28 @@ sbuf *led_attsb;
 
 int dstrlen(const char *s, char delim)
 {
+#ifdef __SSE2__
+	const char *i = s;
+	/* scalar prefix until 16-byte aligned */
+	while (((uintptr_t)i & 15) && *i && *i != delim)
+		i++;
+	if (!*i || *i == delim)
+		return i - s;
+	__m128i vd = _mm_set1_epi8(delim);
+	__m128i vz = _mm_setzero_si128();
+	for (;;) {
+		__m128i c = _mm_load_si128((const __m128i *)i);
+		int mask = _mm_movemask_epi8(
+			_mm_or_si128(_mm_cmpeq_epi8(c, vd), _mm_cmpeq_epi8(c, vz)));
+		if (mask)
+			return i + __builtin_ctz(mask) - s;
+		i += 16;
+	}
+#else
 	register const char *i;
 	for (i=s; *i && *i != delim; ++i);
 	return i-s;
+#endif
 }
 
 static int search(const char *pattern, int l)
diff --git a/ren.c b/ren.c
index 4fd79fba..54f9f22f 100644
--- a/ren.c
+++ b/ren.c
@@ -108,9 +108,42 @@ ren_state *ren_position(char *s)
 		rstate->holelen = uc_len(ss);
 		memcpy(rstate->nullhole, ss, rstate->holelen);
 		memset(ss, 0, rstate->holelen);
-	} else
-		for (n = 0; (l = uc_len(ss)); n++)
+	} else {
+		n = 0;
+#ifdef __SSE2__
+		if (utf8_length[0xc0] != 1) {
+			__m128i v_mask = _mm_set1_epi8((char)0xc0);
+			__m128i v_cont = _mm_set1_epi8((char)0x80);
+			__m128i v_zero = _mm_setzero_si128();
+			/* align to 16 bytes for safe page-boundary loads */
+			while ((uintptr_t)ss & 15) {
+				l = uc_len(ss);
+				if (!l)
+					goto count_done;
+				n++;
+				ss += l;
+			}
+			for (;;) {
+				__m128i chunk = _mm_load_si128((const __m128i*)ss);
+				int null_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(chunk, v_zero));
+				__m128i masked = _mm_and_si128(chunk, v_mask);
+				int cont_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(masked, v_cont));
+				if (null_mask) {
+					int end = __builtin_ctz(null_mask);
+					int valid = (1 << end) - 1;
+					n += __builtin_popcount(~cont_mask & valid);
+					ss += end;
+					goto count_done;
+				}
+				n += 16 - __builtin_popcount(cont_mask);
+				ss += 16;
+			}
+		} else
+#endif
+		for (; (l = uc_len(ss)); n++)
 			ss += l;
+count_done:;
+	}
 	unsigned int b = n + 1, c = 2, i;
 	int cpos = 0, wid, *col;
 	int *pos = emalloc((b * 2 * sizeof(pos[0])) + b * sizeof(char*));
diff --git a/uc.c b/uc.c
index b1002c4e..e1637ca5 100644
--- a/uc.c
+++ b/uc.c
@@ -22,6 +22,34 @@ unsigned char utf8_length[256] = {
 int uc_slen(char *s)
 {
 	int n = 0, l;
+#ifdef __SSE2__
+	if (utf8_length[0xc0] != 1) {
+		__m128i v_mask = _mm_set1_epi8((char)0xc0);
+		__m128i v_cont = _mm_set1_epi8((char)0x80);
+		__m128i v_zero = _mm_setzero_si128();
+		while ((uintptr_t)s & 15) {
+			l = uc_len(s);
+			if (!l)
+				return n;
+			n++;
+			s += l;
+		}
+		for (;;) {
+			__m128i chunk = _mm_load_si128((const __m128i*)s);
+			int null_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(chunk, v_zero));
+			__m128i masked = _mm_and_si128(chunk, v_mask);
+			int cont_mask = _mm_movemask_epi8(_mm_cmpeq_epi8(masked, v_cont));
+			if (null_mask) {
+				int end = __builtin_ctz(null_mask);
+				int valid = (1 << end) - 1;
+				return n + __builtin_popcount(~cont_mask & valid);
+			}
+			n += 16 - __builtin_popcount(cont_mask);
+			s += 16;
+		}
+		return n;
+	}
+#endif
 	for (; (l = uc_len(s)); n++)
 		s += l;
 	return n;
diff --git a/vi.c b/vi.c
index 357df5ff..cca05855 100644
--- a/vi.c
+++ b/vi.c
@@ -1,3 +1,7 @@
+#ifdef __SSE2__
+#include <stdint.h>
+#include <emmintrin.h>
+#endif
 #include <ctype.h>
 #include <fcntl.h>
 #include <stdio.h>
