diff --git a/build-aux/configure-lib.sh b/build-aux/configure-lib.sh index 5ffb8b3d..11ce436d 100644 --- a/build-aux/configure-lib.sh +++ b/build-aux/configure-lib.sh @@ -243,7 +243,9 @@ lib/stdio/feof.c lib/stdio/fgets.c lib/stdio/fileno.c lib/stdio/freopen.c +lib/stdio/fscanf.c lib/stdio/perror.c +lib/stdio/vfscanf.c lib/stdlib/__exit.c lib/stdlib/abort.c lib/stdlib/abs.c @@ -270,7 +272,6 @@ lib/stub/ctime.c lib/stub/fpurge.c lib/stub/freadahead.c lib/stub/frexp.c -lib/stub/fscanf.c lib/stub/getgrgid.c lib/stub/getgrnam.c lib/stub/getlogin.c diff --git a/include/stdarg.h b/include/stdarg.h index b0471913..638f71d0 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -41,6 +41,7 @@ typedef char *va_list; int vexec (char const *file_name, va_list ap); int vfprintf (FILE * stream, char const *template, va_list ap); +int vfscanf (FILE * stream, char const *template, va_list ap); int vprintf (char const *format, va_list ap); int vsprintf (char *str, char const *format, va_list ap); int vsnprintf (char *str, size_t size, char const *format, va_list ap); diff --git a/include/stdio.h b/include/stdio.h index ed46d6c5..c8684e0f 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -69,6 +69,7 @@ int fprintf (FILE * stream, char const *format, ...); int fpurge (FILE * stream); int fputc (int c, FILE * stream); int fputs (char const *s, FILE * stream); +int fscanf (FILE * stream, char const *template, ...); int fseek (FILE * stream, long offset, int whence); int getc (FILE * stream); int getchar (void); @@ -81,7 +82,7 @@ int remove (char const *file_name); int setvbuf (FILE * stream, char *buf, int mode, size_t size); int snprintf (char *str, size_t size, char const *format, ...); int sprintf (char *str, char const *format, ...); -int sscanf (char const *str, const char *format, ...); +int sscanf (char const *str, char const *format, ...); int ungetc (int c, FILE * stream); long ftell (FILE * stream); size_t fread (void *ptr, size_t size, size_t count, FILE * stream); diff --git a/lib/stub/fscanf.c b/lib/stdio/fscanf.c similarity index 74% rename from lib/stub/fscanf.c rename to lib/stdio/fscanf.c index 0973adc4..ee2ae67a 100644 --- a/lib/stub/fscanf.c +++ b/lib/stdio/fscanf.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -19,15 +19,15 @@ */ #include -#include -#include +#include +#include int -fscanf (FILE *stream, char const *template, ...) +fscanf (FILE * stream, char const *template, ...) { - static int stub = 0; - if (__mes_debug () && !stub) - eputs ("fscan stub\n"); - stub = 1; - return 0; + va_list ap; + va_start (ap, template); + int r = vfscanf (stream, template, ap); + va_end (ap); + return r; } diff --git a/lib/stdio/sscanf.c b/lib/stdio/sscanf.c index 0d1ed682..d5459df1 100644 --- a/lib/stdio/sscanf.c +++ b/lib/stdio/sscanf.c @@ -23,7 +23,7 @@ #include int -sscanf (char const *str, const char *template, ...) +sscanf (char const *str, char const *template, ...) { va_list ap; va_start (ap, template); diff --git a/lib/stdio/vfscanf.c b/lib/stdio/vfscanf.c new file mode 100644 index 00000000..efa957a2 --- /dev/null +++ b/lib/stdio/vfscanf.c @@ -0,0 +1,121 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen + * + * This file is part of GNU Mes. + * + * GNU Mes is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or (at + * your option) any later version. + * + * GNU Mes is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Mes. If not, see . + */ + +#include +#include +#include + +int +vfscanf (FILE * stream, char const *template, va_list ap) +{ + char p = fgetc (stream); + char const *t = template; + int count = 0; + while (*t && p != EOF) + if (*t != '%') + { + t++; + p = fgetc (stream); + } + else + { + t++; + char c = *t; + if (c == 'l') + c = *++t; + switch (c) + { + case '%': + { + p = fgetc (stream); + break; + } + case 'c': + { + char *c = va_arg (ap, char *); + *c = p; + p = fgetc (stream); + count++; + break; + } + case 'd': + case 'i': + case 'u': + { + int *d = va_arg (ap, int *); + char buf[20]; + char *q = buf; + if (p == '+' || p == '-') + { + *q++ = p; + p = fgetc (stream); + } + while (isdigit (p)) + { + *q++ = p; + p = fgetc (stream); + } + ungetc (p, stream); + *q = 0; + q = buf; + *d = abtol (&q, 10); + count++; + break; + } + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + { + float *f = va_arg (ap, float *); + char buf[20]; + char *q = buf; + if (p == '+' || p == '-') + { + *q++ = p; + p = fgetc (stream); + } + while (isdigit (p)) + { + *q++ = p; + p = fgetc (stream); + } + ungetc (p, stream); + *q = 0; + q = buf; + *f = strtod (q, &q); + count++; + break; + } + default: + { + eputs ("vsscanf: not supported: %:"); + eputc (c); + eputs ("\n"); + t++; + p = fgetc (stream); + } + } + t++; + } + va_end (ap); + return count; +}