Added negation of message sets.
`from ! subject:/daily/' outputs all messages whose subject does not contain the word 'daily'.
Showing
1 changed file
with
45 additions
and
4 deletions
... | @@ -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 | { | ... | ... |
-
Please register or sign in to post a comment