From 01fd63f17c80e81218b3d65f1455a62c411dc6ff Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Tue, 30 Apr 2013 11:55:11 +0200 Subject: sync with Context from 2013-04-30 --- lualibs-dir.lua | 23 +++++- lualibs-os.lua | 16 +++- lualibs-package.lua | 216 ++++++++++++++++++++++++++------------------------- lualibs-table.lua | 9 +-- lualibs-util-env.lua | 29 +++++++ 5 files changed, 177 insertions(+), 116 deletions(-) diff --git a/lualibs-dir.lua b/lualibs-dir.lua index 00cda38..3d0576e 100644 --- a/lualibs-dir.lua +++ b/lualibs-dir.lua @@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['l-dir'] = { local type, select = type, select local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub -local concat, insert, remove = table.concat, table.insert, table.remove +local concat, insert, remove, unpack = table.concat, table.insert, table.remove, table.unpack local lpegmatch = lpeg.match local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V @@ -447,3 +447,24 @@ function dir.pop() end return d end + +local function found(...) -- can have nil entries + for i=1,select("#",...) do + local path = select(i,...) + local kind = type(path) + if kind == "string" then + if isdir(path) then + return path + end + elseif kind == "table" then + -- here we asume no holes, i.e. an indexed table + local path = found(unpack(path)) + if path then + return path + end + end + end + -- return nil -- if we want print("crappath") to show something +end + +dir.found = found diff --git a/lualibs-os.lua b/lualibs-os.lua index 42f3e48..05ca0ac 100644 --- a/lualibs-os.lua +++ b/lualibs-os.lua @@ -452,8 +452,20 @@ function os.now() return date("!%Y-%m-%d %H:%M:%S") -- 2011-12-04 14:59:12 end -if not os.sleep and socket then - os.sleep = socket.sleep +-- if not os.sleep and socket then +-- os.sleep = socket.sleep +-- end + +if not os.sleep then + local socket = socket + function os.sleep(n) + if not socket then + -- so we delay ... if os.sleep is really needed then one should also + -- be sure that socket can be found + socket = require("socket") + end + socket.sleep(n) + end end -- print(os.which("inkscape.exe")) diff --git a/lualibs-package.lua b/lualibs-package.lua index 7b82fa5..579fd39 100644 --- a/lualibs-package.lua +++ b/lualibs-package.lua @@ -30,8 +30,6 @@ local filejoin = file and file.join or function(path,name) return pat local isreadable = file and file.is_readable or function(name) local f = io.open(name) if f then f:close() return true end end local addsuffix = file and file.addsuffix or function(name,suffix) return name .. "." .. suffix end --- - -- local separator, concatinator, placeholder, pathofexecutable, ignorebefore = string.match(package.config,"(.-)\n(.-)\n(.-)\n(.-)\n(.-)\n") -- -- local config = { @@ -42,8 +40,6 @@ local addsuffix = file and file.addsuffix or function(name,suffix) return nam -- ignorebefore = ignorebefore, -- - remove all before this when making lua_open -- } --- - local function cleanpath(path) -- hm, don't we have a helper for this? return path end @@ -54,16 +50,18 @@ local function lualibfile(name) return lpegmatch(pattern,name) or name end +local offset = luarocks and 1 or 0 -- todo: also check other extras + local helpers = package.helpers or { cleanpath = cleanpath, lualibfile = lualibfile, trace = false, report = function(...) print(format(...)) end, builtin = { - ["preload table"] = searchers[1], -- special case, built-in libs - ["path specification"] = searchers[2], - ["cpath specification"] = searchers[3], - ["all in one fallback"] = searchers[4], -- special case, combined libs + ["preload table"] = searchers[1+offset], -- special case, built-in libs + ["path specification"] = searchers[2+offset], + ["cpath specification"] = searchers[3+offset], + ["all in one fallback"] = searchers[4+offset], -- special case, combined libs }, methods = { }, @@ -84,28 +82,69 @@ package.helpers = helpers local methods = helpers.methods local builtin = helpers.builtin --- extra tds/ctx paths +-- extra tds/ctx paths ... a bit of overhead for efficient tracing local extraluapaths = { } local extralibpaths = { } local luapaths = nil -- delayed local libpaths = nil -- delayed +local oldluapath = nil +local oldlibpath = nil + +local nofextralua = -1 +local nofextralib = -1 +local nofpathlua = -1 +local nofpathlib = -1 + +local function listpaths(what,paths) + local nofpaths = #paths + if nofpaths > 0 then + for i=1,nofpaths do + helpers.report("using %s path %i: %s",what,i,paths[i]) + end + else + helpers.report("no %s paths defined",what) + end + return nofpaths +end local function getextraluapaths() + if helpers.trace and #extraluapaths ~= nofextralua then + nofextralua = listpaths("extra lua",extraluapaths) + end return extraluapaths end local function getextralibpaths() + if helpers.trace and #extralibpaths ~= nofextralib then + nofextralib = listpaths("extra lib",extralibpaths) + end return extralibpaths end local function getluapaths() - luapaths = luapaths or file.splitpath(package.path, ";") + local luapath = package.path or "" + if oldluapath ~= luapath then + luapaths = file.splitpath(luapath,";") + oldluapath = luapath + nofpathlua = -1 + end + if helpers.trace and #luapaths ~= nofpathlua then + nofpathlua = listpaths("builtin lua",luapaths) + end return luapaths end local function getlibpaths() - libpaths = libpaths or file.splitpath(package.cpath, ";") + local libpath = package.cpath or "" + if oldlibpath ~= libpath then + libpaths = file.splitpath(libpath,";") + oldlibpath = libpath + nofpathlib = -1 + end + if helpers.trace and #libpaths ~= nofpathlib then + nofpathlib = listpaths("builtin lib",libpaths) + end return libpaths end @@ -167,8 +206,10 @@ end -- lib loader (used elsewhere) local function loadedaslib(resolved,rawname) -- todo: strip all before first - - -- local init = "luaopen_" .. string.match(rawname,".-([^%.]+)$") - local init = "luaopen_"..gsub(rawname,"%.","_") + local base = gsub(rawname,"%.","_") + -- so, we can do a require("foo/bar") and initialize bar + -- local base = gsub(file.basename(rawname),"%.","_") + local init = "luaopen_" .. gsub(base,"%.","_") if helpers.trace then helpers.report("calling loadlib with '%s' with init '%s'",resolved,init) end @@ -180,159 +221,120 @@ helpers.loadedaslib = loadedaslib -- wrapped and new loaders local function loadedbypath(name,rawname,paths,islib,what) - local trace = helpers.trace - local report = helpers.report - if trace then - report("locating '%s' as '%s' on '%s' paths",rawname,name,what) - end + local trace = helpers.trace for p=1,#paths do - local path = paths[p] + local path = paths[p] local resolved = filejoin(path,name) - if trace then -- mode detail - report("checking '%s' using '%s' path '%s'",name,what,path) + if trace then + helpers.report("%s path, identifying '%s' on '%s'",what,name,path) end if isreadable(resolved) then if trace then - report("'%s' located on '%s'",name,resolved) + helpers.report("%s path, '%s' found on '%s'",what,name,resolved) end - local result = nil if islib then - result = loadedaslib(resolved,rawname) + return loadedaslib(resolved,rawname) else - result = loadfile(resolved) + return loadfile(resolved) end - if result then - result() - end - return true, result end end end helpers.loadedbypath = loadedbypath --- alternatively we could set the package.searchers - methods["already loaded"] = function(name) - local result = package.loaded[name] - if result then - return true, result - end + return package.loaded[name] end methods["preload table"] = function(name) - local result = builtin["preload table"](name) - if type(result) == "function" then - return true, result - end + return builtin["preload table"](name) end methods["lua extra list"] = function(name) - local thename = lualibfile(name) - local luaname = addsuffix(thename,"lua") - local luapaths = getextraluapaths() - local done, result = loadedbypath(luaname,name,luapaths,false,"lua") - if done then - return true, result - end + return loadedbypath(addsuffix(lualibfile(name),"lua" ),name,getextraluapaths(),false,"lua") end methods["lib extra list"] = function(name) - local thename = lualibfile(name) - local libname = addsuffix(thename,os.libsuffix) - local libpaths = getextralibpaths() - local done, result = loadedbypath(libname,name,libpaths,true,"lib") - if done then - return true, result - end + return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true, "lib") end -local shown = false - methods["path specification"] = function(name) - if not shown and helpers.trace then - local luapaths = getluapaths() -- triggers list building - if #luapaths > 0 then - helpers.report("using %s built in lua paths",#luapaths) - else - helpers.report("no built in lua paths defined") - end - shown = true - end - local result = builtin["path specification"](name) - if type(result) == "function" then - return true, result() - end + getluapaths() -- triggers list building and tracing + return builtin["path specification"](name) end -local shown = false - methods["cpath specification"] = function(name) - if not shown and helpers.trace then - local libpaths = getlibpaths() -- triggers list building - if #libpaths > 0 then - helpers.report("using %s built in lib paths",#libpaths) - else - helpers.report("no built in lib paths defined") - end - shown = true - end - local result = builtin["cpath specification"](name) - if type(result) == "function" then - return true, result() - end + getlibpaths() -- triggers list building and tracing + return builtin["cpath specification"](name) end methods["all in one fallback"] = function(name) - local result = builtin["all in one fallback"](name) - if type(result) == "function" then - return true, result() - end + return builtin["all in one fallback"](name) end methods["not loaded"] = function(name) if helpers.trace then - helpers.report("unable to locate '%s'",name) + helpers.report("unable to locate '%s'",name or "?") end + return nil end +local level = 0 +local used = { } + +helpers.traceused = false + function helpers.loaded(name) local sequence = helpers.sequence + level = level + 1 for i=1,#sequence do - local step = sequence[i] + local method = sequence[i] if helpers.trace then - helpers.report("locating '%s' using method '%s'",name,step) + helpers.report("%s, level '%s', method '%s', name '%s'","locating",level,method,name) end - local done, result = methods[step](name) - if done then + local result, rest = methods[method](name) + if type(result) == "function" then if helpers.trace then - helpers.report("'%s' located via method '%s' returns '%s'",name,step,type(result)) + helpers.report("%s, level '%s', method '%s', name '%s'","found",level,method,name) end - if result then - package.loaded[name] = result + if helpers.traceused then + used[#used+1] = { level = level, name = name } end - return result + level = level - 1 + return result, rest end end - return nil -- we must return a value + -- safeguard, we never come here + level = level - 1 + return nil +end + +function helpers.showused() + local n = #used + if n > 0 then + helpers.report("%s libraries loaded:",n) + helpers.report() + for i=1,n do + local u = used[i] + helpers.report("%i %a",u.level,u.name) + end + helpers.report() + end end function helpers.unload(name) if helpers.trace then if package.loaded[name] then - helpers.report("unloading '%s', %s",name,"done") + helpers.report("unloading, name '%s', %s",name,"done") else - helpers.report("unloading '%s', %s",name,"not loaded") + helpers.report("unloading, name '%s', %s",name,"not loaded") end end - package.loaded[name] = nil -- does that work? is readable only, maybe we need our own hash + package.loaded[name] = nil end -searchers[1] = nil -searchers[2] = nil -searchers[3] = nil -searchers[4] = nil - -helpers.savedrequire = helpers.savedrequire or require +-- overloading require does not work out well so we need to push it in +-- front .. -require = helpers.loaded +table.insert(searchers,1,helpers.loaded) diff --git a/lualibs-table.lua b/lualibs-table.lua index 640bbbb..e57abe8 100644 --- a/lualibs-table.lua +++ b/lualibs-table.lua @@ -1094,7 +1094,7 @@ function table.tofile(filename,root,name,specification) end end -local function flattened(t,f,depth) +local function flattened(t,f,depth) -- also handles { nil, 1, nil, 2 } if f == nil then f = { } depth = 0xFFFF @@ -1110,19 +1110,16 @@ local function flattened(t,f,depth) if depth > 0 and type(v) == "table" then flattened(v,f,depth-1) else - f[k] = v + f[#f+1] = v end end end - local n = #f for k=1,#t do local v = t[k] if depth > 0 and type(v) == "table" then flattened(v,f,depth-1) - n = #f else - n = n + 1 - f[n] = v + f[#f+1] = v end end return f diff --git a/lualibs-util-env.lua b/lualibs-util-env.lua index 283b91c..f4f3ef6 100644 --- a/lualibs-util-env.lua +++ b/lualibs-util-env.lua @@ -206,6 +206,35 @@ function environment.reconstructcommandline(arg,noquote) end end +-- handy in e.g. package.addluapath(environment.relativepath("scripts")) + +function environment.relativepath(path,root) + if not path then + path = "" + end + if not file.is_rootbased_path(path) then + if not root then + root = file.pathpart(environment.ownscript or environment.ownname or ".") + end + if root == "" then + root = "." + end + path = root .. "/" .. path + end + return file.collapsepath(path,true) +end + +-- -- when script lives on e:/tmp we get this: +-- +-- print(environment.relativepath("x/y/z","c:/w")) -- c:/w/x/y/z +-- print(environment.relativepath("x")) -- e:/tmp/x +-- print(environment.relativepath("../x")) -- e:/x +-- print(environment.relativepath("./x")) -- e:/tmp/x +-- print(environment.relativepath("/x")) -- /x +-- print(environment.relativepath("c:/x")) -- c:/x +-- print(environment.relativepath("//x")) -- //x +-- print(environment.relativepath()) -- e:/tmp + -- -- to be tested: -- -- function environment.reconstructcommandline(arg,noquote) -- cgit v1.2.3