aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authordaurnimator <quae@daurnimator.com>2017-04-13 16:18:32 +1000
committerdaurnimator <quae@daurnimator.com>2017-04-19 18:09:12 +1000
commit006badf9d13971010384340ff786c1cd62c268f6 (patch)
treeb190d238838a4549fe2ef57ba7dd24bc26e37d38 /tests
parenta0f96081d3533d795c7a1575eb08837a3b0d26d7 (diff)
downloadfengari-006badf9d13971010384340ff786c1cd62c268f6.tar.gz
fengari-006badf9d13971010384340ff786c1cd62c268f6.tar.bz2
fengari-006badf9d13971010384340ff786c1cd62c268f6.zip
lua-cli: Add command line options
Diffstat (limited to 'tests')
-rwxr-xr-xtests/manual-tests/lua-cli.js242
1 files changed, 199 insertions, 43 deletions
diff --git a/tests/manual-tests/lua-cli.js b/tests/manual-tests/lua-cli.js
index b71a576..5bbf5cd 100755
--- a/tests/manual-tests/lua-cli.js
+++ b/tests/manual-tests/lua-cli.js
@@ -41,13 +41,110 @@ const dostring = function(L, s, name) {
return dochunk(L, lauxlib.luaL_loadbuffer(L, buffer, buffer.length, lua.to_luastring(name)));
};
+const dolibrary = function(L, name) {
+ lapi.lua_getglobal(L, lua.to_luastring("require"));
+ lapi.lua_pushliteral(L, name);
+ let status = docall(L, 1, 1); /* call 'require(name)' */
+ if (status === lua.thread_status.LUA_OK)
+ lapi.lua_setglobal(L, lua.to_luastring(name)); /* global[name] = require return */
+ return report(L, status);
+};
+
+let progname = process.argv[1];
+
+const print_usage = function(badoption) {
+ lauxlib.lua_writestringerror(`${progname}: `);
+ if (badoption[1] === "e" || badoption[1] === "l")
+ lauxlib.lua_writestringerror(`'${badoption}' needs argument\n`);
+ else
+ lauxlib.lua_writestringerror(`'unrecognized option '${badoption}'\n`);
+ lauxlib.lua_writestringerror(
+ `usage: ${progname} [options] [script [args]]\n` +
+ "Available options are:\n" +
+ " -e stat execute string 'stat'\n" +
+ " -i enter interactive mode after executing 'script'\n" +
+ " -l name require library 'name'\n" +
+ " -v show version information\n" +
+ " -E ignore environment variables\n" +
+ " -- stop handling options\n" +
+ " - stop handling options and execute stdin\n"
+ );
+};
+
const L = lauxlib.luaL_newstate();
let script = 2; // Where to start args from
+let has_E = false;
+let has_i = false;
+let has_v = false;
+let has_e = false;
+
+(function() {
+ let i;
+ for (i = 2; i<process.argv.length; i++) {
+ script = i;
+ if (process.argv[i][0] != "-") {
+ return;
+ }
+ switch(process.argv[i][1]) {
+ case '-':
+ if (process.argv[i][2]) {
+ print_usage(process.argv[script]);
+ return process.exit(1);
+ }
+ script = i + 1;
+ return;
+ case void 0: /* script name is '-' */
+ return;
+ case 'E':
+ has_E = true;
+ break;
+ case 'i':
+ has_i = true;
+ /* (-i implies -v) */
+ /* falls through */
+ case 'v':
+ if (process.argv[i].length > 2) {
+ /* invalid option */
+ print_usage(process.argv[script]);
+ return process.exit(1);
+ }
+ has_v = true;
+ break;
+ case 'e':
+ has_e = true;
+ /* falls through */
+ case 'l': /* both options need an argument */
+ if (process.argv[i].length < 3) { /* no concatenated argument? */
+ i++; /* try next 'process.argv' */
+ if (process.argv.length <= i || process.argv[i][0] === '-') {
+ /* no next argument or it is another option */
+ print_usage(process.argv[script]);
+ return process.exit(1);
+ }
+ }
+ break;
+ default: /* invalid option */
+ print_usage(process.argv[script]);
+ return process.exit(1);
+ }
+ }
+ script = i;
+})();
+if (has_v)
+ console.log(lua.FENGARI_COPYRIGHT);
+
+if (has_E) {
+ /* signal for libraries to ignore env. vars. */
+ lapi.lua_pushboolean(L, 1);
+ lapi.lua_setfield(L, lua.LUA_REGISTRYINDEX, lua.to_luastring("LUA_NOENV"));
+}
+
+/* open standard libraries */
linit.luaL_openlibs(L);
-/* create 'arg' table */
+/* create table 'arg' */
lapi.lua_createtable(L, process.argv.length - (script + 1), script + 1);
for (let i = 0; i < process.argv.length; i++) {
lapi.lua_pushliteral(L, process.argv[i]);
@@ -55,7 +152,8 @@ for (let i = 0; i < process.argv.length; i++) {
}
lapi.lua_setglobal(L, lua.to_luastring("arg"));
-{
+if (!has_E) {
+ /* run LUA_INIT */
let name = "LUA_INIT"+lua.LUA_VERSUFFIX;
let init = process.env[name];
if (!init) {
@@ -75,55 +173,113 @@ lapi.lua_setglobal(L, lua.to_luastring("arg"));
}
}
-console.log(lua.FENGARI_COPYRIGHT);
-
-for (;;) {
- lapi.lua_getglobal(L, _PROMPT);
- let input = readlineSync.prompt({
- prompt: lapi.lua_tojsstring(L, -1) || '> '
- });
- lapi.lua_pop(L, 1);
+/* execute arguments -e and -l */
+for (let i = 1; i < script; i++) {
+ let option = process.argv[i][1];
+ if (option == 'e' || option == 'l') {
+ let extra = process.argv[i].substring(2); /* both options need an argument */
+ if (extra.length === 0)
+ extra = process.argv[++i];
+ let status;
+ if (option == 'e') {
+ status = dostring(L, extra, "=(command line)");
+ } else {
+ status = dolibrary(L, extra);
+ }
+ if (status !== lua.thread_status.LUA_OK) {
+ return process.exit(1);
+ }
+ }
+}
- if (input.length === 0)
- continue;
+const pushargs = function(L) {
+ if (lapi.lua_getglobal(L, lua.to_luastring("arg")) !== lua.constant_types.LUA_TTABLE)
+ lauxlib.luaL_error(L, lua.to_luastring("'arg' is not a table"));
+ let n = lauxlib.luaL_len(L, -1);
+ lauxlib.luaL_checkstack(L, n+3, lua.to_luastring("too many arguments to script"));
+ let i;
+ for (i=1; i<=n; i++)
+ lapi.lua_rawgeti(L, -i, i);
+ lapi.lua_remove(L, -i);
+ return n;
+};
+const handle_script = function(L, argv) {
+ let fname = argv[0];
let status;
- {
- let buffer = lua.to_luastring("return " + input);
- status = lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin);
- }
- if (status !== lua.thread_status.LUA_OK) {
- lapi.lua_pop(L, 1);
- let buffer = lua.to_luastring(input);
- if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin) === lua.thread_status.LUA_OK) {
- status = lua.thread_status.LUA_OK;
- }
+ if (fname === "-" && argv[-1] !== "--")
+ fname = void 0; /* stdin */
+ status = lauxlib.luaL_loadfile(L, lua.to_luastring(fname));
+ if (status === lua.thread_status.LUA_OK) {
+ let n = pushargs(L); /* push arguments to script */
+ status = docall(L, n, lua.LUA_MULTRET);
}
- while (status === lua.thread_status.LUA_ERRSYNTAX && lapi.lua_tojsstring(L, -1).endsWith("<eof>")) {
- /* continuation */
- lapi.lua_pop(L, 1);
- lapi.lua_getglobal(L, _PROMPT2);
- input += "\n" + readlineSync.prompt({
- prompt: lapi.lua_tojsstring(L, -1) || '>> '
+ return report(L, status);
+};
+
+const doREPL = function(L) {
+ for (;;) {
+ lapi.lua_getglobal(L, _PROMPT);
+ let input = readlineSync.prompt({
+ prompt: lapi.lua_tojsstring(L, -1) || '> '
});
lapi.lua_pop(L, 1);
- let buffer = lua.to_luastring(input);
- status = lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin);
- }
- if (status === lua.thread_status.LUA_OK) {
- status = docall(L, 0, lua.LUA_MULTRET);
- }
- if (status === lua.thread_status.LUA_OK) {
- let n = lapi.lua_gettop(L);
- if (n > 0) { /* any result to be printed? */
- lapi.lua_getglobal(L, lua.to_luastring("print"));
- lapi.lua_insert(L, 1);
- if (lapi.lua_pcall(L, n, 0, 0) != lua.thread_status.LUA_OK) {
- lauxlib.lua_writestringerror(`error calling 'print' (${lapi.lua_tojsstring(L, -1)})\n`);
+
+ if (input.length === 0)
+ continue;
+
+ let status;
+ {
+ let buffer = lua.to_luastring("return " + input);
+ status = lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin);
+ }
+ if (status !== lua.thread_status.LUA_OK) {
+ lapi.lua_pop(L, 1);
+ let buffer = lua.to_luastring(input);
+ if (lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin) === lua.thread_status.LUA_OK) {
+ status = lua.thread_status.LUA_OK;
}
}
+ while (status === lua.thread_status.LUA_ERRSYNTAX && lapi.lua_tojsstring(L, -1).endsWith("<eof>")) {
+ /* continuation */
+ lapi.lua_pop(L, 1);
+ lapi.lua_getglobal(L, _PROMPT2);
+ input += "\n" + readlineSync.prompt({
+ prompt: lapi.lua_tojsstring(L, -1) || '>> '
+ });
+ lapi.lua_pop(L, 1);
+ let buffer = lua.to_luastring(input);
+ status = lauxlib.luaL_loadbuffer(L, buffer, buffer.length, stdin);
+ }
+ if (status === lua.thread_status.LUA_OK) {
+ status = docall(L, 0, lua.LUA_MULTRET);
+ }
+ if (status === lua.thread_status.LUA_OK) {
+ let n = lapi.lua_gettop(L);
+ if (n > 0) { /* any result to be printed? */
+ lapi.lua_getglobal(L, lua.to_luastring("print"));
+ lapi.lua_insert(L, 1);
+ if (lapi.lua_pcall(L, n, 0, 0) != lua.thread_status.LUA_OK) {
+ lauxlib.lua_writestringerror(`error calling 'print' (${lapi.lua_tojsstring(L, -1)})\n`);
+ }
+ }
+ } else {
+ report(L, status);
+ }
+ lapi.lua_settop(L, 0); /* remove eventual returns */
+ }
+};
+
+if (script < process.argv.length && /* execute main script (if there is one) */
+ handle_script(L, process.argv.slice(script)) !== lua.thread_status.LUA_OK) {
+ /* success */
+} else if (has_i) {
+ doREPL(L);
+} else if (script == process.argv.length && !has_e && !has_v) { /* no arguments? */
+ if (process.stdin.isTTY) { /* running in interactive mode? */
+ console.log(lua.FENGARI_COPYRIGHT);
+ doREPL(L); /* do read-eval-print loop */
} else {
- report(L, status);
+ dofile(L, null);
}
- lapi.lua_settop(L, 0); /* remove eventual returns */
}