diff --git a/cores/arduino/Arduino.h b/cores/arduino/Arduino.h index 053ea7f..eacc1c5 100644 --- a/cores/arduino/Arduino.h +++ b/cores/arduino/Arduino.h @@ -30,6 +30,7 @@ // AVR stuff, assuming Arduino.h or WProgram.h // automatically includes it... #include +#include //#include #include "binary.h" diff --git a/cores/arduino/WString.cpp b/cores/arduino/WString.cpp index a683864..a5fd924 100644 --- a/cores/arduino/WString.cpp +++ b/cores/arduino/WString.cpp @@ -20,11 +20,11 @@ */ #include "WString.h" -#include "itoa.h" +#include "stdlib_noniso.h" + -#ifdef NOTYET /* XXX Marko FIXME! */ #include "avr/dtostrf.h" -#endif + extern "C" { #include "avr/pgmspace.h" @@ -114,7 +114,7 @@ String::String(unsigned long value, unsigned char base) *this = buf; } -#ifdef NOTYET /* XXX Marko FIXME! */ + String::String(float value, unsigned char decimalPlaces) { init(); @@ -128,7 +128,7 @@ String::String(double value, unsigned char decimalPlaces) char buf[33]; *this = dtostrf(value, (decimalPlaces + 2), decimalPlaces, buf); } -#endif /* XXX Marko FIXME! */ + String::~String() { @@ -331,7 +331,7 @@ unsigned char String::concat(unsigned long num) return concat(buf, strlen(buf)); } -#ifdef NOTYET /* XXX Marko FIXME! */ + unsigned char String::concat(float num) { char buf[20]; @@ -345,7 +345,7 @@ unsigned char String::concat(double num) char* string = dtostrf(num, 4, 2, buf); return concat(string, strlen(string)); } -#endif /* XXX Marko FIXME! */ + unsigned char String::concat(const __FlashStringHelper * str) { @@ -748,7 +748,7 @@ void String::trim(void) /* Parsing / Conversion */ /*********************************************/ -#ifdef NOTYET /* XXX Marko FIXME! */ + long String::toInt(void) const { if (buffer) return atol(buffer); @@ -760,4 +760,4 @@ float String::toFloat(void) const if (buffer) return float(atof(buffer)); return 0; } -#endif /* XXX Marko FIXME! */ + diff --git a/cores/arduino/avr/dtostrf.h b/cores/arduino/avr/dtostrf.h new file mode 100644 index 0000000..2d287ca --- /dev/null +++ b/cores/arduino/avr/dtostrf.h @@ -0,0 +1,34 @@ +/* + dtostrf - Emulation for dtostrf function from avr-libc + Copyright (c) 2015 Arduino LLC. All rights reserved. + + This 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 2.1 of the License, or (at your option) any later version. + + This 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#if !defined(ARDUINO_ARCH_AVR) + +#ifdef __cplusplus +extern "C" { +#endif + +char *dtostrf(double val, signed char width, unsigned char prec, char *sout); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cores/arduino/itoa.c b/cores/arduino/itoa.c deleted file mode 100644 index 5e61d0a..0000000 --- a/cores/arduino/itoa.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This 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 2.1 of the License, or (at your option) any later version. - - This 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 this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "itoa.h" -#include - -#ifdef __cplusplus -extern "C"{ -#endif // __cplusplus - -#if 0 -/* reverse: reverse string s in place */ -static void reverse( char s[] ) -{ - int i, j ; - char c ; - - for ( i = 0, j = strlen(s)-1 ; i < j ; i++, j-- ) - { - c = s[i] ; - s[i] = s[j] ; - s[j] = c ; - } -} - -/* itoa: convert n to characters in s */ -extern void itoa( int n, char s[] ) -{ - int i, sign ; - - if ( (sign = n) < 0 ) /* record sign */ - { - n = -n; /* make n positive */ - } - - i = 0; - do - { /* generate digits in reverse order */ - s[i++] = n % 10 + '0'; /* get next digit */ - } while ((n /= 10) > 0) ; /* delete it */ - - if (sign < 0 ) - { - s[i++] = '-'; - } - - s[i] = '\0'; - - reverse( s ) ; -} - -#else - -extern char* ltoa( long value, char *string, int radix ) -{ - char tmp[33]; - char *tp = tmp; - long i; - unsigned long v; - int sign; - char *sp; - - if ( string == NULL ) - { - return 0 ; - } - - if (radix > 36 || radix <= 1) - { - return 0 ; - } - - sign = (radix == 10 && value < 0); - if (sign) - { - v = -value; - } - else - { - v = (unsigned long)value; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+'0'; - else - *tp++ = i + 'a' - 10; - } - - sp = string; - - if (sign) - *sp++ = '-'; - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - - return string; -} - -extern char* ultoa( unsigned long value, char *string, int radix ) -{ - char tmp[33]; - char *tp = tmp; - long i; - unsigned long v = value; - char *sp; - - if ( string == NULL ) - { - return 0; - } - - if (radix > 36 || radix <= 1) - { - return 0; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+'0'; - else - *tp++ = i + 'a' - 10; - } - - sp = string; - - - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - - return string; -} -#endif /* 0 */ - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus diff --git a/cores/arduino/itoa.h b/cores/arduino/itoa.h index b9b4dbc..17f14c5 100644 --- a/cores/arduino/itoa.h +++ b/cores/arduino/itoa.h @@ -23,8 +23,10 @@ extern "C"{ #endif // __cplusplus -extern char* ltoa( long value, char *string, int radix ) ; -extern char* ultoa( unsigned long value, char *string, int radix ) ; +extern char* itoa(int value, char *string, int radix); +extern char* ltoa(long value, char *string, int radix); +extern char* utoa(unsigned value, char *string, int radix); +extern char* ultoa(unsigned long value, char *string, int radix); #ifdef __cplusplus } // extern "C" diff --git a/cores/arduino/stdlib_noniso.c b/cores/arduino/stdlib_noniso.c new file mode 100644 index 0000000..e792048 --- /dev/null +++ b/cores/arduino/stdlib_noniso.c @@ -0,0 +1,161 @@ +/* + core_esp8266_noniso.c - nonstandard (but usefull) conversion functions + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This 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 2.1 of the License, or (at your option) any later version. + + This 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 03 April 2015 by Markus Sattler + + */ + +#include +#include +#include +#include +#include +#include "stdlib_noniso.h" + +void reverse(char* begin, char* end) { + char *is = begin; + char *ie = end - 1; + while(is < ie) { + char tmp = *ie; + *ie = *is; + *is = tmp; + ++is; + --ie; + } +} + +char* ltoa(long value, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } + + char* out = result; + long quotient = abs(value); + + do { + const long tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); + + // Apply negative sign + if(value < 0) + *out++ = '-'; + + reverse(result, out); + *out = 0; + return result; +} + +char* ultoa(unsigned long value, char* result, int base) { + if(base < 2 || base > 16) { + *result = 0; + return result; + } + + char* out = result; + unsigned long quotient = value; + + do { + const unsigned long tmp = quotient / base; + *out = "0123456789abcdef"[quotient - (tmp * base)]; + ++out; + quotient = tmp; + } while(quotient); + + reverse(result, out); + *out = 0; + return result; +} + +char * dtostrf(double number, signed char width, unsigned char prec, char *s) { + bool negative = false; + + if (isnan(number)) { + strcpy(s, "nan"); + return s; + } + if (isinf(number)) { + strcpy(s, "inf"); + return s; + } + + char* out = s; + + int fillme = width; // how many cells to fill for the integer part + if (prec > 0) { + fillme -= (prec+1); + } + + // Handle negative numbers + if (number < 0.0) { + negative = true; + fillme--; + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + // I optimized out most of the divisions + double rounding = 2.0; + for (uint8_t i = 0; i < prec; ++i) + rounding *= 10.0; + rounding = 1.0 / rounding; + + number += rounding; + + // Figure out how big our number really is + double tenpow = 1.0; + int digitcount = 1; + while (number >= 10.0 * tenpow) { + tenpow *= 10.0; + digitcount++; + } + + number /= tenpow; + fillme -= digitcount; + + // Pad unused cells with spaces + while (fillme-- > 0) { + *out++ = ' '; + } + + // Handle negative sign + if (negative) *out++ = '-'; + + // Print the digits, and if necessary, the decimal point + digitcount += prec; + int8_t digit = 0; + while (digitcount-- > 0) { + digit = (int8_t)number; + if (digit > 9) digit = 9; // insurance + *out++ = (char)('0' | digit); + if ((digitcount == prec) && (prec > 0)) { + *out++ = '.'; + } + number -= digit; + number *= 10.0; + } + + // make sure the string is terminated + *out = 0; + return s; +} diff --git a/cores/arduino/stdlib_noniso.h b/cores/arduino/stdlib_noniso.h new file mode 100644 index 0000000..3df2cc2 --- /dev/null +++ b/cores/arduino/stdlib_noniso.h @@ -0,0 +1,49 @@ +/* + stdlib_noniso.h - nonstandard (but usefull) conversion functions + + Copyright (c) 2014 Ivan Grokhotkov. All rights reserved. + + This 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 2.1 of the License, or (at your option) any later version. + + This 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 this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef STDLIB_NONISO_H +#define STDLIB_NONISO_H + +#ifdef __cplusplus +extern "C" { +#endif + +int atoi(const char *s); + +long atol(const char* s); + +double atof(const char* s); + +char* itoa (int val, char *s, int radix); + +char* ltoa (long val, char *s, int radix); + +char* utoa (unsigned int val, char *s, int radix); + +char* ultoa (unsigned long val, char *s, int radix); + +char* dtostrf (double val, signed char width, unsigned char prec, char *s); + +#ifdef __cplusplus +} // extern "C" +#endif + + +#endif