X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=miniexpect.c;h=eca8e9a9280a11a8f9a3dc79f1736d8d3460d017;hb=d568459fc424175df73779da8cae92fee466abf6;hp=f525b68630a7f15fa6b9d97abb7e9b2d634ff4af;hpb=5cac23de1963880d8fb3aed4be47ec2894cf520c;p=miniexpect.git diff --git a/miniexpect.c b/miniexpect.c index f525b68..eca8e9a 100644 --- a/miniexpect.c +++ b/miniexpect.c @@ -50,6 +50,7 @@ create_handle (void) h->pid = 0; h->timeout = 60000; h->read_size = 1024; + h->pcre_error = 0; h->buffer = NULL; h->len = h->alloc = 0; h->user1 = h->user2 = h->user3 = NULL; @@ -196,10 +197,7 @@ mexp_spawnv (const char *file, char **argv) } enum mexp_status -mexp_expect (mexp_h *h, const pcre *code, - const pcre_extra *extra, - int options, int *ovector, int ovecsize, - int *pcre_ret) +mexp_expect (mexp_h *h, const mexp_regexp *regexps, int *ovector, int ovecsize) { time_t start_t, now_t; int timeout; @@ -209,9 +207,11 @@ mexp_expect (mexp_h *h, const pcre *code, time (&start_t); - options |= PCRE_PARTIAL_SOFT; - /* Clear the read buffer. */ + /* XXX This is possibly incorrect because it throws away inputs that + * may not have been matched yet. A better idea is to record the + * end of the previous match and only throw that away. + */ clear_buffer (h); for (;;) { @@ -277,34 +277,50 @@ mexp_expect (mexp_h *h, const pcre *code, fprintf (stderr, "DEBUG: buffer content: %s\n", h->buffer); #endif - /* See if there is a full or partial match against the regular expression. */ - if (code) { + /* See if there is a full or partial match against any regexp. */ + if (regexps) { + size_t i; + int can_clear_buffer = 1; + assert (h->buffer != NULL); - r = pcre_exec (code, extra, h->buffer, (int)h->len, 0, - options, ovector, ovecsize); - if (pcre_ret) - *pcre_ret = r; - - if (r >= 0) { - /* A full match. */ - return MEXP_MATCHED; - } - else if (r == PCRE_ERROR_NOMATCH) { - /* No match at all, so we can dump the input buffer. */ - clear_buffer (h); + for (i = 0; regexps[i].r > 0; ++i) { + int options = regexps[i].options | PCRE_PARTIAL_SOFT; + + r = pcre_exec (regexps[i].re, regexps[i].extra, + h->buffer, (int)h->len, 0, + options, + ovector, ovecsize); + h->pcre_error = r; + + if (r >= 0) { + /* A full match. */ + return regexps[i].r; + } + + else if (r == PCRE_ERROR_NOMATCH) { + /* No match at all. */ + /* (nothing here) */ + } + + else if (r == PCRE_ERROR_PARTIAL) { + /* Partial match. Keep the buffer and keep reading. */ + can_clear_buffer = 0; + } + + else { + /* An actual PCRE error. */ + return MEXP_PCRE_ERROR; + } } - else if (r == PCRE_ERROR_PARTIAL) { - /* Partial match. Keep the buffer and keep reading. */ - /* (nothing here) */ - } + /* If none of the regular expressions matched (not partially) + * then we can clear the buffer. This is an optimization. + */ + if (can_clear_buffer) + clear_buffer (h); - else { - /* An actual PCRE error. */ - return MEXP_PCRE_ERROR; - } - } /* if (code) */ + } /* if (regexps) */ } }