Commit 621726ac 621726ac90e3678f5c40b67aa3053ffde05d4161 by Sergey Poznyakoff

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.
1 parent 6025666d
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 }
......