summaryrefslogtreecommitdiff
path: root/src/liolib.js
blob: f753f9168b13906bfb77795a59b5d114665c95ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
"use strict";

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 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;
    p.closef = null;
    lauxlib.luaL_setmetatable(L, lauxlib.LUA_FILEHANDLE);
    return p;
};

const iolib = {
};

const flib = {
    "__tostring": f_tostring
};

const createmeta = function(L) {
    lauxlib.luaL_newmetatable(L, lauxlib.LUA_FILEHANDLE);  /* create metatable for file handles */
    lua.lua_pushvalue(L, -1);  /* push metatable */
    lua.lua_setfield(L, -2, lua.to_luastring("__index", true));  /* metatable.__index = metatable */
    lauxlib.luaL_setfuncs(L, flib, 0);  /* add file methods to new metatable */
    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;
};

module.exports.luaopen_io = luaopen_io;