X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=miniexpect.c;h=e1a184ce10e9b0bf03aeb8a1afb0c7af816ae84e;hb=ef57e4a7956ef591db6578d8ca928b4287e75a3f;hp=7f02584d500bbb9acf7b4c1557146f3093dba8fd;hpb=469839bd6141f85d6382dc1878d97456ff80d9ea;p=miniexpect.git diff --git a/miniexpect.c b/miniexpect.c index 7f02584..e1a184c 100644 --- a/miniexpect.c +++ b/miniexpect.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,13 @@ #include +/* RHEL 6 pcre did not define PCRE_PARTIAL_SOFT. However PCRE_PARTIAL + * is a synonym so use that. + */ +#ifndef PCRE_PARTIAL_SOFT +#define PCRE_PARTIAL_SOFT PCRE_PARTIAL +#endif + #include "miniexpect.h" #define DEBUG 0 @@ -53,6 +61,7 @@ create_handle (void) h->pcre_error = 0; h->buffer = NULL; h->len = h->alloc = 0; + h->next_match = -1; h->user1 = h->user2 = h->user3 = NULL; return h; @@ -64,6 +73,7 @@ clear_buffer (mexp_h *h) free (h->buffer); h->buffer = NULL; h->alloc = h->len = 0; + h->next_match = -1; } int @@ -104,6 +114,7 @@ mexp_spawnl (const char *file, const char *arg, ...) new_argv = realloc (argv, sizeof (char *) * (i+1)); if (new_argv == NULL) { free (argv); + va_end (args); return NULL; } argv = new_argv; @@ -112,13 +123,14 @@ mexp_spawnl (const char *file, const char *arg, ...) h = mexp_spawnv (file, argv); free (argv); + va_end (args); return h; } mexp_h * mexp_spawnv (const char *file, char **argv) { - mexp_h *h; + mexp_h *h = NULL; int fd = -1; int err; char slave[1024]; @@ -194,6 +206,8 @@ mexp_spawnv (const char *file, char **argv) close (fd); if (pid > 0) waitpid (pid, NULL, 0); + if (h != NULL) + mexp_close (h); errno = err; return NULL; } @@ -209,12 +223,19 @@ mexp_expect (mexp_h *h, const mexp_regexp *regexps, int *ovector, int ovecsize) time (&start_t); - /* 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); + if (h->next_match == -1) { + /* Fully clear the buffer, then read. */ + clear_buffer (h); + } else { + /* See the comment in the manual about h->next_match. We have + * some data remaining in the buffer, so begin by matching that. + */ + memmove (&h->buffer[0], &h->buffer[h->next_match], h->len - h->next_match); + h->len -= h->next_match; + h->buffer[h->len] = '\0'; + h->next_match = -1; + goto try_match; + } for (;;) { /* If we've got a timeout then work out how many seconds are left. @@ -279,6 +300,7 @@ mexp_expect (mexp_h *h, const mexp_regexp *regexps, int *ovector, int ovecsize) fprintf (stderr, "DEBUG: buffer content: %s\n", h->buffer); #endif + try_match: /* See if there is a full or partial match against any regexp. */ if (regexps) { size_t i; @@ -297,6 +319,10 @@ mexp_expect (mexp_h *h, const mexp_regexp *regexps, int *ovector, int ovecsize) if (r >= 0) { /* A full match. */ + if (ovector != NULL && ovecsize >= 1 && ovector[1] >= 0) + h->next_match = ovector[1]; + else + h->next_match = -1; return regexps[i].r; }