1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-19 22:35:12 +03:00

#1471 - libio added to Lua. For tests, can be simplified and expanded

This commit is contained in:
bsongis 2015-03-16 20:10:16 +01:00
parent 7863bb23b9
commit 4e55213ae6
5 changed files with 114 additions and 52 deletions

View file

@ -937,7 +937,7 @@ ifeq ($(PCB), TARANIS)
CPPSRC += lua_api.cpp CPPSRC += lua_api.cpp
LUASRC = lua/src/lapi.c lua/src/lcode.c lua/src/lctype.c lua/src/ldebug.c lua/src/ldo.c lua/src/ldump.c lua/src/lfunc.c lua/src/lgc.c lua/src/llex.c lua/src/lmem.c \ LUASRC = lua/src/lapi.c lua/src/lcode.c lua/src/lctype.c lua/src/ldebug.c lua/src/ldo.c lua/src/ldump.c lua/src/lfunc.c lua/src/lgc.c lua/src/llex.c lua/src/lmem.c \
lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/lrotable.c lua/src/ltm.c lua/src/lundump.c lua/src/lvm.c lua/src/lzio.c \ lua/src/lobject.c lua/src/lopcodes.c lua/src/lparser.c lua/src/lstate.c lua/src/lstring.c lua/src/ltable.c lua/src/lrotable.c lua/src/ltm.c lua/src/lundump.c lua/src/lvm.c lua/src/lzio.c \
lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/lbitlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c lua/src/lbaselib.c lua/src/linit.c lua/src/lmathlib.c lua/src/lbitlib.c lua/src/loadlib.c lua/src/lauxlib.c lua/src/ltablib.c lua/src/lcorolib.c lua/src/liolib.c
SRC += $(LUASRC) SRC += $(LUASRC)
LUADEP = lua_exports.inc LUADEP = lua_exports.inc
ifeq ($(USE_BIN_ALLOCATOR), YES) ifeq ($(USE_BIN_ALLOCATOR), YES)

View file

@ -26,8 +26,10 @@ typedef struct luaL_Reg {
extern const luaL_Reg baselib[]; extern const luaL_Reg baselib[];
extern const luaL_Reg mathlib[]; extern const luaL_Reg mathlib[];
extern const luaL_Reg opentxLib[];
extern const luaL_Reg bitlib[]; extern const luaL_Reg bitlib[];
extern const luaL_Reg iolib[];
extern const luaL_Reg opentxLib[];
extern const luaL_Reg lcdLib[]; extern const luaL_Reg lcdLib[];
extern const luaL_Reg modelLib[]; extern const luaL_Reg modelLib[];
@ -191,14 +193,17 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
#define LUA_FILEHANDLE "FILE*" #define LUA_FILEHANDLE "FILE*"
#if defined(USE_FATFS)
#define FILE FIL
#endif
typedef struct luaL_Stream { typedef struct luaL_Stream {
#if defined(USE_FATFS) #if defined(USE_FATFS)
FIL *f; /* stream (NULL for incompletely created streams) */ FIL f;
#else #else
FILE *f; /* stream (NULL for incompletely created streams) */ FILE *f; /* stream (NULL for incompletely created streams) */
#endif
lua_CFunction closef; /* to close stream (NULL for closed streams) */ lua_CFunction closef; /* to close stream (NULL for closed streams) */
#endif
} luaL_Stream; } luaL_Stream;
/* }====================================================== */ /* }====================================================== */

View file

@ -31,7 +31,7 @@ static const luaL_Reg loadedlibs[] = {
// {LUA_LOADLIBNAME, luaopen_package}, // {LUA_LOADLIBNAME, luaopen_package},
// {LUA_COLIBNAME, luaopen_coroutine}, // {LUA_COLIBNAME, luaopen_coroutine},
// {LUA_TABLIBNAME, luaopen_table}, // {LUA_TABLIBNAME, luaopen_table},
// {LUA_IOLIBNAME, luaopen_io}, {LUA_IOLIBNAME, luaopen_io},
// {LUA_OSLIBNAME, luaopen_os}, // {LUA_OSLIBNAME, luaopen_os},
// {LUA_STRLIBNAME, luaopen_string}, // {LUA_STRLIBNAME, luaopen_string},
// {LUA_BITLIBNAME, luaopen_bit32}, // {LUA_BITLIBNAME, luaopen_bit32},
@ -45,6 +45,7 @@ const luaR_table lua_rotable[] =
{ {
{LUA_MATHLIBNAME, mathlib, mathlib_vals}, {LUA_MATHLIBNAME, mathlib, mathlib_vals},
{LUA_BITLIBNAME, bitlib, NULL}, {LUA_BITLIBNAME, bitlib, NULL},
{LUA_IOLIBNAME, iolib, NULL},
{"lcd", lcdLib, NULL}, {"lcd", lcdLib, NULL},
{"model", modelLib, NULL}, {"model", modelLib, NULL},
{"__baselib", baselib, NULL}, {"__baselib", baselib, NULL},

View file

@ -121,8 +121,9 @@ typedef luaL_Stream LStream;
#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) #define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE))
#define isclosed(p) ((p)->closef == NULL) #if !defined(USE_FATFS)
#define isclosed(p) ((p)->closef == NULL)
static int io_type (lua_State *L) { static int io_type (lua_State *L) {
LStream *p; LStream *p;
@ -147,13 +148,18 @@ static int f_tostring (lua_State *L) {
return 1; return 1;
} }
#endif
static FILE *tofile (lua_State *L) { static FILE *tofile (lua_State *L) {
LStream *p = tolstream(L); LStream *p = tolstream(L);
#if defined(USE_FATFS)
return &p->f;
#else
if (isclosed(p)) if (isclosed(p))
luaL_error(L, "attempt to use a closed file"); luaL_error(L, "attempt to use a closed file");
lua_assert(p->f); lua_assert(p->f);
return p->f; return p->f;
#endif
} }
@ -164,36 +170,48 @@ static FILE *tofile (lua_State *L) {
*/ */
static LStream *newprefile (lua_State *L) { static LStream *newprefile (lua_State *L) {
LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
#if !defined(USE_FATFS)
p->closef = NULL; /* mark file handle as 'closed' */ p->closef = NULL; /* mark file handle as 'closed' */
#endif
luaL_setmetatable(L, LUA_FILEHANDLE); luaL_setmetatable(L, LUA_FILEHANDLE);
return p; return p;
} }
#if !defined(USE_FATFS)
static int aux_close (lua_State *L) { static int aux_close (lua_State *L) {
#if !defined(USE_FATFS)
LStream *p = tolstream(L); LStream *p = tolstream(L);
lua_CFunction cf = p->closef; lua_CFunction cf = p->closef;
p->closef = NULL; /* mark stream as closed */ p->closef = NULL; /* mark stream as closed */
return (*cf)(L); /* close it */ return (*cf)(L); /* close it */
#else
return 0;
#endif
} }
#endif
static int io_close (lua_State *L) { static int io_close (lua_State *L) {
#if defined(USE_FATFS)
f_close(tofile(L));
return 0;
#else
if (lua_isnone(L, 1)) /* no argument? */ if (lua_isnone(L, 1)) /* no argument? */
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
tofile(L); /* make sure argument is an open stream */ tofile(L); /* make sure argument is an open stream */
return aux_close(L); return aux_close(L);
#endif
} }
#if !defined(USE_FATFS)
static int f_gc (lua_State *L) { static int f_gc (lua_State *L) {
#if !defined(USE_FATFS)
LStream *p = tolstream(L); LStream *p = tolstream(L);
if (!isclosed(p) && p->f != NULL) if (!isclosed(p) && p->f != NULL)
aux_close(L); /* ignore closed and incompletely open files */ aux_close(L); /* ignore closed and incompletely open files */
#endif
return 0; return 0;
} }
/* /*
** function to close regular files ** function to close regular files
*/ */
@ -202,34 +220,49 @@ static int io_fclose (lua_State *L) {
int res = fclose(p->f); int res = fclose(p->f);
return luaL_fileresult(L, (res == 0), NULL); return luaL_fileresult(L, (res == 0), NULL);
} }
#endif
static LStream *newfile (lua_State *L) { static LStream *newfile (lua_State *L) {
LStream *p = newprefile(L); LStream *p = newprefile(L);
#if !defined(USE_FATFS)
p->f = NULL; p->f = NULL;
p->closef = &io_fclose; p->closef = &io_fclose;
#endif
return p; return p;
} }
#if !defined(USE_FATFS)
static void opencheck (lua_State *L, const char *fname, const char *mode) { static void opencheck (lua_State *L, const char *fname, const char *mode) {
LStream *p = newfile(L); LStream *p = newfile(L);
p->f = fopen(fname, mode); p->f = fopen(fname, mode);
if (p->f == NULL) if (p->f == NULL)
luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
} }
#endif
static int io_open (lua_State *L) { static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r"); const char *md = luaL_optstring(L, 2, "r");
LStream *p = newfile(L); LStream *p = newfile(L);
const char *md = mode; /* to traverse/check mode */ #if defined(USE_FATFS)
luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); BYTE mode;
p->f = fopen(filename, mode); if (!md || *md == 'r')
mode = FA_READ;
else if (*md == 'w')
mode = FA_WRITE;
else
luaL_argerror(L, (2), ("invalid mode"));
FRESULT result = f_open(&p->f, filename, mode);
return result == FR_OK ? 1 : 0;
#else
const char *mode = md; /* to traverse/check mode */
luaL_argcheck(L, lua_checkmode(mode), 2, "invalid mode");
p->f = fopen(filename, md);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
#endif
} }
#if !defined(USE_FATFS)
/* /*
** function to close 'popen' files ** function to close 'popen' files
@ -239,7 +272,6 @@ static int io_pclose (lua_State *L) {
return luaL_execresult(L, lua_pclose(L, p->f)); return luaL_execresult(L, lua_pclose(L, p->f));
} }
static int io_popen (lua_State *L) { static int io_popen (lua_State *L) {
const char *filename = luaL_checkstring(L, 1); const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r"); const char *mode = luaL_optstring(L, 2, "r");
@ -336,7 +368,6 @@ static int io_lines (lua_State *L) {
return 1; return 1;
} }
/* /*
** {====================================================== ** {======================================================
** READ ** READ
@ -356,7 +387,6 @@ static int read_number (lua_State *L, FILE *f) {
} }
} }
static int test_eof (lua_State *L, FILE *f) { static int test_eof (lua_State *L, FILE *f) {
int c = lua_getc(f); int c = lua_getc(f);
ungetc(c, f); ungetc(c, f);
@ -386,7 +416,6 @@ static int read_line (lua_State *L, FILE *f, int chop) {
} }
} }
#define MAX_SIZE_T (~(size_t)0) #define MAX_SIZE_T (~(size_t)0)
static void read_all (lua_State *L, FILE *f) { static void read_all (lua_State *L, FILE *f) {
@ -403,21 +432,21 @@ static void read_all (lua_State *L, FILE *f) {
} }
luaL_pushresult(&b); /* close buffer */ luaL_pushresult(&b); /* close buffer */
} }
#endif
static int read_chars (lua_State *L, FILE *f, size_t n) { static int read_chars (lua_State *L, FILE *f, size_t n) {
size_t nr; /* number of chars actually read */ unsigned int nr; /* number of chars actually read */
char *p; char *p;
luaL_Buffer b; luaL_Buffer b;
luaL_buffinit(L, &b); luaL_buffinit(L, &b);
p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */
nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ FRESULT result = f_read(f, p, n, &nr); /* try to read 'n' chars */
luaL_addsize(&b, nr); luaL_addsize(&b, nr);
luaL_pushresult(&b); /* close buffer */ luaL_pushresult(&b); /* close buffer */
return (nr > 0); /* true iff read something */ return (result == FR_OK && nr > 0); /* true iff read something */
} }
#if !defined(USE_FATFS)
static int g_read (lua_State *L, FILE *f, int first) { static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1; int nargs = lua_gettop(L) - 1;
int success; int success;
@ -477,7 +506,18 @@ static int f_read (lua_State *L) {
return g_read(L, tofile(L), 2); return g_read(L, tofile(L), 2);
} }
#else
static int io_read (lua_State *L) {
LStream *p = tolstream(L);
size_t l = (size_t)lua_tointeger(L, 2);
read_chars(L, &p->f, l);
return 1;
}
#endif
#if !defined(USE_FATFS)
static int io_readline (lua_State *L) { static int io_readline (lua_State *L) {
LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
int i; int i;
@ -507,6 +547,7 @@ static int io_readline (lua_State *L) {
/* }====================================================== */ /* }====================================================== */
#endif
static int g_write (lua_State *L, FILE *f, int arg) { static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - arg; int nargs = lua_gettop(L) - arg;
@ -515,31 +556,38 @@ static int g_write (lua_State *L, FILE *f, int arg) {
if (lua_type(L, arg) == LUA_TNUMBER) { if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */ /* optimization: could be done exactly as for strings */
status = status && status = status &&
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; f_printf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
} }
else { else {
size_t l; size_t l;
UINT count;
const char *s = luaL_checklstring(L, arg, &l); const char *s = luaL_checklstring(L, arg, &l);
status = status && (fwrite(s, sizeof(char), l, f) == l); status = status && (f_write(f, s, l, &count) == FR_OK && count == l);
} }
} }
if (status) return 1; /* file handle already on stack top */ if (status) return 1; /* file handle already on stack top */
else return luaL_fileresult(L, status, NULL); else return luaL_fileresult(L, status, NULL);
} }
#if !defined(USE_FATFS)
static int io_write (lua_State *L) { static int io_write (lua_State *L) {
return g_write(L, getiofile(L, IO_OUTPUT), 1); return g_write(L, getiofile(L, IO_OUTPUT), 1);
} }
static int f_write (lua_State *L) { static int f_write (lua_State *L) {
FILE *f = tofile(L); FILE *f = tofile(L);
lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
return g_write(L, f, 2); return g_write(L, f, 2);
} }
#else
static int io_write (lua_State *L) {
FILE *f = tofile(L);
lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */
return g_write(L, f, 2);
}
#endif
#if !defined(USE_FATFS)
static int f_seek (lua_State *L) { static int f_seek (lua_State *L) {
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL}; static const char *const modenames[] = {"set", "cur", "end", NULL};
@ -570,7 +618,7 @@ static int f_setvbuf (lua_State *L) {
} }
#if !defined(USE_FATFS)
static int io_flush (lua_State *L) { static int io_flush (lua_State *L) {
return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
} }
@ -579,26 +627,29 @@ static int io_flush (lua_State *L) {
static int f_flush (lua_State *L) { static int f_flush (lua_State *L) {
return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
} }
#endif
#endif
/* /*
** functions for 'io' library ** functions for 'io' library
*/ */
static const luaL_Reg iolib[] = { const luaL_Reg iolib[] = {
{"close", io_close}, {"close", io_close},
{"flush", io_flush}, // {"flush", io_flush},
{"input", io_input}, // {"input", io_input},
{"lines", io_lines}, // {"lines", io_lines},
{"open", io_open}, {"open", io_open},
{"output", io_output}, // {"output", io_output},
{"popen", io_popen}, // {"popen", io_popen},
{"read", io_read}, {"read", io_read},
{"tmpfile", io_tmpfile}, // {"tmpfile", io_tmpfile},
{"type", io_type}, // {"type", io_type},
{"write", io_write}, {"write", io_write},
{NULL, NULL} {NULL, NULL}
}; };
#if !defined(USE_FATFS)
/* /*
** methods for file handles ** methods for file handles
@ -607,7 +658,7 @@ static const luaL_Reg flib[] = {
{"close", io_close}, {"close", io_close},
{"flush", f_flush}, {"flush", f_flush},
{"lines", f_lines}, {"lines", f_lines},
{"read", f_read}, {"read", io_read},
{"seek", f_seek}, {"seek", f_seek},
{"setvbuf", f_setvbuf}, {"setvbuf", f_setvbuf},
{"write", f_write}, {"write", f_write},
@ -616,16 +667,17 @@ static const luaL_Reg flib[] = {
{NULL, NULL} {NULL, NULL}
}; };
#endif
static void createmeta (lua_State *L) { static void createmeta (lua_State *L) {
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
lua_pushvalue(L, -1); /* push metatable */ lua_pushvalue(L, -1); /* push metatable */
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ // lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ // luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
lua_pop(L, 1); /* pop new metatable */ lua_pop(L, 1); /* pop new metatable */
} }
#if !defined(USE_FATFS)
/* /*
** function to (not) close the standard files stdin, stdout, and stderr ** function to (not) close the standard files stdin, stdout, and stderr
*/ */
@ -650,14 +702,15 @@ static void createstdfile (lua_State *L, FILE *f, const char *k,
lua_setfield(L, -2, fname); /* add file to module */ lua_setfield(L, -2, fname); /* add file to module */
} }
#endif
LUAMOD_API int luaopen_io (lua_State *L) { LUAMOD_API int luaopen_io (lua_State *L) {
luaL_newlib(L, iolib); /* new module */ // luaL_newlib(L, iolib); /* new module */
createmeta(L); createmeta(L);
/* create (and set) default files */ /* create (and set) default files */
createstdfile(L, stdin, IO_INPUT, "stdin"); // createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout"); // createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, NULL, "stderr"); // createstdfile(L, stderr, NULL, "stderr");
return 1; // return 1;
return 0;
} }

View file

@ -119,6 +119,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop; int loop;
if (ttisrotable(t)) { if (ttisrotable(t)) {
setnilvalue(val); setnilvalue(val);
TRACE("luaV_gettable(key=%s)", key);
if (ttisstring(key)) { if (ttisstring(key)) {
char keyname[LUA_MAX_ROTABLE_NAME + 1]; char keyname[LUA_MAX_ROTABLE_NAME + 1];
lu_byte keytype; lu_byte keytype;
@ -143,8 +144,10 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
} }
/* else will try the tag method */ /* else will try the tag method */
} }
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) {
TRACE("ERREUR ICI");
luaG_typeerror(L, t, "index"); luaG_typeerror(L, t, "index");
}
if (ttisfunction(tm) || ttislightfunction(tm)) { if (ttisfunction(tm) || ttislightfunction(tm)) {
callTM(L, tm, t, key, val, 1); callTM(L, tm, t, key, val, 1);
return; return;