From: David Bremner Date: Thu, 8 Jun 2017 02:11:48 +0000 (-0300) Subject: lib/index.cc: generalize filter state machine X-Git-Tag: 0.25_rc0~47 X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=commitdiff_plain;h=64f81f95a19b28681a74a58b8cae205bff885755;hp=4a085a51376d888185e6719c397832173a4ba159;ds=sidebyside lib/index.cc: generalize filter state machine To match things more complicated than fixed strings, we need states with multiple out arrows. --- diff --git a/lib/index.cc b/lib/index.cc index 19ddc39c..8a18abf4 100644 --- a/lib/index.cc +++ b/lib/index.cc @@ -159,16 +159,23 @@ filter_filter (GMimeFilter *gmime_filter, char *inbuf, size_t inlen, size_t pres g_mime_filter_set_size (gmime_filter, inlen, FALSE); outptr = gmime_filter->outbuf; + next = filter->state; while (inptr < inend) { - if (*inptr >= states[filter->state].a && - *inptr <= states[filter->state].b) - { - next = states[filter->state].next_if_match; - } - else - { - next = states[filter->state].next_if_not_match; - } + /* Each state is defined by a contiguous set of rows of the + * state table marked by a common value for '.state'. The + * state numbers must be equal to the index of the first row + * in a given state; thus the loop condition here looks for a + * jump to a first row of a state, which is a real transition + * in the underlying DFA. + */ + do { + if (*inptr >= states[next].a && *inptr <= states[next].b) { + next = states[next].next_if_match; + } else { + next = states[next].next_if_not_match; + } + + } while (next != states[next].state); if (filter->state < filter->first_skipping_state) *outptr++ = *inptr;