You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
199 lines
4.8 KiB
199 lines
4.8 KiB
/* $Id: scanf.c,v 1.1.1.1 2006/09/14 01:59:06 root Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Opsycon AB.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
|
|
#include <pmon.h>
|
|
|
|
/*
|
|
* ** fscanf --\ sscanf --\
|
|
* ** | |
|
|
* ** scanf --+-- vfscanf ----- vsscanf
|
|
* **
|
|
* ** This not been very well tested.. it probably has bugs
|
|
*/
|
|
static int vfscanf __P((FILE *, const char *, va_list));
|
|
static int vsscanf __P((const char *, const char *, va_list));
|
|
|
|
#define ISSPACE " \t\n\r\f\v"
|
|
|
|
/*
|
|
* scanf(fmt,va_alist)
|
|
*/
|
|
int
|
|
scanf (const char *fmt, ...)
|
|
{
|
|
int count;
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
count = vfscanf (stdin, fmt, ap);
|
|
va_end (ap);
|
|
return (count);
|
|
}
|
|
|
|
/*
|
|
* fscanf(fp,fmt,va_alist)
|
|
*/
|
|
int
|
|
fscanf (FILE *fp, const char *fmt, ...)
|
|
{
|
|
int count;
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
count = vfscanf (fp, fmt, ap);
|
|
va_end (ap);
|
|
return (count);
|
|
}
|
|
|
|
/*
|
|
* sscanf(buf,fmt,va_alist)
|
|
*/
|
|
int
|
|
sscanf (const char *buf, const char *fmt, ...)
|
|
{
|
|
int count;
|
|
va_list ap;
|
|
|
|
va_start (ap, fmt);
|
|
count = vsscanf (buf, fmt, ap);
|
|
va_end (ap);
|
|
return (count);
|
|
}
|
|
|
|
/*
|
|
* vfscanf(fp,fmt,ap)
|
|
*/
|
|
static int
|
|
vfscanf (FILE *fp, const char *fmt, va_list ap)
|
|
{
|
|
int count;
|
|
char buf[MAXLN + 1];
|
|
|
|
if (fgets (buf, MAXLN, fp) == 0)
|
|
return (-1);
|
|
count = vsscanf (buf, fmt, ap);
|
|
return (count);
|
|
}
|
|
|
|
|
|
/*
|
|
* vsscanf(buf,fmt,ap)
|
|
*/
|
|
static int
|
|
vsscanf (const char *buf, const char *s, va_list ap)
|
|
{
|
|
int count, noassign, width, base, lflag;
|
|
const char *tc;
|
|
char *t, tmp[MAXLN];
|
|
|
|
count = noassign = width = lflag = 0;
|
|
while (*s && *buf) {
|
|
while (isspace (*s))
|
|
s++;
|
|
if (*s == '%') {
|
|
s++;
|
|
for (; *s; s++) {
|
|
if (strchr ("dibouxcsefg%", *s))
|
|
break;
|
|
if (*s == '*')
|
|
noassign = 1;
|
|
else if (*s == 'l' || *s == 'L')
|
|
lflag = 1;
|
|
else if (*s >= '1' && *s <= '9') {
|
|
for (tc = s; isdigit (*s); s++);
|
|
strncpy (tmp, tc, s - tc);
|
|
tmp[s - tc] = '\0';
|
|
atob (&width, tmp, 10);
|
|
s--;
|
|
}
|
|
}
|
|
if (*s == 's') {
|
|
while (isspace (*buf))
|
|
buf++;
|
|
if (!width)
|
|
width = strcspn (buf, ISSPACE);
|
|
if (!noassign) {
|
|
strncpy (t = va_arg (ap, char *), buf, width);
|
|
t[width] = '\0';
|
|
}
|
|
buf += width;
|
|
} else if (*s == 'c') {
|
|
if (!width)
|
|
width = 1;
|
|
if (!noassign) {
|
|
strncpy (t = va_arg (ap, char *), buf, width);
|
|
t[width] = '\0';
|
|
}
|
|
buf += width;
|
|
} else if (strchr ("dobxu", *s)) {
|
|
while (isspace (*buf))
|
|
buf++;
|
|
if (*s == 'd' || *s == 'u')
|
|
base = 10;
|
|
else if (*s == 'x')
|
|
base = 16;
|
|
else if (*s == 'o')
|
|
base = 8;
|
|
else if (*s == 'b')
|
|
base = 2;
|
|
if (!width) {
|
|
if (isspace (*(s + 1)) || *(s + 1) == 0)
|
|
width = strcspn (buf, ISSPACE);
|
|
else
|
|
width = strchr (buf, *(s + 1)) - buf;
|
|
}
|
|
strncpy (tmp, buf, width);
|
|
tmp[width] = '\0';
|
|
buf += width;
|
|
if (!noassign)
|
|
atob (va_arg (ap, u_int32_t *), tmp, base);
|
|
}
|
|
if (!noassign)
|
|
count++;
|
|
width = noassign = lflag = 0;
|
|
s++;
|
|
} else {
|
|
while (isspace (*buf))
|
|
buf++;
|
|
if (*s != *buf)
|
|
break;
|
|
else
|
|
s++, buf++;
|
|
}
|
|
}
|
|
return (count);
|
|
}
|
|
|