Index: head/stand/common/interp_lua.c =================================================================== --- head/stand/common/interp_lua.c +++ head/stand/common/interp_lua.c @@ -128,7 +128,7 @@ int interp_run(const char *line) { - int argc; + int argc, nargc; char **argv; lua_State *luap; struct interp_lua_softc *softc = &lua_softc; @@ -137,19 +137,39 @@ luap = softc->luap; LDBG("executing line..."); if ((status = luaL_dostring(luap, line)) != 0) { + lua_pop(luap, 1); /* - * If we could not parse the line as Lua syntax, - * try parsing it as a loader command. + * The line wasn't executable as lua; run it through parse to + * to get consistent parsing of command line arguments, then + * run it through cli_execute. If that fails, then we'll try it + * as a builtin. */ - lua_pop(luap, 1); if (parse(&argc, &argv, line) == 0) { - status = interp_builtin_cmd(argc, argv); - if (status != CMD_OK) + lua_getglobal(luap, "cli_execute"); + for (nargc = 0; nargc < argc; ++nargc) { + lua_pushstring(luap, argv[nargc]); + } + status = lua_pcall(luap, argc, 1, 0); + lua_pop(luap, 1); + if (status != 0) { + /* + * Lua cli_execute will pass the function back + * through loader.command, which is a proxy to + * interp_builtin_cmd. If we failed to interpret + * the command, though, then there's a chance + * that didn't happen. Call interp_builtin_cmd + * directly if our lua_pcall was not successful. + */ + status = interp_builtin_cmd(argc, argv); + } + if (status != 0) { printf("Command failed\n"); + status = CMD_ERROR; + } free(argv); } else { printf("Failed to parse \'%s\'\n", line); - status = -1; + status = CMD_ERROR; } } Index: head/stand/lua/loader.lua =================================================================== --- head/stand/lua/loader.lua +++ head/stand/lua/loader.lua @@ -1,5 +1,6 @@ -- -- Copyright (c) 2015 Pedro Souza +-- Copyright (c) 2018 Kyle Evans -- All rights reserved. -- -- Redistribution and use in source and binary forms, with or without @@ -29,6 +30,24 @@ config = require("config"); menu = require("menu"); password = require("password"); + +-- Declares a global function cli_execute that attempts to dispatch the +-- arguments passed as a lua function. This gives lua a chance to intercept +-- builtin CLI commands like "boot" +function cli_execute(...) + local cmd_name, cmd_args = ...; + local cmd = _G[cmd_name]; + if (cmd ~= nil) and (type(cmd) == "function") then + -- Pass argv wholesale into cmd. We could omit argv[0] since the + -- traditional reasons for including it don't necessarily apply, + -- it may not be totally redundant if we want to have one global + -- handling multiple commands + cmd(...); + else + loader.command(...); + end + +end config.load(); password.check();