Extended regexp syntax: IDENT:/EXPR/ fetches all messages whose header
IDENT matches given EXPR. The match is case-sensitive if IDENT starts with a capital letter and is case-insensitive otherwise.
Showing
2 changed files
with
64 additions
and
21 deletions
1 | 2001-08-14 Sergey Poznyakoff | ||
2 | |||
3 | * mail/msgset.y: Extended regexp syntax: IDENT:/EXPR/ fetches | ||
4 | all messages whose header IDENT matches given EXPR. The match | ||
5 | is case-sensitive if IDENT starts with a capital letter and | ||
6 | is case-insensitive otherwise. | ||
7 | |||
1 | 2001-08-12 Alain Magloire | 8 | 2001-08-12 Alain Magloire |
2 | 9 | ||
3 | * mailbox2/*: Move more code from the original mailbox | 10 | * mailbox2/*: Move more code from the original mailbox | ... | ... |
... | @@ -23,9 +23,15 @@ | ... | @@ -23,9 +23,15 @@ |
23 | #include <xalloc.h> | 23 | #include <xalloc.h> |
24 | #include <mail.h> | 24 | #include <mail.h> |
25 | 25 | ||
26 | struct header_data | ||
27 | { | ||
28 | char *header; | ||
29 | char *expr; | ||
30 | }; | ||
31 | |||
26 | static msgset_t *msgset_select (int (*sel)(), void *closure, int rev, | 32 | static msgset_t *msgset_select (int (*sel)(), void *closure, int rev, |
27 | int max_matches); | 33 | int max_matches); |
28 | static int select_subject (message_t msg, void *closure); | 34 | static int select_header (message_t msg, void *closure); |
29 | static int select_type (message_t msg, void *closure); | 35 | static int select_type (message_t msg, void *closure); |
30 | static int select_sender (message_t msg, void *closure); | 36 | static int select_sender (message_t msg, void *closure); |
31 | static int select_deleted (message_t msg, void *closure); | 37 | static int select_deleted (message_t msg, void *closure); |
... | @@ -41,9 +47,11 @@ static msgset_t *result; | ... | @@ -41,9 +47,11 @@ static msgset_t *result; |
41 | } | 47 | } |
42 | 48 | ||
43 | %token <type> TYPE | 49 | %token <type> TYPE |
44 | %token <string> IDENT REGEXP | 50 | %token <string> IDENT REGEXP HEADER |
45 | %token <number> NUMBER | 51 | %token <number> NUMBER |
46 | %type <mset> msgset msgspec msg rangeset range partno number | 52 | %type <mset> msgset msgspec msg rangeset range partno number |
53 | %type <string> header | ||
54 | |||
47 | %% | 55 | %% |
48 | 56 | ||
49 | input : /* empty */ | 57 | input : /* empty */ |
... | @@ -101,10 +109,15 @@ msgspec : msg | ... | @@ -101,10 +109,15 @@ msgspec : msg |
101 | | range | 109 | | range |
102 | ; | 110 | ; |
103 | 111 | ||
104 | msg : REGEXP /* /.../ */ | 112 | msg : header REGEXP /* /.../ */ |
105 | { | 113 | { |
106 | $$ = msgset_select (select_subject, (void *)$1, 0, 0); | 114 | struct header_data hd; |
107 | free ($1); | 115 | hd.header = $1; |
116 | hd.expr = $2; | ||
117 | $$ = msgset_select (select_header, &hd, 0, 0); | ||
118 | if ($1) | ||
119 | free ($1); | ||
120 | free ($2); | ||
108 | } | 121 | } |
109 | | TYPE /* :n, :d, etc */ | 122 | | TYPE /* :n, :d, etc */ |
110 | { | 123 | { |
... | @@ -122,6 +135,16 @@ msg : REGEXP /* /.../ */ | ... | @@ -122,6 +135,16 @@ msg : REGEXP /* /.../ */ |
122 | } | 135 | } |
123 | ; | 136 | ; |
124 | 137 | ||
138 | header : /* empty */ | ||
139 | { | ||
140 | $$ = NULL; | ||
141 | } | ||
142 | | HEADER | ||
143 | { | ||
144 | $$ = $1; | ||
145 | } | ||
146 | ; | ||
147 | |||
125 | rangeset : range | 148 | rangeset : range |
126 | | rangeset ',' range | 149 | | rangeset ',' range |
127 | { | 150 | { |
... | @@ -225,12 +248,17 @@ yylex() | ... | @@ -225,12 +248,17 @@ yylex() |
225 | char *p = cur_p; | 248 | char *p = cur_p; |
226 | int len; | 249 | int len; |
227 | 250 | ||
228 | while (*cur_p && *cur_p != ',' && *cur_p != '-') | 251 | while (*cur_p && *cur_p != ',' && *cur_p != '-' && *cur_p != ':') |
229 | cur_p++; | 252 | cur_p++; |
230 | len = cur_p - p + 1; | 253 | len = cur_p - p + 1; |
231 | yylval.string = xmalloc (len); | 254 | yylval.string = xmalloc (len); |
232 | memcpy (yylval.string, p, len-1); | 255 | memcpy (yylval.string, p, len-1); |
233 | yylval.string[len-1] = 0; | 256 | yylval.string[len-1] = 0; |
257 | if (*cur_p == ':') | ||
258 | { | ||
259 | ++cur_p; | ||
260 | return HEADER; | ||
261 | } | ||
234 | return IDENT; | 262 | return IDENT; |
235 | } | 263 | } |
236 | 264 | ||
... | @@ -434,13 +462,15 @@ msgset_select (int (*sel)(), void *closure, int rev, int max_matches) | ... | @@ -434,13 +462,15 @@ msgset_select (int (*sel)(), void *closure, int rev, int max_matches) |
434 | } | 462 | } |
435 | 463 | ||
436 | int | 464 | int |
437 | select_subject (message_t msg, void *closure) | 465 | select_header (message_t msg, void *closure) |
438 | { | 466 | { |
439 | char *expr = (char*) closure; | 467 | struct header_data *hd = (struct header_data *)closure; |
440 | header_t hdr; | 468 | header_t hdr; |
441 | char *subject; | 469 | char *contents; |
470 | char *header = hd->header ? hd->header : MU_HEADER_SUBJECT; | ||
471 | |||
442 | message_get_header (msg, &hdr); | 472 | message_get_header (msg, &hdr); |
443 | if (header_aget_value (hdr, MU_HEADER_SUBJECT, &subject) == 0) | 473 | if (header_aget_value (hdr, header, &contents) == 0) |
444 | { | 474 | { |
445 | if (!(util_find_env ("noregex"))->set) | 475 | if (!(util_find_env ("noregex"))->set) |
446 | { | 476 | { |
... | @@ -448,21 +478,27 @@ select_subject (message_t msg, void *closure) | ... | @@ -448,21 +478,27 @@ select_subject (message_t msg, void *closure) |
448 | case) in pattern, treating errors as no match. | 478 | case) in pattern, treating errors as no match. |
449 | Return 1 for match, 0 for no match. | 479 | Return 1 for match, 0 for no match. |
450 | */ | 480 | */ |
451 | regex_t re; | 481 | regex_t re; |
452 | int status; | 482 | int status; |
453 | if (regcomp (&re, expr, REG_EXTENDED | REG_ICASE) != 0) | 483 | int flags = REG_EXTENDED; |
454 | return 0; | 484 | |
455 | status = regexec (&re, subject, 0, NULL, 0); | 485 | if (islower (header[0])) |
456 | if (status != 0) | 486 | flags |= REG_ICASE; |
457 | return 0; | 487 | if (regcomp (&re, hd->expr, flags) != 0) |
458 | return status == 0; | 488 | { |
489 | free (contents); | ||
490 | return 0; | ||
491 | } | ||
492 | status = regexec (&re, contents, 0, NULL, 0); | ||
493 | free (contents); | ||
494 | return status == 0; | ||
459 | } | 495 | } |
460 | else | 496 | else |
461 | { | 497 | { |
462 | int rc; | 498 | int rc; |
463 | util_strupper (subject); | 499 | util_strupper (contents); |
464 | rc = strstr (subject, expr) != NULL; | 500 | rc = strstr (contents, hd->expr) != NULL; |
465 | free (subject); | 501 | free (contents); |
466 | return rc; | 502 | return rc; |
467 | } | 503 | } |
468 | } | 504 | } | ... | ... |
-
Please register or sign in to post a comment