]>
git.proxmox.com Git - libgit2.git/blob - src/regexp.c
2 * Copyright (C) the libgit2 contributors. All rights reserved.
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
10 #if defined(GIT_REGEX_BUILTIN) || defined(GIT_REGEX_PCRE)
12 int git_regexp_compile(git_regexp
*r
, const char *pattern
, int flags
)
14 int erroffset
, cflags
= 0;
17 if (flags
& GIT_REGEXP_ICASE
)
18 cflags
|= PCRE_CASELESS
;
20 if ((*r
= pcre_compile(pattern
, cflags
, &error
, &erroffset
, NULL
)) == NULL
) {
21 git_error_set_str(GIT_ERROR_REGEX
, error
);
22 return GIT_EINVALIDSPEC
;
28 void git_regexp_dispose(git_regexp
*r
)
34 int git_regexp_match(const git_regexp
*r
, const char *string
)
37 if ((error
= pcre_exec(*r
, NULL
, string
, (int) strlen(string
), 0, 0, NULL
, 0)) < 0)
38 return (error
== PCRE_ERROR_NOMATCH
) ? GIT_ENOTFOUND
: GIT_EINVALIDSPEC
;
42 int git_regexp_search(const git_regexp
*r
, const char *string
, size_t nmatches
, git_regmatch
*matches
)
44 int static_ovec
[9], *ovec
;
48 /* The ovec array always needs to be a mutiple of three */
49 if (nmatches
<= ARRAY_SIZE(static_ovec
) / 3)
52 ovec
= git__calloc(nmatches
* 3, sizeof(*ovec
));
53 GIT_ERROR_CHECK_ALLOC(ovec
);
55 if ((error
= pcre_exec(*r
, NULL
, string
, (int) strlen(string
), 0, 0, ovec
, (int) nmatches
* 3)) < 0)
59 error
= (int) nmatches
;
61 for (i
= 0; i
< (unsigned int) error
; i
++) {
62 matches
[i
].start
= (ovec
[i
* 2] < 0) ? -1 : ovec
[i
* 2];
63 matches
[i
].end
= (ovec
[i
* 2 + 1] < 0) ? -1 : ovec
[i
* 2 + 1];
65 for (i
= (unsigned int) error
; i
< nmatches
; i
++)
66 matches
[i
].start
= matches
[i
].end
= -1;
69 if (nmatches
> ARRAY_SIZE(static_ovec
) / 3)
72 return (error
== PCRE_ERROR_NOMATCH
) ? GIT_ENOTFOUND
: GIT_EINVALIDSPEC
;
76 #elif defined(GIT_REGEX_PCRE2)
78 int git_regexp_compile(git_regexp
*r
, const char *pattern
, int flags
)
80 unsigned char errmsg
[1024];
82 int error
, cflags
= 0;
84 if (flags
& GIT_REGEXP_ICASE
)
85 cflags
|= PCRE2_CASELESS
;
87 if ((*r
= pcre2_compile((const unsigned char *) pattern
, PCRE2_ZERO_TERMINATED
,
88 cflags
, &error
, &erroff
, NULL
)) == NULL
) {
89 pcre2_get_error_message(error
, errmsg
, sizeof(errmsg
));
90 git_error_set_str(GIT_ERROR_REGEX
, (char *) errmsg
);
91 return GIT_EINVALIDSPEC
;
97 void git_regexp_dispose(git_regexp
*r
)
103 int git_regexp_match(const git_regexp
*r
, const char *string
)
105 pcre2_match_data
*data
;
108 data
= pcre2_match_data_create(1, NULL
);
109 GIT_ERROR_CHECK_ALLOC(data
);
111 if ((error
= pcre2_match(*r
, (const unsigned char *) string
, strlen(string
),
112 0, 0, data
, NULL
)) < 0)
113 return (error
== PCRE2_ERROR_NOMATCH
) ? GIT_ENOTFOUND
: GIT_EINVALIDSPEC
;
115 pcre2_match_data_free(data
);
119 int git_regexp_search(const git_regexp
*r
, const char *string
, size_t nmatches
, git_regmatch
*matches
)
121 pcre2_match_data
*data
= NULL
;
126 if ((data
= pcre2_match_data_create(nmatches
, NULL
)) == NULL
) {
131 if ((error
= pcre2_match(*r
, (const unsigned char *) string
, strlen(string
),
132 0, 0, data
, NULL
)) < 0)
135 if (error
== 0 || (unsigned int) error
> nmatches
)
137 ovec
= pcre2_get_ovector_pointer(data
);
139 for (i
= 0; i
< (unsigned int) error
; i
++) {
140 matches
[i
].start
= (ovec
[i
* 2] == PCRE2_UNSET
) ? -1 : (ssize_t
) ovec
[i
* 2];
141 matches
[i
].end
= (ovec
[i
* 2 + 1] == PCRE2_UNSET
) ? -1 : (ssize_t
) ovec
[i
* 2 + 1];
143 for (i
= (unsigned int) error
; i
< nmatches
; i
++)
144 matches
[i
].start
= matches
[i
].end
= -1;
147 pcre2_match_data_free(data
);
149 return (error
== PCRE2_ERROR_NOMATCH
) ? GIT_ENOTFOUND
: GIT_EINVALIDSPEC
;
153 #elif defined(GIT_REGEX_REGCOMP) || defined(GIT_REGEX_REGCOMP_L)
155 #if defined(GIT_REGEX_REGCOMP_L)
156 # include <xlocale.h>
159 int git_regexp_compile(git_regexp
*r
, const char *pattern
, int flags
)
161 int cflags
= REG_EXTENDED
, error
;
164 if (flags
& GIT_REGEXP_ICASE
)
167 # if defined(GIT_REGEX_REGCOMP)
168 if ((error
= regcomp(r
, pattern
, cflags
)) != 0)
170 if ((error
= regcomp_l(r
, pattern
, cflags
, (locale_t
) 0)) != 0)
173 regerror(error
, r
, errmsg
, sizeof(errmsg
));
174 git_error_set_str(GIT_ERROR_REGEX
, errmsg
);
175 return GIT_EINVALIDSPEC
;
181 void git_regexp_dispose(git_regexp
*r
)
186 int git_regexp_match(const git_regexp
*r
, const char *string
)
189 if ((error
= regexec(r
, string
, 0, NULL
, 0)) != 0)
190 return (error
== REG_NOMATCH
) ? GIT_ENOTFOUND
: GIT_EINVALIDSPEC
;
194 int git_regexp_search(const git_regexp
*r
, const char *string
, size_t nmatches
, git_regmatch
*matches
)
196 regmatch_t static_m
[3], *m
;
200 if (nmatches
<= ARRAY_SIZE(static_m
))
203 m
= git__calloc(nmatches
, sizeof(*m
));
205 if ((error
= regexec(r
, string
, nmatches
, m
, 0)) != 0)
208 for (i
= 0; i
< nmatches
; i
++) {
209 matches
[i
].start
= (m
[i
].rm_so
< 0) ? -1 : m
[i
].rm_so
;
210 matches
[i
].end
= (m
[i
].rm_eo
< 0) ? -1 : m
[i
].rm_eo
;
214 if (nmatches
> ARRAY_SIZE(static_m
))
217 return (error
== REG_NOMATCH
) ? GIT_ENOTFOUND
: GIT_EINVALIDSPEC
;