From 56b5adb7f3683cd9e88f8d2cabd885e49a3d2398 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 26 Apr 2017 23:29:17 +1000 Subject: src/iolib.js: Create stdin/stdout/stderr --- README.md | 6 +++--- src/liolib.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9d7e70e..56f3496 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ - [x] os (~~`os.setlocale()`~~) - [ ] Package - [ ] io - - [ ] `io.stdin` - - [ ] `io.stdout` - - [ ] `io.stderr` + - [x] `io.stdin` + - [x] `io.stdout` + - [x] `io.stderr` - [ ] `io.flush()` - [ ] `io.input()` - [ ] `io.lines()` diff --git a/src/liolib.js b/src/liolib.js index 22dc2e8..247baef 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -3,6 +3,23 @@ const lua = require('./lua.js'); const lauxlib = require('./lauxlib.js'); +const IO_PREFIX = "_IO_"; +const IOPREF_LEN = IO_PREFIX.length; +const IO_INPUT = lua.to_luastring(IO_PREFIX + "input"); +const IO_OUTPUT = lua.to_luastring(IO_PREFIX + "output"); + +const tolstream = function(L) { + return lauxlib.luaL_checkudata(L, 1, lauxlib.LUA_FILEHANDLE); +}; + +const newprefile = function(L) { + let p = lua.lua_newuserdata(L); + p.f = null; + p.closef = null; + lauxlib.luaL_setmetatable(L, lauxlib.LUA_FILEHANDLE); + return p; +}; + const iolib = { }; @@ -17,9 +34,32 @@ const createmeta = function(L) { lua.lua_pop(L, 1); /* pop new metatable */ }; +const io_noclose = function(L) { + let p = tolstream(L); + p.closef = io_noclose; + lua.lua_pushnil(L); + lua.lua_pushliteral(L, "cannot close standard file"); + return 2; +}; + +const createstdfile = function(L, f, k, fname) { + let p = newprefile(L); + p.f = f; + p.closef = io_noclose; + if (k !== null) { + lua.lua_pushvalue(L, -1); + lua.lua_setfield(L, lua.LUA_REGISTRYINDEX, k); /* add file to registry */ + } + lua.lua_setfield(L, -2, fname); /* add file to module */ +}; + const luaopen_io = function(L) { lauxlib.luaL_newlib(L, iolib); createmeta(L); + /* create (and set) default files */ + createstdfile(L, process.stdin, IO_INPUT, lua.to_luastring("stdin")); + createstdfile(L, process.stdout, IO_OUTPUT, lua.to_luastring("stdout")); + createstdfile(L, process.stderr, null, lua.to_luastring("stderr")); return 1; }; -- cgit v1.2.3-70-g09d2 From 9a24308b0f8bb04d533d9abae39bd7546cf92377 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 26 Apr 2017 23:30:30 +1000 Subject: src/iolib.js: Add file:__tostring() --- README.md | 2 +- src/liolib.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 56f3496..02110dd 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ - [ ] `file:setvbuf()` - [ ] `file:write()` - [ ] `file:__gc()` - - [ ] `file:__tostring()` + - [x] `file:__tostring()` - [ ] C API - [x] ... - [ ] lua_arith diff --git a/src/liolib.js b/src/liolib.js index 247baef..f753f91 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -12,6 +12,19 @@ const tolstream = function(L) { return lauxlib.luaL_checkudata(L, 1, lauxlib.LUA_FILEHANDLE); }; +const isclosed = function(p) { + return p.closef === null; +}; + +const f_tostring = function(L) { + let p = tolstream(L); + if (isclosed(p)) + lua.lua_pushliteral(L, "file (closed)"); + else + lua.lua_pushstring(L, lua.to_luastring(`file (${p.f.toString()})`)); + return 1; +}; + const newprefile = function(L) { let p = lua.lua_newuserdata(L); p.f = null; @@ -24,6 +37,7 @@ const iolib = { }; const flib = { + "__tostring": f_tostring }; const createmeta = function(L) { -- cgit v1.2.3-70-g09d2 From 290ddad546117d6b55639faa7ad943d96f8e224c Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 27 Apr 2017 00:03:08 +1000 Subject: src/liolib.js: Implement io.write --- README.md | 2 +- src/liolib.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 02110dd..804136a 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ - [ ] `io.read()` - [ ] `io.tmpfile()` - [ ] `io.type()` - - [ ] `io.write()` + - [x] `io.write()` - [ ] `io.close()` - [ ] `file:flush()` - [ ] `file:lines()` diff --git a/src/liolib.js b/src/liolib.js index f753f91..f581323 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -1,5 +1,7 @@ "use strict"; +const fs = require('fs'); + const lua = require('./lua.js'); const lauxlib = require('./lauxlib.js'); @@ -33,7 +35,37 @@ const newprefile = function(L) { return p; }; +const getiofile = function(L, findex) { + lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, findex); + let p = lua.lua_touserdata(L, -1); + if (isclosed(p)) + lauxlib.luaL_error(L, lua.to_luastring(`standard ${lua.to_jsstring(findex.slice(IOPREF_LEN))} file is closed`)); + return p.f; +}; + +const g_write = function(L, f, arg) { + let nargs = lua.lua_gettop(L) - arg; + let status = true; + let err; + for (; nargs--; arg++) { + let s = lauxlib.luaL_checklstring(L, arg); + try { + status = status && (fs.writeSync(f.fd, Uint8Array.from(s)) === s.length); + } catch (e) { + status = false; + err = e; + } + } + if (status) return 1; /* file handle already on stack top */ + else return lauxlib.luaL_fileresult(L, status, null, err); +}; + +const io_write = function(L) { + return g_write(L, getiofile(L, IO_OUTPUT), 1); +}; + const iolib = { + "write": io_write }; const flib = { -- cgit v1.2.3-70-g09d2 From 5525f63f02352a3347911d0d179657983ea5171a Mon Sep 17 00:00:00 2001 From: daurnimator Date: Thu, 27 Apr 2017 03:02:41 +1000 Subject: src/liolib: Add file:write() --- README.md | 2 +- src/liolib.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 804136a..d62d8d4 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ - [ ] `file:read()` - [ ] `file:read()` - [ ] `file:setvbuf()` - - [ ] `file:write()` + - [x] `file:write()` - [ ] `file:__gc()` - [x] `file:__tostring()` - [ ] C API diff --git a/src/liolib.js b/src/liolib.js index f581323..9940583 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -1,5 +1,6 @@ "use strict"; +const assert = require('assert'); const fs = require('fs'); const lua = require('./lua.js'); @@ -27,6 +28,14 @@ const f_tostring = function(L) { return 1; }; +const tofile = function(L) { + let p = tolstream(L); + if (isclosed(p)) + lauxlib.luaL_error(L, "attempt to use a closed file"); + assert(p.f); + return p.f; +}; + const newprefile = function(L) { let p = lua.lua_newuserdata(L); p.f = null; @@ -64,11 +73,18 @@ const io_write = function(L) { return g_write(L, getiofile(L, IO_OUTPUT), 1); }; +const f_write = function(L) { + let f = tofile(L); + lua.lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + return g_write(L, f, 2); +}; + const iolib = { "write": io_write }; const flib = { + "write": f_write, "__tostring": f_tostring }; -- cgit v1.2.3-70-g09d2 From 134f6bd221ad8880cb1b8514bb84e3b41d2b0d61 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 3 May 2017 17:52:42 +1000 Subject: src/liolib.js: add io.close() --- README.md | 2 +- src/liolib.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d62d8d4..2c6cbba 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ - [ ] `io.tmpfile()` - [ ] `io.type()` - [x] `io.write()` - - [ ] `io.close()` + - [x] `io.close()` - [ ] `file:flush()` - [ ] `file:lines()` - [ ] `file:read()` diff --git a/src/liolib.js b/src/liolib.js index 9940583..2136755 100644 --- a/src/liolib.js +++ b/src/liolib.js @@ -44,6 +44,20 @@ const newprefile = function(L) { return p; }; +const aux_close = function(L) { + let p = tolstream(L); + let cf = p.closef; + p.closef = null; + return cf(L); +}; + +const io_close = function(L) { + if (lua.lua_isnone(L, 1)) /* no argument? */ + lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); +}; + const getiofile = function(L, findex) { lua.lua_getfield(L, lua.LUA_REGISTRYINDEX, findex); let p = lua.lua_touserdata(L, -1); @@ -80,10 +94,12 @@ const f_write = function(L) { }; const iolib = { + "close": io_close, "write": io_write }; const flib = { + "close": io_close, "write": f_write, "__tostring": f_tostring }; -- cgit v1.2.3-70-g09d2