Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- -*- coding: raw-text-unix; backup-by-copying: t -*- -- This file: http://angg.twu.net/LUA/lua50init.lua.html -- http://angg.twu.net/dednat4/edrxlib.lua.html -- http://angg.twu.net/blogme3/edrxlib.lua.html -- On my system ~/LUA/lua50init.lua the two "edrxlib.lua"s -- are hard linked: -- (find-sh0 "cp -flv ~/LUA/lua50init.lua ~/dednat4/edrxlib.lua") -- (find-sh0 "cp -flv ~/LUA/lua50init.lua ~/blogme3/edrxlib.lua") -- (find-sh0 "ls -li ~/LUA/lua50init.lua ~/{dednat4,blogme3}/edrxlib.lua") -- (find-tkdiff "~/LUA/lua50init.lua" "~/dednat4/edrxlib.lua") -- (find-tkdiff "~/LUA/lua50init.lua" "~/dednat4/blogme3.lua") -- (find-elnode "Rename or Copy" "hard links") -- (find-elnode "Rename or Copy" "backup-by-copying") -- -- This is my "init file" for Lua. As I have LUA_INIT set -- to "@$HOME/LUA/lua50init.lua", the Lua interpreter loads -- this on start-up. -- See: (find-angg ".zshrc" "lua" "LUA_INIT") -- (find-luamanualw3m "#6" "LUA_INIT" "@filename") -- (find-man "1 lua50" "LUA_INIT") -- (find-man "1 lua51" "LUA_INIT") -- (find-lua51w3m "doc/lua.html" "LUA_INIT") -- http://www.lua.org/manual/5.1/lua.html -- http://linux.die.net/man/1/lua -- Author: Eduardo Ochs <[email protected]> -- Version: 2010sep01 -- Public domain. -- -- Note: "dednat4.lua" tries to load this at startup, with -- 'require "edrxlib"', just after setting the path; if this has -- already been loaded by LUA_INIT, then the 'require "edrxlib"' -- is a no-op, because of the "package.loaded.edrxlib = ..." at -- the end of this file - otherwise it is loaded, probably from -- the "~/dednat4/" dir. See this for the details: -- (find-dn4 "dednat4.lua" "edrxlib") -- -- Blogme3 does the same trick: -- (find-blogme3 "blogme3.lua" "edrxlib") -- -- This file used to work both on lua-5.0 and lua-5.1 - -- but now I have stopped using lua-5.0, and I'm trying -- (slowly!) to make this more readable, remove the -- cruft, some 5.0-isms, some obsolete loaders, etc. -- «.escripts» (to "escripts") -- «.build-lua» (to "build-lua") -- «.compat» (to "compat") -- «.string-methods» (to "string-methods") -- «.otherfunctions» (to "otherfunctions") -- «.printf» (to "printf") -- «.pack-and-unpack» (to "pack-and-unpack") -- «.0-based» (to "0-based") -- «.P» (to "P") -- «.PP» (to "PP") -- «.PPP» (to "PPP") -- «.tests» (to "tests") -- «.envsubst» (to "envsubst") -- «.readfile» (to "readfile") -- «.mytostring» (to "mytostring") -- «.mysortedpairs» (to "mysortedpairs") -- «.mytostringk2» (to "mytostringk2") -- «.split» (to "split") -- «.ee_expand» (to "ee_expand") -- «.ee_dofile» (to "ee_dofile") -- «.ee_loadlib» (to "ee_loadlib") -- «.untabify» (to "untabify") -- «.load_dednat4» (to "load_dednat4") -- «.load_rex» (to "load_rex") -- «.load_posix» (to "load_posix") -- «.load_PP» (to "load_PP") -- «.PPeval» (to "PPeval") -- «.loadswigso» (to "loadswigso") -- «.loadcinvoke» (to "loadcinvoke") -- «.loadlpeg» (to "loadlpeg") -- «.loadbitlib» (to "loadbitlib") -- «.autoload» (to "autoload") -- «.loadtcl» (to "loadtcl") -- «.loadldb» (to "loadldb") -- «.loadpeek» (to "loadpeek") -- «.loadalarm» (to "loadalarm") -- «.loadposix» (to "loadposix") -- «.getoutput» (to "getoutput") -- «.preparef2n» (to "preparef2n") -- «.each2» (to "each2") -- «.splitlines» (to "splitlines") -- «.translatechars» (to "translatechars") -- «.sbeconcat» (to "sbeconcat") -- «.concatbestrings» (to "concatbestrings") -- «.lpeg_togsub» (to "lpeg_togsub") -- «.lpeg_gsub» (to "lpeg_gsub") -- «.lpeg_gsub_» (to "lpeg_gsub_") -- «.lpeg_balanced» (to "lpeg_balanced") -- «.over» (to "over") -- «.interactor» (to "interactor") -- «.mytraceback» (to "mytraceback") -- «.errorfb_line» (to "errorfb_line") -- «.ee_template» (to "ee_template") -- «.ee_into» (to "ee_into") -- «.chdir» (to "chdir") -- «.package.require» (to "package.require") -- «escripts» (to ".escripts") -- «build-lua» (to ".build-lua") -- (find-es "lua5" "install-5.1.2") -- «compat» (to ".compat") -- On Lua 4.x these functions had the short names on the left; -- on Lua-5.0.x a file etc/compat.lua could be used to make the short -- names work, but on Lua-5.1.x this compat.lua has been dropped... -- I still like the short names, so: -- (find-lua51file "src/lstrlib.c" "{\"find\", str_find},") -- (find-lua50file "etc/compat.lua" "strfind = str.find") write = io.write -- (find-luamanualw3m "#pdf-io.write") format = string.format -- (find-luamanualw3m "#pdf-string.format") gsub = string.gsub -- (find-luamanualw3m "#pdf-string.gsub") strfind = string.find -- (find-luamanualw3m "#pdf-string.find") strlen = string.len -- (find-luamanualw3m "#pdf-string.len") strsub = string.sub -- (find-luamanualw3m "#pdf-string.sub") concat = table.concat -- (find-luamanualw3m "#pdf-table.concat") tinsert = table.insert -- (find-luamanualw3m "#pdf-table.insert") tremove = table.remove -- (find-luamanualw3m "#pdf-table.remove") -- foreachi = table.foreachi -- (find-luamanualw3m "#7.2" "table.foreachi") getn = table.getn -- (find-luamanualw3m "#7.2" "table.getn") -- «string-methods» (to ".string-methods") -- A note about "string methods": if s is a string, then a piece of -- code like "s:rep(2)" works like "string.rep(s, 2)"; this is a -- Lua-5.1-ism that is not described in the first edition of PiL - the -- one that is online, that covers only Lua 5.0. When we do -- -- s = "foo" -- print(s:rep(2)) -- -- then the "s:rep(2)" is syntax sugar for 's["rep"](s,2)'. At first -- sight, the table access s["rep"] should fail, but in 5.1 strings -- have a metatable like this: -- -- setmetatable("str", {__index = string}) -- -- and so instead of failing Lua does something else... the s["rep"] -- becomes getmetatable(s).__index["rep"], and that is just -- string["rep"], i.e., string.rep; so, s:rep(2) works like -- string.rep(s, 2). -- -- See: -- (find-luamanualw3m "#2.2" "a.name as syntactic sugar") -- (find-luamanualw3m "#2.5.8" "v:name(args)" "v.name(v,args)") -- (find-luamanualw3m "#2.8" "Tables and userdata have individual metatables") -- (find-luamanualw3m "#2.8" "table[key]" "h = metatable(table).__index") -- (find-luamanualw3m "#5.4" "object-oriented style" "s:byte(i)") -- (find-luamanualw3m "#pdf-string.rep") -- (find-pilw3m "13.4.1.html" "The __index Metamethod") -- «otherfunctions» (to ".otherfunctions") -- «printf» (to ".printf") -- printf = function (...) write(format(unpack(arg))) end printf = function (...) write(format(...)) end -- «pack-and-unpack» (to ".pack-and-unpack") -- (find-es "lua5" "pack-and-unpack") -- (find-es "lua5" "LUA_COMPAT_VARARG") -- (find-luamanualw3m "#pdf-unpack") -- (find-luamanualw3m "#7.1" "pseudo-argument arg") -- 5.1 only: -- pack = function (...) return arg end -- myunpack = function (arg) return unpack(arg, 1, arg.n) end -- These definitions should work both on 5.1 and on 5.2: pack = table.pack or function (...) return arg end unpack = unpack or table.unpack myunpack = function (arg) return unpack(arg, 1, arg.n) end -- Examples: -- PP(pack(nil, 22, nil, 44, nil)) --> {2=22, 4=44, "n"=5} -- PP(unpack({nil, 22, nil, 44, nil, n=5})) --> <nil> 22 -- PP(myunpack({nil, 22, nil, 44, nil, n=5})) --> <nil> 22 <nil> 44 <nil> -- «0-based» (to ".0-based") -- (find-es "lua5" "0-based") -- 0-based string functions. -- (To do: remove this! I think I only use 0-based string functions at -- dednat4 - and now I'm almost getting used to the 1-based -- conventions...) -- (find-sh "lua -e \"print(substr0('abcdef', 2, 3)) --> cde\"") substr0 = function (str, start0, len) return string.sub(str, start0 + 1, len and start0 + len) end -- «P» (to ".P") -- Like "print", but distinguishing strings from numbers, and using "<>"s. -- See: (find-luamanualw3m "#pdf-type") -- Examples: -- print(nil, 22, "33", {}, false, print) --> nil 22 33 table: 0x806da60 false function: 0x806b388 -- P(nil, 22, "33", {}, false, print) --> <nil> 22 "33" <table> <boolean> <function> -- P = function (...) local arg = arg or pack(...) -- for Lua 5.2 for i=1,arg.n do local v = arg[i] if type(v)=="number" then printf(" %d", v) elseif type(v)=="string" then printf(" %q", v) else printf(" <%s>", type(v)) end end print() end -- Note: "table.foreach(t, print)" is often enough for inspecting tables. -- Ref: http://lua-users.org/lists/lua-l/2008-02/msg00932.html -- http://lua-users.org/lists/lua-l/2008-02/msg00944.html -- «PP» (to ".PP") -- My favourite function for inspecting data! -- This is like "print" too, but it uses "mytostring" to print the -- contents of tables recursively. The output format is compact, -- human-friendly, and simple to understand and to implement. Note: on -- cyclic structures "mytostring" will loop and break; and metatables -- are ignored (I use them very rarely, btw). -- Examples: -- PP(nil, true, false, 22, "22", "a\nb", print, nil) --> <nil> <true> <false> 22 "22" "a\ -- b" <function: 0x806b388> <nil> -- -- PP({44, 55, nil, 77, [{a=11}]={[22]="b"}, [{}]={}, [{}]={}}) --> {1=44, 2=55, 4=77, {"a"=11}={22="b"}, {}={}, {}={}} -- PP = function (...) local arg = arg or pack(...) -- for Lua 5.2 for i=1,arg.n do printf(" %s", mytostring(arg[i])) end printf("\n") return myunpack(arg) -- todo: change to "..." (a 5.1-ism) end -- «PPP» (to ".PPP") -- Useful for debugging sometimes. -- I don't use this much. -- PP(string.rep("ab", 4)) --> "abababab" -- PP(string.rep(PPP("rep:")("ab", 4))) --> (rep: "ab" 4)"abababab" PPP = function (idstr) return function (...) printf("(%s", idstr) for i=1,arg.n do printf(" %s", mytostring(arg[i])) end printf(")") return unpack(arg) end end -- «tests» (to ".tests") -- P(string.find("0123456789", "3(45)(67)", 4)) --> 4 8 "45" "67" -- P(string.find("0123456789", "3(45)(67)", 5)) --> <nil> -- «envsubst» (to ".envsubst") -- (find-es "lua5" "envsubst") setenv_ = {} setenv = function (varname, value) setenv_[varname] = value end getenv = function (varname) return setenv_[varname] or os.getenv(varname) end envsubst = function (str) return string.gsub(str, "%$([%a_][%w_]*)", function (e) return getenv(e) or "" end) end -- «readfile» (to ".readfile") -- (find-es "lua5" "readfile") -- (find-luamanualw3m "#pdf-io.open") -- (find-luamanualw3m "#pdf-file:read") -- (find-luamanualw3m "#pdf-file:write") readfile = function (fname) local f = assert(io.open(fname, "r")) local bigstr = f:read("*a") f:close() return bigstr end writefile = function (fname, bigstr) local f = assert(io.open(fname, "w+")) f:write(bigstr) f:close() end -- «mytostring» (to ".mytostring") -- mysort, mytostring, and mytostring_arg are used interally by "PP". -- (find-es "lua5" "mytostring") -- A possible replacement: -- (find-angg "LUA/tos.lua") mysort = function (origtable) local tmptable = {} for key,val in pairs(origtable) do table.insert(tmptable, {key=key, val=val}) end local comp = function (item1, item2) local key1, key2 = item1.key, item2.key local type1, type2 = type(key1), type(key2) if type1==type2 then if type1=="number" then return key1 < key2 end if type1=="string" then return key1 < key2 end return tostring(key1) < tostring(key2) else return type1<type2 end end table.sort(tmptable, comp) return tmptable end mytostring_table_orig = function (o, sep) -- o is a table local images = {} for _,p in ipairs(mysort(o)) do table.insert(images, mytostringk(p.key).."="..mytostring(p.val)) end return "{"..table.concat(images, sep or ", ").."}" end mytostring_table_new = function (o, sep) -- o is a table if getmetatable(o) and getmetatable(o).__tostring then return tostring(o) end return mytostring_table_orig(o, sep) end mytostring_table = mytostring_table_new mytostring = function (o) local t = type(o) if t=="number" then return tostring(o) end if t=="string" then return format("%q", o) end if t=="table" then return mytostring_table(o) end return "<"..tostring(o)..">" end mytostringk = mytostring -- change this to print string keys differently mytostring_arg = function (arg, sep) local images = {} for i=1,arg.n do images[i] = mytostring(arg[i]) end return table.concat(images, sep or " ") end -- mytostring_arg({n=4, nil, 22, 33, nil}) --> "<nil> 22 33 <nil>" -- «mysortedpairs» (to ".mysortedpairs") -- This is useful in iteractive scripts. The name is bad, I know. -- (find-pilw3m "7.1.html" "simple iterator") mysortedpairs = function (T) local T = mysort(T) local i,n = 0,#T return function () i = i + 1 if i <= n then return T[i].key,T[i].val end end end -- «mytostringk2» (to ".mytostringk2") -- Experimental. Usage: -- mytostringk = mytostringk2 mytostringk2 = function (o) if type(o) == "string" and o:match("^[A-Za-z_][A-Za-z_0-9]*$") then return o else return mytostring(o) end end -- «split» (to ".split") -- (find-es "lua5" "split") split = function (str, pat) local arr = {} string.gsub(str, pat or "([^%s]+)", function (word) table.insert(arr, word) end) return arr end -- «ee_expand» (to ".ee_expand") -- (find-eev "eev.el" "ee-expand") ee_expand = function (path) path = string.gsub(path, "^~$", "$HOME/", 1) path = string.gsub(path, "^~/", "$HOME/", 1) path = string.gsub(path, "^%$(%w+)", os.getenv, 1) return path end -- «ee_dofile» (to ".ee_dofile") -- «ee_loadlib» (to ".ee_loadlib") ee_dofile = function (path) return dofile(ee_expand(path)) end ee_loadlib = function (libname, funcname) return assert(package.loadlib(ee_expand(libname), funcname))() end -- «untabify» (to ".untabify") -- Note: to untabify strings in encodings where chars can be more than -- 1-byte long, change the "strlen" below... (I never had to do that, -- though). untabify_table = {" ", " ", " ", " ", " ", " ", " ", " "} --{"--------", "-------", "------", "-----", "----", "---", "--", "-"} untabify_strtab = function (strbeforetab) return strbeforetab .. untabify_table[math.mod(strlen(strbeforetab), 8) + 1] end untabify = function (str) return (gsub(str, "([^\t\r\n]*)\t", untabify_strtab)) end -- (find-luamanualw3m "#pdf-math.min") -- (find-luamanualw3m "#pdf-math.max") -- PP(math.min("22", "200")) --> 22 -- PP(min("22", "200")) --> "200" min = function (a, b) if a < b then return a else return b end end max = function (a, b) if a < b then return b else return a end end -- «load_dednat4» (to ".load_dednat4") -- (find-angg ".emacs" "eepitch-dednat4") -- (find-es "xypic" "eepitch-dednat4") -- (find-dn4 "dednat4.lua" "diag-head") -- (find-dn4 "dednat4.lua" "abbrev-head") -- (find-dn4 "dednat4.lua" "tree-head" "treeheadcode1") -- (find-dn4 "dednat4.lua" "processfile") -- (defun eepitch-dednat4 () (interactive) (eepitch-comint "dednat4" "lua51 -e load_dednat4() -i")) -- (eepitch-kill) -- (eepitch-dednat4) load_dednat4 = function () dednat4dir = dednat4dir or ee_expand("~/dednat4/") print("Loading: " .. dednat4dir .. "dednat4.lua") dofile(dednat4dir .. "dednat4.lua") A = function (abbrev, expansion) addabbrev(abbrev, expansion) end D = function (linestr) dofs(untabify(linestr)) end DX = function (linestr) dxy2Dx(untabify(linestr)) end D2 = function (linestr) dxy2D(untabify(linestr)) end end -- «load_rex» (to ".load_rex") -- (find-es "lua5" "rexlib") -- Usage: if not rex then load_rex() end -- Note (2007): I haven't used this in ages! -- Lpeg is much better, and nowadays I would try to use "require" here -- instead of loadlib... load_rex = function () assert(loadlib(getenv("HOME").."/.lua50/lrexlib.so", "luaopen_rex"))() setmetatable(rex, {__call = function (self, p, cf, lo) return self.newPOSIX(p, cf, lo) end}) function rex.find(s, p, st) return rex(p):match(s, st) end function rex.gsub(s, p, f, n) return rex(p):gmatch(s, f, n) end end -- «load_posix» (to ".load_posix") -- This is for lua-5.0, for 5.1 see: (to "loadposix") -- (find-es "lua5" "load_posix") -- (find-es "lua5" "posix-install") load_posix = function () assert(loadlib(getenv("HOME").."/.lua50/lposix.so", "luaopen_posix"))() end -- «load_PP» (to ".load_PP") -- Load PP.so, that defines a C function called PP for inspecting the stack. -- Old version, for lua-5.0: -- -- (find-angg ".lua50/PP.c") -- load_PP = function () -- assert(loadlib(getenv("HOME").."/.lua50/PP.so", "PP_init"))() -- end -- New version, for lua-5.1: load_PP = function () assert(package.loadlib(getenv("HOME").."/.lua51/PP.so", "PP_init"))() end -- 2008dec01: load_PP is not needed for debugging anymore!... -- The user-defined GDB command `PP' used to call the C function `PP', -- that was defined in PP.c/PP.so - but I changed the GDB `PP' to make -- it run directly all the calls to Lua that the C `PP' used to make. -- See: (find-angg ".lua51/PP.c") -- (find-angg ".lua51/PP.gdb") -- «PPeval» (to ".PPeval") -- (find-angg ".lua51/PP.gdb" "PPeval") -- (find-lua51file "src/lua.c" "first line starts with `=' ?") PPeval = function (str) local e, code = string.match(str, "^(=?=?)(.*)$") local eval = function (str) return assert(loadstring(str))() end if e == "==" then PP(eval("return "..code)) elseif e == "=" then print(eval("return "..code)) else return eval(code) end end -- «loadswigso» (to ".loadswigso") -- (find-es "swig" "myswiglua") -- Example: loadswigso("C", "./myparser.so", "parser", "countwords") loadswigso = function (modulename, fname_so, ...) assert(loadlib(fname_so, modulename.."_Init"))() local module = _G[modulename] for i=1,arg.n do _G[arg[i]] = module[arg[i]] -- export to the table of globals end end -- «loadcinvoke» (to ".loadcinvoke") -- (find-es "lua5" "cinvoke") loadcinvoke = function () local oldcpath = package.cpath package.cpath = ee_expand("~/usrc/cinvoke-1.0/bindings/lua/?.so") require "cinvoke_lua" package.cpath = oldcpath end -- «loadlpeg» (to ".loadlpeg") -- (find-es "lua5" "lpeg-0.7") -- (find-es "lua5" "lpeg-0.8.1") -- (find-es "lua5" "lpeg-0.9") -- (find-es "lua5" "lpeg") loadlpeg = function () local oldcpath = package.cpath -- package.cpath = ee_expand("~/usrc/lpeg-0.4/?.so") -- package.cpath = ee_expand("~/usrc/lpeg-0.5/?.so") -- package.cpath = ee_expand("~/usrc/lpeg-0.7/?.so")..";"..oldcpath -- (find-luamanualw3m "#pdf-package.cpath") -- (find-sh0 "lua51 -e 'print(package.path)'") -- (find-sh0 "lua51 -e 'print(package.cpath)'") -- package.cpath = ee_expand("~/usrc/lpeg-0.8.1/?.so")..";"..oldcpath package.cpath = ee_expand("~/usrc/lpeg-0.9/?.so")..";"..oldcpath require "lpeg" package.cpath = oldcpath lpeg.test = function (pat, str) PP(pat:C():match(str)) end lpeg.testt = function (pat, str) PP(pat:Ct():match(str)) end lpeg.togsub = lpeg_togsub -- (to "lpeg_togsub") lpeg.gsub = lpeg_gsub -- (to "lpeg_gsub") lpeg.gsub_ = lpeg_gsub_ -- (to "lpeg_gsub_") lpeg.Balanced = lpeg_balanced -- (to "lpeg_balanced") end -- «loadbitlib» (to ".loadbitlib") -- (find-es "lua5" "bitlib-51") loadbitlib = function (fname) if bit then return "bitlib already loaded" end fname = fname or "~/usrc/bitlib-25/lbitlib.so" assert(package.loadlib(ee_expand(fname), "luaopen_bit"))() end -- «autoload» (to ".autoload") -- Like in elisp. For global functions only. -- (find-luamanualw3m "#pdf-require") -- autoload = function (funname, loader) _G[funname] = function (...) loader() return _G[funname](unpack(arg)) -- todo: change to "..." (a 5.1-ism) end end tcl = function (...) -- <-- this is a kind of autoload local filename = ee_expand("~/.lua51/luatclbridge.so") local initname = "luaopen_luatclbridge" tcl = assert(package.loadlib(filename, initname))() return tcl(unpack(arg)) -- todo: change to "..." (a 5.1-ism) end -- «loadtcl» (to ".loadtcl") -- (find-es "lua5" "luatclbridge") -- (find-angg "LUA/luatclbridge.c") -- loadtcl = function () -- local filename = ee_expand("~/LUA/tlbridge.so") -- local initname = "luaopen_tlbridge" -- tcl = tcl or assert(package.loadlib(filename, initname))() -- end loadtcl = function () -- local filename = ee_expand("~/LUA/luatclbridge.so") local filename = ee_expand("~/.lua51/luatclbridge.so") local initname = "luaopen_luatclbridge" if not tcl then tcl, tclfindexecutable = assert(package.loadlib(filename, initname))() tclfindexecutable("/home/edrx/usrc/tk8.4/tk8.4-8.4.12/unix/wish") -- test end end loadtk = function () loadtcl(); return tcl("package require Tk") end loadexpect = function () loadtcl(); return tcl("package require Expect") end loadsnack = function () loadtcl(); return tcl("package require sound") end -- (find-es "tcl" "snack") -- (find-anggfile "TCL/piano.tcl") -- «loadldb» (to ".loadldb") -- (find-es "lua5" "ldb-from-tgz") -- (find-es "lua5" "ldb") loadldb = function () local oldpath = package.path -- package.path = ee_expand("$S/http/primero.ricilake.net/lua/?.lua") -- package.path = ee_expand("~/LUA/?.lua") package.path = ee_expand("~/usrc/ldb/?.lua") ldb = require "ldb" package.path = oldpath end -- «loadpeek» (to ".loadpeek") -- (find-angg "DAVINCI/peek.c") -- (find-angg "DAVINCI/peek.lua") loadpeek = function () if not peek then assert(package.loadlib(ee_expand("~/DAVINCI/peek.so"), "peek_init"))() end end getaddr = function (obj) return tonumber(string.match(tostring(obj), " 0x([0-9A-Za-z]+)"), 16) end -- «loadalarm» (to ".loadalarm") -- (find-es "lua5" "signal") loadalarm = function () if not alarm then assert(package.loadlib(ee_expand("~/usrc/alarm/lalarm.so"), "luaopen_alarm"))() end end -- «loadposix» (to ".loadposix") -- New way (active below): (find-es "lua5" "luaposix") -- old way (commented out): (find-es "lua5" "posix-lua51") loadposix = function () if not posix then -- assert(package.loadlib(ee_expand("~/usrc/posix/lposix.so"), "luaopen_posix"))() ee_loadlib("~/usrc/luaposix-5.1.4/posix.so", "luaopen_posix") end end -- «getoutput» (to ".getoutput") -- (find-es "lua5" "getoutput") getoutput = function (command) local pipe = assert(io.popen(command)) local output = pipe:read("*a") pipe:close() return output end -- «preparef2n» (to ".preparef2n") -- (find-es "lua5" "functionnames") -- preparef2n: create a table with names of functions. -- Example: -- f2n = preparef2n() -- print(f2n(loadstring)) --> "loadstring" -- -- This is new (2007mar11), and not very well-tested. -- Note: there's no support yet for submodules (like "socket.http"). -- I wrote this for my traceback functions... -- preparef2n__ = function (fun2name, dictname, dictnamedot, dict) for name,value in pairs(dict or _G) do if type(value) == "function" then if string.match(name, "^[A-Za-z_][0-9A-Za-z_]*$") then fun2name[value] = dictnamedot..name else fun2name[value] = string.format("%s[%q]", dictname, name) end end end end preparef2n_ = function (fun2name, dictnames) for _,dn in ipairs(split(dictnames)) do if dn == "_G" then preparef2n__(fun2name, "_G", "", _G) else preparef2n__(fun2name, dn, dn..".", _G[dn]) end end end preparef2n = function (otherdictnames) local f2n = {} local standarddicts = " coroutine debug io math os package string table " preparef2n_(f2n, standarddicts .. (otherdictnames or "") .. " _G ") return f2n end --------[ keys, map, seq, nop, each2, splitlines, chartranslator ]-------- keys = function (tbl) local ks = {} for k,_ in pairs(tbl) do tinsert(ks,k) end return ks end map = function (f, arr, n) local brr = {} for i=1,(n or #arr) do tinsert(brr, f(arr[i])) end return brr end seq = function (a, b, c) local arr = {} for i=a,b,(c or 1) do tinsert(arr, i) end return arr end nop = function () end id = function (...) return ... end -- «each2» (to ".each2") -- (find-es "lua5" "each2") each2 = function (tbl) local i = 1 return function () if i <= getn(tbl) then i = i + 2 return tbl[i - 2], tbl[i - 1] end end end -- «splitlines» (to ".splitlines") splitlines = function (bigstr) local arr = split(bigstr, "([^\n]*)\n?") tremove(arr) return arr end -- «translatechars» (to ".translatechars") -- (find-node "(coreutils)Translating") translatechars = function (str, re, tbl) return (gsub(str, re, function (c) return tbl[c] or c end)) end -- chartranslator = function (re, tbl) -- return function (str) -- return gsub(str, re, function (c) return tbl[c] or c end) -- end -- end -- -- sgmlify = chartranslator(sgmlify_re, sgmlify_table) -- «sbeconcat» (to ".sbeconcat") -- Concatenate a table with strings and with begin/end pairs -- Example: -- sbeconcat("abfoocd"){1, 3, "FOO", 6, 8} --> "abFOOcd" -- This is ugly! concatbestrings, below, is much clearer. -- sbeconcat = function (subj, f) f = f or function (str) return str end return function (table1) local table2, i, n = {}, 1, table.getn(table1) while i <= n do local obj = table1[i] if type(obj) == "string" then tinsert(table2, obj) i = i + 1 else local str = string.sub(subj, obj, table1[i+1] - 1) tinsert(table2, f(str)) --< sgmlify? i = i + 2 end end return table.concat(table2) end end -- «concatbestrings» (to ".concatbestrings") -- A "table of bestrings" is a table containing pairs of numbers -- (begin/end pairs) and strings. Example: -- concatbestrings("abfoocd", nil, {1, 3, "FOO", 6, 8}) --> "abFOOcd" -- (a table of bestrings) -> \-----------------/ -- concatbestrings = function (subj, f, bestrings) f = f or function (s) return s end local table2, i = {}, 1 while i <= #bestrings do local obj = bestrings[i] if type(obj) == "string" then table.insert(table2, obj) i = i + 1 else local str = string.sub(subj, obj, bestrings[i+1] - 1) table.insert(table2, f(str)) i = i + 2 end end return table.concat(table2) end curriedconcatbestrings = function (subj, f) return function (bestrings) return concatbestrings(subj, f, bestrings) end end -- «lpeg_togsub» (to ".lpeg_togsub") -- «lpeg_gsub» (to ".lpeg_gsub") -- A pattern that returns a string can be "Kleene-starred with -- the least possible filling" to create a pattern that works -- somewhat like a gsub, but that returns a table of bestrings... -- Roughly, that would be like converting "(pat)" into -- "\\(().-()(pat)\\)*().-()", where the "\\(...\\)" is a "shy -- group" - i.e., its parentheses do not return a capture. -- -- Actually this returns a sequence of captures, not a table; use Ct() -- to pack them in to a table, and then a concatbestrings. -- -- The logic: the pattern PosPosWord, below, works like this: -- -- -> Pos -----+1--> Pos --> Word --> -- ^ 2 -- | \---> Anychar ->\ -- | | -- \------------------/ -- -- where each "Pos" returns a number, and "Word" returns a string. -- The "1" and the "2" indicate the order in which the branches are -- tried (at the "+"). The rest of the function shouldn't be hard to -- understand. -- -- (find-es "lua5" "lpeg-quickref") lpeg_togsub = function (Word) local Pos = lpeg.Cp() local AnyChar = lpeg.P(1) local BeRest = Pos * AnyChar^0 * Pos local PosPosWord = Pos * lpeg.P { Pos * Word + AnyChar * lpeg.V(1) } return PosPosWord^0 * BeRest end lpeg_gsub = function (Word, subj, f) f = f or function (...) return ... end return concatbestrings(subj, f, Word:togsub():Ct():match(subj)) end -- Example: -- loadlpeg() -- Word = lpeg.R("AZ")^1 / function (s) return "<"..s..">" end -- = Word:gsub("abFOOcdBAR", function (s) return "_"..s.."_" end) -- --> "_ab_<FOO>_cd_<BAR>__" -- «lpeg_gsub_» (to ".lpeg_gsub_") -- An alternative (faster but more complex): -- With gsub_ we can reuse a prebuilt :togsub():Ct() pattern, -- without having to build it anew each time. -- loadlpeg() -- WordTogsubCt = Word:togsub():Ct() -- = WordTogsubCt:gsub_("abFOOcdBAR", function (s) return "_"..s.."_" end) -- --> "_ab_<FOO>_cd_<BAR>__" -- lpeg_gsub_ = function (WordTogsubCt, subj, f) f = f or function (...) return ... end return concatbestrings(subj, f, WordTogsubCt:match(subj)) end -- «lpeg_balanced» (to ".lpeg_balanced") -- (find-angg "LUA/preproc.lua") lpeg_balanced = function (Open, MidChars, Close) local Middle Open = lpeg.P(Open) Close = lpeg.P(Close) MidChars = MidChars or (1 - (Open + Close))^1 Middle = lpeg.P { (MidChars + Open * lpeg.V(1) * Close)^0 } return Open * Middle:C() * Close, Middle end -- «over» (to ".over") -- Example: -- A = {a=22} -- B = over(A, {b=33}) -- PP(B, A, B.b, B.a) -- --> {"b"=33} {"a"=22} 33 22 over = function (bottomtable, toptable) return setmetatable(toptable or {}, {__index = bottomtable}) end -- «interactor» (to ".interactor") -- This is very new, incomplete, etc; I'm rewriting it. -- The new version is at: (find-angg "LUA/reader.lua") -- (find-es "lua5" "interactor") -- (find-THLw3m "repl.html") -- Example: -- compiled, errmsg = interactor():read(".>"):complete() -- Some explanations: -- interactor() returns a table that is "over" interactor_metatable, -- I:read(".>") reads the first line with prompt ".>", -- I:complete() tries to run loadstring(I:body()); while that is -- not a complete Lua chunk, keep reading. When either -- the input becomes complete or another error besides -- "incomplete" occurs, return I.compiled and I.errmsg. -- Notes: -- On "abort" (i.e., either reading a line with just ".", or getting -- an eof), I:complete() returns two nils. In all the other cases -- exactly one of I.compiled, I.errmsg will be non-nil, and -- assert(I.compiled, I.errmsg)() would do what's expected. -- I'm planning the treat an abort at the first line specially - -- meaning "return from the interactor loop". -- This doesn't do much at this moment - I'm experiment with loops -- around interactor():read(".>"):complete(), but the code for -- these experiments is elsewhere... -- interactor_metatable = { concat = function (self) return table.concat(self, "\n") end, body = function (self) return self:concat() end, -- overriddable prompt = function (self) return ">> " end, -- overriddable abort = function (self) end, -- overriddable; message load = function (self) if self.line then self.compiled, self.errmsg = loadstring(self:body()) self.incomplete = self.errmsg and string.find(self.errmsg, ": unexpected symbol near '<eof>'$") else self.compiled, self.errmsg, self.incomplete = nil, nil, nil end return self end, read = function (self, prompt) io.write(prompt or self:prompt()) self.line = io.read() if self.line == "." then self:abort(); self.line = nil end if self.line then table.insert(self, self.line) end return self end, complete = function (self) while self.line and self.incomplete do self:read(); self:load() end return self end, } interactor = function () return over(interactor_metatable) end -- «mytraceback» (to ".mytraceback") -- (find-es "lua5" "xpcall" "mytraceback =") -- (find-luamanualw3m "#pdf-xpcall") -- (find-luamanualw3m "#pdf-debug.traceback") -- (find-luamanualw3m "#pdf-error") mytraceback = function (errmsg) io.output():flush() print(debug.traceback(errmsg, 2)) end xxcall = function (f) if not xpcall(f, mytraceback) then error() end end -- «errorfb_line» (to ".errorfb_line") -- (find-luamanualw3m "#lua_Debug") -- (find-lua51tag "db_errorfb" "ar.short_src") -- (find-lua51tag "dblib" "{\"traceback\", db_errorfb},") -- http://www.lua.org/source/5.1/ldblib.c.html#db_errorfb -- http://www.lua.org/source/5.1/ldblib.c.html#dblib errorfb_line = function (ar) local s = "" local printf = function (...) s = s .. format(...) end printf("%s:", ar.short_src) if ar.currentline > 0 then printf("%d:", ar.currentline) end if ar.namewhat ~= "" then printf(" in function '%s'", ar.name) else if ar.what == "main" then printf(" in main chunk") elseif ar.what == "C" or ar.what == "tail" then printf(" ?") else printf(" in function <%s:%d>", ar.short_src, ar.linedefined) end end return s end -- «ee_template» (to ".ee_template") -- (find-eev "eev-insert.el" "ee-template") -- ee_template({a="<AA>", b="<BB>"}, "foo{a}bar{c}plic") -- --> "foo<AA>bar{c}plic" ee_template = function (pairs, templatestr) return (string.gsub(templatestr, "{([^{}]+)}", pairs)) end -- «ee_into» (to ".ee_into") -- ee_into("a b c", "<AA> <BB>") -- --> {"a"="<AA>", "b"="<BB>"} ee_into = function (fieldnames, data) if type(fieldnames) == "string" then fieldnames = split(fieldnames) end if type(data) == "string" then data = split(data) end local o = {} for i=1,#fieldnames do o[fieldnames[i]] = data[i] end return o end -- «chdir» (to ".chdir") -- 2008may23 chdir = function (dir) loadposix(); return assert(posix.chdir(ee_expand(dir))) end -- «package.require» (to ".package.require") -- Make package.require consider that this file has been loaded when -- it was loaded by LUA_INIT=@.../LUA/lua50init.lua (see the comments -- at the top of this file) so that we can do 'require "lua50init"' or -- 'require "edrxlib"'... -- (find-luamanualw3m "#pdf-require") -- (find-lua51file "") -- (find-lua51file "src/loadlib.c" "static int ll_require ") package.loaded.lua50init = package.loaded.lua50init or "(loaded by LUA_INIT=@...)" package.loaded.edrxlib = package.loaded.edrxlib or "(loaded by LUA_INIT=@...)" -- Local Variables: -- coding: raw-text-unix -- ee-anchor-format: "«%s»" -- End: