tokscan.c revision da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
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* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
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 *
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 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * message support for %s and %v data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (5:12345) fixed length strings, ) may be \t
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * (null) NiL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
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 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a null arg pointer skips that arg
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * %c char
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 *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * unmatched char args are set to "", int args to 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <tok.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char empty[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get one string token into p
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlextok(register char* s, register int c, char** p, int* n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '(' && (!c || c == ' ' || c == '\n'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = strtol(s + 1, &b, 10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*b == ':')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*(t = ++b + q) == ')' || *t == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto end;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (strneq(b, "null)", 5))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = b + 5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto end;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || !q && *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!c || c == ' ' || c == '\n') (*n)++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = empty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t) *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s == '\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin u = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*++s || *s == '\n' && (!*++s || *s == '\n')) continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b == u) b = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!t) t = u;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!t) t = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s == '\r') *s = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s == '"' || *s == '\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = *s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (b == (s - 1)) b = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (!t) t = s - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s == c || c == ' ' && *s == '\t')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t) *t = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == ' ') while (*s == ' ' || *s == '\t') s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*n)++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t) *t++ = *s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p) *p = b;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * scan entry
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintokscan(register char* s, char** nxt, const char* fmt, ...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int num = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* skip = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int onum;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double dval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_list ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* p_char;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin double* p_double;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int* p_int;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long* p_long;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short* p_short;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char** p_string;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* prv_f = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_list prv_ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_start(ap, fmt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = empty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = (char*)fmt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (;;) switch (c = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (f = prv_f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prv_f = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* prv_ap value is guarded by prv_f */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_copy(ap, prv_ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ' ':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s == ' ' || *s == '\t') s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '%':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin onum = num;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c = *f++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'h':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '%':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin prv_f = f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f = va_arg(ap, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_copy(prv_ap, ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_copy(ap, va_listval(va_arg(ap, va_listarg)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'c':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_char = va_arg(ap, char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(c = *s) || c == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_char) *p_char = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_char) *p_char = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'd':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'x':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'd':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'x':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = 16;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin val = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_char = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else val = strtol(s, &p_char, c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'h':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_short = va_arg(ap, short*)) *p_short = (short)val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_long = va_arg(ap, long*)) *p_long = val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_int = va_arg(ap, int*)) *p_int = (int)val;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s != p_char)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p_char;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'g':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dval = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_char = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else dval = strtod(s, &p_char);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_double = va_arg(ap, double*)) *p_double = dval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (s != p_char)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = p_char;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_string = va_arg(ap, char**);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q = *f) f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*s || *s == '\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_string) *p_string = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else s = lextok(s, q, p_string, &num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'v':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_string = va_arg(ap, char**);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = va_arg(ap, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q = *f) f++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((!*s || *s == '\n') && p_string)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p_string = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p_string = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*s && *s != '\n' && --c > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = lextok(s, q, p_string, &num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_string) p_string++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (p_string) *p_string = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (skip) num = onum;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (num == onum)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!num) num = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip = s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = empty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\n':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*s++ != c) && !skip)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin skip = s - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = empty;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_end(ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*s == '\n') *s++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (nxt) *nxt = skip ? skip : s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(num);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}