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.
* 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 2019-01-03 12:37:35 +01:00
parent 0ce74918c1
commit 09a7722c21
No known key found for this signature in database
GPG Key ID: F3C1A0D9C1D65273
11 changed files with 221 additions and 3 deletions

View File

@ -193,6 +193,7 @@ scaffold/tests/85-sizeof
lib/tests/dirent/90-readdir
lib/tests/io/90-stat
lib/tests/mes/90-abtod
lib/tests/mes/90-dtoab
lib/tests/posix/90-execlp
lib/tests/posix/90-unsetenv
lib/tests/signal/90-signal
@ -200,6 +201,7 @@ lib/tests/stdio/90-fopen
lib/tests/stdio/90-fopen-append
lib/tests/stdio/90-fread-fwrite
lib/tests/stdio/90-fseek
lib/tests/stdio/90-sprintf
lib/tests/stdlib/90-strtol
lib/tests/string/90-snprintf
lib/tests/string/90-strpbrk
@ -218,6 +220,9 @@ scaffold/tests/17-compare-unsigned-short-le
scaffold/tests/66-local-char-array
scaffold/tests/a0-call-trunc-int
scaffold/tests/a0-math-divide-signed-negative
lib/tests/mes/90-abtod
lib/tests/mes/90-dtoab
lib/tests/stdio/90-sprintf
"
if [ "$mes_arch" = "x86_64-gcc" ]; then

View File

@ -26,6 +26,7 @@
int __mes_debug ();
double abtod (char const** p, int base);
long abtol (char const** p, int base);
char const* dtoab (double number, int base, int signed_p);
char const* ntoab (long number, int base, int signed_p);
char const* itoa (int number);
char const* ltoa (long number);

View File

@ -62,6 +62,7 @@ int errno;
#include <ctype/tolower.c>
#include <ctype/toupper.c>
#include <mes/abtod.c> // implementation instead of stub for GNU gawk
#include <mes/dtoab.c> // implementation instead of stub for GNU gawk
#include <mes/search-path.c>
#include <posix/execvp.c>
#include <stdio/fclose.c>

45
lib/mes/dtoab.c Normal file
View File

@ -0,0 +1,45 @@
/* -*-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 <libmes.h>
#include <limits.h>
char const*
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

@ -27,11 +27,11 @@ ntoab (long x, int base, int signed_p)
char *p = itoa_buf + 11;
*p-- = 0;
int sign = 0;
int sign_p = 0;
unsigned long u = x;
if (signed_p && x < 0)
{
sign = 1;
sign_p = 1;
u = -x;
}
@ -42,7 +42,7 @@ ntoab (long x, int base, int signed_p)
u = u / base;
} while (u);
if (sign && *(p + 1) != '0')
if (sign_p && *(p + 1) != '0')
*p-- = '-';
return p+1;

View File

@ -183,6 +183,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 const *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

@ -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 const *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 <libmes.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