From cc5302af315d7493a8c75deb499cae80599eab60 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 19 Mar 2013 22:10:27 +0100 Subject: [PATCH] Add atof(3). --- libc/Makefile | 1 + libc/atof.cpp | 81 +++++++++++++++++++++++++++++++++++++++++++ libc/include/stdlib.h | 2 +- 3 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 libc/atof.cpp diff --git a/libc/Makefile b/libc/Makefile index f1cd1b44..6ee8c199 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -20,6 +20,7 @@ FREEOBJS=\ abort.o \ abs.o \ _assert.o \ +atof.o \ atoi.o \ atoll.o \ atol.o \ diff --git a/libc/atof.cpp b/libc/atof.cpp new file mode 100644 index 00000000..fa1be629 --- /dev/null +++ b/libc/atof.cpp @@ -0,0 +1,81 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2013. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + atof.cpp + Converts floats represented as strings to binary representation. + +*******************************************************************************/ + +#include +#include + +// TODO: This horribly hacky code is taken from sdlquake's common.c, which is +// licensed under the GPL. Since most Sortix software is GPL-compatible +// this will do for now. It's a temporary measure until I get around to +// writing a real strtod function - most of them are true horrors. + +extern "C" double atof(const char* str) +{ + int sign = *str == '-' ? (str++, -1) : 1; + double val = 0.0; + + if ( str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) + { + str += 2; + while ( true ) + { + char c = *str++; + if ( '0' <= c && c <= '9' ) + val = val * 16 + c - '0'; + else if ( 'a' <= c && c <= 'f' ) + val = val * 16 + c - 'a' + 10; + else if ( 'A' <= c && c <= 'F' ) + val = val * 16 + c - 'A' + 10; + else + return val * sign; + } + } + + int decimal = -1; + int total = 0; + while ( true ) + { + char c = *str++; + if (c == '.') + { + decimal = total; + continue; + } + if ( c < '0' || c > '9' ) + break; + val = val * 10 + c - '0'; + total++; + } + + if ( decimal == -1 ) + return val * sign; + + while ( decimal < total ) + { + val /= 10; + total--; + } + + return val * sign; +} diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index 081ed2f1..48427457 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -64,6 +64,7 @@ typedef struct void abort(void) __attribute__ ((__noreturn__)); int abs(int value); int atexit(void (*function)(void)); +double atof(const char* value); int atoi(const char*); long atol(const char*); long long atoll(const char*); @@ -120,7 +121,6 @@ int clearenv(void); /* TODO: These are not implemented in sortix libc yet. */ #if defined(__SORTIX_SHOW_UNIMPLEMENTED) long a64l(const char* s); -double atof(const char* value); double drand48(void); double erand48(unsigned short [3]); int getsubopt(char**, char* const *, char**);