Somewhat less broken besh, but something's still not right...

This commit is contained in:
Florian Nücke 2014-04-24 21:35:17 +02:00
parent 8978280e3c
commit a9cf5b2da3

View File

@ -11,7 +11,11 @@ local term = require("term")
local text = require("text") local text = require("text")
local unicode = require("unicode") local unicode = require("unicode")
local function expandParam(param) -- Avoid scoping issues by simple forward declaring all methods... it's
-- not a beauty, but it works :P
local expand, expandCmd, expandMath, expandParam, parseCommand, parseCommands
expandParam = function(param)
local par, word, op = nil, nil, nil local par, word, op = nil, nil, nil
for _, oper in ipairs{':%-', '%-', ':=', '=', ':%?','%?', ':%+', '%+'} do for _, oper in ipairs{':%-', '%-', ':=', '=', ':%?','%?', ':%+', '%+'} do
par, word = param:match("(.-)"..oper.."(.*)") par, word = param:match("(.-)"..oper.."(.*)")
@ -86,11 +90,11 @@ local function expandParam(param)
end end
end end
local function expandCmd(cmd) expandCmd = function(cmd)
return cmd return cmd
end end
local function expandMath(expr) expandMath = function(expr)
local success, reason = load("return "..expr, os.getenv("SHELL"), 't', {}) local success, reason = load("return "..expr, os.getenv("SHELL"), 't', {})
if success then if success then
return success() return success()
@ -99,7 +103,7 @@ local function expandMath(expr)
end end
end end
local function expand(token) expand = function(token)
local expr = {} local expr = {}
local matchStack = {} local matchStack = {}
local escaped = false local escaped = false
@ -210,7 +214,7 @@ local function expand(token)
return table.concat(endToken) return table.concat(endToken)
end end
local function parseCommand(tokens) parseCommand = function(tokens)
if #tokens == 0 then if #tokens == 0 then
return return
end end
@ -263,14 +267,15 @@ local function parseCommand(tokens)
return nil, state return nil, state
end end
end end
return program, args, input, output, mode return program, args, input, output, mode
end end
local function parseCommands(command) parseCommands = function(command)
local tokens, reason = text.tokenize(command) local tokens, reason = text.tokenize(command)
if not tokens then if not tokens then
return nil, reason return nil, reason
elseif #tokens == 0 then
return true
end end
local commands, command = {}, {} local commands, command = {}, {}
@ -468,5 +473,48 @@ local function execute(command, env, ...)
return table.unpack(result, 1, result.n) return table.unpack(result, 1, result.n)
end end
local env = setmetatable({os=setmetatable({execute=execute}, {__index=os})}, {__index=_ENV}) local args, options = shell.parse(...)
shell.execute("/bin/sh", env, ...) local history = {}
if #args == 0 and (io.input() == io.stdin or options.i) and not options.c then
-- interactive shell.
while true do
if not term.isAvailable() then -- don't clear unless we lost the term
while not term.isAvailable() do
event.pull("term_available")
end
term.clear()
end
while term.isAvailable() do
local foreground = component.gpu.setForeground(0xFF0000)
term.write(expand(os.getenv("PS1") or "$ "))
component.gpu.setForeground(foreground)
local command = term.read(history)
if not command then
term.write("exit\n")
return -- eof
end
while #history > 10 do
table.remove(history, 1)
end
command = text.trim(command)
if command == "exit" then
return
elseif command ~= "" then
local result, reason = execute(command)
if not result then
io.stderr:write((tostring(reason) or "unknown error").. "\n")
elseif term.getCursor() > 1 then
term.write("\n")
end
end
end
end
else
-- execute command.
local result = table.pack(execute(...))
if not result[1] then
error(result[2])
end
return table.unpack(result, 2)
end