mescc: Mes C Library: Support GNU Awk: Add dtoab, %f in vfprintf, vsnprintf.

* include/libmes.h (dtoab): Declare.
* lib/mes/ntoab.c (ntoab): Update.
* lib/mes/dtoab.c: New file.
* build-aux/configure-lib.sh (libmes_SOURCES, libc_tcc_SOURCES): Add
it.
* lib/tests/mes/90-dtoab.c: Test it.
* lib/tests/stdio/90-sprintf.c: Test it.
* build-aux/check-mescc.sh (tests): Run it, against...
* lib/tests/mes/90-dtoab.stdout: ...baseline.
* lib/stdio/vfprintf.c (vfprintf): Support %f, even more naive support
for %e, %E, %g, %G.
* lib/stdio/vsnprintf.c (vsnprintf): Likewise.
This commit is contained in:
Jan Nieuwenhuizen 2020-01-12 18:42:25 +01:00
parent 742e88abd5
commit f3154aabe4
No known key found for this signature in database
GPG key ID: F3C1A0D9C1D65273
10 changed files with 221 additions and 3 deletions

View file

@ -201,6 +201,7 @@ if test -z "$bootstrap"; then
lib/tests/dirent/90-readdir.c
lib/tests/io/90-stat.c
lib/tests/mes/90-abtod.c
lib/tests/mes/90-dtoab.c
lib/tests/posix/90-execlp.c
lib/tests/posix/90-unsetenv.c
lib/tests/signal/90-signal.c
@ -208,6 +209,7 @@ lib/tests/stdio/90-fopen.c
lib/tests/stdio/90-fopen-append.c
lib/tests/stdio/90-fread-fwrite.c
lib/tests/stdio/90-fseek.c
lib/tests/stdio/90-sprintf.c
lib/tests/stdlib/90-strtol.c
lib/tests/string/90-snprintf.c
lib/tests/string/90-strpbrk.c
@ -226,7 +228,6 @@ fi
XFAIL_TESTS="
lib/tests/mes/90-abtod.c
lib/tests/stdio/90-sprintf.c
lib/tests/stdio/90-sprintf.c
"
if test $compiler = mescc; then
@ -235,6 +236,7 @@ lib/tests/scaffold/17-compare-unsigned-char-le.c
lib/tests/scaffold/17-compare-unsigned-short-le.c
lib/tests/scaffold/66-local-char-array.c
lib/tests/scaffold/72-typedef-struct-def-local.c
lib/tests/mes/90-dtoab.c
lib/tests/scaffold/90-goto-var.c
lib/tests/scaffold/91-goto-array.c
"
@ -253,6 +255,7 @@ fi
if test $mes_cpu = x86; then
XFAIL_TESTS="$XFAIL_TESTS
lib/tests/mes/90-dtoab.c
"
fi

View file

@ -87,6 +87,7 @@ lib/linux/lseek.c
else
libmes_SOURCES="$libmes_SOURCES
lib/mes/abtod.c
lib/mes/dtoab.c
"
fi
@ -158,6 +159,7 @@ lib/ctype/isupper.c
lib/ctype/tolower.c
lib/ctype/toupper.c
lib/mes/abtod.c
lib/mes/dtoab.c
lib/mes/search-path.c
lib/posix/execvp.c
lib/stdio/fclose.c

View file

@ -30,6 +30,7 @@ void __ungetc_set (int filedes, int c);
int __ungetc_p (int filedes);
double abtod (char const **p, int base);
long abtol (char const **p, int base);
char *dtoab (double number, int base, int signed_p);
char *itoa (int number);
char *ltoa (long number);
char *ltoab (long x, int base);

46
lib/mes/dtoab.c Normal file
View file

@ -0,0 +1,46 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <mes/lib.h>
#include <limits.h>
#include <string.h>
char *
dtoab (double d, int base, int signed_p)
{
static char dtoa_buf[40];
long i = (long) d;
char *p = ntoab (i, base, signed_p);
strcpy (dtoa_buf, p);
long f = (d - (double) i) * (double) 100000000000;
if (f)
{
if (f < 0)
f = -f;
strcat (dtoa_buf, ".");
p = ntoab (f, base, 1);
strcat (dtoa_buf, p);
p = strchr (dtoa_buf, 0);
p--;
while (*p && *p == '0')
*p-- = 0;
}
return dtoa_buf;
}

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of GNU Mes.
*
@ -182,6 +182,50 @@ vfprintf (FILE * f, char const *format, va_list ap)
}
break;
}
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
{
double d = va_arg (ap, double);
char *s = dtoab (d, 10, 1);
if (c == 'E' || c == 'G')
strupr (s);
int length = strlen (s);
if (precision == -1)
precision = length;
if (!left_p)
{
while (width-- > precision)
{
fputc (pad, f);
count++;
}
while (precision > length)
{
fputc ('0', f);
precision--;
width--;
count++;
}
}
while (*s)
{
if (precision-- <= 0)
break;
width--;
fputc (*s++, f);
count++;
}
while (width > 0)
{
width--;
fputc (pad, f);
count++;
}
break;
}
case 'n':
{
int *n = va_arg (ap, int *);

View file

@ -1,6 +1,6 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
* Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of GNU Mes.
*
@ -198,6 +198,55 @@ vsnprintf (char *str, size_t size, char const *format, va_list ap)
}
break;
}
case 'f':
case 'e':
case 'E':
case 'g':
case 'G':
{
double d = va_arg (ap, double);
char *s = dtoab (d, 10, 1);
if (c == 'E' || c == 'G')
strupr (s);
int length = strlen (s);
if (precision == -1)
precision = length;
if (!left_p)
{
while (width-- > precision)
{
if (count < size)
*str++ = pad;
count++;
}
while (precision > length)
{
if (count < size)
*str++ = '0';
precision--;
width--;
count++;
}
}
while (*s)
{
if (precision-- <= 0)
break;
width--;
c = *s++;
if (count < size)
*str++ = c;
count++;
}
while (width > 0)
{
width--;
if (count < size)
*str++ = pad;
count++;
}
break;
}
case 'n':
{
int *n = va_arg (ap, int *);

36
lib/tests/mes/90-dtoab.c Normal file
View file

@ -0,0 +1,36 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <mes/lib.h>
#include <stdlib.h>
int
main ()
{
double d = 1.23;
char *p = dtoab (d, 10, 1);
puts (p);
d = -3.141592653589;
p = dtoab (d, 10, 1);
puts (p);
return 0;
}

View file

@ -0,0 +1,2 @@
1.23
-3.14159265358

View file

@ -0,0 +1,34 @@
/* -*-comment-start: "//";comment-end:""-*-
* GNU Mes --- Maxwell Equations of Software
* Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <libmes.h>
#include <stdio.h>
#include <stdlib.h>
int
main ()
{
char buf[20];
double d = 0;
sprintf (buf, "%.6g", d);
puts (buf);
return 0;
}

View file

@ -0,0 +1 @@
0