diff options
| -rw-r--r-- | Makefile | 5 | ||||
| -rwxr-xr-x | configure | 20 | ||||
| -rw-r--r-- | text.c | 29 | ||||
| -rw-r--r-- | text.h | 2 | ||||
| -rw-r--r-- | util.h | 11 |
5 files changed, 66 insertions, 1 deletions
@@ -32,8 +32,11 @@ CFLAGS_STD ?= -std=c99 -D_POSIX_C_SOURCE=200809L -D_XOPEN_SOURCE=700 -DNDEBUG CFLAGS_STD += -DVERSION=\"${VERSION}\" LDFLAGS_STD ?= -lc +CFLAGS_LIBC ?= -DHAVE_MEMRCHR=0 + CFLAGS_VIS = $(CFLAGS_AUTO) $(CFLAGS_TERMKEY) $(CFLAGS_CURSES) $(CFLAGS_ACL) \ - $(CFLAGS_SELINUX) $(CFLAGS_TRE) $(CFLAGS_LUA) $(CFLAGS_LPEG) $(CFLAGS_STD) + $(CFLAGS_SELINUX) $(CFLAGS_TRE) $(CFLAGS_LUA) $(CFLAGS_LPEG) $(CFLAGS_STD) \ + $(CFLAGS_LIBC) CFLAGS_VIS += -DVIS_PATH=\"${SHAREPREFIX}/vis\" CFLAGS_VIS += -DCONFIG_HELP=${CONFIG_HELP} @@ -594,6 +594,25 @@ EOF fi fi +printf "checking for memrchr... " + +cat > "$tmpc" <<EOF +#define _GNU_SOURCE +#include <string.h> + +int main(int argc, char *argv[]) { + return !memrchr("\n", '\n', 1); +} +EOF + +if $CC $CFLAGS "$tmpc" $LDFLAGS -o "$tmpo" >/dev/null 2>&1; then + HAVE_MEMRCHR=1 + printf "%s\n" "yes" +else + HAVE_MEMRCHR=0 + printf "%s\n" "no" +fi + printf "completing config.mk... " exec 3>&1 1>>config.mk @@ -621,6 +640,7 @@ LDFLAGS_ACL = $LDFLAGS_ACL CONFIG_SELINUX = $CONFIG_SELINUX CFLAGS_SELINUX = $CFLAGS_SELINUX LDFLAGS_SELINUX = $LDFLAGS_SELINUX +CFLAGS_LIBC = -DHAVE_MEMRCHR=$HAVE_MEMRCHR EOF exec 1>&3 3>&- @@ -1,3 +1,4 @@ +#define _GNU_SOURCE // memrchr(3) is non-standard #include <unistd.h> #include <stdio.h> #include <stdlib.h> @@ -1455,6 +1456,34 @@ bool text_iterator_byte_prev(Iterator *it, char *b) { return true; } +bool text_iterator_byte_find_prev(Iterator *it, char b) { + while (it->text) { + const char *match = memrchr(it->start, b, it->text - it->start); + if (match) { + it->pos -= it->text - match; + it->text = match; + return true; + } + text_iterator_prev(it); + } + text_iterator_next(it); + return false; +} + +bool text_iterator_byte_find_next(Iterator *it, char b) { + while (it->text) { + const char *match = memchr(it->text, b, it->end - it->text); + if (match) { + it->pos += match - it->text; + it->text = match; + return true; + } + text_iterator_next(it); + } + text_iterator_prev(it); + return false; +} + bool text_iterator_codepoint_next(Iterator *it, char *c) { while (text_iterator_byte_next(it, NULL)) { if (ISUTF8(*it->text)) { @@ -97,6 +97,8 @@ bool text_iterator_byte_prev(Iterator*, char *b); /* if the new position is at EOF a NUL byte (which is not actually * part of the file) is read. */ bool text_iterator_byte_next(Iterator*, char *b); +bool text_iterator_byte_find_prev(Iterator*, char b); +bool text_iterator_byte_find_next(Iterator*, char b); /* move to the next/previous UTF-8 encoded Unicode codepoint * and set c (if it is non NULL) to the first byte */ bool text_iterator_codepoint_next(Iterator *it, char *c); @@ -23,4 +23,15 @@ static inline bool addu(size_t a, size_t b, size_t *c) { } #endif +#if !HAVE_MEMRCHR +/* MIT licensed implementation from musl libc */ +static void *memrchr(const void *m, int c, size_t n) +{ + const unsigned char *s = m; + c = (unsigned char)c; + while (n--) if (s[n]==c) return (void *)(s+n); + return 0; +} #endif + +#endif /* UTIL_H */ |
