aboutsummaryrefslogtreecommitdiff
path: root/text.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2017-04-07 16:04:40 +0200
committerMarc André Tanner <mat@brain-dump.org>2017-04-09 11:27:14 +0200
commitd2004b15f1e90efafedc367335c07ad4636d291d (patch)
tree3ab47dc219f5ad3b2f3bc9d3699aecc3b7ffd656 /text.c
parent3349b97344c6c7032bff7aaa13985406ca571c34 (diff)
downloadvis-d2004b15f1e90efafedc367335c07ad4636d291d.tar.gz
vis-d2004b15f1e90efafedc367335c07ad4636d291d.tar.xz
text: add mem{r,}chr(3) based byte search functions
These are generally implemented efficiently in libc. While memrchr(3) is non-standard, it is a common extension. If it is not available, we use a simple C implementation from musl.
Diffstat (limited to 'text.c')
-rw-r--r--text.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/text.c b/text.c
index f789339..1bf1940 100644
--- a/text.c
+++ b/text.c
@@ -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)) {