mirror of
https://github.com/opentx/opentx.git
synced 2025-07-20 23:05:12 +03:00
#1471 - libio added to Lua. For tests, can be simplified and expanded
This commit is contained in:
parent
7863bb23b9
commit
4e55213ae6
5 changed files with 114 additions and 52 deletions
|
@ -937,7 +937,7 @@ ifeq ($(PCB), TARANIS)
|
|||
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 \
|
||||
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)
|
||||
LUADEP = lua_exports.inc
|
||||
ifeq ($(USE_BIN_ALLOCATOR), YES)
|
||||
|
|
|
@ -26,8 +26,10 @@ typedef struct luaL_Reg {
|
|||
|
||||
extern const luaL_Reg baselib[];
|
||||
extern const luaL_Reg mathlib[];
|
||||
extern const luaL_Reg opentxLib[];
|
||||
extern const luaL_Reg bitlib[];
|
||||
extern const luaL_Reg iolib[];
|
||||
|
||||
extern const luaL_Reg opentxLib[];
|
||||
extern const luaL_Reg lcdLib[];
|
||||
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*"
|
||||
|
||||
#if defined(USE_FATFS)
|
||||
#define FILE FIL
|
||||
#endif
|
||||
|
||||
typedef struct luaL_Stream {
|
||||
#if defined(USE_FATFS)
|
||||
FIL *f; /* stream (NULL for incompletely created streams) */
|
||||
FIL f;
|
||||
#else
|
||||
FILE *f; /* stream (NULL for incompletely created streams) */
|
||||
#endif
|
||||
lua_CFunction closef; /* to close stream (NULL for closed streams) */
|
||||
#endif
|
||||
} luaL_Stream;
|
||||
|
||||
/* }====================================================== */
|
||||
|
|
|
@ -31,7 +31,7 @@ static const luaL_Reg loadedlibs[] = {
|
|||
// {LUA_LOADLIBNAME, luaopen_package},
|
||||
// {LUA_COLIBNAME, luaopen_coroutine},
|
||||
// {LUA_TABLIBNAME, luaopen_table},
|
||||
// {LUA_IOLIBNAME, luaopen_io},
|
||||
{LUA_IOLIBNAME, luaopen_io},
|
||||
// {LUA_OSLIBNAME, luaopen_os},
|
||||
// {LUA_STRLIBNAME, luaopen_string},
|
||||
// {LUA_BITLIBNAME, luaopen_bit32},
|
||||
|
@ -45,6 +45,7 @@ const luaR_table lua_rotable[] =
|
|||
{
|
||||
{LUA_MATHLIBNAME, mathlib, mathlib_vals},
|
||||
{LUA_BITLIBNAME, bitlib, NULL},
|
||||
{LUA_IOLIBNAME, iolib, NULL},
|
||||
{"lcd", lcdLib, NULL},
|
||||
{"model", modelLib, NULL},
|
||||
{"__baselib", baselib, NULL},
|
||||
|
|
|
@ -121,8 +121,9 @@ typedef luaL_Stream LStream;
|
|||
|
||||
#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) {
|
||||
LStream *p;
|
||||
|
@ -147,13 +148,18 @@ static int f_tostring (lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static FILE *tofile (lua_State *L) {
|
||||
LStream *p = tolstream(L);
|
||||
#if defined(USE_FATFS)
|
||||
return &p->f;
|
||||
#else
|
||||
if (isclosed(p))
|
||||
luaL_error(L, "attempt to use a closed file");
|
||||
lua_assert(p->f);
|
||||
return p->f;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,36 +170,48 @@ static FILE *tofile (lua_State *L) {
|
|||
*/
|
||||
static LStream *newprefile (lua_State *L) {
|
||||
LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream));
|
||||
#if !defined(USE_FATFS)
|
||||
p->closef = NULL; /* mark file handle as 'closed' */
|
||||
#endif
|
||||
luaL_setmetatable(L, LUA_FILEHANDLE);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
static int aux_close (lua_State *L) {
|
||||
#if !defined(USE_FATFS)
|
||||
LStream *p = tolstream(L);
|
||||
lua_CFunction cf = p->closef;
|
||||
p->closef = NULL; /* mark stream as closed */
|
||||
return (*cf)(L); /* close it */
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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? */
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */
|
||||
tofile(L); /* make sure argument is an open stream */
|
||||
return aux_close(L);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
static int f_gc (lua_State *L) {
|
||||
#if !defined(USE_FATFS)
|
||||
LStream *p = tolstream(L);
|
||||
if (!isclosed(p) && p->f != NULL)
|
||||
aux_close(L); /* ignore closed and incompletely open files */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** function to close regular files
|
||||
*/
|
||||
|
@ -202,34 +220,49 @@ static int io_fclose (lua_State *L) {
|
|||
int res = fclose(p->f);
|
||||
return luaL_fileresult(L, (res == 0), NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static LStream *newfile (lua_State *L) {
|
||||
LStream *p = newprefile(L);
|
||||
#if !defined(USE_FATFS)
|
||||
p->f = NULL;
|
||||
p->closef = &io_fclose;
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
static void opencheck (lua_State *L, const char *fname, const char *mode) {
|
||||
LStream *p = newfile(L);
|
||||
p->f = fopen(fname, mode);
|
||||
if (p->f == NULL)
|
||||
luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int io_open (lua_State *L) {
|
||||
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);
|
||||
const char *md = mode; /* to traverse/check mode */
|
||||
luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");
|
||||
p->f = fopen(filename, mode);
|
||||
#if defined(USE_FATFS)
|
||||
BYTE 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;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
|
||||
/*
|
||||
** 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));
|
||||
}
|
||||
|
||||
|
||||
static int io_popen (lua_State *L) {
|
||||
const char *filename = luaL_checkstring(L, 1);
|
||||
const char *mode = luaL_optstring(L, 2, "r");
|
||||
|
@ -336,7 +368,6 @@ static int io_lines (lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** READ
|
||||
|
@ -356,7 +387,6 @@ static int read_number (lua_State *L, FILE *f) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static int test_eof (lua_State *L, FILE *f) {
|
||||
int c = lua_getc(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)
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
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;
|
||||
luaL_Buffer b;
|
||||
luaL_buffinit(L, &b);
|
||||
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_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) {
|
||||
int nargs = lua_gettop(L) - 1;
|
||||
int success;
|
||||
|
@ -477,7 +506,18 @@ static int f_read (lua_State *L) {
|
|||
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) {
|
||||
LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1));
|
||||
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) {
|
||||
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) {
|
||||
/* optimization: could be done exactly as for strings */
|
||||
status = status &&
|
||||
fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
|
||||
f_printf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
|
||||
}
|
||||
else {
|
||||
size_t l;
|
||||
UINT count;
|
||||
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 */
|
||||
else return luaL_fileresult(L, status, NULL);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
static int io_write (lua_State *L) {
|
||||
return g_write(L, getiofile(L, IO_OUTPUT), 1);
|
||||
}
|
||||
|
||||
|
||||
static int f_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);
|
||||
}
|
||||
#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 const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
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) {
|
||||
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) {
|
||||
return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** functions for 'io' library
|
||||
*/
|
||||
static const luaL_Reg iolib[] = {
|
||||
const luaL_Reg iolib[] = {
|
||||
{"close", io_close},
|
||||
{"flush", io_flush},
|
||||
{"input", io_input},
|
||||
{"lines", io_lines},
|
||||
// {"flush", io_flush},
|
||||
// {"input", io_input},
|
||||
// {"lines", io_lines},
|
||||
{"open", io_open},
|
||||
{"output", io_output},
|
||||
{"popen", io_popen},
|
||||
// {"output", io_output},
|
||||
// {"popen", io_popen},
|
||||
{"read", io_read},
|
||||
{"tmpfile", io_tmpfile},
|
||||
{"type", io_type},
|
||||
// {"tmpfile", io_tmpfile},
|
||||
// {"type", io_type},
|
||||
{"write", io_write},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
|
||||
/*
|
||||
** methods for file handles
|
||||
|
@ -607,7 +658,7 @@ static const luaL_Reg flib[] = {
|
|||
{"close", io_close},
|
||||
{"flush", f_flush},
|
||||
{"lines", f_lines},
|
||||
{"read", f_read},
|
||||
{"read", io_read},
|
||||
{"seek", f_seek},
|
||||
{"setvbuf", f_setvbuf},
|
||||
{"write", f_write},
|
||||
|
@ -616,16 +667,17 @@ static const luaL_Reg flib[] = {
|
|||
{NULL, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
static void createmeta (lua_State *L) {
|
||||
luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */
|
||||
lua_pushvalue(L, -1); /* push metatable */
|
||||
lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
|
||||
luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
|
||||
// lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */
|
||||
// luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */
|
||||
lua_pop(L, 1); /* pop new metatable */
|
||||
}
|
||||
|
||||
|
||||
#if !defined(USE_FATFS)
|
||||
/*
|
||||
** 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 */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
LUAMOD_API int luaopen_io (lua_State *L) {
|
||||
luaL_newlib(L, iolib); /* new module */
|
||||
// luaL_newlib(L, iolib); /* new module */
|
||||
createmeta(L);
|
||||
/* create (and set) default files */
|
||||
createstdfile(L, stdin, IO_INPUT, "stdin");
|
||||
createstdfile(L, stdout, IO_OUTPUT, "stdout");
|
||||
createstdfile(L, stderr, NULL, "stderr");
|
||||
return 1;
|
||||
// createstdfile(L, stdin, IO_INPUT, "stdin");
|
||||
// createstdfile(L, stdout, IO_OUTPUT, "stdout");
|
||||
// createstdfile(L, stderr, NULL, "stderr");
|
||||
// return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
|
|||
int loop;
|
||||
if (ttisrotable(t)) {
|
||||
setnilvalue(val);
|
||||
TRACE("luaV_gettable(key=%s)", key);
|
||||
if (ttisstring(key)) {
|
||||
char keyname[LUA_MAX_ROTABLE_NAME + 1];
|
||||
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 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");
|
||||
}
|
||||
if (ttisfunction(tm) || ttislightfunction(tm)) {
|
||||
callTM(L, tm, t, key, val, 1);
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue