diff options
Diffstat (limited to 'lib/libedit/tokenizer.c')
-rw-r--r-- | lib/libedit/tokenizer.c | 585 |
1 files changed, 300 insertions, 285 deletions
diff --git a/lib/libedit/tokenizer.c b/lib/libedit/tokenizer.c index 6f152838803..da1c64fdcb0 100644 --- a/lib/libedit/tokenizer.c +++ b/lib/libedit/tokenizer.c @@ -1,5 +1,5 @@ -/* $OpenBSD: tokenizer.c,v 1.8 2003/08/11 18:21:40 deraadt Exp $ */ -/* $NetBSD: tokenizer.c,v 1.2 1997/01/11 06:48:15 lukem Exp $ */ +/* $OpenBSD: tokenizer.c,v 1.9 2003/10/31 08:42:24 otto Exp $ */ +/* $NetBSD: tokenizer.c,v 1.12 2003/08/07 16:44:34 agc Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -33,46 +33,48 @@ * SUCH DAMAGE. */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; #else -static const char rcsid[] = "$OpenBSD: tokenizer.c,v 1.8 2003/08/11 18:21:40 deraadt Exp $"; +static const char rcsid[] = "$OpenBSD: tokenizer.c,v 1.9 2003/10/31 08:42:24 otto Exp $"; #endif #endif /* not lint && not SCCSID */ /* * tokenize.c: Bourne shell like tokenizer */ -#include "sys.h" #include <string.h> #include <stdlib.h> #include "tokenizer.h" -typedef enum { Q_none, Q_single, Q_double, Q_one, Q_doubleone } quote_t; +typedef enum { + Q_none, Q_single, Q_double, Q_one, Q_doubleone +} quote_t; -#define IFS "\t \n" +#define IFS "\t \n" -#define TOK_KEEP 1 -#define TOK_EAT 2 +#define TOK_KEEP 1 +#define TOK_EAT 2 -#define WINCR 20 -#define AINCR 10 +#define WINCR 20 +#define AINCR 10 -#define tok_malloc(a) malloc(a) -#define tok_free(a) free(a) -#define tok_realloc(a, b) realloc(a, b) +#define tok_malloc(a) malloc(a) +#define tok_free(a) free(a) +#define tok_realloc(a, b) realloc(a, b) struct tokenizer { - char *ifs; /* In field separator */ - int argc, amax; /* Current and maximum number of args */ - char **argv; /* Argument list */ - char *wptr, *wmax; /* Space and limit on the word buffer */ - char *wstart; /* Beginning of next word */ - char *wspace; /* Space of word buffer */ - quote_t quote; /* Quoting state */ - int flags; /* flags; */ + char *ifs; /* In field separator */ + int argc, amax; /* Current and maximum number of args */ + char **argv; /* Argument list */ + char *wptr, *wmax; /* Space and limit on the word buffer */ + char *wstart; /* Beginning of next word */ + char *wspace; /* Space of word buffer */ + quote_t quote; /* Quoting state */ + int flags; /* flags; */ }; @@ -83,16 +85,16 @@ private void tok_finish(Tokenizer *); * Finish a word in the tokenizer. */ private void -tok_finish(tok) - Tokenizer *tok; +tok_finish(Tokenizer *tok) { - *tok->wptr = '\0'; - if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) { - tok->argv[tok->argc++] = tok->wstart; - tok->argv[tok->argc] = NULL; - tok->wstart = ++tok->wptr; - } - tok->flags &= ~TOK_KEEP; + + *tok->wptr = '\0'; + if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) { + tok->argv[tok->argc++] = tok->wstart; + tok->argv[tok->argc] = NULL; + tok->wstart = ++tok->wptr; + } + tok->flags &= ~TOK_KEEP; } @@ -100,24 +102,40 @@ tok_finish(tok) * Initialize the tokenizer */ public Tokenizer * -tok_init(ifs) - const char *ifs; +tok_init(const char *ifs) { - Tokenizer* tok = (Tokenizer*) tok_malloc(sizeof(Tokenizer)); - - tok->ifs = strdup(ifs ? ifs : IFS); - tok->argc = 0; - tok->amax = AINCR; - tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); - tok->argv[0] = NULL; - tok->wspace = (char *) tok_malloc(WINCR); - tok->wmax = tok->wspace + WINCR; - tok->wstart = tok->wspace; - tok->wptr = tok->wspace; - tok->flags = 0; - tok->quote = Q_none; - - return tok; + Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); + + if (tok == NULL) + return NULL; + tok->ifs = strdup(ifs ? ifs : IFS); + if (tok->ifs == NULL) { + tok_free((ptr_t)tok); + return NULL; + } + tok->argc = 0; + tok->amax = AINCR; + tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); + if (tok->argv == NULL) { + tok_free((ptr_t)tok->ifs); + tok_free((ptr_t)tok); + return NULL; + } + tok->argv[0] = NULL; + tok->wspace = (char *) tok_malloc(WINCR); + if (tok->wspace == NULL) { + tok_free((ptr_t)tok->argv); + tok_free((ptr_t)tok->ifs); + tok_free((ptr_t)tok); + return NULL; + } + tok->wmax = tok->wspace + WINCR; + tok->wstart = tok->wspace; + tok->wptr = tok->wspace; + tok->flags = 0; + tok->quote = Q_none; + + return (tok); } @@ -125,14 +143,14 @@ tok_init(ifs) * Reset the tokenizer */ public void -tok_reset(tok) - Tokenizer *tok; +tok_reset(Tokenizer *tok) { - tok->argc = 0; - tok->wstart = tok->wspace; - tok->wptr = tok->wspace; - tok->flags = 0; - tok->quote = Q_none; + + tok->argc = 0; + tok->wstart = tok->wspace; + tok->wptr = tok->wspace; + tok->flags = 0; + tok->quote = Q_none; } @@ -140,13 +158,13 @@ tok_reset(tok) * Clean up */ public void -tok_end(tok) - Tokenizer *tok; +tok_end(Tokenizer *tok) { - tok_free((ptr_t) tok->ifs); - tok_free((ptr_t) tok->wspace); - tok_free((ptr_t) tok->argv); - tok_free((ptr_t) tok); + + tok_free((ptr_t) tok->ifs); + tok_free((ptr_t) tok->wspace); + tok_free((ptr_t) tok->argv); + tok_free((ptr_t) tok); } @@ -158,235 +176,232 @@ tok_end(tok) * 3: Quoted return * 2: Unmatched double quote * 1: Unmatched single quote - * 0: Ok + * 0: Ok */ public int -tok_line(tok, line, argc, argv) - Tokenizer *tok; - const char* line; - int *argc; - char ***argv; +tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) { - const char *ptr; - - while (1) { - switch (*(ptr = line++)) { - case '\'': - tok->flags |= TOK_KEEP; - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - tok->quote = Q_single; /* Enter single quote mode */ - break; - - case Q_single: /* Exit single quote mode */ - tok->quote = Q_none; - break; - - case Q_one: /* Quote this ' */ - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - case Q_double: /* Stay in double quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this ' */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - case '"': - tok->flags &= ~TOK_EAT; - tok->flags |= TOK_KEEP; - switch (tok->quote) { - case Q_none: /* Enter double quote mode */ - tok->quote = Q_double; - break; - - case Q_double: - tok->quote = Q_none; /* Exit double quote mode */ - break; - - case Q_one: /* Quote this " */ - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - case Q_single: /* Stay in single quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this " */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - case '\\': - tok->flags |= TOK_KEEP; - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: /* Quote next character */ - tok->quote = Q_one; - break; - - case Q_double: - tok->quote = Q_doubleone;/* Quote next character */ - break; - - case Q_one: - *tok->wptr++ = *ptr; - tok->quote = Q_none; /* Quote this, restore state */ - break; - - case Q_single: /* Stay in single quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this \ */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - case '\n': - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - tok_finish(tok); - *argv = tok->argv; - *argc = tok->argc; - return(0); - - case Q_single: - case Q_double: - *tok->wptr++ = *ptr; /* Add the return */ - break; - - case Q_doubleone: - tok->flags |= TOK_EAT; - tok->quote = Q_double; /* Back to double, eat the '\n' */ - break; - - case Q_one: - tok->flags |= TOK_EAT; - tok->quote = Q_none; /* No quote, more eat the '\n' */ - break; - - default: - return(0); - } - break; - - case '\0': - switch (tok->quote) { - case Q_none: - /* Finish word and return */ - if (tok->flags & TOK_EAT) { - tok->flags &= ~TOK_EAT; - return 3; + const char *ptr; + + for (;;) { + switch (*(ptr = line++)) { + case '\'': + tok->flags |= TOK_KEEP; + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: + tok->quote = Q_single; /* Enter single quote + * mode */ + break; + + case Q_single: /* Exit single quote mode */ + tok->quote = Q_none; + break; + + case Q_one: /* Quote this ' */ + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + case Q_double: /* Stay in double quote mode */ + *tok->wptr++ = *ptr; + break; + + case Q_doubleone: /* Quote this ' */ + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + case '"': + tok->flags &= ~TOK_EAT; + tok->flags |= TOK_KEEP; + switch (tok->quote) { + case Q_none: /* Enter double quote mode */ + tok->quote = Q_double; + break; + + case Q_double: /* Exit double quote mode */ + tok->quote = Q_none; + break; + + case Q_one: /* Quote this " */ + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + case Q_single: /* Stay in single quote mode */ + *tok->wptr++ = *ptr; + break; + + case Q_doubleone: /* Quote this " */ + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + case '\\': + tok->flags |= TOK_KEEP; + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: /* Quote next character */ + tok->quote = Q_one; + break; + + case Q_double: /* Quote next character */ + tok->quote = Q_doubleone; + break; + + case Q_one: /* Quote this, restore state */ + *tok->wptr++ = *ptr; + tok->quote = Q_none; + break; + + case Q_single: /* Stay in single quote mode */ + *tok->wptr++ = *ptr; + break; + + case Q_doubleone: /* Quote this \ */ + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + case '\n': + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: + tok_finish(tok); + *argv = (const char **)tok->argv; + *argc = tok->argc; + return (0); + + case Q_single: + case Q_double: + *tok->wptr++ = *ptr; /* Add the return */ + break; + + case Q_doubleone: /* Back to double, eat the '\n' */ + tok->flags |= TOK_EAT; + tok->quote = Q_double; + break; + + case Q_one: /* No quote, more eat the '\n' */ + tok->flags |= TOK_EAT; + tok->quote = Q_none; + break; + + default: + return (0); + } + break; + + case '\0': + switch (tok->quote) { + case Q_none: + /* Finish word and return */ + if (tok->flags & TOK_EAT) { + tok->flags &= ~TOK_EAT; + return (3); + } + tok_finish(tok); + *argv = (const char **)tok->argv; + *argc = tok->argc; + return (0); + + case Q_single: + return (1); + + case Q_double: + return (2); + + case Q_doubleone: + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + case Q_one: + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + default: + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: + if (strchr(tok->ifs, *ptr) != NULL) + tok_finish(tok); + else + *tok->wptr++ = *ptr; + break; + + case Q_single: + case Q_double: + *tok->wptr++ = *ptr; + break; + + + case Q_doubleone: + *tok->wptr++ = '\\'; + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + case Q_one: + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + + } + break; } - tok_finish(tok); - *argv = tok->argv; - *argc = tok->argc; - return(0); - - case Q_single: - return(1); - - case Q_double: - return(2); - - case Q_doubleone: - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - case Q_one: - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - default: - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - if (strchr(tok->ifs, *ptr) != NULL) - tok_finish(tok); - else - *tok->wptr++ = *ptr; - break; - - case Q_single: - case Q_double: - *tok->wptr++ = *ptr; - break; - - - case Q_doubleone: - *tok->wptr++ = '\\'; - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - case Q_one: - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - - } - break; - } - - if (tok->wptr >= tok->wmax - 4) { - size_t size = tok->wmax - tok->wspace + WINCR; - char *s; - int offs; - - if ((s = tok_realloc(tok->wspace, size)) == NULL) - return -1; - - if ((offs = s - tok->wspace) != 0) { - int i; - for (i = 0; i < tok->argc; i++) - tok->argv[i] = tok->argv[i] + offs; - tok->wptr = tok->wptr + offs; - tok->wstart = tok->wstart + offs; - tok->wspace = s; - } - tok->wmax = s + size; - } - if (tok->argc >= tok->amax - 4) { - char **nargv = (char **) tok_realloc(tok->argv, (tok->amax + AINCR) - * sizeof(char*)); - if (nargv == NULL) - return -1; - tok->amax += AINCR; - tok->argv = nargv; + if (tok->wptr >= tok->wmax - 4) { + size_t size = tok->wmax - tok->wspace + WINCR; + char *s = (char *) tok_realloc(tok->wspace, size); + if (s == NULL) + return (-1); + + if (s != tok->wspace) { + int i; + for (i = 0; i < tok->argc; i++) { + tok->argv[i] = + (tok->argv[i] - tok->wspace) + s; + } + tok->wptr = (tok->wptr - tok->wspace) + s; + tok->wstart = (tok->wstart - tok->wspace) + s; + tok->wspace = s; + } + tok->wmax = s + size; + } + if (tok->argc >= tok->amax - 4) { + char **p; + tok->amax += AINCR; + p = (char **) tok_realloc(tok->argv, + tok->amax * sizeof(char *)); + if (p == NULL) + return (-1); + tok->argv = p; + } } - } } |