6 bool text_range_valid(Filerange
*r
) {
7 return r
->start
!= EPOS
&& r
->end
!= EPOS
&& r
->start
<= r
->end
;
10 size_t text_range_size(Filerange
*r
) {
11 return text_range_valid(r
) ? r
->end
- r
->start
: 0;
14 Filerange
text_range_empty(void) {
15 return (Filerange
){ .start
= EPOS
, .end
= EPOS
};
18 Filerange
text_range_union(Filerange
*r1
, Filerange
*r2
) {
19 if (!text_range_valid(r1
))
21 if (!text_range_valid(r2
))
24 .start
= MIN(r1
->start
, r2
->start
),
25 .end
= MAX(r1
->end
, r2
->end
),
29 Filerange
text_range_new(size_t a
, size_t b
) {
36 bool text_range_equal(Filerange
*r1
, Filerange
*r2
) {
37 if (!text_range_valid(r1
) && !text_range_valid(r2
))
39 return r1
->start
== r2
->start
&& r1
->end
== r2
->end
;
42 bool text_range_overlap(Filerange
*r1
, Filerange
*r2
) {
43 if (!text_range_valid(r1
) || !text_range_valid(r2
))
45 return r1
->start
<= r2
->end
&& r2
->start
<= r1
->end
;
48 bool text_range_contains(Filerange
*r
, size_t pos
) {
49 return text_range_valid(r
) && r
->start
<= pos
&& pos
<= r
->end
;
52 int text_char_count(const char *data
, size_t len
) {
57 size_t wclen
= mbrtowc(&wc
, data
, len
, &ps
);
58 if (wclen
== (size_t)-1 && errno
== EILSEQ
) {
60 while (!ISUTF8(*data
))
62 } else if (wclen
== (size_t)-2) {
64 } else if (wclen
== 0) {
69 int width
= wcwidth(wc
);