* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Christos Zoulas of Cornell University.
* %sccs.include.redist.c%
#if !defined(lint) && !defined(SCCSID)
static char sccsid
[] = "@(#)tokenizer.c 5.2 (Berkeley) %G%";
#endif /* not lint && not SCCSID */
* tokenize.c: Bourne shell like tokenizer
typedef enum { Q_none
, Q_single
, Q_double
, Q_one
, Q_doubleone
} quote_t
;
#define tok_malloc(a) malloc(a)
#define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b)
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 */
private void tok_finish
__P((Tokenizer
*));
* Finish a word in the tokenizer.
if ((tok
->flags
& TOK_KEEP
) || tok
->wptr
!= tok
->wstart
) {
tok
->argv
[tok
->argc
++] = tok
->wstart
;
tok
->argv
[tok
->argc
] = NULL
;
tok
->wstart
= ++tok
->wptr
;
* Initialize the tokenizer
Tokenizer
* tok
= (Tokenizer
*) tok_malloc(sizeof(Tokenizer
));
tok
->ifs
= strdup(ifs
? ifs
: IFS
);
tok
->argv
= (char **) tok_malloc(sizeof(char *) * tok
->amax
);
tok
->wspace
= (char *) tok_malloc(WINCR
);
tok
->wmax
= tok
->wspace
+ WINCR
;
tok
->wstart
= tok
->wspace
;
tok
->wstart
= tok
->wspace
;
tok_free((ptr_t
) tok
->ifs
);
tok_free((ptr_t
) tok
->wspace
);
tok_free((ptr_t
) tok
->argv
);
* Bourne shell like tokenizing
* 2: Unmatched double quote
* 1: Unmatched single quote
tok_line(tok
, line
, argc
, argv
)
switch (*(ptr
= line
++)) {
tok
->quote
= Q_single
; /* Enter single quote mode */
case Q_single
: /* Exit single quote mode */
case Q_one
: /* Quote this ' */
case Q_double
: /* Stay in double quote mode */
case Q_doubleone
: /* Quote this ' */
case Q_none
: /* Enter double quote mode */
tok
->quote
= Q_none
; /* Exit double quote mode */
case Q_one
: /* Quote this " */
case Q_single
: /* Stay in single quote mode */
case Q_doubleone
: /* Quote this " */
case Q_none
: /* Quote next character */
tok
->quote
= Q_doubleone
;/* Quote next character */
tok
->quote
= Q_none
; /* Quote this, restore state */
case Q_single
: /* Stay in single quote mode */
case Q_doubleone
: /* Quote this \ */
*tok
->wptr
++ = *ptr
; /* Add the return */
tok
->quote
= Q_double
; /* Back to double, eat the '\n' */
tok
->quote
= Q_none
; /* No quote, more eat the '\n' */
/* Finish word and return */
if (tok
->flags
& TOK_EAT
) {
if (strchr(tok
->ifs
, *ptr
) != NULL
)
if (tok
->wptr
>= tok
->wmax
- 4) {
size_t size
= tok
->wmax
- tok
->wspace
+ WINCR
;
char *s
= (char *) tok_realloc(tok
->wspace
, size
);
int offs
= s
- tok
->wspace
;
for (i
= 0; i
< tok
->argc
; i
++)
tok
->argv
[i
] = tok
->argv
[i
] + offs
;
tok
->wptr
= tok
->wptr
+ offs
;
tok
->wstart
= tok
->wstart
+ offs
;
if (tok
->argc
>= tok
->amax
- 4) {
tok
->argv
= (char **) tok_realloc(tok
->argv
,
tok
->amax
* sizeof(char*));