OctOS: Add command framework

Documented in commands.md and applications.md.
master
octacian 2017-03-28 16:23:49 -07:00
parent a32178ae55
commit 9ec3d9e76f
12 changed files with 112 additions and 23 deletions

View File

@ -0,0 +1,16 @@
# Applications with OctOS
OctOS has a simple framework to allow the player to easily create their own programs for their computers. All you have to do, is place a file in the `bin` directory to tell OctOS about your application, while the code is typically placed in `exec`.
Files in `bin` do not have to follow any naming convention and typically do not even have an extension. They are formatted as shown below, `name` and `exec` being the only required fields. If `name` is not defined, the file name will be used.
```
name = <name>
description = <description>
exec = <path to code (e.g. os/exec/help.lua)>
```
Files in `exec` should be referenced by a file in `bin`. Any parameters provided when executing the command will be provided to the file and can be retrieved from the `...` variable, as shown below.
```lua
local params = ...
```

10
doc/computers/commands.md Normal file
View File

@ -0,0 +1,10 @@
# OctOS Commands
OctOS is the operating system used by digicomputers. OctOS is made of many Linux-like commands which are documented under the Commands section, however, there is also an API which can be used when writing programs for OctOS which is documented in `os_api.md`. Available commands are documented below.
#### `help [command, "all"]`
Shows help about the command specified or all commands if `all` is specified.
#### `lua [code]`
Runs Lua code from the command line under the secure environment.

View File

@ -1,5 +1,5 @@
# Computer OS API
This API can be used by players to interact with the computer under a safe and secure environment. The documentation is divided into two sections as is the code, main (for general functions), and filesystem (for filesystem access).
# OctOS
OctOS is the operating system used by digicomputers. OctOS is made of many Linux-like commands which are documented in `commands.md`, however, there is also an API which can be used when writing programs for OctOS. The API can be used by players to interact with the computer under a safe and secure environment. The documentation is divided into two sections as is the code, main (for general functions), and filesystem (for filesystem access).
## Main
This contains a set of functions mainly for the purpose of interacting with the computer's displays.

View File

@ -95,7 +95,7 @@ function digicompute.env()
end
-- [function] run code
function digicompute.run_code(code, env)
function digicompute.run_code(code, env, ...)
if code:byte(1) == 27 then
return nil, "Binary code prohibited."
end
@ -114,15 +114,15 @@ function digicompute.run_code(code, env)
debug.sethook(function()
error("Code timed out!", 2)
end, "", 10000)
local ok, ret = pcall(f)
local ok, ret = pcall(f, ...)
debug.sethook() -- Clear hook
if not ok then return false, ret end
return true, ret
end
-- [function] run file
function digicompute.run_file(path, env)
function digicompute.run_file(path, env, ...)
local code = digicompute.builtin.read(path)
local ok, res = digicompute.run_code(code, env)
local ok, res = digicompute.run_code(code, env, ...)
return ok, res
end

View File

@ -439,7 +439,8 @@ function digicompute.c:make_env(pos, player)
end
-- [function] get userdata value
function main.get_userdata(key)
return minetest.deserialize(meta:get_string("userdata"))[key] or nil
local res = meta:get_string("userdata")
return minetest.deserialize(res)[key] or nil
end
-- [function] set userdata value
function main.set_userdata(key, value)
@ -452,8 +453,12 @@ function digicompute.c:make_env(pos, player)
return digicompute.c:open(pos, minetest.get_player_by_name(meta:get_string("current_user")))
end
-- [function] run code
function main.run(code)
return digicompute.c:run_code(pos, player, code)
function main.run(code, ...)
return digicompute.c:run_code(pos, player, code, ...)
end
-- [function] loadstring
function main.loadstring(string)
return loadstring(string)
end
-- Filesystem Environment Functions
@ -505,8 +510,8 @@ function digicompute.c:make_env(pos, player)
return digicompute.builtin.cpdir(cpath..original, cpath..new)
end
-- [function] run file
function fs.run(path)
return digicompute.c:run_file(pos, player, path)
function fs.run(path, ...)
return digicompute.c:run_file(pos, player, path, ...)
end
-- [function] Settings
function main.Settings(path)
@ -530,17 +535,17 @@ function digicompute.c:make_env(pos, player)
end
-- [function] run code
function digicompute.c:run_code(pos, player, code)
function digicompute.c:run_code(pos, player, code, ...)
local env = digicompute.c:make_env(pos, player)
local ok, res = digicompute.run_code(code, env)
local ok, res = digicompute.run_code(code, env, ...)
return ok, res
end
-- [function] run file
function digicompute.c:run_file(pos, player, path)
function digicompute.c:run_file(pos, player, path, ...)
local path = minetest.get_meta(pos):get_string("path")..path
local env = digicompute.c:make_env(pos, player)
local ok, res = digicompute.run_file(path, env)
local ok, res = digicompute.run_file(path, env, ...)
return ok, res
end
@ -570,7 +575,7 @@ function digicompute.register_computer(itemstring, def)
meta:set_string("input", "") -- Initialize input buffer
meta:set_string("output", "") -- Initialize output buffer
meta:set_string("os", "") -- Initialize OS table
meta:set_string("userspace", "") -- Initialize userspace table
meta:set_string("userdata", "") -- Initialize userdata table
meta:set_string("help", "Type a command and press enter.") -- Initialize help
digicompute.c:new_id(pos) -- Set up ID

3
octos/bin/help Normal file
View File

@ -0,0 +1,3 @@
name = help
description = Show help information
exec = os/exec/help.lua

3
octos/bin/lua Normal file
View File

@ -0,0 +1,3 @@
name = lua
description = Execute Lua code
exec = os/exec/lua.lua

12
octos/exec/help.lua Normal file
View File

@ -0,0 +1,12 @@
-- cmd: help --
local params = ...
local bin = get_userdata("bin")
if params[1] == "all" then
for name, info in pairs(bin) do
print(name..": "..info.description)
end
else
print("Specify a command to get help for or use help all to view help for all commands.")
end

8
octos/exec/lua.lua Normal file
View File

@ -0,0 +1,8 @@
local params = ...
local code = (table.concat(params, " "))
local res = run(code)
if not res then
print("Error: Could not run `"..code.."`")
end

0
octos/exec/nil Normal file
View File

View File

@ -1,12 +1,25 @@
local input = get_attr("input")
local input = get_attr("input"):split(" ")
local bin = get_userdata("bin")
if input ~= "" then
print(input, false) -- print input
if input[1] ~= "" then
print(get_attr("input"), false)
local ok, res = run(input)
if res then print(res) end
local binentry = bin[input[1]]
print(get_os("prefix")) -- Print prefix
if binentry then
-- Remove first param
table.remove(input, 1)
fs.run(binentry.exec, input)
else
print(input[1]..": command not found")
end
print(get_os("prefix"))
-- Clear input
set_input("")
refresh() -- refresh
-- Refresh view
refresh()
end

View File

@ -4,6 +4,25 @@ set_os("off", "shutdown")
set_os("reboot", "shutdown -r")
set_os("prefix", get_attr("name")..":~$ ")
-- Initialize bin table
local bin = {}
-- Load bin file
local bin_contents = fs.list("os/bin")
for _,f in ipairs(bin_contents.files) do
local fpath = "os/bin/"..f
local cmd_info = Settings(fpath):to_table()
local name = cmd_info.name or f
bin[name] = {
description = cmd_info.description or "",
exec = cmd_info.exec or "os/exec/nil"
}
end
-- Save bin table
set_userdata("bin", bin)
-- Set initial output value
set_output("Welcome to octOS version 0.2.\n\n"..get_os("prefix")) -- print welcome