dte test coverage


Directory: ./
File: src/regexp.h
Date: 2025-07-03 15:44:24
Exec Total Coverage
Lines: 8 8 100.0%
Functions: 2 2 100.0%
Branches: 2 6 33.3%

Line Branch Exec Source
1 #ifndef REGEXP_H
2 #define REGEXP_H
3
4 #include <regex.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 #include "command/error.h"
9 #include "util/macros.h"
10
11 enum {
12 #ifdef REG_ENHANCED
13 // The REG_ENHANCED flag enables various extensions on macOS
14 // (see "enhanced features" in re_format(7)). Most of these
15 // extensions are enabled by default on Linux (in both glibc
16 // and musl) without the need for any extra flags.
17 DEFAULT_REGEX_FLAGS = REG_EXTENDED | REG_ENHANCED,
18 #else
19 // POSIX Extended Regular Expressions (ERE) are used almost
20 // everywhere in this codebase, except where Basic Regular
21 // Expressions (BRE) are explicitly called for (most notably
22 // in search_tag(), which is used for ctags patterns).
23 DEFAULT_REGEX_FLAGS = REG_EXTENDED,
24 #endif
25 };
26
27 typedef struct {
28 const char *str; // Pattern string, interned by str_intern()
29 regex_t re; // regex(3) object, compiled with regcomp(3)
30 } InternedRegexp;
31
32 // Platform-specific patterns for matching word boundaries, as detected
33 // and initialized by regexp_init_word_boundary_tokens()
34 typedef struct {
35 char start[8];
36 char end[8];
37 uint8_t len;
38 } RegexpWordBoundaryTokens;
39
40 void regexp_compile_or_fatal_error(regex_t *re, const char *pattern, int flags) NONNULL_ARGS;
41 bool regexp_init_word_boundary_tokens(RegexpWordBoundaryTokens *rwbt) NONNULL_ARGS;
42 bool regexp_error_msg(ErrorBuffer *ebuf, const regex_t *re, const char *pattern, int err) NONNULL_ARG(2, 3);
43 char *regexp_escape(const char *pattern, size_t len) NONNULL_ARGS WARN_UNUSED_RESULT;
44 size_t regexp_escapeb(char *buf, size_t buflen, const char *pat, size_t plen) NONNULL_ARG(1) NONNULL_ARG_IF_NONZERO_LENGTH(3, 4);
45
46 const InternedRegexp *regexp_intern(ErrorBuffer *ebuf, const char *pattern) NONNULL_ARG(2) WARN_UNUSED_RESULT;
47 bool regexp_is_interned(const char *pattern) NONNULL_ARGS;
48 void free_interned_regexps(void);
49
50 WARN_UNUSED_RESULT NONNULL_ARGS
51 bool regexp_exec (
52 const regex_t *re,
53 const char *buf,
54 size_t size,
55 size_t nmatch,
56 regmatch_t *pmatch,
57 int flags
58 );
59
60 WARN_UNUSED_RESULT NONNULL_ARG(2, 3)
61 303 static inline bool regexp_compile(ErrorBuffer *ebuf, regex_t *re, const char *pattern, int flags)
62 {
63 303 int err = regcomp(re, pattern, flags | DEFAULT_REGEX_FLAGS);
64
1/4
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→7) taken 303 times.
✗ Branch 2 (5→6) not taken.
✗ Branch 3 (5→7) not taken.
303 return !err || regexp_error_msg(ebuf, re, pattern, err);
65 }
66
67 WARN_UNUSED_RESULT NONNULL_ARG(2)
68 56 static inline bool regexp_is_valid(ErrorBuffer *ebuf, const char *pattern, int flags)
69 {
70 56 regex_t re;
71
1/2
✓ Branch 0 (3→4) taken 56 times.
✗ Branch 1 (3→6) not taken.
56 if (!regexp_compile(ebuf, &re, pattern, flags | REG_NOSUB)) {
72 return false;
73 }
74 56 regfree(&re);
75 56 return true;
76 }
77
78 #endif
79