diff --git a/libmaxsi/Makefile b/libmaxsi/Makefile index e969d26a..cfb33a9f 100644 --- a/libmaxsi/Makefile +++ b/libmaxsi/Makefile @@ -62,6 +62,7 @@ $(CPU)/signal.o \ start.o \ time.o \ random.o \ +integer.o MAXSIHEADERS=\ error.h \ diff --git a/libmaxsi/c/hsrc/stdlib.h b/libmaxsi/c/hsrc/stdlib.h index 6c32d0f4..e700b5a9 100644 --- a/libmaxsi/c/hsrc/stdlib.h +++ b/libmaxsi/c/hsrc/stdlib.h @@ -51,6 +51,10 @@ void _Exit(int status); void free(void*); void* malloc(size_t); int rand(void); +long strtol(const char* restrict, char** restrict, int); +unsigned long strtoul(const char* restrict, char** restrict, int); +unsigned long long strtoull(const char* restrict, char** restrict, int); +long long strtoll(const char* restrict, char** restrict, int); /* TODO: These are not implemented in libmaxsi/sortix yet. */ #ifndef SORTIX_UNIMPLEMENTED @@ -103,11 +107,7 @@ void srand48(long); void srandom(unsigned); double strtod(const char* restrict, char** restrict); float strtof(const char* restrict, char** restrict); -long strtol(const char* restrict, char** restrict, int); long double strtold(const char* restrict, char** restrict); -long long strtoll(const char* restrict, char** restrict, int); -unsigned long strtoul(const char* restrict, char** restrict, int); -unsigned long long strtoull(const char* restrict, char** restrict, int); int system(const char*); int unlockpt(int); int unsetenv(const char*); diff --git a/libmaxsi/integer.cpp b/libmaxsi/integer.cpp new file mode 100644 index 00000000..845c762d --- /dev/null +++ b/libmaxsi/integer.cpp @@ -0,0 +1,106 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of LibMaxsi. + + LibMaxsi 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. + + LibMaxsi 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 LibMaxsi. If not, see . + + init.cpp + Initializes the process by setting up the heap, signal handling, + static memory and other useful things. + +******************************************************************************/ + +#include "platform.h" + +namespace Maxsi +{ + namespace Integer + { + static bool IsSpace(char c) + { + switch ( c ) + { + case ' ': + case '\r': + case '\f': + case '\n': + case '\t': + case '\v': + return true; + } + return false; + } + + static int Debase(char c) + { + if ( '0' <= c && c <= '9' ) { return c - '0'; } + if ( 'a' <= c && c <= 'z' ) { return c - 'a'; } + if ( 'A' <= c && c <= 'Z' ) { return c - 'A'; } + return -1; + } + + template INT ParseInteger(const char* str, char** endptr, int base) + { + int origbase = base; + while ( IsSpace(*str) ) { str++; } + if ( base < 0 || 36 < base ) { if ( endptr ) { *endptr = (char*) str; } return 0; } + INT result = 0; + bool negative = false; + char c = *str; + if ( !UNSIGNED && c == '-' ) { str++; negative = true; } + if ( !UNSIGNED && c == '+' ) { str++; negative = false; } + if ( !base && str[0] == '0' ) + { + if ( str[1] == 'x' || str[1] == 'X' ) { str += 2; base = 16; } + else { str++; base = 8; } + } + if ( !base ) { base = 10; } + if ( origbase == 16 && str[0] == '0' && (str[1] == 'x' || str[1] == 'X') ) { str += 2; } + while ( (c = *str++ ) ) + { + int val = Debase(c); + if ( val < 0 ) { break; } + if ( base <= val ) { break; } + if ( !UNSIGNED && negative ) { val = -val; } + // TODO: Detect overflow! + result = result * (INT) base + (INT) val; + } + if ( endptr ) { *endptr = (char*) str; } + return result; + } + + extern "C" long int strtol(const char* str, char** endptr, int base) + { + return ParseInteger(str, endptr, base); + } + + extern "C" long int strtoll(const char* str, char** endptr, int base) + { + return ParseInteger(str, endptr, base); + } + + extern "C" unsigned long int strtoul(const char* str, char** endptr, int base) + { + return ParseInteger(str, endptr, base); + } + + extern "C" unsigned long int strtoull(const char* str, char** endptr, int base) + { + return ParseInteger(str, endptr, base); + } + } +} +