NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
regex3.h File Reference

Manage regular expressions. More...

#include <regex.h>
#include <stdbool.h>
#include <stdint.h>
#include "queue.h"
#include <stddef.h>
+ Include dependency graph for regex3.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Regex
 Cached regular expression. More...
 
struct  RegexNode
 List of regular expressions. More...
 
struct  Replace
 List of regular expressions. More...
 

Macros

#define REG_WORDS   0
 
#define REG_COMP(preg, regex, cflags)
 Compile a regular expression.
 

Functions

static regoff_t mutt_regmatch_start (const regmatch_t *match)
 Return the start of a match.
 
static regoff_t mutt_regmatch_end (const regmatch_t *match)
 Return the end of a match.
 
static size_t mutt_regmatch_len (const regmatch_t *match)
 Return the length of a match.
 
 STAILQ_HEAD (RegexList, RegexNode)
 
 STAILQ_HEAD (ReplaceList, Replace)
 
struct Regexmutt_regex_compile (const char *str, uint16_t flags)
 Create an Regex from a string.
 
struct Regexmutt_regex_new (const char *str, uint32_t flags, struct Buffer *err)
 Create an Regex from a string.
 
void mutt_regex_free (struct Regex **ptr)
 Free a Regex object.
 
int mutt_regexlist_add (struct RegexList *rl, const char *str, uint16_t flags, struct Buffer *err)
 Compile a regex string and add it to a list.
 
void mutt_regexlist_free (struct RegexList *rl)
 Free a RegexList object.
 
bool mutt_regexlist_match (struct RegexList *rl, const char *str)
 Does a string match any Regex in the list?
 
struct RegexNodemutt_regexlist_new (void)
 Create a new RegexList.
 
int mutt_regexlist_remove (struct RegexList *rl, const char *str)
 Remove a Regex from a list.
 
int mutt_replacelist_add (struct ReplaceList *rl, const char *pat, const char *templ, struct Buffer *err)
 Add a pattern and a template to a list.
 
char * mutt_replacelist_apply (struct ReplaceList *rl, const char *str)
 Apply replacements to a buffer.
 
void mutt_replacelist_free (struct ReplaceList *rl)
 Free a ReplaceList object.
 
bool mutt_replacelist_match (struct ReplaceList *rl, char *buf, size_t buflen, const char *str)
 Does a string match a pattern?
 
struct Replacemutt_replacelist_new (void)
 Create a new ReplaceList.
 
int mutt_replacelist_remove (struct ReplaceList *rl, const char *pat)
 Remove a pattern from a list.
 
bool mutt_regex_match (const struct Regex *regex, const char *str)
 Shorthand to mutt_regex_capture()
 
bool mutt_regex_capture (const struct Regex *regex, const char *str, size_t num, regmatch_t matches[])
 Match a regex against a string, with provided options.
 

Detailed Description

Manage regular expressions.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file regex3.h.

Macro Definition Documentation

◆ REG_WORDS

#define REG_WORDS   0

Definition at line 38 of file regex3.h.

◆ REG_COMP

#define REG_COMP ( preg,
regex,
cflags )
Value:
regcomp(preg, regex, REG_WORDS | REG_EXTENDED | (cflags))
#define REG_WORDS
Definition regex3.h:38

Compile a regular expression.

Parameters
pregregex_t struct to fill
regexRegular expression string
cflagsFlags
Return values
0Success
numFailure, e.g. REG_BADPAT

Definition at line 49 of file regex3.h.

Function Documentation

◆ mutt_regmatch_start()

static regoff_t mutt_regmatch_start ( const regmatch_t * match)
inlinestatic

Return the start of a match.

Parameters
matchMatch
Return values
numStart of the match

Definition at line 56 of file regex3.h.

57{
58 return match->rm_so;
59}
+ Here is the caller graph for this function:

◆ mutt_regmatch_end()

static regoff_t mutt_regmatch_end ( const regmatch_t * match)
inlinestatic

Return the end of a match.

Parameters
matchMatch
Return values
numEnd of the match

Definition at line 66 of file regex3.h.

67{
68 return match->rm_eo;
69}
+ Here is the caller graph for this function:

◆ mutt_regmatch_len()

static size_t mutt_regmatch_len ( const regmatch_t * match)
inlinestatic

Return the length of a match.

Parameters
matchMatch
Return values
numLength of the match

Definition at line 76 of file regex3.h.

77{
78 return match->rm_eo - match->rm_so;
79}
+ Here is the caller graph for this function:

◆ STAILQ_HEAD() [1/2]

STAILQ_HEAD ( RegexList ,
RegexNode  )

◆ STAILQ_HEAD() [2/2]

STAILQ_HEAD ( ReplaceList ,
Replace  )

◆ mutt_regex_compile()

struct Regex * mutt_regex_compile ( const char * str,
uint16_t flags )

Create an Regex from a string.

Parameters
strRegular expression
flagsType flags, e.g. REG_ICASE
Return values
ptrNew Regex object
NULLError

Definition at line 59 of file regex.c.

60{
61 if (!str || (*str == '\0'))
62 return NULL;
63 struct Regex *rx = MUTT_MEM_CALLOC(1, struct Regex);
64 rx->pattern = mutt_str_dup(str);
65 rx->regex = MUTT_MEM_CALLOC(1, regex_t);
66 if (REG_COMP(rx->regex, str, flags) != 0)
67 mutt_regex_free(&rx);
68
69 return rx;
70}
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
void mutt_regex_free(struct Regex **ptr)
Free a Regex object.
Definition regex.c:118
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition regex3.h:49
Cached regular expression.
Definition regex3.h:85
char * pattern
printable version
Definition regex3.h:86
regex_t * regex
compiled expression
Definition regex3.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regex_new()

struct Regex * mutt_regex_new ( const char * str,
uint32_t flags,
struct Buffer * err )

Create an Regex from a string.

Parameters
strRegular expression
flagsType flags, e.g. D_REGEX_MATCH_CASE
errBuffer for error messages
Return values
ptrNew Regex object
NULLError

Definition at line 80 of file regex.c.

81{
82 if (!str || (*str == '\0'))
83 return NULL;
84
85 uint16_t rflags = 0;
86 struct Regex *reg = MUTT_MEM_CALLOC(1, struct Regex);
87
88 reg->regex = MUTT_MEM_CALLOC(1, regex_t);
89 reg->pattern = mutt_str_dup(str);
90
91 /* Should we use smart case matching? */
92 if (((flags & D_REGEX_MATCH_CASE) == 0) && mutt_mb_is_lower(str))
93 rflags |= REG_ICASE;
94
95 /* Is a prefix of '!' allowed? */
96 if (((flags & D_REGEX_ALLOW_NOT) != 0) && (str[0] == '!'))
97 {
98 reg->pat_not = true;
99 str++;
100 }
101
102 int rc = REG_COMP(reg->regex, str, rflags);
103 if (rc != 0)
104 {
105 if (err)
106 regerror(rc, reg->regex, err->data, err->dsize);
107 mutt_regex_free(&reg);
108 return NULL;
109 }
110
111 return reg;
112}
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
Definition mbyte.c:355
size_t dsize
Length of data.
Definition buffer.h:39
char * data
Pointer to data.
Definition buffer.h:37
bool pat_not
do not match
Definition regex3.h:88
#define D_REGEX_ALLOW_NOT
Regex can begin with '!'.
Definition types.h:107
#define D_REGEX_MATCH_CASE
Case-sensitive matching.
Definition types.h:106
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regex_free()

void mutt_regex_free ( struct Regex ** ptr)

Free a Regex object.

Parameters
[out]ptrRegex to free

Definition at line 118 of file regex.c.

119{
120 if (!ptr || !*ptr)
121 return;
122
123 struct Regex *rx = *ptr;
124 FREE(&rx->pattern);
125 if (rx->regex)
126 regfree(rx->regex);
127 FREE(&rx->regex);
128 FREE(ptr);
129}
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
+ Here is the caller graph for this function:

◆ mutt_regexlist_add()

int mutt_regexlist_add ( struct RegexList * rl,
const char * str,
uint16_t flags,
struct Buffer * err )

Compile a regex string and add it to a list.

Parameters
rlRegexList to add to
strString to compile into a regex
flagsFlags, e.g. REG_ICASE
errBuffer for error messages
Return values
0Success, Regex compiled and added to the list
-1Error, see message in 'err'

Definition at line 140 of file regex.c.

142{
143 if (!rl || !str || (*str == '\0'))
144 return 0;
145
146 struct Regex *rx = mutt_regex_compile(str, flags);
147 if (!rx)
148 {
149 buf_printf(err, "Bad regex: %s\n", str);
150 return -1;
151 }
152
153 /* check to make sure the item is not already on this rl */
154 struct RegexNode *np = NULL;
155 STAILQ_FOREACH(np, rl, entries)
156 {
157 if (mutt_istr_equal(rx->pattern, np->regex->pattern))
158 break; /* already on the rl */
159 }
160
161 if (np)
162 {
163 mutt_regex_free(&rx);
164 }
165 else
166 {
167 np = mutt_regexlist_new();
168 np->regex = rx;
169 STAILQ_INSERT_TAIL(rl, np, entries);
170 }
171
172 return 0;
173}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
struct RegexNode * mutt_regexlist_new(void)
Create a new RegexList.
Definition regex.c:222
struct Regex * mutt_regex_compile(const char *str, uint16_t flags)
Create an Regex from a string.
Definition regex.c:59
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:427
List of regular expressions.
Definition regex3.h:95
struct Regex * regex
Regex containing a regular expression.
Definition regex3.h:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regexlist_free()

void mutt_regexlist_free ( struct RegexList * rl)

Free a RegexList object.

Parameters
rlRegexList to free

Definition at line 179 of file regex.c.

180{
181 if (!rl)
182 return;
183
184 struct RegexNode *np = NULL;
185 struct RegexNode *tmp = NULL;
186 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
187 {
188 STAILQ_REMOVE(rl, np, RegexNode, entries);
190 FREE(&np);
191 }
192 STAILQ_INIT(rl);
193}
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_INIT(head)
Definition queue.h:410
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regexlist_match()

bool mutt_regexlist_match ( struct RegexList * rl,
const char * str )

Does a string match any Regex in the list?

Parameters
rlRegexList to match against
strString to compare
Return values
trueString matches one of the Regexes in the list

Definition at line 201 of file regex.c.

202{
203 if (!rl || !str)
204 return false;
205 struct RegexNode *np = NULL;
206 STAILQ_FOREACH(np, rl, entries)
207 {
208 if (mutt_regex_match(np->regex, str))
209 {
210 mutt_debug(LL_DEBUG5, "%s matches %s\n", str, np->regex->pattern);
211 return true;
212 }
213 }
214
215 return false;
216}
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition regex.c:618
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regexlist_new()

struct RegexNode * mutt_regexlist_new ( void )

Create a new RegexList.

Return values
ptrNew RegexList object

Definition at line 222 of file regex.c.

223{
224 return MUTT_MEM_CALLOC(1, struct RegexNode);
225}
+ Here is the caller graph for this function:

◆ mutt_regexlist_remove()

int mutt_regexlist_remove ( struct RegexList * rl,
const char * str )

Remove a Regex from a list.

Parameters
rlRegexList to alter
strPattern to remove from the list
Return values
0Success, pattern was found and removed from the list
-1Error, pattern wasn't found

If the pattern is "*", then all the Regexes are removed.

Definition at line 236 of file regex.c.

237{
238 if (!rl || !str)
239 return -1;
240
241 if (mutt_str_equal("*", str))
242 {
243 mutt_regexlist_free(rl); /* "unCMD *" means delete all current entries */
244 return 0;
245 }
246
247 int rc = -1;
248 struct RegexNode *np = NULL;
249 struct RegexNode *tmp = NULL;
250 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
251 {
252 if (mutt_istr_equal(str, np->regex->pattern))
253 {
254 STAILQ_REMOVE(rl, np, RegexNode, entries);
256 FREE(&np);
257 rc = 0;
258 }
259 }
260
261 return rc;
262}
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition regex.c:179
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_replacelist_add()

int mutt_replacelist_add ( struct ReplaceList * rl,
const char * pat,
const char * templ,
struct Buffer * err )

Add a pattern and a template to a list.

Parameters
rlReplaceList to add to
patPattern to compile into a regex
templTemplate string to associate with the pattern
errBuffer for error messages
Return values
0Success, pattern added to the ReplaceList
-1Error, see message in 'err'

Definition at line 273 of file regex.c.

275{
276 if (!rl || !pat || (*pat == '\0') || !templ)
277 return 0;
278
279 struct Regex *rx = mutt_regex_compile(pat, REG_ICASE);
280 if (!rx)
281 {
282 buf_printf(err, _("Bad regex: %s"), pat);
283 return -1;
284 }
285
286 /* check to make sure the item is not already on this rl */
287 struct Replace *np = NULL;
288 STAILQ_FOREACH(np, rl, entries)
289 {
290 if (mutt_istr_equal(rx->pattern, np->regex->pattern))
291 {
292 /* Already on the rl. Formerly we just skipped this case, but
293 * now we're supporting removals, which means we're supporting
294 * re-adds conceptually. So we probably want this to imply a
295 * removal, then do an add. We can achieve the removal by freeing
296 * the template, and leaving t pointed at the current item. */
297 FREE(&np->templ);
298 break;
299 }
300 }
301
302 /* If np is set, it's pointing into an extant ReplaceList* that we want to
303 * update. Otherwise we want to make a new one to link at the rl's end. */
304 if (np)
305 {
306 mutt_regex_free(&rx);
307 }
308 else
309 {
311 np->regex = rx;
312 rx = NULL;
313 STAILQ_INSERT_TAIL(rl, np, entries);
314 }
315
316 /* Now np is the Replace that we want to modify. It is prepared. */
317 np->templ = mutt_str_dup(templ);
318
319 /* Find highest match number in template string */
320 np->nmatch = 0;
321 for (const char *p = templ; *p;)
322 {
323 if (*p == '%')
324 {
325 int n = 0;
326 const char *end = mutt_str_atoi(++p, &n);
327 if (!end)
328 {
329 // this is not an error, we might have matched %R or %L in subject-regex
330 mutt_debug(LL_DEBUG2, "Invalid match number in replacelist: '%s'\n", p);
331 }
332 if (n > np->nmatch)
333 {
334 np->nmatch = n;
335 }
336 if (end)
337 {
338 p = end;
339 }
340 else
341 {
342 p++;
343 }
344 }
345 else
346 {
347 p++;
348 }
349 }
350
351 if (np->nmatch > np->regex->regex->re_nsub)
352 {
353 if (err)
354 buf_addstr(err, _("Not enough subexpressions for template"));
356 return -1;
357 }
358
359 np->nmatch++; /* match 0 is always the whole expr */
360 return 0;
361}
const char * mutt_str_atoi(const char *str, int *dst)
Convert ASCII string to an integer.
Definition atoi.c:191
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
#define _(a)
Definition message.h:28
int mutt_replacelist_remove(struct ReplaceList *rl, const char *pat)
Remove a pattern from a list.
Definition regex.c:569
struct Replace * mutt_replacelist_new(void)
Create a new ReplaceList.
Definition regex.c:558
List of regular expressions.
Definition regex3.h:105
char * templ
Template to match.
Definition regex3.h:108
size_t nmatch
Match the 'nth' occurrence (0 means the whole expression)
Definition regex3.h:107
struct Regex * regex
Regex containing a regular expression.
Definition regex3.h:106
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_replacelist_apply()

char * mutt_replacelist_apply ( struct ReplaceList * rl,
const char * str )

Apply replacements to a buffer.

Parameters
rlReplaceList to apply
strString to manipulate
Return values
ptrNew string with replacements
Note
Caller must free the returned string

Definition at line 371 of file regex.c.

372{
373 if (!rl || !str || (*str == '\0'))
374 return NULL;
375
376 static regmatch_t *pmatch = NULL;
377 static size_t nmatch = 0;
378 char *p = NULL;
379
380 struct Buffer *src = buf_pool_get();
381 struct Buffer *dst = buf_pool_get();
382
383 buf_strcpy(src, str);
384
385 struct Replace *np = NULL;
386 STAILQ_FOREACH(np, rl, entries)
387 {
388 /* If this pattern needs more matches, expand pmatch. */
389 if (np->nmatch > nmatch)
390 {
391 MUTT_MEM_REALLOC(&pmatch, np->nmatch, regmatch_t);
392 nmatch = np->nmatch;
393 }
394
395 if (mutt_regex_capture(np->regex, buf_string(src), np->nmatch, pmatch))
396 {
397 mutt_debug(LL_DEBUG5, "%s matches %s\n", buf_string(src), np->regex->pattern);
398
399 buf_reset(dst);
400 if (np->templ)
401 {
402 for (p = np->templ; *p;)
403 {
404 if (*p == '%')
405 {
406 p++;
407 if (*p == 'L')
408 {
409 p++;
410 buf_addstr_n(dst, buf_string(src), pmatch[0].rm_so);
411 }
412 else if (*p == 'R')
413 {
414 p++;
415 buf_addstr(dst, src->data + pmatch[0].rm_eo);
416 }
417 else
418 {
419 long n = strtoul(p, &p, 10); /* get subst number */
420 if (n < np->nmatch)
421 {
422 buf_addstr_n(dst, src->data + pmatch[n].rm_so,
423 pmatch[n].rm_eo - pmatch[n].rm_so);
424 }
425 while (mutt_isdigit(*p)) /* skip subst token */
426 p++;
427 }
428 }
429 else
430 {
431 buf_addch(dst, *p++);
432 }
433 }
434 }
435
436 buf_strcpy(src, buf_string(dst));
437 mutt_debug(LL_DEBUG5, "subst %s\n", buf_string(dst));
438 }
439 }
440
441 char *result = buf_strdup(src);
442
443 buf_pool_release(&src);
444 buf_pool_release(&dst);
445 return result;
446}
size_t buf_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition buffer.c:109
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:248
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:577
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
bool mutt_isdigit(int arg)
Wrapper for isdigit(3)
Definition ctype.c:66
#define MUTT_MEM_REALLOC(pptr, n, type)
Definition memory.h:55
bool mutt_regex_capture(const struct Regex *regex, const char *str, size_t nmatch, regmatch_t matches[])
Match a regex against a string, with provided options.
Definition regex.c:601
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_replacelist_free()

void mutt_replacelist_free ( struct ReplaceList * rl)

Free a ReplaceList object.

Parameters
rlReplaceList to free

Definition at line 452 of file regex.c.

453{
454 if (!rl)
455 return;
456
457 struct Replace *np = NULL;
458 struct Replace *tmp = NULL;
459 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
460 {
461 STAILQ_REMOVE(rl, np, Replace, entries);
463 FREE(&np->templ);
464 FREE(&np);
465 }
466}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_replacelist_match()

bool mutt_replacelist_match ( struct ReplaceList * rl,
char * buf,
size_t buflen,
const char * str )

Does a string match a pattern?

Parameters
rlReplaceList of patterns
bufBuffer to save match
buflenBuffer length
strString to check
Return values
trueString matches a patterh in the ReplaceList

Match a string against the patterns defined by the 'spam' command and output the expanded format into buf when there is a match. If buflen<=0, the match is performed but the format is not expanded and no assumptions are made about the value of buf so it may be NULL.

Definition at line 481 of file regex.c.

482{
483 if (!rl || !buf || !str)
484 return false;
485
486 static regmatch_t *pmatch = NULL;
487 static size_t nmatch = 0;
488 int tlen = 0;
489 char *p = NULL;
490
491 struct Replace *np = NULL;
492 STAILQ_FOREACH(np, rl, entries)
493 {
494 /* If this pattern needs more matches, expand pmatch. */
495 if (np->nmatch > nmatch)
496 {
497 MUTT_MEM_REALLOC(&pmatch, np->nmatch, regmatch_t);
498 nmatch = np->nmatch;
499 }
500
501 /* Does this pattern match? */
502 if (mutt_regex_capture(np->regex, str, (size_t) np->nmatch, pmatch))
503 {
504 mutt_debug(LL_DEBUG5, "%s matches %s\n", str, np->regex->pattern);
505 mutt_debug(LL_DEBUG5, "%d subs\n", (int) np->regex->regex->re_nsub);
506
507 /* Copy template into buf, with substitutions. */
508 for (p = np->templ; *p && (tlen < (buflen - 1));)
509 {
510 /* backreference to pattern match substring, eg. %1, %2, etc) */
511 if (*p == '%')
512 {
513 char *e = NULL; /* used as pointer to end of integer backreference in strtol() call */
514
515 p++; /* skip over % char */
516 long n = strtol(p, &e, 10);
517 /* Ensure that the integer conversion succeeded (e!=p) and bounds check. The upper bound check
518 * should not strictly be necessary since add_to_spam_list() finds the largest value, and
519 * the static array above is always large enough based on that value. */
520 if ((e != p) && (n >= 0) && (n < np->nmatch) && (pmatch[n].rm_so != -1))
521 {
522 /* copy as much of the substring match as will fit in the output buffer, saving space for
523 * the terminating nul char */
524 for (int idx = pmatch[n].rm_so;
525 (idx < pmatch[n].rm_eo) && (tlen < (buflen - 1)); idx++)
526 {
527 buf[tlen++] = str[idx];
528 }
529 }
530 p = e; /* skip over the parsed integer */
531 }
532 else
533 {
534 buf[tlen++] = *p++;
535 }
536 }
537 /* tlen should always be less than buflen except when buflen<=0
538 * because the bounds checks in the above code leave room for the
539 * terminal nul char. This should avoid returning an unterminated
540 * string to the caller. When buflen<=0 we make no assumption about
541 * the validity of the buf pointer. */
542 if (tlen < buflen)
543 {
544 buf[tlen] = '\0';
545 mutt_debug(LL_DEBUG5, "\"%s\"\n", buf);
546 }
547 return true;
548 }
549 }
550
551 return false;
552}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_replacelist_new()

struct Replace * mutt_replacelist_new ( void )

Create a new ReplaceList.

Return values
ptrNew ReplaceList

Definition at line 558 of file regex.c.

559{
560 return MUTT_MEM_CALLOC(1, struct Replace);
561}
+ Here is the caller graph for this function:

◆ mutt_replacelist_remove()

int mutt_replacelist_remove ( struct ReplaceList * rl,
const char * pat )

Remove a pattern from a list.

Parameters
rlReplaceList to modify
patPattern to remove
Return values
numMatching patterns removed

Definition at line 569 of file regex.c.

570{
571 if (!rl || !pat)
572 return 0;
573
574 int nremoved = 0;
575 struct Replace *np = NULL;
576 struct Replace *tmp = NULL;
577 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
578 {
579 if (mutt_str_equal(np->regex->pattern, pat))
580 {
581 STAILQ_REMOVE(rl, np, Replace, entries);
583 FREE(&np->templ);
584 FREE(&np);
585 nremoved++;
586 }
587 }
588
589 return nremoved;
590}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regex_match()

bool mutt_regex_match ( const struct Regex * regex,
const char * str )

Shorthand to mutt_regex_capture()

Parameters
regexRegex which is desired to match against
strString to search with given regex
Return values
truestr matches
falsestr does not match

Definition at line 618 of file regex.c.

619{
620 return mutt_regex_capture(regex, str, 0, NULL);
621}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_regex_capture()

bool mutt_regex_capture ( const struct Regex * regex,
const char * str,
size_t nmatch,
regmatch_t matches[] )

Match a regex against a string, with provided options.

Parameters
regexRegex to execute
strString to apply regex on
nmatchLength of matches
matchesregmatch_t to hold match indices
Return values
truestr matches
falsestr does not match

Definition at line 601 of file regex.c.

603{
604 if (!regex || !str || !regex->regex)
605 return false;
606
607 int rc = regexec(regex->regex, str, nmatch, matches, 0);
608 return ((rc == 0) ^ regex->pat_not);
609}
+ Here is the caller graph for this function: