mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 03:05:30 -04:00
Merge branch 'master-MC1.7.10' of github.com:MightyPirates/OpenComputers into master-MC1.8.9
This commit is contained in:
commit
82970cc92f
@ -286,7 +286,7 @@ minecraft {
|
||||
mappings = "stable_22"
|
||||
|
||||
replace "@VERSION@", project.simpleVersion
|
||||
replace "@MCVERSION@", config.minecraft.version
|
||||
replace "/*@MCVERSIONDEP@*/", ", acceptedMinecraftVersions = \"[${config.minecraft.version},${config.minecraft.version}+)\""
|
||||
}
|
||||
|
||||
processResources {
|
||||
|
@ -13,9 +13,14 @@ for i = 1, #args do
|
||||
io.stderr:write(string.format('cat %s: Is a directory\n', arg))
|
||||
ec = 1
|
||||
else
|
||||
local file, reason = args[i] == "-" and io.stdin or io.open(shell.resolve(args[i]))
|
||||
local file, reason
|
||||
if args[i] == "-" then
|
||||
file, reason = io.stdin, "missing stdin"
|
||||
else
|
||||
file, reason = io.open(shell.resolve(args[i]))
|
||||
end
|
||||
if not file then
|
||||
io.stderr:write(string.format("cat: %s: %s\n",args[i],tostring(reason)))
|
||||
io.stderr:write(string.format("cat: %s: %s\n", args[i], tostring(reason)))
|
||||
ec = 1
|
||||
else
|
||||
repeat
|
||||
|
@ -148,12 +148,14 @@ end
|
||||
local to = shell.resolve(args[#args])
|
||||
|
||||
for i = 1, #args - 1 do
|
||||
local fromPath, cuts = args[i]:gsub("(/%.%.?)$", "%1")
|
||||
fromPath = shell.resolve(fromPath)
|
||||
local arg = args[i]
|
||||
local fromPath = shell.resolve(arg)
|
||||
-- a "contents of" copy is where src path ends in . or ..
|
||||
-- a source path ending with . is not sufficient - could be the source filename
|
||||
local contents_of = arg:match("%.$") and not fromPath:match("%.$")
|
||||
local toPath = to
|
||||
-- fromPath ending with /. indicates copying the contents of fromPath
|
||||
-- in which case (cuts>0) we do not append fromPath name to toPath
|
||||
if cuts == 0 and fs.isDirectory(toPath) then
|
||||
-- we do not append fromPath name to toPath in case of contents_of copy
|
||||
if not contents_of and fs.isDirectory(toPath) then
|
||||
toPath = fs.concat(toPath, fs.name(fromPath))
|
||||
end
|
||||
result, reason = recurse(fromPath, toPath)
|
||||
|
@ -19,7 +19,7 @@ for i = 1, #args do
|
||||
reason = "unknown reason"
|
||||
end
|
||||
end
|
||||
io.stderr:write(path .. ": " .. reason .. "\n")
|
||||
io.stderr:write("mkdir: cannot create directory '" .. tostring(args[i]) .. "': " .. reason .. "\n")
|
||||
ec = 1
|
||||
end
|
||||
end
|
||||
|
@ -1,12 +1,12 @@
|
||||
local fs = require("filesystem")
|
||||
local guid = require("guid")
|
||||
local uuid = require("uuid")
|
||||
local shell = require("shell")
|
||||
local sh = require("sh")
|
||||
|
||||
local touch = loadfile(shell.resolve("touch", "lua"))
|
||||
local mkdir = loadfile(shell.resolve("mkdir", "lua"))
|
||||
|
||||
if not guid or not touch then
|
||||
if not uuid or not touch then
|
||||
local errorMessage = "missing tools for mktmp"
|
||||
io.stderr:write(errorMessage .. '\n')
|
||||
return false, errorMessage
|
||||
@ -58,7 +58,7 @@ if not fs.exists(prefix) then
|
||||
end
|
||||
|
||||
while true do
|
||||
local tmp = prefix .. guid.next()
|
||||
local tmp = prefix .. uuid.next()
|
||||
if not fs.exists(tmp) then
|
||||
|
||||
local ok, reason
|
||||
|
@ -1,6 +1,7 @@
|
||||
require("filesystem").mount(
|
||||
setmetatable({
|
||||
isReadOnly = function()return false end
|
||||
isReadOnly = function()return false end,
|
||||
address = require("uuid").next()
|
||||
},
|
||||
{
|
||||
__index=function(tbl,key)return require("devfs")[key]end
|
||||
|
@ -1,111 +1,292 @@
|
||||
local fs = require("filesystem")
|
||||
local comp = require("component")
|
||||
|
||||
local proxy = {points={},address=require("guid").next()}
|
||||
local function new_node(parent, name, is_dir, proxy)
|
||||
local node = {parent=parent, name=name, is_dir=is_dir, proxy=proxy}
|
||||
if not proxy then
|
||||
node.children = {}
|
||||
end
|
||||
return node
|
||||
end
|
||||
|
||||
local nop = function()end
|
||||
local function new_devfs_dir(name)
|
||||
local sys = {}
|
||||
sys.mtab = new_node(nil, name or "/", true)
|
||||
|
||||
function proxy.getLabel()
|
||||
-- returns: dir, point or path
|
||||
-- node (table): the handler responsible for the path
|
||||
-- this is essentially the device filesystem that is registered for the given path
|
||||
-- point (string): the point name (like a file name)
|
||||
function sys.findNode(path, create)
|
||||
checkArg(1, path, "string")
|
||||
local segments = fs.segments(path)
|
||||
local node = sys.mtab
|
||||
while #segments > 0 do
|
||||
local name = table.remove(segments, 1)
|
||||
local prev_path = path
|
||||
path = table.concat(segments, "/")
|
||||
|
||||
if not node.children[name] then
|
||||
if not create then
|
||||
path = prev_path
|
||||
break
|
||||
end
|
||||
node.children[name] = new_node(node, name, true, false)
|
||||
end
|
||||
|
||||
node = node.children[name]
|
||||
|
||||
if node.proxy then -- if there is a proxy handler we stop searching here
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- only dirs can have trailing path
|
||||
-- trailing path on a dev point (file) not allowed
|
||||
if path == "" or node.is_dir and node.proxy then
|
||||
return node, path
|
||||
end
|
||||
end
|
||||
|
||||
function sys.invoke(method, path, ...)
|
||||
local node, rest = sys.findNode(path)
|
||||
if not node or -- not found
|
||||
rest == "" and node.is_dir or -- path is dir
|
||||
not node.proxy[method] then -- optional method
|
||||
return 0
|
||||
end
|
||||
-- proxy could be a file, which doesn't take an argument, but it can be ignored if passed
|
||||
return node.proxy[method](rest)
|
||||
end
|
||||
|
||||
function sys.size(path)
|
||||
return sys.invoke("size", path)
|
||||
end
|
||||
|
||||
function sys.lastModified(path)
|
||||
return sys.invoke("lastModified", path)
|
||||
end
|
||||
|
||||
function sys.isDirectory(path)
|
||||
local node, rest = sys.findNode(path)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
|
||||
if rest == "" then
|
||||
return node.is_dir
|
||||
elseif node.proxy then
|
||||
return node.proxy.isDirectory(rest)
|
||||
end
|
||||
end
|
||||
|
||||
function sys.open(path, mode)
|
||||
checkArg(1, path, "string")
|
||||
checkArg(2, mode, "string", "nil")
|
||||
|
||||
if not sys.exists(path) then
|
||||
return nil, path.." file not found"
|
||||
elseif sys.isDirectory(path) then
|
||||
return nil, path.." is a directory"
|
||||
end
|
||||
|
||||
mode = mode or "r"
|
||||
-- everything at this level should be a binary open
|
||||
mode = mode:gsub("b", "")
|
||||
|
||||
if not ({a=true,w=true,r=true})[mode] then
|
||||
return nil, "invalid mode"
|
||||
end
|
||||
|
||||
local node, rest = sys.findNode(path)
|
||||
-- there must be a node, else exists would have failed
|
||||
|
||||
local args = {}
|
||||
if rest ~= "" then
|
||||
-- having more rest means we expect the proxy fs to open the point
|
||||
args[1] = rest
|
||||
end
|
||||
args[#args+1] = mode
|
||||
|
||||
return node.proxy.open(table.unpack(args))
|
||||
end
|
||||
|
||||
function sys.list(path)
|
||||
local node, rest = sys.findNode(path)
|
||||
if not node or (rest ~= "" and not node.is_dir) then-- not found
|
||||
return {}
|
||||
elseif rest == "" and not node.is_dir then -- path is file
|
||||
return {path}
|
||||
elseif node.proxy then
|
||||
-- proxy could be a file, which doesn't take an argument, but it can be ignored if passed
|
||||
return node.proxy.list(rest)
|
||||
end
|
||||
|
||||
-- rest == "" and node.is_dir
|
||||
local keys = {}
|
||||
for k in pairs(node.children) do
|
||||
table.insert(keys, k)
|
||||
end
|
||||
return keys
|
||||
end
|
||||
|
||||
function sys.remove(path)
|
||||
checkArg(1, path, "string")
|
||||
|
||||
if path == "" then
|
||||
return nil, "no such file or directory"
|
||||
end
|
||||
|
||||
if not sys.exists(path) then
|
||||
return nil, path.." file not found"
|
||||
end
|
||||
|
||||
local node, rest = sys.findNode(path)
|
||||
|
||||
if rest ~= "" then -- if rest is not resolved, this isn't our path
|
||||
return node.proxy.remove(rest)
|
||||
end
|
||||
|
||||
node.parent.children[node.name] = nil
|
||||
end
|
||||
|
||||
function sys.exists(path)
|
||||
checkArg(1, path, "string")
|
||||
local node, rest = sys.findNode(path)
|
||||
|
||||
if not node then
|
||||
return false
|
||||
elseif rest == "" then
|
||||
return true
|
||||
else
|
||||
return node.proxy.exists(rest)
|
||||
end
|
||||
end
|
||||
|
||||
function sys.create(path, handler)
|
||||
if sys.exists(path) then
|
||||
return nil, "path already exists"
|
||||
end
|
||||
|
||||
local segments = fs.segments(path)
|
||||
local target = table.remove(segments)
|
||||
path = table.concat(segments, "/")
|
||||
|
||||
if not target or target == "" then
|
||||
return nil, "missing argument"
|
||||
end
|
||||
|
||||
local node, rest = sys.findNode(path, true)
|
||||
if rest ~= "" then
|
||||
return node.proxy.create(rest, handler)
|
||||
end
|
||||
node.children[target] = new_node(node, target, not not handler.list, handler)
|
||||
return true
|
||||
end
|
||||
|
||||
return sys
|
||||
end
|
||||
|
||||
local devfs = new_devfs_dir()
|
||||
|
||||
local bfd = "bad file descriptor"
|
||||
|
||||
function devfs.getLabel()
|
||||
return "devfs"
|
||||
end
|
||||
|
||||
function proxy.setLabel(value)
|
||||
function devfs.setLabel(value)
|
||||
error("drive does not support labeling")
|
||||
end
|
||||
|
||||
function proxy.spaceTotal()
|
||||
function devfs.spaceTotal()
|
||||
return 0
|
||||
end
|
||||
|
||||
function proxy.spaceUsed()
|
||||
function devfs.spaceUsed()
|
||||
return 0
|
||||
end
|
||||
|
||||
function proxy.exists(path)
|
||||
return not not proxy.points[path]
|
||||
function devfs.makeDirectory(path)
|
||||
return false, "to create dirs in devfs use devfs.create"
|
||||
end
|
||||
|
||||
function proxy.size(path)
|
||||
return 0
|
||||
end
|
||||
|
||||
function proxy.isDirectory(path)
|
||||
return false
|
||||
end
|
||||
|
||||
function proxy.lastModified(path)
|
||||
return fs.lastModified("/dev/")
|
||||
end
|
||||
|
||||
function proxy.list()
|
||||
local keys = {}
|
||||
for k,v in pairs(proxy.points) do
|
||||
table.insert(keys, k)
|
||||
end
|
||||
return keys
|
||||
end
|
||||
|
||||
function proxy.makeDirectory(path)
|
||||
return false
|
||||
end
|
||||
|
||||
function proxy.remove(path)
|
||||
if not proxy.exists(path) then return false end
|
||||
proxy.points[path] = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function proxy.rename(from, to)
|
||||
return false
|
||||
end
|
||||
|
||||
proxy.close = nop
|
||||
|
||||
function proxy.open(path, mode)
|
||||
checkArg(1, path, "string")
|
||||
|
||||
local handle = proxy.points[path]
|
||||
if not handle then return nil, "device point [" .. path .. "] does not exist" end
|
||||
|
||||
local msg = "device point [" .. path .. "] cannot be opened for "
|
||||
|
||||
if mode == "r" then
|
||||
if not handle.read then
|
||||
return nil, msg .. "read"
|
||||
end
|
||||
else
|
||||
if not handle.write then
|
||||
return nil, msg .. "write"
|
||||
end
|
||||
end
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
function proxy.read(h,...)
|
||||
function devfs.read(h,...)
|
||||
if not h.read then return nil, bfd end
|
||||
return h:read(...)
|
||||
end
|
||||
|
||||
function proxy.seek(h,...)
|
||||
function devfs.seek(h,...)
|
||||
if not h.seek then return nil, bfd end
|
||||
return h:seek(...)
|
||||
end
|
||||
|
||||
function proxy.write(h,...)
|
||||
function devfs.write(h,...)
|
||||
if not h.write then return nil, bfd end
|
||||
return h:write(...)
|
||||
end
|
||||
|
||||
function proxy.create(path, handle)
|
||||
handle.close = handle.close or nop
|
||||
proxy.points[path] = handle
|
||||
return true
|
||||
function devfs.close(h, ...)
|
||||
if not h.close then return nil, bfd end
|
||||
return h:close(...)
|
||||
end
|
||||
|
||||
proxy.create("null", {write = nop})
|
||||
proxy.create("random", {read = function(_,n)
|
||||
local chars = {}
|
||||
for i=1,n do
|
||||
table.insert(chars,string.char(math.random(0,255)))
|
||||
end
|
||||
return table.concat(chars)
|
||||
end})
|
||||
-- devfs.create creates a new dev point at path
|
||||
-- devfs is mounted to /sys by default, and /dev is a symlink to /sys/dev. If you want a devfs point to show up in /dev, specify a path here as "/dev/your_path")
|
||||
-- the handler can be a single file dev file (called a point), or a devfs dir [which allows it to list its own dynamic list of points and dirs]
|
||||
-- note: devfs dirs that list their own child dirs will have to handle directory queries on their own, such as list() and open(path, mode)
|
||||
|
||||
return proxy
|
||||
-- A handler represents a directory IF it defines list(), which returns a string array of the point names
|
||||
-- a directory handler acts like simplified filesystem of its own.
|
||||
-- note: that when creating new devfs points or dirs, devfs.create will not traverse into dynamic directory children of dev mount points
|
||||
-- Meaning, if you create a devfs dir, which returns dirs children of its own, devfs.create does not support creating dev points
|
||||
-- on those children
|
||||
|
||||
-- see new_devfs_dir() -- it might work for you, /dev uses it
|
||||
|
||||
-- Also note, your own devfs dirs may implement open() however they like -- devfs points' open() is called by the devfs library but dynamic
|
||||
-- dir act as their own library for their own points
|
||||
|
||||
-- ### devfs point methods ###
|
||||
-- Required
|
||||
-- open(mode: string []) file: returns new file handle for point (see "devfs point handle methods")
|
||||
-- Optional
|
||||
-- size(path) number
|
||||
|
||||
-- ### devfs point handle instance methods ###
|
||||
-- Required
|
||||
-- + technicaly, one of the following is not required when the mode is for the other (e.g. no read when in write mode)
|
||||
-- write(self, value, ...) boolean: writes each value (params list) and returns success
|
||||
-- read(self, n: number) string: return string of n bytes, nil when no more bytes available
|
||||
-- Optional
|
||||
-- seek(self, whence [string], offset [number]) number: move file handle from whence by offset, return offset result
|
||||
-- close(self) boolean: close the file handle. Note that if your open method allocated resources, you'll need to release them in close
|
||||
|
||||
-- ### devfs dir methods ###
|
||||
-- Required
|
||||
-- list() string[]: return list of child point names
|
||||
-- if you use new_devfs_dir, set metatable on .points with __pairs and __index if you want a dynamic list of files
|
||||
-- open(path, mode) file (table): return a file handle to path (path is relative)
|
||||
-- it would be nice to make open() optional, but devfs doesn't know where you might store your point handlers, if you even have any
|
||||
-- Optional
|
||||
-- size(path) number
|
||||
-- lastModified(path) number
|
||||
-- isDirectory(path) boolean -- default returns false. Having dynamic dirs is considered advanced
|
||||
-- remove(path) boolean
|
||||
-- rename(path) boolean
|
||||
-- exists(path) boolean -- default checks path against list() results
|
||||
|
||||
-- /dev is a special handler
|
||||
|
||||
local function devfs_load(key)
|
||||
return require("tools/devfs/" .. key)
|
||||
end
|
||||
|
||||
devfs.create("null", devfs_load("null"))
|
||||
devfs.create("random", devfs_load("random"))
|
||||
if comp.isAvailable("eeprom") then
|
||||
devfs.create("eeprom", devfs_load("eeprom"))
|
||||
devfs.create("eeprom-data", devfs_load("eeprom-data"))
|
||||
end
|
||||
|
||||
return devfs
|
||||
|
@ -112,9 +112,7 @@ function filesystem.setAutorunEnabled(value)
|
||||
saveConfig()
|
||||
end
|
||||
|
||||
function filesystem.segments(path)
|
||||
return segments(path)
|
||||
end
|
||||
filesystem.segments = segments
|
||||
|
||||
function filesystem.canonical(path)
|
||||
local result = table.concat(segments(path), "/")
|
||||
@ -367,7 +365,11 @@ function filesystem.makeDirectory(path)
|
||||
end
|
||||
local node, rest = findNode(path)
|
||||
if node.fs and rest then
|
||||
return node.fs.makeDirectory(rest)
|
||||
local success, reason = node.fs.makeDirectory(rest)
|
||||
if not success and not reason and node.fs.isReadOnly() then
|
||||
reason = "filesystem is readonly"
|
||||
end
|
||||
return success, reason
|
||||
end
|
||||
if node.fs then
|
||||
return nil, "virtual directory with that name already exists"
|
||||
@ -502,11 +504,12 @@ function filesystem.open(path, mode)
|
||||
checkArg(1, path, "string")
|
||||
mode = tostring(mode or "r")
|
||||
checkArg(2, mode, "string")
|
||||
|
||||
assert(({r=true, rb=true, w=true, wb=true, a=true, ab=true})[mode],
|
||||
"bad argument #2 (r[b], w[b] or a[b] expected, got " .. mode .. ")")
|
||||
|
||||
local node, rest = findNode(path)
|
||||
if not node.fs or not rest then
|
||||
if not node.fs or not rest or (({r=true,rb=true})[mode] and not node.fs.exists(rest)) then
|
||||
return nil, "file not found"
|
||||
end
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
local guid = {}
|
||||
|
||||
function guid.toHex(n)
|
||||
if type(n) ~= 'number' then
|
||||
return nil, string.format("toHex only converts numbers to strings, %s is not a string, but a %s", tostring(n), type(n))
|
||||
end
|
||||
if n == 0 then
|
||||
return '0'
|
||||
end
|
||||
|
||||
local hexchars = "0123456789abcdef"
|
||||
local result = ""
|
||||
local prefix = "" -- maybe later allow for arg to request 0x prefix
|
||||
if n < 0 then
|
||||
prefix = "-"
|
||||
n = -n
|
||||
end
|
||||
|
||||
while n > 0 do
|
||||
local next = math.floor(n % 16) + 1 -- lua has 1 based array indices
|
||||
n = math.floor(n / 16)
|
||||
result = hexchars:sub(next, next) .. result
|
||||
end
|
||||
|
||||
return prefix .. result
|
||||
end
|
||||
|
||||
function guid.next()
|
||||
-- e.g. 3c44c8a9-0613-46a2-ad33-97b6ba2e9d9a
|
||||
-- 8-4-4-4-12
|
||||
local sets = {8, 4, 4, 4, 12}
|
||||
local result = ""
|
||||
|
||||
local i
|
||||
for _,set in ipairs(sets) do
|
||||
if result:len() > 0 then
|
||||
result = result .. "-"
|
||||
end
|
||||
for i = 1,set do
|
||||
result = result .. guid.toHex(math.random(0, 15))
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
return guid
|
@ -454,7 +454,7 @@ function --[[@delayloaded-start@]] sh.internal.glob(glob_pattern)
|
||||
|
||||
local function magical(s)
|
||||
for _,glob_rule in ipairs(sh.internal.globbers) do
|
||||
if s:match("[^%%]-"..text.escapeMagic(glob_rule[2])) then
|
||||
if (" "..s):match("[^%%]"..text.escapeMagic(glob_rule[2])) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
@ -464,7 +464,6 @@ function --[[@delayloaded-start@]] sh.internal.glob(glob_pattern)
|
||||
local root = is_abs and '' or shell.getWorkingDirectory():gsub("([^/])$","%1/")
|
||||
local paths = {is_abs and "/" or ''}
|
||||
local relative_separator = ''
|
||||
|
||||
for i,segment in ipairs(segments) do
|
||||
local enclosed_pattern = string.format("^(%s)/?$", segment)
|
||||
local next_paths = {}
|
||||
|
@ -243,14 +243,17 @@ function term.readKeyboard(ops)
|
||||
end
|
||||
|
||||
while true do
|
||||
local killed, name, address, char, code = term.internal.pull(input)
|
||||
local ok, name, address, char, code = term.internal.pull(input)
|
||||
if not term.isAvailable() then
|
||||
return
|
||||
end
|
||||
-- we have to keep checking what kb is active in case it is switching during use
|
||||
-- we could have multiple screens, each with keyboards active
|
||||
local main_kb = term.keyboard(w)
|
||||
local main_sc = term.screen(w)
|
||||
local c = nil
|
||||
local c
|
||||
local backup_cache = hints.cache
|
||||
if name == "interrupted" or name == "term_unavailable" then
|
||||
if name == "interrupted" then
|
||||
draw("^C\n",true)
|
||||
return ""
|
||||
elseif address == main_kb or address == main_sc then
|
||||
|
@ -288,4 +288,93 @@ function --[[@delayloaded-start@]] text.internal.normalize(words, omitQuotes)
|
||||
return norms
|
||||
end --[[@delayloaded-end@]]
|
||||
|
||||
function --[[@delayloaded-start@]] text.internal.seeker(handle, whence, to)
|
||||
if not handle.txt then
|
||||
return nil, "bad file descriptor"
|
||||
end
|
||||
to = to or 0
|
||||
if whence == "cur" then
|
||||
handle.offset = handle.offset + to
|
||||
elseif whence == "set" then
|
||||
handle.offset = to
|
||||
elseif whence == "end" then
|
||||
handle.offset = handle.len + to
|
||||
end
|
||||
handle.offset = math.max(0, math.min(handle.offset, handle.len))
|
||||
return handle.offset
|
||||
end --[[@delayloaded-end@]]
|
||||
|
||||
function --[[@delayloaded-start@]] text.internal.reader(txt)
|
||||
checkArg(1, txt, "string")
|
||||
local reader =
|
||||
{
|
||||
txt = txt,
|
||||
len = unicode.len(txt),
|
||||
offset = 0,
|
||||
read = function(_, n)
|
||||
checkArg(1, n, "number")
|
||||
if not _.txt then
|
||||
return nil, "bad file descriptor"
|
||||
end
|
||||
if _.offset >= _.len then
|
||||
return nil
|
||||
end
|
||||
local last_offset = _.offset
|
||||
_:seek("cur", n)
|
||||
local next = unicode.sub(_.txt, last_offset + 1, _.offset)
|
||||
return next
|
||||
end,
|
||||
seek = text.internal.seeker,
|
||||
close = function(_)
|
||||
if not _.txt then
|
||||
return nil, "bad file descriptor"
|
||||
end
|
||||
_.txt = nil
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
return reader
|
||||
end --[[@delayloaded-end@]]
|
||||
|
||||
function --[[@delayloaded-start@]] text.internal.writer(ostream, append_txt)
|
||||
if type(ostream) == "table" then
|
||||
local mt = getmetatable(ostream) or {}
|
||||
checkArg(1, mt.__call, "function")
|
||||
end
|
||||
checkArg(1, ostream, "function", "table")
|
||||
checkArg(2, append_txt, "string", "nil")
|
||||
local writer =
|
||||
{
|
||||
txt = "",
|
||||
offset = 0,
|
||||
len = 0,
|
||||
write = function(_, ...)
|
||||
if not _.txt then
|
||||
return nil, "bad file descriptor"
|
||||
end
|
||||
local pre, vs, pos = unicode.sub(_.txt, 1, _.offset), {}, unicode.sub(_.txt, _.offset + 1)
|
||||
for i,v in ipairs({...}) do
|
||||
table.insert(vs, v)
|
||||
end
|
||||
vs = table.concat(vs)
|
||||
_:seek("cur", unicode.len(vs))
|
||||
_.txt = pre .. vs .. pos
|
||||
_.len = unicode.len(_.txt)
|
||||
return true
|
||||
end,
|
||||
seek = text.internal.seeker,
|
||||
close = function(_)
|
||||
if not _.txt then
|
||||
return nil, "bad file descriptor"
|
||||
end
|
||||
ostream((append_txt or "") .. _.txt)
|
||||
_.txt = nil
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
return writer
|
||||
end --[[@delayloaded-end@]]
|
||||
|
||||
return text, local_env
|
||||
|
@ -0,0 +1,19 @@
|
||||
local comp = require("component")
|
||||
local text = require("text")
|
||||
|
||||
if not comp.isAvailable("eeprom") then
|
||||
return nil
|
||||
end
|
||||
|
||||
return
|
||||
{
|
||||
open = function(mode)
|
||||
if ({r=true, rb=true})[mode] then
|
||||
return text.internal.reader(comp.eeprom.getData())
|
||||
end
|
||||
return text.internal.writer(comp.eeprom.setData, ({a=true,ab=true})[mode] and comp.eeprom.getData())
|
||||
end,
|
||||
size = function()
|
||||
return string.len(comp.eeprom.getData())
|
||||
end
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
local comp = require("component")
|
||||
local text = require("text")
|
||||
|
||||
if not comp.isAvailable("eeprom") then
|
||||
return nil
|
||||
end
|
||||
|
||||
return
|
||||
{
|
||||
open = function(mode)
|
||||
if ({r=true, rb=true})[mode] then
|
||||
return text.internal.reader(comp.eeprom.get())
|
||||
end
|
||||
return text.internal.writer(comp.eeprom.set, ({a=true,ab=true})[mode] and comp.eeprom.get())
|
||||
end,
|
||||
size = function()
|
||||
return string.len(comp.eeprom.get())
|
||||
end
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
return
|
||||
{
|
||||
open = function(mode)
|
||||
if not mode or not mode:match("[wa]") then
|
||||
return nil, "write only"
|
||||
end
|
||||
return
|
||||
{
|
||||
write = function() end
|
||||
}
|
||||
end
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
return
|
||||
{
|
||||
open = function(mode)
|
||||
if mode and not mode:match("r") then
|
||||
return nil, "read only"
|
||||
end
|
||||
return
|
||||
{
|
||||
read = function(self, n)
|
||||
local chars = {}
|
||||
for i=1,n do
|
||||
table.insert(chars,string.char(math.random(0,255)))
|
||||
end
|
||||
return table.concat(chars)
|
||||
end
|
||||
}
|
||||
end,
|
||||
size = function()
|
||||
return math.huge
|
||||
end
|
||||
}
|
@ -171,16 +171,11 @@ options.setboot = source.prop.setboot and not options.nosetboot
|
||||
options.reboot = source.prop.reboot and not options.noreboot
|
||||
options.source_dir = fs.canonical(source.prop.fromDir or options.fromDir or "") .. '/.'
|
||||
|
||||
local installer_path = options.source_root .. "/.install"
|
||||
if fs.exists(installer_path) then
|
||||
os.exit(loadfile("/lib/tools/install_utils.lua", "bt", _G)('install', options))
|
||||
end
|
||||
|
||||
local cp_args =
|
||||
{
|
||||
"-vrx" .. (options.update and "ui" or ""),
|
||||
options.source_root .. options.source_dir,
|
||||
options.target_root .. options.target_dir
|
||||
options.target_root:gsub("//","/") .. options.target_dir
|
||||
}
|
||||
|
||||
local source_display = (source.prop or {}).label or source.dev.getLabel() or source.path
|
||||
@ -194,6 +189,11 @@ if not ((io.read() or "n").."y"):match("^%s*[Yy]") then
|
||||
os.exit()
|
||||
end
|
||||
|
||||
local installer_path = options.source_root .. "/.install"
|
||||
if fs.exists(installer_path) then
|
||||
os.exit(loadfile("/lib/tools/install_utils.lua", "bt", _G)('install', options))
|
||||
end
|
||||
|
||||
return
|
||||
{
|
||||
setlabel = options.setlabel,
|
||||
|
@ -41,18 +41,18 @@ end
|
||||
if cmd == 'select' then
|
||||
if #options.sources == 0 then
|
||||
if options.source_label then
|
||||
io.stderr:write("No install source matched given label: " .. options.source_label .. '\n')
|
||||
io.stderr:write("Nothing to install labeled: " .. options.source_label .. '\n')
|
||||
elseif options.from then
|
||||
io.stderr:write("No install source found: " .. options.from .. '\n')
|
||||
io.stderr:write("Nothing to install from: " .. options.from .. '\n')
|
||||
else
|
||||
io.stderr:write("Could not find any available installations\n")
|
||||
io.stderr:write("Nothing to install\n")
|
||||
end
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
if #options.targets == 0 then
|
||||
if options.to then
|
||||
io.stderr:write("No such filesystem to install to: " .. options.to .. '\n')
|
||||
io.stderr:write("No such target to install to: " .. options.to .. '\n')
|
||||
else
|
||||
io.stderr:write("No writable disks found, aborting\n")
|
||||
end
|
||||
|
@ -0,0 +1,22 @@
|
||||
local uuid = {}
|
||||
|
||||
function uuid.next()
|
||||
-- e.g. 3c44c8a9-0613-46a2-ad33-97b6ba2e9d9a
|
||||
-- 8-4-4-4-12 (halved sizes because bytes make hex pairs)
|
||||
local sets = {4, 2, 2, 2, 6}
|
||||
local result = ""
|
||||
|
||||
local i
|
||||
for _,set in ipairs(sets) do
|
||||
if result:len() > 0 then
|
||||
result = result .. "-"
|
||||
end
|
||||
for i = 1,set do
|
||||
result = result .. string.format("%02x", math.random(0, 255))
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
return uuid
|
@ -9,10 +9,10 @@ DESCRIPTION
|
||||
|
||||
OPTIONS
|
||||
--from=ADDR
|
||||
Specifies the source filesystem or its root path. ADDR can be the device guid or a directory path. If this is a directory path, it represents a root path to install from. This option can also be used to specify source paths that would otherwise be ignored, those being devfs, tmpfs, and the rootfs. e.g. --from=/tmp . Note that if both --from and a [name] is given, install expects the source path to have a .prop defining the same name. See .prop for more details.
|
||||
Specifies the source filesystem or its root path. ADDR can be the device uuid or a directory path. If this is a directory path, it represents a root path to install from. This option can also be used to specify source paths that would otherwise be ignored, those being devfs, tmpfs, and the rootfs. e.g. --from=/tmp . Note that if both --from and a [name] is given, install expects the source path to have a .prop defining the same name. See .prop for more details.
|
||||
|
||||
--to=ADDR
|
||||
Same as --from but specifies the target filesystem by guid or its root path. This option can also be used to specify filesystems that are otherwise ignored including tmpfs. i.e. --to=ADDR where ADDR matches the tmpfs device address or its mount point path. e.g. --to=/tmp
|
||||
Same as --from but specifies the target filesystem by uuid or its root path. This option can also be used to specify filesystems that are otherwise ignored including tmpfs. i.e. --to=ADDR where ADDR matches the tmpfs device address or its mount point path. e.g. --to=/tmp
|
||||
|
||||
--fromDir=PATH
|
||||
Install PATH from source. PATH is relative to the root of the source filesystem or path given by --from. The default is .
|
||||
|
@ -302,7 +302,7 @@ leashUpgrade {
|
||||
}
|
||||
navigationUpgrade {
|
||||
input: [[ingotGold, compass, ingotGold]
|
||||
["oc:circuitChip2", {item=map, subID=any}, "oc:circuitChip2"]
|
||||
["oc:circuitChip2", {item=filled_map, subID=any}, "oc:circuitChip2"]
|
||||
[ingotGold, potion, ingotGold]]
|
||||
}
|
||||
pistonUpgrade {
|
||||
|
@ -144,7 +144,7 @@ generatorUpgrade {
|
||||
navigationUpgrade {
|
||||
# 2 = MV Casing
|
||||
input: [[{block="gt.blockcasings", subID=2}, compass, screwStainlessSteel]
|
||||
["oc:circuitChip3", {item=map, subID=any}, "oc:circuitChip3"]
|
||||
["oc:circuitChip3", {item=filled_map, subID=any}, "oc:circuitChip3"]
|
||||
[screwStainlessSteel, potion, craftingToolScrewdriver]]
|
||||
}
|
||||
signUpgrade {
|
||||
@ -341,4 +341,4 @@ screen3 {
|
||||
input: [[plateTitanium, "oc:materialCircuitBoardPrinted", craftingToolWrench]
|
||||
["oc:circuitChip3", "oc:screen2", "oc:circuitChip3"]
|
||||
[plateTitanium, "oc:materialCircuitBoardPrinted", craftingToolScrewdriver]]
|
||||
}
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ inventoryControllerUpgrade {
|
||||
}
|
||||
navigationUpgrade {
|
||||
input: [[ingotGold, compass, ingotGold]
|
||||
["oc:circuitChip3", {item=map, subID=any}, "oc:circuitChip3"]
|
||||
["oc:circuitChip3", {item=filled_map, subID=any}, "oc:circuitChip3"]
|
||||
[ingotGold, potion, ingotGold]]
|
||||
}
|
||||
signUpgrade {
|
||||
|
@ -14,7 +14,7 @@ import org.apache.logging.log4j.Logger
|
||||
|
||||
@Mod(modid = OpenComputers.ID, name = OpenComputers.Name,
|
||||
version = OpenComputers.Version,
|
||||
modLanguage = "scala", useMetadata = true, acceptedMinecraftVersions = "[@MCVERSION@,@MCVERSION@+)")
|
||||
modLanguage = "scala", useMetadata = true /*@MCVERSIONDEP@*/)
|
||||
object OpenComputers {
|
||||
final val ID = "OpenComputers"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user