in sys/wince/celib.c [541:759]
int __cdecl fscanf(FILE *f, const char *format, ...)
{
/* Format spec: %[*] [width] [l] type ] */
int ch;
int sch;
int matched = 0;
int width = 65535;
int modifier = -1;
int skip_flag = 0;
int n_read = 0;
char buf[BUFSZ];
TCHAR wbuf[BUFSZ];
char *p;
va_list args;
#define RETURN_SCANF(i) \
{ \
va_end(args); \
return i; \
}
#define NEXT_CHAR(f) (n_read++, fgetc(f))
va_start(args, format);
ch = *format++;
sch = NEXT_CHAR(f);
while (ch && sch != EOF) {
if (isspace(ch)) {
while (ch && isspace(ch))
ch = *format++;
while (sch != EOF && isspace(sch))
sch = NEXT_CHAR(f);
format--;
goto next_spec;
}
/* read % */
if (ch != '%') {
if (sch != ch)
RETURN_SCANF(matched);
sch = NEXT_CHAR(f);
goto next_spec;
} else {
/* process '%%' */
ch = *format++;
if (ch == '%') {
if (sch != '%')
RETURN_SCANF(matched);
sch = NEXT_CHAR(f);
goto next_spec;
}
if (ch == '*') {
/* read skip flag - '*' */
skip_flag = 1;
ch = *format++;
}
/* get width */
if (isdigit(ch)) {
width = 0;
while (ch && isdigit(ch)) {
width = width * 10 + (ch - '0');
ch = *format++;
}
}
/* get modifier */
if (ch == 'l') {
modifier = 'l';
ch = *format++;
}
/* get type */
switch (ch) {
case 'c':
if (!skip_flag) {
*(va_arg(args, char *) ) = sch;
matched++;
}
sch = NEXT_CHAR(f);
goto next_spec;
case 'd':
p = buf;
/* skip space */
while (sch != EOF && isspace(sch))
sch = NEXT_CHAR(f);
while (sch != EOF && isdigit(sch) && --width >= 0) {
*p++ = sch;
sch = NEXT_CHAR(f);
}
*p = '\x0';
if (!skip_flag) {
matched++;
if (modifier == 'l') {
*(va_arg(args, long *) ) =
wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
} else {
*(va_arg(args, int *) ) =
wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 10);
}
}
goto next_spec;
case 'x':
p = buf;
while (sch != EOF && isspace(sch))
sch = NEXT_CHAR(f);
while (sch != EOF && isxdigit(sch) && --width >= 0) {
*p++ = sch;
sch = NEXT_CHAR(f);
}
*p = '\x0';
if (!skip_flag) {
matched++;
if (modifier == 'l') {
*(va_arg(args, long *) ) =
wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
} else {
*(va_arg(args, int *) ) =
wcstol(NH_A2W(buf, wbuf, BUFSZ), NULL, 16);
}
}
goto next_spec;
case 'n':
*(va_arg(args, int *) ) = n_read;
matched++;
goto next_spec;
case 's':
if (skip_flag) {
while (sch != EOF && !isspace(sch) && --width >= 0) {
sch = NEXT_CHAR(f);
}
} else {
p = va_arg(args, char *);
while (sch != EOF && !isspace(sch) && --width >= 0) {
*p++ = sch;
sch = NEXT_CHAR(f);
}
*p = '\x0';
matched++;
}
goto next_spec;
case '[': {
char pattern[256];
int start, end;
int negate;
ZeroMemory(pattern, sizeof(pattern));
p = pattern;
/* try to parse '^' modifier */
ch = *format++;
if (ch == '^') {
negate = 1;
ch = *format++;
} else {
negate = 0;
}
if (ch == 0)
RETURN_SCANF(EOF);
for (; ch && ch != ']'; ch = *format++) {
/* try to parse range: a-z */
if (format[0] == '-' && format[1] && format[1] != ']') {
start = ch;
format++;
end = *format++;
while (start <= end) {
if (!strchr(pattern, (char) start))
*p++ = (char) start;
start++;
}
} else {
if (!strchr(pattern, (char) ch))
*p++ = (char) ch;
}
}
if (skip_flag) {
while (sch != EOF && strchr(pattern, sch)
&& --width >= 0) {
sch = NEXT_CHAR(f);
}
} else {
p = va_arg(args, char *);
if (negate)
while (sch != EOF && !strchr(pattern, sch)
&& --width >= 0) {
*p++ = sch;
sch = NEXT_CHAR(f);
}
else
while (sch != EOF && strchr(pattern, sch)
&& --width >= 0) {
*p++ = sch;
sch = NEXT_CHAR(f);
}
*p = '\x0';
matched++;
}
}
goto next_spec;
default:
RETURN_SCANF(EOF);
}
}
next_spec:
width = 65535;
modifier = -1;
skip_flag = 0;
ch = *format++;
}
fseek(f, -1, SEEK_CUR);
RETURN_SCANF(matched);
#undef RETURN_SCANF
#undef NEXT_CHAR
}