From 0abe3bf0522afe6c51b72dcc9dccdcf091d284b7 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Tue, 4 Oct 2016 01:38:08 +0900 Subject: [PATCH] dummix update Former-commit-id: 5a1a3c240fa0ec4cc20d384fc73f329967c72839 Former-commit-id: 2b641da84d742b381e86a060481d3a7cd9a7b66a --- .../assets/loots/dummix/bin/dsh.lua | 71 +++++---- .../assets/loots/dummix/bin/lessismore.lua | 146 +++++++++++++++--- .../assets/loots/dummix/etc/_boot.lua | 18 ++- .../assets/loots/dummix/usr/share/man/msh | 2 +- .../virtualcomputer/assets/lua/BOOT.lua | 36 ++++- .../virtualcomputer/assets/lua/ROMLIB.lua | 67 ++++++-- 6 files changed, 263 insertions(+), 77 deletions(-) mode change 100644 => 100755 src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/dsh.lua mode change 100644 => 100755 src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/lessismore.lua mode change 100644 => 100755 src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/etc/_boot.lua mode change 100644 => 100755 src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/usr/share/man/msh diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/dsh.lua b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/dsh.lua old mode 100644 new mode 100755 index c2092ce17..b680bc502 --- a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/dsh.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/dsh.lua @@ -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 \ No newline at end of file diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/lessismore.lua b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/lessismore.lua old mode 100644 new mode 100755 index 7d5878451..3e08e310b --- a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/lessismore.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/bin/lessismore.lua @@ -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 diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/etc/_boot.lua b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/etc/_boot.lua old mode 100644 new mode 100755 index 64a8a0f7b..d66a39acf --- a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/etc/_boot.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/etc/_boot.lua @@ -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) diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/usr/share/man/msh b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/usr/share/man/msh old mode 100644 new mode 100755 index 7e19e54d2..2aa7e18fc --- a/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/usr/share/man/msh +++ b/src/net/torvald/terrarum/virtualcomputer/assets/loots/dummix/usr/share/man/msh @@ -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. \ No newline at end of file diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/lua/BOOT.lua b/src/net/torvald/terrarum/virtualcomputer/assets/lua/BOOT.lua index 57ec92250..8500d8bf1 100644 --- a/src/net/torvald/terrarum/virtualcomputer/assets/lua/BOOT.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/lua/BOOT.lua @@ -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. diff --git a/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua b/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua index 12f76902c..fd78185fe 100644 --- a/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua +++ b/src/net/torvald/terrarum/virtualcomputer/assets/lua/ROMLIB.lua @@ -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,