mescc: Mes C Library: Support GNU Awk: Add dtoab, %f in vfprintf, vsnprintf.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 12 Jan 2020 17:42:25 +0000 (18:42 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 12 Jan 2020 17:42:25 +0000 (18:42 +0100)
* 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.

build-aux/check-mescc.sh
build-aux/configure-lib.sh
include/mes/lib.h
lib/mes/dtoab.c [new file with mode: 0644]
lib/stdio/vfprintf.c
lib/stdio/vsnprintf.c
lib/tests/mes/90-dtoab.c [new file with mode: 0644]
lib/tests/mes/90-dtoab.stdout [new file with mode: 0644]
lib/tests/stdio/90-sprintf.c [new file with mode: 0644]
lib/tests/stdio/90-sprintf.stdout [new file with mode: 0644]

index d5fc5d0709ca9b2271b4f4696aa5f9421fc25341..eec0e4ece44dc695456b8c239b553d7b5aa55473 100755 (executable)
@@ -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
 
index ccec0f19df49f858b74f77aabb3387b768871720..0cecaccf94043b6f71ca4daab336705962e71e03 100644 (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
index e05da652a4228364a47e3ef4279735c1bac99d64..6b66107b45da3dcf073302dc5c64828c9b5f5bac 100644 (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);
diff --git a/lib/mes/dtoab.c b/lib/mes/dtoab.c
new file mode 100644 (file)
index 0000000..dc19050
--- /dev/null
@@ -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;
+}
index 119e41ae7f882f5a411c96a599995660cba28dc0..9de972ade07440de06330656ed488d65de24580f 100644 (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 *);
index 2c224bfe44948cca0bc71f8d8ac87cb2b9d65b41..8b99ff589314551c3c6bfb5464c3762e1a85f4ca 100644 (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 *);
diff --git a/lib/tests/mes/90-dtoab.c b/lib/tests/mes/90-dtoab.c
new file mode 100644 (file)
index 0000000..1f7e29d
--- /dev/null
@@ -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;
+}
diff --git a/lib/tests/mes/90-dtoab.stdout b/lib/tests/mes/90-dtoab.stdout
new file mode 100644 (file)
index 0000000..8860921
--- /dev/null
@@ -0,0 +1,2 @@
+1.23
+-3.14159265358
diff --git a/lib/tests/stdio/90-sprintf.c b/lib/tests/stdio/90-sprintf.c
new file mode 100644 (file)
index 0000000..2401195
--- /dev/null
@@ -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;
+}
diff --git a/lib/tests/stdio/90-sprintf.stdout b/lib/tests/stdio/90-sprintf.stdout
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0