diff options
Diffstat (limited to 'usr/src/lib/libast/common/string/tok.c')
-rw-r--r-- | usr/src/lib/libast/common/string/tok.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/string/tok.c b/usr/src/lib/libast/common/string/tok.c new file mode 100644 index 0000000000..7bf89ca30c --- /dev/null +++ b/usr/src/lib/libast/common/string/tok.c @@ -0,0 +1,190 @@ +/*********************************************************************** +* * +* This software is part of the ast package * +* Copyright (c) 1985-2007 AT&T Knowledge Ventures * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Knowledge Ventures * +* * +* A copy of the License is available at * +* http://www.opensource.org/licenses/cpl1.0.txt * +* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * +* * +* Information and Software Systems Research * +* AT&T Research * +* Florham Park NJ * +* * +* Glenn Fowler <gsf@research.att.com> * +* David Korn <dgk@research.att.com> * +* Phong Vo <kpv@research.att.com> * +* * +***********************************************************************/ +#pragma prototyped +/* + * Glenn Fowler + * AT&T Research + * + * token stream routines + */ + +#include <ast.h> +#include <tok.h> + +#define FLG_RESTORE 01 /* restore string on close */ +#define FLG_NEWLINE 02 /* return newline token next */ + +typedef struct Tok_s /* token stream state */ +{ + union + { + char* end; /* end ('\0') of last token */ + struct Tok_s* nxt; /* next in free list */ + } ptr; + char chr; /* replace *end with this */ + char flg; /* FLG_* */ +} Tok_t; + +static Tok_t* freelist; + +/* + * open a new token stream on s + * if f==0 then string is not restored + */ + +char* +tokopen(register char* s, int f) +{ + register Tok_t* p; + + if (p = freelist) + freelist = freelist->ptr.nxt; + else if (!(p = newof(0, Tok_t, 1, 0))) + return 0; + p->chr = *(p->ptr.end = s); + p->flg = f ? FLG_RESTORE : 0; + return (char*)p; +} + +/* + * close a token stream + * restore the string to its original state + */ + +void +tokclose(char* u) +{ + register Tok_t* p = (Tok_t*)u; + + if (p->flg == FLG_RESTORE && *p->ptr.end != p->chr) + *p->ptr.end = p->chr; + p->ptr.nxt = freelist; + freelist = p; +} + +/* + * return next space separated token + * "\n" is returned as a token + * 0 returned when no tokens remain + * "..." and '...' quotes are honored with \ escapes + */ + +char* +tokread(char* u) +{ + register Tok_t* p = (Tok_t*)u; + register char* s; + register char* r; + register int q; + register int c; + + /* + * restore string on each call + */ + + if (!p->chr) + return 0; + s = p->ptr.end; + switch (p->flg) + { + case FLG_NEWLINE: + p->flg = 0; + return "\n"; + case FLG_RESTORE: + if (*s != p->chr) + *s = p->chr; + break; + default: + if (!*s) + s++; + break; + } + + /* + * skip leading space + */ + + while (*s == ' ' || *s == '\t') + s++; + if (!*s) + { + p->ptr.end = s; + p->chr = 0; + return 0; + } + + /* + * find the end of this token + */ + + r = s; + q = 0; + for (;;) + switch (c = *r++) + { + case '\n': + if (!q) + { + if (s == (r - 1)) + { + if (!p->flg) + { + p->ptr.end = r; + return "\n"; + } + r++; + } + else if (!p->flg) + p->flg = FLG_NEWLINE; + } + /*FALLTHROUGH*/ + case ' ': + case '\t': + if (q) + break; + /*FALLTHROUGH*/ + case 0: + if (s == --r) + { + p->ptr.end = r; + p->chr = 0; + } + else + { + p->chr = *(p->ptr.end = r); + if (*r) + *r = 0; + } + return s; + case '\\': + if (*r) + r++; + break; + case '"': + case '\'': + if (c == q) + q = 0; + else if (!q) + q = c; + break; + } +} |