tokscan.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Copyright (c) 1985-2007 AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* by AT&T Knowledge Ventures *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * scan s for tokens in fmt
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * s modified in place and not restored
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if nxt!=0 then it will point to the first unread char in s
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the number of scanned tokens is returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * -1 returned if s was not empty and fmt failed to match
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ' ' in fmt matches 0 or more {space,tab}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * '\n' in fmt eats remainder of current line
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * "..." and '...' quotes interpreted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * newline is equivalent to end of buf except when quoted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * \\ quotes following char
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * message support for %s and %v data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (5:12345) fixed length strings, ) may be \t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (null) NiL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * "..." and '...' may span \n, and \\n is the line splice
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * quoted '\r' translated to '\n'
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise tokenizing is unconditionally terminated by '\n'
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a null arg pointer skips that arg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %[hl]d [short|int|long] base 10
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %f double
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %g double
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %[hl]n [short|int|long] C-style base
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %[hl]o [short|int|long] base 8
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %s string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %[hl]u same as %[hl]n
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %v argv, elements
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %[hl]x [short|int|long] base 16
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * unmatched char args are set to "", int args to 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get one string token into p
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlextok(register char* s, register int c, char** p, int* n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = b + 5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || !q && *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t) *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*++s || *s == '\n' && (!*++s || *s == '\n')) continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b == u) b = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!t) t = u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t) t = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b == (s - 1)) b = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!t) t = s - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t) *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t) *t++ = *s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p) *p = b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * scan entry
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintokscan(register char* s, char** nxt, const char* fmt, ...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* skip = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (char*)fmt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;) switch (c = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* prv_ap value is guarded by prv_f */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = *s) || c == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_short = va_arg(ap, short*)) *p_short = (short)val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q = *f) f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q = *f) f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s && *s != '\n' && --c > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*s++ != c) && !skip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '\n') *s++ = 0;