diff --git a/build-aux/check-mescc.sh b/build-aux/check-mescc.sh index b688b40f..d5fc5d07 100755 --- a/build-aux/check-mescc.sh +++ b/build-aux/check-mescc.sh @@ -200,6 +200,7 @@ if test -z "$bootstrap"; then TESTS="$TESTS lib/tests/dirent/90-readdir.c lib/tests/io/90-stat.c +lib/tests/mes/90-abtod.c lib/tests/posix/90-execlp.c lib/tests/posix/90-unsetenv.c lib/tests/signal/90-signal.c @@ -223,6 +224,7 @@ lib/tests/scaffold/a1-global-no-clobber.c fi XFAIL_TESTS=" +lib/tests/mes/90-abtod.c lib/tests/stdio/90-sprintf.c lib/tests/stdio/90-sprintf.c " @@ -262,6 +264,7 @@ fi if test $compiler = gcc; then XFAIL_TESTS="$XFAIL_TESTS +lib/tests/mes/90-abtod.c " if test $mes_cpu = x86; then diff --git a/build-aux/configure-lib.sh b/build-aux/configure-lib.sh index 02a71430..6c959a6c 100644 --- a/build-aux/configure-lib.sh +++ b/build-aux/configure-lib.sh @@ -86,6 +86,7 @@ lib/linux/lseek.c fi else libmes_SOURCES="$libmes_SOURCES +lib/mes/abtod.c " fi @@ -156,6 +157,7 @@ lib/ctype/islower.c lib/ctype/isupper.c lib/ctype/tolower.c lib/ctype/toupper.c +lib/mes/abtod.c lib/mes/search-path.c lib/posix/execvp.c lib/stdio/fclose.c @@ -180,6 +182,7 @@ lib/stdio/vsprintf.c lib/stdio/vsscanf.c lib/stdlib/calloc.c lib/stdlib/qsort.c +lib/stdlib/strtod.c lib/stdlib/strtof.c lib/stdlib/strtol.c lib/stdlib/strtold.c diff --git a/include/mes/lib.h b/include/mes/lib.h index 1de015fa..e05da652 100644 --- a/include/mes/lib.h +++ b/include/mes/lib.h @@ -28,6 +28,7 @@ void __ungetc_init (); void __ungetc_clear (int filedes); 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 *itoa (int number); char *ltoa (long number); diff --git a/lib/mes/abtod.c b/lib/mes/abtod.c new file mode 100644 index 00000000..a24acf6f --- /dev/null +++ b/lib/mes/abtod.c @@ -0,0 +1,53 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2016,2017,2018,2019 Jan (janneke) Nieuwenhuizen + * + * 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 . + */ + +#include + +double +abtod (char const **p, int base) +{ + char const *s = *p; + double d = 0; + int sign_p = 0; + if (!base) + base = 10; + double dbase = base; + long i = abtol (&s, base); + long f = 0; + long e = 0; + if (*s == '.') + { + s++; + f = abtol (&s, base); + } + if (*s == 'e') + { + s++; + e = abtol (&s, base); + } + d = i + f / dbase; + if (e < 0) + while (e++) + d = d / dbase; + while (e--) + d = d * dbase; + *p = s; + return sign_p ? -d : d; +} diff --git a/lib/mes/abtol.c b/lib/mes/abtol.c index d16a6ea4..44a474b1 100644 --- a/lib/mes/abtol.c +++ b/lib/mes/abtol.c @@ -26,12 +26,16 @@ abtol (char const **p, int base) { char const *s = *p; int i = 0; - int sign = 1; + int sign_p = 0; if (!base) base = 10; + while (isspace (*s)) + s++; + if (*s && *s == '+') + s++; if (*s && *s == '-') { - sign = -1; + sign_p = 1; s++; } while (isnumber (*s, base)) @@ -42,5 +46,5 @@ abtol (char const **p, int base) s++; } *p = s; - return i * sign; + return sign_p ? -i : i; } diff --git a/lib/stdlib/strtod.c b/lib/stdlib/strtod.c new file mode 100644 index 00000000..65367f51 --- /dev/null +++ b/lib/stdlib/strtod.c @@ -0,0 +1,41 @@ +/* -*-comment-start: "//";comment-end:""-*- + * GNU Mes --- Maxwell Equations of Software + * Copyright © 2017,2018,2019 Jan (janneke) Nieuwenhuizen + * + * 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 . + */ + +#include +#include +#include + +double +strtod (char const *string, char **tailptr) +{ + int base = 10; + if (!strncmp (string, "0x", 2)) + { + string += 2; + base = 16; + } + if (tailptr) + { + *tailptr = (char *) string; + return abtod ((char const **) tailptr, base); + } + char **p = (char **) &string; + return abtod ((char const **) p, base); +} diff --git a/lib/stub/strtod.c b/lib/tests/mes/90-abtod.c similarity index 79% rename from lib/stub/strtod.c rename to lib/tests/mes/90-abtod.c index 4638fcae..9f081fde 100644 --- a/lib/stub/strtod.c +++ b/lib/tests/mes/90-abtod.c @@ -1,6 +1,6 @@ /* -*-comment-start: "//";comment-end:""-*- * GNU Mes --- Maxwell Equations of Software - * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen + * Copyright © 2019 Jan (janneke) Nieuwenhuizen * * This file is part of GNU Mes. * @@ -21,12 +21,13 @@ #include #include -double -strtod (char const *string, char **tailptr) +int +main () { - static int stub = 0; - if (__mes_debug () && !stub) - eputs ("strtod stub\n"); - stub = 1; + char *s = "1.2e3"; + char *p = s; + double d = abtod (&p, 0); + printf ("%f\n", d); + return 0; } diff --git a/lib/tests/mes/90-abtod.stdout b/lib/tests/mes/90-abtod.stdout new file mode 100644 index 00000000..84402f49 --- /dev/null +++ b/lib/tests/mes/90-abtod.stdout @@ -0,0 +1 @@ +1200.000000