NeoMutt  2023-03-22-27-g3cb248
Teaching an old dog new tricks
DOXYGEN
regex.c File Reference

Manage regular expressions. More...

#include "config.h"
#include <ctype.h>
#include <regex.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "atoi.h"
#include "buffer.h"
#include "logging.h"
#include "mbyte.h"
#include "memory.h"
#include "message.h"
#include "queue.h"
#include "regex3.h"
#include "string2.h"
+ Include dependency graph for regex.c:

Go to the source code of this file.

Functions

struct Regexmutt_regex_compile (const char *str, uint16_t flags)
 Create an Regex from a string. More...
 
struct Regexmutt_regex_new (const char *str, uint32_t flags, struct Buffer *err)
 Create an Regex from a string. More...
 
void mutt_regex_free (struct Regex **r)
 Free a Regex object. More...
 
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. More...
 
void mutt_regexlist_free (struct RegexList *rl)
 Free a RegexList object. More...
 
bool mutt_regexlist_match (struct RegexList *rl, const char *str)
 Does a string match any Regex in the list? More...
 
struct RegexNodemutt_regexlist_new (void)
 Create a new RegexList. More...
 
int mutt_regexlist_remove (struct RegexList *rl, const char *str)
 Remove a Regex from a list. More...
 
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. More...
 
char * mutt_replacelist_apply (struct ReplaceList *rl, char *buf, size_t buflen, const char *str)
 Apply replacements to a buffer. More...
 
void mutt_replacelist_free (struct ReplaceList *rl)
 Free a ReplaceList object. More...
 
bool mutt_replacelist_match (struct ReplaceList *rl, char *buf, size_t buflen, const char *str)
 Does a string match a pattern? More...
 
struct Replacemutt_replacelist_new (void)
 Create a new ReplaceList. More...
 
int mutt_replacelist_remove (struct ReplaceList *rl, const char *pat)
 Remove a pattern from a list. More...
 
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. More...
 
bool mutt_regex_match (const struct Regex *regex, const char *str)
 Shorthand to mutt_regex_capture() More...
 

Detailed Description

Manage regular expressions.

Authors
  • Richard Russon
  • Simon Symeonidis

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 regex.c.

Function Documentation

◆ 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 55 of file regex.c.

56{
57 if (!str || (*str == '\0'))
58 return NULL;
59 struct Regex *rx = mutt_mem_calloc(1, sizeof(struct Regex));
60 rx->pattern = mutt_str_dup(str);
61 rx->regex = mutt_mem_calloc(1, sizeof(regex_t));
62 if (REG_COMP(rx->regex, str, flags) != 0)
63 mutt_regex_free(&rx);
64
65 return rx;
66}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void mutt_regex_free(struct Regex **r)
Free a Regex object.
Definition: regex.c:114
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
Cached regular expression.
Definition: regex3.h:89
char * pattern
printable version
Definition: regex3.h:90
regex_t * regex
compiled expression
Definition: regex3.h:91
+ 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. DT_REGEX_MATCH_CASE
errBuffer for error messages
Return values
ptrNew Regex object
NULLError

Definition at line 76 of file regex.c.

77{
78 if (!str || (*str == '\0'))
79 return NULL;
80
81 uint16_t rflags = 0;
82 struct Regex *reg = mutt_mem_calloc(1, sizeof(struct Regex));
83
84 reg->regex = mutt_mem_calloc(1, sizeof(regex_t));
85 reg->pattern = mutt_str_dup(str);
86
87 /* Should we use smart case matching? */
88 if (((flags & DT_REGEX_MATCH_CASE) == 0) && mutt_mb_is_lower(str))
89 rflags |= REG_ICASE;
90
91 /* Is a prefix of '!' allowed? */
92 if (((flags & DT_REGEX_ALLOW_NOT) != 0) && (str[0] == '!'))
93 {
94 reg->pat_not = true;
95 str++;
96 }
97
98 int rc = REG_COMP(reg->regex, str, rflags);
99 if (rc != 0)
100 {
101 if (err)
102 regerror(rc, reg->regex, err->data, err->dsize);
103 mutt_regex_free(&reg);
104 return NULL;
105 }
106
107 return reg;
108}
bool mutt_mb_is_lower(const char *s)
Does a multi-byte string contain only lowercase characters?
Definition: mbyte.c:357
#define DT_REGEX_ALLOW_NOT
Regex can begin with '!'.
Definition: regex3.h:36
#define DT_REGEX_MATCH_CASE
Case-sensitive matching.
Definition: regex3.h:35
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
bool pat_not
do not match
Definition: regex3.h:92
+ 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 **  r)

Free a Regex object.

Parameters
[out]rRegex to free

Definition at line 114 of file regex.c.

115{
116 if (!r || !*r)
117 return;
118
119 FREE(&(*r)->pattern);
120 if ((*r)->regex)
121 regfree((*r)->regex);
122 FREE(&(*r)->regex);
123 FREE(r);
124}
#define FREE(x)
Definition: memory.h:43
+ 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 135 of file regex.c.

137{
138 if (!rl || !str || (*str == '\0'))
139 return 0;
140
141 struct Regex *rx = mutt_regex_compile(str, flags);
142 if (!rx)
143 {
144 mutt_buffer_printf(err, "Bad regex: %s\n", str);
145 return -1;
146 }
147
148 /* check to make sure the item is not already on this rl */
149 struct RegexNode *np = NULL;
150 STAILQ_FOREACH(np, rl, entries)
151 {
152 if (mutt_istr_equal(rx->pattern, np->regex->pattern))
153 break; /* already on the rl */
154 }
155
156 if (np)
157 {
158 mutt_regex_free(&rx);
159 }
160 else
161 {
162 np = mutt_regexlist_new();
163 np->regex = rx;
164 STAILQ_INSERT_TAIL(rl, np, entries);
165 }
166
167 return 0;
168}
int mutt_buffer_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:216
struct Regex * mutt_regex_compile(const char *str, uint16_t flags)
Create an Regex from a string.
Definition: regex.c:55
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
List of regular expressions.
Definition: regex3.h:99
struct Regex * regex
Regex containing a regular expression.
Definition: regex3.h:100
+ 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 174 of file regex.c.

175{
176 if (!rl)
177 return;
178
179 struct RegexNode *np = NULL, *tmp = NULL;
180 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
181 {
182 STAILQ_REMOVE(rl, np, RegexNode, entries);
184 FREE(&np);
185 }
186 STAILQ_INIT(rl);
187}
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_INIT(head)
Definition: queue.h:372
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
+ 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 195 of file regex.c.

196{
197 if (!rl || !str)
198 return false;
199 struct RegexNode *np = NULL;
200 STAILQ_FOREACH(np, rl, entries)
201 {
202 if (mutt_regex_match(np->regex, str))
203 {
204 mutt_debug(LL_DEBUG5, "%s matches %s\n", str, np->regex->pattern);
205 return true;
206 }
207 }
208
209 return false;
210}
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:635
+ 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 216 of file regex.c.

217{
218 return mutt_mem_calloc(1, sizeof(struct RegexNode));
219}
+ Here is the call graph for this function:
+ 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 230 of file regex.c.

231{
232 if (!rl || !str)
233 return -1;
234
235 if (mutt_str_equal("*", str))
236 {
237 mutt_regexlist_free(rl); /* "unCMD *" means delete all current entries */
238 return 0;
239 }
240
241 int rc = -1;
242 struct RegexNode *np = NULL, *tmp = NULL;
243 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
244 {
245 if (mutt_istr_equal(str, np->regex->pattern))
246 {
247 STAILQ_REMOVE(rl, np, RegexNode, entries);
249 FREE(&np);
250 rc = 0;
251 }
252 }
253
254 return rc;
255}
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:174
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
+ 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 266 of file regex.c.

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

Apply replacements to a buffer.

Parameters
rlReplaceList to apply
bufBuffer for the result
buflenLength of the buffer
strString to manipulate
Return values
ptrPointer to 'buf'

If 'buf' is NULL, a new string will be returned. It must be freed by the caller.

Note
This function uses a fixed size buffer of 1024 and so should only be used for visual modifications, such as disp_subj.

Definition at line 370 of file regex.c.

371{
372 static regmatch_t *pmatch = NULL;
373 static size_t nmatch = 0;
374 static char twinbuf[2][1024];
375 int switcher = 0;
376 char *p = NULL;
377 size_t cpysize, tlen;
378 char *src = NULL, *dst = NULL;
379
380 if (buf && (buflen != 0))
381 buf[0] = '\0';
382
383 if (!rl || !str || (*str == '\0') || (buf && (buflen == 0)))
384 return buf;
385
386 twinbuf[0][0] = '\0';
387 twinbuf[1][0] = '\0';
388 src = twinbuf[switcher];
389 dst = src;
390
391 mutt_str_copy(src, str, sizeof(*twinbuf));
392
393 struct Replace *np = NULL;
394 STAILQ_FOREACH(np, rl, entries)
395 {
396 /* If this pattern needs more matches, expand pmatch. */
397 if (np->nmatch > nmatch)
398 {
399 mutt_mem_realloc(&pmatch, np->nmatch * sizeof(regmatch_t));
400 nmatch = np->nmatch;
401 }
402
403 if (mutt_regex_capture(np->regex, src, np->nmatch, pmatch))
404 {
405 tlen = 0;
406 switcher ^= 1;
407 dst = twinbuf[switcher];
408
409 mutt_debug(LL_DEBUG5, "%s matches %s\n", src, np->regex->pattern);
410
411 /* Copy into other twinbuf with substitutions */
412 if (np->templ)
413 {
414 for (p = np->templ; *p && (tlen < (sizeof(*twinbuf) - 1));)
415 {
416 if (*p == '%')
417 {
418 p++;
419 if (*p == 'L')
420 {
421 p++;
422 cpysize = MIN(pmatch[0].rm_so, (sizeof(*twinbuf) - 1) - tlen);
423 strncpy(&dst[tlen], src, cpysize);
424 tlen += cpysize;
425 }
426 else if (*p == 'R')
427 {
428 p++;
429 cpysize = MIN(strlen(src) - pmatch[0].rm_eo, (sizeof(*twinbuf) - 1) - tlen);
430 strncpy(&dst[tlen], &src[pmatch[0].rm_eo], cpysize);
431 tlen += cpysize;
432 }
433 else
434 {
435 long n = strtoul(p, &p, 10); /* get subst number */
436 if (n < np->nmatch)
437 {
438 while (isdigit((unsigned char) *p)) /* skip subst token */
439 p++;
440 for (int i = pmatch[n].rm_so;
441 (i < pmatch[n].rm_eo) && (tlen < (sizeof(*twinbuf) - 1)); i++)
442 {
443 dst[tlen++] = src[i];
444 }
445 }
446 }
447 }
448 else
449 {
450 dst[tlen++] = *p++;
451 }
452 }
453 }
454 dst[tlen] = '\0';
455 mutt_debug(LL_DEBUG5, "subst %s\n", dst);
456 }
457 src = dst;
458 }
459
460 if (buf)
461 mutt_str_copy(buf, dst, buflen);
462 else
463 buf = mutt_str_dup(dst);
464 return buf;
465}
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
#define MIN(a, b)
Definition: memory.h:31
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:618
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:652
+ 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 471 of file regex.c.

472{
473 if (!rl)
474 return;
475
476 struct Replace *np = NULL, *tmp = NULL;
477 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
478 {
479 STAILQ_REMOVE(rl, np, Replace, entries);
481 FREE(&np->templ);
482 FREE(&np);
483 }
484}
+ 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 499 of file regex.c.

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

577{
578 return mutt_mem_calloc(1, sizeof(struct Replace));
579}
+ Here is the call graph for this function:
+ 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 587 of file regex.c.

588{
589 if (!rl || !pat)
590 return 0;
591
592 int nremoved = 0;
593 struct Replace *np = NULL, *tmp = NULL;
594 STAILQ_FOREACH_SAFE(np, rl, entries, tmp)
595 {
596 if (mutt_str_equal(np->regex->pattern, pat))
597 {
598 STAILQ_REMOVE(rl, np, Replace, entries);
600 FREE(&np->templ);
601 FREE(&np);
602 nremoved++;
603 }
604 }
605
606 return nremoved;
607}
+ 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 618 of file regex.c.

620{
621 if (!regex || !str || !regex->regex)
622 return false;
623
624 int rc = regexec(regex->regex, str, nmatch, matches, 0);
625 return ((rc == 0) ^ regex->pat_not);
626}
+ 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 635 of file regex.c.

636{
637 return mutt_regex_capture(regex, str, 0, NULL);
638}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: