diff options
| author | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-03-21 15:29:53 +0100 | 
|---|---|---|
| committer | Benoit Giannangeli <benoit.giannangeli@boursorama.fr> | 2017-03-23 08:28:07 +0100 | 
| commit | 9e08fa3a4b9f8848bb4eac3e745079282099a3d8 (patch) | |
| tree | 64be88a45075fe93bbd8c03c3244d3a83fad7491 /src/lauxlib.js | |
| parent | c4b23126f0cb803ec944c5d7877bbf669f582374 (diff) | |
| download | fengari-9e08fa3a4b9f8848bb4eac3e745079282099a3d8.tar.gz fengari-9e08fa3a4b9f8848bb4eac3e745079282099a3d8.tar.bz2 fengari-9e08fa3a4b9f8848bb4eac3e745079282099a3d8.zip | |
loadfile
Diffstat (limited to 'src/lauxlib.js')
| -rw-r--r-- | src/lauxlib.js | 129 | 
1 files changed, 124 insertions, 5 deletions
| diff --git a/src/lauxlib.js b/src/lauxlib.js index ac7ab00..dbdb251 100644 --- a/src/lauxlib.js +++ b/src/lauxlib.js @@ -3,11 +3,12 @@  const assert = require('assert'); -const lstate = require('./lstate.js'); -const lapi   = require('./lapi.js'); -const lua    = require('./lua.js'); -const ldebug = require('./ldebug.js'); -const CT     = lua.constant_types; +const lstate  = require('./lstate.js'); +const lapi    = require('./lapi.js'); +const lua     = require('./lua.js'); +const ldebug  = require('./ldebug.js'); +const lobject = require('./lobject.js'); +const CT      = lua.constant_types;  const LUA_LOADED_TABLE = "_LOADED"; @@ -399,6 +400,124 @@ const luaL_newlib = function(L, l) {      luaL_setfuncs(L, l, 0);  }; +// Only with Node +if (typeof window === "undefined") { +    const fs = require('fs'); + +    class LoadF { +        constructor() { +            this.n = NaN;  /* number of pre-read characters */ +            this.f = null;  /* file being read */ +            this.buff = new Buffer(1024);  /* area for reading file */ +            this.pos = 0;  /* current position in file */ +        } +    } + +    const getF = function(L, ud) { +        let lf = ud; +        let bytes = 0; +        if (lf.n > 0) {  /* are there pre-read characters to be read? */ +            lf.n = 0;  /* no more pre-read characters */ +        } else {  /* read a block from file */ +            lf.buff.fill(0); +            bytes = fs.readSync(lf.f, lf.buff, 0, lf.buff.length, lf.pos); /* read block */ +            lf.pos += bytes; +        } +        return bytes > 0 ? new lobject.TValue(0, lf.buff).jsstring() : null; // TODO: Here reading utf8 only +    }; + +    const errfile = function(L, what, fnameindex, error) { +        let serr = error.message; +        let filename = lapi.lua_tostring(L, fnameindex).slice(1); +        lapi.lua_pushstring(L, `cannot ${what} ${filename}: ${serr}`); +        lapi.lua_remove(L, fnameindex); +        return lua.thread_status.LUA_ERRFILE; +    }; + +    const getc = function(lf) { +        let b = new Buffer(1); +        let bytes = fs.readSync(lf.f, b, 0, 1, lf.pos); +        lf.pos += bytes; +        return bytes > 0 ? b.readUInt8() : null; +    }; + +    const skipBOM = function(lf) { +        let p = "\xEF\xBB\xBF";  /* UTF-8 BOM mark */ +        lf.n = 0; +        let c; +        do { +            c = getc(lf); +            if (c === null || c !== p.charCodeAt(0)) return c; +            p = p.slice(1); +            lf.buff[lf.n++] = c;  /* to be read by the parser */ +        } while (p.length > 0); +        lf.n = 0;  /* prefix matched; discard it */ +        return getc(lf);  /* return next character */ +    }; + +    /* +    ** reads the first character of file 'f' and skips an optional BOM mark +    ** in its beginning plus its first line if it starts with '#'. Returns +    ** true if it skipped the first line.  In any case, '*cp' has the +    ** first "valid" character of the file (after the optional BOM and +    ** a first-line comment). +    */ +    const skipcomment = function(lf) { +        let c = skipBOM(lf); +        if (c === '#'.charCodeAt(0)) {  /* first line is a comment (Unix exec. file)? */ +            do {  /* skip first line */ +                c = getc(lf); +            } while (c && c !== '\n'.charCodeAt(0)); +            return getc(lf);  /* skip end-of-line, if present */ +        } else { +            lf.pos--; +            return false; +        } +    }; + +    const luaL_loadfilex = function(L, filename, mode) { +        let lf = new LoadF(); +        let fnameindex = lapi.lua_gettop(L) + 1;  /* index of filename on the stack */ +        if (filename === null) { +            lapi.lua_pushliteral(L, "=stdin"); +            lf.f = process.stdin.fd; +        } else { +            lapi.lua_pushstring(L, `@${filename}`); +            try { +                lf.f = fs.openSync(filename, "r"); +            } catch (e) { +                return errfile(L, "open", fnameindex, e); +            } +        } + +        try { +            let c; +            if ((c = skipcomment(lf)))  /* read initial portion */ +                lf.buff[lf.n++] = '\n'.charCodeAt(0);  /* add line to correct line numbers */ + +            if (c === lua.LUA_SIGNATURE.charCodeAt(0) && filename) {  /* binary file? */ +                // ... +            } + +            let status = lapi.lua_load(L, getF, lf, lapi.lua_tostring(L, -1), mode); +            if (filename) fs.closeSync(lf.f);  /* close file (even in case of errors) */ +            lapi.lua_remove(L, fnameindex); +            return status; +        } catch (err) { +            lapi.lua_settop(L, fnameindex);  /* ignore results from 'lua_load' */ +            return errfile(L, "read", fnameindex); +        } +    }; + +    const luaL_loadfile = function(L, filename) { +        return luaL_loadfilex(L, filename, null); +    }; + +    module.exports.luaL_loadfilex = luaL_loadfilex; +    module.exports.luaL_loadfile  = luaL_loadfile; + +} +  module.exports.LUA_LOADED_TABLE  = LUA_LOADED_TABLE;  module.exports.luaL_Buffer       = luaL_Buffer;  module.exports.luaL_addchar      = luaL_addchar; | 
