mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Reduction of moose.lua sizing working now!
This commit is contained in:
529
Utils/luarocks/share/lua/5.1/pl/utils.lua
Normal file
529
Utils/luarocks/share/lua/5.1/pl/utils.lua
Normal file
@@ -0,0 +1,529 @@
|
||||
--- Generally useful routines.
|
||||
-- See <a href="../../index.html#utils">the Guide</a>.
|
||||
-- @class module
|
||||
-- @name pl.utils
|
||||
local format,gsub,byte = string.format,string.gsub,string.byte
|
||||
local clock = os.clock
|
||||
local stdout = io.stdout
|
||||
local append = table.insert
|
||||
|
||||
local collisions = {}
|
||||
|
||||
local utils = {}
|
||||
|
||||
utils._VERSION = "0.9.4"
|
||||
|
||||
utils.dir_separator = _G.package.config:sub(1,1)
|
||||
|
||||
--- end this program gracefully.
|
||||
-- @param code The exit code or a message to be printed
|
||||
-- @param ... extra arguments for message's format'
|
||||
-- @see utils.fprintf
|
||||
function utils.quit(code,...)
|
||||
if type(code) == 'string' then
|
||||
utils.fprintf(io.stderr,code,...)
|
||||
code = -1
|
||||
else
|
||||
utils.fprintf(io.stderr,...)
|
||||
end
|
||||
io.stderr:write('\n')
|
||||
os.exit(code)
|
||||
end
|
||||
|
||||
--- print an arbitrary number of arguments using a format.
|
||||
-- @param fmt The format (see string.format)
|
||||
-- @param ... Extra arguments for format
|
||||
function utils.printf(fmt,...)
|
||||
utils.fprintf(stdout,fmt,...)
|
||||
end
|
||||
|
||||
--- write an arbitrary number of arguments to a file using a format.
|
||||
-- @param f File handle to write to.
|
||||
-- @param fmt The format (see string.format).
|
||||
-- @param ... Extra arguments for format
|
||||
function utils.fprintf(f,fmt,...)
|
||||
utils.assert_string(2,fmt)
|
||||
f:write(format(fmt,...))
|
||||
end
|
||||
|
||||
local function import_symbol(T,k,v,libname)
|
||||
local key = rawget(T,k)
|
||||
-- warn about collisions!
|
||||
if key and k ~= '_M' and k ~= '_NAME' and k ~= '_PACKAGE' and k ~= '_VERSION' then
|
||||
utils.printf("warning: '%s.%s' overrides existing symbol\n",libname,k)
|
||||
end
|
||||
rawset(T,k,v)
|
||||
end
|
||||
|
||||
local function lookup_lib(T,t)
|
||||
for k,v in pairs(T) do
|
||||
if v == t then return k end
|
||||
end
|
||||
return '?'
|
||||
end
|
||||
|
||||
local already_imported = {}
|
||||
|
||||
--- take a table and 'inject' it into the local namespace.
|
||||
-- @param t The Table
|
||||
-- @param T An optional destination table (defaults to callers environment)
|
||||
function utils.import(t,T)
|
||||
T = T or _G
|
||||
t = t or utils
|
||||
if type(t) == 'string' then
|
||||
t = require (t)
|
||||
end
|
||||
local libname = lookup_lib(T,t)
|
||||
if already_imported[t] then return end
|
||||
already_imported[t] = libname
|
||||
for k,v in pairs(t) do
|
||||
import_symbol(T,k,v,libname)
|
||||
end
|
||||
end
|
||||
|
||||
utils.patterns = {
|
||||
FLOAT = '[%+%-%d]%d*%.?%d*[eE]?[%+%-]?%d*',
|
||||
INTEGER = '[+%-%d]%d*',
|
||||
IDEN = '[%a_][%w_]*',
|
||||
FILE = '[%a%.\\][:%][%w%._%-\\]*'
|
||||
}
|
||||
|
||||
--- escape any 'magic' characters in a string
|
||||
-- @param s The input string
|
||||
function utils.escape(s)
|
||||
utils.assert_string(1,s)
|
||||
return (s:gsub('[%-%.%+%[%]%(%)%$%^%%%?%*]','%%%1'))
|
||||
end
|
||||
|
||||
--- return either of two values, depending on a condition.
|
||||
-- @param cond A condition
|
||||
-- @param value1 Value returned if cond is true
|
||||
-- @param value2 Value returned if cond is false (can be optional)
|
||||
function utils.choose(cond,value1,value2)
|
||||
if cond then return value1
|
||||
else return value2
|
||||
end
|
||||
end
|
||||
|
||||
local raise
|
||||
|
||||
--- return the contents of a file as a string
|
||||
-- @param filename The file path
|
||||
-- @param is_bin open in binary mode
|
||||
-- @return file contents
|
||||
function utils.readfile(filename,is_bin)
|
||||
local mode = is_bin and 'b' or ''
|
||||
utils.assert_string(1,filename)
|
||||
local f,err = io.open(filename,'r'..mode)
|
||||
if not f then return utils.raise (err) end
|
||||
local res,err = f:read('*a')
|
||||
f:close()
|
||||
if not res then return raise (err) end
|
||||
return res
|
||||
end
|
||||
|
||||
--- write a string to a file
|
||||
-- @param filename The file path
|
||||
-- @param str The string
|
||||
-- @return true or nil
|
||||
-- @return error message
|
||||
-- @raise error if filename or str aren't strings
|
||||
function utils.writefile(filename,str)
|
||||
utils.assert_string(1,filename)
|
||||
utils.assert_string(2,str)
|
||||
local f,err = io.open(filename,'w')
|
||||
if not f then return raise(err) end
|
||||
f:write(str)
|
||||
f:close()
|
||||
return true
|
||||
end
|
||||
|
||||
--- return the contents of a file as a list of lines
|
||||
-- @param filename The file path
|
||||
-- @return file contents as a table
|
||||
-- @raise errror if filename is not a string
|
||||
function utils.readlines(filename)
|
||||
utils.assert_string(1,filename)
|
||||
local f,err = io.open(filename,'r')
|
||||
if not f then return raise(err) end
|
||||
local res = {}
|
||||
for line in f:lines() do
|
||||
append(res,line)
|
||||
end
|
||||
f:close()
|
||||
return res
|
||||
end
|
||||
|
||||
--- split a string into a list of strings separated by a delimiter.
|
||||
-- @param s The input string
|
||||
-- @param re A Lua string pattern; defaults to '%s+'
|
||||
-- @param plain don't use Lua patterns
|
||||
-- @param n optional maximum number of splits
|
||||
-- @return a list-like table
|
||||
-- @raise error if s is not a string
|
||||
function utils.split(s,re,plain,n)
|
||||
utils.assert_string(1,s)
|
||||
local find,sub,append = string.find, string.sub, table.insert
|
||||
local i1,ls = 1,{}
|
||||
if not re then re = '%s+' end
|
||||
if re == '' then return {s} end
|
||||
while true do
|
||||
local i2,i3 = find(s,re,i1,plain)
|
||||
if not i2 then
|
||||
local last = sub(s,i1)
|
||||
if last ~= '' then append(ls,last) end
|
||||
if #ls == 1 and ls[1] == '' then
|
||||
return {}
|
||||
else
|
||||
return ls
|
||||
end
|
||||
end
|
||||
append(ls,sub(s,i1,i2-1))
|
||||
if n and #ls == n then
|
||||
ls[#ls] = sub(s,i1)
|
||||
return ls
|
||||
end
|
||||
i1 = i3+1
|
||||
end
|
||||
end
|
||||
|
||||
--- split a string into a number of values.
|
||||
-- @param s the string
|
||||
-- @param re the delimiter, default space
|
||||
-- @return n values
|
||||
-- @usage first,next = splitv('jane:doe',':')
|
||||
-- @see split
|
||||
function utils.splitv (s,re)
|
||||
return unpack(utils.split(s,re))
|
||||
end
|
||||
|
||||
local lua52 = table.pack ~= nil
|
||||
local lua51_load = load
|
||||
|
||||
if not lua52 then -- define Lua 5.2 style load()
|
||||
function utils.load(str,src,mode,env)
|
||||
local chunk,err
|
||||
if type(str) == 'string' then
|
||||
chunk,err = loadstring(str,src)
|
||||
else
|
||||
chunk,err = lua51_load(str,src)
|
||||
end
|
||||
if chunk and env then setfenv(chunk,env) end
|
||||
return chunk,err
|
||||
end
|
||||
else
|
||||
utils.load = load
|
||||
-- setfenv/getfenv replacements for Lua 5.2
|
||||
-- by Sergey Rozhenko
|
||||
-- http://lua-users.org/lists/lua-l/2010-06/msg00313.html
|
||||
-- Roberto Ierusalimschy notes that it is possible for getfenv to return nil
|
||||
-- in the case of a function with no globals:
|
||||
-- http://lua-users.org/lists/lua-l/2010-06/msg00315.html
|
||||
function setfenv(f, t)
|
||||
f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func)
|
||||
local name
|
||||
local up = 0
|
||||
repeat
|
||||
up = up + 1
|
||||
name = debug.getupvalue(f, up)
|
||||
until name == '_ENV' or name == nil
|
||||
if name then
|
||||
debug.upvaluejoin(f, up, function() return name end, 1) -- use unique upvalue
|
||||
debug.setupvalue(f, up, t)
|
||||
end
|
||||
end
|
||||
|
||||
function getfenv(f)
|
||||
f = (type(f) == 'function' and f or debug.getinfo(f + 1, 'f').func)
|
||||
local name, val
|
||||
local up = 0
|
||||
repeat
|
||||
up = up + 1
|
||||
name, val = debug.getupvalue(f, up)
|
||||
until name == '_ENV' or name == nil
|
||||
return val
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- execute a shell command.
|
||||
-- This is a compatibility function that returns the same for Lua 5.1 and Lua 5.2
|
||||
-- @param cmd a shell command
|
||||
-- @return true if successful
|
||||
-- @return actual return code
|
||||
function utils.execute (cmd)
|
||||
local res1,res2,res2 = os.execute(cmd)
|
||||
if not lua52 then
|
||||
return res1==0,res1
|
||||
else
|
||||
return res1,res2
|
||||
end
|
||||
end
|
||||
|
||||
if not lua52 then
|
||||
function table.pack (...)
|
||||
local n = select('#',...)
|
||||
return {n=n; ...},n
|
||||
end
|
||||
local sep = package.config:sub(1,1)
|
||||
function package.searchpath (mod,path)
|
||||
mod = mod:gsub('%.',sep)
|
||||
for m in path:gmatch('[^;]+') do
|
||||
local nm = m:gsub('?',mod)
|
||||
local f = io.open(nm,'r')
|
||||
if f then f:close(); return nm end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not table.pack then table.pack = _G.pack end
|
||||
if not rawget(_G,"pack") then _G.pack = table.pack end
|
||||
|
||||
--- take an arbitrary set of arguments and make into a table.
|
||||
-- This returns the table and the size; works fine for nil arguments
|
||||
-- @param ... arguments
|
||||
-- @return table
|
||||
-- @return table size
|
||||
-- @usage local t,n = utils.args(...)
|
||||
|
||||
--- 'memoize' a function (cache returned value for next call).
|
||||
-- This is useful if you have a function which is relatively expensive,
|
||||
-- but you don't know in advance what values will be required, so
|
||||
-- building a table upfront is wasteful/impossible.
|
||||
-- @param func a function of at least one argument
|
||||
-- @return a function with at least one argument, which is used as the key.
|
||||
function utils.memoize(func)
|
||||
return setmetatable({}, {
|
||||
__index = function(self, k, ...)
|
||||
local v = func(k,...)
|
||||
self[k] = v
|
||||
return v
|
||||
end,
|
||||
__call = function(self, k) return self[k] end
|
||||
})
|
||||
end
|
||||
|
||||
--- is the object either a function or a callable object?.
|
||||
-- @param obj Object to check.
|
||||
function utils.is_callable (obj)
|
||||
return type(obj) == 'function' or getmetatable(obj) and getmetatable(obj).__call
|
||||
end
|
||||
|
||||
--- is the object of the specified type?.
|
||||
-- If the type is a string, then use type, otherwise compare with metatable
|
||||
-- @param obj An object to check
|
||||
-- @param tp String of what type it should be
|
||||
function utils.is_type (obj,tp)
|
||||
if type(tp) == 'string' then return type(obj) == tp end
|
||||
local mt = getmetatable(obj)
|
||||
return tp == mt
|
||||
end
|
||||
|
||||
local fileMT = getmetatable(io.stdout)
|
||||
|
||||
--- a string representation of a type.
|
||||
-- For tables with metatables, we assume that the metatable has a `_name`
|
||||
-- field. Knows about Lua file objects.
|
||||
-- @param obj an object
|
||||
-- @return a string like 'number', 'table' or 'List'
|
||||
function utils.type (obj)
|
||||
local t = type(obj)
|
||||
if t == 'table' or t == 'userdata' then
|
||||
local mt = getmetatable(obj)
|
||||
if mt == fileMT then
|
||||
return 'file'
|
||||
else
|
||||
return mt._name or "unknown "..t
|
||||
end
|
||||
else
|
||||
return t
|
||||
end
|
||||
end
|
||||
|
||||
--- is this number an integer?
|
||||
-- @param x a number
|
||||
-- @raise error if x is not a number
|
||||
function utils.is_integer (x)
|
||||
return math.ceil(x)==x
|
||||
end
|
||||
|
||||
utils.stdmt = {
|
||||
List = {_name='List'}, Map = {_name='Map'},
|
||||
Set = {_name='Set'}, MultiMap = {_name='MultiMap'}
|
||||
}
|
||||
|
||||
local _function_factories = {}
|
||||
|
||||
--- associate a function factory with a type.
|
||||
-- A function factory takes an object of the given type and
|
||||
-- returns a function for evaluating it
|
||||
-- @param mt metatable
|
||||
-- @param fun a callable that returns a function
|
||||
function utils.add_function_factory (mt,fun)
|
||||
_function_factories[mt] = fun
|
||||
end
|
||||
|
||||
local function _string_lambda(f)
|
||||
local raise = utils.raise
|
||||
if f:find '^|' or f:find '_' then
|
||||
local args,body = f:match '|([^|]*)|(.+)'
|
||||
if f:find '_' then
|
||||
args = '_'
|
||||
body = f
|
||||
else
|
||||
if not args then return raise 'bad string lambda' end
|
||||
end
|
||||
local fstr = 'return function('..args..') return '..body..' end'
|
||||
local fn,err = loadstring(fstr)
|
||||
if not fn then return raise(err) end
|
||||
fn = fn()
|
||||
return fn
|
||||
else return raise 'not a string lambda'
|
||||
end
|
||||
end
|
||||
|
||||
--- an anonymous function as a string. This string is either of the form
|
||||
-- '|args| expression' or is a function of one argument, '_'
|
||||
-- @param lf function as a string
|
||||
-- @return a function
|
||||
-- @usage string_lambda '|x|x+1' (2) == 3
|
||||
-- @usage string_lambda '_+1 (2) == 3
|
||||
utils.string_lambda = utils.memoize(_string_lambda)
|
||||
|
||||
local ops
|
||||
|
||||
--- process a function argument.
|
||||
-- This is used throughout Penlight and defines what is meant by a function:
|
||||
-- Something that is callable, or an operator string as defined by <code>pl.operator</code>,
|
||||
-- such as '>' or '#'. If a function factory has been registered for the type, it will
|
||||
-- be called to get the function.
|
||||
-- @param idx argument index
|
||||
-- @param f a function, operator string, or callable object
|
||||
-- @param msg optional error message
|
||||
-- @return a callable
|
||||
-- @raise if idx is not a number or if f is not callable
|
||||
-- @see utils.is_callable
|
||||
function utils.function_arg (idx,f,msg)
|
||||
utils.assert_arg(1,idx,'number')
|
||||
local tp = type(f)
|
||||
if tp == 'function' then return f end -- no worries!
|
||||
-- ok, a string can correspond to an operator (like '==')
|
||||
if tp == 'string' then
|
||||
if not ops then ops = require 'pl.operator'.optable end
|
||||
local fn = ops[f]
|
||||
if fn then return fn end
|
||||
local fn, err = utils.string_lambda(f)
|
||||
if not fn then error(err..': '..f) end
|
||||
return fn
|
||||
elseif tp == 'table' or tp == 'userdata' then
|
||||
local mt = getmetatable(f)
|
||||
if not mt then error('not a callable object',2) end
|
||||
local ff = _function_factories[mt]
|
||||
if not ff then
|
||||
if not mt.__call then error('not a callable object',2) end
|
||||
return f
|
||||
else
|
||||
return ff(f) -- we have a function factory for this type!
|
||||
end
|
||||
end
|
||||
if not msg then msg = " must be callable" end
|
||||
if idx > 0 then
|
||||
error("argument "..idx..": "..msg,2)
|
||||
else
|
||||
error(msg,2)
|
||||
end
|
||||
end
|
||||
|
||||
--- bind the first argument of the function to a value.
|
||||
-- @param fn a function of at least two values (may be an operator string)
|
||||
-- @param p a value
|
||||
-- @return a function such that f(x) is fn(p,x)
|
||||
-- @raise same as @{function_arg}
|
||||
-- @see pl.func.curry
|
||||
function utils.bind1 (fn,p)
|
||||
fn = utils.function_arg(1,fn)
|
||||
return function(...) return fn(p,...) end
|
||||
end
|
||||
|
||||
--- assert that the given argument is in fact of the correct type.
|
||||
-- @param n argument index
|
||||
-- @param val the value
|
||||
-- @param tp the type
|
||||
-- @param verify an optional verfication function
|
||||
-- @param msg an optional custom message
|
||||
-- @param lev optional stack position for trace, default 2
|
||||
-- @raise if the argument n is not the correct type
|
||||
-- @usage assert_arg(1,t,'table')
|
||||
-- @usage assert_arg(n,val,'string',path.isdir,'not a directory')
|
||||
function utils.assert_arg (n,val,tp,verify,msg,lev)
|
||||
if type(val) ~= tp then
|
||||
error(("argument %d expected a '%s', got a '%s'"):format(n,tp,type(val)),2)
|
||||
end
|
||||
if verify and not verify(val) then
|
||||
error(("argument %d: '%s' %s"):format(n,val,msg),lev or 2)
|
||||
end
|
||||
end
|
||||
|
||||
--- assert the common case that the argument is a string.
|
||||
-- @param n argument index
|
||||
-- @param val a value that must be a string
|
||||
-- @raise val must be a string
|
||||
function utils.assert_string (n,val)
|
||||
utils.assert_arg(n,val,'string',nil,nil,nil,3)
|
||||
end
|
||||
|
||||
local err_mode = 'default'
|
||||
|
||||
--- control the error strategy used by Penlight.
|
||||
-- Controls how <code>utils.raise</code> works; the default is for it
|
||||
-- to return nil and the error string, but if the mode is 'error' then
|
||||
-- it will throw an error. If mode is 'quit' it will immediately terminate
|
||||
-- the program.
|
||||
-- @param mode - either 'default', 'quit' or 'error'
|
||||
-- @see utils.raise
|
||||
function utils.on_error (mode)
|
||||
err_mode = mode
|
||||
end
|
||||
|
||||
--- used by Penlight functions to return errors. Its global behaviour is controlled
|
||||
-- by <code>utils.on_error</code>
|
||||
-- @param err the error string.
|
||||
-- @see utils.on_error
|
||||
function utils.raise (err)
|
||||
if err_mode == 'default' then return nil,err
|
||||
elseif err_mode == 'quit' then utils.quit(err)
|
||||
else error(err,2)
|
||||
end
|
||||
end
|
||||
|
||||
raise = utils.raise
|
||||
|
||||
--- load a code string or bytecode chunk.
|
||||
-- @param code Lua code as a string or bytecode
|
||||
-- @param name for source errors
|
||||
-- @param mode kind of chunk, 't' for text, 'b' for bytecode, 'bt' for all (default)
|
||||
-- @param env the environment for the new chunk (default nil)
|
||||
-- @return compiled chunk
|
||||
-- @return error message (chunk is nil)
|
||||
-- @function utils.load
|
||||
|
||||
|
||||
--- Lua 5.2 Compatible Functions
|
||||
-- @section lua52
|
||||
|
||||
--- pack an argument list into a table.
|
||||
-- @param ... any arguments
|
||||
-- @return a table with field n set to the length
|
||||
-- @return the length
|
||||
-- @function table.pack
|
||||
|
||||
------
|
||||
-- return the full path where a Lua module name would be matched.
|
||||
-- @param mod module name, possibly dotted
|
||||
-- @param path a path in the same form as package.path or package.cpath
|
||||
-- @see path.package_path
|
||||
-- @function package.searchpath
|
||||
|
||||
return utils
|
||||
|
||||
|
||||
Reference in New Issue
Block a user