From 93714ad0a4b2ae59cb7eccedc83cd53e3cfcee8a Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sat, 19 Aug 2017 10:51:24 +0200 Subject: [PATCH] mescc: Tinycc support: strtoull. * 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 | 3 ++- mlibc/include/ctype.h | 1 + mlibc/include/mlibc.h | 5 +++- mlibc/libc-gcc.c | 37 +++++++++++++++++++++++--- mlibc/libc-mes+tcc.c | 6 ++--- mlibc/libc-mes.c | 44 +++++++++++++++++++++++++------ scaffold/tests/7j-strtoull.c | 50 ++++++++++++++++++++++++++++++++++++ 7 files changed, 129 insertions(+), 17 deletions(-) create mode 100644 scaffold/tests/7j-strtoull.c diff --git a/make.scm b/make.scm index fea0869a..fc4080ae 100755 --- 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))) diff --git a/mlibc/include/ctype.h b/mlibc/include/ctype.h index 32be3c50..d6e961c2 100644 --- a/mlibc/include/ctype.h +++ b/mlibc/include/ctype.h @@ -29,6 +29,7 @@ #else // ! (__GNUC__ && POSIX) int isdigit (int); +int isxdigit (int); #endif // ! (__GNUC__ && POSIX) #endif // __MES_CTYPE_H diff --git a/mlibc/include/mlibc.h b/mlibc/include/mlibc.h index 84573acb..fb24f0bb 100644 --- a/mlibc/include/mlibc.h +++ b/mlibc/include/mlibc.h @@ -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 diff --git a/mlibc/libc-gcc.c b/mlibc/libc-gcc.c index 2a636e8a..d278e00b 100644 --- a/mlibc/libc-gcc.c +++ b/mlibc/libc-gcc.c @@ -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 diff --git a/mlibc/libc-mes+tcc.c b/mlibc/libc-mes+tcc.c index 23d7da59..1ef52069 100644 --- a/mlibc/libc-mes+tcc.c +++ b/mlibc/libc-mes+tcc.c @@ -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) diff --git a/mlibc/libc-mes.c b/mlibc/libc-mes.c index eee37500..d4f985a3 100644 --- a/mlibc/libc-mes.c +++ b/mlibc/libc-mes.c @@ -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 index 00000000..3d113174 --- /dev/null +++ b/scaffold/tests/7j-strtoull.c @@ -0,0 +1,50 @@ +/* -*-comment-start: "//";comment-end:""-*- + * Mes --- Maxwell Equations of Software + * Copyright © 2017 Jan Nieuwenhuizen + * + * 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 . + */ + +#include "30-test.i" +#include +#include +#include +#include + +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; +}