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
) {
41 text_iterator_codepoint_next(it
, NULL
);
43 } else if (wclen
== (size_t)-2) {
44 if (!text_iterator_next(it
)) {
48 } else if (wclen
== 0) {
49 text_iterator_byte_next(it
, NULL
);
56 text_iterator_next(it
);
67 *pos_add
= it
->pos
- start
;
72 if (it
->pos
< r
->end
&& text_iterator_byte_get(it
, (char*)c
)) {
73 text_iterator_byte_next(it
, NULL
);
82 static void str_rewind(size_t pos
, void *context
) {
84 r
->it
= text_iterator_get(r
->text
, pos
);
87 static int str_compare(size_t pos1
, size_t pos2
, size_t len
, void *context
) {
90 void *buf1
= malloc(len
), *buf2
= malloc(len
);
93 text_bytes_get(r
->text
, pos1
, len
, buf1
);
94 text_bytes_get(r
->text
, pos2
, len
, buf2
);
95 ret
= memcmp(buf1
, buf2
, len
);
102 Regex
*text_regex_new(void) {
103 Regex
*r
= calloc(1, sizeof(*r
));
106 r
->str_source
= (tre_str_source
) {
107 .get_next_char
= str_next_char
,
108 .rewind
= str_rewind
,
109 .compare
= str_compare
,
115 void text_regex_free(Regex
*r
) {
118 tre_regfree(&r
->regex
);
122 int text_regex_compile(Regex
*regex
, const char *string
, int cflags
) {
123 int r
= tre_regcomp(®ex
->regex
, string
, cflags
);
125 tre_regcomp(®ex
->regex
, "\0\0", 0);
129 int text_regex_match(Regex
*r
, const char *data
, int eflags
) {
130 return tre_regexec(&r
->regex
, data
, 0, NULL
, eflags
);
133 int text_search_range_forward(Text
*txt
, size_t pos
, size_t len
, Regex
*r
, size_t nmatch
, RegexMatch pmatch
[], int eflags
) {
135 r
->it
= text_iterator_get(txt
, pos
);
138 regmatch_t match
[nmatch
];
139 int ret
= tre_reguexec(&r
->regex
, &r
->str_source
, nmatch
, match
, eflags
);
141 for (size_t i
= 0; i
< nmatch
; i
++) {
142 pmatch
[i
].start
= match
[i
].rm_so
== -1 ? EPOS
: pos
+ match
[i
].rm_so
;
143 pmatch
[i
].end
= match
[i
].rm_eo
== -1 ? EPOS
: pos
+ match
[i
].rm_eo
;
149 int text_search_range_backward(Text
*txt
, size_t pos
, size_t len
, Regex
*r
, size_t nmatch
, RegexMatch pmatch
[], int eflags
) {
150 int ret
= REG_NOMATCH
;
151 size_t end
= pos
+ len
;
153 while (pos
< end
&& !text_search_range_forward(txt
, pos
, len
, r
, nmatch
, pmatch
, eflags
)) {
155 // FIXME: assumes nmatch >= 1
156 size_t next
= pmatch
[0].end
;
158 next
= text_line_next(txt
, pos
);