Commit 655b06b4 authored by devsaurus's avatar devsaurus
Browse files

Merge remote-tracking branch 'upstream/dev' into dev

parents 588ea031 2c5c00a5
...@@ -24,10 +24,26 @@ Tencent QQ group: 309957875<br /> ...@@ -24,10 +24,26 @@ Tencent QQ group: 309957875<br />
- fix wifi smart connect - fix wifi smart connect
- add spi module (done) - add spi module (done)
- add mqtt module (done) - add mqtt module (done)
- add coap module - add coap module (in coap branch)
- cross compiler - cross compiler (done)
# Change log # Change log
2015-02-13<br />
add node.compile() api to compile lua text file into lua bytecode file.<br />
this will reduce memory usage noticeably when require modules into NodeMCU.<br />
raise internal LUA_BUFFERSIZE from 1024 to 4096.<br />
lua require("mod") will load "mod.lc" file first if exist.<br />
build latest pre_build bin.
2015-02-12<br />
fix float print.<br />
update spiffs, add file.rename api to file module.<br />
fix some file system bug. need more tests.<br />
add support to 8Mbyte, 16Mbyte flash.<br />
remove node.led() and node.key() api.<br />
some update to lua_modules and examples.<br />
build latest pre_build bin.
2015-01-27<br /> 2015-01-27<br />
support floating point LUA.<br /> support floating point LUA.<br />
use macro LUA_NUMBER_INTEGRAL in user_config.h control this feature.<br /> use macro LUA_NUMBER_INTEGRAL in user_config.h control this feature.<br />
...@@ -44,27 +60,6 @@ added LUA examples and modules [by dvv](https://github.com/dvv). <br /> ...@@ -44,27 +60,6 @@ added LUA examples and modules [by dvv](https://github.com/dvv). <br />
added node.readvdd33() API [by alonewolfx2](https://github.com/alonewolfx2).<br /> added node.readvdd33() API [by alonewolfx2](https://github.com/alonewolfx2).<br />
build pre_build bin. build pre_build bin.
2015-01-24<br />
migrate to sdk 0.9.5 release.<br />
tmr.time() now return second(not precise yet). <br />
build pre_build bin.
2015-01-23<br />
merge mqtt branch to master.<br />
build pre_build bin.
2015-01-18<br />
merge mqtt module to [new branch mqtt](https://github.com/nodemcu/nodemcu-firmware/tree/mqtt) from [https://github.com/tuanpmt/esp_mqtt](https://github.com/tuanpmt/esp_mqtt).<br />
merge spi module from iabdalkader:spi. <br />
fix #110,set local port to random in client mode.<br />
modify gpio.read to NOT set pin to input mode automatic.<br />
add PATH env with C:\MinGW\bin;C:\MinGW\msys\1.0\bin;C:\Python27 in eclipse project. resolve #103.
2015-01-08<br />
fix net.socket:send() issue when multi sends are called. <br />
*NOTE*: if data length is bigger than 1460, send next packet AFTER "sent" callback is called.<br />
fix file.read() api, take 0xFF as a regular byte, not EOF.<br />
pre_build/latest/nodemcu_512k_latest.bin is removed. use pre_build/latest/nodemcu_latest.bin instead.
[more change log](https://github.com/nodemcu/nodemcu-firmware/wiki)<br /> [more change log](https://github.com/nodemcu/nodemcu-firmware/wiki)<br />
...@@ -309,6 +304,7 @@ cu:send("hello") ...@@ -309,6 +304,7 @@ cu:send("hello")
####Use DS18B20 module extends your esp8266 ####Use DS18B20 module extends your esp8266
```lua ```lua
-- read temperature with DS18B20 -- read temperature with DS18B20
node.compile("ds18b20.lua") -- run this only once to compile and save to "ds18b20.lc"
t=require("ds18b20") t=require("ds18b20")
t.setup(9) t.setup(9)
addrs=t.addrs() addrs=t.addrs()
......
...@@ -7,12 +7,16 @@ ...@@ -7,12 +7,16 @@
#define NODE_VERSION_INTERNAL 0U #define NODE_VERSION_INTERNAL 0U
#define NODE_VERSION "NodeMCU 0.9.5" #define NODE_VERSION "NodeMCU 0.9.5"
#define BUILD_DATE "build 20150127" #define BUILD_DATE "build 20150214"
// #define DEVKIT_VERSION_0_9 1 // define this only if you use NodeMCU devkit v0.9
// #define FLASH_512K // #define FLASH_512K
// #define FLASH_1M // #define FLASH_1M
// #define FLASH_2M // #define FLASH_2M
// #define FLASH_4M // #define FLASH_4M
// #define FLASH_8M
// #define FLASH_16M
#define FLASH_AUTOSIZE #define FLASH_AUTOSIZE
// #define DEVELOP_VERSION // #define DEVELOP_VERSION
#define FULL_VERSION_FOR_USER #define FULL_VERSION_FOR_USER
...@@ -48,6 +52,7 @@ ...@@ -48,6 +52,7 @@
#define BUILD_SPIFFS 1 #define BUILD_SPIFFS 1
#define LUA_USE_MODULES #define LUA_USE_MODULES
#ifdef LUA_USE_MODULES #ifdef LUA_USE_MODULES
#define LUA_USE_MODULES_NODE #define LUA_USE_MODULES_NODE
#define LUA_USE_MODULES_FILE #define LUA_USE_MODULES_FILE
...@@ -64,13 +69,16 @@ ...@@ -64,13 +69,16 @@
#define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_BIT
#define LUA_USE_MODULES_U8G #define LUA_USE_MODULES_U8G
#define LUA_USE_MODULES_MQTT #define LUA_USE_MODULES_MQTT
#define LUA_USE_MODULES_WS2812 // #define LUA_USE_MODULES_WS2812 // TODO: put this device specific module to device driver section.
#endif /* LUA_USE_MODULES */ #endif /* LUA_USE_MODULES */
// TODO: put device specific module to device driver section.
#ifdef LUA_USE_DEVICE_DRIVER
#define LUA_USE_DEVICE_WS2812
#endif /* LUA_USE_DEVICE_DRIVER */
// #define LUA_NUMBER_INTEGRAL // #define LUA_NUMBER_INTEGRAL
#ifndef LUA_NUMBER_INTEGRAL
#define PRINTF_LONG_SUPPORT
#endif
#define LUA_OPTRAM #define LUA_OPTRAM
#ifdef LUA_OPTRAM #ifdef LUA_OPTRAM
...@@ -80,6 +88,8 @@ ...@@ -80,6 +88,8 @@
#endif /* LUA_OPTRAM */ #endif /* LUA_OPTRAM */
#define READLINE_INTERVAL 80 #define READLINE_INTERVAL 80
#ifdef DEVKIT_VERSION_0_9
#define KEY_SHORT_MS 200 #define KEY_SHORT_MS 200
#define KEY_LONG_MS 3000 #define KEY_LONG_MS 3000
#define KEY_SHORT_COUNT (KEY_SHORT_MS / READLINE_INTERVAL) #define KEY_SHORT_COUNT (KEY_SHORT_MS / READLINE_INTERVAL)
...@@ -87,6 +97,7 @@ ...@@ -87,6 +97,7 @@
#define LED_HIGH_COUNT_DEFAULT 10 #define LED_HIGH_COUNT_DEFAULT 10
#define LED_LOW_COUNT_DEFAULT 0 #define LED_LOW_COUNT_DEFAULT 0
#endif
// Configure U8glib fonts // Configure U8glib fonts
......
...@@ -58,423 +58,1049 @@ int c_stderr = 1001; ...@@ -58,423 +58,1049 @@ int c_stderr = 1001;
#else #else
/* #define FLOATINGPT 1
File: printf.c #define NEWFP 1
#define ENDIAN_LITTLE 1234
#define ENDIAN_BIG 4321
#define ENDIAN_PDP 3412
#define ENDIAN ENDIAN_BIG
Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs /* $Id: strichr.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
All rights reserved. /*
* Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Opsycon AB.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
//#include <string.h>
#include "c_string.h"
Redistribution and use in source and binary forms, with or without modification, char *
are permitted provided that the following conditions are met: strichr(char *p, int c)
{
char *t;
Redistributions of source code must retain the above copyright notice, this list if (p != NULL) {
of conditions and the following disclaimer. for(t = p; *t; t++);
for (; t >= p; t--) {
*(t + 1) = *t;
}
*p = c;
}
return (p);
}
Redistributions in binary form must reproduce the above copyright notice, this /* $Id: str_fmt.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
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 * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
without specific prior written permission. *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Opsycon AB.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
//#include <string.h>
#include "c_string.h"
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" #define FMT_RJUST 0
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED #define FMT_LJUST 1
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. #define FMT_RJUST0 2
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, #define FMT_CENTER 3
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.
---------------------------------------------------------------------- /*
* Format string by inserting blanks.
*/
This library is realy just two files: 'printf.h' and 'printf.c'. void
str_fmt(char *p, int size, int fmt)
{
int n, m, len;
They provide a simple and small (+200 loc) printf functionality to len = strlen (p);
be used in embedded systems. switch (fmt) {
case FMT_RJUST:
for (n = size - len; n > 0; n--)
strichr (p, ' ');
break;
case FMT_LJUST:
for (m = size - len; m > 0; m--)
strcat (p, " ");
break;
case FMT_RJUST0:
for (n = size - len; n > 0; n--)
strichr (p, '0');
break;
case FMT_CENTER:
m = (size - len) / 2;
n = size - (len + m);
for (; m > 0; m--)
strcat (p, " ");
for (; n > 0; n--)
strichr (p, ' ');
break;
}
}
I've found them so usefull in debugging that I do not bother with a /* $Id: strtoupp.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
debugger at all.
They are distributed in source form, so to use them, just compile them /*
into your project. * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Opsycon AB.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
//#include <string.h>
//#include <ctype.h>
#include "c_string.h"
#include "c_ctype.h"
Two printf variants are provided: printf and sprintf. void
strtoupper(char *p)
{
if(!p)
return;
for (; *p; p++)
*p = toupper (*p);
}
The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. /* $Id: atob.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
Zero padding and field width are also supported. /*
* Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Opsycon AB.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the //#include <sys/types.h>
long specifier is also //#include <string.h>
supported. Note that this will pull in some long math routines (pun intended!) //#include <pmon.h>
and thus make your executable noticably longer. #include "c_string.h"
typedef int int32_t;
typedef unsigned int u_int32_t;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef int32_t register_t;
typedef long long quad_t;
typedef unsigned long long u_quad_t;
typedef double rtype;
The memory foot print of course depends on the target cpu, compiler and #ifndef __P
compiler options, but a rough guestimate (based on a H8S target) is about #define __P(args) args
1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. #endif
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, static char * _getbase __P((char *, int *));
something like : static int _atob __P((unsigned long long *, char *p, int));
void putc ( void* p, char c) static char *
{ _getbase(char *p, int *basep)
while (!SERIAL_PORT_EMPTY) ; {
SERIAL_PORT_TX_REGISTER = c; if (p[0] == '0') {
switch (p[1]) {
case 'x':
*basep = 16;
break;
case 't': case 'n':
*basep = 10;
break;
case 'o':
*basep = 8;
break;
default:
*basep = 10;
return (p);
}
return (p + 2);
} }
*basep = 10;
return (p);
}
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 * _atob(vp,p,base)
passed to your 'putc' routine. This allows you to pass some storage space (or */
anything realy) to the character output function, if necessary. static int
This is not often needed but it was implemented like that because it made _atob (u_quad_t *vp, char *p, int base)
implementing the sprintf function so neat (look at the source code). {
u_quad_t value, v1, v2;
char *q, tmp[20];
int digit;
The code is re-entrant, except for the 'init_printf' function, so it if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
is safe to call it from interupts too, although this may result in mixed output. base = 16;
If you rely on re-entrancy, take care that your 'putc' function is re-entrant! p += 2;
}
The printf and sprintf functions are actually macros that translate to if (base == 16 && (q = strchr (p, '.')) != 0) {
'tfp_printf' and 'tfp_sprintf'. This makes it possible if (q - p > sizeof(tmp) - 1)
to use them along with 'stdio.h' printf's in a single source file. return (0);
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. strncpy (tmp, p, q - p);
tmp[q - p] = '\0';
if (!_atob (&v1, tmp, 16))
return (0);
regs Kusti, 23.10.2004 q++;
*/ if (strchr (q, '.'))
return (0);
/* if (!_atob (&v2, q, 16))
Add lightweight %g support by vowstar, <vowstar@gmail.com> return (0);
NodeMCU Team, 26.1.2015 *vp = (v1 << 16) + v2;
*/ return (1);
}
typedef void (*putcf) (void *, char); value = *vp = 0;
for (; *p; p++) {
if (*p >= '0' && *p <= '9')
digit = *p - '0';
else if (*p >= 'a' && *p <= 'f')
digit = *p - 'a' + 10;
else if (*p >= 'A' && *p <= 'F')
digit = *p - 'A' + 10;
else
return (0);
#ifdef PRINTF_LONG_SUPPORT if (digit >= base)
return (0);
value *= base;
value += digit;
}
*vp = value;
return (1);
}
static int uli2a(unsigned long int num, unsigned int base, int uc, char *bf) /*
* atob(vp,p,base)
* converts p to binary result in vp, rtn 1 on success
*/
int
atob(u_int32_t *vp, char *p, int base)
{ {
int n = 0; u_quad_t v;
unsigned long int d = 1;
int len = 1; if (base == 0)
while (num / d >= base) p = _getbase (p, &base);
{ if (_atob (&v, p, base)) {
d *= base; *vp = v;
len ++; return (1);
}
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 (0);
return len;
} }
static int li2a (long num, char *bf)
/*
* llatob(vp,p,base)
* converts p to binary result in vp, rtn 1 on success
*/
int
llatob(u_quad_t *vp, char *p, int base)
{ {
int len = 0; if (base == 0)
if (num < 0) p = _getbase (p, &base);
{ return _atob(vp, p, base);
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) /*
* char *btoa(dst,value,base)
* converts value to ascii, result in dst
*/
char *
btoa(char *dst, u_int value, int base)
{ {
int n = 0; char buf[34], digit;
unsigned int d = 1; int i, j, rem, neg;
int len = 1;
while (num / d >= base) if (value == 0) {
{ dst[0] = '0';
d *= base; dst[1] = 0;
len ++; return (dst);
} }
while (d != 0)
{ neg = 0;
int dgt = num / d; if (base == -10) {
num %= d; base = 10;
d /= base; if (value & (1L << 31)) {
if (n || dgt > 0 || d == 0) value = (~value) + 1;
{ neg = 1;
*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
++n;
} }
} }
*bf = 0;
return len; for (i = 0; value != 0; i++) {
rem = value % base;
value /= base;
if (rem >= 0 && rem <= 9)
digit = rem + '0';
else if (rem >= 10 && rem <= 36)
digit = (rem - 10) + 'a';
buf[i] = digit;
}
buf[i] = 0;
if (neg)
strcat (buf, "-");
/* reverse the string */
for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--)
dst[i] = buf[j];
dst[i] = 0;
return (dst);
} }
static int i2a (int num, char *bf) /*
* char *btoa(dst,value,base)
* converts value to ascii, result in dst
*/
char *
llbtoa(char *dst, u_quad_t value, int base)
{ {
int len = 0; char buf[66], digit;
if (num < 0) int i, j, rem, neg;
{
num = -num; if (value == 0) {
*bf++ = '-'; dst[0] = '0';
len ++; dst[1] = 0;
return (dst);
} }
len += ui2a(num, 10, 0, bf);
return len; neg = 0;
if (base == -10) {
base = 10;
if (value & (1LL << 63)) {
value = (~value) + 1;
neg = 1;
}
}
for (i = 0; value != 0; i++) {
rem = value % base;
value /= base;
if (rem >= 0 && rem <= 9)
digit = rem + '0';
else if (rem >= 10 && rem <= 36)
digit = (rem - 10) + 'a';
buf[i] = digit;
}
buf[i] = 0;
if (neg)
strcat (buf, "-");
/* reverse the string */
for (i = 0, j = strlen (buf) - 1; j >= 0; i++, j--)
dst[i] = buf[j];
dst[i] = 0;
return (dst);
} }
// Converts a floating point number to string. /*
static int d2a(double num, char *bf) * gethex(vp,p,n)
* convert n hex digits from p to binary, result in vp,
* rtn 1 on success
*/
int
gethex(int32_t *vp, char *p, int n)
{ {
int len = 0; u_long v;
double ipart = 0; int digit;
double fpart = 0;
double absnum = num; for (v = 0; n > 0; n--) {
if (*p == 0)
// Add sign return (0);
if (absnum < 0) if (*p >= '0' && *p <= '9')
{ digit = *p - '0';
absnum = -absnum; else if (*p >= 'a' && *p <= 'f')
*bf++ = '-'; digit = *p - 'a' + 10;
// len must add 1 when return else if (*p >= 'A' && *p <= 'F')
// but can't add at here digit = *p - 'A' + 10;
else
return (0);
v <<= 4;
v |= digit;
p++;
} }
*vp = v;
return (1);
}
// Extract integer part /* $Id: vsprintf.c,v 1.1.1.1 2006/08/23 17:03:06 pefo Exp $ */
ipart = (int)absnum;
// Extract floating part /*
fpart = absnum - (double)ipart; * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Opsycon AB.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
*/
//#include <stdio.h>
//#include <stdarg.h>
//#include <string.h>
//#include <ctype.h>
//#include <pmon.h>
#include "c_stdarg.h"
#include "c_string.h"
#include "c_ctype.h"
// convert integer part to string /*
#ifdef PRINTF_LONG_SUPPORT * int vsprintf(d,s,ap)
len += li2a(ipart, bf); */
#else int
len += i2a(ipart, bf); vsprintf (char *d, const char *s, va_list ap)
{
const char *t;
char *p, *dst, tmp[40];
unsigned int n;
int fmt, trunc, haddot, width, base, longlong;
#ifdef FLOATINGPT
double dbl;
#ifndef NEWFP
EP ex;
#endif #endif
#endif
dst = d;
for (; *s;) {
if (*s == '%') {
s++;
fmt = FMT_RJUST;
width = trunc = haddot = longlong = 0;
for (; *s; s++) {
if (strchr("bcdefgilopPrRsuxX%", *s))
break;
else if (*s == '-')
fmt = FMT_LJUST;
else if (*s == '0')
fmt = FMT_RJUST0;
else if (*s == '~')
fmt = FMT_CENTER;
else if (*s == '*') {
if (haddot)
trunc = va_arg(ap, int);
else
width = va_arg(ap, int);
} else if (*s >= '1' && *s <= '9') {
for (t = s; isdigit(*s); s++);
strncpy(tmp, t, s - t);
tmp[s - t] = '\0';
atob(&n, tmp, 10);
if (haddot)
trunc = n;
else
width = n;
s--;
} else if (*s == '.')
haddot = 1;
}
if (*s == '%') {
*d++ = '%';
*d = 0;
} else if (*s == 's') {
p = va_arg(ap, char *);
if (p)
strcpy(d, p);
else
strcpy(d, "(null)");
} else if (*s == 'c') {
n = va_arg (ap, int);
*d = n;
d[1] = 0;
} else {
if (*s == 'l') {
if (*++s == 'l') {
longlong = 1;
++s;
}
}
if (strchr("bdiopPrRxXu", *s)) {
if (*s == 'd' || *s == 'i')
base = -10;
else if (*s == 'u')
base = 10;
else if (*s == 'x' || *s == 'X')
base = 16;
else if(*s == 'p' || *s == 'P') {
base = 16;
if (*s == 'p') {
*d++ = '0';
*d++ = 'x';
}
fmt = FMT_RJUST0;
if (sizeof(long) > 4) {
width = 16;
longlong = 1;
} else {
width = 8;
}
}
else if(*s == 'r' || *s == 'R') {
base = 16;
if (*s == 'r') {
*d++ = '0';
*d++ = 'x';
}
fmt = FMT_RJUST0;
if (sizeof(register_t) > 4) {
width = 16;
longlong = 1;
} else {
width = 8;
}
}
else if (*s == 'o')
base = 8;
else if (*s == 'b')
base = 2;
if (longlong)
llbtoa(d, va_arg (ap, quad_t),
base);
else
btoa(d, va_arg (ap, int), base);
#ifndef EPSILON if (*s == 'X')
#define EPSILON ((double)(0.00000001)) strtoupper(d);
}
#ifdef FLOATINGPT
else if (strchr ("eEfgG", *s)) {
//static void dtoa (char *, double, int, int, int);
void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec);
dbl = va_arg(ap, double);
dtoa(d, dbl, *s, width, trunc);
trunc = 0;
}
#endif #endif
if (fpart < EPSILON) }
{ if (trunc)
// fpart is zero d[trunc] = 0;
if (width)
str_fmt (d, width, fmt);
for (; *d; d++);
s++;
} else
*d++ = *s++;
} }
else *d = 0;
{ return (d - dst);
bf += len; }
// add dot
*bf ++ = '.'; #ifdef FLOATINGPT
len += 1; /*
// add zero after dot * Floating point output, cvt() onward lifted from BSD sources:
while (fpart < 0.1) *
{ * Copyright (c) 1990 The Regents of the University of California.
fpart *= 10; * All rights reserved.
*bf ++ = '0'; *
len += 1; * This code is derived from software contributed to Berkeley by
} * Chris Torek.
while ((fpart < (double)1.0 / EPSILON) && ((fpart - (int)fpart) > EPSILON)) *
{ * Redistribution and use in source and binary forms, with or without
fpart = fpart * 10; * modification, are permitted provided that the following conditions
} * are met:
#ifdef PRINTF_LONG_SUPPORT * 1. Redistributions of source code must retain the above copyright
len += li2a((int)fpart, bf); * notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*/
#define MAX_FCONVERSION 512 /* largest possible real conversion */
#define MAX_EXPT 5 /* largest possible exponent field */
#define MAX_FRACT 39 /* largest possible fraction field */
#define TESTFLAG(x) 0
typedef double rtype;
extern double modf(double, double *);
#define to_char(n) ((n) + '0')
#define to_digit(c) ((c) - '0')
#define _isNan(arg) ((arg) != (arg))
static int cvt (rtype arg, int prec, char *signp, int fmtch,
char *startp, char *endp);
static char *c_round (double fract, int *exp, char *start, char *end,
char ch, char *signp);
static char *exponent(char *p, int exp, int fmtch);
/*
* _finite arg not Infinity or Nan
*/
static int _finite(rtype d)
{
#if ENDIAN == ENDIAN_LITTLE
struct IEEEdp {
unsigned manl:32;
unsigned manh:20;
unsigned exp:11;
unsigned sign:1;
} *ip;
#else #else
len += i2a((int)fpart, bf); struct IEEEdp {
unsigned sign:1;
unsigned exp:11;
unsigned manh:20;
unsigned manl:32;
} *ip;
#endif #endif
}
#undef EPSILON
if (num < 0)
{
len ++;
}
return len;
}
static int a2d(char ch) ip = (struct IEEEdp *)&d;
{ return (ip->exp != 0x7ff);
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)
void dtoa (char *dbuf, rtype arg, int fmtch, int width, int prec)
{ {
char *p = *src; char buf[MAX_FCONVERSION+1], *cp;
int num = 0; char sign;
int digit; int size;
while ((digit = a2d(ch)) >= 0)
{ if( !_finite(arg) ) {
if (digit > base) break; if( _isNan(arg) )
num = num * base + digit; strcpy (dbuf, "NaN");
ch = *p++; else if( arg < 0)
strcpy (dbuf, "-Infinity");
else
strcpy (dbuf, "Infinity");
return;
} }
*src = p;
*nump = num;
return ch;
}
static void putchw(void *putp, putcf putf, int n, char z, char *bf) if (prec == 0)
{ prec = 6;
char fc = z ? '0' : ' '; else if (prec > MAX_FRACT)
char ch; prec = MAX_FRACT;
char *p = bf;
while (*p++ && n > 0) /* leave room for sign at start of buffer */
n--; cp = buf + 1;
while (n-- > 0)
putf(putp, fc); /*
while ((ch = *bf++)) * cvt may have to round up before the "start" of
putf(putp, ch); * its buffer, i.e. ``intf("%.2f", (double)9.999);'';
* if the first character is still NUL, it did.
* softsign avoids negative 0 if _double < 0 but
* no significant digits will be shown.
*/
*cp = '\0';
size = cvt (arg, prec, &sign, fmtch, cp, buf + sizeof(buf));
if (*cp == '\0')
cp++;
if (sign)
*--cp = sign, size++;
cp[size] = 0;
memcpy (dbuf, cp, size + 1);
} }
void c_format(void *putp, putcf putf, char *fmt, va_list va)
static int
cvt(rtype number, int prec, char *signp, int fmtch, char *startp, char *endp)
{ {
char bf[12]; register char *p, *t;
register double fract;
double integer, tmp;
int dotrim, expcnt, gformat;
dotrim = expcnt = gformat = 0;
if (number < 0) {
number = -number;
*signp = '-';
} else
*signp = 0;
char ch; fract = modf(number, &integer);
/* get an extra slot for rounding. */
t = ++startp;
while ((ch = *(fmt++))) /*
{ * get integer portion of number; put into the end of the buffer; the
if (ch != '%') * .01 is added for modf(356.0 / 10, &integer) returning .59999999...
putf(putp, ch); */
for (p = endp - 1; integer; ++expcnt) {
tmp = modf(integer / 10, &integer);
*p-- = to_char((int)((tmp + .01) * 10));
}
switch (fmtch) {
case 'f':
/* reverse integer into beginning of buffer */
if (expcnt)
for (; ++p < endp; *t++ = *p);
else else
{ *t++ = '0';
char lz = 0; /*
#ifdef PRINTF_LONG_SUPPORT * if precision required or alternate flag set, add in a
char lng = 0; * decimal point.
#endif */
int w = 0; if (prec || TESTFLAG(ALTERNATE_FORM))
ch = *(fmt++); *t++ = '.';
if (ch == '0') /* if requires more precision and some fraction left */
{ if (fract) {
ch = *(fmt++); if (prec)
lz = 1; do {
} fract = modf(fract * 10, &tmp);
if (ch >= '0' && ch <= '9') *t++ = to_char((int)tmp);
{ } while (--prec && fract);
ch = a2i(ch, &fmt, 10, &w); if (fract)
} startp = c_round(fract, (int *)NULL, startp,
#ifdef PRINTF_LONG_SUPPORT t - 1, (char)0, signp);
if (ch == 'l') }
{ for (; prec--; *t++ = '0');
ch = *(fmt++); break;
lng = 1; case 'e':
} case 'E':
#endif eformat: if (expcnt) {
switch (ch) *t++ = *++p;
{ if (prec || TESTFLAG(ALTERNATE_FORM))
case 0: *t++ = '.';
goto abort; /* if requires more precision and some integer left */
case 'u' : for (; prec && ++p < endp; --prec)
{ *t++ = *p;
#ifdef PRINTF_LONG_SUPPORT /*
if (lng) * if done precision and more of the integer component,
uli2a(va_arg(va, unsigned long int), 10, 0, bf); * round using it; adjust fract so we don't re-round
else * later.
#endif */
ui2a(va_arg(va, unsigned int), 10, 0, bf); if (!prec && ++p < endp) {
putchw(putp, putf, w, lz, bf); fract = 0;
break; startp = c_round((double)0, &expcnt, startp,
t - 1, *p, signp);
} }
case 'o' : /* adjust expcnt for digit in front of decimal */
{ --expcnt;
#ifdef PRINTF_LONG_SUPPORT }
if (lng) /* until first fractional digit, decrement exponent */
uli2a(va_arg(va, unsigned long int), 8, 0, bf); else if (fract) {
else /* adjust expcnt for digit in front of decimal */
#endif for (expcnt = -1;; --expcnt) {
ui2a(va_arg(va, unsigned int), 8, 0, bf); fract = modf(fract * 10, &tmp);
putchw(putp, putf, w, lz, bf); if (tmp)
break; break;
} }
case 'd' : case 'i': *t++ = to_char((int)tmp);
{ if (prec || TESTFLAG(ALTERNATE_FORM))
#ifdef PRINTF_LONG_SUPPORT *t++ = '.';
if (lng) }
li2a(va_arg(va, unsigned long int), bf); else {
else *t++ = '0';
#endif if (prec || TESTFLAG(ALTERNATE_FORM))
i2a(va_arg(va, int), bf); *t++ = '.';
putchw(putp, putf, w, lz, bf); }
break; /* if requires more precision and some fraction left */
if (fract) {
if (prec)
do {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
} while (--prec && fract);
if (fract)
startp = c_round(fract, &expcnt, startp,
t - 1, (char)0, signp);
}
/* if requires more precision */
for (; prec--; *t++ = '0');
/* unless alternate flag, trim any g/G format trailing 0's */
if (gformat && !TESTFLAG(ALTERNATE_FORM)) {
while (t > startp && *--t == '0');
if (*t == '.')
--t;
++t;
}
t = exponent(t, expcnt, fmtch);
break;
case 'g':
case 'G':
/* a precision of 0 is treated as a precision of 1. */
if (!prec)
++prec;
/*
* ``The style used depends on the value converted; style e
* will be used only if the exponent resulting from the
* conversion is less than -4 or greater than the precision.''
* -- ANSI X3J11
*/
if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
/*
* g/G format counts "significant digits, not digits of
* precision; for the e/E format, this just causes an
* off-by-one problem, i.e. g/G considers the digit
* before the decimal point significant and e/E doesn't
* count it as precision.
*/
--prec;
fmtch -= 2; /* G->E, g->e */
gformat = 1;
goto eformat;
}
/*
* reverse integer into beginning of buffer,
* note, decrement precision
*/
if (expcnt)
for (; ++p < endp; *t++ = *p, --prec);
else
*t++ = '0';
/*
* if precision required or alternate flag set, add in a
* decimal point. If no digits yet, add in leading 0.
*/
if (prec || TESTFLAG(ALTERNATE_FORM)) {
dotrim = 1;
*t++ = '.';
}
else
dotrim = 0;
/* if requires more precision and some fraction left */
if (fract) {
if (prec) {
do {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
} while(!tmp && !expcnt);
while (--prec && fract) {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
}
} }
case 'x': case 'X' : if (fract)
#ifdef PRINTF_LONG_SUPPORT startp = c_round(fract, (int *)NULL, startp,
if (lng) t - 1, (char)0, signp);
uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf); }
else /* alternate format, adds 0's for precision, else trim 0's */
#endif if (TESTFLAG(ALTERNATE_FORM))
ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf); for (; prec--; *t++ = '0');
putchw(putp, putf, w, lz, bf); else if (dotrim) {
while (t > startp && *--t == '0');
if (*t != '.')
++t;
}
}
return (t - startp);
}
static char *
c_round(double fract, int *exp, char *start, char *end, char ch, char *signp)
{
double tmp;
if (fract)
(void)modf(fract * 10, &tmp);
else
tmp = to_digit(ch);
if (tmp > 4)
for (;; --end) {
if (*end == '.')
--end;
if (++*end <= '9')
break; break;
case 'e': case 'E': case 'f': *end = '0';
case 'g': case 'G': if (end == start) {
{ if (exp) { /* e/E; increment exponent */
d2a(va_arg(va, double), bf); *end = '1';
putchw(putp, putf, w, lz, bf); ++*exp;
}
else { /* f; add extra digit */
*--end = '1';
--start;
}
break; break;
} }
case 'c' : }
putf(putp, (char)(va_arg(va, int))); /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
break; else if (*signp == '-')
case 's' : for (;; --end) {
putchw(putp, putf, w, 0, va_arg(va, char *)); if (*end == '.')
break; --end;
case '%' : if (*end != '0')
putf(putp, ch);
default:
break; break;
} if (end == start)
*signp = 0;
} }
} return (start);
abort:;
} }
static char *
static void putcp(void *p, char c) exponent(char *p, int exp, int fmtch)
{ {
*(*((char **)p))++ = c; char *t;
char expbuf[MAX_FCONVERSION];
*p++ = fmtch;
if (exp < 0) {
exp = -exp;
*p++ = '-';
}
else
*p++ = '+';
t = expbuf + MAX_FCONVERSION;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAX_FCONVERSION; *p++ = *t++);
}
else {
*p++ = '0';
*p++ = to_char(exp);
}
return (p);
} }
#endif /* FLOATINGPT */
void c_sprintf(char *s, char *fmt, ...) void c_sprintf(char *s, char *fmt, ...)
{ {
va_list va; va_list arg;
va_start(va, fmt); va_start(arg, fmt);
c_format(&s, putcp, fmt, va); vsprintf(s, fmt, arg);
putcp(&s, 0); va_end(arg);
va_end(va);
} }
#endif #endif
...@@ -3,68 +3,65 @@ ...@@ -3,68 +3,65 @@
#include "c_types.h" #include "c_types.h"
#include "c_string.h" #include "c_string.h"
#include "user_interface.h" #include "user_interface.h"
#include "user_config.h"
// const char *lua_init_value = "print(\"Hello world\")"; // const char *lua_init_value = "print(\"Hello world\")";
const char *lua_init_value = "@init.lua"; const char *lua_init_value = "@init.lua";
// int c_abs(int x){ // int c_abs(int x){
// return x>0?x:0-x; // return x>0?x:0-x;
// } // }
// void c_exit(int e){ // void c_exit(int e){
// } // }
const char *c_getenv(const char *__string){ const char *c_getenv(const char *__string)
if (c_strcmp(__string, "LUA_INIT") == 0){ {
return lua_init_value; if (c_strcmp(__string, "LUA_INIT") == 0)
} {
return NULL; return lua_init_value;
}
return NULL;
} }
// make sure there is enough memory before real malloc, otherwise malloc will panic and reset // make sure there is enough memory before real malloc, otherwise malloc will panic and reset
// void *c_malloc(size_t __size){ // void *c_malloc(size_t __size){
// if(__size>system_get_free_heap_size()){ // if(__size>system_get_free_heap_size()){
// NODE_ERR("malloc: not enough memory\n"); // NODE_ERR("malloc: not enough memory\n");
// return NULL; // return NULL;
// } // }
// return (void *)os_malloc(__size); // return (void *)os_malloc(__size);
// } // }
// void *c_zalloc(size_t __size){ // void *c_zalloc(size_t __size){
// if(__size>system_get_free_heap_size()){ // if(__size>system_get_free_heap_size()){
// NODE_ERR("zalloc: not enough memory\n"); // NODE_ERR("zalloc: not enough memory\n");
// return NULL; // return NULL;
// } // }
// return (void *)os_zalloc(__size); // return (void *)os_zalloc(__size);
// } // }
// void c_free(void *p){ // void c_free(void *p){
// // NODE_ERR("free1: %d\n", system_get_free_heap_size()); // // NODE_ERR("free1: %d\n", system_get_free_heap_size());
// os_free(p); // os_free(p);
// // NODE_ERR("-free1: %d\n", system_get_free_heap_size()); // // NODE_ERR("-free1: %d\n", system_get_free_heap_size());
// } // }
// int c_rand(void){ // int c_rand(void){
// } // }
// void c_srand(unsigned int __seed){ // void c_srand(unsigned int __seed){
// } // }
// int c_atoi(const char *__nptr){ // int c_atoi(const char *__nptr){
// } // }
#include <_ansi.h> #include <_ansi.h>
//#include <reent.h> //#include <reent.h>
#include <string.h> #include <string.h>
//#include "mprec.h" //#include "mprec.h"
double c_strtod(const char *string, char **endPtr) double powersOf10[] ICACHE_STORE_ATTR ICACHE_RODATA_ATTR = /* Table giving binary powers of 10. Entry */
{ {
int maxExponent = 511; /* Largest possible base 10 exponent. Any 10., /* is 10^2^i. Used to convert decimal */
* exponent larger than this will already 100., /* exponents into floating-point numbers. */
* 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.0e4,
1.0e8, 1.0e8,
1.0e16, 1.0e16,
...@@ -72,43 +69,57 @@ double c_strtod(const char *string, char **endPtr) ...@@ -72,43 +69,57 @@ double c_strtod(const char *string, char **endPtr)
1.0e64, 1.0e64,
1.0e128, 1.0e128,
1.0e256 1.0e256
}; };
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.
*/
int sign, expSign = FALSE; int sign, expSign = FALSE;
double fraction, dblExp, *d; double fraction, dblExp, *d;
register const char *p; register const char *p;
register int c; register int c;
int exp = 0; /* Exponent read from "EX" field. */ int exp = 0; /* Exponent read from "EX" field. */
int fracExp = 0; /* Exponent that derives from the fractional int fracExp = 0; /* Exponent that derives from the fractional
* part. Under normal circumstatnces, it is * part. Under normal circumstatnces, it is
* the negative of the number of digits in F. * the negative of the number of digits in F.
* However, if I is very long, the last digits * However, if I is very long, the last digits
* of I get dropped (otherwise a long I with a * of I get dropped (otherwise a long I with a
* large negative exponent could cause an * large negative exponent could cause an
* unnecessary overflow on I alone). In this * unnecessary overflow on I alone). In this
* case, fracExp is incremented one for each * case, fracExp is incremented one for each
* dropped digit. */ * dropped digit. */
int mantSize; /* Number of digits in mantissa. */ int mantSize; /* Number of digits in mantissa. */
int decPt; /* Number of mantissa digits BEFORE decimal int decPt; /* Number of mantissa digits BEFORE decimal
* point. */ * point. */
const char *pExp; /* Temporarily holds location of exponent const char *pExp; /* Temporarily holds location of exponent
* in string. */ * in string. */
/* /*
* Strip off leading blanks and check for a sign. * Strip off leading blanks and check for a sign.
*/ */
p = string; p = string;
while (isspace((unsigned char)(*p))) { while (isspace((unsigned char)(*p)))
p += 1; {
p += 1;
}
if (*p == '-')
{
sign = TRUE;
p += 1;
} }
if (*p == '-') { else
sign = TRUE; {
p += 1; if (*p == '+')
} else { {
if (*p == '+') { p += 1;
p += 1; }
} sign = FALSE;
sign = FALSE;
} }
/* /*
...@@ -119,14 +130,16 @@ double c_strtod(const char *string, char **endPtr) ...@@ -119,14 +130,16 @@ double c_strtod(const char *string, char **endPtr)
decPt = -1; decPt = -1;
for (mantSize = 0; ; mantSize += 1) for (mantSize = 0; ; mantSize += 1)
{ {
c = *p; c = *p;
if (!isdigit(c)) { if (!isdigit(c))
if ((c != '.') || (decPt >= 0)) { {
break; if ((c != '.') || (decPt >= 0))
} {
decPt = mantSize; break;
} }
p += 1; decPt = mantSize;
}
p += 1;
} }
/* /*
...@@ -135,49 +148,60 @@ double c_strtod(const char *string, char **endPtr) ...@@ -135,49 +148,60 @@ double c_strtod(const char *string, char **endPtr)
* If the mantissa has more than 18 digits, ignore the extras, since * If the mantissa has more than 18 digits, ignore the extras, since
* they can't affect the value anyway. * they can't affect the value anyway.
*/ */
pExp = p; pExp = p;
p -= mantSize; p -= mantSize;
if (decPt < 0) { if (decPt < 0)
decPt = mantSize; {
} else { decPt = mantSize;
mantSize -= 1; /* One of the digits was the point. */
} }
if (mantSize > 18) { else
fracExp = decPt - 18; {
mantSize = 18; mantSize -= 1; /* One of the digits was the point. */
} else {
fracExp = decPt - mantSize;
} }
if (mantSize == 0) { if (mantSize > 18)
fraction = 0.0; {
p = string; fracExp = decPt - 18;
goto done; mantSize = 18;
} else { }
int frac1, frac2; else
frac1 = 0; {
for ( ; mantSize > 9; mantSize -= 1) fracExp = decPt - mantSize;
{ }
c = *p; if (mantSize == 0)
p += 1; {
if (c == '.') { fraction = 0.0;
c = *p; p = string;
p += 1; goto done;
} }
frac1 = 10*frac1 + (c - '0'); else
} {
frac2 = 0; int frac1, frac2;
for (; mantSize > 0; mantSize -= 1) frac1 = 0;
{ for ( ; mantSize > 9; mantSize -= 1)
c = *p; {
p += 1; c = *p;
if (c == '.') { p += 1;
c = *p; if (c == '.')
p += 1; {
} c = *p;
frac2 = 10*frac2 + (c - '0'); p += 1;
} }
fraction = (1.0e9 * frac1) + frac2; 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;
} }
/* /*
...@@ -185,30 +209,40 @@ double c_strtod(const char *string, char **endPtr) ...@@ -185,30 +209,40 @@ double c_strtod(const char *string, char **endPtr)
*/ */
p = pExp; p = pExp;
if ((*p == 'E') || (*p == 'e')) { if ((*p == 'E') || (*p == 'e'))
p += 1; {
if (*p == '-') { p += 1;
expSign = TRUE; if (*p == '-')
p += 1; {
} else { expSign = TRUE;
if (*p == '+') { p += 1;
p += 1; }
} else
expSign = FALSE; {
} if (*p == '+')
if (!isdigit((unsigned char)(*p))) { {
p = pExp; p += 1;
goto done; }
} expSign = FALSE;
while (isdigit((unsigned char)(*p))) { }
exp = exp * 10 + (*p - '0'); if (!isdigit((unsigned char)(*p)))
p += 1; {
} p = pExp;
goto done;
}
while (isdigit((unsigned char)(*p)))
{
exp = exp * 10 + (*p - '0');
p += 1;
}
} }
if (expSign) { if (expSign)
exp = fracExp - exp; {
} else { exp = fracExp - exp;
exp = fracExp + exp; }
else
{
exp = fracExp + exp;
} }
/* /*
...@@ -217,41 +251,52 @@ double c_strtod(const char *string, char **endPtr) ...@@ -217,41 +251,52 @@ double c_strtod(const char *string, char **endPtr)
* many powers of 2 of 10. Then combine the exponent with the * many powers of 2 of 10. Then combine the exponent with the
* fraction. * fraction.
*/ */
if (exp < 0) { if (exp < 0)
expSign = TRUE; {
exp = -exp; expSign = TRUE;
} else { exp = -exp;
expSign = FALSE;
} }
if (exp > maxExponent) { else
exp = maxExponent; {
// errno = ERANGE; expSign = FALSE;
}
if (exp > maxExponent)
{
exp = maxExponent;
// errno = ERANGE;
} }
dblExp = 1.0; dblExp = 1.0;
for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { for (d = powersOf10; exp != 0; exp >>= 1, d += 1)
if (exp & 01) { {
dblExp *= *d; if (exp & 01)
} {
dblExp *= *d;
}
}
if (expSign)
{
fraction /= dblExp;
} }
if (expSign) { else
fraction /= dblExp; {
} else { fraction *= dblExp;
fraction *= dblExp;
} }
done: done:
if (endPtr != NULL) { if (endPtr != NULL)
*endPtr = (char *) p; {
*endPtr = (char *) p;
} }
if (sign) { if (sign)
return -fraction; {
return -fraction;
} }
return fraction; return fraction;
} }
// long c_strtol(const char *__n, char **__end_PTR, int __base){ // long c_strtol(const char *__n, char **__end_PTR, int __base){
// } // }
// unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base){ // unsigned long c_strtoul(const char *__n, char **__end_PTR, int __base){
// } // }
......
...@@ -652,7 +652,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { ...@@ -652,7 +652,8 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
typedef struct LoadFSF { typedef struct LoadFSF {
int extraline; int extraline;
int f; int f;
char buff[LUAL_BUFFERSIZE]; char *buff;
int len;
} LoadFSF; } LoadFSF;
...@@ -665,7 +666,7 @@ static const char *getFSF (lua_State *L, void *ud, size_t *size) { ...@@ -665,7 +666,7 @@ static const char *getFSF (lua_State *L, void *ud, size_t *size) {
return "\n"; return "\n";
} }
if (fs_eof(lf->f)) return NULL; if (fs_eof(lf->f)) return NULL;
*size = fs_read(lf->f, lf->buff, sizeof(lf->buff)); *size = fs_read(lf->f, lf->buff, (lf->len));
return (*size > 0) ? lf->buff : NULL; return (*size > 0) ? lf->buff : NULL;
} }
...@@ -684,6 +685,9 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) { ...@@ -684,6 +685,9 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
int c; int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0; lf.extraline = 0;
// lf.len = LUAL_BUFFERSIZE;
lf.len = 0;
lf.buff = NULL;
if (filename == NULL) { if (filename == NULL) {
return luaL_error(L, "filename is NULL"); return luaL_error(L, "filename is NULL");
} }
...@@ -692,6 +696,10 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) { ...@@ -692,6 +696,10 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
lf.f = fs_open(filename, FS_RDONLY); lf.f = fs_open(filename, FS_RDONLY);
if (lf.f < FS_OPEN_OK) return errfsfile(L, "open", fnameindex); if (lf.f < FS_OPEN_OK) return errfsfile(L, "open", fnameindex);
} }
lf.len = fs_size(lf.f) + 32;
lf.buff = c_zalloc(lf.len);
if(!lf.buff) return LUA_ERRMEM;
c = fs_getc(lf.f); c = fs_getc(lf.f);
if (c == '#') { /* Unix exec. file? */ if (c == '#') { /* Unix exec. file? */
lf.extraline = 1; lf.extraline = 1;
...@@ -701,7 +709,13 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) { ...@@ -701,7 +709,13 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
fs_close(lf.f); fs_close(lf.f);
lf.f = fs_open(filename, FS_RDONLY); /* reopen in binary mode */ lf.f = fs_open(filename, FS_RDONLY); /* reopen in binary mode */
if (lf.f < FS_OPEN_OK) return errfsfile(L, "reopen", fnameindex); if (lf.f < FS_OPEN_OK){
if(lf.buff)
c_free(lf.buff);
lf.buff = NULL;
lf.len = 0;
return errfsfile(L, "reopen", fnameindex);
}
/* skip eventual `#!...' */ /* skip eventual `#!...' */
while ((c = fs_getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ; while ((c = fs_getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
lf.extraline = 0; lf.extraline = 0;
...@@ -711,6 +725,9 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) { ...@@ -711,6 +725,9 @@ LUALIB_API int luaL_loadfsfile (lua_State *L, const char *filename) {
if (filename) fs_close(lf.f); /* close file (even in case of errors) */ if (filename) fs_close(lf.f); /* close file (even in case of errors) */
lua_remove(L, fnameindex); lua_remove(L, fnameindex);
if(lf.buff)
c_free(lf.buff);
lf.buff = NULL;
return status; return status;
} }
......
...@@ -30,10 +30,13 @@ lua_Load gLoad; ...@@ -30,10 +30,13 @@ lua_Load gLoad;
static const char *progname = LUA_PROGNAME; static const char *progname = LUA_PROGNAME;
#ifdef DEVKIT_VERSION_0_9
static int key_press_count = 0; static int key_press_count = 0;
int led_high_count = LED_HIGH_COUNT_DEFAULT; int led_high_count = LED_HIGH_COUNT_DEFAULT;
int led_low_count = LED_LOW_COUNT_DEFAULT; int led_low_count = LED_LOW_COUNT_DEFAULT;
static int led_count = 0; static int led_count = 0;
#endif
#if 0 #if 0
static void lstop (lua_State *L, lua_Debug *ar) { static void lstop (lua_State *L, lua_Debug *ar) {
(void)ar; /* unused arg. */ (void)ar; /* unused arg. */
...@@ -541,6 +544,7 @@ void dojob(lua_Load *load){ ...@@ -541,6 +544,7 @@ void dojob(lua_Load *load){
// NODE_DBG("dojob() is called with firstline.\n"); // NODE_DBG("dojob() is called with firstline.\n");
} }
#ifdef DEVKIT_VERSION_0_9
extern void key_long_press(void *arg); extern void key_long_press(void *arg);
extern void key_short_press(void *arg); extern void key_short_press(void *arg);
static bool key_short_pressed = false; static bool key_short_pressed = false;
...@@ -579,6 +583,7 @@ void update_key_led(){ ...@@ -579,6 +583,7 @@ void update_key_led(){
} }
} }
} }
#endif
#ifndef uart_putc #ifndef uart_putc
#define uart_putc uart0_putc #define uart_putc uart0_putc
...@@ -590,7 +595,9 @@ extern uint16_t need_len; ...@@ -590,7 +595,9 @@ extern uint16_t need_len;
extern int16_t end_char; extern int16_t end_char;
void readline(lua_Load *load){ void readline(lua_Load *load){
// NODE_DBG("readline() is called.\n"); // NODE_DBG("readline() is called.\n");
#ifdef DEVKIT_VERSION_0_9
update_key_led(); update_key_led();
#endif
char ch; char ch;
while (uart_getc(&ch)) while (uart_getc(&ch))
{ {
......
...@@ -108,7 +108,7 @@ ...@@ -108,7 +108,7 @@
#define LUA_CDIR LUA_ROOT "lib/lua/5.1/" #define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
#ifndef LUA_RPC #ifndef LUA_RPC
#define LUA_PATH_DEFAULT "?.lua;?.lc" #define LUA_PATH_DEFAULT "?.lc;?.lua"
#define LUA_CPATH_DEFAULT "" #define LUA_CPATH_DEFAULT ""
#else // #ifndef LUA_RPC #else // #ifndef LUA_RPC
#define LUA_PATH_DEFAULT \ #define LUA_PATH_DEFAULT \
...@@ -601,8 +601,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length); ...@@ -601,8 +601,7 @@ extern int readline4lua(const char *prompt, char *buffer, int length);
#endif // #if !defined LUA_INTEGRAL_LONGLONG #endif // #if !defined LUA_INTEGRAL_LONGLONG
#else #else
#define LUA_NUMBER_SCAN "%lf" #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 #endif // #if defined LUA_NUMBER_INTEGRAL
#define lua_number2str(s,n) c_sprintf((s), LUA_NUMBER_FMT, (n)) #define lua_number2str(s,n) c_sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ #define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
......
...@@ -125,7 +125,7 @@ static int file_remove( lua_State* L ) ...@@ -125,7 +125,7 @@ static int file_remove( lua_State* L )
if( len > FS_NAME_MAX_LENGTH ) if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long"); return luaL_error(L, "filename too long");
file_close(L); file_close(L);
SPIFFS_remove(&fs, fname); SPIFFS_remove(&fs, (char *)fname);
return 0; return 0;
} }
...@@ -150,6 +150,31 @@ static int file_check( lua_State* L ) ...@@ -150,6 +150,31 @@ static int file_check( lua_State* L )
} }
#endif #endif
// Lua: rename("oldname", "newname")
static int file_rename( lua_State* L )
{
size_t len;
if((FS_OPEN_OK - 1)!=file_fd){
fs_close(file_fd);
file_fd = FS_OPEN_OK - 1;
}
const char *oldname = luaL_checklstring( L, 1, &len );
if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long");
const char *newname = luaL_checklstring( L, 2, &len );
if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long");
if(SPIFFS_OK==myspiffs_rename( oldname, newname )){
lua_pushboolean(L, 1);
} else {
lua_pushboolean(L, 0);
}
return 1;
}
#endif #endif
// g_read() // g_read()
...@@ -282,6 +307,7 @@ const LUA_REG_TYPE file_map[] = ...@@ -282,6 +307,7 @@ const LUA_REG_TYPE file_map[] =
{ LSTRKEY( "seek" ), LFUNCVAL( file_seek ) }, { LSTRKEY( "seek" ), LFUNCVAL( file_seek ) },
{ LSTRKEY( "flush" ), LFUNCVAL( file_flush ) }, { LSTRKEY( "flush" ), LFUNCVAL( file_flush ) },
// { LSTRKEY( "check" ), LFUNCVAL( file_check ) }, // { LSTRKEY( "check" ), LFUNCVAL( file_check ) },
{ LSTRKEY( "rename" ), LFUNCVAL( file_rename ) },
#endif #endif
#if LUA_OPTIMIZE_MEMORY > 0 #if LUA_OPTIMIZE_MEMORY > 0
......
...@@ -1241,6 +1241,31 @@ static int net_socket_unhold( lua_State* L ) ...@@ -1241,6 +1241,31 @@ static int net_socket_unhold( lua_State* L )
return 0; return 0;
} }
// Lua: ip,port = sk:getpeer()
static int net_socket_getpeer( lua_State* L )
{
lnet_userdata *nud;
const char *mt = "net.socket";
nud = (lnet_userdata *)luaL_checkudata(L, 1, mt);
luaL_argcheck(L, nud, 1, "Server/Socket expected");
if(nud!=NULL && nud->pesp_conn!=NULL ){
char temp[20] = {0};
c_sprintf(temp, IPSTR, IP2STR( &(nud->pesp_conn->proto.tcp->remote_ip) ) );
if ( nud->pesp_conn->proto.tcp->remote_port != 0 ) {
lua_pushstring( L, temp );
lua_pushinteger( L, nud->pesp_conn->proto.tcp->remote_port );
} else {
lua_pushnil( L );
lua_pushnil( L );
}
} else {
lua_pushnil( L );
lua_pushnil( L );
}
return 2;
}
// Lua: socket:dns( string, function(ip) ) // Lua: socket:dns( string, function(ip) )
static int net_socket_dns( lua_State* L ) static int net_socket_dns( lua_State* L )
{ {
...@@ -1302,6 +1327,7 @@ static const LUA_REG_TYPE net_socket_map[] = ...@@ -1302,6 +1327,7 @@ static const LUA_REG_TYPE net_socket_map[] =
{ LSTRKEY( "hold" ), LFUNCVAL ( net_socket_hold ) }, { LSTRKEY( "hold" ), LFUNCVAL ( net_socket_hold ) },
{ LSTRKEY( "unhold" ), LFUNCVAL ( net_socket_unhold ) }, { LSTRKEY( "unhold" ), LFUNCVAL ( net_socket_unhold ) },
{ LSTRKEY( "dns" ), LFUNCVAL ( net_socket_dns ) }, { LSTRKEY( "dns" ), LFUNCVAL ( net_socket_dns ) },
{ LSTRKEY( "getpeer" ), LFUNCVAL ( net_socket_getpeer ) },
// { LSTRKEY( "delete" ), LFUNCVAL ( net_socket_delete ) }, // { LSTRKEY( "delete" ), LFUNCVAL ( net_socket_delete ) },
{ LSTRKEY( "__gc" ), LFUNCVAL ( net_socket_delete ) }, { LSTRKEY( "__gc" ), LFUNCVAL ( net_socket_delete ) },
#if LUA_OPTIMIZE_MEMORY > 0 #if LUA_OPTIMIZE_MEMORY > 0
......
// Module for interfacing with system // Module for interfacing with system
//#include "lua.h" #include "lua.h"
#include "lualib.h"
#include "lauxlib.h" #include "lauxlib.h"
#include "ldo.h"
#include "lfunc.h"
#include "lmem.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lstring.h"
#include "lundump.h"
#include "platform.h" #include "platform.h"
#include "auxmods.h" #include "auxmods.h"
#include "lrotable.h" #include "lrotable.h"
...@@ -14,6 +22,7 @@ ...@@ -14,6 +22,7 @@
//#include "spi_flash.h" //#include "spi_flash.h"
#include "user_interface.h" #include "user_interface.h"
#include "flash_api.h" #include "flash_api.h"
#include "flash_fs.h"
// Lua: restart() // Lua: restart()
static int node_restart( lua_State* L ) static int node_restart( lua_State* L )
...@@ -124,6 +133,9 @@ static int node_heap( lua_State* L ) ...@@ -124,6 +133,9 @@ static int node_heap( lua_State* L )
return 1; return 1;
} }
static lua_State *gL = NULL;
#ifdef DEVKIT_VERSION_0_9
extern int led_high_count; // this is defined in lua.c extern int led_high_count; // this is defined in lua.c
extern int led_low_count; extern int led_low_count;
// Lua: led(low, high) // Lua: led(low, high)
...@@ -155,7 +167,6 @@ static int node_led( lua_State* L ) ...@@ -155,7 +167,6 @@ static int node_led( lua_State* L )
static int long_key_ref = LUA_NOREF; static int long_key_ref = LUA_NOREF;
static int short_key_ref = LUA_NOREF; static int short_key_ref = LUA_NOREF;
static lua_State *gL = NULL;
void default_long_press(void *arg){ void default_long_press(void *arg){
if(led_high_count == 12 && led_low_count == 12){ if(led_high_count == 12 && led_low_count == 12){
...@@ -228,6 +239,7 @@ static int node_key( lua_State* L ) ...@@ -228,6 +239,7 @@ static int node_key( lua_State* L )
return 0; return 0;
} }
#endif
extern lua_Load gLoad; extern lua_Load gLoad;
extern os_timer_t lua_timer; extern os_timer_t lua_timer;
...@@ -308,6 +320,73 @@ static int node_output( lua_State* L ) ...@@ -308,6 +320,73 @@ static int node_output( lua_State* L )
return 0; return 0;
} }
static int writer(lua_State* L, const void* p, size_t size, void* u)
{
UNUSED(L);
int file_fd = *( (int *)u );
if((FS_OPEN_OK - 1)==file_fd)
return 1;
NODE_DBG("get fd:%d,size:%d\n",file_fd,size);
if(size!=0 && (size!=fs_write(file_fd, (const char *)p, size)) )
return 1;
NODE_DBG("write fd:%d,size:%d\n",file_fd,size);
return 0;
}
#define toproto(L,i) (clvalue(L->top+(i))->l.p)
// Lua: compile(filename) -- compile lua file into lua bytecode, and save to .lc
static int node_compile( lua_State* L )
{
Proto* f;
int file_fd = FS_OPEN_OK - 1;
size_t len;
const char *fname = luaL_checklstring( L, 1, &len );
if( len > FS_NAME_MAX_LENGTH )
return luaL_error(L, "filename too long");
char output[FS_NAME_MAX_LENGTH];
c_strcpy(output, fname);
// check here that filename end with ".lua".
if(len<4 || (c_strcmp( output+len-4,".lua")!=0) )
return luaL_error(L, "not a .lua file");
output[c_strlen(output)-2] = 'c';
output[c_strlen(output)-1] = '\0';
NODE_DBG(output);
NODE_DBG("\n");
if (luaL_loadfsfile(L,fname)!=0){
return luaL_error(L, lua_tostring(L,-1));
}
f = toproto(L,-1);
int stripping = 1; /* strip debug information? */
file_fd = fs_open(output, fs_mode2flag("w+"));
if(file_fd < FS_OPEN_OK)
{
return luaL_error(L, "cannot open/write to file");
}
lua_lock(L);
int result=luaU_dump(L,f,writer,&file_fd,stripping);
lua_unlock(L);
fs_flush(file_fd);
fs_close(file_fd);
file_fd = FS_OPEN_OK - 1;
if (result==LUA_ERR_CC_INTOVERFLOW){
return luaL_error(L, "value too big or small for target integer type");
}
if (result==LUA_ERR_CC_NOTINTEGER){
return luaL_error(L, "target lua_Number is integral but fractional value found");
}
return 0;
}
// Module function map // Module function map
#define MIN_OPT_LEVEL 2 #define MIN_OPT_LEVEL 2
#include "lrodefs.h" #include "lrodefs.h"
...@@ -320,11 +399,14 @@ const LUA_REG_TYPE node_map[] = ...@@ -320,11 +399,14 @@ const LUA_REG_TYPE node_map[] =
{ LSTRKEY( "flashid" ), LFUNCVAL( node_flashid ) }, { LSTRKEY( "flashid" ), LFUNCVAL( node_flashid ) },
{ LSTRKEY( "flashsize" ), LFUNCVAL( node_flashsize) }, { LSTRKEY( "flashsize" ), LFUNCVAL( node_flashsize) },
{ LSTRKEY( "heap" ), LFUNCVAL( node_heap ) }, { LSTRKEY( "heap" ), LFUNCVAL( node_heap ) },
#ifdef DEVKIT_VERSION_0_9
{ LSTRKEY( "key" ), LFUNCVAL( node_key ) }, { LSTRKEY( "key" ), LFUNCVAL( node_key ) },
{ LSTRKEY( "led" ), LFUNCVAL( node_led ) }, { LSTRKEY( "led" ), LFUNCVAL( node_led ) },
#endif
{ LSTRKEY( "input" ), LFUNCVAL( node_input ) }, { LSTRKEY( "input" ), LFUNCVAL( node_input ) },
{ LSTRKEY( "output" ), LFUNCVAL( node_output ) }, { LSTRKEY( "output" ), LFUNCVAL( node_output ) },
{ LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) }, { LSTRKEY( "readvdd33" ), LFUNCVAL( node_readvdd33) },
{ LSTRKEY( "compile" ), LFUNCVAL( node_compile) },
// Combined to dsleep(us, option) // Combined to dsleep(us, option)
// { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) }, // { LSTRKEY( "dsleepsetoption" ), LFUNCVAL( node_deepsleep_setoption) },
#if LUA_OPTIMIZE_MEMORY > 0 #if LUA_OPTIMIZE_MEMORY > 0
......
...@@ -256,8 +256,19 @@ static int wifi_setip( lua_State* L, uint8_t mode ) ...@@ -256,8 +256,19 @@ static int wifi_setip( lua_State* L, uint8_t mode )
ip = parse_key(L, "gateway"); ip = parse_key(L, "gateway");
if(ip!=0) if(ip!=0)
pTempIp.gw.addr = ip; pTempIp.gw.addr = ip;
wifi_station_dhcpc_stop();
lua_pushboolean(L,wifi_set_ip_info(mode, &pTempIp)); if(STATION_IF == mode)
{
wifi_station_dhcpc_stop();
lua_pushboolean(L,wifi_set_ip_info(mode, &pTempIp));
}
else
{
wifi_softap_dhcps_stop();
lua_pushboolean(L,wifi_set_ip_info(mode, &pTempIp));
wifi_softap_dhcps_start();
}
return 1; return 1;
} }
......
...@@ -25,6 +25,10 @@ ...@@ -25,6 +25,10 @@
#define FLASH_SEC_NUM 0x200 #define FLASH_SEC_NUM 0x200
#elif defined(FLASH_4M) #elif defined(FLASH_4M)
#define FLASH_SEC_NUM 0x400 #define FLASH_SEC_NUM 0x400
#elif defined(FLASH_8M)
#define FLASH_SEC_NUM 0x800
#elif defined(FLASH_16M)
#define FLASH_SEC_NUM 0x1000
#elif defined(FLASH_AUTOSIZE) #elif defined(FLASH_AUTOSIZE)
#define FLASH_SEC_NUM (flash_get_sec_num()) #define FLASH_SEC_NUM (flash_get_sec_num())
#else #else
......
...@@ -56,6 +56,12 @@ uint32_t flash_get_size_byte(void) ...@@ -56,6 +56,12 @@ uint32_t flash_get_size_byte(void)
case SIZE_32MBIT: case SIZE_32MBIT:
// 32Mbit, 4MByte // 32Mbit, 4MByte
flash_size = 4 * 1024 * 1024; flash_size = 4 * 1024 * 1024;
case SIZE_64MBIT:
// 64Mbit, 8MByte
flash_size = 8 * 1024 * 1024;
case SIZE_128MBIT:
// 128Mbit, 16MByte
flash_size = 16 * 1024 * 1024;
break; break;
default: default:
// Unknown flash size, fall back mode. // Unknown flash size, fall back mode.
......
...@@ -52,6 +52,8 @@ typedef struct ...@@ -52,6 +52,8 @@ typedef struct
SIZE_8MBIT = 2, SIZE_8MBIT = 2,
SIZE_16MBIT = 3, SIZE_16MBIT = 3,
SIZE_32MBIT = 4, SIZE_32MBIT = 4,
SIZE_64MBIT = 5,
SIZE_128MBIT = 6,
} size : 4; } size : 4;
} ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo; } ICACHE_STORE_TYPEDEF_ATTR SPIFlashInfo;
......
...@@ -68,6 +68,8 @@ ...@@ -68,6 +68,8 @@
#define fs_format myspiffs_format #define fs_format myspiffs_format
#define fs_check myspiffs_check #define fs_check myspiffs_check
#define fs_rename myspiffs_rename
#define fs_size myspiffs_size
#define FS_NAME_MAX_LENGTH SPIFFS_OBJ_NAME_LEN #define FS_NAME_MAX_LENGTH SPIFFS_OBJ_NAME_LEN
......
...@@ -185,6 +185,8 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari ...@@ -185,6 +185,8 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari
{ {
switch( baud ) switch( baud )
{ {
case BIT_RATE_300:
case BIT_RATE_600:
case BIT_RATE_1200: case BIT_RATE_1200:
case BIT_RATE_2400: case BIT_RATE_2400:
case BIT_RATE_4800: case BIT_RATE_4800:
...@@ -195,8 +197,11 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari ...@@ -195,8 +197,11 @@ uint32_t platform_uart_setup( unsigned id, uint32_t baud, int databits, int pari
case BIT_RATE_74880: case BIT_RATE_74880:
case BIT_RATE_115200: case BIT_RATE_115200:
case BIT_RATE_230400: case BIT_RATE_230400:
case BIT_RATE_256000:
case BIT_RATE_460800: case BIT_RATE_460800:
case BIT_RATE_921600: case BIT_RATE_921600:
case BIT_RATE_1843200:
case BIT_RATE_3686400:
UartDev.baut_rate = baud; UartDev.baut_rate = baud;
break; break;
default: default:
......
The MIT License (MIT)
Copyright (c) 2013-2015 Peter Andersson (pelleplutt1976<at>gmail.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
...@@ -40,7 +40,7 @@ Also, toss up some of the needed buffers: ...@@ -40,7 +40,7 @@ Also, toss up some of the needed buffers:
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2]; static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
static u8_t spiffs_fds[32*4]; static u8_t spiffs_fds[32*4];
static u8_t spiffs_cache[(LOG_PAGE_SIZE+32)*4]; static u8_t spiffs_cache_buf[(LOG_PAGE_SIZE+32)*4];
Now, write the my_spiffs_mount function: Now, write the my_spiffs_mount function:
...@@ -50,7 +50,7 @@ Now, write the my_spiffs_mount function: ...@@ -50,7 +50,7 @@ Now, write the my_spiffs_mount function:
cfg.phys_addr = 0; // start spiffs at start of spi flash cfg.phys_addr = 0; // start spiffs at start of spi flash
cfg.phys_erase_block = 65536; // according to datasheet cfg.phys_erase_block = 65536; // according to datasheet
cfg.log_block_size = 65536; // let us not complicate things cfg.log_block_size = 65536; // let us not complicate things
cfg.log_block_size = LOG_PAGE_SIZE; // as we said cfg.log_page_size = LOG_PAGE_SIZE; // as we said
cfg.hal_read_f = my_spi_read; cfg.hal_read_f = my_spi_read;
cfg.hal_write_f = my_spi_write; cfg.hal_write_f = my_spi_write;
...@@ -61,8 +61,8 @@ Now, write the my_spiffs_mount function: ...@@ -61,8 +61,8 @@ Now, write the my_spiffs_mount function:
spiffs_work_buf, spiffs_work_buf,
spiffs_fds, spiffs_fds,
sizeof(spiffs_fds), sizeof(spiffs_fds),
spiffs_cache, spiffs_cache_buf,
sizeof(spiffs_cache), sizeof(spiffs_cache_buf),
0); 0);
printf("mount res: %i\n", res); printf("mount res: %i\n", res);
} }
...@@ -127,6 +127,29 @@ Compile, run, cross fingers hard, and you'll get the output: ...@@ -127,6 +127,29 @@ Compile, run, cross fingers hard, and you'll get the output:
Got errors? Check spiffs.h for error definitions to get a clue what went voodoo. Got errors? Check spiffs.h for error definitions to get a clue what went voodoo.
* THINGS TO CHECK
When you alter the spiffs_config values, make sure you also check the typedefs
in spiffs_config.h:
- spiffs_block_ix
- spiffs_page_ix
- spiffs_obj_id
- spiffs_span_ix
The sizes of these typedefs must not underflow, else spiffs might end up in
eternal loops. Each typedef is commented what check for.
Also, if you alter the code or just want to verify your configuration, you can
run
> make test
in the spiffs folder. This will run all testcases using the configuration in
default/spiffs_config.h and test/params_test.h. The tests are written for linux
but should run under cygwin also.
* INTEGRATING SPIFFS * INTEGRATING SPIFFS
In order to integrate spiffs to your embedded target, you will basically need: In order to integrate spiffs to your embedded target, you will basically need:
......
/*
* params_test.h
*
* Created on: May 26, 2013
* Author: petera
*/
#ifndef PARAMS_TEST_H_
#define PARAMS_TEST_H_
// // total emulated spi flash size
// #define PHYS_FLASH_SIZE (16*1024*1024)
// // spiffs file system size
// #define SPIFFS_FLASH_SIZE (2*1024*1024)
// // spiffs file system offset in emulated spi flash
// #define SPIFFS_PHYS_ADDR (4*1024*1024)
// #define SECTOR_SIZE 65536
// #define LOG_BLOCK (SECTOR_SIZE*2)
// #define LOG_PAGE (SECTOR_SIZE/256)
// #define FD_BUF_SIZE 64*6
// #define CACHE_BUF_SIZE (LOG_PAGE + 32)*8
// #define ASSERT(c, m) real_assert((c),(m), __FILE__, __LINE__);
typedef signed int s32_t;
typedef unsigned int u32_t;
typedef signed short s16_t;
typedef unsigned short u16_t;
typedef signed char s8_t;
typedef unsigned char u8_t;
void real_assert(int c, const char *n, const char *file, int l);
#endif /* PARAMS_TEST_H_ */
...@@ -98,7 +98,7 @@ int myspiffs_check( void ) ...@@ -98,7 +98,7 @@ int myspiffs_check( void )
} }
int myspiffs_open(const char *name, int flags){ int myspiffs_open(const char *name, int flags){
return (int)SPIFFS_open(&fs, name, (spiffs_flags)flags, 0); return (int)SPIFFS_open(&fs, (char *)name, (spiffs_flags)flags, 0);
} }
int myspiffs_close( int fd ){ int myspiffs_close( int fd ){
...@@ -162,6 +162,12 @@ int myspiffs_error( int fd ){ ...@@ -162,6 +162,12 @@ int myspiffs_error( int fd ){
void myspiffs_clearerr( int fd ){ void myspiffs_clearerr( int fd ){
fs.errno = SPIFFS_OK; fs.errno = SPIFFS_OK;
} }
int myspiffs_rename( const char *old, const char *newname ){
return SPIFFS_rename(&fs, (char *)old, (char *)newname);
}
size_t myspiffs_size( int fd ){
return SPIFFS_size(&fs, (spiffs_file)fd);
}
#if 0 #if 0
void test_spiffs() { void test_spiffs() {
char buf[12]; char buf[12];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment