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

View File

@@ -7,15 +7,22 @@ SYNOPSIS:
more [filename] more [filename]
]] ]]
local args = {...} local args = {...}
displayLineNo = true
local prompt = function() local prompt = function()
term.setForeCol(3) 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.setForeCol(1)
term.emit(18, 1, term.height()) term.emit(18, 1, term.height())
term.emit(29, 2, term.height()) term.emit(29, 2, term.height())
term.emit(81, 13, term.height()) term.emit(81, 13, term.height())
term.setForeCol(3) term.setForeCol(3)
term.setBackCol(0)
end end
local function printUsage() local function printUsage()
@@ -24,12 +31,29 @@ local function printUsage()
end end
if args[1] == nil or #args[1] <= 0 then printUsage() return 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 -- -- fetch text --
---------------- ----------------
local lines = {} lines = {}
local displayHeight = term.height() - 1 -- bottom one line for prompt displayHeight = term.height() - 1 -- bottom one line for prompt
local file = fs.open(args[1], "r") local file = fs.open(args[1], "r")
local line = "" local line = ""
@@ -38,31 +62,109 @@ repeat
table.insert(lines, line) table.insert(lines, line)
until line == nil 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 -- -- 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 if term.isTeletype() then
for _, l in ipairs(line) do for _, l in ipairs(line) do
term.print(l) term.print(l)
end end
else quit = true
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
end end
term.newLine()
term.clear()
term.setCursorBlink(false)
redrawText()
repeat
prompt()
term.setCursor(1, term.height())
processInput()
until quit
term.clearLine()
return return

View File

@@ -11,7 +11,8 @@ dirlist = {
"/usr", "/usr",
"/usr/bin", -- more utilities and binaries (e.g. less/more, nano) "/usr/bin", -- more utilities and binaries (e.g. less/more, nano)
"/home", -- home directory for user "/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 -- just make them if they don't exist
for _, dir in ipairs(dirlist) do 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 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 -- run default shell
fs.dofile(os.defaultshell) fs.dofile(os.defaultshell)

View File

@@ -8,5 +8,5 @@
See copyright information for the game you are actually playing. See copyright information for the game you are actually playing.
DESCRIPTION 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. a file user had put as an argument.

View File

@@ -24,7 +24,8 @@ end
fs.dofile = function(p, ...) fs.dofile = function(p, ...)
local f = fs.open(p, "r") local f = fs.open(p, "r")
local s = f.readAll() local s = f.readAll()
_G.runscript(s, "="..p, ...) f.close()
_G.runscript(s, p, ...)
end end
computer.realTime = function() return 0 end computer.realTime = function() return 0 end
@@ -726,7 +727,13 @@ end
local sandbox, libprocess local sandbox, libprocess
sandbox = { sandbox = {
assert = assert, 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, error = error,
_G = nil, -- see below _G = nil, -- see below
getmetatable = function(t) getmetatable = function(t)
@@ -747,7 +754,26 @@ sandbox = {
end end
return load(ld, source, mode, env or sandbox) return load(ld, source, mode, env or sandbox)
end, 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, next = next,
pairs = pairs, pairs = pairs,
pcall = function(...) pcall = function(...)
@@ -755,7 +781,7 @@ sandbox = {
checkDeadline() checkDeadline()
return table.unpack(result, 1, result.n) return table.unpack(result, 1, result.n)
end, end,
print = nil, -- in boot/*_base.lua print = _G.print, -- in boot/*_base.lua
rawequal = rawequal, rawequal = rawequal,
rawget = rawget, rawget = rawget,
rawlen = rawlen, rawlen = rawlen,
@@ -1019,7 +1045,7 @@ require("ROMLIB")
speaker.enqueue(80, computer.bellpitch) -- term.bell sometimes get squelched speaker.enqueue(80, computer.bellpitch) -- term.bell sometimes get squelched
-- load bios, if any -- 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. -- halt/run luaprompt upon the termination of bios.
-- Valid BIOS should load OS and modify 'shell.status' to 'shell.halt' before terminating itself. -- Valid BIOS should load OS and modify 'shell.status' to 'shell.halt' before terminating itself.

View File

@@ -6,7 +6,7 @@
-- ALIASES -- -- ALIASES --
------------- -------------
_G.io = {} _G.io = {} -- we make our own sandbox'd system
--[[fs.dofile = function(p, ...) --[[fs.dofile = function(p, ...)
local f = fs.open(p, "r") local f = fs.open(p, "r")
@@ -70,9 +70,42 @@ end
return key return key
end]] -- DELETED: use _G.input.isKeyDown(keycode) end]] -- DELETED: use _G.input.isKeyDown(keycode)
--- ---
-- IO IMPLEMENTATION --
--- ---
input.readLine = _G.__scanforline__ 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 -- -- PRINTSTREAM --
@@ -115,20 +148,26 @@ end
_G.shell = {} _G.shell = {}
shell.status = shell.ok 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 "#!" -- check for interpreter key "#!"
local f = fs.open(path, "r") local f = fs.open(path, "r")
local s = "" local s = f.readAll()
repeat f.close()
s = f.readLine()
if (s == nil) then return end -- empty file
until #s > 0
if s:sub(1,2) == "#!" then if s:sub(1,2) == "#!" then
local interpreter = s:sub(3) 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 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
end end
@@ -272,9 +311,9 @@ local keycodeNumToName = {
["200"] = "up", ["200"] = "up",
["201"] = "pageUp", ["201"] = "pageUp",
["203"] = "left", ["203"] = "left",
["208"] = "right", ["205"] = "right",
["207"] = "end", ["207"] = "end",
["205"] = "down", ["208"] = "down",
["209"] = "pageDown", ["209"] = "pageDown",
["210"] = "insert", ["210"] = "insert",
["211"] = "delete", ["211"] = "delete",
@@ -367,9 +406,9 @@ _G.keys = {
["up"] = 200, ["up"] = 200,
["pageUp"] = 201, ["pageUp"] = 201,
["left"] = 203, ["left"] = 203,
["right"] = 208, ["right"] = 205,
["end"] = 207, ["end"] = 207,
["down"] = 205, ["down"] = 208,
["pageDown"] = 209, ["pageDown"] = 209,
["insert"] = 210, ["insert"] = 210,
["delete"] = 211, ["delete"] = 211,