2 #define _GNU_SOURCE /* memrchr(3) is non-standard */
12 bool text_iterator_byte_get(const Iterator
*it
, char *b
) {
13 if (text_iterator_valid(it
)) {
14 const Text
*txt
= text_iterator_text(it
);
15 if (it
->start
<= it
->text
&& it
->text
< it
->end
) {
18 } else if (it
->pos
== text_size(txt
)) {
26 bool text_iterator_byte_next(Iterator
*it
, char *b
) {
27 if (!text_iterator_has_next(it
))
30 if (it
->text
< it
->end
) {
34 } else if (!text_iterator_has_prev(it
)) {
38 while (it
->text
== it
->end
) {
39 if (!text_iterator_next(it
)) {
44 return text_iterator_prev(it
);
53 bool text_iterator_byte_prev(Iterator
*it
, char *b
) {
54 if (!text_iterator_has_prev(it
))
56 bool eof
= !text_iterator_has_next(it
);
57 while (it
->text
== it
->start
) {
58 if (!text_iterator_prev(it
)) {
63 return text_iterator_next(it
);
75 bool text_iterator_byte_find_prev(Iterator
*it
, char b
) {
77 const char *match
= memrchr(it
->start
, b
, it
->text
- it
->start
);
79 it
->pos
-= it
->text
- match
;
83 text_iterator_prev(it
);
85 text_iterator_next(it
);
89 bool text_iterator_byte_find_next(Iterator
*it
, char b
) {
91 const char *match
= memchr(it
->text
, b
, it
->end
- it
->text
);
93 it
->pos
+= match
- it
->text
;
97 text_iterator_next(it
);
99 text_iterator_prev(it
);
103 bool text_iterator_codepoint_next(Iterator
*it
, char *c
) {
104 while (text_iterator_byte_next(it
, NULL
)) {
105 if (ISUTF8(*it
->text
)) {
114 bool text_iterator_codepoint_prev(Iterator
*it
, char *c
) {
115 while (text_iterator_byte_prev(it
, NULL
)) {
116 if (ISUTF8(*it
->text
)) {
125 bool text_iterator_char_next(Iterator
*it
, char *c
) {
126 if (!text_iterator_codepoint_next(it
, c
))
128 mbstate_t ps
= { 0 };
129 const Text
*txt
= text_iterator_text(it
);
131 char buf
[MB_LEN_MAX
];
132 size_t len
= text_bytes_get(txt
, it
->pos
, sizeof buf
, buf
);
134 size_t wclen
= mbrtowc(&wc
, buf
, len
, &ps
);
135 if (wclen
== (size_t)-1 && errno
== EILSEQ
) {
137 } else if (wclen
== (size_t)-2) {
139 } else if (wclen
== 0) {
142 int width
= wcwidth(wc
);
145 if (!text_iterator_codepoint_next(it
, c
))
152 bool text_iterator_char_prev(Iterator
*it
, char *c
) {
153 if (!text_iterator_codepoint_prev(it
, c
))
155 const Text
*txt
= text_iterator_text(it
);
157 char buf
[MB_LEN_MAX
];
158 size_t len
= text_bytes_get(txt
, it
->pos
, sizeof buf
, buf
);
160 mbstate_t ps
= { 0 };
161 size_t wclen
= mbrtowc(&wc
, buf
, len
, &ps
);
162 if (wclen
== (size_t)-1 && errno
== EILSEQ
) {
164 } else if (wclen
== (size_t)-2) {
166 } else if (wclen
== 0) {
169 int width
= wcwidth(wc
);
172 if (!text_iterator_codepoint_prev(it
, c
))