dummix update

Former-commit-id: 5a1a3c240fa0ec4cc20d384fc73f329967c72839
Former-commit-id: 2b641da84d742b381e86a060481d3a7cd9a7b66a
This commit is contained in:
Song Minjae
2016-10-04 01:38:08 +09:00
parent a4a9c037a6
commit 0abe3bf052
6 changed files with 263 additions and 77 deletions

View File

@@ -30,28 +30,20 @@ local function endsWithSlash(p)
return p:byte(#p) == 47
end
local function errorCmdNotFound(cmd)
print(cmd..": command not found")
end
local function errorNoSuchFile(cmd)
print(cmd..": No such file")
end
local function errorNoSuchFileOrDir(cmd)
print(cmd..": No such file or directory")
end
--local __DSHDEBUG__ = 0x51621D
__DSHDEBUG__ = 0x51621D
local function debug(msg)
if __DSHDEBUG__ then print("DEBUG", msg) end
end
local function printErr(msg)
print(DLE..msg)
end
-- BUILTINS -------------------------------------------------------------------
local function cd(args)
local dir = args[1]
local function cd(tArgs)
local dir = tArgs[1]
if (dir == nil or #dir < 1) then return end
@@ -60,7 +52,7 @@ local function cd(args)
local chkdir = expandPath(dir)
if not fs.exists(chkdir) then
errorNoSuchFileOrDir("cd: "..dir)
os.errorNoSuchFileOrDir("cd: "..dir)
return
end
@@ -86,25 +78,24 @@ local function cd(args)
end
end
local function exit(args)
local function exit(tArgs)
exitshell = true
end
local function exec(args)
--debug("EXEC\t"..table.concat(args, " "))
local function exec(tArgs)
debug("EXECARGS\t"..table.concat(tArgs, ", "))
if (args[1] == nil or #args[1] < 1) then return end
if (tArgs[1] == nil or #tArgs[1] < 1) then return end
local filePath = args[1]
local fullFilePath = expandPath(args[1])
local filePath = tArgs[1]
local fullFilePath = expandPath(tArgs[1])
local execArgs = {}
for i, v in ipairs(args) do
for i, v in ipairs(tArgs) do
if (i >= 2) then table.insert(execArgs, v) end
end
local execByPathFileExists = false
local execByPathArg = ""
--fs.dofile(fullFilePath, execArgs)
-- do some sophisticated file-matching
-- step 1: exact file
if fs.isFile(fullFilePath) then shell.run(fullFilePath, execArgs)
@@ -137,9 +128,9 @@ local function exec(args)
return EXIT_SUCCESS
else
if filePath:byte(1) == 46 or filePath:byte(1) == 47 then
errorNoSuchFile(filePath)
os.errorNoSuchFile(filePath)
else
errorCmdNotFound(filePath)
os.errorCmdNotFound(filePath)
end
end
@@ -156,9 +147,11 @@ local builtins = {
clear = term.clear
}
local function runcommand(str)
local function runcommand(str, recurse)
if #str < 1 then return end
local cmdFound = false
-- simple cmd parse: WORD ARG1 ARG2 ARG3 ...
local args = {}
local command = ""
@@ -169,20 +162,30 @@ local function runcommand(str)
if builtins[command] then -- try for builtins table
builtins[command](args)
return EXIT_SUCCESS
cmdFound = true
return true
else
-- FIXME: 'exec programname args' works, but not 'programname args'
-- try for os.dshenv.aliases
if os.dshenv.aliases[command] then
--builtins[os.dshenv.aliases[command]](args)
runcommand(os.dshenv.aliases[command])
return EXIT_SUCCESS
if not recurse then
cmdFound = runcommand(os.dshenv.aliases[command], true)
end
else
-- try to launch as program
table.insert(args, 1, command)
exec(args)
if not recurse then
cmdFound = runcommand("exec "..str, true)
end
end
end
-- command not found (really)
if not cmdFound then
os.errorCmdNotFound(command)
end
end
-- END OF SYNTAX PARSER -------------------------------------------------------
@@ -235,11 +238,11 @@ local time = os.date()
print(time)
repeat
term.setCursorBlink(true)
io.write(getPromptText())
local s = input.readLine()
runcommand(s)
until exitshell
::terminate::
collectgarbage()
return EXIT_SUCCESS
return EXIT_SUCCESS

View File

@@ -7,15 +7,22 @@ SYNOPSIS:
more [filename]
]]
local args = {...}
displayLineNo = true
local prompt = function()
term.setForeCol(3)
term.emitString("scroll", 4, term.height())
term.emitString("quit", 15, term.height())
term.emitString(" scroll ", 3, term.height())
term.emitString(" quit", 14, term.height())
term.setForeCol(1)
term.emit(18, 1, term.height())
term.emit(29, 2, term.height())
term.emit(81, 13, term.height())
term.setForeCol(3)
term.setBackCol(0)
end
local function printUsage()
@@ -24,12 +31,29 @@ local function printUsage()
end
if args[1] == nil or #args[1] <= 0 then printUsage() return end
if not fs.exists(args[1]) then os.errorNoSuchFileOrDir(args[1]) return end
if not fs.isFile(args[1]) then os.errorIsDir(args[1]) return end
function log10(n)
if n < 1 then return 0
elseif n < 10 then return 1
elseif n < 100 then return 2
elseif n < 1000 then return 3
elseif n < 10000 then return 4
elseif n < 100000 then return 5
elseif n < 1000000 then return 6
elseif n < 10000000 then return 7
elseif n < 100000000 then return 8
elseif n < 1000000000 then return 9
else return 10
end
end
----------------
-- fetch text --
----------------
local lines = {}
local displayHeight = term.height() - 1 -- bottom one line for prompt
lines = {}
displayHeight = term.height() - 1 -- bottom one line for prompt
local file = fs.open(args[1], "r")
local line = ""
@@ -38,31 +62,109 @@ repeat
table.insert(lines, line)
until line == nil
lineNoLen = log10(#lines)
-----------
-- input --
-----------
local function scrollDownAction(n)
term.clearLine() -- prevent prompt to be scrolled
curY = curY + n
-- prevent overscroll
if (curY > #lines - displayHeight) then
curY = #lines - displayHeight
end
term.scroll(n)
for i = 0, n - 1 do
drawString(curY + displayHeight - i, displayHeight - i) -- redraw newline
end
end
local function scrollUpAction(n)
curY = curY - n
-- prevent overscroll
if (curY < 1) then
curY = 1
end
term.scroll(-n)
for i = 0, n - 1 do
drawString(curY + i, i + 1) -- redraw prev line
end
term.setCursor(n, term.height())
end
local function processInput()
if input.isKeyDown(keys.q) then quit = true end
if input.isKeyDown(keys.down) and curY < #lines - displayHeight then
scrollDownAction(1)
prompt()
elseif input.isKeyDown(keys.pageDown) and curY < #lines - displayHeight then
scrollDownAction(8)
prompt()
elseif input.isKeyDown(keys.up) and curY > 1 then
scrollUpAction(1)
term.clearLine() -- make space for prompt
prompt()
elseif input.isKeyDown(keys.pageUp) and curY > 1 then
scrollUpAction(8)
term.clearLine() -- make space for prompt
prompt()
end
machine.sleep(50)
end
-------------
-- display --
-------------
displayWidth = term.width() - 1 - (displayLineNo and lineNoLen or 0)
function drawString(lineNo, y)
local string = (lineNo > #lines) and ""
or lines[lineNo]:sub(curX, curX + displayWidth)
if (displayLineNo) then
local lineNoStr = DC3..string.format("%"..lineNoLen.."d", curY + y - 1)..DC4
string = lineNoStr..string
end
local strDrawX = curX
term.emitString(string, strDrawX, y)
end
function redrawText()
for i = curY, #lines do
if (i >= displayHeight + curY) then break end
drawString(i, i - curY + 1)
end
end
curY = 1
curX = 1
quit = false
if term.isTeletype() then
for _, l in ipairs(line) do
term.print(l)
end
else
term.clear()
term.setCursorBlink(false)
local key = 0
repeat
prompt()
for i, line in ipairs(lines) do
if (i > displayHeight) then break end
term.emitString(line, 1, i)
end
term.setCursor(1, term.height())
if input.isKeyDown(keys.q) then break end
until false
quit = true
end
term.newLine()
term.clear()
term.setCursorBlink(false)
redrawText()
repeat
prompt()
term.setCursor(1, term.height())
processInput()
until quit
term.clearLine()
return

View File

@@ -11,7 +11,8 @@ dirlist = {
"/usr",
"/usr/bin", -- more utilities and binaries (e.g. less/more, nano)
"/home", -- home directory for user
"/home/bin" -- user-installed apps
"/home/bin", -- user-installed apps
"/media" -- auto mounts (e.g. "/media/fd1", "/media/hdb", "/media/sda")
}
-- just make them if they don't exist
for _, dir in ipairs(dirlist) do
@@ -43,6 +44,21 @@ os.defaultshell = "/bin/dsh.lua"
os.clock = function() return machine.milliTime() / 1000 end -- uptime of the computer, in seconds
function os.errorCmdNotFound(cmd)
print(cmd..": command not found")
end
function os.errorNoSuchFile(cmd)
print(cmd..": No such file")
end
function os.errorNoSuchFileOrDir(cmd)
print(cmd..": No such file or directory")
end
function os.errorIsDir(cmd)
print(cmd.." is a directory")
end
-- run default shell
fs.dofile(os.defaultshell)

View File

@@ -8,5 +8,5 @@
See copyright information for the game you are actually playing.
DESCRIPTION
Moonshell is a Lua prompt that reads lua script from the user, or execute
Msh is a Lua prompt that reads lua script from the user, or execute
a file user had put as an argument.

View File

@@ -24,7 +24,8 @@ end
fs.dofile = function(p, ...)
local f = fs.open(p, "r")
local s = f.readAll()
_G.runscript(s, "="..p, ...)
f.close()
_G.runscript(s, p, ...)
end
computer.realTime = function() return 0 end
@@ -726,7 +727,13 @@ end
local sandbox, libprocess
sandbox = {
assert = assert,
dofile = nil, -- in boot/*_base.lua
dofile = function(filename)
local program, reason = loadfile(filename)
if not program then
return error(reason .. ':' .. filename, 0)
end
return program()
end, -- in boot/*_base.lua
error = error,
_G = nil, -- see below
getmetatable = function(t)
@@ -747,7 +754,26 @@ sandbox = {
end
return load(ld, source, mode, env or sandbox)
end,
loadfile = nil, -- in boot/*_base.lua
loadfile = function(filename, mode, env)
local file, reason = io.open(filename)
if not file then
return nil, reason
end
local source, reason = file:read("*a")
file:close()
if not source then
return nil, reason
end
if string.sub(source, 1, 1) == "#" then
local endline = string.find(source, "\n", 2, true)
if endline then
source = string.sub(source, endline + 1)
else
source = ""
end
end
return load(source, "=" .. filename, mode, env)
end, -- in boot/*_base.lua
next = next,
pairs = pairs,
pcall = function(...)
@@ -755,7 +781,7 @@ sandbox = {
checkDeadline()
return table.unpack(result, 1, result.n)
end,
print = nil, -- in boot/*_base.lua
print = _G.print, -- in boot/*_base.lua
rawequal = rawequal,
rawget = rawget,
rawlen = rawlen,
@@ -1019,7 +1045,7 @@ require("ROMLIB")
speaker.enqueue(80, computer.bellpitch) -- term.bell sometimes get squelched
-- load bios, if any
if fs.exists(computer.bootloader) then shell.run(computer.bootloader) end
if fs.exists(computer.bootloader) then fs.dofile(computer.bootloader) end
-- halt/run luaprompt upon the termination of bios.
-- Valid BIOS should load OS and modify 'shell.status' to 'shell.halt' before terminating itself.

View File

@@ -6,7 +6,7 @@
-- ALIASES --
-------------
_G.io = {}
_G.io = {} -- we make our own sandbox'd system
--[[fs.dofile = function(p, ...)
local f = fs.open(p, "r")
@@ -70,9 +70,42 @@ end
return key
end]] -- DELETED: use _G.input.isKeyDown(keycode)
--- ---
-- IO IMPLEMENTATION --
--- ---
input.readLine = _G.__scanforline__
io.read = _G.__scanforline__
io.__openfile__ = "stdin"
io.stdin = "stdin"
io.stdout = "stdout"
io.stderr = "stderr"
io.open = fs.open
io.input = function(luafile)
io.__openfile__ = luafile
end
io.read = function(option)
if io.__openfile__ == "stdin" then
return _G.__scanforline__()
end
function _readAll()
return io.__openfile__.readAll()
end
function _readLine()
return io.__openfile__.readLine()
end
options = {}
options["*n"] = function() error("Read number is not supported, yet!") end--_readNumber
options["*a"] = _readAll
options["*l"] = _readLine
end
-----------------
-- PRINTSTREAM --
@@ -115,20 +148,26 @@ end
_G.shell = {}
shell.status = shell.ok
shell.run = function(path)
-- run a script with path (string) and argstable (table)
shell.run = function(path, argstable)
-- check for interpreter key "#!"
local f = fs.open(path, "r")
local s = ""
repeat
s = f.readLine()
if (s == nil) then return end -- empty file
until #s > 0
local s = f.readAll()
f.close()
if s:sub(1,2) == "#!" then
local interpreter = s:sub(3)
fs.dofile(interpreter..".lua", path)
if not argstable then
xpcall(function() fs.dofile(interpreter..".lua", path) end, function(err) print(DLE..err) end)
else
xpcall(function() fs.dofile(interpreter..".lua", path, table.unpack(argstable)) end, function(err) print(DLE..err) end)
end
else
fs.dofile(path)
if not argstable then
xpcall(function() fs.dofile(path) end, function(err) print(DLE..err) end)
else
xpcall(function() fs.dofile(path, table.unpack(argstable)) end, function(err) print(DLE..err) end)
end
end
end
@@ -272,9 +311,9 @@ local keycodeNumToName = {
["200"] = "up",
["201"] = "pageUp",
["203"] = "left",
["208"] = "right",
["205"] = "right",
["207"] = "end",
["205"] = "down",
["208"] = "down",
["209"] = "pageDown",
["210"] = "insert",
["211"] = "delete",
@@ -367,9 +406,9 @@ _G.keys = {
["up"] = 200,
["pageUp"] = 201,
["left"] = 203,
["right"] = 208,
["right"] = 205,
["end"] = 207,
["down"] = 205,
["down"] = 208,
["pageDown"] = 209,
["insert"] = 210,
["delete"] = 211,