diff --git a/app/include/user_config.h b/app/include/user_config.h index b6c80153..c812f2fa 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -7,7 +7,7 @@ #define NODE_VERSION_INTERNAL 0U #define NODE_VERSION "NodeMCU 0.9.5" -#define BUILD_DATE "build 20150126" +#define BUILD_DATE "build 20150127" // #define FLASH_512K // #define FLASH_1M @@ -67,7 +67,10 @@ #define LUA_USE_MODULES_MQTT #endif /* LUA_USE_MODULES */ -#define LUA_NUMBER_INTEGRAL +// #define LUA_NUMBER_INTEGRAL +#ifndef LUA_NUMBER_INTEGRAL +#define PRINTF_LONG_SUPPORT +#endif #define LUA_OPTRAM #ifdef LUA_OPTRAM diff --git a/app/libc/c_math.c b/app/libc/c_math.c index 185e5691..859b143b 100644 --- a/app/libc/c_math.c +++ b/app/libc/c_math.c @@ -1,37 +1,172 @@ #include "c_math.h" #include "c_types.h" +double floor(double x) +{ + return (double) (x < 0.f ? (((int) x) - 1) : ((int) x)); +} + +double pow(double x, double y) +{ +#define MAXEXP 2031 /* (MAX_EXP * 16) - 1 */ +#define MINEXP -2047 /* (MIN_EXP * 16) - 1 */ +#define HUGE MAXFLOAT + double a1[] = + { + 1.0, + 0.95760328069857365, + 0.91700404320467123, + 0.87812608018664974, + 0.84089641525371454, + 0.80524516597462716, + 0.77110541270397041, + 0.73841307296974966, + 0.70710678118654752, + 0.67712777346844637, + 0.64841977732550483, + 0.62092890603674203, + 0.59460355750136054, + 0.56939431737834583, + 0.54525386633262883, + 0.52213689121370692, + 0.50000000000000000 + }; + double a2[] = + { + 0.24114209503420288E-17, + 0.92291566937243079E-18, + -0.15241915231122319E-17, + -0.35421849765286817E-17, + -0.31286215245415074E-17, + -0.44654376565694490E-17, + 0.29306999570789681E-17, + 0.11260851040933474E-17 + }; + double p1 = 0.833333333333332114e-1; + double p2 = 0.125000000005037992e-1; + double p3 = 0.223214212859242590e-2; + double p4 = 0.434457756721631196e-3; + double q1 = 0.693147180559945296e0; + double q2 = 0.240226506959095371e0; + double q3 = 0.555041086640855953e-1; + double q4 = 0.961812905951724170e-2; + double q5 = 0.133335413135857847e-2; + double q6 = 0.154002904409897646e-3; + double q7 = 0.149288526805956082e-4; + double k = 0.442695040888963407; + + double frexp(), g, ldexp(), r, u1, u2, v, w, w1, w2, y1, y2, z; + int iw1, m, p; + + if (y == 0.0) + return (1.0); + if (x <= 0.0) + { + if (x == 0.0) + { + if (y > 0.0) + return (x); + //cmemsg(FP_POWO, &y); + //return(HUGE); + } + else + { + //cmemsg(FP_POWN, &x); + x = -x; + } + } + g = frexp(x, &m); + p = 0; + if (g <= a1[8]) + p = 8; + if (g <= a1[p + 4]) + p += 4; + if (g <= a1[p + 2]) + p += 2; + p++; + z = ((g - a1[p]) - a2[p / 2]) / (g + a1[p]); + z += z; + v = z * z; + r = (((p4 * v + p3) * v + p2) * v + p1) * v * z; + r += k * r; + u2 = (r + z * k) + z; + u1 = 0.0625 * (double)(16 * m - p); + y1 = 0.0625 * (double)((int)(16.0 * y)); + y2 = y - y1; + w = u2 * y + u1 * y2; + w1 = 0.0625 * (double)((int)(16.0 * w)); + w2 = w - w1; + w = w1 + u1 * y1; + w1 = 0.0625 * (double)((int)(16.0 * w)); + w2 += (w - w1); + w = 0.0625 * (double)((int)(16.0 * w2)); + iw1 = 16.0 * (w1 + w); + w2 -= w; + while (w2 > 0.0) + { + iw1++; + w2 -= 0.0625; + } + if (iw1 > MAXEXP) + { + //cmemsg(FP_POWO, &y); + return (HUGE); + } + if (iw1 < MINEXP) + { + //cmemsg(FP_POWU, &y); + return (0.0); + } + m = iw1 / 16; + if (iw1 >= 0) + m++; + p = 16 * m - iw1; + z = ((((((q7 * w2 + q6) * w2 + q5) * w2 + q4) * w2 + q3) * w2 + q2) * w2 + q1) * w2; + z = a1[p] + a1[p] * z; + return (ldexp(z, m)); +} + #if 0 #ifndef __math_68881 -double atan(double x){ - return x; +double atan(double x) +{ + return x; } -double cos(double x){ - return x; +double cos(double x) +{ + return x; } -double sin(double x){ - return x; +double sin(double x) +{ + return x; } -double tan(double x){ - return x; +double tan(double x) +{ + return x; } -double tanh(double x){ - return x; +double tanh(double x) +{ + return x; } -double frexp(double x, int *y){ - return x; +double frexp(double x, int *y) +{ + return x; } -double modf(double x, double *y){ - return x; +double modf(double x, double *y) +{ + return x; } -double ceil(double x){ - return x; +double ceil(double x) +{ + return x; } -double fabs(double x){ - return x; +double fabs(double x) +{ + return x; } -double floor(double x){ - return x; +double floor(double x) +{ + return x; } #endif /* ! defined (__math_68881) */ @@ -39,41 +174,53 @@ double floor(double x){ #ifndef _REENT_ONLY #ifndef __math_68881 -double acos(double x){ - return x; +double acos(double x) +{ + return x; } -double asin(double x){ - return x; +double asin(double x) +{ + return x; } -double atan2(double x, double y){ - return x; +double atan2(double x, double y) +{ + return x; } -double cosh(double x){ - return x; +double cosh(double x) +{ + return x; } -double sinh(double x){ - return x; +double sinh(double x) +{ + return x; } -double exp(double x){ - return x; +double exp(double x) +{ + return x; } -double ldexp(double x, int y){ - return x; +double ldexp(double x, int y) +{ + return x; } -double log(double x){ - return x; +double log(double x) +{ + return x; } -double log10(double x){ - return x; +double log10(double x) +{ + return x; } -double pow(double x, double y){ - return x; +double pow(double x, double y) +{ + return x; } -double sqrt(double x){ - return x; +double sqrt(double x) +{ + return x; } -double fmod(double x, double y){ - return x; +double fmod(double x, double y) +{ + return x; } #endif /* ! defined (__math_68881) */ #endif /* ! defined (_REENT_ONLY) */ diff --git a/app/libc/c_math.h b/app/libc/c_math.h index 65e31afe..ef18ee79 100644 --- a/app/libc/c_math.h +++ b/app/libc/c_math.h @@ -1,6 +1,10 @@ #ifndef _C_MATH_H_ #define _C_MATH_H_ #include + +double floor(double); +double pow(double, double); + #if 0 #ifndef HUGE_VAL #define HUGE_VAL (1.0e99) diff --git a/app/libc/c_stdio.c b/app/libc/c_stdio.c index 0d52d29c..de9954cd 100644 --- a/app/libc/c_stdio.c +++ b/app/libc/c_stdio.c @@ -12,44 +12,457 @@ int c_stderr = 1001; // FILE *c_tmpfile(void){ // } -// int c_putchar(int c){ +// int c_putchar(int c){ // } -// int c_printf(const char *c, ...){ +// int c_printf(const char *c, ...){ // } // int c_sprintf(char *c, const char *s, ...){ // } -// int c_fprintf(FILE *f, const char *s, ...){ +// int c_fprintf(FILE *f, const char *s, ...){ // } -// int c_fscanf(FILE *f, const char *s, ...){ +// int c_fscanf(FILE *f, const char *s, ...){ // } -// int c_fclose(FILE *f){ +// int c_fclose(FILE *f){ // } -// int c_fflush(FILE *f){ +// int c_fflush(FILE *f){ // } -// int c_setvbuf(FILE *f, char *c, int d, size_t t){ +// int c_setvbuf(FILE *f, char *c, int d, size_t t){ // } // void c_clearerr(FILE *f){ // } -// int c_fseek(FILE *f, long l, int d){ +// int c_fseek(FILE *f, long l, int d){ // } // long c_ftell( FILE *f){ // } -// int c_fputs(const char *c, FILE *f){ +// int c_fputs(const char *c, FILE *f){ // } // char *c_fgets(char *c, int d, FILE *f){ // } -// int c_ungetc(int d, FILE *f){ +// int c_ungetc(int d, FILE *f){ // } // size_t c_fread(void *p, size_t _size, size_t _n, FILE *f){ // } // size_t c_fwrite(const void *p, size_t _size, size_t _n, FILE *f){ // } -// int c_feof(FILE *f){ +// int c_feof(FILE *f){ // } -// int c_ferror(FILE *f){ +// int c_ferror(FILE *f){ // } -// int c_getc(FILE *f){ +// int c_getc(FILE *f){ // } + +#if defined( LUA_NUMBER_INTEGRAL ) + +#else + +/* +File: printf.c + +Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list +of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this +list of conditions and the following disclaimer in the documentation and/or other +materials provided with the distribution. + +Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its +contributors may be used to endorse or promote products derived from this software +without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY +OF SUCH DAMAGE. + +---------------------------------------------------------------------- + +This library is realy just two files: 'printf.h' and 'printf.c'. + +They provide a simple and small (+200 loc) printf functionality to +be used in embedded systems. + +I've found them so usefull in debugging that I do not bother with a +debugger at all. + +They are distributed in source form, so to use them, just compile them +into your project. + +Two printf variants are provided: printf and sprintf. + +The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. + +Zero padding and field width are also supported. + +If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the +long specifier is also +supported. Note that this will pull in some long math routines (pun intended!) +and thus make your executable noticably longer. + +The memory foot print of course depends on the target cpu, compiler and +compiler options, but a rough guestimate (based on a H8S target) is about +1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. +Not too bad. Your milage may vary. By hacking the source code you can +get rid of some hunred bytes, I'm sure, but personally I feel the balance of +functionality and flexibility versus code size is close to optimal for +many embedded systems. + +To use the printf you need to supply your own character output function, +something like : + +void putc ( void* p, char c) + { + while (!SERIAL_PORT_EMPTY) ; + SERIAL_PORT_TX_REGISTER = c; + } + +Before you can call printf you need to initialize it to use your +character output function with something like: + +init_printf(NULL,putc); + +Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', +the NULL (or any pointer) you pass into the 'init_printf' will eventually be +passed to your 'putc' routine. This allows you to pass some storage space (or +anything realy) to the character output function, if necessary. +This is not often needed but it was implemented like that because it made +implementing the sprintf function so neat (look at the source code). + +The code is re-entrant, except for the 'init_printf' function, so it +is safe to call it from interupts too, although this may result in mixed output. +If you rely on re-entrancy, take care that your 'putc' function is re-entrant! + +The printf and sprintf functions are actually macros that translate to +'tfp_printf' and 'tfp_sprintf'. This makes it possible +to use them along with 'stdio.h' printf's in a single source file. +You just need to undef the names before you include the 'stdio.h'. +Note that these are not function like macros, so if you have variables +or struct members with these names, things will explode in your face. +Without variadic macros this is the best we can do to wrap these +fucnction. If it is a problem just give up the macros and use the +functions directly or rename them. + +For further details see source code. + +regs Kusti, 23.10.2004 +*/ + +/* +Add lightweight %g support by vowstar, +NodeMCU Team, 26.1.2015 +*/ + +typedef void (*putcf) (void *, char); + +#ifdef PRINTF_LONG_SUPPORT + +static int uli2a(unsigned long int num, unsigned int base, int uc, char *bf) +{ + int n = 0; + unsigned long int d = 1; + int len = 1; + while (num / d >= base) + { + d *= base; + len ++; + } + while (d != 0) + { + int dgt = num / d; + num %= d; + d /= base; + if (n || dgt > 0 || d == 0) + { + *bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; + return len; +} + +static int li2a (long num, char *bf) +{ + int len = 0; + if (num < 0) + { + num = -num; + *bf++ = '-'; + len ++; + } + len += uli2a(num, 10, 0, bf); + return len; +} + +#endif + +static int ui2a(unsigned int num, unsigned int base, int uc, char *bf) +{ + int n = 0; + unsigned int d = 1; + int len = 1; + while (num / d >= base) + { + d *= base; + len ++; + } + while (d != 0) + { + int dgt = num / d; + num %= d; + d /= base; + if (n || dgt > 0 || d == 0) + { + *bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10); + ++n; + } + } + *bf = 0; + return len; +} + +static int i2a (int num, char *bf) +{ + int len = 0; + if (num < 0) + { + num = -num; + *bf++ = '-'; + len ++; + } + len += ui2a(num, 10, 0, bf); + return len; +} + +// Converts a floating point number to string. +static int d2a(double num, char *bf) +{ + int len = 0; + double ipart = 0; + double fpart = 0; + double absnum = num; + + // Add sign + if (absnum < 0) + { + absnum = -absnum; + *bf++ = '-'; + // len must add 1 when return + // but can't add at here + } + + // Extract integer part + ipart = (int)absnum; + + // Extract floating part + fpart = absnum - (double)ipart; + + // convert integer part to string +#ifdef PRINTF_LONG_SUPPORT + len += li2a(ipart, bf); +#else + len += i2a(ipart, bf); +#endif + +#ifndef EPSILON +#define EPSILON ((double)(0.00000001)) +#endif + if (fpart < EPSILON) + { + // fpart is zero + } + else + { + bf += len; + // add dot + *bf ++ = '.'; + len += 1; + // add zero after dot + while (fpart < 0.1) + { + fpart *= 10; + *bf ++ = '0'; + len += 1; + } + while ((fpart < (double)1.0 / EPSILON) && ((fpart - (int)fpart) > EPSILON)) + { + fpart = fpart * 10; + } +#ifdef PRINTF_LONG_SUPPORT + len += li2a((int)fpart, bf); +#else + len += i2a((int)fpart, bf); +#endif + } +#undef EPSILON + if (num < 0) + { + len ++; + } + return len; +} + +static int a2d(char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + else if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + else if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + else return -1; +} + +static char a2i(char ch, char **src, int base, int *nump) +{ + char *p = *src; + int num = 0; + int digit; + while ((digit = a2d(ch)) >= 0) + { + if (digit > base) break; + num = num * base + digit; + ch = *p++; + } + *src = p; + *nump = num; + return ch; +} + +static void putchw(void *putp, putcf putf, int n, char z, char *bf) +{ + char fc = z ? '0' : ' '; + char ch; + char *p = bf; + while (*p++ && n > 0) + n--; + while (n-- > 0) + putf(putp, fc); + while ((ch = *bf++)) + putf(putp, ch); +} + +void c_format(void *putp, putcf putf, char *fmt, va_list va) +{ + char bf[12]; + + char ch; + + + while ((ch = *(fmt++))) + { + if (ch != '%') + putf(putp, ch); + else + { + char lz = 0; +#ifdef PRINTF_LONG_SUPPORT + char lng = 0; +#endif + int w = 0; + ch = *(fmt++); + if (ch == '0') + { + ch = *(fmt++); + lz = 1; + } + if (ch >= '0' && ch <= '9') + { + ch = a2i(ch, &fmt, 10, &w); + } +#ifdef PRINTF_LONG_SUPPORT + if (ch == 'l') + { + ch = *(fmt++); + lng = 1; + } +#endif + switch (ch) + { + case 0: + goto abort; + case 'u' : + { +#ifdef PRINTF_LONG_SUPPORT + if (lng) + uli2a(va_arg(va, unsigned long int), 10, 0, bf); + else +#endif + ui2a(va_arg(va, unsigned int), 10, 0, bf); + putchw(putp, putf, w, lz, bf); + break; + } + case 'd' : + { +#ifdef PRINTF_LONG_SUPPORT + if (lng) + li2a(va_arg(va, unsigned long int), bf); + else +#endif + i2a(va_arg(va, int), bf); + putchw(putp, putf, w, lz, bf); + break; + } + case 'x': case 'X' : +#ifdef PRINTF_LONG_SUPPORT + if (lng) + uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf); + else +#endif + ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf); + putchw(putp, putf, w, lz, bf); + break; + case 'g' : + { + d2a(va_arg(va, double), bf); + putchw(putp, putf, w, lz, bf); + break; + } + case 'c' : + putf(putp, (char)(va_arg(va, int))); + break; + case 's' : + putchw(putp, putf, w, 0, va_arg(va, char *)); + break; + case '%' : + putf(putp, ch); + default: + break; + } + } + } +abort:; +} + + +static void putcp(void *p, char c) +{ + *(*((char **)p))++ = c; +} + + +void c_sprintf(char *s, char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + c_format(&s, putcp, fmt, va); + putcp(&s, 0); + va_end(va); +} + +#endif diff --git a/app/libc/c_stdio.h b/app/libc/c_stdio.h index c24f82d2..88c368f6 100644 --- a/app/libc/c_stdio.h +++ b/app/libc/c_stdio.h @@ -56,7 +56,13 @@ extern void output_redirect(const char *str); // #define c_printf os_printf // int c_printf(const char *c, ...); +#if defined( LUA_NUMBER_INTEGRAL ) #define c_sprintf os_sprintf +#else +#include "c_stdarg.h" +void c_sprintf(char* s,char *fmt, ...); +#endif + // #define c_vsprintf ets_vsprintf #define c_printf(...) do { \ unsigned char __print_buf[BUFSIZ]; \ diff --git a/app/libc/c_stdlib.c b/app/libc/c_stdlib.c index 2b2fa1d8..fffd47b5 100644 --- a/app/libc/c_stdlib.c +++ b/app/libc/c_stdlib.c @@ -50,8 +50,207 @@ const char *c_getenv(const char *__string){ // int c_atoi(const char *__nptr){ // } -// double c_strtod(const char *__n, char **__end_PTR){ -// } +#include <_ansi.h> +//#include +#include +//#include "mprec.h" + +double c_strtod(const char *string, char **endPtr) +{ + int maxExponent = 511; /* Largest possible base 10 exponent. Any + * exponent larger than this will already + * produce underflow or overflow, so there's + * no need to worry about additional digits. + */ + double powersOf10[] = { /* Table giving binary powers of 10. Entry */ + 10., /* is 10^2^i. Used to convert decimal */ + 100., /* exponents into floating-point numbers. */ + 1.0e4, + 1.0e8, + 1.0e16, + 1.0e32, + 1.0e64, + 1.0e128, + 1.0e256 + }; + int sign, expSign = FALSE; + double fraction, dblExp, *d; + register const char *p; + register int c; + int exp = 0; /* Exponent read from "EX" field. */ + int fracExp = 0; /* Exponent that derives from the fractional + * part. Under normal circumstatnces, it is + * the negative of the number of digits in F. + * However, if I is very long, the last digits + * of I get dropped (otherwise a long I with a + * large negative exponent could cause an + * unnecessary overflow on I alone). In this + * case, fracExp is incremented one for each + * dropped digit. */ + int mantSize; /* Number of digits in mantissa. */ + int decPt; /* Number of mantissa digits BEFORE decimal + * point. */ + const char *pExp; /* Temporarily holds location of exponent + * in string. */ + + /* + * Strip off leading blanks and check for a sign. + */ + + p = string; + while (isspace((unsigned char)(*p))) { + p += 1; + } + if (*p == '-') { + sign = TRUE; + p += 1; + } else { + if (*p == '+') { + p += 1; + } + sign = FALSE; + } + + /* + * Count the number of digits in the mantissa (including the decimal + * point), and also locate the decimal point. + */ + + decPt = -1; + for (mantSize = 0; ; mantSize += 1) + { + c = *p; + if (!isdigit(c)) { + if ((c != '.') || (decPt >= 0)) { + break; + } + decPt = mantSize; + } + p += 1; + } + + /* + * Now suck up the digits in the mantissa. Use two integers to + * collect 9 digits each (this is faster than using floating-point). + * If the mantissa has more than 18 digits, ignore the extras, since + * they can't affect the value anyway. + */ + + pExp = p; + p -= mantSize; + if (decPt < 0) { + decPt = mantSize; + } else { + mantSize -= 1; /* One of the digits was the point. */ + } + if (mantSize > 18) { + fracExp = decPt - 18; + mantSize = 18; + } else { + fracExp = decPt - mantSize; + } + if (mantSize == 0) { + fraction = 0.0; + p = string; + goto done; + } else { + int frac1, frac2; + frac1 = 0; + for ( ; mantSize > 9; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac1 = 10*frac1 + (c - '0'); + } + frac2 = 0; + for (; mantSize > 0; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac2 = 10*frac2 + (c - '0'); + } + fraction = (1.0e9 * frac1) + frac2; + } + + /* + * Skim off the exponent. + */ + + p = pExp; + if ((*p == 'E') || (*p == 'e')) { + p += 1; + if (*p == '-') { + expSign = TRUE; + p += 1; + } else { + if (*p == '+') { + p += 1; + } + expSign = FALSE; + } + if (!isdigit((unsigned char)(*p))) { + p = pExp; + goto done; + } + while (isdigit((unsigned char)(*p))) { + exp = exp * 10 + (*p - '0'); + p += 1; + } + } + if (expSign) { + exp = fracExp - exp; + } else { + exp = fracExp + exp; + } + + /* + * Generate a floating-point number that represents the exponent. + * Do this by processing the exponent one bit at a time to combine + * many powers of 2 of 10. Then combine the exponent with the + * fraction. + */ + + if (exp < 0) { + expSign = TRUE; + exp = -exp; + } else { + expSign = FALSE; + } + if (exp > maxExponent) { + exp = maxExponent; + // errno = ERANGE; + } + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { + if (exp & 01) { + dblExp *= *d; + } + } + if (expSign) { + fraction /= dblExp; + } else { + fraction *= dblExp; + } + +done: + if (endPtr != NULL) { + *endPtr = (char *) p; + } + + if (sign) { + return -fraction; + } + return fraction; +} + // long c_strtol(const char *__n, char **__end_PTR, int __base){ // } // unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base){ diff --git a/app/libc/c_stdlib.h b/app/libc/c_stdlib.h index c290ee2e..3757c135 100644 --- a/app/libc/c_stdlib.h +++ b/app/libc/c_stdlib.h @@ -36,7 +36,7 @@ #define c_abs abs #define c_atoi atoi -// #define c_strtod strtod +//#define c_strtod strtod #define c_strtol strtol #define c_strtoul strtoul @@ -55,7 +55,7 @@ void c_free(void *); // void c_srand(unsigned int __seed); // int c_atoi(const char *__nptr); -// double c_strtod(const char *__n, char **__end_PTR); +double c_strtod(const char *__n, char **__end_PTR); // // long c_strtol(const char *__n, char **__end_PTR, int __base); // unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base); // // long long c_strtoll(const char *__n, char **__end_PTR, int __base); diff --git a/app/lua/luaconf.h b/app/lua/luaconf.h index 90da40dc..08c50c59 100644 --- a/app/lua/luaconf.h +++ b/app/lua/luaconf.h @@ -601,7 +601,8 @@ extern int readline4lua(const char *prompt, char *buffer, int length); #endif // #if !defined LUA_INTEGRAL_LONGLONG #else #define LUA_NUMBER_SCAN "%lf" -#define LUA_NUMBER_FMT "%.14g" +//#define LUA_NUMBER_FMT "%.14g" +#define LUA_NUMBER_FMT "%g" #endif // #if defined LUA_NUMBER_INTEGRAL #define lua_number2str(s,n) c_sprintf((s), LUA_NUMBER_FMT, (n)) #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ diff --git a/app/lua/lvm.c b/app/lua/lvm.c index fe0243e2..06147856 100644 --- a/app/lua/lvm.c +++ b/app/lua/lvm.c @@ -8,6 +8,7 @@ #include "c_stdio.h" #include "c_stdlib.h" #include "c_string.h" +#include "c_math.h" #define lvm_c #define LUA_CORE diff --git a/ld/eagle.app.v6.ld b/ld/eagle.app.v6.ld index 608fafbd..3234dc02 100644 --- a/ld/eagle.app.v6.ld +++ b/ld/eagle.app.v6.ld @@ -5,7 +5,7 @@ MEMORY dport0_0_seg : org = 0x3FF00000, len = 0x10 dram0_0_seg : org = 0x3FFE8000, len = 0x14000 iram1_0_seg : org = 0x40100000, len = 0x8000 - irom0_0_seg : org = 0x40210000, len = 0x50000 + irom0_0_seg : org = 0x40210000, len = 0x51000 } PHDRS diff --git a/pre_build/0.9.5/nodemcu_20150127.bin b/pre_build/0.9.5/nodemcu_20150127.bin new file mode 100644 index 00000000..91614241 Binary files /dev/null and b/pre_build/0.9.5/nodemcu_20150127.bin differ diff --git a/pre_build/latest/nodemcu_latest.bin b/pre_build/latest/nodemcu_latest.bin index 4e3e63a7..91614241 100644 Binary files a/pre_build/latest/nodemcu_latest.bin and b/pre_build/latest/nodemcu_latest.bin differ