mescc: Tinycc support: strtoull.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sat, 19 Aug 2017 08:51:24 +0000 (10:51 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sat, 19 Aug 2017 08:51:24 +0000 (10:51 +0200)
* mlibc/include/mlibc.h (_atoi): Declare.
* mlibc/include/ctype.h (isxdigit): Declare.
* mlibc/libc-gcc.c (isxdigit, _atoi): New function.
  (atoi): Use it.
* mlibc/libc-mes.c (isxdigit, _atoi): New function.
  (atoi): Use it.
* scaffold/tests/7j-strtoull.c (test): Test it.
* make.scm (add-scaffold-test): Build it.

make.scm
mlibc/include/ctype.h
mlibc/include/mlibc.h
mlibc/libc-gcc.c
mlibc/libc-mes+tcc.c
mlibc/libc-mes.c
scaffold/tests/7j-strtoull.c [new file with mode: 0644]

index fea0869a7121f68ad3d7fdbab0d2db76a597a7bf..fc4080aeae51dca12193531391e9620c39d192e4 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -168,7 +168,8 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
    "7f-struct-pointer-arithmetic"
    "7g-struct-byte-word-field"
    "7h-struct-assign"
-   "7i-struct-struct"))
+   "7i-struct-struct"
+   "7j-strtoull"))
 
 (add-target (group "check-scaffold-tests/7" #:dependencies (filter (target-prefix? "check-scaffold/tests/7") %targets)))
 
index 32be3c50f9a672c83a218b169b71713b2969f5cc..d6e961c233c5cec8dc58e9cca71812714eb04de4 100644 (file)
@@ -29,6 +29,7 @@
 
 #else // ! (__GNUC__ && POSIX)
 int isdigit (int);
+int isxdigit (int);
 #endif // ! (__GNUC__ && POSIX)
 
 #endif // __MES_CTYPE_H
index 84573acb4b058c208e83b9a18df51cec62a9f717..fb24f0bb3da48aa2a8aefdfedc078dfc97c3ff35 100644 (file)
@@ -22,5 +22,8 @@
 #define __MES_MLIBC_H
 
 char const* itoa (int);
+int _atoi (char const**, int base);
+int eputc (int c);
+int eputs (char const* s);
 
-#endif //__MLIBC_H
+#endif //__MES_MLIBC_H
index 2a636e8aef01e812e8d47a765ff8a1058e8af4e5..d278e00b212deba6278608215859826358b80285 100644 (file)
@@ -331,24 +331,53 @@ isdigit (int c)
 }
 
 int
-atoi (char const *s)
+isxdigit (int c)
 {
+  return isdigit (c) || (c>='a') && (c<='f');
+}
+
+int
+isnumber (int c, int base)
+{
+  if (base == 2)
+    return (c>='0') && (c<='1');
+  if (base == 8)
+    return (c>='0') && (c<='7');
+  if (base == 10)
+    return isdigit (c);
+  if (base == 16)
+    return isxdigit (c);
+}
+
+int
+_atoi (char const **p, int base)
+{
+  char const *s = *p;
   int i = 0;
   int sign = 1;
+  if (!base) base = 10;
   if (*s && *s == '-')
     {
       sign = -1;
       s++;
     }
-  while (isdigit (*s))
+  while (isnumber (*s, base))
     {
-      i *= 10;
-      i += (*s - '0');
+      i *= base;
+      int m = *s > '9' ? 'a' - 10 : '0';
+      i += *s - m;
       s++;
     }
+  *p = s;
   return i * sign;
 }
 
+int
+atoi (char const *s)
+{
+  char const *p = s;
+  return _atoi (&p, 0);
+}
 
 // FIXME: copied from libc-mes.c now
 #include <stdarg.h>
index 23d7da59bdf3467214cd7dc313c74f91f332e907..1ef52069be2cd7eb950f02dd87f95f1cfd2ff7d0 100644 (file)
@@ -326,10 +326,10 @@ strtoul (char const *nptr, char **endptr, int base)
 }
 
 unsigned long long
-strtoull (char const *nptr, char **endptr, int base)
+strtoull (char const *p, char **end, int base)
 {
-  eputs ("strtoull stub\n");
-  return 0;
+  *end = p;
+  return _atoi (end, base);
 }
 
 time_t time (time_t *tloc)
index eee3750020568e4dd4d6420ea7c2147c45b21e5f..d4f985a39e4de7b9fac9dff6d0976217c19e5d60 100644 (file)
@@ -299,32 +299,60 @@ itoa (int x)
 }
 
 int
-isdigit (char c)
+isdigit (int c)
 {
-  //return (c>='0') && (c<='9');
-  if (c>='0' && c<='9') return 1;
-  return 0;
+  return (c>='0') && (c<='9');
 }
 
 int
-atoi (char const *s)
+isxdigit (int c)
+{
+  return isdigit (c) || (c>='a') && (c<='f');
+}
+
+int
+isnumber (int c, int base)
 {
+  if (base == 2)
+    return (c>='0') && (c<='1');
+  if (base == 8)
+    return (c>='0') && (c<='7');
+  if (base == 10)
+    return isdigit (c);
+  if (base == 16)
+    return isxdigit (c);
+}
+
+int
+_atoi (char const **p, int base)
+{
+  char const *s = *p;
   int i = 0;
   int sign = 1;
+  if (!base) base = 10;
   if (*s && *s == '-')
     {
       sign = -1;
       s++;
     }
-  while (isdigit (*s))
+  while (isnumber (*s, base))
     {
-      i *= 10;
-      i += (*s - '0');
+      i *= base;
+      int m = *s > '9' ? 'a' - 10 : '0';
+      i += *s - m;
       s++;
     }
+  *p = s;
   return i * sign;
 }
 
+int
+atoi (char const *s)
+{
+  char const *p = s;
+  return _atoi (&p, 0);
+}
+
 char *g_brk = 0;
 
 void *
diff --git a/scaffold/tests/7j-strtoull.c b/scaffold/tests/7j-strtoull.c
new file mode 100644 (file)
index 0000000..3d11317
--- /dev/null
@@ -0,0 +1,50 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of Mes.
+ *
+ * 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.
+ *
+ * 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 Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "30-test.i"
+#include <mlibc.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+unsigned long long
+strtoull (char const *p, char **end, int base)
+{
+  *end = p;
+  return _atoi (end, base);
+}
+
+int
+test ()
+{
+  char *p = "42foo\n";
+  int n = _atoi (&p, 0);
+  if (n != 42) return 1;
+  eputs (p);
+  if (strcmp (p, "foo\n")) return 2;
+
+  p = "2azar\n";
+  n = strtoull (p, (char**)&p, 16);  
+  if (n != 42) return 3;
+  eputs (p);
+  if (strcmp (p, "zar\n")) return 4;
+  
+  return 0;
+}