Skip to content

Commit 02683b2

Browse files
committed
regexec: prefix all regexec function calls with p_
Prefix all the calls to the the regexec family of functions with `p_`. This allows us to swap out all the regular expression functions with our own implementation. Move the declarations to `posix_regex.h` for simpler inclusion.
1 parent c9f116f commit 02683b2

File tree

12 files changed

+106
-77
lines changed

12 files changed

+106
-77
lines changed

src/common.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@
8585
*/
8686
#include "git2/deprecated.h"
8787

88-
#include <regex.h>
88+
#include "posix.h"
89+
#include "posix_regex.h"
8990

9091
#define DEFAULT_BUFSIZE 65536
9192
#define FILEIO_BUFSIZE DEFAULT_BUFSIZE
@@ -118,7 +119,7 @@ void git_error_set(int error_class, const char *string, ...) GIT_FORMAT_PRINTF(2
118119
* Set the error message for a regex failure, using the internal regex
119120
* error code lookup and return a libgit error code.
120121
*/
121-
int git_error_set_regex(const regex_t *regex, int error_code);
122+
int git_error_set_regex(const p_regex_t *regex, int error_code);
122123

123124
/**
124125
* Set error message for user callback if needed.

src/config.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ typedef struct {
345345
git_config_iterator parent;
346346
git_config_iterator *current;
347347
const git_config *cfg;
348-
regex_t regex;
348+
p_regex_t regex;
349349
size_t i;
350350
} all_iter;
351351

@@ -423,7 +423,7 @@ static int all_iter_glob_next(git_config_entry **entry, git_config_iterator *_it
423423
*/
424424
while ((error = all_iter_next(entry, _iter)) == 0) {
425425
/* skip non-matching keys if regexp was provided */
426-
if (regexec(&iter->regex, (*entry)->name, 0, NULL, 0) != 0)
426+
if (p_regexec(&iter->regex, (*entry)->name, 0, NULL, 0) != 0)
427427
continue;
428428

429429
/* and simply return if we like the entry's name */
@@ -447,7 +447,7 @@ static void all_iter_glob_free(git_config_iterator *_iter)
447447
{
448448
all_iter *iter = (all_iter *) _iter;
449449

450-
regfree(&iter->regex);
450+
p_regfree(&iter->regex);
451451
all_iter_free(_iter);
452452
}
453453

@@ -480,7 +480,7 @@ int git_config_iterator_glob_new(git_config_iterator **out, const git_config *cf
480480
iter = git__calloc(1, sizeof(all_iter));
481481
GIT_ERROR_CHECK_ALLOC(iter);
482482

483-
if ((result = p_regcomp(&iter->regex, regexp, REG_EXTENDED)) != 0) {
483+
if ((result = p_regcomp(&iter->regex, regexp, P_REG_EXTENDED)) != 0) {
484484
git_error_set_regex(&iter->regex, result);
485485
git__free(iter);
486486
return -1;
@@ -510,15 +510,15 @@ int git_config_backend_foreach_match(
510510
{
511511
git_config_entry *entry;
512512
git_config_iterator* iter;
513-
regex_t regex;
513+
p_regex_t regex;
514514
int error = 0;
515515

516516
assert(backend && cb);
517517

518518
if (regexp != NULL) {
519-
if ((error = p_regcomp(&regex, regexp, REG_EXTENDED)) != 0) {
519+
if ((error = p_regcomp(&regex, regexp, P_REG_EXTENDED)) != 0) {
520520
git_error_set_regex(&regex, error);
521-
regfree(&regex);
521+
p_regfree(&regex);
522522
return -1;
523523
}
524524
}
@@ -530,7 +530,7 @@ int git_config_backend_foreach_match(
530530

531531
while (!(iter->next(&entry, iter) < 0)) {
532532
/* skip non-matching keys if regexp was provided */
533-
if (regexp && regexec(&regex, entry->name, 0, NULL, 0) != 0)
533+
if (regexp && p_regexec(&regex, entry->name, 0, NULL, 0) != 0)
534534
continue;
535535

536536
/* abort iterator on non-zero return value */
@@ -541,7 +541,7 @@ int git_config_backend_foreach_match(
541541
}
542542

543543
if (regexp != NULL)
544-
regfree(&regex);
544+
p_regfree(&regex);
545545

546546
iter->free(iter);
547547

@@ -981,7 +981,7 @@ typedef struct {
981981
git_config_iterator parent;
982982
git_config_iterator *iter;
983983
char *name;
984-
regex_t regex;
984+
p_regex_t regex;
985985
int have_regex;
986986
} multivar_iter;
987987

@@ -997,7 +997,7 @@ static int multivar_iter_next(git_config_entry **entry, git_config_iterator *_it
997997
if (!iter->have_regex)
998998
return 0;
999999

1000-
if (regexec(&iter->regex, (*entry)->value, 0, NULL, 0) == 0)
1000+
if (p_regexec(&iter->regex, (*entry)->value, 0, NULL, 0) == 0)
10011001
return 0;
10021002
}
10031003

@@ -1012,7 +1012,7 @@ void multivar_iter_free(git_config_iterator *_iter)
10121012

10131013
git__free(iter->name);
10141014
if (iter->have_regex)
1015-
regfree(&iter->regex);
1015+
p_regfree(&iter->regex);
10161016
git__free(iter);
10171017
}
10181018

@@ -1032,11 +1032,11 @@ int git_config_multivar_iterator_new(git_config_iterator **out, const git_config
10321032
goto on_error;
10331033

10341034
if (regexp != NULL) {
1035-
error = p_regcomp(&iter->regex, regexp, REG_EXTENDED);
1035+
error = p_regcomp(&iter->regex, regexp, P_REG_EXTENDED);
10361036
if (error != 0) {
10371037
git_error_set_regex(&iter->regex, error);
10381038
error = -1;
1039-
regfree(&iter->regex);
1039+
p_regfree(&iter->regex);
10401040
goto on_error;
10411041
}
10421042

src/config_file.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
#include <ctype.h>
2323
#include <sys/types.h>
24-
#include <regex.h>
2524

2625
/* Max depth for [include] directives */
2726
#define MAX_INCLUDE_DEPTH 10
@@ -62,7 +61,7 @@ typedef struct {
6261
} diskfile_parse_state;
6362

6463
static int config_read(git_config_entries *entries, const git_repository *repo, git_config_file *file, git_config_level_t level, int depth);
65-
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char *value);
64+
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const p_regex_t *preg, const char *value);
6665
static char *escape_value(const char *ptr);
6766

6867
static int config_snapshot(git_config_backend **out, git_config_backend *in);
@@ -329,15 +328,15 @@ static int config_set_multivar(
329328
{
330329
diskfile_backend *b = (diskfile_backend *)cfg;
331330
char *key;
332-
regex_t preg;
331+
p_regex_t preg;
333332
int result;
334333

335334
assert(regexp);
336335

337336
if ((result = git_config__normalize_name(name, &key)) < 0)
338337
return result;
339338

340-
result = p_regcomp(&preg, regexp, REG_EXTENDED);
339+
result = p_regcomp(&preg, regexp, P_REG_EXTENDED);
341340
if (result != 0) {
342341
git_error_set_regex(&preg, result);
343342
result = -1;
@@ -352,7 +351,7 @@ static int config_set_multivar(
352351

353352
out:
354353
git__free(key);
355-
regfree(&preg);
354+
p_regfree(&preg);
356355

357356
return result;
358357
}
@@ -395,7 +394,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
395394
diskfile_backend *b = (diskfile_backend *)cfg;
396395
git_config_entries *entries = NULL;
397396
git_config_entry *entry = NULL;
398-
regex_t preg = { 0 };
397+
p_regex_t preg = { 0 };
399398
char *key = NULL;
400399
int result;
401400

@@ -413,7 +412,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
413412
goto out;
414413
}
415414

416-
if ((result = p_regcomp(&preg, regexp, REG_EXTENDED)) != 0) {
415+
if ((result = p_regcomp(&preg, regexp, P_REG_EXTENDED)) != 0) {
417416
git_error_set_regex(&preg, result);
418417
result = -1;
419418
goto out;
@@ -428,7 +427,7 @@ static int config_delete_multivar(git_config_backend *cfg, const char *name, con
428427
out:
429428
git_config_entries_free(entries);
430429
git__free(key);
431-
regfree(&preg);
430+
p_regfree(&preg);
432431
return result;
433432
}
434433

@@ -954,7 +953,7 @@ struct write_data {
954953
const char *section;
955954
const char *orig_name;
956955
const char *name;
957-
const regex_t *preg;
956+
const p_regex_t *preg;
958957
const char *value;
959958
};
960959

@@ -1059,7 +1058,7 @@ static int write_on_variable(
10591058

10601059
/* If we have a regex to match the value, see if it matches */
10611060
if (has_matched && write_data->preg != NULL)
1062-
has_matched = (regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
1061+
has_matched = (p_regexec(write_data->preg, var_value, 0, NULL, 0) == 0);
10631062

10641063
/* If this isn't the name/value we're looking for, simply dump the
10651064
* existing data back out and continue on.
@@ -1120,7 +1119,7 @@ static int write_on_eof(
11201119
/*
11211120
* This is pretty much the parsing, except we write out anything we don't have
11221121
*/
1123-
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const regex_t *preg, const char* value)
1122+
static int config_write(diskfile_backend *cfg, const char *orig_key, const char *key, const p_regex_t *preg, const char* value)
11241123
{
11251124
int result;
11261125
char *orig_section, *section, *orig_name, *name, *ldot;

src/diff_driver.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "git2/attr.h"
1111

12+
#include "common.h"
1213
#include "diff.h"
1314
#include "strmap.h"
1415
#include "map.h"
@@ -24,7 +25,7 @@ typedef enum {
2425
} git_diff_driver_t;
2526

2627
typedef struct {
27-
regex_t re;
28+
p_regex_t re;
2829
int flags;
2930
} git_diff_driver_pattern;
3031

@@ -38,7 +39,7 @@ struct git_diff_driver {
3839
uint32_t binary_flags;
3940
uint32_t other_flags;
4041
git_array_t(git_diff_driver_pattern) fn_patterns;
41-
regex_t word_pattern;
42+
p_regex_t word_pattern;
4243
char name[GIT_FLEX_ARRAY];
4344
};
4445

@@ -129,7 +130,7 @@ static int diff_driver_add_patterns(
129130

130131
static int diff_driver_xfuncname(const git_config_entry *entry, void *payload)
131132
{
132-
return diff_driver_add_patterns(payload, entry->value, REG_EXTENDED);
133+
return diff_driver_add_patterns(payload, entry->value, P_REG_EXTENDED);
133134
}
134135

135136
static int diff_driver_funcname(const git_config_entry *entry, void *payload)
@@ -204,12 +205,12 @@ static int git_diff_driver_builtin(
204205

205206
if (ddef->fns &&
206207
(error = diff_driver_add_patterns(
207-
drv, ddef->fns, ddef->flags | REG_EXTENDED)) < 0)
208+
drv, ddef->fns, ddef->flags | P_REG_EXTENDED)) < 0)
208209
goto done;
209210

210211
if (ddef->words &&
211212
(error = p_regcomp(
212-
&drv->word_pattern, ddef->words, ddef->flags | REG_EXTENDED)))
213+
&drv->word_pattern, ddef->words, ddef->flags | P_REG_EXTENDED)))
213214
{
214215
error = git_error_set_regex(&drv->word_pattern, error);
215216
goto done;
@@ -309,7 +310,7 @@ static int git_diff_driver_load(
309310
goto done;
310311
if (!ce || !ce->value)
311312
/* no diff.<driver>.wordregex, so just continue */;
312-
else if (!(error = p_regcomp(&drv->word_pattern, ce->value, REG_EXTENDED)))
313+
else if (!(error = p_regcomp(&drv->word_pattern, ce->value, P_REG_EXTENDED)))
313314
found_driver = true;
314315
else {
315316
/* TODO: warn about bad regex instead of failure */
@@ -393,10 +394,10 @@ void git_diff_driver_free(git_diff_driver *driver)
393394
return;
394395

395396
for (i = 0; i < git_array_size(driver->fn_patterns); ++i)
396-
regfree(& git_array_get(driver->fn_patterns, i)->re);
397+
p_regfree(& git_array_get(driver->fn_patterns, i)->re);
397398
git_array_clear(driver->fn_patterns);
398399

399-
regfree(&driver->word_pattern);
400+
p_regfree(&driver->word_pattern);
400401

401402
git__free(driver);
402403
}
@@ -444,12 +445,12 @@ static int diff_context_line__pattern_match(
444445
git_diff_driver *driver, git_buf *line)
445446
{
446447
size_t i, maxi = git_array_size(driver->fn_patterns);
447-
regmatch_t pmatch[2];
448+
p_regmatch_t pmatch[2];
448449

449450
for (i = 0; i < maxi; ++i) {
450451
git_diff_driver_pattern *pat = git_array_get(driver->fn_patterns, i);
451452

452-
if (!regexec(&pat->re, line->ptr, 2, pmatch, 0)) {
453+
if (!p_regexec(&pat->re, line->ptr, 2, pmatch, 0)) {
453454
if (pat->flags & REG_NEGATE)
454455
return false;
455456

src/errors.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,16 +105,16 @@ void git_error_set_str(int error_class, const char *string)
105105
set_error_from_buffer(error_class);
106106
}
107107

108-
int git_error_set_regex(const regex_t *regex, int error_code)
108+
int git_error_set_regex(const p_regex_t *regex, int error_code)
109109
{
110110
char error_buf[1024];
111111

112112
assert(error_code);
113113

114-
regerror(error_code, regex, error_buf, sizeof(error_buf));
114+
p_regerror(error_code, regex, error_buf, sizeof(error_buf));
115115
git_error_set_str(GIT_ERROR_REGEX, error_buf);
116116

117-
if (error_code == REG_NOMATCH)
117+
if (error_code == P_REG_NOMATCH)
118118
return GIT_ENOTFOUND;
119119

120120
return GIT_EINVALIDSPEC;

src/posix_regex.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (C) the libgit2 contributors. All rights reserved.
3+
*
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.
6+
*/
7+
#ifndef INCLUDE_posix_regex_h__
8+
#define INCLUDE_posix_regex_h__
9+
10+
#include "common.h"
11+
#include <regex.h>
12+
13+
/*
14+
* Regular expressions: if the operating system has p_regcomp_l,
15+
* use that as our p_regcomp implementation, otherwise fall back
16+
* to standard regcomp.
17+
*/
18+
19+
#define P_REG_EXTENDED REG_EXTENDED
20+
#define P_REG_ICASE REG_ICASE
21+
#define P_REG_NOMATCH REG_NOMATCH
22+
23+
#define p_regex_t regex_t
24+
#define p_regmatch_t regmatch_t
25+
26+
#define p_regerror regerror
27+
#define p_regexec regexec
28+
#define p_regfree regfree
29+
30+
#ifdef GIT_USE_REGCOMP_L
31+
#include <xlocale.h>
32+
33+
GIT_INLINE(int) p_regcomp(p_regex_t *preg, const char *pattern, int cflags)
34+
{
35+
return regcomp_l(preg, pattern, cflags, (locale_t) 0);
36+
}
37+
#else
38+
# define p_regcomp regcomp
39+
#endif
40+
41+
#endif

0 commit comments

Comments
 (0)