6 #include "text-regex.h"
7 #include "text-motions.h"
11 tre_str_source str_source
;
17 size_t text_regex_nsub(Regex
*r
) {
20 return r
->regex
.re_nsub
;
23 static int str_next_char(tre_char_t
*c
, unsigned int *pos_add
, void *context
) {
25 Iterator
*it
= &r
->it
;
29 size_t start
= it
->pos
;
31 if (it
->pos
>= r
->end
) {
35 size_t rem
= r
->end
- it
->pos
;
36 size_t plen
= it
->end
- it
->text
;
37 size_t len
= rem
< plen
? rem
: plen
;
38 size_t wclen
= mbrtowc(c
, it
->text
, len
, &ps
);
39 if (wclen
== (size_t)-1 && errno
== EILSEQ
) {
42 text_iterator_codepoint_next(it
, NULL
);
44 } else if (wclen
== (size_t)-2) {
45 if (!text_iterator_next(it
)) {
49 } else if (wclen
== 0) {
50 text_iterator_byte_next(it
, NULL
);
57 text_iterator_next(it
);
68 *pos_add
= it
->pos
- start
;
73 if (it
->pos
< r
->end
&& text_iterator_byte_get(it
, (char*)c
)) {
74 text_iterator_byte_next(it
, NULL
);
83 static void str_rewind(size_t pos
, void *context
) {
85 r
->it
= text_iterator_get(r
->text
, pos
);
88 static int str_compare(size_t pos1
, size_t pos2
, size_t len
, void *context
) {
91 void *buf1
= malloc(len
), *buf2
= malloc(len
);
94 text_bytes_get(r
->text
, pos1
, len
, buf1
);
95 text_bytes_get(r
->text
, pos2
, len
, buf2
);
96 ret
= memcmp(buf1
, buf2
, len
);
103 Regex
*text_regex_new(void) {
104 Regex
*r
= calloc(1, sizeof(*r
));
107 r
->str_source
= (tre_str_source
) {
108 .get_next_char
= str_next_char
,
109 .rewind
= str_rewind
,
110 .compare
= str_compare
,
116 void text_regex_free(Regex
*r
) {
119 tre_regfree(&r
->regex
);
123 int text_regex_compile(Regex
*regex
, const char *string
, int cflags
) {
124 int r
= tre_regcomp(®ex
->regex
, string
, cflags
);
126 tre_regcomp(®ex
->regex
, "\0\0", 0);
130 int text_regex_match(Regex
*r
, const char *data
, int eflags
) {
131 return tre_regexec(&r
->regex
, data
, 0, NULL
, eflags
);
134 int text_search_range_forward(Text
*txt
, size_t pos
, size_t len
, Regex
*r
, size_t nmatch
, RegexMatch pmatch
[], int eflags
) {
136 r
->it
= text_iterator_get(txt
, pos
);
139 regmatch_t match
[nmatch
];
140 int ret
= tre_reguexec(&r
->regex
, &r
->str_source
, nmatch
, match
, eflags
);
142 for (size_t i
= 0; i
< nmatch
; i
++) {
143 pmatch
[i
].start
= match
[i
].rm_so
== -1 ? EPOS
: pos
+ match
[i
].rm_so
;
144 pmatch
[i
].end
= match
[i
].rm_eo
== -1 ? EPOS
: pos
+ match
[i
].rm_eo
;
150 int text_search_range_backward(Text
*txt
, size_t pos
, size_t len
, Regex
*r
, size_t nmatch
, RegexMatch pmatch
[], int eflags
) {
151 int ret
= REG_NOMATCH
;
152 size_t end
= pos
+ len
;
154 while (pos
< end
&& !text_search_range_forward(txt
, pos
, len
, r
, nmatch
, pmatch
, eflags
)) {
156 // FIXME: assumes nmatch >= 1
157 size_t next
= pmatch
[0].end
;
159 next
= text_line_next(txt
, pos
);
167 if (text_byte_get(txt
, pos
-1, &c
) && c
== '\n')
168 eflags
&= ~REG_NOTBOL
;
170 eflags
|= REG_NOTBOL
;