2 * Copyright (C) 2003 Red Hat, Inc.
4 * This is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Library General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "../config.h"
21 #include <sys/types.h>
30 #if defined(USE_GNU_REGEX)
32 #elif defined(USE_PCRE)
39 compare_matches(gconstpointer a, gconstpointer b)
41 const struct _vte_regex_match *A, *B;
44 if (B->rm_so != A->rm_so) {
45 return B->rm_so - A->rm_so;
47 return B->rm_eo - A->rm_eo;
51 _vte_regex_sort_matches(struct _vte_regex_match *matches, gsize n_matches)
57 array = g_array_new(0, 0, sizeof(struct _vte_regex_match));
58 g_array_append_vals(array, matches, n_matches);
59 g_array_sort(array, compare_matches);
60 memmove(matches, array->data,
61 n_matches * sizeof(struct _vte_regex_match));
62 g_array_free(array, TRUE);
65 #if defined(USE_GNU_REGEX)
68 struct re_pattern_buffer buffer;
72 _vte_regex_compile(const char *pattern)
74 struct _vte_regex *ret;
77 ret = g_malloc0(sizeof(struct _vte_regex));
78 res = re_compile_pattern(pattern, strlen(pattern), &ret->buffer);
87 _vte_regex_free(struct _vte_regex *regex)
89 regfree(®ex->buffer);
94 _vte_regex_exec(struct _vte_regex *regex, const char *string,
95 gsize nmatch, struct _vte_regex_match *matches)
97 struct re_registers registers;
100 length = strlen(string);
101 registers.num_regs = 0;
102 registers.start = NULL;
103 registers.end = NULL;
104 ret = re_search(®ex->buffer,
109 for (i = 0; i < nmatch; i++) {
110 matches[i].rm_so = -1;
111 matches[i].rm_eo = -1;
113 for (i = 0; (i < nmatch) && (i < registers.num_regs); i++) {
114 matches[i].rm_so = registers.start[i];
115 matches[i].rm_eo = registers.end[i];
117 if ((i == nmatch) || (matches[i].rm_so == -1)) {
118 _vte_regex_sort_matches(matches, i);
127 #elif defined(USE_PCRE)
135 _vte_regex_compile(const char *pattern)
137 struct _vte_regex *ret;
141 ret = g_malloc(sizeof(struct _vte_regex));
143 ret->pcre = pcre_compile(pattern, PCRE_UTF8, &err, &err_offset, NULL);
144 if (ret->pcre == NULL) {
149 ret->extra = pcre_study(ret->pcre, 0, &err);
150 if (ret->extra == NULL) {
151 pcre_free(ret->pcre);
160 _vte_regex_free(struct _vte_regex *regex)
162 pcre_free(regex->pcre);
163 pcre_free(regex->extra);
168 _vte_regex_exec(struct _vte_regex *regex, const char *string,
169 gsize nmatch, struct _vte_regex_match *matches)
171 int i, n_matches, *ovector, ovector_length, length;
173 for (i = 0; i < nmatch; i++) {
174 matches[i].rm_so = -1;
175 matches[i].rm_eo = -1;
178 length = strlen(string);
179 ovector_length = 3 * (length + 1);
180 ovector = g_malloc(sizeof(int) * ovector_length);
182 i = pcre_exec(regex->pcre, regex->extra, string, length,
183 0, 0, ovector, ovector_length);
194 matches[i].rm_so = ovector[i * 2];
195 matches[i].rm_eo = ovector[i * 2 + 1];
198 _vte_regex_sort_matches(matches, n_matches);
210 _vte_regex_compile(const char *pattern)
212 struct _vte_regex *ret;
215 ret = g_malloc(sizeof(struct _vte_regex));
216 i = regcomp(&ret->posix_regex, pattern, REG_EXTENDED);
225 _vte_regex_free(struct _vte_regex *regex)
227 regfree(®ex->posix_regex);
232 _vte_regex_exec(struct _vte_regex *regex, const char *string,
233 gsize nmatch, struct _vte_regex_match *matches)
235 regmatch_t *posix_matches;
238 posix_matches = g_malloc(nmatch * sizeof(regmatch_t));
239 ret = regexec(®ex->posix_regex, string, nmatch, posix_matches, 0);
241 for (i = 0; i < nmatch; i++) {
242 matches[i].rm_so = -1;
243 matches[i].rm_eo = -1;
245 for (i = 0; i < nmatch; i++) {
246 matches[i].rm_so = posix_matches[i].rm_so;
247 matches[i].rm_eo = posix_matches[i].rm_eo;
248 if (matches[i].rm_so == -1) {
249 _vte_regex_sort_matches(matches, i);
254 g_free(posix_matches);