Commit 63d9bc1e 63d9bc1ed24e7bedcc48db1e312328e9771dc511 by Sergey Poznyakoff

Added negation of message sets.

`from ! subject:/daily/' outputs all messages whose subject
does not contain the word 'daily'.
1 parent 44986146
...@@ -63,7 +63,7 @@ static msgset_t *result; ...@@ -63,7 +63,7 @@ static msgset_t *result;
63 %token <type> TYPE 63 %token <type> TYPE
64 %token <string> IDENT REGEXP HEADER BODY 64 %token <string> IDENT REGEXP HEADER BODY
65 %token <number> NUMBER 65 %token <number> NUMBER
66 %type <mset> msgset msgspec msg rangeset range partno number 66 %type <mset> msgset msgspec msgexpr msg rangeset range partno number
67 %type <string> header 67 %type <string> header
68 68
69 %% 69 %%
...@@ -102,17 +102,28 @@ input : /* empty */ ...@@ -102,17 +102,28 @@ input : /* empty */
102 } 102 }
103 ; 103 ;
104 104
105 msgset : msgspec 105 msgset : msgexpr
106 | msgset ',' msgspec 106 | msgset ',' msgexpr
107 { 107 {
108 $$ = msgset_append ($1, $3); 108 $$ = msgset_append ($1, $3);
109 } 109 }
110 | msgset msgspec 110 | msgset msgexpr
111 { 111 {
112 $$ = msgset_append ($1, $2); 112 $$ = msgset_append ($1, $2);
113 } 113 }
114 ; 114 ;
115 115
116 msgexpr : msgspec
117 | '{' msgset '}'
118 {
119 $$ = $2;
120 }
121 | '!' msgexpr
122 {
123 $$ = msgset_negate ($2);
124 }
125 ;
126
116 msgspec : msg 127 msgspec : msg
117 | msg '[' rangeset ']' 128 | msg '[' rangeset ']'
118 { 129 {
...@@ -390,6 +401,36 @@ msgset_append (msgset_t *one, msgset_t *two) ...@@ -390,6 +401,36 @@ msgset_append (msgset_t *one, msgset_t *two)
390 return one; 401 return one;
391 } 402 }
392 403
404 int
405 msgset_member (msgset_t *set, size_t n)
406 {
407 for (; set; set = set->next)
408 if (set->msg_part[0] == n)
409 return 1;
410 return 0;
411 }
412
413 msgset_t *
414 msgset_negate (msgset_t *set)
415 {
416 size_t i;
417 msgset_t *first = NULL, *last = NULL;
418
419 for (i = 1; i < total; i++)
420 {
421 if (!msgset_member (set, i))
422 {
423 msgset_t *mp = msgset_make_1 (i);
424 if (!first)
425 first = mp;
426 else
427 last->next = mp;
428 last = mp;
429 }
430 }
431 return first;
432 }
433
393 msgset_t * 434 msgset_t *
394 msgset_range (int low, int high) 435 msgset_range (int low, int high)
395 { 436 {
......