diff options
author | Marius <mariausol@gmail.com> | 2013-10-20 01:20:14 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2013-10-20 01:20:14 +0300 |
commit | 965214d981e6129b782c67adcaf3a81aedcb0bac (patch) | |
tree | 84f5945aae8efc9b6eb1898b873be5453cafe43d /scripts | |
parent | e7d0d90a434e5452ff9e86c8abab5a4cac35e2f1 (diff) | |
download | context-965214d981e6129b782c67adcaf3a81aedcb0bac.tar.gz |
stable 2013.05.28 00:36
Diffstat (limited to 'scripts')
-rw-r--r-- | scripts/context/lua/mtx-context.lua | 230 | ||||
-rw-r--r-- | scripts/context/lua/mtx-flac.lua | 37 | ||||
-rw-r--r-- | scripts/context/lua/mtx-fonts.lua | 8 | ||||
-rw-r--r-- | scripts/context/lua/mtx-grep.lua | 4 | ||||
-rw-r--r-- | scripts/context/lua/mtx-plain.lua | 7 | ||||
-rw-r--r-- | scripts/context/lua/mtx-profile.lua | 32 | ||||
-rw-r--r-- | scripts/context/lua/mtx-rsync.lua | 33 | ||||
-rw-r--r-- | scripts/context/lua/mtx-server-ctx-fonttest.lua | 294 | ||||
-rw-r--r-- | scripts/context/lua/mtx-server-ctx-help.lua | 24 | ||||
-rw-r--r-- | scripts/context/lua/mtx-server.lua | 6 | ||||
-rw-r--r-- | scripts/context/lua/mtx-tools.lua | 1 | ||||
-rw-r--r-- | scripts/context/lua/mtx-update.lua | 13 | ||||
-rw-r--r-- | scripts/context/lua/mtxlibs.lua | 3 | ||||
-rw-r--r-- | scripts/context/lua/mtxrun.lua | 1678 | ||||
-rw-r--r-- | scripts/context/ruby/base/pdf.rb | 10 | ||||
-rw-r--r-- | scripts/context/ruby/base/switch.rb | 10 | ||||
-rw-r--r-- | scripts/context/ruby/base/tex.rb | 53 | ||||
-rw-r--r-- | scripts/context/stubs/mswin/mtxrun.lua | 1678 | ||||
-rw-r--r-- | scripts/context/stubs/mswin/setuptex.bat | 12 | ||||
-rw-r--r-- | scripts/context/stubs/unix/mtxrun | 1678 |
20 files changed, 2064 insertions, 3747 deletions
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index 4c6672051..87ed3475d 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -17,17 +17,8 @@ local settings_to_array = utilities.parsers.settings_to_array local appendtable = table.append local lpegpatterns, lpegmatch, Cs, P = lpeg.patterns, lpeg.match, lpeg.Cs, lpeg.P -local getargument = environment.getargument or environment.argument -local setargument = environment.setargument - -local filejoinname = file.join -local filebasename = file.basename -local filepathpart = file.pathpart -local filesuffix = file.suffix -local fileaddsuffix = file.addsuffix -local filenewsuffix = file.replacesuffix -local removesuffix = file.removesuffix -local validfile = lfs.isfile +local getargument = environment.getargument or environment.argument +local setargument = environment.setargument local application = logs.application { name = "mtx-context", @@ -171,14 +162,14 @@ function ctxrunner.checkfile(ctxdata,ctxname,defaultname) return end - ctxdata.ctxname = ctxname or removesuffix(ctxdata.jobname) or "" + ctxdata.ctxname = ctxname or file.removesuffix(ctxdata.jobname) or "" if ctxdata.ctxname == "" then return end - ctxdata.jobname = fileaddsuffix(ctxdata.jobname,'tex') - ctxdata.ctxname = fileaddsuffix(ctxdata.ctxname,'ctx') + ctxdata.jobname = file.addsuffix(ctxdata.jobname,'tex') + ctxdata.ctxname = file.addsuffix(ctxdata.ctxname,'ctx') report("jobname: %s",ctxdata.jobname) report("ctxname: %s",ctxdata.ctxname) @@ -186,14 +177,14 @@ function ctxrunner.checkfile(ctxdata,ctxname,defaultname) -- mtxrun should resolve kpse: and file: local usedname = ctxdata.ctxname - local found = validfile(usedname) + local found = lfs.isfile(usedname) -- no further test if qualified path if not found then for _, path in next, ctx_locations do - local fullname = filejoinname(path,ctxdata.ctxname) - if validfile(fullname) then + local fullname = file.join(path,ctxdata.ctxname) + if lfs.isfile(fullname) then usedname = fullname found = true break @@ -206,7 +197,7 @@ function ctxrunner.checkfile(ctxdata,ctxname,defaultname) found = usedname ~= "" end - if not found and defaultname and defaultname ~= "" and validfile(defaultname) then + if not found and defaultname and defaultname ~= "" and lfs.isfile(defaultname) then usedname = defaultname found = true end @@ -223,7 +214,7 @@ function ctxrunner.checkfile(ctxdata,ctxname,defaultname) -- test for valid, can be text file end - local ctxpaths = table.append({'.', filepathpart(ctxdata.ctxname)}, ctx_locations) + local ctxpaths = table.append({'.', file.dirname(ctxdata.ctxname)}, ctx_locations) xml.include(xmldata,'ctx:include','name', ctxpaths) @@ -277,7 +268,7 @@ end local function multipass_copyluafile(jobname) local tuaname, tucname = jobname..".tua", jobname..".tuc" - if validfile(tuaname) then + if lfs.isfile(tuaname) then os.remove(tucname) os.rename(tuaname,tucname) end @@ -287,38 +278,32 @@ end local pattern = lpegpatterns.utfbom^-1 * (P("%% ") + P("% ")) * Cs((1-lpegpatterns.newline)^1) -local prefile = nil -local predata = nil - local function preamble_analyze(filename) -- only files on current path - filename = fileaddsuffix(filename,"tex") -- to be sure - if predata and prefile == filename then - return predata - end - prefile = filename - predata = { } - local line = io.loadlines(prefile) + local t = { } + local line = io.loadlines(file.addsuffix(filename,"tex")) if line then local preamble = lpegmatch(pattern,line) if preamble then - utilities.parsers.options_to_hash(preamble,predata) - predata.type = "tex" + for key, value in gmatch(preamble,"(%S+)%s*=%s*(%S+)") do + t[key] = value + end + t.type = "tex" elseif find(line,"^<?xml ") then - predata.type = "xml" + t.type = "xml" end - if predata.nofruns then - multipass_nofruns = predata.nofruns + if t.nofruns then + multipass_nofruns = t.nofruns end - if not predata.engine then - predata.engine = environment.basicengines[engine_old] --'luatex' + if not t.engine then + t.engine = environment.basicengines[engine_old] --'luatex' end - if predata.engine ~= engine_old then -- hack - if environment.validengines[predata.engine] and predata.engine ~= environment.basicengines[engine_old] then - restart(engine_old,predata.engine) + if t.engine ~= engine_old then -- hack + if environment.validengines[t.engine] and t.engine ~= environment.basicengines[engine_old] then + restart(engine_old,t.engine) end end end - return predata + return t end -- automatically opening and closing pdf files @@ -329,21 +314,21 @@ local function pdf_open(name,method) pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex")) pdfview.setmethod(method) report(pdfview.status()) - pdfview.open(filenewsuffix(name,"pdf")) + pdfview.open(file.replacesuffix(name,"pdf")) end local function pdf_close(name,method) pdfview = pdfview or dofile(resolvers.findfile("l-pdfview.lua","tex")) pdfview.setmethod(method) - pdfview.close(filenewsuffix(name,"pdf")) + pdfview.close(file.replacesuffix(name,"pdf")) end -- result file handling local function result_push_purge(oldbase,newbase) for _, suffix in next, usedsuffixes.after do - local oldname = fileaddsuffix(oldbase,suffix) - local newname = fileaddsuffix(newbase,suffix) + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) os.remove(newname) os.remove(oldname) end @@ -351,8 +336,8 @@ end local function result_push_keep(oldbase,newbase) for _, suffix in next, usedsuffixes.before do - local oldname = fileaddsuffix(oldbase,suffix) - local newname = fileaddsuffix(newbase,suffix) + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) local tmpname = "keep-"..oldname os.remove(tmpname) os.rename(oldname,tmpname) @@ -363,8 +348,8 @@ end local function result_save_error(oldbase,newbase) for _, suffix in next, usedsuffixes.keep do - local oldname = fileaddsuffix(oldbase,suffix) - local newname = fileaddsuffix(newbase,suffix) + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) os.remove(newname) -- to be sure os.rename(oldname,newname) end @@ -372,8 +357,8 @@ end local function result_save_purge(oldbase,newbase) for _, suffix in next, usedsuffixes.after do - local oldname = fileaddsuffix(oldbase,suffix) - local newname = fileaddsuffix(newbase,suffix) + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) os.remove(newname) -- to be sure os.rename(oldname,newname) end @@ -381,8 +366,8 @@ end local function result_save_keep(oldbase,newbase) for _, suffix in next, usedsuffixes.after do - local oldname = fileaddsuffix(oldbase,suffix) - local newname = fileaddsuffix(newbase,suffix) + local oldname = file.addsuffix(oldbase,suffix) + local newname = file.addsuffix(newbase,suffix) local tmpname = "keep-"..oldname os.remove(newname) os.rename(oldname,newname) @@ -435,7 +420,7 @@ local function run_plain(plainformat,filename) local command = format("mtxrun --script --texformat=%s plain %s",plainformat,filename) report("running command: %s\n\n",command) -- todo: load and run - local resultname = filenewsuffix(filename,"pdf") + local resultname = file.replacesuffix(filename,"pdf") local pdfview = getargument("autopdf") or getargument("closepdf") if pdfview then pdf_close(resultname,pdfview) @@ -477,10 +462,6 @@ end -- -local function check_synctex(a_synctex) - return a_synctex and (tonumber(a_synctex) or (toboolean(a_synctex,true) and 1) or (a_synctex == "zipped" and 1) or (a_synctex == "unzipped" and -1)) or nil -end - function scripts.context.run(ctxdata,filename) -- local a_nofile = getargument("nofile") @@ -545,29 +526,27 @@ function scripts.context.run(ctxdata,filename) local a_texformat = getargument("texformat") -- a_batchmode = (a_batchmode and "batchmode") or (a_nonstopmode and "nonstopmode") or nil - a_synctex = check_synctex(a_synctex) + a_synctex = tonumber(a_synctex) or (toboolean(a_synctex,true) and 1) or (a_synctex == "zipped" and 1) or (a_synctex == "unzipped" and -1) or nil -- for i=1,#filelist do -- local filename = filelist[i] - local basename = filebasename(filename) -- use splitter - local pathname = filepathpart(filename) + local basename = file.basename(filename) -- use splitter + local pathname = file.dirname(filename) -- if pathname == "" and not a_global and filename ~= usedfiles.nop then filename = "./" .. filename - if not validfile(filename) then + if not lfs.isfile(filename) then report("warning: no (local) file %a, proceeding",filename) end end -- - local jobname = removesuffix(basename) - -- local jobname = removesuffix(filename) + local jobname = file.removesuffix(basename) + -- local jobname = file.removesuffix(filename) local ctxname = ctxdata and ctxdata.ctxname -- local analysis = preamble_analyze(filename) -- - a_synctex = a_synctex or check_synctex(analysis.synctex) - -- if a_mkii or analysis.engine == 'pdftex' or analysis.engine == 'xetex' then run_texexec(filename,a_purge,a_purgeall) elseif plain_format(a_texformat or analysis.texformat) then @@ -589,13 +568,13 @@ function scripts.context.run(ctxdata,filename) local suffix = validstring(getargument("suffix")) local resultname = validstring(getargument("result")) if suffix then - resultname = removesuffix(jobname) .. suffix + resultname = file.removesuffix(jobname) .. suffix end local oldbase = "" local newbase = "" if resultname then - oldbase = removesuffix(jobname) - newbase = removesuffix(resultname) + oldbase = file.removesuffix(jobname) + newbase = file.removesuffix(resultname) if oldbase ~= newbase then if a_purgeresult then result_push_purge(oldbase,newbase) @@ -828,7 +807,7 @@ function scripts.context.pipe() -- still used? filename = "\\relax" report("entering scrollmode, end job with \\end") else - filename = fileaddsuffix(filename,"tmp") + filename = file.addsuffix(filename,"tmp") io.savedata(filename,"\\relax") report("entering scrollmode using '%s' with optionfile, end job with \\end",filename) end @@ -854,7 +833,7 @@ local function make_mkiv_format(name,engine) end local function make_mkii_format(name,engine) - local command = format("mtxrun texexec.rb --make %s --%s",name,engine) + local command = format("mtxrun texexec.rb --make --%s %s",name,engine) report("running command: %s",command) os.spawn(command) end @@ -896,26 +875,24 @@ function scripts.context.ctx() end function scripts.context.autoctx() - local ctxdata = nil - local files = environment.files + local ctxdata = nil + local files = environment.files local firstfile = #files > 0 and files[1] if firstfile then - local suffix = filesuffix(firstfile) - local ctxname = nil + local suffix = file.suffix(firstfile) if suffix == "xml" then local chunk = io.loadchunk(firstfile) -- 1024 if chunk then - ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>") + local ctxname = match(chunk,"<%?context%-directive%s+job%s+ctxfile%s+([^ ]-)%s*?>") + if ctxname then + ctxdata = ctxrunner.new() + ctxdata.jobname = firstfile + ctxrunner.checkfile(ctxdata,ctxname) + ctxrunner.checkflags(ctxdata) + end end - elseif suffix == "tex" or suffix == "mkiv" then - local analysis = preamble_analyze(firstfile) - ctxname = analysis.ctxfile or analysis.ctx - end - if ctxname then - ctxdata = ctxrunner.new() - ctxdata.jobname = firstfile - ctxrunner.checkfile(ctxdata,ctxname) - ctxrunner.checkflags(ctxdata) + elseif suffix == "tex" then + -- maybe but we scan the preamble later too end end scripts.context.run(ctxdata) @@ -944,10 +921,10 @@ end -- formatname = "metafun" -- end -- if getargument("pdf") then --- local basename = removesuffix(filename) +-- local basename = file.removesuffix(filename) -- local resultname = getargument("result") or basename -- local jobname = "mtx-context-metapost" --- local tempname = fileaddsuffix(jobname,"tex") +-- local tempname = file.addsuffix(jobname,"tex") -- io.savedata(tempname,format(template,"metafun",filename)) -- environment.files[1] = tempname -- setargument("result",resultname) @@ -984,7 +961,7 @@ function scripts.context.version() end end --- purging files (we should have an mkii and mkiv variants) +-- purging files local generic_files = { "texexec.tex", "texexec.tui", "texexec.tuo", @@ -998,32 +975,15 @@ local obsolete_results = { } local temporary_runfiles = { - "tui", -- mkii two pass file - "tua", -- mkiv obsolete - "tup", "ted", "tes", -- texexec - "top", -- mkii options file - "log", -- tex log file - "tmp", -- mkii buffer file - "run", -- mkii stub - "bck", -- backup (obsolete) - "rlg", -- resource log - "ctl", -- - "mpt", "mpx", "mpd", "mpo", "mpb", -- metafun - "prep", -- context preprocessed - "pgf", -- tikz - "aux", "blg", -- bibtex -} - -local synctex_runfiles = { - "synctex", "synctex.gz", -- synctex + "tui", "tua", "tup", "ted", "tes", "top", + "log", "tmp", "run", "bck", "rlg", + "mpt", "mpx", "mpd", "mpo", "mpb", "ctl", + "synctex", "synctex.gz", "pgf", + "prep", } local persistent_runfiles = { - "tuo", -- mkii two pass file - "tub", -- mkii buffer file - "top", -- mkii options file - "tuc", -- mkiv two pass file - "bbl", -- bibtex + "tuo", "tub", "top", "tuc" } local special_runfiles = { @@ -1031,40 +991,34 @@ local special_runfiles = { } local function purge_file(dfile,cfile) - if cfile and validfile(cfile) then + if cfile and lfs.isfile(cfile) then if os.remove(dfile) then - return filebasename(dfile) + return file.basename(dfile) end elseif dfile then if os.remove(dfile) then - return filebasename(dfile) + return file.basename(dfile) end end end function scripts.context.purge_job(jobname,all,mkiitoo) if jobname and jobname ~= "" then - jobname = filebasename(jobname) - local filebase = removesuffix(jobname) + jobname = file.basename(jobname) + local filebase = file.removesuffix(jobname) if mkiitoo then scripts.context.purge(all,filebase,true) -- leading "./" else local deleted = { } for i=1,#obsolete_results do - deleted[#deleted+1] = purge_file(fileaddsuffix(filebase,obsolete_results[i]),fileaddsuffix(filebase,"pdf")) + deleted[#deleted+1] = purge_file(filebase.."."..obsolete_results[i],filebase..".pdf") end for i=1,#temporary_runfiles do - deleted[#deleted+1] = purge_file(fileaddsuffix(filebase,temporary_runfiles[i])) - end - if not environment.argument("synctex") then - -- special case: not deleted when --synctex is given, but what if given in preamble - for i=1,#synctex_runfiles do - deleted[#deleted+1] = purge_file(fileaddsuffix(filebase,synctex_runfiles[i])) - end + deleted[#deleted+1] = purge_file(filebase.."."..temporary_runfiles[i]) end if all then for i=1,#persistent_runfiles do - deleted[#deleted+1] = purge_file(fileaddsuffix(filebase,persistent_runfiles[i])) + deleted[#deleted+1] = purge_file(filebase.."."..persistent_runfiles[i]) end end if #deleted > 0 then @@ -1080,15 +1034,14 @@ function scripts.context.purge(all,pattern,mkiitoo) local files = dir.glob(pattern) local obsolete = table.tohash(obsolete_results) local temporary = table.tohash(temporary_runfiles) - local synctex = table.tohash(synctex_runfiles) local persistent = table.tohash(persistent_runfiles) local generic = table.tohash(generic_files) local deleted = { } for i=1,#files do local name = files[i] - local suffix = filesuffix(name) - local basename = filebasename(name) - if obsolete[suffix] or temporary[suffix] or synctex[suffix] or persistent[suffix] or generic[basename] then + local suffix = file.suffix(name) + local basename = file.basename(name) + if obsolete[suffix] or temporary[suffix] or persistent[suffix] or generic[basename] then deleted[#deleted+1] = purge_file(name) elseif mkiitoo then for i=1,#special_runfiles do @@ -1107,7 +1060,8 @@ end local function touch(path,name,versionpattern,kind,kindpattern) if path and path ~= "" then - name = filejoinname(path,name) + name = file.join(path,name) +print(name) else name = resolvers.findfile(name) end @@ -1129,7 +1083,7 @@ local function touch(path,name,versionpattern,kind,kindpattern) end) or newdata end if newdata ~= "" and (oldversion ~= newversion or oldkind ~= newkind or newdata ~= olddata) then - local backup = filenewsuffix(name,"tmp") + local backup = file.replacesuffix(name,"tmp") os.remove(backup) os.rename(name,backup) io.savedata(name,newdata) @@ -1143,12 +1097,12 @@ local p_contextversion = "(\\edef\\contextversion%s*{)(.-)(})" local p_newcontextversion = "(\\newcontextversion%s*{)(.-)(})" local function touchfiles(suffix,kind,path) - local foundname, oldversion, newversion, oldkind, newkind = touch(path,fileaddsuffix("context",suffix),p_contextversion,kind,p_contextkind) + local foundname, oldversion, newversion, oldkind, newkind = touch(path,file.addsuffix("context",suffix),p_contextversion,kind,p_contextkind) if foundname then report("old version : %s (%s)",oldversion,oldkind) report("new version : %s (%s)",newversion,newkind) report("touched file : %s",foundname) - local foundname = touch(path,fileaddsuffix("cont-new",suffix),p_newcontextversion) + local foundname = touch(path,file.addsuffix("cont-new",suffix),p_newcontextversion) if foundname then report("touched file : %s", foundname) end @@ -1189,19 +1143,19 @@ function scripts.context.modules(pattern) end -- my dev path for i=1,#cards do - dir.glob(filejoinname(filepathpart(found),cards[i]),list) + dir.glob(file.join(file.dirname(found),cards[i]),list) end else resolvers.findwildcardfiles(pattern,list) - dir.glob(filejoinname(filepathpart(found,pattern)),list) + dir.glob(file.join(file.dirname(found,pattern)),list) end local done = { } -- todo : sort for i=1,#list do local v = list[i] - local base = filebasename(v) + local base = file.basename(v) if not done[base] then done[base] = true - local suffix = filesuffix(base) + local suffix = file.suffix(base) if suffix == "tex" or suffix == "mkiv" or suffix == "mkvi" or suffix == "mkix" or suffix == "mkxi" then local prefix = match(base,"^([xmst])%-") if prefix then @@ -1239,7 +1193,7 @@ function scripts.context.extras(pattern) end local found = resolvers.findfile("context.mkiv") if found ~= "" then - pattern = filejoinname(dir.expandname(filepathpart(found)),format("mtx-context-%s.tex",pattern or "*")) + pattern = file.join(dir.expandname(file.dirname(found)),format("mtx-context-%s.tex",pattern or "*")) local list = dir.glob(pattern) for i=1,#list do local v = list[i] diff --git a/scripts/context/lua/mtx-flac.lua b/scripts/context/lua/mtx-flac.lua index 4e01abc99..2155b24be 100644 --- a/scripts/context/lua/mtx-flac.lua +++ b/scripts/context/lua/mtx-flac.lua @@ -56,20 +56,11 @@ readers.default = function(f,size,target) f:seek("cur",size) end -local valid = { - ["fLaC"] = true, - ["ID3♥"] = false, -} - function flac.getmetadata(filename) local f = io.open(filename, "rb") if f then - local banner = readstring(f,4) - local whatsit = valid[banner] - if whatsit ~= nil then - if whatsit == false then - flac.report("suspicious flac file: %s (%s)",filename,banner) - end + local banner = readstring(f,4) + if banner == "fLaC" then local data = { banner = banner, filename = filename, @@ -105,14 +96,13 @@ function flac.savecollection(pattern,filename) local files = dir.glob(pattern) flac.report("%s files found, analyzing files",#files) local music = { } - table.sort(files) for i=1,#files do local data = flac.getmetadata(files[i]) if data then - local tags = data.tags - local info = data.info - local artist = tags.artist or "no-artist" - local album = tags.album or "no-album" + local tags = data.tags + local info = data.info + local artist = tags.artist + local album = tags.album local albums = music[artist] if not albums then albums = { } @@ -144,18 +134,8 @@ function flac.savecollection(pattern,filename) f:write("\t<artist>\n") f:write("\t\t<name>",lpegmatch(p_escaped,artist),"</name>\n") f:write("\t\t<albums>\n") - local list = table.keys(albums) - table.sort(list,function(a,b) - local ya, yb = albums[a].year or 0, albums[b].year or 0 - if ya == yb then - return a < b - else - return ya < yb - end - end) - for nofalbums=1,#list do - local album = list[nofalbums] - local data = albums[album] + for album, data in sortedpairs(albums) do + nofalbums = nofalbums + 1 f:write("\t\t\t<album year='",data.year or 0,"'>\n") f:write("\t\t\t\t<name>",lpegmatch(p_escaped,album),"</name>\n") f:write("\t\t\t\t<tracks>\n") @@ -199,7 +179,6 @@ local helpinfo = [[ <category name="basic"> <subcategory> <flag name="collect"><short>collect albums in xml file</short></flag> - <flag name="pattern"><short>use pattern for locating files</short></flag> </subcategory> </category> </flags> diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua index 7d8b5f610..b171dd611 100644 --- a/scripts/context/lua/mtx-fonts.lua +++ b/scripts/context/lua/mtx-fonts.lua @@ -85,8 +85,8 @@ local report = application.report if not fontloader then fontloader = fontforge end dofile(resolvers.findfile("font-otp.lua","tex")) -- we need to unpack the font for analysis -dofile(resolvers.findfile("font-syn.lua","tex")) dofile(resolvers.findfile("font-trt.lua","tex")) +dofile(resolvers.findfile("font-syn.lua","tex")) dofile(resolvers.findfile("font-mis.lua","tex")) scripts = scripts or { } @@ -132,9 +132,9 @@ function fonts.names.statistics() end -function fonts.names.simple(alsotypeone) +function fonts.names.simple() local simpleversion = 1.001 - local simplelist = { "ttf", "otf", "ttc", "dfont", alsotypeone and "afm" or nil } + local simplelist = { "ttf", "otf", "ttc", "dfont" } local name = "luatex-fonts-names.lua" local path = file.collapsepath(caches.getwritablepath("..","..","generic","fonts","data")) fonts.names.filters.list = simplelist @@ -182,7 +182,7 @@ end function scripts.fonts.reload() if getargument("simple") then - fonts.names.simple(getargument("typeone")) + fonts.names.simple() else fonts.names.load(true,getargument("force")) end diff --git a/scripts/context/lua/mtx-grep.lua b/scripts/context/lua/mtx-grep.lua index d0f33cb21..dbcce67f6 100644 --- a/scripts/context/lua/mtx-grep.lua +++ b/scripts/context/lua/mtx-grep.lua @@ -51,9 +51,7 @@ local content = lpeg.C((1-newline)^0) * newline + lpeg.C(lpeg.P(1)^1) local write_nl = texio.write_nl --- local pattern = "LIJST[@TYPE='BULLET']/LIJSTITEM[contains(text(),'Kern')]" - --- 'Cc%(\\\"\\\"%)' + -- local pattern = "LIJST[@TYPE='BULLET']/LIJSTITEM[contains(text(),'Kern')]" function scripts.grep.find(pattern, files, offset) if pattern and pattern ~= "" then diff --git a/scripts/context/lua/mtx-plain.lua b/scripts/context/lua/mtx-plain.lua index d10c21375..f43dcdeaf 100644 --- a/scripts/context/lua/mtx-plain.lua +++ b/scripts/context/lua/mtx-plain.lua @@ -24,7 +24,6 @@ local helpinfo = [[ <category name="basic"> <subcategory> <flag name="make"><short>create format file</short></flag> - <flag name="fonts"><short>create plain font database</short></flag> <flag name="run"><short>process file</short></flag> <flag name="format" value="string"><short>format name (default: luatex-plain)</short></flag> <flag name="engine" value="string"><short>engine to use (default: luatex)</short></flag> @@ -106,10 +105,6 @@ function scripts.plain.run(texengine,texformat,filename) execute('%s --fmt=%s "%s"',texengine,file.removesuffix(texformat),filename) end -function scripts.plain.fonts() - execute('mtxrun --script fonts --reload --simple --typeone') -end - local texformat = environment.arguments.texformat or environment.arguments.format local texengine = environment.arguments.texengine or environment.arguments.engine @@ -127,8 +122,6 @@ if environment.arguments.exporthelp then application.export(environment.arguments.exporthelp,filename) elseif environment.arguments.make then scripts.plain.make(texengine,texformat) -elseif environment.arguments.fonts then - scripts.plain.fonts() elseif filename then scripts.plain.run(texengine,texformat,filename) else diff --git a/scripts/context/lua/mtx-profile.lua b/scripts/context/lua/mtx-profile.lua index 0d0c28084..3550474f3 100644 --- a/scripts/context/lua/mtx-profile.lua +++ b/scripts/context/lua/mtx-profile.lua @@ -31,7 +31,7 @@ local helpinfo = [[ ]] local application = logs.application { - name = "mtx-profile", + name = "mtx-cache", banner = "ConTeXt MkIV LuaTeX Profiler 1.00", helpinfo = helpinfo, } @@ -56,22 +56,20 @@ function scripts.profiler.analyze(filename) local times, counts, calls = { }, { }, { } local totalruntime, totalcount, totalcalls = 0, 0, 0 for line in f:lines() do - if not find(line,"__index") and not find(line,"__newindex") then - local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)") - if not filename then - -- next - elseif filename == "=[C]" then - if not functionname:find("^%(") then - calls[functionname] = (calls[functionname] or 0) + 1 - end - else - local filename = filename:match("^@(.*)$") - if filename then - local fi = times[filename] - if not fi then fi = { } times[filename] = fi end - fi[functionname] = (fi[functionname] or 0) + tonumber(localtime) - counts[functionname] = (counts[functionname] or 0) + 1 - end + local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)") + if not filename then + -- next + elseif filename == "=[C]" then + if not functionname:find("^%(") then + calls[functionname] = (calls[functionname] or 0) + 1 + end + else + local filename = filename:match("^@(.*)$") + if filename then + local fi = times[filename] + if not fi then fi = { } times[filename] = fi end + fi[functionname] = (fi[functionname] or 0) + tonumber(localtime) + counts[functionname] = (counts[functionname] or 0) + 1 end end end diff --git a/scripts/context/lua/mtx-rsync.lua b/scripts/context/lua/mtx-rsync.lua index 53cabbe4f..65f795ee5 100644 --- a/scripts/context/lua/mtx-rsync.lua +++ b/scripts/context/lua/mtx-rsync.lua @@ -92,26 +92,13 @@ else end end -function rsynccommand(origin,target,dryrun,recurse,delete,exclude) - local command = "rsync -t -p" +function rsynccommand(dryrun,recurse,origin,target) + local command = "rsync -ptlva " if dryrun then - command = command .. " -n" + command = command .. "-n " end if recurse then - command = command .. " -r" - end - if type(exclude) == "table" then - for i=1,#exclude do - local e = exclude[i] - if e then - command = command .. ' --exclude "' .. e .. '"' - end - end - elseif type(exclude) == "string" then - command = command .. " --exclude-from " .. exclude - end - if delete and recurse then - command = command .. " --delete" + command = command .. "-r " end return format('%s %s %s',command,origin,target) end @@ -122,7 +109,7 @@ local rsync = scripts.rsync rsync.mode = "command" -function rsync.run(origin,target,message,recurse,delete,exclude) +function rsync.run(origin,target,message,recurse) if type(origin) == "table" then origin = concat(origin,"/") end @@ -140,15 +127,15 @@ function rsync.run(origin,target,message,recurse,delete,exclude) report_message(message) end if rsync.mode == "dryrun" then - local command = rsynccommand(origin,target,true,recurse,delete,exclude) + local command = rsynccommand(true,recurse,origin,target) report_dryrun(command.."\n") os.execute(command) elseif rsync.mode == "force" then - local command = rsynccommand(origin,target,false,recurse,delete,exclude) + local command = rsynccommand(false,recurse,origin,target) report_normal(command.."\n") os.execute(command) else - local command = rsynccommand(origin,target,true,recurse,delete,exclude) + local command = rsynccommand(true,recurse,origin,target) report_command(command) end end @@ -167,10 +154,8 @@ function rsync.job(list) local target = li.target local message = li.message local recurse = li.recurse - local delete = li.delete - local exclude = li.exclude if origin and #origin > 0 and target and #target > 0 then -- string or table - rsync.run(origin,target,message,recurse,delete,exclude) + rsync.run(origin,target,message,recurse) else report_message("invalid job specification at index %s",i) end diff --git a/scripts/context/lua/mtx-server-ctx-fonttest.lua b/scripts/context/lua/mtx-server-ctx-fonttest.lua index da87fe9e8..a8d7edf41 100644 --- a/scripts/context/lua/mtx-server-ctx-fonttest.lua +++ b/scripts/context/lua/mtx-server-ctx-fonttest.lua @@ -20,62 +20,44 @@ dofile(resolvers.findfile("font-mis.lua","tex")) local format, gsub, concat, match, find = string.format, string.gsub, table.concat, string.match, string.find -local formatters = string.formatters +local report = logs.reporter("ctx-fonttest") -local report = logs.reporter("ctx-fonttest") - -local sample_line = "This is a sample line!" -local tempname = "mtx-server-ctx-fonttest-temp" -local temppath = caches.setfirstwritablefile("temp","mtx-server-ctx-fonttest") -local basename = "mtx-server-ctx-fonttest-data.lua" -local basepath = temppath +local sample_line = "This is a sample line!" +local tempname = "mtx-server-ctx-fonttest-temp" +local temppath = caches.setfirstwritablefile("temp","mtx-server-ctx-fonttest") +local basename = "mtx-server-ctx-fonttest-data.lua" +local basepath = temppath local remove_suffixes = { "tex", "pdf", "log" } -local what_options = { "trace", "basemode" } +local what_options = { "trace", "basemode" } for i=1,#remove_suffixes do os.remove(file.join(temppath,file.addsuffix(tempname,remove_suffixes[i]))) end -local foolcache = 0 - -local function makename(name,new) - if new then - foolcache = foolcache > 25 and 1 or foolcache + 1 - end - return formatters["%s-%02i"](name,foolcache) -end - --- nowadays i would use the more advanced template mechanism with named variables - local process_templates = { } --- %\definedfont[name:%s*sample] - -process_templates.default = formatters [ [[ +process_templates.default = [[ \starttext - \setupdirections[bidi=one] + \setupdirections[bidi=global] \definefontfeature[sample][analyze=yes,%s] - \definedfont[name:%s*none] + \definedfont[name:%s*sample] \startTEXpage[offset=3pt] \detokenize{%s} - \blank - \definedfont[name:%s*sample] - \detokenize{%s} \stopTEXpage \stoptext -]] ] +]] -process_templates.cache = formatters [ [[ +process_templates.cache = [[ \starttext \definedfont[name:%s] \startTEXpage[offset=3pt] cached: \detokenize{%s} \stopTEXpage \stoptext -]] ] +]] -process_templates.trace = formatters [ [[ +process_templates.trace = [[ \usemodule[fnt-20] \definefontfeature[sample][%s] @@ -91,9 +73,9 @@ process_templates.trace = formatters [ [[ direction=0, features=sample, sample={\detokenize{%s}}] -]] ] +]] -local javascripts = formatters [ [[ +local javascripts = [[ function selected_radio(name) { var form = document.forms["main-form"] ; var script = form.elements[name] ; @@ -169,28 +151,7 @@ function check_language() { function check_feature() { // not needed } -]] ] - -local jitmode = false -- assumes local use (one user as shared) - -local run_context_normal = formatters["mtxrun --path=%q --script context --once --batchmode %q"] -local run_context_jitted = formatters["mtxrun --path=%q --script context --once --batchmode --jit %q"] - -local function runcontext(temppath,filename) - local start = os.clock() - local command = (jitmode and run_context_jitted or run_context_normal)(temppath,filename) - report("temppath: %s",temppath) - report("filename: %s",filename) - report("command: %s",command) - os.execute(command) - return os.clock() - start -end - -local function identifyfonts() - local command = "mtxrun --script font --reload" - report("command: %s",command) - os.execute(command) -end +]] local cache = { } @@ -202,9 +163,8 @@ local function showfeatures(f) features = fonts.helpers.getfeatures(resolvers.findfile(f)) if not features then report("building cache for '%s'",f) - local usedname = file.addsuffix(tempname,"tex") - io.savedata(file.join(temppath,usedname),process_templates.cache(f,f)) - runcontext(temppath,usedname) + io.savedata(file.join(temppath,file.addsuffix(tempname,"tex")),format(process_templates.cache,f,f)) + os.execute(format("mtxrun --path=%s --script context --once --batchmode %s",temppath,tempname)) features = fonts.helpers.getfeatures(f) end cache[f] = features or false @@ -246,15 +206,14 @@ local function showfeatures(f) for what, v in table.sortedhash(features) do show(what) end - -- we could json this local stupid = { } stupid[#stupid+1] = "var feature_hash = new Array ;" for s, sr in next, rev do - stupid[#stupid+1] = formatters["feature_hash['%s'] = new Array ;"](s) + stupid[#stupid+1] = format("feature_hash['%s'] = new Array ;",s) for l, lr in next, sr do - stupid[#stupid+1] = formatters["feature_hash['%s']['%s'] = new Array ;"](s,l) + stupid[#stupid+1] = format("feature_hash['%s']['%s'] = new Array ;",s,l) for f, fr in next, lr do - stupid[#stupid+1] = formatters["feature_hash['%s']['%s']['%s'] = true ;"](s,l,f) + stupid[#stupid+1] = format("feature_hash['%s']['%s']['%s'] = true ;",s,l,f) end end end @@ -269,7 +228,7 @@ local function showfeatures(f) end end -local template_h = formatters [ [[ +local template_h = [[ <tr> <th>safe name </th> <th>family name </th> @@ -277,9 +236,9 @@ local template_h = formatters [ [[ <th>font name </th> <th>weight </th> <th>filename</th> -</tr>]] ] +</tr>]] -local template_d = formatters [ [[ +local template_d = [[ <tr> <td><a href='mtx-server-ctx-fonttest.lua?selection=%s'>%s</a> </td> <td>%s </td> @@ -287,22 +246,19 @@ local template_d = formatters [ [[ <td>%s </td> <td>%s </td> <td>%s</td> -</tr>]] ] +</tr>]] local function select_font() local t = fonts.names.list(".*",false,true) if t then local listoffonts = { } - listoffonts[#listoffonts+1] = "<h1>Fonts</h1><br/>" listoffonts[#listoffonts+1] = "<table>" - listoffonts[#listoffonts+1] = template_h() + listoffonts[#listoffonts+1] = template_h for k, v in table.sortedhash(t) do local kind = v.format if kind == "otf" or kind == "ttf" or kind == "ttc" then local fontname = v.fontname - listoffonts[#listoffonts+1] = template_d( - fontname, - fontname, + listoffonts[#listoffonts+1] = format(template_d, fontname, fontname, v.familyname or "", t.variant or "normal", t.weight or "normal", @@ -320,32 +276,25 @@ local function select_font() return "<b>no fonts</b>" end -local edit_template = formatters [ [[ +local edit_template = [[ <textarea name='sampletext' rows='5' cols='100'>%s</textarea> <br/> <br/>name: <input type='text' name='name' size='20' value=%q/> title: <input type='text' name='title' size='40' value=%q/> <br/> <br/>scripts: %s <br/> <br/>languages: %s <br/> <br/>features: %s <br/> <br/>options: %s -]] ] +]] -- <embed src="%s#toolbar=0&navpanes=0&scrollbar=0" width="100%%"/> -local result_template = formatters [ [[ +local result_template = [[ <br/> <br/> <embed src="%s#view=Fit&toolbar=0&navpanes=0&scrollbar=0" width="100%%"/> - <br/> <br/> results: - <a href='%s' target="source">tex file</a> - <a href='%s' target="result">pdf file</a> - (runtime: %s) + <br/> <br/> results: + <a href='%s' target="source">tex file</a> + <a href='%s' target="result">pdf file</a> <br/> <br/> -]] ] - -local main_template = formatters [ [[ - <h1>Font: %s</h1><br/> - %s - %s -]] ] +]] scripts.webserver.registerpath(temppath) @@ -353,7 +302,7 @@ local function get_specification(name) return fonts.names.resolvedspecification(name or "") end -local function edit_font(currentfont,detail,tempname,runtime) +local function edit_font(currentfont,detail,tempname) report("entering edit mode for '%s'",currentfont) local specification = get_specification(currentfont) if specification then @@ -365,9 +314,9 @@ local function edit_font(currentfont,detail,tempname,runtime) local v = sorted[k] local s = fonts.handlers.otf.tables.scripts[v] or v if detail and v == detail.script then - scripts[#scripts+1] = formatters["<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' checked='checked'/> <span id='t-s-%s'>%s</span>"](s,v,v,v,v) + scripts[#scripts+1] = format("<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' checked='checked'/> <span id='t-s-%s'>%s</span>",s,v,v,v,v) else - scripts[#scripts+1] = formatters["<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' /> <span id='t-s-%s'>%s</span>"](s,v,v,v,v) + scripts[#scripts+1] = format("<input title='%s' id='s-%s' type='radio' name='script' value='%s' onclick='check_script()' /> <span id='t-s-%s'>%s</span>",s,v,v,v,v) end end local sorted = table.sortedkeys(htmldata.languages) @@ -375,9 +324,9 @@ local function edit_font(currentfont,detail,tempname,runtime) local v = sorted[k] local l = fonts.handlers.otf.tables.languages[v] or v if detail and v == detail.language then - languages[#languages+1] = formatters["<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' checked='checked'/> <span id='t-l-%s'>%s</span>"](l,v,v,v,v) + languages[#languages+1] = format("<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' checked='checked'/> <span id='t-l-%s'>%s</span>",l,v,v,v,v) else - languages[#languages+1] = formatters["<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' /> <span id='t-l-%s'>%s</span>"](l,v,v,v,v) + languages[#languages+1] = format("<input title='%s' id='l-%s' type='radio' name='language' value='%s' onclick='check_language()' /> <span id='t-l-%s'>%s</span>",l,v,v,v,v) end end local sorted = table.sortedkeys(htmldata.features) @@ -385,34 +334,28 @@ local function edit_font(currentfont,detail,tempname,runtime) local v = sorted[k] local f = fonts.handlers.otf.tables.features[v] or v if detail and detail["f-"..v] then - features[#features+1] = formatters["<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' checked='checked'/> <span id='t-f-%s'>%s</span>"](f,v,v,v,v) + features[#features+1] = format("<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' checked='checked'/> <span id='t-f-%s'>%s</span>",f,v,v,v,v) else - features[#features+1] = formatters["<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' /> <span id='t-f-%s'>%s</span>"](f,v,v,v,v) + features[#features+1] = format("<input title='%s' id='f-%s' type='checkbox' name='f-%s' onclick='check_feature()' /> <span id='t-f-%s'>%s</span>",f,v,v,v,v) end end for k=1,#what_options do local v = what_options[k] if detail and detail["o-"..v] then - options[#options+1] = formatters["<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/> %s"](v,v,v) + options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s' checked='checked'/> %s",v,v,v) else - options[#options+1] = formatters["<input id='o-%s' type='checkbox' name='o-%s'/> %s"](v,v,v) + options[#options+1] = format("<input id='o-%s' type='checkbox' name='o-%s'/> %s",v,v,v) end end - local e = edit_template( - detail and detail.sampletext or sample_line, - detail and detail.name or "no name", - detail and detail.title or "", - concat(scripts," "), - concat(languages," "), - concat(features," "), - concat(options," ") - ) + local e = format(edit_template, + (detail and detail.sampletext) or sample_line,(detail and detail.name) or "no name",(detail and detail.title) or "", + concat(scripts," "),concat(languages," "),concat(features," "),concat(options," ")) if tempname then - local pdffile, texfile = file.replacesuffix(tempname,"pdf"), file.replacesuffix(tempname,"tex") - local r = result_template(pdffile,texfile,pdffile,runtime and formatters["%0.3f"](runtime) or "-") - return main_template(currentfont,e,r), htmldata.javascript or "" + local pdffile, texfile = file.addsuffix(tempname,"pdf"), file.addsuffix(tempname,"tex") + local r = format(result_template,pdffile,texfile,pdffile) + return e .. r, htmldata.javascript or "" else - return main_template(currentfont,e,""), htmldata.javascript or "" + return e, htmldata.javascript or "" end else return "error, nothing set up yet" @@ -425,13 +368,13 @@ end local function process_font(currentfont,detail) -- maybe just fontname local features = { "mode=node", - formatters["language=%s"](detail.language or "dflt"), - formatters["script=%s"](detail.script or "dflt"), + format("language=%s",detail.language or "dflt"), + format("script=%s",detail.script or "dflt"), } for k,v in next, detail do local f = match(k,"^f%-(.*)$") if f then - features[#features+1] = formatters["%s=yes"](f) + features[#features+1] = format("%s=yes",f) end end local variant = process_templates.default @@ -442,76 +385,69 @@ local function process_font(currentfont,detail) -- maybe just fontname if sample == "" then sample = sample_line end report("sample text: %s",sample) dir.mkdirs(temppath) - local tempname = makename(tempname,true) - local usedname = file.addsuffix(tempname,"tex") - local fullname = file.join(temppath,usedname) - local data = variant(concat(features,","),currentfont,sample,currentfont,sample) + local fullname = file.join(temppath,file.addsuffix(tempname,"tex")) + local data = format(variant,concat(features,","),currentfont,sample) + local command = format("mtxrun --path=%q --script context --once --batchmode %q",temppath,tempname) + report("filename: %s",fullname) + report("command: %s",command) io.savedata(fullname,data) - io.flush() - local runtime = runcontext(temppath,usedname) - return edit_font(currentfont,detail,tempname,runtime) + os.execute(command) + return edit_font(currentfont,detail,tempname) end -local tex_template = formatters [ [[ -<h1>Font: %s</h1><br/> +local tex_template = [[ <pre><tt> %s </tt></pre> -]] ] +]] local function show_source(currentfont,detail) - local tempname = makename(tempname) if tempname and tempname ~= "" then - local data = io.loaddata(file.join(temppath,file.replacesuffix(tempname,"tex"))) or "no source yet" - return tex_template(currentfont,data) + local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,"tex"))) or "no source yet" + return format(tex_template,data) else return "no source file" end end local function show_log(currentfont,detail) - local tempname = makename(tempname) if tempname and tempname ~= "" then - local data = io.loaddata(file.join(temppath,file.replacesuffix(tempname,'log'))) or "no log file yet" + local data = io.loaddata(file.join(temppath,file.addsuffix(tempname,'log'))) or "no log file yet" data = gsub(data,"[%s%%]*begin of optionfile.-end of optionfile[%s%%]*","\n") - return tex_template(currentfont,data) + return format(tex_template,data) else return "no log file" end end --- much nicer would be an lmx template - local function show_font(currentfont,detail) local specification = get_specification(currentfont) local features = fonts.helpers.getfeatures(specification.filename) local result = { } - result[#result+1] = formatters["<h1>Font: %s</h1><br/>"](currentfont) + result[#result+1] = format("<h1>names</h1>",what) result[#result+1] = "<table>" - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>fontname </td><td style='width:20em'>%s</td>"] (specification.fontname or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>designsize </td><td style='width:20em'>%s</td></tr>"](specification.designsize or "-") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>fullname </td><td style='width:20em'>%s</td>"] (specification.fullname or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>minimumsize</td><td style='width:20em'>%s</td></tr>"](specification.minsize or "-") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>filename </td><td style='width:20em'>%s</td>"] (specification.fontfile or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>maximumsize</td><td style='width:20em'>%s</td></tr>"](specification.maxsize or "-") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>rawname </td><td style='width:20em'>%s</td>"] (specification.rawname or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>fontweight </td><td style='width:20em'>%s</td></tr>"](specification.fontweight or "-") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>familyname </td><td style='width:20em'>%s</td>"] (specification.familyname or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>angle </td><td style='width:20em'>%s</td></tr>"](specification.angle or "-") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>subfamily </td><td style='width:20em'>%s</td>"] (specification.subfamily or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>variant </td><td style='width:20em'>%s</td></tr>"](specification.variant ~= "" and specification.variant or "normal") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>format </td><td style='width:20em'>%s</td>"] (specification.format or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>style </td><td style='width:20em'>%s</td></tr>"](specification.style ~= "" and specification.style or "normal") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>pfmwidth </td><td style='width:20em'>%s</td>"] (specification.pfmwidth ~= "" and specification.pfmwidth or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>weight </td><td style='width:20em'>%s</td></tr>"](specification.weight ~= "" and specification.weight or "normal") - result[#result+1] = formatters["<tr><td class='tc' style='width:10em'>pfmheight </td><td style='width:20em'>%s</td>"] (specification.pfmweight ~= "" and specification.pfmweight or "-") - result[#result+1] = formatters[" <td class='tc' style='width:10em'>width </td><td style='width:20em'>%s</td></tr>"](specification.width ~= "" and specification.width or "normal") + result[#result+1] = format("<tr><td class='tc'>fontname: </td><td>%s</td></tr>",currentfont) + result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fontname or "-") + result[#result+1] = format("<tr><td class='tc'>filename: </td><td>%s</td></tr>",specification.fontfile or "-") + result[#result+1] = format("<tr><td class='tc'>familyname: </td><td>%s</td></tr>",specification.familyname or "-") + result[#result+1] = format("<tr><td class='tc'>fontweight: </td><td>%s</td></tr>",specification.fontweight or "-") + result[#result+1] = format("<tr><td class='tc'>format: </td><td>%s</td></tr>",specification.format or "-") + result[#result+1] = format("<tr><td class='tc'>fullname: </td><td>%s</td></tr>",specification.fullname or "-") + result[#result+1] = format("<tr><td class='tc'>subfamily: </td><td>%s</td></tr>",specification.subfamily or "-") + result[#result+1] = format("<tr><td class='tc'>rawname: </td><td>%s</td></tr>",specification.rawname or "-") + result[#result+1] = format("<tr><td class='tc'>designsize: </td><td>%s</td></tr>",specification.designsize or "-") + result[#result+1] = format("<tr><td class='tc'>minimumsize:</td><td>%s</td></tr>",specification.minsize or "-") + result[#result+1] = format("<tr><td class='tc'>maximumsize:</td><td>%s</td></tr>",specification.maxsize or "-") + result[#result+1] = format("<tr><td class='tc'>style: </td><td>%s</td></tr>",specification.style ~= "" and specification.style or "normal") + result[#result+1] = format("<tr><td class='tc'>variant: </td><td>%s</td></tr>",specification.variant ~= "" and specification.variant or "normal") + result[#result+1] = format("<tr><td class='tc'>weight: </td><td>%s</td></tr>",specification.weight ~= "" and specification.weight or "normal") + result[#result+1] = format("<tr><td class='tc'>width: </td><td>%s</td></tr>",specification.width ~= "" and specification.width or "normal") result[#result+1] = "</table>" if features then for what, v in table.sortedhash(features) do local data = features[what] if data and next(data) then - result[#result+1] = formatters["<h1>%s features</h1><br/>"](what) + result[#result+1] = format("<h1>%s features</h1>",what) result[#result+1] = "<table>" result[#result+1] = "<tr><th>feature</th><th>tag </th><th>script </th><th>languages </th></tr>" for f,ff in table.sortedhash(data) do @@ -525,7 +461,7 @@ local function show_font(currentfont,detail) done = true end local title = fonts.handlers.otf.tables.features[f] or "" - result[#result+1] = formatters["<tr><td width='50%%'>%s </td><td><tt>%s </tt></td><td><tt>%s </tt></td><td><tt>%s </tt></td></tr>"](title,f,s,concat(table.sortedkeys(ss)," ")) + result[#result+1] = format("<tr><td width='50%%'>%s </td><td><tt>%s </tt></td><td><tt>%s </tt></td><td><tt>%s </tt></td></tr>",title,f,s,concat(table.sortedkeys(ss)," ")) end end result[#result+1] = "</table>" @@ -537,7 +473,8 @@ local function show_font(currentfont,detail) return concat(result,"\n") end -local info_template = formatters [ [[ + +local info_template = [[ <pre><tt> version : %s comment : %s @@ -548,14 +485,14 @@ maillist : ntg-context at ntg.nl webpage : www.pragma-ade.nl wiki : contextgarden.net </tt></pre> -]] ] +]] local function info_about() local m = modules ['mtx-server-ctx-fonttest'] - return info_template(m.version,m.comment,m.author,m.copyright) + return format(info_template,m.version,m.comment,m.author,m.copyright) end -local save_template = formatters [ [[ +local save_template = [[ the current setup has been saved: <br/> <br/> <table> @@ -568,7 +505,7 @@ local save_template = formatters [ [[ <tr><td class='tc'>options </td><td>%s</td></tr> <tr><td class='tc'>sampletext </td><td>%s</td></tr> </table> -]] ] +]] local function loadbase() local datafile = file.join(basepath,basename) @@ -647,23 +584,23 @@ local function save_font(currentfont,detail) font = currentfont, title = title, script = script, language = language, features = features, options = options, text = text, } savebase(storage,name) - return save_template(name,title,currentfont,script,language,concat(table.sortedkeys(features)," "),concat(table.sortedkeys(options)," "),text) + return format(save_template,name,title,currentfont,script,language,concat(table.sortedkeys(features)," "),concat(table.sortedkeys(options)," "),text) end local function load_font(currentfont) local datafile = file.join(basepath,basename) local storage = loadbase(datafile) local result = {} - result[#result+1] = "<tr><th>del </th><th>name </th><th>font </th><th>fontname </th><th>script </th><th>language </th><th>features </th><th>title </th><th>sampletext </th></tr>" + result[#result+1] = format("<tr><th>del </th><th>name </th><th>font </th><th>fontname </th><th>script </th><th>language </th><th>features </th><th>title </th><th>sampletext </th></tr>") for k,v in table.sortedhash(storage) do local fontname, fontfile = get_specification(v.font) - result[#result+1] = formatters["<tr><td><a href='mtx-server-ctx-fonttest.lua?deletename=%s'>x</a> </td><td><a href='mtx-server-ctx-fonttest.lua?loadname=%s'>%s</a> </td><td>%s </td<td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td></tr>"]( + result[#result+1] = format("<tr><td><a href='mtx-server-ctx-fonttest.lua?deletename=%s'>x</a> </td><td><a href='mtx-server-ctx-fonttest.lua?loadname=%s'>%s</a> </td><td>%s </td<td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td><td>%s </td></tr>", k,k,k,v.font,fontname,v.script,v.language,concat(table.sortedkeys(v.features)," "),v.title or "no title",v.text or "") end if #result == 1 then return "nothing saved yet" else - return formatters["<table>%s</table>"](concat(result,"\n")) + return format("<table>%s</table>",concat(result,"\n")) end end @@ -671,12 +608,12 @@ local function reset_font(currentfont) return edit_font(currentfont) end -local extras_template = formatters [ [[ +local extras_template = [[ <a href='mtx-server-ctx-fonttest.lua?extra=reload'>remake font database</a> (take some time)<br/><br/> -]] ] +]] local function do_extras(detail,currentfont,extra) - return extras_template() + return extras_template end local extras = { } @@ -688,13 +625,16 @@ local function do_extra(detail,currentfont,extra) end function extras.reload() - identifyfonts() + local command = "mtxrun --script font --reload" + report("run command: %s",command) + os.execute(command) return do_extras() end -local status_template = formatters [ [[ + +local status_template = [[ <input type="hidden" name="currentfont" value="%s" /> -]] ] +]] local variables = { ['color-background-one'] = lmx.get('color-background-green'), @@ -703,8 +643,6 @@ local variables = { ['formaction'] = "mtx-server-ctx-fonttest.lua", } --- todo: use lmx file - function doit(configuration,filename,hashed) local start = os.clock() @@ -715,12 +653,6 @@ function doit(configuration,filename,hashed) local action = detail.action local selection = detail.selection - if action == "luajittex" then - jitmode = true - elseif action == "luatex" then - jitmode = false - end - local loadname = detail.loadname local deletename = detail.deletename local extra = detail.extra @@ -741,34 +673,30 @@ function doit(configuration,filename,hashed) local fontname, fontfile = get_specification(currentfont) if fontfile then - variables.title = formatters['ConTeXt Font Tester: %s (%s)'](fontname,fontfile) + variables.title = format('ConTeXt Font Tester: %s (%s)',fontname,fontfile) else variables.title = 'ConTeXt Font Tester' end - if jitmode then - variables.title = variables.title .. " (using LuaJit vm)" - end - -- lua table and adapt - report("action: %s",action or "no action") - - local buttons = { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras', jitmode and "luatex" or "luajittex" } + local buttons = { 'process', 'select', 'save', 'load', 'edit', 'reset', 'features', 'source', 'log', 'info', 'extras'} local menu = { } for i=1,#buttons do local button = buttons[i] - menu[#menu+1] = formatters["<button name='action' value='%s' type='submit'>%s</button>"](button,button) + menu[#menu+1] = format("<button name='action' value='%s' type='submit'>%s</button>",button,button) end variables.menu = concat(menu," ") - variables.status = status_template(currentfont or "") + variables.status = format(status_template,currentfont or "") variables.maintext = "" variables.javascriptdata = "" variables.javascripts = "" variables.javascriptinit = "" + report("action: %s",action or "no action") + local result if action == "select" then diff --git a/scripts/context/lua/mtx-server-ctx-help.lua b/scripts/context/lua/mtx-server-ctx-help.lua index d948c6e46..b8dc0dfb2 100644 --- a/scripts/context/lua/mtx-server-ctx-help.lua +++ b/scripts/context/lua/mtx-server-ctx-help.lua @@ -542,11 +542,11 @@ function document.setups.collect(name,int,lastmode) local left, right = d[k].at.name or "?", { } if tag == "inherit" then local name = d[k].at.name or "?" - local url = format(document.setups.formats.href_as_command[lastmode],name,lastmode,name) + local goto = format(document.setups.formats.href_as_command[lastmode],name,lastmode,name) if #parameters > 0 and not find(parameters[#parameters],"<br/>") then parameters[#parameters+1] = format(formats.parameter,"<br/>","","") end - parameters[#parameters+1] = format(formats.parameter,what,format(formats.special,translate("inherits",int)),url) + parameters[#parameters+1] = format(formats.parameter,what,format(formats.special,translate("inherits",int)),goto) else for r, d, k in xml.elements(d[k],"(cd:constant|cd:resolve)") do local tag = d[k].tg @@ -664,23 +664,9 @@ local function doit(configuration,filename,hashed) if document.setups.showsources and lastsource and lastsource ~= "" then -- todo: mkii, mkiv, tex (can be different) - local name = lastsource - local full = resolvers.findfile(name) - if full == "" and file.suffix(lastsource) == "tex" then - name = file.replacesuffix(lastsource,"mkiv") - full = resolvers.findfile(name) - if full == "" then - name = file.replacesuffix(lastsource,"mkvi") - full = resolvers.findfile(name) - end - end - if full == "" then - variables.maintitle = lastsource - variables.maintext = format(formats.listing,"no source found") - else - variables.maintitle = name - variables.maintext = format(formats.listing,io.loaddata(full)) - end + local data = io.loaddata(resolvers.findfile(lastsource)) + variables.maintitle = lastsource + variables.maintext = format(formats.listing,data) lastsource = "" elseif lastcommand and lastcommand ~= "" then local data = document.setups.collect(lastcommand,lastinterface,lastmode) diff --git a/scripts/context/lua/mtx-server.lua b/scripts/context/lua/mtx-server.lua index 5466bfe80..5ec15de70 100644 --- a/scripts/context/lua/mtx-server.lua +++ b/scripts/context/lua/mtx-server.lua @@ -43,7 +43,7 @@ scripts.webserver = scripts.webserver or { } dofile(resolvers.findfile("luat-soc.lua","tex")) local socket = socket or require("socket") ------ http = http or require("socket.http") -- not needed +local http = http or require("socket.http") -- not needed local format = string.format -- The following two lists are taken from webrick (ruby) and @@ -197,7 +197,6 @@ function handlers.generic(client,configuration,data,suffix,iscontent) client:send("Connection: close\r\n") client:send(format("Content-Length: %s\r\n",#data)) client:send(format("Content-Type: %s\r\n",(suffix and mimetypes[suffix]) or "text/html")) - client:send("Cache-Control: no-cache, no-store, must-revalidate, max-age=0\r\n") client:send("\r\n") client:send(data) client:send("\r\n") @@ -334,9 +333,8 @@ function scripts.webserver.run(configuration) report("no url") errormessage(client,configuration,404) else - fullurl = url.unescapeget(fullurl) report("requested url: %s",fullurl) - -- fullurl = socket.url.unescape(fullurl) -- happens later + fullurl = socket.url.unescape(fullurl) -- still needed? local hashed = url.hashed(fullurl) local query = url.query(hashed.query) local filename = hashed.path -- hm, not query? diff --git a/scripts/context/lua/mtx-tools.lua b/scripts/context/lua/mtx-tools.lua index a38e9d7e6..19b7458a1 100644 --- a/scripts/context/lua/mtx-tools.lua +++ b/scripts/context/lua/mtx-tools.lua @@ -31,7 +31,6 @@ local helpinfo = [[ <flag name="recurse"><short>recurse into subdirecories</short></flag> <flag name="stripname"><short>take pathpart of given pattern</short></flag> <flag name="longname"><short>set name attributes to full path name</short></flag> - <flag name="downcase"><short>lowercase names</short></flag> </subcategory> <subcategory> <flag name="pattern"><short>glob pattern (default: *)</short></flag> diff --git a/scripts/context/lua/mtx-update.lua b/scripts/context/lua/mtx-update.lua index 25a5ac527..64203d3e3 100644 --- a/scripts/context/lua/mtx-update.lua +++ b/scripts/context/lua/mtx-update.lua @@ -162,9 +162,6 @@ scripts.update.platforms = { ["windows"] = "mswin", ["win32"] = "mswin", ["win"] = "mswin", - ["mswin-64"] = "mswin-64", - ["windows-64"] = "mswin-64", - ["win64"] = "mswin-64", ["linux"] = "linux", ["freebsd"] = "freebsd", ["freebsd-amd64"] = "freebsd-amd64", @@ -253,7 +250,7 @@ function scripts.update.synchronize() bin = gsub(bin,"\\","/") - if not find(url,"::$") then url = url .. "::" end + if not url:find("::$") then url = url .. "::" end local ok = lfs.attributes(texroot,"mode") == "directory" if not ok and force then dir.mkdirs(texroot) @@ -314,10 +311,10 @@ function scripts.update.synchronize() os.execute(command) -- read output of rsync local data = io.loaddata(temp_file) or "" - -- for every line extract the filename : drwxr-sr-x 18 2013/10/06 06:16:10 libertine - for chmod, s in gmatch(data,"([d%-][rwxst%-]+).-(%S+)[\n\r]") do + -- for every line extract the filename + for chmod, s in data:gmatch("([d%-][rwx%-]+).-(%S+)[\n\r]") do -- skip "current" folder - if s ~= '.' and #chmod >= 10 then + if s ~= '.' and chmod:len() == 10 then folders[#folders+1] = s end end @@ -433,7 +430,7 @@ function scripts.update.synchronize() if not environment.argument("force") then dryrunflags = "--dry-run" end - if (find(destination,"texmf$") or find(destination,"texmf%-context$") or find(destination,"texmf%-modules$")) and (not environment.argument("keep")) then + if (destination:find("texmf$") or destination:find("texmf%-context$") or destination:find("texmf%-modules$")) and (not environment.argument("keep")) then deleteflags = states.get("rsync.flags.delete") end command = format("%s %s %s %s %s'%s' '%s'", bin, normalflags, deleteflags, dryrunflags, url, archives, destination) diff --git a/scripts/context/lua/mtxlibs.lua b/scripts/context/lua/mtxlibs.lua index ae9d70108..7f52ac8bd 100644 --- a/scripts/context/lua/mtxlibs.lua +++ b/scripts/context/lua/mtxlibs.lua @@ -111,7 +111,6 @@ local ownlibs = { "lxml-aux.lua", "lxml-xml.lua", - "trac-xml.lua", -- handy for helpinfo } package.path = "t:/sources/?.lua;t:/sources/?;" .. package.path @@ -185,7 +184,7 @@ end local arguments = environment.arguments local files = environment.files -if file.basename(environment.ownname) ~= "mtxlibs.lua" then +if environment.ownname ~= "mtxlibs.lua" then return end diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 9edbbf4bf..d07dfc9a7 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -144,7 +144,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-package"] = package.loaded["l-package"] or true --- original size: 10594, stripped down to: 7819 +-- original size: 9893, stripped down to: 7253 if not modules then modules={} end modules ['l-package']={ version=1.001, @@ -154,7 +154,7 @@ if not modules then modules={} end modules ['l-package']={ license="see context related readme files" } local type=type -local gsub,format,find=string.gsub,string.format,string.find +local gsub,format=string.gsub,string.format local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match local package=package local searchers=package.searchers or package.loaders @@ -184,7 +184,6 @@ local helpers=package.helpers or { sequence={ "already loaded", "preload table", - "qualified path", "lua extra list", "lib extra list", "path specification", @@ -330,30 +329,12 @@ local function loadedbypath(name,rawname,paths,islib,what) end end helpers.loadedbypath=loadedbypath -local function loadedbyname(name,rawname) - if find(name,"^/") or find(name,"^[a-zA-Z]:/") then - local trace=helpers.trace - if trace then - helpers.report("qualified name, identifying '%s'",what,name) - end - if isreadable(name) then - if trace then - helpers.report("qualified name, '%s' found",what,name) - end - return loadfile(name) - end - end -end -helpers.loadedbyname=loadedbyname methods["already loaded"]=function(name) return package.loaded[name] end methods["preload table"]=function(name) return builtin["preload table"](name) end -methods["qualified path"]=function(name) - return loadedbyname(addsuffix(lualibfile(name),"lua"),name) -end methods["lua extra list"]=function(name) return loadedbypath(addsuffix(lualibfile(name),"lua" ),name,getextraluapaths(),false,"lua") end @@ -434,7 +415,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true --- original size: 29245, stripped down to: 15964 +-- original size: 26252, stripped down to: 14371 if not modules then modules={} end modules ['l-lpeg']={ version=1.001, @@ -444,7 +425,6 @@ if not modules then modules={} end modules ['l-lpeg']={ license="see context related readme files" } lpeg=require("lpeg") -if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end local type,next,tostring=type,next,tostring local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format local floor=math.floor @@ -460,46 +440,28 @@ patterns.anything=anything patterns.endofstring=endofstring patterns.beginofstring=alwaysmatched patterns.alwaysmatched=alwaysmatched -local sign=S('+-') -local zero=P('0') -local digit=R('09') -local octdigit=R("07") -local lowercase=R("az") -local uppercase=R("AZ") -local underscore=P("_") -local hexdigit=digit+lowercase+uppercase +local digit,sign=R('09'),S('+-') local cr,lf,crlf=P("\r"),P("\n"),P("\r\n") local newline=crlf+S("\r\n") local escaped=P("\\")*anything local squote=P("'") local dquote=P('"') local space=P(" ") -local period=P(".") -local comma=P(",") -local utfbom_32_be=P('\000\000\254\255') -local utfbom_32_le=P('\255\254\000\000') -local utfbom_16_be=P('\254\255') -local utfbom_16_le=P('\255\254') -local utfbom_8=P('\239\187\191') +local utfbom_32_be=P('\000\000\254\255') +local utfbom_32_le=P('\255\254\000\000') +local utfbom_16_be=P('\255\254') +local utfbom_16_le=P('\254\255') +local utfbom_8=P('\239\187\191') local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8 local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8") -local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8") local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0) local utf8next=R("\128\191") -patterns.utfbom_32_be=utfbom_32_be -patterns.utfbom_32_le=utfbom_32_le -patterns.utfbom_16_be=utfbom_16_be -patterns.utfbom_16_le=utfbom_16_le -patterns.utfbom_8=utfbom_8 -patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n") -patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000") patterns.utf8one=R("\000\127") patterns.utf8two=R("\194\223")*utf8next patterns.utf8three=R("\224\239")*utf8next*utf8next patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next patterns.utfbom=utfbom patterns.utftype=utftype -patterns.utfstricttype=utfstricttype patterns.utfoffset=utfoffset local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false) @@ -523,8 +485,23 @@ local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0)) patterns.stripper=stripper patterns.collapser=collapser -patterns.lowercase=lowercase -patterns.uppercase=uppercase +patterns.digit=digit +patterns.sign=sign +patterns.cardinal=sign^0*digit^1 +patterns.integer=sign^0*digit^1 +patterns.unsigned=digit^0*P('.')*digit^1 +patterns.float=sign^0*patterns.unsigned +patterns.cunsigned=digit^0*P(',')*digit^1 +patterns.cfloat=sign^0*patterns.cunsigned +patterns.number=patterns.float+patterns.integer +patterns.cnumber=patterns.cfloat+patterns.integer +patterns.oct=P("0")*R("07")^1 +patterns.octal=patterns.oct +patterns.HEX=P("0x")*R("09","AF")^1 +patterns.hex=P("0x")*R("09","af")^1 +patterns.hexadecimal=P("0x")*R("09","AF","af")^1 +patterns.lowercase=R("az") +patterns.uppercase=R("AZ") patterns.letter=patterns.lowercase+patterns.uppercase patterns.space=space patterns.tab=P("\t") @@ -532,12 +509,12 @@ patterns.spaceortab=patterns.space+patterns.tab patterns.newline=newline patterns.emptyline=newline^1 patterns.equal=P("=") -patterns.comma=comma -patterns.commaspacer=comma*spacer^0 -patterns.period=period +patterns.comma=P(",") +patterns.commaspacer=P(",")*spacer^0 +patterns.period=P(".") patterns.colon=P(":") patterns.semicolon=P(";") -patterns.underscore=underscore +patterns.underscore=P("_") patterns.escaped=escaped patterns.squote=squote patterns.dquote=dquote @@ -550,29 +527,10 @@ patterns.unspacer=((patterns.spacer^1)/"")^0 patterns.singlequoted=squote*patterns.nosquote*squote patterns.doublequoted=dquote*patterns.nodquote*dquote patterns.quoted=patterns.doublequoted+patterns.singlequoted -patterns.digit=digit -patterns.octdigit=octdigit -patterns.hexdigit=hexdigit -patterns.sign=sign -patterns.cardinal=digit^1 -patterns.integer=sign^-1*digit^1 -patterns.unsigned=digit^0*period*digit^1 -patterns.float=sign^-1*patterns.unsigned -patterns.cunsigned=digit^0*comma*digit^1 -patterns.cfloat=sign^-1*patterns.cunsigned -patterns.number=patterns.float+patterns.integer -patterns.cnumber=patterns.cfloat+patterns.integer -patterns.oct=zero*octdigit^1 -patterns.octal=patterns.oct -patterns.HEX=zero*P("X")*(digit+uppercase)^1 -patterns.hex=zero*P("x")*(digit+lowercase)^1 -patterns.hexadecimal=zero*S("xX")*hexdigit^1 -patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigit^1+hexdigit^1*period*hexdigit^0+hexdigit^1)*(S("pP")*sign^-1*hexdigit^1)^-1 -patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^1)*S("eE")*sign^-1*digit^1 -patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring +patterns.propername=R("AZ","az","__")*R("09","AZ","az","__")^0*P(-1) patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) -patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0)) +patterns.longtostring=Cs(whitespace^0/""*nonwhitespace^0*((whitespace^0/" "*(patterns.quoted+nonwhitespace)^1)^0)) local function anywhere(pattern) return P { P(pattern)+1*V(1) } end @@ -744,7 +702,7 @@ function lpeg.replacer(one,two,makefunction,isutf) return pattern end end -function lpeg.finder(lst,makefunction) +function lpeg.finder(lst,makefunction) local pattern if type(lst)=="table" then pattern=P(false) @@ -773,8 +731,8 @@ local splitters_f,splitters_s={},{} function lpeg.firstofsplit(separator) local splitter=splitters_f[separator] if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0) + separator=P(separator) + splitter=C((1-separator)^0) splitters_f[separator]=splitter end return splitter @@ -782,31 +740,12 @@ end function lpeg.secondofsplit(separator) local splitter=splitters_s[separator] if not splitter then - local pattern=P(separator) - splitter=(1-pattern)^0*pattern*C(anything^0) - splitters_s[separator]=splitter - end - return splitter -end -local splitters_s,splitters_p={},{} -function lpeg.beforesuffix(separator) - local splitter=splitters_s[separator] - if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0)*pattern*endofstring + separator=P(separator) + splitter=(1-separator)^0*separator*C(anything^0) splitters_s[separator]=splitter end return splitter end -function lpeg.afterprefix(separator) - local splitter=splitters_p[separator] - if not splitter then - local pattern=P(separator) - splitter=pattern*C(anything^0) - splitters_p[separator]=splitter - end - return splitter -end function lpeg.balancer(left,right) left,right=P(left),P(right) return P { left*((1-left-right)+V(1))^0*right } @@ -1038,6 +977,9 @@ end function lpeg.times(pattern,n) return P(nextstep(n,2^16,{ "start",["1"]=pattern })) end +local digit=R("09") +local period=P(".") +local zero=P("0") local trailingzeros=zero^0*-digit local case_1=period*trailingzeros/"" local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"") @@ -1071,7 +1013,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-string"] = package.loaded["l-string"] or true --- original size: 5547, stripped down to: 2708 +-- original size: 5513, stripped down to: 2708 if not modules then modules={} end modules ['l-string']={ version=1.001, @@ -1172,7 +1114,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-table"] = package.loaded["l-table"] or true --- original size: 30618, stripped down to: 19908 +-- original size: 44626, stripped down to: 19688 if not modules then modules={} end modules ['l-table']={ version=1.001, @@ -1440,7 +1382,6 @@ local noquotes,hexify,handle,reduce,compact,inline,functions local reserved=table.tohash { 'and','break','do','else','elseif','end','false','for','function','if', 'in','local','nil','not','or','repeat','return','then','true','until','while', - 'NaN','goto', } local function simple_table(t) if #t>0 then @@ -1460,12 +1401,12 @@ local function simple_table(t) else tt[nt]=tostring(v) end + elseif tv=="boolean" then + nt=nt+1 + tt[nt]=tostring(v) elseif tv=="string" then nt=nt+1 tt[nt]=format("%q",v) - elseif tv=="boolean" then - nt=nt+1 - tt[nt]=v and "true" or "false" else tt=nil break @@ -1498,7 +1439,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s[%q]={",depth,name)) end elseif tn=="boolean" then - handle(format("%s[%s]={",depth,name and "true" or "false")) + handle(format("%s[%s]={",depth,tostring(name))) else handle(format("%s{",depth)) end @@ -1522,21 +1463,21 @@ local function do_serialize(root,name,depth,level,indexed) for i=1,#sk do local k=sk[i] local v=root[k] - local tv,tk=type(v),type(k) + local t,tk=type(v),type(k) if compact and first and tk=="number" and k>=first and k<=last then - if tv=="number" then + if t=="number" then if hexify then handle(format("%s 0x%04X,",depth,v)) else handle(format("%s %s,",depth,v)) end - elseif tv=="string" then + elseif t=="string" then if reduce and tonumber(v) then handle(format("%s %s,",depth,v)) else handle(format("%s %q,",depth,v)) end - elseif tv=="table" then + elseif t=="table" then if not next(v) then handle(format("%s {},",depth)) elseif inline then @@ -1549,11 +1490,11 @@ local function do_serialize(root,name,depth,level,indexed) else do_serialize(v,k,depth,level+1,true) end - elseif tv=="boolean" then - handle(format("%s %s,",depth,v and "true" or "false")) - elseif tv=="function" then + elseif t=="boolean" then + handle(format("%s %s,",depth,tostring(v))) + elseif t=="function" then if functions then - handle(format('%s load(%q),',depth,dump(v))) + handle(format('%s load(%q),',depth,dump(v))) else handle(format('%s "function",',depth)) end @@ -1564,7 +1505,7 @@ local function do_serialize(root,name,depth,level,indexed) if false then handle(format("%s __p__=nil,",depth)) end - elseif tv=="number" then + elseif t=="number" then if tk=="number" then if hexify then handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) @@ -1573,9 +1514,9 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then if hexify then - handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=0x%04X,",depth,tostring(k),v)) else - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%s,",depth,tostring(k),v)) end elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then @@ -1590,7 +1531,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%q]=%s,",depth,k,v)) end end - elseif tv=="string" then + elseif t=="string" then if reduce and tonumber(v) then if tk=="number" then if hexify then @@ -1599,7 +1540,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%s,",depth,k,v)) end elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%s,",depth,tostring(k),v)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%s,",depth,k,v)) else @@ -1613,14 +1554,14 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%q,",depth,k,v)) end elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%q,",depth,tostring(k),v)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,v)) else handle(format("%s [%q]=%q,",depth,k,v)) end end - elseif tv=="table" then + elseif t=="table" then if not next(v) then if tk=="number" then if hexify then @@ -1629,7 +1570,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]={},",depth,k)) end elseif tk=="boolean" then - handle(format("%s [%s]={},",depth,k and "true" or "false")) + handle(format("%s [%s]={},",depth,tostring(k))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={},",depth,k)) else @@ -1645,7 +1586,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) end elseif tk=="boolean" then - handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) + handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", "))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={ %s },",depth,k,concat(st,", "))) else @@ -1657,21 +1598,21 @@ local function do_serialize(root,name,depth,level,indexed) else do_serialize(v,k,depth,level+1) end - elseif tv=="boolean" then + elseif t=="boolean" then if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [0x%04X]=%s,",depth,k,tostring(v))) else - handle(format("%s [%s]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [%s]=%s,",depth,k,tostring(v))) end elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) + handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%s,",depth,k,v and "true" or "false")) + handle(format("%s %s=%s,",depth,k,tostring(v))) else - handle(format("%s [%q]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [%q]=%s,",depth,k,tostring(v))) end - elseif tv=="function" then + elseif t=="function" then if functions then local f=getinfo(v).what=="C" and dump(dummy) or dump(v) if tk=="number" then @@ -1681,7 +1622,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=load(%q),",depth,k,f)) end elseif tk=="boolean" then - handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + handle(format("%s [%s]=load(%q),",depth,tostring(k),f)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=load(%q),",depth,k,f)) else @@ -1696,7 +1637,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%q,",depth,k,tostring(v))) end elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) + handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,tostring(v))) else @@ -2040,7 +1981,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-io"] = package.loaded["l-io"] or true --- original size: 8817, stripped down to: 6340 +-- original size: 8799, stripped down to: 6325 if not modules then modules={} end modules ['l-io']={ version=1.001, @@ -2071,7 +2012,6 @@ local function readall(f) return f:read('*all') else local done=f:seek("set",0) - local step if size<1024*1024 then step=1024*1024 elseif size>16*1024*1024 then @@ -2575,7 +2515,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-os"] = package.loaded["l-os"] or true --- original size: 15800, stripped down to: 9551 +-- original size: 14017, stripped down to: 8504 if not modules then modules={} end modules ['l-os']={ version=1.001, @@ -2656,13 +2596,7 @@ function os.exec (...) ioflush() return exec (...) end function io.popen (...) ioflush() return iopopen(...) end function os.resultof(command) local handle=io.popen(command,"r") - if handle then - local result=handle:read("*all") or "" - handle:close() - return result - else - return "" - end + return handle and handle:read("*all") or "" end if not io.fileseparator then if find(os.getenv("PATH"),";") then @@ -2696,11 +2630,10 @@ if not os.times then } end end -local gettimeofday=os.gettimeofday or os.clock -os.gettimeofday=gettimeofday -local startuptime=gettimeofday() +os.gettimeofday=os.gettimeofday or os.clock +local startuptime=os.gettimeofday() function os.runtime() - return gettimeofday()-startuptime + return os.gettimeofday()-startuptime end os.resolvers=os.resolvers or {} local resolvers=os.resolvers @@ -2833,38 +2766,26 @@ function os.timezone(delta) end local timeformat=format("%%s%s",os.timezone(true)) local dateformat="!%Y-%m-%d %H:%M:%S" -local lasttime=nil -local lastdate=nil function os.fulltime(t,default) - t=t and tonumber(t) or 0 + t=tonumber(t) or 0 if t>0 then elseif default then return default else - t=time() - end - if t~=lasttime then - lasttime=t - lastdate=format(timeformat,date(dateformat)) + t=nil end - return lastdate + return format(timeformat,date(dateformat,t)) end local dateformat="%Y-%m-%d %H:%M:%S" -local lasttime=nil -local lastdate=nil function os.localtime(t,default) - t=t and tonumber(t) or 0 + t=tonumber(t) or 0 if t>0 then elseif default then return default else - t=time() - end - if t~=lasttime then - lasttime=t - lastdate=date(dateformat,t) + t=nil end - return lastdate + return date(dateformat,t) end function os.converttime(t,default) local t=tonumber(t) @@ -2914,38 +2835,6 @@ if not os.sleep then socket.sleep(n) end end -local function isleapyear(year) - return (year%400==0) or ((year%100~=0) and (year%4==0)) -end -os.isleapyear=isleapyear -local days={ 31,28,31,30,31,30,31,31,30,31,30,31 } -local function nofdays(year,month) - if not month then - return isleapyear(year) and 365 or 364 - else - return month==2 and isleapyear(year) and 29 or days[month] - end -end -os.nofdays=nofdays -function os.weekday(day,month,year) - return date("%w",time { year=year,month=month,day=day })+1 -end -function os.validdate(year,month,day) - if month<1 then - month=1 - elseif month>12 then - month=12 - end - if day<1 then - day=1 - else - local max=nofdays(year,month) - if day>max then - day=max - end - end - return year,month,day -end end -- of closure @@ -2954,7 +2843,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-file"] = package.loaded["l-file"] or true --- original size: 18308, stripped down to: 9948 +-- original size: 17777, stripped down to: 9653 if not modules then modules={} end modules ['l-file']={ version=1.001, @@ -3197,24 +3086,17 @@ end function file.joinpath(tab,separator) return tab and concat(tab,separator or io.pathseparator) end -local someslash=S("\\/") local stripper=Cs(P(fwslash)^0/""*reslasher) -local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon +local isnetwork=fwslash*fwslash*(1-fwslash)+(1-fwslash-colon)^1*colon local isroot=fwslash^1*-1 local hasroot=fwslash^1 -local reslasher=lpeg.replacer(S("\\/"),"/") local deslasher=lpeg.replacer(S("\\/")^1,"/") function file.join(...) local lst={... } local one=lst[1] if lpegmatch(isnetwork,one) then - local one=lpegmatch(reslasher,one) local two=lpegmatch(deslasher,concat(lst,"/",2)) - if lpegmatch(hasroot,two) then - return one..two - else - return one.."/"..two - end + return one.."/"..two elseif lpegmatch(isroot,one) then local two=lpegmatch(deslasher,concat(lst,"/",2)) if lpegmatch(hasroot,two) then @@ -3231,9 +3113,7 @@ end local drivespec=R("az","AZ")^1*colon local anchors=fwslash+drivespec local untouched=periods+(1-period)^1*P(-1) -local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0) -local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//") -local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) +local splitstarter=(Cs(drivespec*(bwslash/"/"+fwslash)^0)+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) local absolute=fwslash function file.collapsepath(str,anchor) if not str then @@ -3481,7 +3361,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-url"] = package.loaded["l-url"] or true --- original size: 11993, stripped down to: 5584 +-- original size: 11806, stripped down to: 5417 if not modules then modules={} end modules ['l-url']={ version=1.001, @@ -3532,14 +3412,9 @@ setmetatable(escapes,{ __index=function(t,k) end }) local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_")^1+P(1)/escapes)^0) local unescaper=Cs((escapedchar+1)^0) -local getcleaner=Cs((P("+++")/"%%2B"+P("+")/"%%20"+P(1))^1) lpegpatterns.urlunescaped=escapedchar lpegpatterns.urlescaper=escaper lpegpatterns.urlunescaper=unescaper -lpegpatterns.urlgetcleaner=getcleaner -function url.unescapeget(str) - return lpegmatch(getcleaner,str) -end local function split(str) return (type(str)=="string" and lpegmatch(parser,str)) or str end @@ -3692,7 +3567,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 14229, stripped down to: 8740 +-- original size: 13738, stripped down to: 8560 if not modules then modules={} end modules ['l-dir']={ version=1.001, @@ -3715,7 +3590,6 @@ local isdir=lfs.isdir local isfile=lfs.isfile local currentdir=lfs.currentdir local chdir=lfs.chdir -local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") if not isdir then function isdir(name) local a=attributes(name) @@ -3787,21 +3661,11 @@ local function collectpattern(path,patt,recurse,result) return result end dir.collectpattern=collectpattern -local separator -if onwindows then - local slash=S("/\\")/"/" - pattern=Ct { - [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3), - [2]=Cs(((1-S("*?/\\"))^0*slash)^0), - [3]=Cs(P(1)^0) - } -else - pattern=Ct { - [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3), - [2]=C(((1-S("*?/"))^0*P("/"))^0), - [3]=C(P(1)^0) - } -end +local pattern=Ct { + [1]=(C(P(".")+P("/")^1)+C(R("az","AZ")*P(":")*P("/")^0)+Cc("./"))*V(2)*V(3), + [2]=C(((1-S("*?/"))^0*P("/"))^0), + [3]=C(P(1)^0) +} local filter=Cs (( P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1) )^0 ) @@ -3885,6 +3749,7 @@ function dir.ls(pattern) return concat(glob(pattern),"\n") end local make_indeed=true +local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") if onwindows then function dir.mkdirs(...) local str,pth="","" @@ -3897,8 +3762,9 @@ if onwindows then str=str.."/"..s end end + local first,middle,last local drive=false - local first,middle,last=match(str,"^(//)(//*)(.*)$") + first,middle,last=match(str,"^(//)(//*)(.*)$") if first then else first,last=match(str,"^(//)/*(.-)$") @@ -4059,7 +3925,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-boolean"] = package.loaded["l-boolean"] or true --- original size: 1809, stripped down to: 1527 +-- original size: 1781, stripped down to: 1503 if not modules then modules={} end modules ['l-boolean']={ version=1.001, @@ -4115,9 +3981,9 @@ function string.booleanstring(str) end function string.is_boolean(str,default) if type(str)=="string" then - if str=="true" or str=="yes" or str=="on" or str=="t" or str=="1" then + if str=="true" or str=="yes" or str=="on" or str=="t" then return true - elseif str=="false" or str=="no" or str=="off" or str=="f" or str=="0" then + elseif str=="false" or str=="no" or str=="off" or str=="f" then return false end end @@ -4131,7 +3997,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-unicode"] = package.loaded["l-unicode"] or true --- original size: 33066, stripped down to: 14607 +-- original size: 26810, stripped down to: 11943 if not modules then modules={} end modules ['l-unicode']={ version=1.001, @@ -4144,7 +4010,7 @@ utf=utf or (unicode and unicode.utf8) or {} utf.characters=utf.characters or string.utfcharacters utf.values=utf.values or string.utfvalues local type=type -local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch +local char,byte,format,sub=string.char,string.byte,string.format,string.sub local concat=table.concat local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp local lpegmatch,patterns=lpeg.match,lpeg.patterns @@ -4154,7 +4020,6 @@ local replacer=lpeg.replacer local utfvalues=utf.values local utfgmatch=utf.gmatch local p_utftype=patterns.utftype -local p_utfstricttype=patterns.utfstricttype local p_utfoffset=patterns.utfoffset local p_utf8char=patterns.utf8char local p_utf8byte=patterns.utf8byte @@ -4411,181 +4276,112 @@ function utf.magic(f) end return lpegmatch(p_utftype,str) end -local utf16_to_utf8_be,utf16_to_utf8_le -local utf32_to_utf8_be,utf32_to_utf8_le -local utf_16_be_linesplitter=patterns.utfbom_16_be^-1*lpeg.tsplitat(patterns.utf_16_be_nl) -local utf_16_le_linesplitter=patterns.utfbom_16_le^-1*lpeg.tsplitat(patterns.utf_16_le_nl) -if bytepairs then - utf16_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in bytepairs(t[i]) do - if right then - local now=256*left+right - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end - end - end - t[i]=concat(result,"",1,r) - end - return t +local function utf16_to_utf8_be(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) end - utf16_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in bytepairs(t[i]) do - if right then - local now=256*right+left - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end - end - end - t[i]=concat(result,"",1,r) - end - return t - end - utf32_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utflinesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,-1 - for a,b in bytepairs(t[i]) do - if a and b then - if more<0 then - more=256*256*256*a+256*256*b - else - r=r+1 - result[t]=utfchar(more+256*a+b) - more=-1 - end + local result={} + for i=1,#t do + local r,more=0,0 + for left,right in bytepairs(t[i]) do + if right then + local now=256*left+right + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now else - break + r=r+1 + result[r]=utfchar(now) end end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf32_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utflinesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,-1 - for a,b in bytepairs(t[i]) do - if a and b then - if more<0 then - more=256*b+a - else - r=r+1 - result[t]=utfchar(more+256*256*256*b+256*256*a) - more=-1 - end + return t +end +local function utf16_to_utf8_le(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,0 + for left,right in bytepairs(t[i]) do + if right then + local now=256*right+left + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now else - break + r=r+1 + result[r]=utfchar(now) end end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end -else - utf16_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in gmatch(t[i],"(.)(.)") do - if left=="\000" then + return t +end +local function utf32_to_utf8_be(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,-1 + for a,b in bytepairs(t[i]) do + if a and b then + if more<0 then + more=256*256*256*a+256*256*b + else r=r+1 - result[r]=utfchar(byte(right)) - elseif right then - local now=256*byte(left)+byte(right) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end + result[t]=utfchar(more+256*a+b) + more=-1 end + else + break end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf16_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in gmatch(t[i],"(.)(.)") do - if right=="\000" then + return t +end +local function utf32_to_utf8_le(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,-1 + for a,b in bytepairs(t[i]) do + if a and b then + if more<0 then + more=256*b+a + else r=r+1 - result[r]=utfchar(byte(left)) - elseif right then - local now=256*byte(right)+byte(left) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end + result[t]=utfchar(more+256*256*256*b+256*256*a) + more=-1 end + else + break end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf32_to_utf8_le=function() return {} end - utf32_to_utf8_be=function() return {} end + return t end -utf.utf16_to_utf8_le=utf16_to_utf8_le -utf.utf16_to_utf8_be=utf16_to_utf8_be -utf.utf32_to_utf8_le=utf32_to_utf8_le utf.utf32_to_utf8_be=utf32_to_utf8_be +utf.utf32_to_utf8_le=utf32_to_utf8_le +utf.utf16_to_utf8_be=utf16_to_utf8_be +utf.utf16_to_utf8_le=utf16_to_utf8_le function utf.utf8_to_utf8(t) return type(t)=="string" and lpegmatch(utflinesplitter,t) or t end @@ -4617,17 +4413,11 @@ local function big(c) end local _,l_remap=utf.remapper(little) local _,b_remap=utf.remapper(big) -function utf.utf8_to_utf16_be(str) - return char(254,255)..lpegmatch(b_remap,str) -end -function utf.utf8_to_utf16_le(str) - return char(255,254)..lpegmatch(l_remap,str) -end function utf.utf8_to_utf16(str,littleendian) if littleendian then - return utf.utf8_to_utf16_le(str) + return char(255,254)..lpegmatch(l_remap,str) else - return utf.utf8_to_utf16_be(str) + return char(254,255)..lpegmatch(b_remap,str) end end local pattern=Cs ( @@ -4642,21 +4432,6 @@ end function utf.xstring(s) return format("0x%05X",type(s)=="number" and s or utfbyte(s)) end -function utf.toeight(str) - if not str then - return nil - end - local utftype=lpegmatch(p_utfstricttype,str) - if utftype=="utf-8" then - return sub(str,4) - elseif utftype=="utf-16-le" then - return utf16_to_utf8_le(str) - elseif utftype=="utf-16-be" then - return utf16_to_utf8_ne(str) - else - return str - end -end local p_nany=p_utf8char/"" if utfgmatch then function utf.count(str,what) @@ -4759,7 +4534,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-str"] = package.loaded["util-str"] or true --- original size: 25122, stripped down to: 13877 +-- original size: 22834, stripped down to: 12570 if not modules then modules={} end modules ['util-str']={ version=1.001, @@ -4921,7 +4696,6 @@ local tracedchar = string.tracedchar local autosingle = string.autosingle local autodouble = string.autodouble local sequenced = table.sequenced -local formattednumber = number.formatted ]] local template=[[ %s @@ -4936,7 +4710,7 @@ setmetatable(arguments,{ __index=function(t,k) end }) local prefix_any=C((S("+- .")+R("09"))^0) -local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0) +local prefix_tab=C((1-R("az","AZ","09","%%"))^0) local format_s=function(f) n=n+1 if f and f~="" then @@ -4966,7 +4740,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("a%s",n) end end local format_d=format_i @@ -5118,39 +4892,6 @@ end local format_W=function(f) return format("nspaces[%s]",tonumber(f) or 0) end -local digit=patterns.digit -local period=patterns.period -local three=digit*digit*digit -local splitter=Cs ( - (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2) -) -patterns.formattednumber=splitter -function number.formatted(n,sep1,sep2) - local s=type(s)=="string" and n or format("%0.2f",n) - if sep1==true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1=="." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1=="," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") - else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") - end -end -local format_m=function(f) - n=n+1 - if not f or f=="" then - f="," - end - return format([[formattednumber(a%s,%q,".")]],n,f) -end -local format_M=function(f) - n=n+1 - if not f or f=="" then - f="." - end - return format([[formattednumber(a%s,%q,",")]],n,f) -end local format_rest=function(s) return format("%q",s) end @@ -5188,8 +4929,7 @@ local builder=Cs { "start", +V("w") +V("W") +V("a") -+V("A") -+V("m")+V("M") ++V("A") +V("*") )+V("*") )*(P(-1)+Carg(1)) @@ -5220,16 +4960,14 @@ local builder=Cs { "start", ["b"]=(prefix_any*P("b"))/format_b, ["t"]=(prefix_tab*P("t"))/format_t, ["T"]=(prefix_tab*P("T"))/format_T, - ["l"]=(prefix_any*P("l"))/format_l, - ["L"]=(prefix_any*P("L"))/format_L, + ["l"]=(prefix_tab*P("l"))/format_l, + ["L"]=(prefix_tab*P("L"))/format_L, ["I"]=(prefix_any*P("I"))/format_I, ["w"]=(prefix_any*P("w"))/format_w, ["W"]=(prefix_any*P("W"))/format_W, - ["m"]=(prefix_tab*P("m"))/format_m, - ["M"]=(prefix_tab*P("M"))/format_M, ["a"]=(prefix_any*P("a"))/format_a, ["A"]=(prefix_any*P("A"))/format_A, - ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, + ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%%%")^1)/format_rest, ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local direct=Cs ( @@ -5275,13 +5013,10 @@ local function add(t,name,template,preamble) end end strings.formatters.add=add -patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) -patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) -patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) -patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"')) +lpeg.patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) +lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]]) add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]]) -add(formatters,"lua",[[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]]) end -- of closure @@ -5290,7 +5025,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23952, stripped down to: 16092 +-- original size: 14510, stripped down to: 8531 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5302,14 +5037,13 @@ if not modules then modules={} end modules ['util-tab']={ utilities=utilities or {} utilities.tables=utilities.tables or {} local tables=utilities.tables -local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub +local format,gmatch,gsub=string.format,string.gmatch,string.gsub local concat,insert,remove=table.concat,table.insert,table.remove local setmetatable,getmetatable,tonumber,tostring=setmetatable,getmetatable,tonumber,tostring local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc -local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs +local serialize,sortedkeys,sortedpairs=table.serialize,table.sortedkeys,table.sortedpairs local formatters=string.formatters -local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") function tables.definetable(target,nofirst,nolast) local composed,shortcut,t=nil,nil,{} @@ -5513,78 +5247,47 @@ function tables.encapsulate(core,capsule,protect) } ) end end -local f_hashed_string=formatters["[%q]=%q,"] -local f_hashed_number=formatters["[%q]=%s,"] -local f_hashed_boolean=formatters["[%q]=%l,"] -local f_hashed_table=formatters["[%q]="] -local f_indexed_string=formatters["[%s]=%q,"] -local f_indexed_number=formatters["[%s]=%s,"] -local f_indexed_boolean=formatters["[%s]=%l,"] -local f_indexed_table=formatters["[%s]="] -local f_ordered_string=formatters["%q,"] -local f_ordered_number=formatters["%s,"] -local f_ordered_boolean=formatters["%l,"] -function table.fastserialize(t,prefix) - local r={ prefix or "return" } - local m=1 - local function fastserialize(t,outer) - local n=#t - m=m+1 - r[m]="{" - if n>0 then - for i=0,n do - local v=t[i] - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_ordered_string(v) - elseif tv=="number" then - m=m+1 r[m]=f_ordered_number(v) - elseif tv=="table" then - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_ordered_boolean(v) - end +local function fastserialize(t,r,outer) + r[#r+1]="{" + local n=#t + if n>0 then + for i=1,n do + local v=t[i] + local tv=type(v) + if tv=="string" then + r[#r+1]=formatters["%q,"](v) + elseif tv=="number" then + r[#r+1]=formatters["%s,"](v) + elseif tv=="table" then + fastserialize(v,r) + elseif tv=="boolean" then + r[#r+1]=formatters["%S,"](v) end end + else for k,v in next,t do - local tk=type(k) - if tk=="number" then - if k>n or k<0 then - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_indexed_string(k,v) - elseif tv=="number" then - m=m+1 r[m]=f_indexed_number(k,v) - elseif tv=="table" then - m=m+1 r[m]=f_indexed_table(k) - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_indexed_boolean(k,v) - end - end - else - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_hashed_string(k,v) - elseif tv=="number" then - m=m+1 r[m]=f_hashed_number(k,v) - elseif tv=="table" then - m=m+1 r[m]=f_hashed_table(k) - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_hashed_boolean(k,v) - end + local tv=type(v) + if tv=="string" then + r[#r+1]=formatters["[%q]=%q,"](k,v) + elseif tv=="number" then + r[#r+1]=formatters["[%q]=%s,"](k,v) + elseif tv=="table" then + r[#r+1]=formatters["[%q]="](k) + fastserialize(v,r) + elseif tv=="boolean" then + r[#r+1]=formatters["[%q]=%S,"](k,v) end end - m=m+1 - if outer then - r[m]="}" - else - r[m]="}," - end - return r end - return concat(fastserialize(t,true)) + if outer then + r[#r+1]="}" + else + r[#r+1]="}," + end + return r +end +function table.fastserialize(t,prefix) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) if not str or str=="" then @@ -5604,7 +5307,6 @@ function table.load(filename,loader) if filename then local t=(loader or io.loaddata)(filename) if t and t~="" then - local t=utftoeight(t) t=load(t) if type(t)=="function" then t=t() @@ -5616,12 +5318,9 @@ function table.load(filename,loader) end end function table.save(filename,t,n,...) - io.savedata(filename,table.serialize(t,n==nil and true or n,...)) + io.savedata(filename,serialize(t,n==nil and true or n,...)) end -local f_key_value=formatters["%s=%q"] -local f_add_table=formatters[" {%t},\n"] -local f_return_table=formatters["return {\n%t}"] -local function slowdrop(t) +local function slowdrop(t) local r={} local l={} for i=1,#t do @@ -5629,25 +5328,23 @@ local function slowdrop(t) local j=0 for k,v in next,ti do j=j+1 - l[j]=f_key_value(k,v) + l[j]=formatters["%s=%q"](k,v) end - r[i]=f_add_table(l) + r[i]=formatters[" {%t},\n"](l) end - return f_return_table(r) + return formatters["return {\n%st}"](r) end local function fastdrop(t) local r={ "return {\n" } - local m=1 for i=1,#t do local ti=t[i] - m=m+1 r[m]=" {" + r[#r+1]=" {" for k,v in next,ti do - m=m+1 r[m]=f_key_value(k,v) + r[#r+1]=formatters["%s=%q"](k,v) end - m=m+1 r[m]="},\n" + r[#r+1]="},\n" end - m=m+1 - r[m]="}" + r[#r+1]="}" return concat(r) end function table.drop(t,slow) @@ -5682,216 +5379,6 @@ function table.twowaymapper(t) setmetatable(t,selfmapper) return t end -local f_start_key_idx=formatters["%w{"] -local f_start_key_num=formatters["%w[%s]={"] -local f_start_key_str=formatters["%w[%q]={"] -local f_start_key_boo=formatters["%w[%l]={"] -local f_start_key_nop=formatters["%w{"] -local f_stop=formatters["%w},"] -local f_key_num_value_num=formatters["%w[%s]=%s,"] -local f_key_str_value_num=formatters["%w[%q]=%s,"] -local f_key_boo_value_num=formatters["%w[%l]=%s,"] -local f_key_num_value_str=formatters["%w[%s]=%q,"] -local f_key_str_value_str=formatters["%w[%q]=%q,"] -local f_key_boo_value_str=formatters["%w[%l]=%q,"] -local f_key_num_value_boo=formatters["%w[%s]=%l,"] -local f_key_str_value_boo=formatters["%w[%q]=%l,"] -local f_key_boo_value_boo=formatters["%w[%l]=%l,"] -local f_key_num_value_not=formatters["%w[%s]={},"] -local f_key_str_value_not=formatters["%w[%q]={},"] -local f_key_boo_value_not=formatters["%w[%l]={},"] -local f_key_num_value_seq=formatters["%w[%s]={ %, t },"] -local f_key_str_value_seq=formatters["%w[%q]={ %, t },"] -local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"] -local f_val_num=formatters["%w%s,"] -local f_val_str=formatters["%w%q,"] -local f_val_boo=formatters["%w%l,"] -local f_val_not=formatters["%w{},"] -local f_val_seq=formatters["%w{ %, t },"] -local f_table_return=formatters["return {"] -local f_table_name=formatters["%s={"] -local f_table_direct=formatters["{"] -local f_table_entry=formatters["[%q]={"] -local f_table_finish=formatters["}"] -local spaces=utilities.strings.newrepeater(" ") -local serialize=table.serialize -function table.serialize(root,name,specification) - if type(specification)=="table" then - return serialize(root,name,specification) - end - local t - local n=1 - local function simple_table(t) - if #t>0 then - local n=0 - for _,v in next,t do - n=n+1 - if type(v)=="table" then - return nil - end - end - if n==#t then - local tt={} - local nt=0 - for i=1,#t do - local v=t[i] - local tv=type(v) - nt=nt+1 - if tv=="number" then - tt[nt]=v - elseif tv=="string" then - tt[nt]=format("%q",v) - elseif tv=="boolean" then - tt[nt]=v and "true" or "false" - else - return nil - end - end - return tt - end - end - return nil - end - local function do_serialize(root,name,depth,level,indexed) - if level>0 then - n=n+1 - if indexed then - t[n]=f_start_key_idx(depth) - else - local tn=type(name) - if tn=="number" then - t[n]=f_start_key_num(depth,name) - elseif tn=="string" then - t[n]=f_start_key_str(depth,name) - elseif tn=="boolean" then - t[n]=f_start_key_boo(depth,name) - else - t[n]=f_start_key_nop(depth) - end - end - depth=depth+1 - end - if root and next(root) then - local first=nil - local last=0 - last=#root - for k=1,last do - if root[k]==nil then - last=k-1 - break - end - end - if last>0 then - first=1 - end - local sk=sortedkeys(root) - for i=1,#sk do - local k=sk[i] - local v=root[k] - local tv=type(v) - local tk=type(k) - if first and tk=="number" and k>=first and k<=last then - if tv=="number" then - n=n+1 t[n]=f_val_num(depth,v) - elseif tv=="string" then - n=n+1 t[n]=f_val_str(depth,v) - elseif tv=="table" then - if not next(v) then - n=n+1 t[n]=f_val_not(depth) - else - local st=simple_table(v) - if st then - n=n+1 t[n]=f_val_seq(depth,st) - else - do_serialize(v,k,depth,level+1,true) - end - end - elseif tv=="boolean" then - n=n+1 t[n]=f_val_boo(depth,v) - end - elseif tv=="number" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_num(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_num(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_num(depth,k,v) - end - elseif tv=="string" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_str(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_str(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_str(depth,k,v) - end - elseif tv=="table" then - if not next(v) then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_not(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_not(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_not(depth,k,v) - end - else - local st=simple_table(v) - if not st then - do_serialize(v,k,depth,level+1) - elseif tk=="number" then - n=n+1 t[n]=f_key_num_value_seq(depth,k,st) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_seq(depth,k,st) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_seq(depth,k,st) - end - end - elseif tv=="boolean" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_boo(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_boo(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_boo(depth,k,v) - end - end - end - end - if level>0 then - n=n+1 t[n]=f_stop(depth-1) - end - end - local tname=type(name) - if tname=="string" then - if name=="return" then - t={ f_table_return() } - else - t={ f_table_name(name) } - end - elseif tname=="number" then - t={ f_table_entry(name) } - elseif tname=="boolean" then - if name then - t={ f_table_return() } - else - t={ f_table_direct() } - end - else - t={ f_table_name("t") } - end - if root then - if getmetatable(root) then - local dummy=root._w_h_a_t_e_v_e_r_ - root._w_h_a_t_e_v_e_r_=nil - end - if next(root) then - do_serialize(root,name,1,0) - end - end - n=n+1 - t[n]=f_table_finish() - return concat(t,"\n") -end end -- of closure @@ -5900,7 +5387,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-sto"] = package.loaded["util-sto"] or true --- original size: 4172, stripped down to: 2953 +-- original size: 4432, stripped down to: 3123 if not modules then modules={} end modules ['util-sto']={ version=1.001, @@ -5970,47 +5457,56 @@ end local function f_empty () return "" end local function f_self (t,k) t[k]=k return k end local function f_table (t,k) local v={} t[k]=v return v end -local function f_number(t,k) t[k]=0 return 0 end local function f_ignore() end -local f_index={ - ["empty"]=f_empty, - ["self"]=f_self, - ["table"]=f_table, - ["number"]=f_number, -} -local t_index={ - ["empty"]={ __index=f_empty }, - ["self"]={ __index=f_self }, - ["table"]={ __index=f_table }, - ["number"]={ __index=f_number }, -} +local t_empty={ __index=f_empty } +local t_self={ __index=f_self } +local t_table={ __index=f_table } +local t_ignore={ __newindex=f_ignore } function table.setmetatableindex(t,f) if type(t)~="table" then f,t=t,{} end local m=getmetatable(t) if m then - m.__index=f_index[f] or f + if f=="empty" then + m.__index=f_empty + elseif f=="key" then + m.__index=f_self + elseif f=="table" then + m.__index=f_table + else + m.__index=f + end else - setmetatable(t,t_index[f] or { __index=f }) + if f=="empty" then + setmetatable(t,t_empty) + elseif f=="key" then + setmetatable(t,t_self) + elseif f=="table" then + setmetatable(t,t_table) + else + setmetatable(t,{ __index=f }) + end end return t end -local f_index={ - ["ignore"]=f_ignore, -} -local t_index={ - ["ignore"]={ __newindex=f_ignore }, -} function table.setmetatablenewindex(t,f) if type(t)~="table" then f,t=t,{} end local m=getmetatable(t) if m then - m.__newindex=f_index[f] or f + if f=="ignore" then + m.__newindex=f_ignore + else + m.__newindex=f + end else - setmetatable(t,t_index[f] or { __newindex=f }) + if f=="ignore" then + setmetatable(t,t_ignore) + else + setmetatable(t,{ __newindex=f }) + end end return t end @@ -6047,7 +5543,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 18558, stripped down to: 13323 +-- original size: 17827, stripped down to: 12722 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6059,9 +5555,8 @@ if not modules then modules={} end modules ['util-prs']={ local lpeg,table,string=lpeg,table,string local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local concat,gmatch,find=table.concat,string.gmatch,string.find +local concat,format,gmatch,find=table.concat,string.format,string.gmatch,string.find local tostring,type,next,rawset=tostring,type,next,rawset -local mod,div=math.mod,math.div utilities=utilities or {} local parsers=utilities.parsers or {} utilities.parsers=parsers @@ -6265,12 +5760,6 @@ function parsers.simple_hash_to_string(h,separator) end return concat(t,separator or ",") end -local str=C((1-whitespace-equal)^1) -local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset) -local splitter=setting^1 -function utilities.parsers.options_to_hash(str,target) - return str and lpegmatch(splitter,str,1,target or {}) or {} -end local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1) local pattern_a=spaces*Ct(value*(separator*value)^0) local function repeater(n,str) @@ -6375,7 +5864,7 @@ function parsers.csvsplitter(specification) end whatever=quotedata+whatever end - local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 ) + local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r"))^0 ) return function(data) return lpegmatch(parser,data) end @@ -6483,7 +5972,7 @@ end local function fetch(t,name) return t[name] or {} end -local function process(result,more) +function process(result,more) for k,v in next,more do result[k]=v end @@ -6495,18 +5984,6 @@ local merge=Cf(parser,process) function utilities.parsers.mergehashes(hash,list) return lpegmatch(merge,list,1,hash) end -function utilities.parsers.runtime(time) - if not time then - time=os.runtime() - end - local days=div(time,24*60*60) - time=mod(time,24*60*60) - local hours=div(time,60*60) - time=mod(time,60*60) - local minutes=div(time,60) - local seconds=mod(time,60) - return days,hours,minutes,seconds -end end -- of closure @@ -6908,7 +6385,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-log"] = package.loaded["trac-log"] or true --- original size: 25391, stripped down to: 16561 +-- original size: 21914, stripped down to: 14287 if not modules then modules={} end modules ['trac-log']={ version=1.001, @@ -6921,11 +6398,11 @@ local write_nl,write=texio and texio.write_nl or print,texio and texio.write or local format,gmatch,find=string.format,string.gmatch,string.find local concat,insert,remove=table.concat,table.insert,table.remove local topattern=string.topattern +local texcount=tex and tex.count local next,type,select=next,type,select local utfchar=utf.char local setmetatableindex=table.setmetatableindex local formatters=string.formatters -local texgetcount=tex and tex.getcount logs=logs or {} local logs=logs local moreinfo=[[ @@ -6946,7 +6423,7 @@ utilities.strings.formatters.add ( local function ignore() end setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end) local report,subreport,status,settarget,setformats,settranslations -local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters +local direct,subdirect,writer,pushtarget,poptarget if tex and (tex.jobname or tex.formatname) then local valueiskey={ __index=function(t,k) t[k]=k return k end } local target="term and log" @@ -6959,67 +6436,67 @@ if tex and (tex.jobname or tex.formatname) then newline=function() write_nl(target,"\n") end - local report_yes=formatters["%-15s > %s\n"] - local report_nop=formatters["%-15s >\n"] + local f_one=formatters["%-15s > %s\n"] + local f_two=formatters["%-15s >\n"] report=function(a,b,c,...) if c then - write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],formatters[formats[b]](c,...))) elseif b then - write_nl(target,report_yes(translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,report_nop(translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end - local direct_yes=formatters["%-15s > %s"] - local direct_nop=formatters["%-15s >"] + local f_one=formatters["%-15s > %s"] + local f_two=formatters["%-15s >"] direct=function(a,b,c,...) if c then - return direct_yes(translations[a],formatters[formats[b]](c,...)) + return f_one(translations[a],formatters[formats[b]](c,...)) elseif b then - return direct_yes(translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return direct_nop(translations[a]) + return f_two(translations[a]) else return "" end end - local subreport_yes=formatters["%-15s > %s > %s\n"] - local subreport_nop=formatters["%-15s > %s >\n"] + local f_one=formatters["%-15s > %s > %s\n"] + local f_two=formatters["%-15s > %s >\n"] subreport=function(a,s,b,c,...) if c then - write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],translations[s],formatters[formats[b]](c,...))) elseif b then - write_nl(target,subreport_yes(translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,subreport_nop(translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end - local subdirect_yes=formatters["%-15s > %s > %s"] - local subdirect_nop=formatters["%-15s > %s >"] + local f_one=formatters["%-15s > %s > %s"] + local f_two=formatters["%-15s > %s >"] subdirect=function(a,s,b,c,...) if c then - return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...)) + return f_one(translations[a],translations[s],formatters[formats[b]](c,...)) elseif b then - return subdirect_yes(translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return subdirect_nop(translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end - local status_yes=formatters["%-15s : %s\n"] - local status_nop=formatters["%-15s :\n"] + local f_one=formatters["%-15s : %s\n"] + local f_two=formatters["%-15s :\n"] status=function(a,b,c,...) if c then - write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],formatters[formats[b]](c,...))) elseif b then - write_nl(target,status_yes(translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,status_nop(translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -7056,69 +6533,47 @@ if tex and (tex.jobname or tex.formatname) then settranslations=function(t) translations=t end - setprocessor=function(f) - local writeline=write_nl - write_nl=function(target,...) - writeline(target,f(...)) - end - end - setformatters=function(f) - report_yes=f.report_yes or report_yes - report_nop=f.report_nop or report_nop - subreport_yes=f.subreport_yes or subreport_yes - subreport_nop=f.subreport_nop or subreport_nop - direct_yes=f.direct_yes or direct_yes - direct_nop=f.direct_nop or direct_nop - subdirect_yes=f.subdirect_yes or subdirect_yes - subdirect_nop=f.subdirect_nop or subdirect_nop - status_yes=f.status_yes or status_yes - status_nop=f.status_nop or status_nop - end - setlogfile=ignore - settimedlog=ignore else logs.flush=ignore - writer=function(s) - write_nl(s) - end + writer=write_nl newline=function() write_nl("\n") end - local report_yes=formatters["%-15s | %s"] - local report_nop=formatters["%-15s |"] + local f_one=formatters["%-15s | %s"] + local f_two=formatters["%-15s |"] report=function(a,b,c,...) if c then - write_nl(report_yes(a,formatters[b](c,...))) + write_nl(f_one(a,formatters[b](c,...))) elseif b then - write_nl(report_yes(a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(report_nop(a)) + write_nl(f_two(a)) else write_nl("") end end - local subreport_yes=formatters["%-15s | %s | %s"] - local subreport_nop=formatters["%-15s | %s |"] + local f_one=formatters["%-15s | %s | %s"] + local f_two=formatters["%-15s | %s |"] subreport=function(a,sub,b,c,...) if c then - write_nl(subreport_yes(a,sub,formatters[b](c,...))) + write_nl(f_one(a,sub,formatters[b](c,...))) elseif b then - write_nl(subreport_yes(a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(subreport_nop(a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end - local status_yes=formatters["%-15s : %s\n"] - local status_nop=formatters["%-15s :\n"] + local f_one=formatters["%-15s : %s\n"] + local f_two=formatters["%-15s :\n"] status=function(a,b,c,...) if c then - write_nl(status_yes(a,formatters[b](c,...))) + write_nl(f_one(a,formatters[b](c,...))) elseif b then - write_nl(status_yes(a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(status_nop(a)) + write_nl(f_two(a)) else write_nl("\n") end @@ -7130,49 +6585,6 @@ else poptarget=ignore setformats=ignore settranslations=ignore - setprocessor=function(f) - local writeline=write_nl - write_nl=function(s) - writeline(f(s)) - end - end - setformatters=function(f) - report_yes=f.report_yes or report_yes - report_nop=f.report_nop or report_nop - subreport_yes=f.subreport_yes or subreport_yes - subreport_nop=f.subreport_nop or subreport_nop - status_yes=f.status_yes or status_yes - status_nop=f.status_nop or status_nop - end - setlogfile=function(name,keepopen) - if name and name~="" then - local localtime=os.localtime - local writeline=write_nl - if keepopen then - local f=io.open(name,"ab") - write_nl=function(s) - writeline(s) - f:write(localtime()," | ",s,"\n") - end - else - write_nl=function(s) - writeline(s) - local f=io.open(name,"ab") - f:write(localtime()," | ",s,"\n") - f:close() - end - end - end - setlogfile=ignore - end - settimedlog=function() - local localtime=os.localtime - local writeline=write_nl - write_nl=function(s) - writeline(localtime().." | "..s) - end - settimedlog=ignore - end end logs.report=report logs.subreport=subreport @@ -7182,10 +6594,6 @@ logs.pushtarget=pushtarget logs.poptarget=poptarget logs.setformats=setformats logs.settranslations=settranslations -logs.setlogfile=setlogfile -logs.settimedlog=settimedlog -logs.setprocessor=setprocessor -logs.setformatters=setformatters logs.direct=direct logs.subdirect=subdirect logs.writer=writer @@ -7336,9 +6744,7 @@ end) local report_pages=logs.reporter("pages") local real,user,sub function logs.start_page_number() - real=texgetcount("realpageno") - user=texgetcount("userpageno") - sub=texgetcount("subpageno") + real,user,sub=texcount.realpageno,texcount.userpageno,texcount.subpageno end local timing=false local starttime=nil @@ -7543,7 +6949,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6295, stripped down to: 4966 +-- original size: 5678, stripped down to: 4448 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7552,19 +6958,16 @@ if not modules then modules={} end modules ['trac-inf']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,tonumber,select=type,tonumber,select +local type,tonumber=type,tonumber local format,lower=string.format,string.lower local concat=table.concat local clock=os.gettimeofday or os.clock -local setmetatableindex=table.setmetatableindex -local serialize=table.serialize -local formatters=string.formatters statistics=statistics or {} local statistics=statistics statistics.enable=true statistics.threshold=0.01 local statusinfo,n,registered,timers={},0,{},{} -setmetatableindex(timers,function(t,k) +table.setmetatableindex(timers,function(t,k) local v={ timing=0,loadtime=0 } t[k]=v return v @@ -7693,16 +7096,6 @@ function statistics.timed(action) stoptiming("run") report("total runtime: %s",elapsedtime("run")) end -function statistics.tracefunction(base,tag,...) - for i=1,select("#",...) do - local name=select(i,...) - local stat={} - local func=base[name] - setmetatableindex(stat,function(t,k) t[k]=0 return 0 end) - base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end - statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end) - end -end commands=commands or {} function commands.resettimer(name) resettiming(name or "whatever") @@ -7865,7 +7258,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-lua"] = package.loaded["util-lua"] or true --- original size: 4982, stripped down to: 3511 +-- original size: 12575, stripped down to: 8700 if not modules then modules={} end modules ['util-lua']={ version=1.001, @@ -7900,92 +7293,251 @@ luautilities.suffixes={ tua="tua", tuc="tuc", } -local function register(name) - if tracestripping then - report_lua("stripped bytecode from %a",name or "unknown") +if jit or status.luatex_version>=74 then + local function register(name) + if tracestripping then + report_lua("stripped bytecode from %a",name or "unknown") + end + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 + end + local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + if code and code~="" then + code=load(code) + if code then + code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code~="" then + register(name) + io.savedata(lucfile,code) + return true,0 + end + else + report_lua("fatal error %a in file %a",1,luafile) + end + else + report_lua("fatal error %a in file %a",2,luafile) + end + return false,0 end - strippedchunks[#strippedchunks+1]=name - luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 -end -local function stupidcompile(luafile,lucfile,strip) - local code=io.loaddata(luafile) - if code and code~="" then - code=load(code) + function luautilities.loadedluacode(fullname,forcestrip,name) + name=name or fullname + local code=environment.loadpreprocessedfile and environment.loadpreprocessedfile(fullname) or loadfile(fullname) if code then - code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) - if code and code~="" then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then register(name) - io.savedata(lucfile,code) - return true,0 + return load(dump(code,true)),0 + else + return code,0 end + elseif luautilities.alwaysstripcode then + register(name) + return load(dump(code,true)),0 else - report_lua("fatal error %a in file %a",1,luafile) + return code,0 end - else - report_lua("fatal error %a in file %a",2,luafile) end - return false,0 -end -function luautilities.loadedluacode(fullname,forcestrip,name) - name=name or fullname - local code,message - if environment.loadpreprocessedfile then - code,message=environment.loadpreprocessedfile(fullname) - else - code,message=loadfile(fullname) + function luautilities.strippedloadstring(code,forcestrip,name) + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code=load(code) + if not code then + report_lua("fatal error %a in file %a",3,name) + end + register(name) + code=dump(code,true) + end + return load(code),0 end - if code then - code() + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=stupidcompile(luafile,lucfile,strip~=false) + if done then + report_lua("dumping %a into %a stripped",luafile,lucfile) + if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + report_lua("removing %a",luafile) + os.remove(luafile) + end + end + return done + end + function luautilities.loadstripped(...) + local l=load(...) + if l then + return load(dump(l,true)) + end + end +else + local function register(name,before,after) + local delta=before-after + if tracestripping then + report_lua("bytecodes stripped from %a, # before %s, # after %s, delta %s",name,before,after,delta) + end + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 + luautilities.nofstrippedbytes=luautilities.nofstrippedbytes+delta + return delta + end + local strip_code_pc + if _MAJORVERSION==5 and _MINORVERSION==1 then + strip_code_pc=function(dump,name) + local before=#dump + local version,format,endian,int,size,ins,num=byte(dump,5,11) + local subint + if endian==1 then + subint=function(dump,i,l) + local val=0 + for n=l,1,-1 do + val=val*256+byte(dump,i+n-1) + end + return val,i+l + end + else + subint=function(dump,i,l) + local val=0 + for n=1,l,1 do + val=val*256+byte(dump,i+n-1) + end + return val,i+l + end + end + local strip_function + strip_function=function(dump) + local count,offset=subint(dump,1,size) + local stripped,dirty=rep("\0",size),offset+count + offset=offset+count+int*2+4 + offset=offset+int+subint(dump,offset,int)*ins + count,offset=subint(dump,offset,int) + for n=1,count do + local t + t,offset=subint(dump,offset,1) + if t==1 then + offset=offset+1 + elseif t==4 then + offset=offset+size+subint(dump,offset,size) + elseif t==3 then + offset=offset+num + end + end + count,offset=subint(dump,offset,int) + stripped=stripped..sub(dump,dirty,offset-1) + for n=1,count do + local proto,off=strip_function(sub(dump,offset,-1)) + stripped,offset=stripped..proto,offset+off-1 + end + offset=offset+subint(dump,offset,int)*int+int + count,offset=subint(dump,offset,int) + for n=1,count do + offset=offset+subint(dump,offset,size)+size+int*2 + end + count,offset=subint(dump,offset,int) + for n=1,count do + offset=offset+subint(dump,offset,size)+size + end + stripped=stripped..rep("\0",int*3) + return stripped,offset + end + dump=sub(dump,1,12)..strip_function(sub(dump,13,-1)) + local after=#dump + local delta=register(name,before,after) + return dump,delta + end else - report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message") + strip_code_pc=function(dump,name) + return dump,0 + end end - if forcestrip and luautilities.stripcode then - if type(forcestrip)=="function" then - forcestrip=forcestrip(fullname) + function luautilities.loadedluacode(fullname,forcestrip,name) + local code=environment.loadpreprocessedfile and environment.preprocessedloadfile(fullname) or loadfile(fullname) + if code then + code() end - if forcestrip or luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) + end + if forcestrip then + local code,n=strip_code_pc(dump(code),name) + return load(code),n + elseif luautilities.alwaysstripcode then + return load(strip_code_pc(dump(code),name)) + else + return code,0 + end + elseif luautilities.alwaysstripcode then + return load(strip_code_pc(dump(code),name)) else return code,0 end - elseif luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 - else - return code,0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) - local code,message=load(code) - if not code then - report_lua("loading of file %a failed:\n\t%s",name,message or "no message") + function luautilities.strippedloadstring(code,forcestrip,name) + local n=0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code=load(code) + if not code then + report_lua("fatal error in file %a",name) + end + code,n=strip_code_pc(dump(code),name) + end + return load(code),n end - if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 - else - return code,0 + local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + local n=0 + if code and code~="" then + code=load(code) + if not code then + report_lua("fatal error in file %a",luafile) + end + code=dump(code) + if strip then + code,n=strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) + end + if code and code~="" then + io.savedata(lucfile,code) + end + end + return n end -end -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) - report_lua("compiling %a into %a",luafile,lucfile) - os.remove(lucfile) - local done=stupidcompile(luafile,lucfile,strip~=false) - if done then - report_lua("dumping %a into %a stripped",luafile,lucfile) - if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + local luac_normal="texluac -o %q %q" + local luac_strip="texluac -s -o %q %q" + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=false + if strip~=false then + strip=true + end + if forcestupidcompile then + fallback=true + elseif strip then + done=os.spawn(format(luac_strip,lucfile,luafile))==0 + else + done=os.spawn(format(luac_normal,lucfile,luafile))==0 + end + if not done and fallback then + local n=stupidcompile(luafile,lucfile,strip) + if n>0 then + report_lua("%a dumped into %a (%i bytes stripped)",luafile,lucfile,n) + else + report_lua("%a dumped into %a (unstripped)",luafile,lucfile) + end + cleanup=false + done=true + end + if done and cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then report_lua("removing %a",luafile) os.remove(luafile) end + return done end - return done -end -function luautilities.loadstripped(...) - local l=load(...) - if l then - return load(dump(l,true)) - end + luautilities.loadstripped=loadstring end @@ -8274,7 +7826,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tpl"] = package.loaded["util-tpl"] or true --- original size: 6251, stripped down to: 3488 +-- original size: 5655, stripped down to: 3242 if not modules then modules={} end modules ['util-tpl']={ version=1.001, @@ -8288,8 +7840,8 @@ local templates=utilities.templates local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end) local report_template=logs.reporter("template") local tostring=tostring -local format,sub,byte=string.format,string.sub,string.byte -local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns +local format,sub=string.format,string.sub +local P,C,Cs,Carg,lpegmatch=lpeg.P,lpeg.C,lpeg.Cs,lpeg.Carg,lpeg.match local replacer local function replacekey(k,t,how,recursive) local v=t[k] @@ -8316,13 +7868,10 @@ local sqlescape=lpeg.replacer { { "\r\n","\\n" }, { "\r","\\n" }, } -local sqlquoted=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) -lpegpatterns.sqlescape=sqlescape -lpegpatterns.sqlquoted=sqlquoted -local luaescape=lpegpatterns.luaescape +local sqlquotedescape=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) local escapers={ lua=function(s) - return lpegmatch(luaescape,s) + return sub(format("%q",s),2,-2) end, sql=function(s) return lpegmatch(sqlescape,s) @@ -8333,9 +7882,11 @@ local quotedescapers={ return format("%q",s) end, sql=function(s) - return lpegmatch(sqlquoted,s) + return lpegmatch(sqlquotedescape,s) end, } +lpeg.patterns.sqlescape=sqlescape +lpeg.patterns.sqlescape=sqlquotedescape local luaescaper=escapers.lua local quotedluaescaper=quotedescapers.lua local function replacekeyunquoted(s,t,how,recurse) @@ -8372,11 +7923,6 @@ local function replace(str,mapping,how,recurse) end end templates.replace=replace -function templates.replacer(str,how,recurse) - return function(mapping) - return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str - end -end function templates.load(filename,mapping,how,recurse) local data=io.loaddata(filename) or "" if mapping and next(mapping) then @@ -8402,7 +7948,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8761, stripped down to: 5085 +-- original size: 8722, stripped down to: 5050 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8438,7 +7984,6 @@ local luaengines=allocate { environment.validengines=validengines environment.basicengines=basicengines if not arg then - environment.used_as_library=true elseif luaengines[file.removesuffix(arg[-1])] then elseif validengines[file.removesuffix(arg[0])] then if arg[1]=="--luaonly" then @@ -8599,7 +8144,7 @@ do -- create closure to overcome 200 locals limit package.loaded["luat-env"] = package.loaded["luat-env"] or true --- original size: 5930, stripped down to: 4235 +-- original size: 5874, stripped down to: 4184 if not modules then modules={} end modules ['luat-env']={ version=1.001, @@ -8613,13 +8158,12 @@ local trace_locating=false trackers.register("resolvers.locating",function(v) tr local report_lua=logs.reporter("resolvers","lua") local luautilities=utilities.lua local luasuffixes=luautilities.suffixes -local texgettoks=tex and tex.gettoks environment=environment or {} local environment=environment local mt={ __index=function(_,k) if k=="version" then - local version=texgettoks and texgettoks("contextversiontoks") + local version=tex.toks and tex.toks.contextversiontoks if version and version~="" then rawset(environment,"version",version) return version @@ -8627,7 +8171,7 @@ local mt={ return "unknown" end elseif k=="kind" then - local kind=texgettoks and texgettoks("contextkindtoks") + local kind=tex.toks and tex.toks.contextkindtoks if kind and kind~="" then rawset(environment,"kind",kind) return kind @@ -8754,7 +8298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 42447, stripped down to: 26589 +-- original size: 42495, stripped down to: 26647 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -8765,7 +8309,6 @@ if not modules then modules={} end modules ['lxml-tab']={ } local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end) local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end -if lpeg.setmaxstack then lpeg.setmaxstack(1000) end xml=xml or {} local xml=xml local concat,remove,insert=table.concat,table.remove,table.insert @@ -9185,6 +8728,7 @@ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace* local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset local simpledoctype=(1-close)^1 local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) +local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end @@ -12269,7 +11813,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-exp"] = package.loaded["data-exp"] or true --- original size: 15303, stripped down to: 9716 +-- original size: 14654, stripped down to: 9517 if not modules then modules={} end modules ['data-exp']={ version=1.001, @@ -12281,7 +11825,7 @@ if not modules then modules={} end modules ['data-exp']={ local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub local concat,sort=table.concat,table.sort local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S +local Ct,Cs,Cc,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.P,lpeg.C,lpeg.S local type,next=type,next local ostype=os.type local collapsepath=file.collapsepath @@ -12289,6 +11833,20 @@ local trace_locating=false trackers.register("resolvers.locating",function(v) tr local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end) local report_expansions=logs.reporter("resolvers","expansions") local resolvers=resolvers +local function f_first(a,b) + local t,n={},0 + for s in gmatch(b,"[^,]+") do + n=n+1;t[n]=a..s + end + return concat(t,",") +end +local function f_second(a,b) + local t,n={},0 + for s in gmatch(a,"[^,]+") do + n=n+1;t[n]=s..b + end + return concat(t,",") +end local function f_both(a,b) local t,n={},0 for sb in gmatch(b,"[^,]+") do @@ -12298,15 +11856,6 @@ local function f_both(a,b) end return concat(t,",") end -local comma=P(",") -local nocomma=(1-comma)^1 -local docomma=comma^1/"," -local before=Cs((nocomma*Carg(1)+docomma)^0) -local after=Cs((Carg(1)*nocomma+docomma)^0) -local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0) -local function f_first (a,b) return lpegmatch(after,b,1,a) end -local function f_second(a,b) return lpegmatch(before,a,1,b) end -local function f_both (a,b) return lpegmatch(both,b,1,a) end local left=P("{") local right=P("}") local var=P((1-S("{}" ))^0) @@ -12894,7 +12443,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-tmp"] = package.loaded["data-tmp"] or true --- original size: 15532, stripped down to: 11648 +-- original size: 14615, stripped down to: 11208 if not modules then modules={} end modules ['data-tmp']={ version=1.100, @@ -13108,22 +12657,6 @@ function caches.getfirstreadablefile(filename,...) end return caches.setfirstwritablefile(filename,...) end -function caches.getfirstreadablefile_TEST_ME_FIRST(filename,...) - local fullname,path=caches.setfirstwritablefile(filename,...) - if is_readable(fullname) then - return fullname,path - end - local rd=getreadablepaths(...) - for i=1,#rd do - local path=rd[i] - local fullname=file.join(path,filename) - if is_readable(fullname) then - usedreadables[i]=true - return fullname,path - end - end - return fullname,path -end function caches.setfirstwritablefile(filename,...) local wr=getwritablepath(...) local fullname=file.join(wr,filename) @@ -13269,7 +12802,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-met"] = package.loaded["data-met"] or true --- original size: 5453, stripped down to: 4007 +-- original size: 5137, stripped down to: 4007 if not modules then modules={} end modules ['data-met']={ version=1.100, @@ -13388,7 +12921,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-res"] = package.loaded["data-res"] or true --- original size: 61782, stripped down to: 42959 +-- original size: 61759, stripped down to: 42959 if not modules then modules={} end modules ['data-res']={ version=1.001, @@ -16563,8 +16096,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 680476 --- stripped bytes : 240933 +-- original bytes : 670212 +-- stripped bytes : 245255 -- end library merge @@ -16732,9 +16265,11 @@ end -- verbosity ------ e_verbose = environment.arguments["verbose"] +local e_verbose = environment.arguments["verbose"] -local e_verbose = false +if e_verbose then + trackers.enable("resolvers.locating") +end -- some common flags (also passed through environment) @@ -17455,22 +16990,12 @@ environment.initializearguments(before) instance.lsrmode = environment.argument("lsr") or false -e_verbose = environment.arguments["verbose"] -- delayed till here (we need the ones before script) - -if e_verbose then - trackers.enable("resolvers.locating") -end - -- maybe the unset has to go to this level local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] local e_argument = environment.argument -if e_argument("timedlog") then - logs.settimedlog() -end - if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then resolvers.load_tree(e_argument('tree'),true) -- force resolve of TEXMFCNF @@ -17553,23 +17078,6 @@ else end --- joke .. reminds me of messing with gigi terminals - -if e_argument("ansi") then - - local formatters = string.formatters - - logs.setformatters { - report_yes = formatters["[1;32m%-15s [0;1m|[0m %s"], - report_nop = formatters["[1;32m%-15s [0;1m|[0m"], - subreport_yes = formatters["[1;32m%-15s [0;1m|[1;31m %s [0;1m|[0m %s"], - subreport_nop = formatters["[1;32m%-15s [0;1m|[1;31m %s [0;1m|[0m"], - status_yes = formatters["[1;32m%-15s [0;1m:[0m %s\n"], - status_nop = formatters["[1;32m%-15s [0;1m:[0m\n"], - } - -end - if e_argument("script") or e_argument("scripts") then -- run a script by loading it (using libs), pass args diff --git a/scripts/context/ruby/base/pdf.rb b/scripts/context/ruby/base/pdf.rb index 6be0d3f98..5aec06fc5 100644 --- a/scripts/context/ruby/base/pdf.rb +++ b/scripts/context/ruby/base/pdf.rb @@ -5,24 +5,16 @@ module PDFview @closecalls = Hash.new @allcalls = Hash.new - # acrobat no longer is a valid default as (1) it keeps crashing with pdfopen due to a dual acrobat/reader install (a side effect - # of the api changing every version, and (2) because there are all these anyoing popups with respect to signed, review, online - # this and that stuff ... hardly useable as fast previewer, and (3) sumatra is faster and nicer and doesn't block (okay, we have to - # get rid of this horrible yellow bg-coloring buts that is doable - - @method = 'sumatra' # 'default' # 'xpdf' + @method = 'default' # 'xpdf' @opencalls['default'] = "pdfopen --file" # "pdfopen --back --file" @opencalls['xpdf'] = "xpdfopen" - @opencalls['sumatra'] = 'start "test" sumatrapdf.exe -reuse-instance -bg-color 0xCCCCCC' @closecalls['default'] = "pdfclose --file" @closecalls['xpdf'] = nil - @closecalls['sumatra'] = nil @allcalls['default'] = "pdfclose --all" @allcalls['xpdf'] = nil - @allcalls['sumatra'] = nil def PDFview.setmethod(method) @method = method diff --git a/scripts/context/ruby/base/switch.rb b/scripts/context/ruby/base/switch.rb index 73f532082..e38752018 100644 --- a/scripts/context/ruby/base/switch.rb +++ b/scripts/context/ruby/base/switch.rb @@ -487,20 +487,20 @@ class CommandLine private - def dirtyvalue(value) # \xFF suddenly doesn't work any longer + def dirtyvalue(value) if value then value.gsub(/([\"\'])(.*?)\1/) do - $2.gsub(/\s+/o, "\0xFF") + $2.gsub(/\s+/o, "\xFF") end else '' end end - def cleanvalue(value) # \xFF suddenly doesn't work any longer + def cleanvalue(value) if value then # value.sub(/^([\"\'])(.*?)\1$/) { $2.gsub(/\xFF/o, ' ') } - value.gsub(/\0xFF/o, ' ') + value.gsub(/\xFF/o, ' ') else '' end @@ -569,7 +569,7 @@ class CommandLine def locateseries(series, value) - series.each_char do |key| # was .each but there is no alias to each_char any longer + series.each do |key| locatesingle(key,cleanvalue(value)) end diff --git a/scripts/context/ruby/base/tex.rb b/scripts/context/ruby/base/tex.rb index 9a520f313..77d61b4db 100644 --- a/scripts/context/ruby/base/tex.rb +++ b/scripts/context/ruby/base/tex.rb @@ -364,7 +364,8 @@ class TEX def mpsformats() @@mpsformats.keys.sort end def defaulttexformats() ['en','nl','mptopdf'] end - def defaultmpsformats() ['metafun'] end # no longer formats + # def defaultmpsformats() ['metafun'] end # no longer formats + def defaultmpsformats() [] end def texmakeextras(format) @@texmakestr[format] || '' end def mpsmakeextras(format) @@mpsmakestr[format] || '' end @@ -629,36 +630,34 @@ class TEX texformatpath = '' end # generate mps formats - # if mpsformats && mpsengine then - # report("using mp engine #{mpsengine}") - # mpsformatpath = if getvariable('local') then '.' else Kpse.formatpath(mpsengine,false) end - # report("using mps format path #{mpsformatpath}") - # Dir.chdir(mpsformatpath) rescue false - # if FileTest.writable?(mpsformatpath) then - # mpsformats.each do |mpsformat| - # report("generating mps format #{mpsformat}") - # progname = validprogname([getvariable('progname'),mpsformat,mpsengine]) - # if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then - # setvariable('error','no format made') - # end - # end - # else - # report("unable to make format due to lack of permissions") - # mpsformatpath = '' - # setvariable('error','file permission problem') - # end - # else - # mpsformatpath = '' - # end + if mpsformats && mpsengine then + report("using mp engine #{mpsengine}") + mpsformatpath = if getvariable('local') then '.' else Kpse.formatpath(mpsengine,false) end + report("using mps format path #{mpsformatpath}") + Dir.chdir(mpsformatpath) rescue false + if FileTest.writable?(mpsformatpath) then + mpsformats.each do |mpsformat| + report("generating mps format #{mpsformat}") + progname = validprogname([getvariable('progname'),mpsformat,mpsengine]) + if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then + setvariable('error','no format made') + end + end + else + report("unable to make format due to lack of permissions") + mpsformatpath = '' + setvariable('error','file permission problem') + end + else + mpsformatpath = '' + end # check for problems report("") report("tex engine path: #{texformatpath}") unless texformatpath.empty? - # report("mps engine path: #{mpsformatpath}") unless mpsformatpath.empty? + report("mps engine path: #{mpsformatpath}") unless mpsformatpath.empty? report("") - # [['fmt','tex'],['mem','mps']].each do |f| - # [[texformatpath,'global'],[mpsformatpath,'global'],[savedpath,'current']].each do |p| - [['fmt','tex']].each do |f| - [[texformatpath,'global'],[savedpath,'current']].each do |p| + [['fmt','tex'],['mem','mps']].each do |f| + [[texformatpath,'global'],[mpsformatpath,'global'],[savedpath,'current']].each do |p| begin Dir.chdir(p[0]) rescue diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 9edbbf4bf..d07dfc9a7 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -144,7 +144,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-package"] = package.loaded["l-package"] or true --- original size: 10594, stripped down to: 7819 +-- original size: 9893, stripped down to: 7253 if not modules then modules={} end modules ['l-package']={ version=1.001, @@ -154,7 +154,7 @@ if not modules then modules={} end modules ['l-package']={ license="see context related readme files" } local type=type -local gsub,format,find=string.gsub,string.format,string.find +local gsub,format=string.gsub,string.format local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match local package=package local searchers=package.searchers or package.loaders @@ -184,7 +184,6 @@ local helpers=package.helpers or { sequence={ "already loaded", "preload table", - "qualified path", "lua extra list", "lib extra list", "path specification", @@ -330,30 +329,12 @@ local function loadedbypath(name,rawname,paths,islib,what) end end helpers.loadedbypath=loadedbypath -local function loadedbyname(name,rawname) - if find(name,"^/") or find(name,"^[a-zA-Z]:/") then - local trace=helpers.trace - if trace then - helpers.report("qualified name, identifying '%s'",what,name) - end - if isreadable(name) then - if trace then - helpers.report("qualified name, '%s' found",what,name) - end - return loadfile(name) - end - end -end -helpers.loadedbyname=loadedbyname methods["already loaded"]=function(name) return package.loaded[name] end methods["preload table"]=function(name) return builtin["preload table"](name) end -methods["qualified path"]=function(name) - return loadedbyname(addsuffix(lualibfile(name),"lua"),name) -end methods["lua extra list"]=function(name) return loadedbypath(addsuffix(lualibfile(name),"lua" ),name,getextraluapaths(),false,"lua") end @@ -434,7 +415,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true --- original size: 29245, stripped down to: 15964 +-- original size: 26252, stripped down to: 14371 if not modules then modules={} end modules ['l-lpeg']={ version=1.001, @@ -444,7 +425,6 @@ if not modules then modules={} end modules ['l-lpeg']={ license="see context related readme files" } lpeg=require("lpeg") -if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end local type,next,tostring=type,next,tostring local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format local floor=math.floor @@ -460,46 +440,28 @@ patterns.anything=anything patterns.endofstring=endofstring patterns.beginofstring=alwaysmatched patterns.alwaysmatched=alwaysmatched -local sign=S('+-') -local zero=P('0') -local digit=R('09') -local octdigit=R("07") -local lowercase=R("az") -local uppercase=R("AZ") -local underscore=P("_") -local hexdigit=digit+lowercase+uppercase +local digit,sign=R('09'),S('+-') local cr,lf,crlf=P("\r"),P("\n"),P("\r\n") local newline=crlf+S("\r\n") local escaped=P("\\")*anything local squote=P("'") local dquote=P('"') local space=P(" ") -local period=P(".") -local comma=P(",") -local utfbom_32_be=P('\000\000\254\255') -local utfbom_32_le=P('\255\254\000\000') -local utfbom_16_be=P('\254\255') -local utfbom_16_le=P('\255\254') -local utfbom_8=P('\239\187\191') +local utfbom_32_be=P('\000\000\254\255') +local utfbom_32_le=P('\255\254\000\000') +local utfbom_16_be=P('\255\254') +local utfbom_16_le=P('\254\255') +local utfbom_8=P('\239\187\191') local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8 local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8") -local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8") local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0) local utf8next=R("\128\191") -patterns.utfbom_32_be=utfbom_32_be -patterns.utfbom_32_le=utfbom_32_le -patterns.utfbom_16_be=utfbom_16_be -patterns.utfbom_16_le=utfbom_16_le -patterns.utfbom_8=utfbom_8 -patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n") -patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000") patterns.utf8one=R("\000\127") patterns.utf8two=R("\194\223")*utf8next patterns.utf8three=R("\224\239")*utf8next*utf8next patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next patterns.utfbom=utfbom patterns.utftype=utftype -patterns.utfstricttype=utfstricttype patterns.utfoffset=utfoffset local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false) @@ -523,8 +485,23 @@ local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0)) patterns.stripper=stripper patterns.collapser=collapser -patterns.lowercase=lowercase -patterns.uppercase=uppercase +patterns.digit=digit +patterns.sign=sign +patterns.cardinal=sign^0*digit^1 +patterns.integer=sign^0*digit^1 +patterns.unsigned=digit^0*P('.')*digit^1 +patterns.float=sign^0*patterns.unsigned +patterns.cunsigned=digit^0*P(',')*digit^1 +patterns.cfloat=sign^0*patterns.cunsigned +patterns.number=patterns.float+patterns.integer +patterns.cnumber=patterns.cfloat+patterns.integer +patterns.oct=P("0")*R("07")^1 +patterns.octal=patterns.oct +patterns.HEX=P("0x")*R("09","AF")^1 +patterns.hex=P("0x")*R("09","af")^1 +patterns.hexadecimal=P("0x")*R("09","AF","af")^1 +patterns.lowercase=R("az") +patterns.uppercase=R("AZ") patterns.letter=patterns.lowercase+patterns.uppercase patterns.space=space patterns.tab=P("\t") @@ -532,12 +509,12 @@ patterns.spaceortab=patterns.space+patterns.tab patterns.newline=newline patterns.emptyline=newline^1 patterns.equal=P("=") -patterns.comma=comma -patterns.commaspacer=comma*spacer^0 -patterns.period=period +patterns.comma=P(",") +patterns.commaspacer=P(",")*spacer^0 +patterns.period=P(".") patterns.colon=P(":") patterns.semicolon=P(";") -patterns.underscore=underscore +patterns.underscore=P("_") patterns.escaped=escaped patterns.squote=squote patterns.dquote=dquote @@ -550,29 +527,10 @@ patterns.unspacer=((patterns.spacer^1)/"")^0 patterns.singlequoted=squote*patterns.nosquote*squote patterns.doublequoted=dquote*patterns.nodquote*dquote patterns.quoted=patterns.doublequoted+patterns.singlequoted -patterns.digit=digit -patterns.octdigit=octdigit -patterns.hexdigit=hexdigit -patterns.sign=sign -patterns.cardinal=digit^1 -patterns.integer=sign^-1*digit^1 -patterns.unsigned=digit^0*period*digit^1 -patterns.float=sign^-1*patterns.unsigned -patterns.cunsigned=digit^0*comma*digit^1 -patterns.cfloat=sign^-1*patterns.cunsigned -patterns.number=patterns.float+patterns.integer -patterns.cnumber=patterns.cfloat+patterns.integer -patterns.oct=zero*octdigit^1 -patterns.octal=patterns.oct -patterns.HEX=zero*P("X")*(digit+uppercase)^1 -patterns.hex=zero*P("x")*(digit+lowercase)^1 -patterns.hexadecimal=zero*S("xX")*hexdigit^1 -patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigit^1+hexdigit^1*period*hexdigit^0+hexdigit^1)*(S("pP")*sign^-1*hexdigit^1)^-1 -patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^1)*S("eE")*sign^-1*digit^1 -patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring +patterns.propername=R("AZ","az","__")*R("09","AZ","az","__")^0*P(-1) patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) -patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0)) +patterns.longtostring=Cs(whitespace^0/""*nonwhitespace^0*((whitespace^0/" "*(patterns.quoted+nonwhitespace)^1)^0)) local function anywhere(pattern) return P { P(pattern)+1*V(1) } end @@ -744,7 +702,7 @@ function lpeg.replacer(one,two,makefunction,isutf) return pattern end end -function lpeg.finder(lst,makefunction) +function lpeg.finder(lst,makefunction) local pattern if type(lst)=="table" then pattern=P(false) @@ -773,8 +731,8 @@ local splitters_f,splitters_s={},{} function lpeg.firstofsplit(separator) local splitter=splitters_f[separator] if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0) + separator=P(separator) + splitter=C((1-separator)^0) splitters_f[separator]=splitter end return splitter @@ -782,31 +740,12 @@ end function lpeg.secondofsplit(separator) local splitter=splitters_s[separator] if not splitter then - local pattern=P(separator) - splitter=(1-pattern)^0*pattern*C(anything^0) - splitters_s[separator]=splitter - end - return splitter -end -local splitters_s,splitters_p={},{} -function lpeg.beforesuffix(separator) - local splitter=splitters_s[separator] - if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0)*pattern*endofstring + separator=P(separator) + splitter=(1-separator)^0*separator*C(anything^0) splitters_s[separator]=splitter end return splitter end -function lpeg.afterprefix(separator) - local splitter=splitters_p[separator] - if not splitter then - local pattern=P(separator) - splitter=pattern*C(anything^0) - splitters_p[separator]=splitter - end - return splitter -end function lpeg.balancer(left,right) left,right=P(left),P(right) return P { left*((1-left-right)+V(1))^0*right } @@ -1038,6 +977,9 @@ end function lpeg.times(pattern,n) return P(nextstep(n,2^16,{ "start",["1"]=pattern })) end +local digit=R("09") +local period=P(".") +local zero=P("0") local trailingzeros=zero^0*-digit local case_1=period*trailingzeros/"" local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"") @@ -1071,7 +1013,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-string"] = package.loaded["l-string"] or true --- original size: 5547, stripped down to: 2708 +-- original size: 5513, stripped down to: 2708 if not modules then modules={} end modules ['l-string']={ version=1.001, @@ -1172,7 +1114,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-table"] = package.loaded["l-table"] or true --- original size: 30618, stripped down to: 19908 +-- original size: 44626, stripped down to: 19688 if not modules then modules={} end modules ['l-table']={ version=1.001, @@ -1440,7 +1382,6 @@ local noquotes,hexify,handle,reduce,compact,inline,functions local reserved=table.tohash { 'and','break','do','else','elseif','end','false','for','function','if', 'in','local','nil','not','or','repeat','return','then','true','until','while', - 'NaN','goto', } local function simple_table(t) if #t>0 then @@ -1460,12 +1401,12 @@ local function simple_table(t) else tt[nt]=tostring(v) end + elseif tv=="boolean" then + nt=nt+1 + tt[nt]=tostring(v) elseif tv=="string" then nt=nt+1 tt[nt]=format("%q",v) - elseif tv=="boolean" then - nt=nt+1 - tt[nt]=v and "true" or "false" else tt=nil break @@ -1498,7 +1439,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s[%q]={",depth,name)) end elseif tn=="boolean" then - handle(format("%s[%s]={",depth,name and "true" or "false")) + handle(format("%s[%s]={",depth,tostring(name))) else handle(format("%s{",depth)) end @@ -1522,21 +1463,21 @@ local function do_serialize(root,name,depth,level,indexed) for i=1,#sk do local k=sk[i] local v=root[k] - local tv,tk=type(v),type(k) + local t,tk=type(v),type(k) if compact and first and tk=="number" and k>=first and k<=last then - if tv=="number" then + if t=="number" then if hexify then handle(format("%s 0x%04X,",depth,v)) else handle(format("%s %s,",depth,v)) end - elseif tv=="string" then + elseif t=="string" then if reduce and tonumber(v) then handle(format("%s %s,",depth,v)) else handle(format("%s %q,",depth,v)) end - elseif tv=="table" then + elseif t=="table" then if not next(v) then handle(format("%s {},",depth)) elseif inline then @@ -1549,11 +1490,11 @@ local function do_serialize(root,name,depth,level,indexed) else do_serialize(v,k,depth,level+1,true) end - elseif tv=="boolean" then - handle(format("%s %s,",depth,v and "true" or "false")) - elseif tv=="function" then + elseif t=="boolean" then + handle(format("%s %s,",depth,tostring(v))) + elseif t=="function" then if functions then - handle(format('%s load(%q),',depth,dump(v))) + handle(format('%s load(%q),',depth,dump(v))) else handle(format('%s "function",',depth)) end @@ -1564,7 +1505,7 @@ local function do_serialize(root,name,depth,level,indexed) if false then handle(format("%s __p__=nil,",depth)) end - elseif tv=="number" then + elseif t=="number" then if tk=="number" then if hexify then handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) @@ -1573,9 +1514,9 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then if hexify then - handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=0x%04X,",depth,tostring(k),v)) else - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%s,",depth,tostring(k),v)) end elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then @@ -1590,7 +1531,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%q]=%s,",depth,k,v)) end end - elseif tv=="string" then + elseif t=="string" then if reduce and tonumber(v) then if tk=="number" then if hexify then @@ -1599,7 +1540,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%s,",depth,k,v)) end elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%s,",depth,tostring(k),v)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%s,",depth,k,v)) else @@ -1613,14 +1554,14 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%q,",depth,k,v)) end elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%q,",depth,tostring(k),v)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,v)) else handle(format("%s [%q]=%q,",depth,k,v)) end end - elseif tv=="table" then + elseif t=="table" then if not next(v) then if tk=="number" then if hexify then @@ -1629,7 +1570,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]={},",depth,k)) end elseif tk=="boolean" then - handle(format("%s [%s]={},",depth,k and "true" or "false")) + handle(format("%s [%s]={},",depth,tostring(k))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={},",depth,k)) else @@ -1645,7 +1586,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) end elseif tk=="boolean" then - handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) + handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", "))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={ %s },",depth,k,concat(st,", "))) else @@ -1657,21 +1598,21 @@ local function do_serialize(root,name,depth,level,indexed) else do_serialize(v,k,depth,level+1) end - elseif tv=="boolean" then + elseif t=="boolean" then if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [0x%04X]=%s,",depth,k,tostring(v))) else - handle(format("%s [%s]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [%s]=%s,",depth,k,tostring(v))) end elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) + handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%s,",depth,k,v and "true" or "false")) + handle(format("%s %s=%s,",depth,k,tostring(v))) else - handle(format("%s [%q]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [%q]=%s,",depth,k,tostring(v))) end - elseif tv=="function" then + elseif t=="function" then if functions then local f=getinfo(v).what=="C" and dump(dummy) or dump(v) if tk=="number" then @@ -1681,7 +1622,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=load(%q),",depth,k,f)) end elseif tk=="boolean" then - handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + handle(format("%s [%s]=load(%q),",depth,tostring(k),f)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=load(%q),",depth,k,f)) else @@ -1696,7 +1637,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%q,",depth,k,tostring(v))) end elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) + handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,tostring(v))) else @@ -2040,7 +1981,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-io"] = package.loaded["l-io"] or true --- original size: 8817, stripped down to: 6340 +-- original size: 8799, stripped down to: 6325 if not modules then modules={} end modules ['l-io']={ version=1.001, @@ -2071,7 +2012,6 @@ local function readall(f) return f:read('*all') else local done=f:seek("set",0) - local step if size<1024*1024 then step=1024*1024 elseif size>16*1024*1024 then @@ -2575,7 +2515,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-os"] = package.loaded["l-os"] or true --- original size: 15800, stripped down to: 9551 +-- original size: 14017, stripped down to: 8504 if not modules then modules={} end modules ['l-os']={ version=1.001, @@ -2656,13 +2596,7 @@ function os.exec (...) ioflush() return exec (...) end function io.popen (...) ioflush() return iopopen(...) end function os.resultof(command) local handle=io.popen(command,"r") - if handle then - local result=handle:read("*all") or "" - handle:close() - return result - else - return "" - end + return handle and handle:read("*all") or "" end if not io.fileseparator then if find(os.getenv("PATH"),";") then @@ -2696,11 +2630,10 @@ if not os.times then } end end -local gettimeofday=os.gettimeofday or os.clock -os.gettimeofday=gettimeofday -local startuptime=gettimeofday() +os.gettimeofday=os.gettimeofday or os.clock +local startuptime=os.gettimeofday() function os.runtime() - return gettimeofday()-startuptime + return os.gettimeofday()-startuptime end os.resolvers=os.resolvers or {} local resolvers=os.resolvers @@ -2833,38 +2766,26 @@ function os.timezone(delta) end local timeformat=format("%%s%s",os.timezone(true)) local dateformat="!%Y-%m-%d %H:%M:%S" -local lasttime=nil -local lastdate=nil function os.fulltime(t,default) - t=t and tonumber(t) or 0 + t=tonumber(t) or 0 if t>0 then elseif default then return default else - t=time() - end - if t~=lasttime then - lasttime=t - lastdate=format(timeformat,date(dateformat)) + t=nil end - return lastdate + return format(timeformat,date(dateformat,t)) end local dateformat="%Y-%m-%d %H:%M:%S" -local lasttime=nil -local lastdate=nil function os.localtime(t,default) - t=t and tonumber(t) or 0 + t=tonumber(t) or 0 if t>0 then elseif default then return default else - t=time() - end - if t~=lasttime then - lasttime=t - lastdate=date(dateformat,t) + t=nil end - return lastdate + return date(dateformat,t) end function os.converttime(t,default) local t=tonumber(t) @@ -2914,38 +2835,6 @@ if not os.sleep then socket.sleep(n) end end -local function isleapyear(year) - return (year%400==0) or ((year%100~=0) and (year%4==0)) -end -os.isleapyear=isleapyear -local days={ 31,28,31,30,31,30,31,31,30,31,30,31 } -local function nofdays(year,month) - if not month then - return isleapyear(year) and 365 or 364 - else - return month==2 and isleapyear(year) and 29 or days[month] - end -end -os.nofdays=nofdays -function os.weekday(day,month,year) - return date("%w",time { year=year,month=month,day=day })+1 -end -function os.validdate(year,month,day) - if month<1 then - month=1 - elseif month>12 then - month=12 - end - if day<1 then - day=1 - else - local max=nofdays(year,month) - if day>max then - day=max - end - end - return year,month,day -end end -- of closure @@ -2954,7 +2843,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-file"] = package.loaded["l-file"] or true --- original size: 18308, stripped down to: 9948 +-- original size: 17777, stripped down to: 9653 if not modules then modules={} end modules ['l-file']={ version=1.001, @@ -3197,24 +3086,17 @@ end function file.joinpath(tab,separator) return tab and concat(tab,separator or io.pathseparator) end -local someslash=S("\\/") local stripper=Cs(P(fwslash)^0/""*reslasher) -local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon +local isnetwork=fwslash*fwslash*(1-fwslash)+(1-fwslash-colon)^1*colon local isroot=fwslash^1*-1 local hasroot=fwslash^1 -local reslasher=lpeg.replacer(S("\\/"),"/") local deslasher=lpeg.replacer(S("\\/")^1,"/") function file.join(...) local lst={... } local one=lst[1] if lpegmatch(isnetwork,one) then - local one=lpegmatch(reslasher,one) local two=lpegmatch(deslasher,concat(lst,"/",2)) - if lpegmatch(hasroot,two) then - return one..two - else - return one.."/"..two - end + return one.."/"..two elseif lpegmatch(isroot,one) then local two=lpegmatch(deslasher,concat(lst,"/",2)) if lpegmatch(hasroot,two) then @@ -3231,9 +3113,7 @@ end local drivespec=R("az","AZ")^1*colon local anchors=fwslash+drivespec local untouched=periods+(1-period)^1*P(-1) -local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0) -local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//") -local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) +local splitstarter=(Cs(drivespec*(bwslash/"/"+fwslash)^0)+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) local absolute=fwslash function file.collapsepath(str,anchor) if not str then @@ -3481,7 +3361,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-url"] = package.loaded["l-url"] or true --- original size: 11993, stripped down to: 5584 +-- original size: 11806, stripped down to: 5417 if not modules then modules={} end modules ['l-url']={ version=1.001, @@ -3532,14 +3412,9 @@ setmetatable(escapes,{ __index=function(t,k) end }) local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_")^1+P(1)/escapes)^0) local unescaper=Cs((escapedchar+1)^0) -local getcleaner=Cs((P("+++")/"%%2B"+P("+")/"%%20"+P(1))^1) lpegpatterns.urlunescaped=escapedchar lpegpatterns.urlescaper=escaper lpegpatterns.urlunescaper=unescaper -lpegpatterns.urlgetcleaner=getcleaner -function url.unescapeget(str) - return lpegmatch(getcleaner,str) -end local function split(str) return (type(str)=="string" and lpegmatch(parser,str)) or str end @@ -3692,7 +3567,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 14229, stripped down to: 8740 +-- original size: 13738, stripped down to: 8560 if not modules then modules={} end modules ['l-dir']={ version=1.001, @@ -3715,7 +3590,6 @@ local isdir=lfs.isdir local isfile=lfs.isfile local currentdir=lfs.currentdir local chdir=lfs.chdir -local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") if not isdir then function isdir(name) local a=attributes(name) @@ -3787,21 +3661,11 @@ local function collectpattern(path,patt,recurse,result) return result end dir.collectpattern=collectpattern -local separator -if onwindows then - local slash=S("/\\")/"/" - pattern=Ct { - [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3), - [2]=Cs(((1-S("*?/\\"))^0*slash)^0), - [3]=Cs(P(1)^0) - } -else - pattern=Ct { - [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3), - [2]=C(((1-S("*?/"))^0*P("/"))^0), - [3]=C(P(1)^0) - } -end +local pattern=Ct { + [1]=(C(P(".")+P("/")^1)+C(R("az","AZ")*P(":")*P("/")^0)+Cc("./"))*V(2)*V(3), + [2]=C(((1-S("*?/"))^0*P("/"))^0), + [3]=C(P(1)^0) +} local filter=Cs (( P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1) )^0 ) @@ -3885,6 +3749,7 @@ function dir.ls(pattern) return concat(glob(pattern),"\n") end local make_indeed=true +local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") if onwindows then function dir.mkdirs(...) local str,pth="","" @@ -3897,8 +3762,9 @@ if onwindows then str=str.."/"..s end end + local first,middle,last local drive=false - local first,middle,last=match(str,"^(//)(//*)(.*)$") + first,middle,last=match(str,"^(//)(//*)(.*)$") if first then else first,last=match(str,"^(//)/*(.-)$") @@ -4059,7 +3925,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-boolean"] = package.loaded["l-boolean"] or true --- original size: 1809, stripped down to: 1527 +-- original size: 1781, stripped down to: 1503 if not modules then modules={} end modules ['l-boolean']={ version=1.001, @@ -4115,9 +3981,9 @@ function string.booleanstring(str) end function string.is_boolean(str,default) if type(str)=="string" then - if str=="true" or str=="yes" or str=="on" or str=="t" or str=="1" then + if str=="true" or str=="yes" or str=="on" or str=="t" then return true - elseif str=="false" or str=="no" or str=="off" or str=="f" or str=="0" then + elseif str=="false" or str=="no" or str=="off" or str=="f" then return false end end @@ -4131,7 +3997,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-unicode"] = package.loaded["l-unicode"] or true --- original size: 33066, stripped down to: 14607 +-- original size: 26810, stripped down to: 11943 if not modules then modules={} end modules ['l-unicode']={ version=1.001, @@ -4144,7 +4010,7 @@ utf=utf or (unicode and unicode.utf8) or {} utf.characters=utf.characters or string.utfcharacters utf.values=utf.values or string.utfvalues local type=type -local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch +local char,byte,format,sub=string.char,string.byte,string.format,string.sub local concat=table.concat local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp local lpegmatch,patterns=lpeg.match,lpeg.patterns @@ -4154,7 +4020,6 @@ local replacer=lpeg.replacer local utfvalues=utf.values local utfgmatch=utf.gmatch local p_utftype=patterns.utftype -local p_utfstricttype=patterns.utfstricttype local p_utfoffset=patterns.utfoffset local p_utf8char=patterns.utf8char local p_utf8byte=patterns.utf8byte @@ -4411,181 +4276,112 @@ function utf.magic(f) end return lpegmatch(p_utftype,str) end -local utf16_to_utf8_be,utf16_to_utf8_le -local utf32_to_utf8_be,utf32_to_utf8_le -local utf_16_be_linesplitter=patterns.utfbom_16_be^-1*lpeg.tsplitat(patterns.utf_16_be_nl) -local utf_16_le_linesplitter=patterns.utfbom_16_le^-1*lpeg.tsplitat(patterns.utf_16_le_nl) -if bytepairs then - utf16_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in bytepairs(t[i]) do - if right then - local now=256*left+right - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end - end - end - t[i]=concat(result,"",1,r) - end - return t +local function utf16_to_utf8_be(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) end - utf16_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in bytepairs(t[i]) do - if right then - local now=256*right+left - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end - end - end - t[i]=concat(result,"",1,r) - end - return t - end - utf32_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utflinesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,-1 - for a,b in bytepairs(t[i]) do - if a and b then - if more<0 then - more=256*256*256*a+256*256*b - else - r=r+1 - result[t]=utfchar(more+256*a+b) - more=-1 - end + local result={} + for i=1,#t do + local r,more=0,0 + for left,right in bytepairs(t[i]) do + if right then + local now=256*left+right + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now else - break + r=r+1 + result[r]=utfchar(now) end end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf32_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utflinesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,-1 - for a,b in bytepairs(t[i]) do - if a and b then - if more<0 then - more=256*b+a - else - r=r+1 - result[t]=utfchar(more+256*256*256*b+256*256*a) - more=-1 - end + return t +end +local function utf16_to_utf8_le(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,0 + for left,right in bytepairs(t[i]) do + if right then + local now=256*right+left + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now else - break + r=r+1 + result[r]=utfchar(now) end end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end -else - utf16_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in gmatch(t[i],"(.)(.)") do - if left=="\000" then + return t +end +local function utf32_to_utf8_be(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,-1 + for a,b in bytepairs(t[i]) do + if a and b then + if more<0 then + more=256*256*256*a+256*256*b + else r=r+1 - result[r]=utfchar(byte(right)) - elseif right then - local now=256*byte(left)+byte(right) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end + result[t]=utfchar(more+256*a+b) + more=-1 end + else + break end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf16_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in gmatch(t[i],"(.)(.)") do - if right=="\000" then + return t +end +local function utf32_to_utf8_le(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,-1 + for a,b in bytepairs(t[i]) do + if a and b then + if more<0 then + more=256*b+a + else r=r+1 - result[r]=utfchar(byte(left)) - elseif right then - local now=256*byte(right)+byte(left) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end + result[t]=utfchar(more+256*256*256*b+256*256*a) + more=-1 end + else + break end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf32_to_utf8_le=function() return {} end - utf32_to_utf8_be=function() return {} end + return t end -utf.utf16_to_utf8_le=utf16_to_utf8_le -utf.utf16_to_utf8_be=utf16_to_utf8_be -utf.utf32_to_utf8_le=utf32_to_utf8_le utf.utf32_to_utf8_be=utf32_to_utf8_be +utf.utf32_to_utf8_le=utf32_to_utf8_le +utf.utf16_to_utf8_be=utf16_to_utf8_be +utf.utf16_to_utf8_le=utf16_to_utf8_le function utf.utf8_to_utf8(t) return type(t)=="string" and lpegmatch(utflinesplitter,t) or t end @@ -4617,17 +4413,11 @@ local function big(c) end local _,l_remap=utf.remapper(little) local _,b_remap=utf.remapper(big) -function utf.utf8_to_utf16_be(str) - return char(254,255)..lpegmatch(b_remap,str) -end -function utf.utf8_to_utf16_le(str) - return char(255,254)..lpegmatch(l_remap,str) -end function utf.utf8_to_utf16(str,littleendian) if littleendian then - return utf.utf8_to_utf16_le(str) + return char(255,254)..lpegmatch(l_remap,str) else - return utf.utf8_to_utf16_be(str) + return char(254,255)..lpegmatch(b_remap,str) end end local pattern=Cs ( @@ -4642,21 +4432,6 @@ end function utf.xstring(s) return format("0x%05X",type(s)=="number" and s or utfbyte(s)) end -function utf.toeight(str) - if not str then - return nil - end - local utftype=lpegmatch(p_utfstricttype,str) - if utftype=="utf-8" then - return sub(str,4) - elseif utftype=="utf-16-le" then - return utf16_to_utf8_le(str) - elseif utftype=="utf-16-be" then - return utf16_to_utf8_ne(str) - else - return str - end -end local p_nany=p_utf8char/"" if utfgmatch then function utf.count(str,what) @@ -4759,7 +4534,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-str"] = package.loaded["util-str"] or true --- original size: 25122, stripped down to: 13877 +-- original size: 22834, stripped down to: 12570 if not modules then modules={} end modules ['util-str']={ version=1.001, @@ -4921,7 +4696,6 @@ local tracedchar = string.tracedchar local autosingle = string.autosingle local autodouble = string.autodouble local sequenced = table.sequenced -local formattednumber = number.formatted ]] local template=[[ %s @@ -4936,7 +4710,7 @@ setmetatable(arguments,{ __index=function(t,k) end }) local prefix_any=C((S("+- .")+R("09"))^0) -local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0) +local prefix_tab=C((1-R("az","AZ","09","%%"))^0) local format_s=function(f) n=n+1 if f and f~="" then @@ -4966,7 +4740,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("a%s",n) end end local format_d=format_i @@ -5118,39 +4892,6 @@ end local format_W=function(f) return format("nspaces[%s]",tonumber(f) or 0) end -local digit=patterns.digit -local period=patterns.period -local three=digit*digit*digit -local splitter=Cs ( - (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2) -) -patterns.formattednumber=splitter -function number.formatted(n,sep1,sep2) - local s=type(s)=="string" and n or format("%0.2f",n) - if sep1==true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1=="." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1=="," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") - else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") - end -end -local format_m=function(f) - n=n+1 - if not f or f=="" then - f="," - end - return format([[formattednumber(a%s,%q,".")]],n,f) -end -local format_M=function(f) - n=n+1 - if not f or f=="" then - f="." - end - return format([[formattednumber(a%s,%q,",")]],n,f) -end local format_rest=function(s) return format("%q",s) end @@ -5188,8 +4929,7 @@ local builder=Cs { "start", +V("w") +V("W") +V("a") -+V("A") -+V("m")+V("M") ++V("A") +V("*") )+V("*") )*(P(-1)+Carg(1)) @@ -5220,16 +4960,14 @@ local builder=Cs { "start", ["b"]=(prefix_any*P("b"))/format_b, ["t"]=(prefix_tab*P("t"))/format_t, ["T"]=(prefix_tab*P("T"))/format_T, - ["l"]=(prefix_any*P("l"))/format_l, - ["L"]=(prefix_any*P("L"))/format_L, + ["l"]=(prefix_tab*P("l"))/format_l, + ["L"]=(prefix_tab*P("L"))/format_L, ["I"]=(prefix_any*P("I"))/format_I, ["w"]=(prefix_any*P("w"))/format_w, ["W"]=(prefix_any*P("W"))/format_W, - ["m"]=(prefix_tab*P("m"))/format_m, - ["M"]=(prefix_tab*P("M"))/format_M, ["a"]=(prefix_any*P("a"))/format_a, ["A"]=(prefix_any*P("A"))/format_A, - ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, + ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%%%")^1)/format_rest, ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local direct=Cs ( @@ -5275,13 +5013,10 @@ local function add(t,name,template,preamble) end end strings.formatters.add=add -patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) -patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) -patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) -patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"')) +lpeg.patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) +lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]]) add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]]) -add(formatters,"lua",[[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]]) end -- of closure @@ -5290,7 +5025,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23952, stripped down to: 16092 +-- original size: 14510, stripped down to: 8531 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5302,14 +5037,13 @@ if not modules then modules={} end modules ['util-tab']={ utilities=utilities or {} utilities.tables=utilities.tables or {} local tables=utilities.tables -local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub +local format,gmatch,gsub=string.format,string.gmatch,string.gsub local concat,insert,remove=table.concat,table.insert,table.remove local setmetatable,getmetatable,tonumber,tostring=setmetatable,getmetatable,tonumber,tostring local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc -local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs +local serialize,sortedkeys,sortedpairs=table.serialize,table.sortedkeys,table.sortedpairs local formatters=string.formatters -local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") function tables.definetable(target,nofirst,nolast) local composed,shortcut,t=nil,nil,{} @@ -5513,78 +5247,47 @@ function tables.encapsulate(core,capsule,protect) } ) end end -local f_hashed_string=formatters["[%q]=%q,"] -local f_hashed_number=formatters["[%q]=%s,"] -local f_hashed_boolean=formatters["[%q]=%l,"] -local f_hashed_table=formatters["[%q]="] -local f_indexed_string=formatters["[%s]=%q,"] -local f_indexed_number=formatters["[%s]=%s,"] -local f_indexed_boolean=formatters["[%s]=%l,"] -local f_indexed_table=formatters["[%s]="] -local f_ordered_string=formatters["%q,"] -local f_ordered_number=formatters["%s,"] -local f_ordered_boolean=formatters["%l,"] -function table.fastserialize(t,prefix) - local r={ prefix or "return" } - local m=1 - local function fastserialize(t,outer) - local n=#t - m=m+1 - r[m]="{" - if n>0 then - for i=0,n do - local v=t[i] - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_ordered_string(v) - elseif tv=="number" then - m=m+1 r[m]=f_ordered_number(v) - elseif tv=="table" then - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_ordered_boolean(v) - end +local function fastserialize(t,r,outer) + r[#r+1]="{" + local n=#t + if n>0 then + for i=1,n do + local v=t[i] + local tv=type(v) + if tv=="string" then + r[#r+1]=formatters["%q,"](v) + elseif tv=="number" then + r[#r+1]=formatters["%s,"](v) + elseif tv=="table" then + fastserialize(v,r) + elseif tv=="boolean" then + r[#r+1]=formatters["%S,"](v) end end + else for k,v in next,t do - local tk=type(k) - if tk=="number" then - if k>n or k<0 then - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_indexed_string(k,v) - elseif tv=="number" then - m=m+1 r[m]=f_indexed_number(k,v) - elseif tv=="table" then - m=m+1 r[m]=f_indexed_table(k) - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_indexed_boolean(k,v) - end - end - else - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_hashed_string(k,v) - elseif tv=="number" then - m=m+1 r[m]=f_hashed_number(k,v) - elseif tv=="table" then - m=m+1 r[m]=f_hashed_table(k) - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_hashed_boolean(k,v) - end + local tv=type(v) + if tv=="string" then + r[#r+1]=formatters["[%q]=%q,"](k,v) + elseif tv=="number" then + r[#r+1]=formatters["[%q]=%s,"](k,v) + elseif tv=="table" then + r[#r+1]=formatters["[%q]="](k) + fastserialize(v,r) + elseif tv=="boolean" then + r[#r+1]=formatters["[%q]=%S,"](k,v) end end - m=m+1 - if outer then - r[m]="}" - else - r[m]="}," - end - return r end - return concat(fastserialize(t,true)) + if outer then + r[#r+1]="}" + else + r[#r+1]="}," + end + return r +end +function table.fastserialize(t,prefix) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) if not str or str=="" then @@ -5604,7 +5307,6 @@ function table.load(filename,loader) if filename then local t=(loader or io.loaddata)(filename) if t and t~="" then - local t=utftoeight(t) t=load(t) if type(t)=="function" then t=t() @@ -5616,12 +5318,9 @@ function table.load(filename,loader) end end function table.save(filename,t,n,...) - io.savedata(filename,table.serialize(t,n==nil and true or n,...)) + io.savedata(filename,serialize(t,n==nil and true or n,...)) end -local f_key_value=formatters["%s=%q"] -local f_add_table=formatters[" {%t},\n"] -local f_return_table=formatters["return {\n%t}"] -local function slowdrop(t) +local function slowdrop(t) local r={} local l={} for i=1,#t do @@ -5629,25 +5328,23 @@ local function slowdrop(t) local j=0 for k,v in next,ti do j=j+1 - l[j]=f_key_value(k,v) + l[j]=formatters["%s=%q"](k,v) end - r[i]=f_add_table(l) + r[i]=formatters[" {%t},\n"](l) end - return f_return_table(r) + return formatters["return {\n%st}"](r) end local function fastdrop(t) local r={ "return {\n" } - local m=1 for i=1,#t do local ti=t[i] - m=m+1 r[m]=" {" + r[#r+1]=" {" for k,v in next,ti do - m=m+1 r[m]=f_key_value(k,v) + r[#r+1]=formatters["%s=%q"](k,v) end - m=m+1 r[m]="},\n" + r[#r+1]="},\n" end - m=m+1 - r[m]="}" + r[#r+1]="}" return concat(r) end function table.drop(t,slow) @@ -5682,216 +5379,6 @@ function table.twowaymapper(t) setmetatable(t,selfmapper) return t end -local f_start_key_idx=formatters["%w{"] -local f_start_key_num=formatters["%w[%s]={"] -local f_start_key_str=formatters["%w[%q]={"] -local f_start_key_boo=formatters["%w[%l]={"] -local f_start_key_nop=formatters["%w{"] -local f_stop=formatters["%w},"] -local f_key_num_value_num=formatters["%w[%s]=%s,"] -local f_key_str_value_num=formatters["%w[%q]=%s,"] -local f_key_boo_value_num=formatters["%w[%l]=%s,"] -local f_key_num_value_str=formatters["%w[%s]=%q,"] -local f_key_str_value_str=formatters["%w[%q]=%q,"] -local f_key_boo_value_str=formatters["%w[%l]=%q,"] -local f_key_num_value_boo=formatters["%w[%s]=%l,"] -local f_key_str_value_boo=formatters["%w[%q]=%l,"] -local f_key_boo_value_boo=formatters["%w[%l]=%l,"] -local f_key_num_value_not=formatters["%w[%s]={},"] -local f_key_str_value_not=formatters["%w[%q]={},"] -local f_key_boo_value_not=formatters["%w[%l]={},"] -local f_key_num_value_seq=formatters["%w[%s]={ %, t },"] -local f_key_str_value_seq=formatters["%w[%q]={ %, t },"] -local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"] -local f_val_num=formatters["%w%s,"] -local f_val_str=formatters["%w%q,"] -local f_val_boo=formatters["%w%l,"] -local f_val_not=formatters["%w{},"] -local f_val_seq=formatters["%w{ %, t },"] -local f_table_return=formatters["return {"] -local f_table_name=formatters["%s={"] -local f_table_direct=formatters["{"] -local f_table_entry=formatters["[%q]={"] -local f_table_finish=formatters["}"] -local spaces=utilities.strings.newrepeater(" ") -local serialize=table.serialize -function table.serialize(root,name,specification) - if type(specification)=="table" then - return serialize(root,name,specification) - end - local t - local n=1 - local function simple_table(t) - if #t>0 then - local n=0 - for _,v in next,t do - n=n+1 - if type(v)=="table" then - return nil - end - end - if n==#t then - local tt={} - local nt=0 - for i=1,#t do - local v=t[i] - local tv=type(v) - nt=nt+1 - if tv=="number" then - tt[nt]=v - elseif tv=="string" then - tt[nt]=format("%q",v) - elseif tv=="boolean" then - tt[nt]=v and "true" or "false" - else - return nil - end - end - return tt - end - end - return nil - end - local function do_serialize(root,name,depth,level,indexed) - if level>0 then - n=n+1 - if indexed then - t[n]=f_start_key_idx(depth) - else - local tn=type(name) - if tn=="number" then - t[n]=f_start_key_num(depth,name) - elseif tn=="string" then - t[n]=f_start_key_str(depth,name) - elseif tn=="boolean" then - t[n]=f_start_key_boo(depth,name) - else - t[n]=f_start_key_nop(depth) - end - end - depth=depth+1 - end - if root and next(root) then - local first=nil - local last=0 - last=#root - for k=1,last do - if root[k]==nil then - last=k-1 - break - end - end - if last>0 then - first=1 - end - local sk=sortedkeys(root) - for i=1,#sk do - local k=sk[i] - local v=root[k] - local tv=type(v) - local tk=type(k) - if first and tk=="number" and k>=first and k<=last then - if tv=="number" then - n=n+1 t[n]=f_val_num(depth,v) - elseif tv=="string" then - n=n+1 t[n]=f_val_str(depth,v) - elseif tv=="table" then - if not next(v) then - n=n+1 t[n]=f_val_not(depth) - else - local st=simple_table(v) - if st then - n=n+1 t[n]=f_val_seq(depth,st) - else - do_serialize(v,k,depth,level+1,true) - end - end - elseif tv=="boolean" then - n=n+1 t[n]=f_val_boo(depth,v) - end - elseif tv=="number" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_num(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_num(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_num(depth,k,v) - end - elseif tv=="string" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_str(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_str(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_str(depth,k,v) - end - elseif tv=="table" then - if not next(v) then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_not(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_not(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_not(depth,k,v) - end - else - local st=simple_table(v) - if not st then - do_serialize(v,k,depth,level+1) - elseif tk=="number" then - n=n+1 t[n]=f_key_num_value_seq(depth,k,st) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_seq(depth,k,st) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_seq(depth,k,st) - end - end - elseif tv=="boolean" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_boo(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_boo(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_boo(depth,k,v) - end - end - end - end - if level>0 then - n=n+1 t[n]=f_stop(depth-1) - end - end - local tname=type(name) - if tname=="string" then - if name=="return" then - t={ f_table_return() } - else - t={ f_table_name(name) } - end - elseif tname=="number" then - t={ f_table_entry(name) } - elseif tname=="boolean" then - if name then - t={ f_table_return() } - else - t={ f_table_direct() } - end - else - t={ f_table_name("t") } - end - if root then - if getmetatable(root) then - local dummy=root._w_h_a_t_e_v_e_r_ - root._w_h_a_t_e_v_e_r_=nil - end - if next(root) then - do_serialize(root,name,1,0) - end - end - n=n+1 - t[n]=f_table_finish() - return concat(t,"\n") -end end -- of closure @@ -5900,7 +5387,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-sto"] = package.loaded["util-sto"] or true --- original size: 4172, stripped down to: 2953 +-- original size: 4432, stripped down to: 3123 if not modules then modules={} end modules ['util-sto']={ version=1.001, @@ -5970,47 +5457,56 @@ end local function f_empty () return "" end local function f_self (t,k) t[k]=k return k end local function f_table (t,k) local v={} t[k]=v return v end -local function f_number(t,k) t[k]=0 return 0 end local function f_ignore() end -local f_index={ - ["empty"]=f_empty, - ["self"]=f_self, - ["table"]=f_table, - ["number"]=f_number, -} -local t_index={ - ["empty"]={ __index=f_empty }, - ["self"]={ __index=f_self }, - ["table"]={ __index=f_table }, - ["number"]={ __index=f_number }, -} +local t_empty={ __index=f_empty } +local t_self={ __index=f_self } +local t_table={ __index=f_table } +local t_ignore={ __newindex=f_ignore } function table.setmetatableindex(t,f) if type(t)~="table" then f,t=t,{} end local m=getmetatable(t) if m then - m.__index=f_index[f] or f + if f=="empty" then + m.__index=f_empty + elseif f=="key" then + m.__index=f_self + elseif f=="table" then + m.__index=f_table + else + m.__index=f + end else - setmetatable(t,t_index[f] or { __index=f }) + if f=="empty" then + setmetatable(t,t_empty) + elseif f=="key" then + setmetatable(t,t_self) + elseif f=="table" then + setmetatable(t,t_table) + else + setmetatable(t,{ __index=f }) + end end return t end -local f_index={ - ["ignore"]=f_ignore, -} -local t_index={ - ["ignore"]={ __newindex=f_ignore }, -} function table.setmetatablenewindex(t,f) if type(t)~="table" then f,t=t,{} end local m=getmetatable(t) if m then - m.__newindex=f_index[f] or f + if f=="ignore" then + m.__newindex=f_ignore + else + m.__newindex=f + end else - setmetatable(t,t_index[f] or { __newindex=f }) + if f=="ignore" then + setmetatable(t,t_ignore) + else + setmetatable(t,{ __newindex=f }) + end end return t end @@ -6047,7 +5543,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 18558, stripped down to: 13323 +-- original size: 17827, stripped down to: 12722 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6059,9 +5555,8 @@ if not modules then modules={} end modules ['util-prs']={ local lpeg,table,string=lpeg,table,string local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local concat,gmatch,find=table.concat,string.gmatch,string.find +local concat,format,gmatch,find=table.concat,string.format,string.gmatch,string.find local tostring,type,next,rawset=tostring,type,next,rawset -local mod,div=math.mod,math.div utilities=utilities or {} local parsers=utilities.parsers or {} utilities.parsers=parsers @@ -6265,12 +5760,6 @@ function parsers.simple_hash_to_string(h,separator) end return concat(t,separator or ",") end -local str=C((1-whitespace-equal)^1) -local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset) -local splitter=setting^1 -function utilities.parsers.options_to_hash(str,target) - return str and lpegmatch(splitter,str,1,target or {}) or {} -end local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1) local pattern_a=spaces*Ct(value*(separator*value)^0) local function repeater(n,str) @@ -6375,7 +5864,7 @@ function parsers.csvsplitter(specification) end whatever=quotedata+whatever end - local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 ) + local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r"))^0 ) return function(data) return lpegmatch(parser,data) end @@ -6483,7 +5972,7 @@ end local function fetch(t,name) return t[name] or {} end -local function process(result,more) +function process(result,more) for k,v in next,more do result[k]=v end @@ -6495,18 +5984,6 @@ local merge=Cf(parser,process) function utilities.parsers.mergehashes(hash,list) return lpegmatch(merge,list,1,hash) end -function utilities.parsers.runtime(time) - if not time then - time=os.runtime() - end - local days=div(time,24*60*60) - time=mod(time,24*60*60) - local hours=div(time,60*60) - time=mod(time,60*60) - local minutes=div(time,60) - local seconds=mod(time,60) - return days,hours,minutes,seconds -end end -- of closure @@ -6908,7 +6385,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-log"] = package.loaded["trac-log"] or true --- original size: 25391, stripped down to: 16561 +-- original size: 21914, stripped down to: 14287 if not modules then modules={} end modules ['trac-log']={ version=1.001, @@ -6921,11 +6398,11 @@ local write_nl,write=texio and texio.write_nl or print,texio and texio.write or local format,gmatch,find=string.format,string.gmatch,string.find local concat,insert,remove=table.concat,table.insert,table.remove local topattern=string.topattern +local texcount=tex and tex.count local next,type,select=next,type,select local utfchar=utf.char local setmetatableindex=table.setmetatableindex local formatters=string.formatters -local texgetcount=tex and tex.getcount logs=logs or {} local logs=logs local moreinfo=[[ @@ -6946,7 +6423,7 @@ utilities.strings.formatters.add ( local function ignore() end setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end) local report,subreport,status,settarget,setformats,settranslations -local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters +local direct,subdirect,writer,pushtarget,poptarget if tex and (tex.jobname or tex.formatname) then local valueiskey={ __index=function(t,k) t[k]=k return k end } local target="term and log" @@ -6959,67 +6436,67 @@ if tex and (tex.jobname or tex.formatname) then newline=function() write_nl(target,"\n") end - local report_yes=formatters["%-15s > %s\n"] - local report_nop=formatters["%-15s >\n"] + local f_one=formatters["%-15s > %s\n"] + local f_two=formatters["%-15s >\n"] report=function(a,b,c,...) if c then - write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],formatters[formats[b]](c,...))) elseif b then - write_nl(target,report_yes(translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,report_nop(translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end - local direct_yes=formatters["%-15s > %s"] - local direct_nop=formatters["%-15s >"] + local f_one=formatters["%-15s > %s"] + local f_two=formatters["%-15s >"] direct=function(a,b,c,...) if c then - return direct_yes(translations[a],formatters[formats[b]](c,...)) + return f_one(translations[a],formatters[formats[b]](c,...)) elseif b then - return direct_yes(translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return direct_nop(translations[a]) + return f_two(translations[a]) else return "" end end - local subreport_yes=formatters["%-15s > %s > %s\n"] - local subreport_nop=formatters["%-15s > %s >\n"] + local f_one=formatters["%-15s > %s > %s\n"] + local f_two=formatters["%-15s > %s >\n"] subreport=function(a,s,b,c,...) if c then - write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],translations[s],formatters[formats[b]](c,...))) elseif b then - write_nl(target,subreport_yes(translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,subreport_nop(translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end - local subdirect_yes=formatters["%-15s > %s > %s"] - local subdirect_nop=formatters["%-15s > %s >"] + local f_one=formatters["%-15s > %s > %s"] + local f_two=formatters["%-15s > %s >"] subdirect=function(a,s,b,c,...) if c then - return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...)) + return f_one(translations[a],translations[s],formatters[formats[b]](c,...)) elseif b then - return subdirect_yes(translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return subdirect_nop(translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end - local status_yes=formatters["%-15s : %s\n"] - local status_nop=formatters["%-15s :\n"] + local f_one=formatters["%-15s : %s\n"] + local f_two=formatters["%-15s :\n"] status=function(a,b,c,...) if c then - write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],formatters[formats[b]](c,...))) elseif b then - write_nl(target,status_yes(translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,status_nop(translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -7056,69 +6533,47 @@ if tex and (tex.jobname or tex.formatname) then settranslations=function(t) translations=t end - setprocessor=function(f) - local writeline=write_nl - write_nl=function(target,...) - writeline(target,f(...)) - end - end - setformatters=function(f) - report_yes=f.report_yes or report_yes - report_nop=f.report_nop or report_nop - subreport_yes=f.subreport_yes or subreport_yes - subreport_nop=f.subreport_nop or subreport_nop - direct_yes=f.direct_yes or direct_yes - direct_nop=f.direct_nop or direct_nop - subdirect_yes=f.subdirect_yes or subdirect_yes - subdirect_nop=f.subdirect_nop or subdirect_nop - status_yes=f.status_yes or status_yes - status_nop=f.status_nop or status_nop - end - setlogfile=ignore - settimedlog=ignore else logs.flush=ignore - writer=function(s) - write_nl(s) - end + writer=write_nl newline=function() write_nl("\n") end - local report_yes=formatters["%-15s | %s"] - local report_nop=formatters["%-15s |"] + local f_one=formatters["%-15s | %s"] + local f_two=formatters["%-15s |"] report=function(a,b,c,...) if c then - write_nl(report_yes(a,formatters[b](c,...))) + write_nl(f_one(a,formatters[b](c,...))) elseif b then - write_nl(report_yes(a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(report_nop(a)) + write_nl(f_two(a)) else write_nl("") end end - local subreport_yes=formatters["%-15s | %s | %s"] - local subreport_nop=formatters["%-15s | %s |"] + local f_one=formatters["%-15s | %s | %s"] + local f_two=formatters["%-15s | %s |"] subreport=function(a,sub,b,c,...) if c then - write_nl(subreport_yes(a,sub,formatters[b](c,...))) + write_nl(f_one(a,sub,formatters[b](c,...))) elseif b then - write_nl(subreport_yes(a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(subreport_nop(a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end - local status_yes=formatters["%-15s : %s\n"] - local status_nop=formatters["%-15s :\n"] + local f_one=formatters["%-15s : %s\n"] + local f_two=formatters["%-15s :\n"] status=function(a,b,c,...) if c then - write_nl(status_yes(a,formatters[b](c,...))) + write_nl(f_one(a,formatters[b](c,...))) elseif b then - write_nl(status_yes(a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(status_nop(a)) + write_nl(f_two(a)) else write_nl("\n") end @@ -7130,49 +6585,6 @@ else poptarget=ignore setformats=ignore settranslations=ignore - setprocessor=function(f) - local writeline=write_nl - write_nl=function(s) - writeline(f(s)) - end - end - setformatters=function(f) - report_yes=f.report_yes or report_yes - report_nop=f.report_nop or report_nop - subreport_yes=f.subreport_yes or subreport_yes - subreport_nop=f.subreport_nop or subreport_nop - status_yes=f.status_yes or status_yes - status_nop=f.status_nop or status_nop - end - setlogfile=function(name,keepopen) - if name and name~="" then - local localtime=os.localtime - local writeline=write_nl - if keepopen then - local f=io.open(name,"ab") - write_nl=function(s) - writeline(s) - f:write(localtime()," | ",s,"\n") - end - else - write_nl=function(s) - writeline(s) - local f=io.open(name,"ab") - f:write(localtime()," | ",s,"\n") - f:close() - end - end - end - setlogfile=ignore - end - settimedlog=function() - local localtime=os.localtime - local writeline=write_nl - write_nl=function(s) - writeline(localtime().." | "..s) - end - settimedlog=ignore - end end logs.report=report logs.subreport=subreport @@ -7182,10 +6594,6 @@ logs.pushtarget=pushtarget logs.poptarget=poptarget logs.setformats=setformats logs.settranslations=settranslations -logs.setlogfile=setlogfile -logs.settimedlog=settimedlog -logs.setprocessor=setprocessor -logs.setformatters=setformatters logs.direct=direct logs.subdirect=subdirect logs.writer=writer @@ -7336,9 +6744,7 @@ end) local report_pages=logs.reporter("pages") local real,user,sub function logs.start_page_number() - real=texgetcount("realpageno") - user=texgetcount("userpageno") - sub=texgetcount("subpageno") + real,user,sub=texcount.realpageno,texcount.userpageno,texcount.subpageno end local timing=false local starttime=nil @@ -7543,7 +6949,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6295, stripped down to: 4966 +-- original size: 5678, stripped down to: 4448 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7552,19 +6958,16 @@ if not modules then modules={} end modules ['trac-inf']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,tonumber,select=type,tonumber,select +local type,tonumber=type,tonumber local format,lower=string.format,string.lower local concat=table.concat local clock=os.gettimeofday or os.clock -local setmetatableindex=table.setmetatableindex -local serialize=table.serialize -local formatters=string.formatters statistics=statistics or {} local statistics=statistics statistics.enable=true statistics.threshold=0.01 local statusinfo,n,registered,timers={},0,{},{} -setmetatableindex(timers,function(t,k) +table.setmetatableindex(timers,function(t,k) local v={ timing=0,loadtime=0 } t[k]=v return v @@ -7693,16 +7096,6 @@ function statistics.timed(action) stoptiming("run") report("total runtime: %s",elapsedtime("run")) end -function statistics.tracefunction(base,tag,...) - for i=1,select("#",...) do - local name=select(i,...) - local stat={} - local func=base[name] - setmetatableindex(stat,function(t,k) t[k]=0 return 0 end) - base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end - statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end) - end -end commands=commands or {} function commands.resettimer(name) resettiming(name or "whatever") @@ -7865,7 +7258,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-lua"] = package.loaded["util-lua"] or true --- original size: 4982, stripped down to: 3511 +-- original size: 12575, stripped down to: 8700 if not modules then modules={} end modules ['util-lua']={ version=1.001, @@ -7900,92 +7293,251 @@ luautilities.suffixes={ tua="tua", tuc="tuc", } -local function register(name) - if tracestripping then - report_lua("stripped bytecode from %a",name or "unknown") +if jit or status.luatex_version>=74 then + local function register(name) + if tracestripping then + report_lua("stripped bytecode from %a",name or "unknown") + end + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 + end + local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + if code and code~="" then + code=load(code) + if code then + code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code~="" then + register(name) + io.savedata(lucfile,code) + return true,0 + end + else + report_lua("fatal error %a in file %a",1,luafile) + end + else + report_lua("fatal error %a in file %a",2,luafile) + end + return false,0 end - strippedchunks[#strippedchunks+1]=name - luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 -end -local function stupidcompile(luafile,lucfile,strip) - local code=io.loaddata(luafile) - if code and code~="" then - code=load(code) + function luautilities.loadedluacode(fullname,forcestrip,name) + name=name or fullname + local code=environment.loadpreprocessedfile and environment.loadpreprocessedfile(fullname) or loadfile(fullname) if code then - code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) - if code and code~="" then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then register(name) - io.savedata(lucfile,code) - return true,0 + return load(dump(code,true)),0 + else + return code,0 end + elseif luautilities.alwaysstripcode then + register(name) + return load(dump(code,true)),0 else - report_lua("fatal error %a in file %a",1,luafile) + return code,0 end - else - report_lua("fatal error %a in file %a",2,luafile) end - return false,0 -end -function luautilities.loadedluacode(fullname,forcestrip,name) - name=name or fullname - local code,message - if environment.loadpreprocessedfile then - code,message=environment.loadpreprocessedfile(fullname) - else - code,message=loadfile(fullname) + function luautilities.strippedloadstring(code,forcestrip,name) + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code=load(code) + if not code then + report_lua("fatal error %a in file %a",3,name) + end + register(name) + code=dump(code,true) + end + return load(code),0 end - if code then - code() + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=stupidcompile(luafile,lucfile,strip~=false) + if done then + report_lua("dumping %a into %a stripped",luafile,lucfile) + if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + report_lua("removing %a",luafile) + os.remove(luafile) + end + end + return done + end + function luautilities.loadstripped(...) + local l=load(...) + if l then + return load(dump(l,true)) + end + end +else + local function register(name,before,after) + local delta=before-after + if tracestripping then + report_lua("bytecodes stripped from %a, # before %s, # after %s, delta %s",name,before,after,delta) + end + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 + luautilities.nofstrippedbytes=luautilities.nofstrippedbytes+delta + return delta + end + local strip_code_pc + if _MAJORVERSION==5 and _MINORVERSION==1 then + strip_code_pc=function(dump,name) + local before=#dump + local version,format,endian,int,size,ins,num=byte(dump,5,11) + local subint + if endian==1 then + subint=function(dump,i,l) + local val=0 + for n=l,1,-1 do + val=val*256+byte(dump,i+n-1) + end + return val,i+l + end + else + subint=function(dump,i,l) + local val=0 + for n=1,l,1 do + val=val*256+byte(dump,i+n-1) + end + return val,i+l + end + end + local strip_function + strip_function=function(dump) + local count,offset=subint(dump,1,size) + local stripped,dirty=rep("\0",size),offset+count + offset=offset+count+int*2+4 + offset=offset+int+subint(dump,offset,int)*ins + count,offset=subint(dump,offset,int) + for n=1,count do + local t + t,offset=subint(dump,offset,1) + if t==1 then + offset=offset+1 + elseif t==4 then + offset=offset+size+subint(dump,offset,size) + elseif t==3 then + offset=offset+num + end + end + count,offset=subint(dump,offset,int) + stripped=stripped..sub(dump,dirty,offset-1) + for n=1,count do + local proto,off=strip_function(sub(dump,offset,-1)) + stripped,offset=stripped..proto,offset+off-1 + end + offset=offset+subint(dump,offset,int)*int+int + count,offset=subint(dump,offset,int) + for n=1,count do + offset=offset+subint(dump,offset,size)+size+int*2 + end + count,offset=subint(dump,offset,int) + for n=1,count do + offset=offset+subint(dump,offset,size)+size + end + stripped=stripped..rep("\0",int*3) + return stripped,offset + end + dump=sub(dump,1,12)..strip_function(sub(dump,13,-1)) + local after=#dump + local delta=register(name,before,after) + return dump,delta + end else - report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message") + strip_code_pc=function(dump,name) + return dump,0 + end end - if forcestrip and luautilities.stripcode then - if type(forcestrip)=="function" then - forcestrip=forcestrip(fullname) + function luautilities.loadedluacode(fullname,forcestrip,name) + local code=environment.loadpreprocessedfile and environment.preprocessedloadfile(fullname) or loadfile(fullname) + if code then + code() end - if forcestrip or luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) + end + if forcestrip then + local code,n=strip_code_pc(dump(code),name) + return load(code),n + elseif luautilities.alwaysstripcode then + return load(strip_code_pc(dump(code),name)) + else + return code,0 + end + elseif luautilities.alwaysstripcode then + return load(strip_code_pc(dump(code),name)) else return code,0 end - elseif luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 - else - return code,0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) - local code,message=load(code) - if not code then - report_lua("loading of file %a failed:\n\t%s",name,message or "no message") + function luautilities.strippedloadstring(code,forcestrip,name) + local n=0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code=load(code) + if not code then + report_lua("fatal error in file %a",name) + end + code,n=strip_code_pc(dump(code),name) + end + return load(code),n end - if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 - else - return code,0 + local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + local n=0 + if code and code~="" then + code=load(code) + if not code then + report_lua("fatal error in file %a",luafile) + end + code=dump(code) + if strip then + code,n=strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) + end + if code and code~="" then + io.savedata(lucfile,code) + end + end + return n end -end -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) - report_lua("compiling %a into %a",luafile,lucfile) - os.remove(lucfile) - local done=stupidcompile(luafile,lucfile,strip~=false) - if done then - report_lua("dumping %a into %a stripped",luafile,lucfile) - if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + local luac_normal="texluac -o %q %q" + local luac_strip="texluac -s -o %q %q" + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=false + if strip~=false then + strip=true + end + if forcestupidcompile then + fallback=true + elseif strip then + done=os.spawn(format(luac_strip,lucfile,luafile))==0 + else + done=os.spawn(format(luac_normal,lucfile,luafile))==0 + end + if not done and fallback then + local n=stupidcompile(luafile,lucfile,strip) + if n>0 then + report_lua("%a dumped into %a (%i bytes stripped)",luafile,lucfile,n) + else + report_lua("%a dumped into %a (unstripped)",luafile,lucfile) + end + cleanup=false + done=true + end + if done and cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then report_lua("removing %a",luafile) os.remove(luafile) end + return done end - return done -end -function luautilities.loadstripped(...) - local l=load(...) - if l then - return load(dump(l,true)) - end + luautilities.loadstripped=loadstring end @@ -8274,7 +7826,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tpl"] = package.loaded["util-tpl"] or true --- original size: 6251, stripped down to: 3488 +-- original size: 5655, stripped down to: 3242 if not modules then modules={} end modules ['util-tpl']={ version=1.001, @@ -8288,8 +7840,8 @@ local templates=utilities.templates local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end) local report_template=logs.reporter("template") local tostring=tostring -local format,sub,byte=string.format,string.sub,string.byte -local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns +local format,sub=string.format,string.sub +local P,C,Cs,Carg,lpegmatch=lpeg.P,lpeg.C,lpeg.Cs,lpeg.Carg,lpeg.match local replacer local function replacekey(k,t,how,recursive) local v=t[k] @@ -8316,13 +7868,10 @@ local sqlescape=lpeg.replacer { { "\r\n","\\n" }, { "\r","\\n" }, } -local sqlquoted=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) -lpegpatterns.sqlescape=sqlescape -lpegpatterns.sqlquoted=sqlquoted -local luaescape=lpegpatterns.luaescape +local sqlquotedescape=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) local escapers={ lua=function(s) - return lpegmatch(luaescape,s) + return sub(format("%q",s),2,-2) end, sql=function(s) return lpegmatch(sqlescape,s) @@ -8333,9 +7882,11 @@ local quotedescapers={ return format("%q",s) end, sql=function(s) - return lpegmatch(sqlquoted,s) + return lpegmatch(sqlquotedescape,s) end, } +lpeg.patterns.sqlescape=sqlescape +lpeg.patterns.sqlescape=sqlquotedescape local luaescaper=escapers.lua local quotedluaescaper=quotedescapers.lua local function replacekeyunquoted(s,t,how,recurse) @@ -8372,11 +7923,6 @@ local function replace(str,mapping,how,recurse) end end templates.replace=replace -function templates.replacer(str,how,recurse) - return function(mapping) - return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str - end -end function templates.load(filename,mapping,how,recurse) local data=io.loaddata(filename) or "" if mapping and next(mapping) then @@ -8402,7 +7948,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8761, stripped down to: 5085 +-- original size: 8722, stripped down to: 5050 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8438,7 +7984,6 @@ local luaengines=allocate { environment.validengines=validengines environment.basicengines=basicengines if not arg then - environment.used_as_library=true elseif luaengines[file.removesuffix(arg[-1])] then elseif validengines[file.removesuffix(arg[0])] then if arg[1]=="--luaonly" then @@ -8599,7 +8144,7 @@ do -- create closure to overcome 200 locals limit package.loaded["luat-env"] = package.loaded["luat-env"] or true --- original size: 5930, stripped down to: 4235 +-- original size: 5874, stripped down to: 4184 if not modules then modules={} end modules ['luat-env']={ version=1.001, @@ -8613,13 +8158,12 @@ local trace_locating=false trackers.register("resolvers.locating",function(v) tr local report_lua=logs.reporter("resolvers","lua") local luautilities=utilities.lua local luasuffixes=luautilities.suffixes -local texgettoks=tex and tex.gettoks environment=environment or {} local environment=environment local mt={ __index=function(_,k) if k=="version" then - local version=texgettoks and texgettoks("contextversiontoks") + local version=tex.toks and tex.toks.contextversiontoks if version and version~="" then rawset(environment,"version",version) return version @@ -8627,7 +8171,7 @@ local mt={ return "unknown" end elseif k=="kind" then - local kind=texgettoks and texgettoks("contextkindtoks") + local kind=tex.toks and tex.toks.contextkindtoks if kind and kind~="" then rawset(environment,"kind",kind) return kind @@ -8754,7 +8298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 42447, stripped down to: 26589 +-- original size: 42495, stripped down to: 26647 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -8765,7 +8309,6 @@ if not modules then modules={} end modules ['lxml-tab']={ } local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end) local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end -if lpeg.setmaxstack then lpeg.setmaxstack(1000) end xml=xml or {} local xml=xml local concat,remove,insert=table.concat,table.remove,table.insert @@ -9185,6 +8728,7 @@ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace* local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset local simpledoctype=(1-close)^1 local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) +local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end @@ -12269,7 +11813,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-exp"] = package.loaded["data-exp"] or true --- original size: 15303, stripped down to: 9716 +-- original size: 14654, stripped down to: 9517 if not modules then modules={} end modules ['data-exp']={ version=1.001, @@ -12281,7 +11825,7 @@ if not modules then modules={} end modules ['data-exp']={ local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub local concat,sort=table.concat,table.sort local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S +local Ct,Cs,Cc,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.P,lpeg.C,lpeg.S local type,next=type,next local ostype=os.type local collapsepath=file.collapsepath @@ -12289,6 +11833,20 @@ local trace_locating=false trackers.register("resolvers.locating",function(v) tr local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end) local report_expansions=logs.reporter("resolvers","expansions") local resolvers=resolvers +local function f_first(a,b) + local t,n={},0 + for s in gmatch(b,"[^,]+") do + n=n+1;t[n]=a..s + end + return concat(t,",") +end +local function f_second(a,b) + local t,n={},0 + for s in gmatch(a,"[^,]+") do + n=n+1;t[n]=s..b + end + return concat(t,",") +end local function f_both(a,b) local t,n={},0 for sb in gmatch(b,"[^,]+") do @@ -12298,15 +11856,6 @@ local function f_both(a,b) end return concat(t,",") end -local comma=P(",") -local nocomma=(1-comma)^1 -local docomma=comma^1/"," -local before=Cs((nocomma*Carg(1)+docomma)^0) -local after=Cs((Carg(1)*nocomma+docomma)^0) -local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0) -local function f_first (a,b) return lpegmatch(after,b,1,a) end -local function f_second(a,b) return lpegmatch(before,a,1,b) end -local function f_both (a,b) return lpegmatch(both,b,1,a) end local left=P("{") local right=P("}") local var=P((1-S("{}" ))^0) @@ -12894,7 +12443,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-tmp"] = package.loaded["data-tmp"] or true --- original size: 15532, stripped down to: 11648 +-- original size: 14615, stripped down to: 11208 if not modules then modules={} end modules ['data-tmp']={ version=1.100, @@ -13108,22 +12657,6 @@ function caches.getfirstreadablefile(filename,...) end return caches.setfirstwritablefile(filename,...) end -function caches.getfirstreadablefile_TEST_ME_FIRST(filename,...) - local fullname,path=caches.setfirstwritablefile(filename,...) - if is_readable(fullname) then - return fullname,path - end - local rd=getreadablepaths(...) - for i=1,#rd do - local path=rd[i] - local fullname=file.join(path,filename) - if is_readable(fullname) then - usedreadables[i]=true - return fullname,path - end - end - return fullname,path -end function caches.setfirstwritablefile(filename,...) local wr=getwritablepath(...) local fullname=file.join(wr,filename) @@ -13269,7 +12802,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-met"] = package.loaded["data-met"] or true --- original size: 5453, stripped down to: 4007 +-- original size: 5137, stripped down to: 4007 if not modules then modules={} end modules ['data-met']={ version=1.100, @@ -13388,7 +12921,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-res"] = package.loaded["data-res"] or true --- original size: 61782, stripped down to: 42959 +-- original size: 61759, stripped down to: 42959 if not modules then modules={} end modules ['data-res']={ version=1.001, @@ -16563,8 +16096,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 680476 --- stripped bytes : 240933 +-- original bytes : 670212 +-- stripped bytes : 245255 -- end library merge @@ -16732,9 +16265,11 @@ end -- verbosity ------ e_verbose = environment.arguments["verbose"] +local e_verbose = environment.arguments["verbose"] -local e_verbose = false +if e_verbose then + trackers.enable("resolvers.locating") +end -- some common flags (also passed through environment) @@ -17455,22 +16990,12 @@ environment.initializearguments(before) instance.lsrmode = environment.argument("lsr") or false -e_verbose = environment.arguments["verbose"] -- delayed till here (we need the ones before script) - -if e_verbose then - trackers.enable("resolvers.locating") -end - -- maybe the unset has to go to this level local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] local e_argument = environment.argument -if e_argument("timedlog") then - logs.settimedlog() -end - if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then resolvers.load_tree(e_argument('tree'),true) -- force resolve of TEXMFCNF @@ -17553,23 +17078,6 @@ else end --- joke .. reminds me of messing with gigi terminals - -if e_argument("ansi") then - - local formatters = string.formatters - - logs.setformatters { - report_yes = formatters["[1;32m%-15s [0;1m|[0m %s"], - report_nop = formatters["[1;32m%-15s [0;1m|[0m"], - subreport_yes = formatters["[1;32m%-15s [0;1m|[1;31m %s [0;1m|[0m %s"], - subreport_nop = formatters["[1;32m%-15s [0;1m|[1;31m %s [0;1m|[0m"], - status_yes = formatters["[1;32m%-15s [0;1m:[0m %s\n"], - status_nop = formatters["[1;32m%-15s [0;1m:[0m\n"], - } - -end - if e_argument("script") or e_argument("scripts") then -- run a script by loading it (using libs), pass args diff --git a/scripts/context/stubs/mswin/setuptex.bat b/scripts/context/stubs/mswin/setuptex.bat index 5f30bfd4e..52c60f155 100644 --- a/scripts/context/stubs/mswin/setuptex.bat +++ b/scripts/context/stubs/mswin/setuptex.bat @@ -8,12 +8,6 @@ if "%SETUPTEX%"=="done" goto done if "%~s1"=="" goto selftest -set TEXMFOS=%~s1texmf-mswin-64 -if exist %TEXMFOS%\bin\mtxrun.exe goto start - -set TEXMFOS=%~s1\texmf-mswin-64 -if exist %TEXMFOS%\bin\mtxrun.exe goto start - set TEXMFOS=%~s1texmf-mswin if exist %TEXMFOS%\bin\mtxrun.exe goto start @@ -22,12 +16,6 @@ if exist %TEXMFOS%\bin\mtxrun.exe goto start :selftest -set TEXMFOS=%~d0%~p0texmf-mswin-64 -if exist %TEXMFOS%\bin\mtxrun.exe goto start - -set TEXMFOS=%~d0%~p0\texmf-mswin-64 -if exist %TEXMFOS%\bin\mtxrun.exe goto start - set TEXMFOS=%~d0%~p0texmf-mswin if exist %TEXMFOS%\bin\mtxrun.exe goto start diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 9edbbf4bf..d07dfc9a7 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -144,7 +144,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-package"] = package.loaded["l-package"] or true --- original size: 10594, stripped down to: 7819 +-- original size: 9893, stripped down to: 7253 if not modules then modules={} end modules ['l-package']={ version=1.001, @@ -154,7 +154,7 @@ if not modules then modules={} end modules ['l-package']={ license="see context related readme files" } local type=type -local gsub,format,find=string.gsub,string.format,string.find +local gsub,format=string.gsub,string.format local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match local package=package local searchers=package.searchers or package.loaders @@ -184,7 +184,6 @@ local helpers=package.helpers or { sequence={ "already loaded", "preload table", - "qualified path", "lua extra list", "lib extra list", "path specification", @@ -330,30 +329,12 @@ local function loadedbypath(name,rawname,paths,islib,what) end end helpers.loadedbypath=loadedbypath -local function loadedbyname(name,rawname) - if find(name,"^/") or find(name,"^[a-zA-Z]:/") then - local trace=helpers.trace - if trace then - helpers.report("qualified name, identifying '%s'",what,name) - end - if isreadable(name) then - if trace then - helpers.report("qualified name, '%s' found",what,name) - end - return loadfile(name) - end - end -end -helpers.loadedbyname=loadedbyname methods["already loaded"]=function(name) return package.loaded[name] end methods["preload table"]=function(name) return builtin["preload table"](name) end -methods["qualified path"]=function(name) - return loadedbyname(addsuffix(lualibfile(name),"lua"),name) -end methods["lua extra list"]=function(name) return loadedbypath(addsuffix(lualibfile(name),"lua" ),name,getextraluapaths(),false,"lua") end @@ -434,7 +415,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true --- original size: 29245, stripped down to: 15964 +-- original size: 26252, stripped down to: 14371 if not modules then modules={} end modules ['l-lpeg']={ version=1.001, @@ -444,7 +425,6 @@ if not modules then modules={} end modules ['l-lpeg']={ license="see context related readme files" } lpeg=require("lpeg") -if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end local type,next,tostring=type,next,tostring local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format local floor=math.floor @@ -460,46 +440,28 @@ patterns.anything=anything patterns.endofstring=endofstring patterns.beginofstring=alwaysmatched patterns.alwaysmatched=alwaysmatched -local sign=S('+-') -local zero=P('0') -local digit=R('09') -local octdigit=R("07") -local lowercase=R("az") -local uppercase=R("AZ") -local underscore=P("_") -local hexdigit=digit+lowercase+uppercase +local digit,sign=R('09'),S('+-') local cr,lf,crlf=P("\r"),P("\n"),P("\r\n") local newline=crlf+S("\r\n") local escaped=P("\\")*anything local squote=P("'") local dquote=P('"') local space=P(" ") -local period=P(".") -local comma=P(",") -local utfbom_32_be=P('\000\000\254\255') -local utfbom_32_le=P('\255\254\000\000') -local utfbom_16_be=P('\254\255') -local utfbom_16_le=P('\255\254') -local utfbom_8=P('\239\187\191') +local utfbom_32_be=P('\000\000\254\255') +local utfbom_32_le=P('\255\254\000\000') +local utfbom_16_be=P('\255\254') +local utfbom_16_le=P('\254\255') +local utfbom_8=P('\239\187\191') local utfbom=utfbom_32_be+utfbom_32_le+utfbom_16_be+utfbom_16_le+utfbom_8 local utftype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8")+alwaysmatched*Cc("utf-8") -local utfstricttype=utfbom_32_be*Cc("utf-32-be")+utfbom_32_le*Cc("utf-32-le")+utfbom_16_be*Cc("utf-16-be")+utfbom_16_le*Cc("utf-16-le")+utfbom_8*Cc("utf-8") local utfoffset=utfbom_32_be*Cc(4)+utfbom_32_le*Cc(4)+utfbom_16_be*Cc(2)+utfbom_16_le*Cc(2)+utfbom_8*Cc(3)+Cc(0) local utf8next=R("\128\191") -patterns.utfbom_32_be=utfbom_32_be -patterns.utfbom_32_le=utfbom_32_le -patterns.utfbom_16_be=utfbom_16_be -patterns.utfbom_16_le=utfbom_16_le -patterns.utfbom_8=utfbom_8 -patterns.utf_16_be_nl=P("\000\r\000\n")+P("\000\r")+P("\000\n") -patterns.utf_16_le_nl=P("\r\000\n\000")+P("\r\000")+P("\n\000") patterns.utf8one=R("\000\127") patterns.utf8two=R("\194\223")*utf8next patterns.utf8three=R("\224\239")*utf8next*utf8next patterns.utf8four=R("\240\244")*utf8next*utf8next*utf8next patterns.utfbom=utfbom patterns.utftype=utftype -patterns.utfstricttype=utfstricttype patterns.utfoffset=utfoffset local utf8char=patterns.utf8one+patterns.utf8two+patterns.utf8three+patterns.utf8four local validutf8char=utf8char^0*endofstring*Cc(true)+Cc(false) @@ -523,8 +485,23 @@ local stripper=spacer^0*C((spacer^0*nonspacer^1)^0) local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0)) patterns.stripper=stripper patterns.collapser=collapser -patterns.lowercase=lowercase -patterns.uppercase=uppercase +patterns.digit=digit +patterns.sign=sign +patterns.cardinal=sign^0*digit^1 +patterns.integer=sign^0*digit^1 +patterns.unsigned=digit^0*P('.')*digit^1 +patterns.float=sign^0*patterns.unsigned +patterns.cunsigned=digit^0*P(',')*digit^1 +patterns.cfloat=sign^0*patterns.cunsigned +patterns.number=patterns.float+patterns.integer +patterns.cnumber=patterns.cfloat+patterns.integer +patterns.oct=P("0")*R("07")^1 +patterns.octal=patterns.oct +patterns.HEX=P("0x")*R("09","AF")^1 +patterns.hex=P("0x")*R("09","af")^1 +patterns.hexadecimal=P("0x")*R("09","AF","af")^1 +patterns.lowercase=R("az") +patterns.uppercase=R("AZ") patterns.letter=patterns.lowercase+patterns.uppercase patterns.space=space patterns.tab=P("\t") @@ -532,12 +509,12 @@ patterns.spaceortab=patterns.space+patterns.tab patterns.newline=newline patterns.emptyline=newline^1 patterns.equal=P("=") -patterns.comma=comma -patterns.commaspacer=comma*spacer^0 -patterns.period=period +patterns.comma=P(",") +patterns.commaspacer=P(",")*spacer^0 +patterns.period=P(".") patterns.colon=P(":") patterns.semicolon=P(";") -patterns.underscore=underscore +patterns.underscore=P("_") patterns.escaped=escaped patterns.squote=squote patterns.dquote=dquote @@ -550,29 +527,10 @@ patterns.unspacer=((patterns.spacer^1)/"")^0 patterns.singlequoted=squote*patterns.nosquote*squote patterns.doublequoted=dquote*patterns.nodquote*dquote patterns.quoted=patterns.doublequoted+patterns.singlequoted -patterns.digit=digit -patterns.octdigit=octdigit -patterns.hexdigit=hexdigit -patterns.sign=sign -patterns.cardinal=digit^1 -patterns.integer=sign^-1*digit^1 -patterns.unsigned=digit^0*period*digit^1 -patterns.float=sign^-1*patterns.unsigned -patterns.cunsigned=digit^0*comma*digit^1 -patterns.cfloat=sign^-1*patterns.cunsigned -patterns.number=patterns.float+patterns.integer -patterns.cnumber=patterns.cfloat+patterns.integer -patterns.oct=zero*octdigit^1 -patterns.octal=patterns.oct -patterns.HEX=zero*P("X")*(digit+uppercase)^1 -patterns.hex=zero*P("x")*(digit+lowercase)^1 -patterns.hexadecimal=zero*S("xX")*hexdigit^1 -patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigit^1+hexdigit^1*period*hexdigit^0+hexdigit^1)*(S("pP")*sign^-1*hexdigit^1)^-1 -patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^1)*S("eE")*sign^-1*digit^1 -patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring +patterns.propername=R("AZ","az","__")*R("09","AZ","az","__")^0*P(-1) patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) -patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0)) +patterns.longtostring=Cs(whitespace^0/""*nonwhitespace^0*((whitespace^0/" "*(patterns.quoted+nonwhitespace)^1)^0)) local function anywhere(pattern) return P { P(pattern)+1*V(1) } end @@ -744,7 +702,7 @@ function lpeg.replacer(one,two,makefunction,isutf) return pattern end end -function lpeg.finder(lst,makefunction) +function lpeg.finder(lst,makefunction) local pattern if type(lst)=="table" then pattern=P(false) @@ -773,8 +731,8 @@ local splitters_f,splitters_s={},{} function lpeg.firstofsplit(separator) local splitter=splitters_f[separator] if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0) + separator=P(separator) + splitter=C((1-separator)^0) splitters_f[separator]=splitter end return splitter @@ -782,31 +740,12 @@ end function lpeg.secondofsplit(separator) local splitter=splitters_s[separator] if not splitter then - local pattern=P(separator) - splitter=(1-pattern)^0*pattern*C(anything^0) - splitters_s[separator]=splitter - end - return splitter -end -local splitters_s,splitters_p={},{} -function lpeg.beforesuffix(separator) - local splitter=splitters_s[separator] - if not splitter then - local pattern=P(separator) - splitter=C((1-pattern)^0)*pattern*endofstring + separator=P(separator) + splitter=(1-separator)^0*separator*C(anything^0) splitters_s[separator]=splitter end return splitter end -function lpeg.afterprefix(separator) - local splitter=splitters_p[separator] - if not splitter then - local pattern=P(separator) - splitter=pattern*C(anything^0) - splitters_p[separator]=splitter - end - return splitter -end function lpeg.balancer(left,right) left,right=P(left),P(right) return P { left*((1-left-right)+V(1))^0*right } @@ -1038,6 +977,9 @@ end function lpeg.times(pattern,n) return P(nextstep(n,2^16,{ "start",["1"]=pattern })) end +local digit=R("09") +local period=P(".") +local zero=P("0") local trailingzeros=zero^0*-digit local case_1=period*trailingzeros/"" local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"") @@ -1071,7 +1013,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-string"] = package.loaded["l-string"] or true --- original size: 5547, stripped down to: 2708 +-- original size: 5513, stripped down to: 2708 if not modules then modules={} end modules ['l-string']={ version=1.001, @@ -1172,7 +1114,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-table"] = package.loaded["l-table"] or true --- original size: 30618, stripped down to: 19908 +-- original size: 44626, stripped down to: 19688 if not modules then modules={} end modules ['l-table']={ version=1.001, @@ -1440,7 +1382,6 @@ local noquotes,hexify,handle,reduce,compact,inline,functions local reserved=table.tohash { 'and','break','do','else','elseif','end','false','for','function','if', 'in','local','nil','not','or','repeat','return','then','true','until','while', - 'NaN','goto', } local function simple_table(t) if #t>0 then @@ -1460,12 +1401,12 @@ local function simple_table(t) else tt[nt]=tostring(v) end + elseif tv=="boolean" then + nt=nt+1 + tt[nt]=tostring(v) elseif tv=="string" then nt=nt+1 tt[nt]=format("%q",v) - elseif tv=="boolean" then - nt=nt+1 - tt[nt]=v and "true" or "false" else tt=nil break @@ -1498,7 +1439,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s[%q]={",depth,name)) end elseif tn=="boolean" then - handle(format("%s[%s]={",depth,name and "true" or "false")) + handle(format("%s[%s]={",depth,tostring(name))) else handle(format("%s{",depth)) end @@ -1522,21 +1463,21 @@ local function do_serialize(root,name,depth,level,indexed) for i=1,#sk do local k=sk[i] local v=root[k] - local tv,tk=type(v),type(k) + local t,tk=type(v),type(k) if compact and first and tk=="number" and k>=first and k<=last then - if tv=="number" then + if t=="number" then if hexify then handle(format("%s 0x%04X,",depth,v)) else handle(format("%s %s,",depth,v)) end - elseif tv=="string" then + elseif t=="string" then if reduce and tonumber(v) then handle(format("%s %s,",depth,v)) else handle(format("%s %q,",depth,v)) end - elseif tv=="table" then + elseif t=="table" then if not next(v) then handle(format("%s {},",depth)) elseif inline then @@ -1549,11 +1490,11 @@ local function do_serialize(root,name,depth,level,indexed) else do_serialize(v,k,depth,level+1,true) end - elseif tv=="boolean" then - handle(format("%s %s,",depth,v and "true" or "false")) - elseif tv=="function" then + elseif t=="boolean" then + handle(format("%s %s,",depth,tostring(v))) + elseif t=="function" then if functions then - handle(format('%s load(%q),',depth,dump(v))) + handle(format('%s load(%q),',depth,dump(v))) else handle(format('%s "function",',depth)) end @@ -1564,7 +1505,7 @@ local function do_serialize(root,name,depth,level,indexed) if false then handle(format("%s __p__=nil,",depth)) end - elseif tv=="number" then + elseif t=="number" then if tk=="number" then if hexify then handle(format("%s [0x%04X]=0x%04X,",depth,k,v)) @@ -1573,9 +1514,9 @@ local function do_serialize(root,name,depth,level,indexed) end elseif tk=="boolean" then if hexify then - handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=0x%04X,",depth,tostring(k),v)) else - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%s,",depth,tostring(k),v)) end elseif noquotes and not reserved[k] and lpegmatch(propername,k) then if hexify then @@ -1590,7 +1531,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%q]=%s,",depth,k,v)) end end - elseif tv=="string" then + elseif t=="string" then if reduce and tonumber(v) then if tk=="number" then if hexify then @@ -1599,7 +1540,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%s,",depth,k,v)) end elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%s,",depth,tostring(k),v)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%s,",depth,k,v)) else @@ -1613,14 +1554,14 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%q,",depth,k,v)) end elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",v)) + handle(format("%s [%s]=%q,",depth,tostring(k),v)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,v)) else handle(format("%s [%q]=%q,",depth,k,v)) end end - elseif tv=="table" then + elseif t=="table" then if not next(v) then if tk=="number" then if hexify then @@ -1629,7 +1570,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]={},",depth,k)) end elseif tk=="boolean" then - handle(format("%s [%s]={},",depth,k and "true" or "false")) + handle(format("%s [%s]={},",depth,tostring(k))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={},",depth,k)) else @@ -1645,7 +1586,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]={ %s },",depth,k,concat(st,", "))) end elseif tk=="boolean" then - handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", "))) + handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", "))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s={ %s },",depth,k,concat(st,", "))) else @@ -1657,21 +1598,21 @@ local function do_serialize(root,name,depth,level,indexed) else do_serialize(v,k,depth,level+1) end - elseif tv=="boolean" then + elseif t=="boolean" then if tk=="number" then if hexify then - handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [0x%04X]=%s,",depth,k,tostring(v))) else - handle(format("%s [%s]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [%s]=%s,",depth,k,tostring(v))) end elseif tk=="boolean" then - handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false")) + handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then - handle(format("%s %s=%s,",depth,k,v and "true" or "false")) + handle(format("%s %s=%s,",depth,k,tostring(v))) else - handle(format("%s [%q]=%s,",depth,k,v and "true" or "false")) + handle(format("%s [%q]=%s,",depth,k,tostring(v))) end - elseif tv=="function" then + elseif t=="function" then if functions then local f=getinfo(v).what=="C" and dump(dummy) or dump(v) if tk=="number" then @@ -1681,7 +1622,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=load(%q),",depth,k,f)) end elseif tk=="boolean" then - handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f)) + handle(format("%s [%s]=load(%q),",depth,tostring(k),f)) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=load(%q),",depth,k,f)) else @@ -1696,7 +1637,7 @@ local function do_serialize(root,name,depth,level,indexed) handle(format("%s [%s]=%q,",depth,k,tostring(v))) end elseif tk=="boolean" then - handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v))) + handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v))) elseif noquotes and not reserved[k] and lpegmatch(propername,k) then handle(format("%s %s=%q,",depth,k,tostring(v))) else @@ -2040,7 +1981,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-io"] = package.loaded["l-io"] or true --- original size: 8817, stripped down to: 6340 +-- original size: 8799, stripped down to: 6325 if not modules then modules={} end modules ['l-io']={ version=1.001, @@ -2071,7 +2012,6 @@ local function readall(f) return f:read('*all') else local done=f:seek("set",0) - local step if size<1024*1024 then step=1024*1024 elseif size>16*1024*1024 then @@ -2575,7 +2515,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-os"] = package.loaded["l-os"] or true --- original size: 15800, stripped down to: 9551 +-- original size: 14017, stripped down to: 8504 if not modules then modules={} end modules ['l-os']={ version=1.001, @@ -2656,13 +2596,7 @@ function os.exec (...) ioflush() return exec (...) end function io.popen (...) ioflush() return iopopen(...) end function os.resultof(command) local handle=io.popen(command,"r") - if handle then - local result=handle:read("*all") or "" - handle:close() - return result - else - return "" - end + return handle and handle:read("*all") or "" end if not io.fileseparator then if find(os.getenv("PATH"),";") then @@ -2696,11 +2630,10 @@ if not os.times then } end end -local gettimeofday=os.gettimeofday or os.clock -os.gettimeofday=gettimeofday -local startuptime=gettimeofday() +os.gettimeofday=os.gettimeofday or os.clock +local startuptime=os.gettimeofday() function os.runtime() - return gettimeofday()-startuptime + return os.gettimeofday()-startuptime end os.resolvers=os.resolvers or {} local resolvers=os.resolvers @@ -2833,38 +2766,26 @@ function os.timezone(delta) end local timeformat=format("%%s%s",os.timezone(true)) local dateformat="!%Y-%m-%d %H:%M:%S" -local lasttime=nil -local lastdate=nil function os.fulltime(t,default) - t=t and tonumber(t) or 0 + t=tonumber(t) or 0 if t>0 then elseif default then return default else - t=time() - end - if t~=lasttime then - lasttime=t - lastdate=format(timeformat,date(dateformat)) + t=nil end - return lastdate + return format(timeformat,date(dateformat,t)) end local dateformat="%Y-%m-%d %H:%M:%S" -local lasttime=nil -local lastdate=nil function os.localtime(t,default) - t=t and tonumber(t) or 0 + t=tonumber(t) or 0 if t>0 then elseif default then return default else - t=time() - end - if t~=lasttime then - lasttime=t - lastdate=date(dateformat,t) + t=nil end - return lastdate + return date(dateformat,t) end function os.converttime(t,default) local t=tonumber(t) @@ -2914,38 +2835,6 @@ if not os.sleep then socket.sleep(n) end end -local function isleapyear(year) - return (year%400==0) or ((year%100~=0) and (year%4==0)) -end -os.isleapyear=isleapyear -local days={ 31,28,31,30,31,30,31,31,30,31,30,31 } -local function nofdays(year,month) - if not month then - return isleapyear(year) and 365 or 364 - else - return month==2 and isleapyear(year) and 29 or days[month] - end -end -os.nofdays=nofdays -function os.weekday(day,month,year) - return date("%w",time { year=year,month=month,day=day })+1 -end -function os.validdate(year,month,day) - if month<1 then - month=1 - elseif month>12 then - month=12 - end - if day<1 then - day=1 - else - local max=nofdays(year,month) - if day>max then - day=max - end - end - return year,month,day -end end -- of closure @@ -2954,7 +2843,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-file"] = package.loaded["l-file"] or true --- original size: 18308, stripped down to: 9948 +-- original size: 17777, stripped down to: 9653 if not modules then modules={} end modules ['l-file']={ version=1.001, @@ -3197,24 +3086,17 @@ end function file.joinpath(tab,separator) return tab and concat(tab,separator or io.pathseparator) end -local someslash=S("\\/") local stripper=Cs(P(fwslash)^0/""*reslasher) -local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon +local isnetwork=fwslash*fwslash*(1-fwslash)+(1-fwslash-colon)^1*colon local isroot=fwslash^1*-1 local hasroot=fwslash^1 -local reslasher=lpeg.replacer(S("\\/"),"/") local deslasher=lpeg.replacer(S("\\/")^1,"/") function file.join(...) local lst={... } local one=lst[1] if lpegmatch(isnetwork,one) then - local one=lpegmatch(reslasher,one) local two=lpegmatch(deslasher,concat(lst,"/",2)) - if lpegmatch(hasroot,two) then - return one..two - else - return one.."/"..two - end + return one.."/"..two elseif lpegmatch(isroot,one) then local two=lpegmatch(deslasher,concat(lst,"/",2)) if lpegmatch(hasroot,two) then @@ -3231,9 +3113,7 @@ end local drivespec=R("az","AZ")^1*colon local anchors=fwslash+drivespec local untouched=periods+(1-period)^1*P(-1) -local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0) -local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//") -local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) +local splitstarter=(Cs(drivespec*(bwslash/"/"+fwslash)^0)+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) local absolute=fwslash function file.collapsepath(str,anchor) if not str then @@ -3481,7 +3361,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-url"] = package.loaded["l-url"] or true --- original size: 11993, stripped down to: 5584 +-- original size: 11806, stripped down to: 5417 if not modules then modules={} end modules ['l-url']={ version=1.001, @@ -3532,14 +3412,9 @@ setmetatable(escapes,{ __index=function(t,k) end }) local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_")^1+P(1)/escapes)^0) local unescaper=Cs((escapedchar+1)^0) -local getcleaner=Cs((P("+++")/"%%2B"+P("+")/"%%20"+P(1))^1) lpegpatterns.urlunescaped=escapedchar lpegpatterns.urlescaper=escaper lpegpatterns.urlunescaper=unescaper -lpegpatterns.urlgetcleaner=getcleaner -function url.unescapeget(str) - return lpegmatch(getcleaner,str) -end local function split(str) return (type(str)=="string" and lpegmatch(parser,str)) or str end @@ -3692,7 +3567,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-dir"] = package.loaded["l-dir"] or true --- original size: 14229, stripped down to: 8740 +-- original size: 13738, stripped down to: 8560 if not modules then modules={} end modules ['l-dir']={ version=1.001, @@ -3715,7 +3590,6 @@ local isdir=lfs.isdir local isfile=lfs.isfile local currentdir=lfs.currentdir local chdir=lfs.chdir -local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") if not isdir then function isdir(name) local a=attributes(name) @@ -3787,21 +3661,11 @@ local function collectpattern(path,patt,recurse,result) return result end dir.collectpattern=collectpattern -local separator -if onwindows then - local slash=S("/\\")/"/" - pattern=Ct { - [1]=(Cs(P(".")+slash^1)+Cs(R("az","AZ")*P(":")*slash^0)+Cc("./"))*V(2)*V(3), - [2]=Cs(((1-S("*?/\\"))^0*slash)^0), - [3]=Cs(P(1)^0) - } -else - pattern=Ct { - [1]=(C(P(".")+P("/")^1)+Cc("./"))*V(2)*V(3), - [2]=C(((1-S("*?/"))^0*P("/"))^0), - [3]=C(P(1)^0) - } -end +local pattern=Ct { + [1]=(C(P(".")+P("/")^1)+C(R("az","AZ")*P(":")*P("/")^0)+Cc("./"))*V(2)*V(3), + [2]=C(((1-S("*?/"))^0*P("/"))^0), + [3]=C(P(1)^0) +} local filter=Cs (( P("**")/".*"+P("*")/"[^/]*"+P("?")/"[^/]"+P(".")/"%%."+P("+")/"%%+"+P("-")/"%%-"+P(1) )^0 ) @@ -3885,6 +3749,7 @@ function dir.ls(pattern) return concat(glob(pattern),"\n") end local make_indeed=true +local onwindows=os.type=="windows" or find(os.getenv("PATH"),";") if onwindows then function dir.mkdirs(...) local str,pth="","" @@ -3897,8 +3762,9 @@ if onwindows then str=str.."/"..s end end + local first,middle,last local drive=false - local first,middle,last=match(str,"^(//)(//*)(.*)$") + first,middle,last=match(str,"^(//)(//*)(.*)$") if first then else first,last=match(str,"^(//)/*(.-)$") @@ -4059,7 +3925,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-boolean"] = package.loaded["l-boolean"] or true --- original size: 1809, stripped down to: 1527 +-- original size: 1781, stripped down to: 1503 if not modules then modules={} end modules ['l-boolean']={ version=1.001, @@ -4115,9 +3981,9 @@ function string.booleanstring(str) end function string.is_boolean(str,default) if type(str)=="string" then - if str=="true" or str=="yes" or str=="on" or str=="t" or str=="1" then + if str=="true" or str=="yes" or str=="on" or str=="t" then return true - elseif str=="false" or str=="no" or str=="off" or str=="f" or str=="0" then + elseif str=="false" or str=="no" or str=="off" or str=="f" then return false end end @@ -4131,7 +3997,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-unicode"] = package.loaded["l-unicode"] or true --- original size: 33066, stripped down to: 14607 +-- original size: 26810, stripped down to: 11943 if not modules then modules={} end modules ['l-unicode']={ version=1.001, @@ -4144,7 +4010,7 @@ utf=utf or (unicode and unicode.utf8) or {} utf.characters=utf.characters or string.utfcharacters utf.values=utf.values or string.utfvalues local type=type -local char,byte,format,sub,gmatch=string.char,string.byte,string.format,string.sub,string.gmatch +local char,byte,format,sub=string.char,string.byte,string.format,string.sub local concat=table.concat local P,C,R,Cs,Ct,Cmt,Cc,Carg,Cp=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Ct,lpeg.Cmt,lpeg.Cc,lpeg.Carg,lpeg.Cp local lpegmatch,patterns=lpeg.match,lpeg.patterns @@ -4154,7 +4020,6 @@ local replacer=lpeg.replacer local utfvalues=utf.values local utfgmatch=utf.gmatch local p_utftype=patterns.utftype -local p_utfstricttype=patterns.utfstricttype local p_utfoffset=patterns.utfoffset local p_utf8char=patterns.utf8char local p_utf8byte=patterns.utf8byte @@ -4411,181 +4276,112 @@ function utf.magic(f) end return lpegmatch(p_utftype,str) end -local utf16_to_utf8_be,utf16_to_utf8_le -local utf32_to_utf8_be,utf32_to_utf8_le -local utf_16_be_linesplitter=patterns.utfbom_16_be^-1*lpeg.tsplitat(patterns.utf_16_be_nl) -local utf_16_le_linesplitter=patterns.utfbom_16_le^-1*lpeg.tsplitat(patterns.utf_16_le_nl) -if bytepairs then - utf16_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in bytepairs(t[i]) do - if right then - local now=256*left+right - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end - end - end - t[i]=concat(result,"",1,r) - end - return t +local function utf16_to_utf8_be(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) end - utf16_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in bytepairs(t[i]) do - if right then - local now=256*right+left - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end - end - end - t[i]=concat(result,"",1,r) - end - return t - end - utf32_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utflinesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,-1 - for a,b in bytepairs(t[i]) do - if a and b then - if more<0 then - more=256*256*256*a+256*256*b - else - r=r+1 - result[t]=utfchar(more+256*a+b) - more=-1 - end + local result={} + for i=1,#t do + local r,more=0,0 + for left,right in bytepairs(t[i]) do + if right then + local now=256*left+right + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now else - break + r=r+1 + result[r]=utfchar(now) end end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf32_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utflinesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,-1 - for a,b in bytepairs(t[i]) do - if a and b then - if more<0 then - more=256*b+a - else - r=r+1 - result[t]=utfchar(more+256*256*256*b+256*256*a) - more=-1 - end + return t +end +local function utf16_to_utf8_le(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,0 + for left,right in bytepairs(t[i]) do + if right then + local now=256*right+left + if more>0 then + now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 + more=0 + r=r+1 + result[r]=utfchar(now) + elseif now>=0xD800 and now<=0xDBFF then + more=now else - break + r=r+1 + result[r]=utfchar(now) end end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end -else - utf16_to_utf8_be=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_be_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in gmatch(t[i],"(.)(.)") do - if left=="\000" then + return t +end +local function utf32_to_utf8_be(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,-1 + for a,b in bytepairs(t[i]) do + if a and b then + if more<0 then + more=256*256*256*a+256*256*b + else r=r+1 - result[r]=utfchar(byte(right)) - elseif right then - local now=256*byte(left)+byte(right) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end + result[t]=utfchar(more+256*a+b) + more=-1 end + else + break end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf16_to_utf8_le=function(t) - if type(t)=="string" then - t=lpegmatch(utf_16_le_linesplitter,t) - end - local result={} - for i=1,#t do - local r,more=0,0 - for left,right in gmatch(t[i],"(.)(.)") do - if right=="\000" then + return t +end +local function utf32_to_utf8_le(t) + if type(t)=="string" then + t=lpegmatch(utflinesplitter,t) + end + local result={} + for i=1,#t do + local r,more=0,-1 + for a,b in bytepairs(t[i]) do + if a and b then + if more<0 then + more=256*b+a + else r=r+1 - result[r]=utfchar(byte(left)) - elseif right then - local now=256*byte(right)+byte(left) - if more>0 then - now=(more-0xD800)*0x400+(now-0xDC00)+0x10000 - more=0 - r=r+1 - result[r]=utfchar(now) - elseif now>=0xD800 and now<=0xDBFF then - more=now - else - r=r+1 - result[r]=utfchar(now) - end + result[t]=utfchar(more+256*256*256*b+256*256*a) + more=-1 end + else + break end - t[i]=concat(result,"",1,r) end - return t + t[i]=concat(result,"",1,r) end - utf32_to_utf8_le=function() return {} end - utf32_to_utf8_be=function() return {} end + return t end -utf.utf16_to_utf8_le=utf16_to_utf8_le -utf.utf16_to_utf8_be=utf16_to_utf8_be -utf.utf32_to_utf8_le=utf32_to_utf8_le utf.utf32_to_utf8_be=utf32_to_utf8_be +utf.utf32_to_utf8_le=utf32_to_utf8_le +utf.utf16_to_utf8_be=utf16_to_utf8_be +utf.utf16_to_utf8_le=utf16_to_utf8_le function utf.utf8_to_utf8(t) return type(t)=="string" and lpegmatch(utflinesplitter,t) or t end @@ -4617,17 +4413,11 @@ local function big(c) end local _,l_remap=utf.remapper(little) local _,b_remap=utf.remapper(big) -function utf.utf8_to_utf16_be(str) - return char(254,255)..lpegmatch(b_remap,str) -end -function utf.utf8_to_utf16_le(str) - return char(255,254)..lpegmatch(l_remap,str) -end function utf.utf8_to_utf16(str,littleendian) if littleendian then - return utf.utf8_to_utf16_le(str) + return char(255,254)..lpegmatch(l_remap,str) else - return utf.utf8_to_utf16_be(str) + return char(254,255)..lpegmatch(b_remap,str) end end local pattern=Cs ( @@ -4642,21 +4432,6 @@ end function utf.xstring(s) return format("0x%05X",type(s)=="number" and s or utfbyte(s)) end -function utf.toeight(str) - if not str then - return nil - end - local utftype=lpegmatch(p_utfstricttype,str) - if utftype=="utf-8" then - return sub(str,4) - elseif utftype=="utf-16-le" then - return utf16_to_utf8_le(str) - elseif utftype=="utf-16-be" then - return utf16_to_utf8_ne(str) - else - return str - end -end local p_nany=p_utf8char/"" if utfgmatch then function utf.count(str,what) @@ -4759,7 +4534,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-str"] = package.loaded["util-str"] or true --- original size: 25122, stripped down to: 13877 +-- original size: 22834, stripped down to: 12570 if not modules then modules={} end modules ['util-str']={ version=1.001, @@ -4921,7 +4696,6 @@ local tracedchar = string.tracedchar local autosingle = string.autosingle local autodouble = string.autodouble local sequenced = table.sequenced -local formattednumber = number.formatted ]] local template=[[ %s @@ -4936,7 +4710,7 @@ setmetatable(arguments,{ __index=function(t,k) end }) local prefix_any=C((S("+- .")+R("09"))^0) -local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0) +local prefix_tab=C((1-R("az","AZ","09","%%"))^0) local format_s=function(f) n=n+1 if f and f~="" then @@ -4966,7 +4740,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("format('%%i',a%s)",n) + return format("a%s",n) end end local format_d=format_i @@ -5118,39 +4892,6 @@ end local format_W=function(f) return format("nspaces[%s]",tonumber(f) or 0) end -local digit=patterns.digit -local period=patterns.period -local three=digit*digit*digit -local splitter=Cs ( - (((1-(three^1*period))^1+C(three))*(Carg(1)*three)^1+C((1-period)^1))*(P(1)/""*Carg(2))*C(2) -) -patterns.formattednumber=splitter -function number.formatted(n,sep1,sep2) - local s=type(s)=="string" and n or format("%0.2f",n) - if sep1==true then - return lpegmatch(splitter,s,1,".",",") - elseif sep1=="." then - return lpegmatch(splitter,s,1,sep1,sep2 or ",") - elseif sep1=="," then - return lpegmatch(splitter,s,1,sep1,sep2 or ".") - else - return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") - end -end -local format_m=function(f) - n=n+1 - if not f or f=="" then - f="," - end - return format([[formattednumber(a%s,%q,".")]],n,f) -end -local format_M=function(f) - n=n+1 - if not f or f=="" then - f="." - end - return format([[formattednumber(a%s,%q,",")]],n,f) -end local format_rest=function(s) return format("%q",s) end @@ -5188,8 +4929,7 @@ local builder=Cs { "start", +V("w") +V("W") +V("a") -+V("A") -+V("m")+V("M") ++V("A") +V("*") )+V("*") )*(P(-1)+Carg(1)) @@ -5220,16 +4960,14 @@ local builder=Cs { "start", ["b"]=(prefix_any*P("b"))/format_b, ["t"]=(prefix_tab*P("t"))/format_t, ["T"]=(prefix_tab*P("T"))/format_T, - ["l"]=(prefix_any*P("l"))/format_l, - ["L"]=(prefix_any*P("L"))/format_L, + ["l"]=(prefix_tab*P("l"))/format_l, + ["L"]=(prefix_tab*P("L"))/format_L, ["I"]=(prefix_any*P("I"))/format_I, ["w"]=(prefix_any*P("w"))/format_w, ["W"]=(prefix_any*P("W"))/format_W, - ["m"]=(prefix_tab*P("m"))/format_m, - ["M"]=(prefix_tab*P("M"))/format_M, ["a"]=(prefix_any*P("a"))/format_a, ["A"]=(prefix_any*P("A"))/format_A, - ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, + ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%%%")^1)/format_rest, ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local direct=Cs ( @@ -5275,13 +5013,10 @@ local function add(t,name,template,preamble) end end strings.formatters.add=add -patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) -patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) -patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) -patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"')) +lpeg.patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) +lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]]) add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]]) -add(formatters,"lua",[[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]]) end -- of closure @@ -5290,7 +5025,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 23952, stripped down to: 16092 +-- original size: 14510, stripped down to: 8531 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -5302,14 +5037,13 @@ if not modules then modules={} end modules ['util-tab']={ utilities=utilities or {} utilities.tables=utilities.tables or {} local tables=utilities.tables -local format,gmatch,gsub,sub=string.format,string.gmatch,string.gsub,string.sub +local format,gmatch,gsub=string.format,string.gmatch,string.gsub local concat,insert,remove=table.concat,table.insert,table.remove local setmetatable,getmetatable,tonumber,tostring=setmetatable,getmetatable,tonumber,tostring local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc -local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs +local serialize,sortedkeys,sortedpairs=table.serialize,table.sortedkeys,table.sortedpairs local formatters=string.formatters -local utftoeight=utf.toeight local splitter=lpeg.tsplitat(".") function tables.definetable(target,nofirst,nolast) local composed,shortcut,t=nil,nil,{} @@ -5513,78 +5247,47 @@ function tables.encapsulate(core,capsule,protect) } ) end end -local f_hashed_string=formatters["[%q]=%q,"] -local f_hashed_number=formatters["[%q]=%s,"] -local f_hashed_boolean=formatters["[%q]=%l,"] -local f_hashed_table=formatters["[%q]="] -local f_indexed_string=formatters["[%s]=%q,"] -local f_indexed_number=formatters["[%s]=%s,"] -local f_indexed_boolean=formatters["[%s]=%l,"] -local f_indexed_table=formatters["[%s]="] -local f_ordered_string=formatters["%q,"] -local f_ordered_number=formatters["%s,"] -local f_ordered_boolean=formatters["%l,"] -function table.fastserialize(t,prefix) - local r={ prefix or "return" } - local m=1 - local function fastserialize(t,outer) - local n=#t - m=m+1 - r[m]="{" - if n>0 then - for i=0,n do - local v=t[i] - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_ordered_string(v) - elseif tv=="number" then - m=m+1 r[m]=f_ordered_number(v) - elseif tv=="table" then - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_ordered_boolean(v) - end +local function fastserialize(t,r,outer) + r[#r+1]="{" + local n=#t + if n>0 then + for i=1,n do + local v=t[i] + local tv=type(v) + if tv=="string" then + r[#r+1]=formatters["%q,"](v) + elseif tv=="number" then + r[#r+1]=formatters["%s,"](v) + elseif tv=="table" then + fastserialize(v,r) + elseif tv=="boolean" then + r[#r+1]=formatters["%S,"](v) end end + else for k,v in next,t do - local tk=type(k) - if tk=="number" then - if k>n or k<0 then - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_indexed_string(k,v) - elseif tv=="number" then - m=m+1 r[m]=f_indexed_number(k,v) - elseif tv=="table" then - m=m+1 r[m]=f_indexed_table(k) - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_indexed_boolean(k,v) - end - end - else - local tv=type(v) - if tv=="string" then - m=m+1 r[m]=f_hashed_string(k,v) - elseif tv=="number" then - m=m+1 r[m]=f_hashed_number(k,v) - elseif tv=="table" then - m=m+1 r[m]=f_hashed_table(k) - fastserialize(v) - elseif tv=="boolean" then - m=m+1 r[m]=f_hashed_boolean(k,v) - end + local tv=type(v) + if tv=="string" then + r[#r+1]=formatters["[%q]=%q,"](k,v) + elseif tv=="number" then + r[#r+1]=formatters["[%q]=%s,"](k,v) + elseif tv=="table" then + r[#r+1]=formatters["[%q]="](k) + fastserialize(v,r) + elseif tv=="boolean" then + r[#r+1]=formatters["[%q]=%S,"](k,v) end end - m=m+1 - if outer then - r[m]="}" - else - r[m]="}," - end - return r end - return concat(fastserialize(t,true)) + if outer then + r[#r+1]="}" + else + r[#r+1]="}," + end + return r +end +function table.fastserialize(t,prefix) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) if not str or str=="" then @@ -5604,7 +5307,6 @@ function table.load(filename,loader) if filename then local t=(loader or io.loaddata)(filename) if t and t~="" then - local t=utftoeight(t) t=load(t) if type(t)=="function" then t=t() @@ -5616,12 +5318,9 @@ function table.load(filename,loader) end end function table.save(filename,t,n,...) - io.savedata(filename,table.serialize(t,n==nil and true or n,...)) + io.savedata(filename,serialize(t,n==nil and true or n,...)) end -local f_key_value=formatters["%s=%q"] -local f_add_table=formatters[" {%t},\n"] -local f_return_table=formatters["return {\n%t}"] -local function slowdrop(t) +local function slowdrop(t) local r={} local l={} for i=1,#t do @@ -5629,25 +5328,23 @@ local function slowdrop(t) local j=0 for k,v in next,ti do j=j+1 - l[j]=f_key_value(k,v) + l[j]=formatters["%s=%q"](k,v) end - r[i]=f_add_table(l) + r[i]=formatters[" {%t},\n"](l) end - return f_return_table(r) + return formatters["return {\n%st}"](r) end local function fastdrop(t) local r={ "return {\n" } - local m=1 for i=1,#t do local ti=t[i] - m=m+1 r[m]=" {" + r[#r+1]=" {" for k,v in next,ti do - m=m+1 r[m]=f_key_value(k,v) + r[#r+1]=formatters["%s=%q"](k,v) end - m=m+1 r[m]="},\n" + r[#r+1]="},\n" end - m=m+1 - r[m]="}" + r[#r+1]="}" return concat(r) end function table.drop(t,slow) @@ -5682,216 +5379,6 @@ function table.twowaymapper(t) setmetatable(t,selfmapper) return t end -local f_start_key_idx=formatters["%w{"] -local f_start_key_num=formatters["%w[%s]={"] -local f_start_key_str=formatters["%w[%q]={"] -local f_start_key_boo=formatters["%w[%l]={"] -local f_start_key_nop=formatters["%w{"] -local f_stop=formatters["%w},"] -local f_key_num_value_num=formatters["%w[%s]=%s,"] -local f_key_str_value_num=formatters["%w[%q]=%s,"] -local f_key_boo_value_num=formatters["%w[%l]=%s,"] -local f_key_num_value_str=formatters["%w[%s]=%q,"] -local f_key_str_value_str=formatters["%w[%q]=%q,"] -local f_key_boo_value_str=formatters["%w[%l]=%q,"] -local f_key_num_value_boo=formatters["%w[%s]=%l,"] -local f_key_str_value_boo=formatters["%w[%q]=%l,"] -local f_key_boo_value_boo=formatters["%w[%l]=%l,"] -local f_key_num_value_not=formatters["%w[%s]={},"] -local f_key_str_value_not=formatters["%w[%q]={},"] -local f_key_boo_value_not=formatters["%w[%l]={},"] -local f_key_num_value_seq=formatters["%w[%s]={ %, t },"] -local f_key_str_value_seq=formatters["%w[%q]={ %, t },"] -local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"] -local f_val_num=formatters["%w%s,"] -local f_val_str=formatters["%w%q,"] -local f_val_boo=formatters["%w%l,"] -local f_val_not=formatters["%w{},"] -local f_val_seq=formatters["%w{ %, t },"] -local f_table_return=formatters["return {"] -local f_table_name=formatters["%s={"] -local f_table_direct=formatters["{"] -local f_table_entry=formatters["[%q]={"] -local f_table_finish=formatters["}"] -local spaces=utilities.strings.newrepeater(" ") -local serialize=table.serialize -function table.serialize(root,name,specification) - if type(specification)=="table" then - return serialize(root,name,specification) - end - local t - local n=1 - local function simple_table(t) - if #t>0 then - local n=0 - for _,v in next,t do - n=n+1 - if type(v)=="table" then - return nil - end - end - if n==#t then - local tt={} - local nt=0 - for i=1,#t do - local v=t[i] - local tv=type(v) - nt=nt+1 - if tv=="number" then - tt[nt]=v - elseif tv=="string" then - tt[nt]=format("%q",v) - elseif tv=="boolean" then - tt[nt]=v and "true" or "false" - else - return nil - end - end - return tt - end - end - return nil - end - local function do_serialize(root,name,depth,level,indexed) - if level>0 then - n=n+1 - if indexed then - t[n]=f_start_key_idx(depth) - else - local tn=type(name) - if tn=="number" then - t[n]=f_start_key_num(depth,name) - elseif tn=="string" then - t[n]=f_start_key_str(depth,name) - elseif tn=="boolean" then - t[n]=f_start_key_boo(depth,name) - else - t[n]=f_start_key_nop(depth) - end - end - depth=depth+1 - end - if root and next(root) then - local first=nil - local last=0 - last=#root - for k=1,last do - if root[k]==nil then - last=k-1 - break - end - end - if last>0 then - first=1 - end - local sk=sortedkeys(root) - for i=1,#sk do - local k=sk[i] - local v=root[k] - local tv=type(v) - local tk=type(k) - if first and tk=="number" and k>=first and k<=last then - if tv=="number" then - n=n+1 t[n]=f_val_num(depth,v) - elseif tv=="string" then - n=n+1 t[n]=f_val_str(depth,v) - elseif tv=="table" then - if not next(v) then - n=n+1 t[n]=f_val_not(depth) - else - local st=simple_table(v) - if st then - n=n+1 t[n]=f_val_seq(depth,st) - else - do_serialize(v,k,depth,level+1,true) - end - end - elseif tv=="boolean" then - n=n+1 t[n]=f_val_boo(depth,v) - end - elseif tv=="number" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_num(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_num(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_num(depth,k,v) - end - elseif tv=="string" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_str(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_str(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_str(depth,k,v) - end - elseif tv=="table" then - if not next(v) then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_not(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_not(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_not(depth,k,v) - end - else - local st=simple_table(v) - if not st then - do_serialize(v,k,depth,level+1) - elseif tk=="number" then - n=n+1 t[n]=f_key_num_value_seq(depth,k,st) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_seq(depth,k,st) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_seq(depth,k,st) - end - end - elseif tv=="boolean" then - if tk=="number" then - n=n+1 t[n]=f_key_num_value_boo(depth,k,v) - elseif tk=="string" then - n=n+1 t[n]=f_key_str_value_boo(depth,k,v) - elseif tk=="boolean" then - n=n+1 t[n]=f_key_boo_value_boo(depth,k,v) - end - end - end - end - if level>0 then - n=n+1 t[n]=f_stop(depth-1) - end - end - local tname=type(name) - if tname=="string" then - if name=="return" then - t={ f_table_return() } - else - t={ f_table_name(name) } - end - elseif tname=="number" then - t={ f_table_entry(name) } - elseif tname=="boolean" then - if name then - t={ f_table_return() } - else - t={ f_table_direct() } - end - else - t={ f_table_name("t") } - end - if root then - if getmetatable(root) then - local dummy=root._w_h_a_t_e_v_e_r_ - root._w_h_a_t_e_v_e_r_=nil - end - if next(root) then - do_serialize(root,name,1,0) - end - end - n=n+1 - t[n]=f_table_finish() - return concat(t,"\n") -end end -- of closure @@ -5900,7 +5387,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-sto"] = package.loaded["util-sto"] or true --- original size: 4172, stripped down to: 2953 +-- original size: 4432, stripped down to: 3123 if not modules then modules={} end modules ['util-sto']={ version=1.001, @@ -5970,47 +5457,56 @@ end local function f_empty () return "" end local function f_self (t,k) t[k]=k return k end local function f_table (t,k) local v={} t[k]=v return v end -local function f_number(t,k) t[k]=0 return 0 end local function f_ignore() end -local f_index={ - ["empty"]=f_empty, - ["self"]=f_self, - ["table"]=f_table, - ["number"]=f_number, -} -local t_index={ - ["empty"]={ __index=f_empty }, - ["self"]={ __index=f_self }, - ["table"]={ __index=f_table }, - ["number"]={ __index=f_number }, -} +local t_empty={ __index=f_empty } +local t_self={ __index=f_self } +local t_table={ __index=f_table } +local t_ignore={ __newindex=f_ignore } function table.setmetatableindex(t,f) if type(t)~="table" then f,t=t,{} end local m=getmetatable(t) if m then - m.__index=f_index[f] or f + if f=="empty" then + m.__index=f_empty + elseif f=="key" then + m.__index=f_self + elseif f=="table" then + m.__index=f_table + else + m.__index=f + end else - setmetatable(t,t_index[f] or { __index=f }) + if f=="empty" then + setmetatable(t,t_empty) + elseif f=="key" then + setmetatable(t,t_self) + elseif f=="table" then + setmetatable(t,t_table) + else + setmetatable(t,{ __index=f }) + end end return t end -local f_index={ - ["ignore"]=f_ignore, -} -local t_index={ - ["ignore"]={ __newindex=f_ignore }, -} function table.setmetatablenewindex(t,f) if type(t)~="table" then f,t=t,{} end local m=getmetatable(t) if m then - m.__newindex=f_index[f] or f + if f=="ignore" then + m.__newindex=f_ignore + else + m.__newindex=f + end else - setmetatable(t,t_index[f] or { __newindex=f }) + if f=="ignore" then + setmetatable(t,t_ignore) + else + setmetatable(t,{ __newindex=f }) + end end return t end @@ -6047,7 +5543,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 18558, stripped down to: 13323 +-- original size: 17827, stripped down to: 12722 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -6059,9 +5555,8 @@ if not modules then modules={} end modules ['util-prs']={ local lpeg,table,string=lpeg,table,string local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local concat,gmatch,find=table.concat,string.gmatch,string.find +local concat,format,gmatch,find=table.concat,string.format,string.gmatch,string.find local tostring,type,next,rawset=tostring,type,next,rawset -local mod,div=math.mod,math.div utilities=utilities or {} local parsers=utilities.parsers or {} utilities.parsers=parsers @@ -6265,12 +5760,6 @@ function parsers.simple_hash_to_string(h,separator) end return concat(t,separator or ",") end -local str=C((1-whitespace-equal)^1) -local setting=Cf(Carg(1)*(whitespace^0*Cg(str*whitespace^0*(equal*whitespace^0*str+Cc(""))))^1,rawset) -local splitter=setting^1 -function utilities.parsers.options_to_hash(str,target) - return str and lpegmatch(splitter,str,1,target or {}) or {} -end local value=P(lbrace*C((nobrace+nestedbraces)^0)*rbrace)+C(digit^1*lparent*(noparent+nestedparents)^1*rparent)+C((nestedbraces+(1-comma))^1) local pattern_a=spaces*Ct(value*(separator*value)^0) local function repeater(n,str) @@ -6375,7 +5864,7 @@ function parsers.csvsplitter(specification) end whatever=quotedata+whatever end - local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 ) + local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r"))^0 ) return function(data) return lpegmatch(parser,data) end @@ -6483,7 +5972,7 @@ end local function fetch(t,name) return t[name] or {} end -local function process(result,more) +function process(result,more) for k,v in next,more do result[k]=v end @@ -6495,18 +5984,6 @@ local merge=Cf(parser,process) function utilities.parsers.mergehashes(hash,list) return lpegmatch(merge,list,1,hash) end -function utilities.parsers.runtime(time) - if not time then - time=os.runtime() - end - local days=div(time,24*60*60) - time=mod(time,24*60*60) - local hours=div(time,60*60) - time=mod(time,60*60) - local minutes=div(time,60) - local seconds=mod(time,60) - return days,hours,minutes,seconds -end end -- of closure @@ -6908,7 +6385,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-log"] = package.loaded["trac-log"] or true --- original size: 25391, stripped down to: 16561 +-- original size: 21914, stripped down to: 14287 if not modules then modules={} end modules ['trac-log']={ version=1.001, @@ -6921,11 +6398,11 @@ local write_nl,write=texio and texio.write_nl or print,texio and texio.write or local format,gmatch,find=string.format,string.gmatch,string.find local concat,insert,remove=table.concat,table.insert,table.remove local topattern=string.topattern +local texcount=tex and tex.count local next,type,select=next,type,select local utfchar=utf.char local setmetatableindex=table.setmetatableindex local formatters=string.formatters -local texgetcount=tex and tex.getcount logs=logs or {} local logs=logs local moreinfo=[[ @@ -6946,7 +6423,7 @@ utilities.strings.formatters.add ( local function ignore() end setmetatableindex(logs,function(t,k) t[k]=ignore;return ignore end) local report,subreport,status,settarget,setformats,settranslations -local direct,subdirect,writer,pushtarget,poptarget,setlogfile,settimedlog,setprocessor,setformatters +local direct,subdirect,writer,pushtarget,poptarget if tex and (tex.jobname or tex.formatname) then local valueiskey={ __index=function(t,k) t[k]=k return k end } local target="term and log" @@ -6959,67 +6436,67 @@ if tex and (tex.jobname or tex.formatname) then newline=function() write_nl(target,"\n") end - local report_yes=formatters["%-15s > %s\n"] - local report_nop=formatters["%-15s >\n"] + local f_one=formatters["%-15s > %s\n"] + local f_two=formatters["%-15s >\n"] report=function(a,b,c,...) if c then - write_nl(target,report_yes(translations[a],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],formatters[formats[b]](c,...))) elseif b then - write_nl(target,report_yes(translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,report_nop(translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end end - local direct_yes=formatters["%-15s > %s"] - local direct_nop=formatters["%-15s >"] + local f_one=formatters["%-15s > %s"] + local f_two=formatters["%-15s >"] direct=function(a,b,c,...) if c then - return direct_yes(translations[a],formatters[formats[b]](c,...)) + return f_one(translations[a],formatters[formats[b]](c,...)) elseif b then - return direct_yes(translations[a],formats[b]) + return f_one(translations[a],formats[b]) elseif a then - return direct_nop(translations[a]) + return f_two(translations[a]) else return "" end end - local subreport_yes=formatters["%-15s > %s > %s\n"] - local subreport_nop=formatters["%-15s > %s >\n"] + local f_one=formatters["%-15s > %s > %s\n"] + local f_two=formatters["%-15s > %s >\n"] subreport=function(a,s,b,c,...) if c then - write_nl(target,subreport_yes(translations[a],translations[s],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],translations[s],formatters[formats[b]](c,...))) elseif b then - write_nl(target,subreport_yes(translations[a],translations[s],formats[b])) + write_nl(target,f_one(translations[a],translations[s],formats[b])) elseif a then - write_nl(target,subreport_nop(translations[a],translations[s])) + write_nl(target,f_two(translations[a],translations[s])) else write_nl(target,"\n") end end - local subdirect_yes=formatters["%-15s > %s > %s"] - local subdirect_nop=formatters["%-15s > %s >"] + local f_one=formatters["%-15s > %s > %s"] + local f_two=formatters["%-15s > %s >"] subdirect=function(a,s,b,c,...) if c then - return subdirect_yes(translations[a],translations[s],formatters[formats[b]](c,...)) + return f_one(translations[a],translations[s],formatters[formats[b]](c,...)) elseif b then - return subdirect_yes(translations[a],translations[s],formats[b]) + return f_one(translations[a],translations[s],formats[b]) elseif a then - return subdirect_nop(translations[a],translations[s]) + return f_two(translations[a],translations[s]) else return "" end end - local status_yes=formatters["%-15s : %s\n"] - local status_nop=formatters["%-15s :\n"] + local f_one=formatters["%-15s : %s\n"] + local f_two=formatters["%-15s :\n"] status=function(a,b,c,...) if c then - write_nl(target,status_yes(translations[a],formatters[formats[b]](c,...))) + write_nl(target,f_one(translations[a],formatters[formats[b]](c,...))) elseif b then - write_nl(target,status_yes(translations[a],formats[b])) + write_nl(target,f_one(translations[a],formats[b])) elseif a then - write_nl(target,status_nop(translations[a])) + write_nl(target,f_two(translations[a])) else write_nl(target,"\n") end @@ -7056,69 +6533,47 @@ if tex and (tex.jobname or tex.formatname) then settranslations=function(t) translations=t end - setprocessor=function(f) - local writeline=write_nl - write_nl=function(target,...) - writeline(target,f(...)) - end - end - setformatters=function(f) - report_yes=f.report_yes or report_yes - report_nop=f.report_nop or report_nop - subreport_yes=f.subreport_yes or subreport_yes - subreport_nop=f.subreport_nop or subreport_nop - direct_yes=f.direct_yes or direct_yes - direct_nop=f.direct_nop or direct_nop - subdirect_yes=f.subdirect_yes or subdirect_yes - subdirect_nop=f.subdirect_nop or subdirect_nop - status_yes=f.status_yes or status_yes - status_nop=f.status_nop or status_nop - end - setlogfile=ignore - settimedlog=ignore else logs.flush=ignore - writer=function(s) - write_nl(s) - end + writer=write_nl newline=function() write_nl("\n") end - local report_yes=formatters["%-15s | %s"] - local report_nop=formatters["%-15s |"] + local f_one=formatters["%-15s | %s"] + local f_two=formatters["%-15s |"] report=function(a,b,c,...) if c then - write_nl(report_yes(a,formatters[b](c,...))) + write_nl(f_one(a,formatters[b](c,...))) elseif b then - write_nl(report_yes(a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(report_nop(a)) + write_nl(f_two(a)) else write_nl("") end end - local subreport_yes=formatters["%-15s | %s | %s"] - local subreport_nop=formatters["%-15s | %s |"] + local f_one=formatters["%-15s | %s | %s"] + local f_two=formatters["%-15s | %s |"] subreport=function(a,sub,b,c,...) if c then - write_nl(subreport_yes(a,sub,formatters[b](c,...))) + write_nl(f_one(a,sub,formatters[b](c,...))) elseif b then - write_nl(subreport_yes(a,sub,b)) + write_nl(f_one(a,sub,b)) elseif a then - write_nl(subreport_nop(a,sub)) + write_nl(f_two(a,sub)) else write_nl("") end end - local status_yes=formatters["%-15s : %s\n"] - local status_nop=formatters["%-15s :\n"] + local f_one=formatters["%-15s : %s\n"] + local f_two=formatters["%-15s :\n"] status=function(a,b,c,...) if c then - write_nl(status_yes(a,formatters[b](c,...))) + write_nl(f_one(a,formatters[b](c,...))) elseif b then - write_nl(status_yes(a,b)) + write_nl(f_one(a,b)) elseif a then - write_nl(status_nop(a)) + write_nl(f_two(a)) else write_nl("\n") end @@ -7130,49 +6585,6 @@ else poptarget=ignore setformats=ignore settranslations=ignore - setprocessor=function(f) - local writeline=write_nl - write_nl=function(s) - writeline(f(s)) - end - end - setformatters=function(f) - report_yes=f.report_yes or report_yes - report_nop=f.report_nop or report_nop - subreport_yes=f.subreport_yes or subreport_yes - subreport_nop=f.subreport_nop or subreport_nop - status_yes=f.status_yes or status_yes - status_nop=f.status_nop or status_nop - end - setlogfile=function(name,keepopen) - if name and name~="" then - local localtime=os.localtime - local writeline=write_nl - if keepopen then - local f=io.open(name,"ab") - write_nl=function(s) - writeline(s) - f:write(localtime()," | ",s,"\n") - end - else - write_nl=function(s) - writeline(s) - local f=io.open(name,"ab") - f:write(localtime()," | ",s,"\n") - f:close() - end - end - end - setlogfile=ignore - end - settimedlog=function() - local localtime=os.localtime - local writeline=write_nl - write_nl=function(s) - writeline(localtime().." | "..s) - end - settimedlog=ignore - end end logs.report=report logs.subreport=subreport @@ -7182,10 +6594,6 @@ logs.pushtarget=pushtarget logs.poptarget=poptarget logs.setformats=setformats logs.settranslations=settranslations -logs.setlogfile=setlogfile -logs.settimedlog=settimedlog -logs.setprocessor=setprocessor -logs.setformatters=setformatters logs.direct=direct logs.subdirect=subdirect logs.writer=writer @@ -7336,9 +6744,7 @@ end) local report_pages=logs.reporter("pages") local real,user,sub function logs.start_page_number() - real=texgetcount("realpageno") - user=texgetcount("userpageno") - sub=texgetcount("subpageno") + real,user,sub=texcount.realpageno,texcount.userpageno,texcount.subpageno end local timing=false local starttime=nil @@ -7543,7 +6949,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 6295, stripped down to: 4966 +-- original size: 5678, stripped down to: 4448 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -7552,19 +6958,16 @@ if not modules then modules={} end modules ['trac-inf']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,tonumber,select=type,tonumber,select +local type,tonumber=type,tonumber local format,lower=string.format,string.lower local concat=table.concat local clock=os.gettimeofday or os.clock -local setmetatableindex=table.setmetatableindex -local serialize=table.serialize -local formatters=string.formatters statistics=statistics or {} local statistics=statistics statistics.enable=true statistics.threshold=0.01 local statusinfo,n,registered,timers={},0,{},{} -setmetatableindex(timers,function(t,k) +table.setmetatableindex(timers,function(t,k) local v={ timing=0,loadtime=0 } t[k]=v return v @@ -7693,16 +7096,6 @@ function statistics.timed(action) stoptiming("run") report("total runtime: %s",elapsedtime("run")) end -function statistics.tracefunction(base,tag,...) - for i=1,select("#",...) do - local name=select(i,...) - local stat={} - local func=base[name] - setmetatableindex(stat,function(t,k) t[k]=0 return 0 end) - base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end - statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end) - end -end commands=commands or {} function commands.resettimer(name) resettiming(name or "whatever") @@ -7865,7 +7258,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-lua"] = package.loaded["util-lua"] or true --- original size: 4982, stripped down to: 3511 +-- original size: 12575, stripped down to: 8700 if not modules then modules={} end modules ['util-lua']={ version=1.001, @@ -7900,92 +7293,251 @@ luautilities.suffixes={ tua="tua", tuc="tuc", } -local function register(name) - if tracestripping then - report_lua("stripped bytecode from %a",name or "unknown") +if jit or status.luatex_version>=74 then + local function register(name) + if tracestripping then + report_lua("stripped bytecode from %a",name or "unknown") + end + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 + end + local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + if code and code~="" then + code=load(code) + if code then + code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code~="" then + register(name) + io.savedata(lucfile,code) + return true,0 + end + else + report_lua("fatal error %a in file %a",1,luafile) + end + else + report_lua("fatal error %a in file %a",2,luafile) + end + return false,0 end - strippedchunks[#strippedchunks+1]=name - luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 -end -local function stupidcompile(luafile,lucfile,strip) - local code=io.loaddata(luafile) - if code and code~="" then - code=load(code) + function luautilities.loadedluacode(fullname,forcestrip,name) + name=name or fullname + local code=environment.loadpreprocessedfile and environment.loadpreprocessedfile(fullname) or loadfile(fullname) if code then - code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) - if code and code~="" then + code() + end + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) + end + if forcestrip or luautilities.alwaysstripcode then register(name) - io.savedata(lucfile,code) - return true,0 + return load(dump(code,true)),0 + else + return code,0 end + elseif luautilities.alwaysstripcode then + register(name) + return load(dump(code,true)),0 else - report_lua("fatal error %a in file %a",1,luafile) + return code,0 end - else - report_lua("fatal error %a in file %a",2,luafile) end - return false,0 -end -function luautilities.loadedluacode(fullname,forcestrip,name) - name=name or fullname - local code,message - if environment.loadpreprocessedfile then - code,message=environment.loadpreprocessedfile(fullname) - else - code,message=loadfile(fullname) + function luautilities.strippedloadstring(code,forcestrip,name) + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + code=load(code) + if not code then + report_lua("fatal error %a in file %a",3,name) + end + register(name) + code=dump(code,true) + end + return load(code),0 end - if code then - code() + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=stupidcompile(luafile,lucfile,strip~=false) + if done then + report_lua("dumping %a into %a stripped",luafile,lucfile) + if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + report_lua("removing %a",luafile) + os.remove(luafile) + end + end + return done + end + function luautilities.loadstripped(...) + local l=load(...) + if l then + return load(dump(l,true)) + end + end +else + local function register(name,before,after) + local delta=before-after + if tracestripping then + report_lua("bytecodes stripped from %a, # before %s, # after %s, delta %s",name,before,after,delta) + end + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 + luautilities.nofstrippedbytes=luautilities.nofstrippedbytes+delta + return delta + end + local strip_code_pc + if _MAJORVERSION==5 and _MINORVERSION==1 then + strip_code_pc=function(dump,name) + local before=#dump + local version,format,endian,int,size,ins,num=byte(dump,5,11) + local subint + if endian==1 then + subint=function(dump,i,l) + local val=0 + for n=l,1,-1 do + val=val*256+byte(dump,i+n-1) + end + return val,i+l + end + else + subint=function(dump,i,l) + local val=0 + for n=1,l,1 do + val=val*256+byte(dump,i+n-1) + end + return val,i+l + end + end + local strip_function + strip_function=function(dump) + local count,offset=subint(dump,1,size) + local stripped,dirty=rep("\0",size),offset+count + offset=offset+count+int*2+4 + offset=offset+int+subint(dump,offset,int)*ins + count,offset=subint(dump,offset,int) + for n=1,count do + local t + t,offset=subint(dump,offset,1) + if t==1 then + offset=offset+1 + elseif t==4 then + offset=offset+size+subint(dump,offset,size) + elseif t==3 then + offset=offset+num + end + end + count,offset=subint(dump,offset,int) + stripped=stripped..sub(dump,dirty,offset-1) + for n=1,count do + local proto,off=strip_function(sub(dump,offset,-1)) + stripped,offset=stripped..proto,offset+off-1 + end + offset=offset+subint(dump,offset,int)*int+int + count,offset=subint(dump,offset,int) + for n=1,count do + offset=offset+subint(dump,offset,size)+size+int*2 + end + count,offset=subint(dump,offset,int) + for n=1,count do + offset=offset+subint(dump,offset,size)+size + end + stripped=stripped..rep("\0",int*3) + return stripped,offset + end + dump=sub(dump,1,12)..strip_function(sub(dump,13,-1)) + local after=#dump + local delta=register(name,before,after) + return dump,delta + end else - report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message") + strip_code_pc=function(dump,name) + return dump,0 + end end - if forcestrip and luautilities.stripcode then - if type(forcestrip)=="function" then - forcestrip=forcestrip(fullname) + function luautilities.loadedluacode(fullname,forcestrip,name) + local code=environment.loadpreprocessedfile and environment.preprocessedloadfile(fullname) or loadfile(fullname) + if code then + code() end - if forcestrip or luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) + end + if forcestrip then + local code,n=strip_code_pc(dump(code),name) + return load(code),n + elseif luautilities.alwaysstripcode then + return load(strip_code_pc(dump(code),name)) + else + return code,0 + end + elseif luautilities.alwaysstripcode then + return load(strip_code_pc(dump(code),name)) else return code,0 end - elseif luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 - else - return code,0 end -end -function luautilities.strippedloadstring(code,forcestrip,name) - local code,message=load(code) - if not code then - report_lua("loading of file %a failed:\n\t%s",name,message or "no message") + function luautilities.strippedloadstring(code,forcestrip,name) + local n=0 + if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then + code=load(code) + if not code then + report_lua("fatal error in file %a",name) + end + code,n=strip_code_pc(dump(code),name) + end + return load(code),n end - if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 - else - return code,0 + local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + local n=0 + if code and code~="" then + code=load(code) + if not code then + report_lua("fatal error in file %a",luafile) + end + code=dump(code) + if strip then + code,n=strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) + end + if code and code~="" then + io.savedata(lucfile,code) + end + end + return n end -end -function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) - report_lua("compiling %a into %a",luafile,lucfile) - os.remove(lucfile) - local done=stupidcompile(luafile,lucfile,strip~=false) - if done then - report_lua("dumping %a into %a stripped",luafile,lucfile) - if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then + local luac_normal="texluac -o %q %q" + local luac_strip="texluac -s -o %q %q" + function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=false + if strip~=false then + strip=true + end + if forcestupidcompile then + fallback=true + elseif strip then + done=os.spawn(format(luac_strip,lucfile,luafile))==0 + else + done=os.spawn(format(luac_normal,lucfile,luafile))==0 + end + if not done and fallback then + local n=stupidcompile(luafile,lucfile,strip) + if n>0 then + report_lua("%a dumped into %a (%i bytes stripped)",luafile,lucfile,n) + else + report_lua("%a dumped into %a (unstripped)",luafile,lucfile) + end + cleanup=false + done=true + end + if done and cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then report_lua("removing %a",luafile) os.remove(luafile) end + return done end - return done -end -function luautilities.loadstripped(...) - local l=load(...) - if l then - return load(dump(l,true)) - end + luautilities.loadstripped=loadstring end @@ -8274,7 +7826,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tpl"] = package.loaded["util-tpl"] or true --- original size: 6251, stripped down to: 3488 +-- original size: 5655, stripped down to: 3242 if not modules then modules={} end modules ['util-tpl']={ version=1.001, @@ -8288,8 +7840,8 @@ local templates=utilities.templates local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end) local report_template=logs.reporter("template") local tostring=tostring -local format,sub,byte=string.format,string.sub,string.byte -local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns +local format,sub=string.format,string.sub +local P,C,Cs,Carg,lpegmatch=lpeg.P,lpeg.C,lpeg.Cs,lpeg.Carg,lpeg.match local replacer local function replacekey(k,t,how,recursive) local v=t[k] @@ -8316,13 +7868,10 @@ local sqlescape=lpeg.replacer { { "\r\n","\\n" }, { "\r","\\n" }, } -local sqlquoted=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) -lpegpatterns.sqlescape=sqlescape -lpegpatterns.sqlquoted=sqlquoted -local luaescape=lpegpatterns.luaescape +local sqlquotedescape=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) local escapers={ lua=function(s) - return lpegmatch(luaescape,s) + return sub(format("%q",s),2,-2) end, sql=function(s) return lpegmatch(sqlescape,s) @@ -8333,9 +7882,11 @@ local quotedescapers={ return format("%q",s) end, sql=function(s) - return lpegmatch(sqlquoted,s) + return lpegmatch(sqlquotedescape,s) end, } +lpeg.patterns.sqlescape=sqlescape +lpeg.patterns.sqlescape=sqlquotedescape local luaescaper=escapers.lua local quotedluaescaper=quotedescapers.lua local function replacekeyunquoted(s,t,how,recurse) @@ -8372,11 +7923,6 @@ local function replace(str,mapping,how,recurse) end end templates.replace=replace -function templates.replacer(str,how,recurse) - return function(mapping) - return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str - end -end function templates.load(filename,mapping,how,recurse) local data=io.loaddata(filename) or "" if mapping and next(mapping) then @@ -8402,7 +7948,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 8761, stripped down to: 5085 +-- original size: 8722, stripped down to: 5050 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -8438,7 +7984,6 @@ local luaengines=allocate { environment.validengines=validengines environment.basicengines=basicengines if not arg then - environment.used_as_library=true elseif luaengines[file.removesuffix(arg[-1])] then elseif validengines[file.removesuffix(arg[0])] then if arg[1]=="--luaonly" then @@ -8599,7 +8144,7 @@ do -- create closure to overcome 200 locals limit package.loaded["luat-env"] = package.loaded["luat-env"] or true --- original size: 5930, stripped down to: 4235 +-- original size: 5874, stripped down to: 4184 if not modules then modules={} end modules ['luat-env']={ version=1.001, @@ -8613,13 +8158,12 @@ local trace_locating=false trackers.register("resolvers.locating",function(v) tr local report_lua=logs.reporter("resolvers","lua") local luautilities=utilities.lua local luasuffixes=luautilities.suffixes -local texgettoks=tex and tex.gettoks environment=environment or {} local environment=environment local mt={ __index=function(_,k) if k=="version" then - local version=texgettoks and texgettoks("contextversiontoks") + local version=tex.toks and tex.toks.contextversiontoks if version and version~="" then rawset(environment,"version",version) return version @@ -8627,7 +8171,7 @@ local mt={ return "unknown" end elseif k=="kind" then - local kind=texgettoks and texgettoks("contextkindtoks") + local kind=tex.toks and tex.toks.contextkindtoks if kind and kind~="" then rawset(environment,"kind",kind) return kind @@ -8754,7 +8298,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 42447, stripped down to: 26589 +-- original size: 42495, stripped down to: 26647 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -8765,7 +8309,6 @@ if not modules then modules={} end modules ['lxml-tab']={ } local trace_entities=false trackers.register("xml.entities",function(v) trace_entities=v end) local report_xml=logs and logs.reporter("xml","core") or function(...) print(string.format(...)) end -if lpeg.setmaxstack then lpeg.setmaxstack(1000) end xml=xml or {} local xml=xml local concat,remove,insert=table.concat,table.remove,table.insert @@ -9185,6 +8728,7 @@ local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace* local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset local simpledoctype=(1-close)^1 local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) +local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end @@ -12269,7 +11813,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-exp"] = package.loaded["data-exp"] or true --- original size: 15303, stripped down to: 9716 +-- original size: 14654, stripped down to: 9517 if not modules then modules={} end modules ['data-exp']={ version=1.001, @@ -12281,7 +11825,7 @@ if not modules then modules={} end modules ['data-exp']={ local format,find,gmatch,lower,char,sub=string.format,string.find,string.gmatch,string.lower,string.char,string.sub local concat,sort=table.concat,table.sort local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local Ct,Cs,Cc,Carg,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.P,lpeg.C,lpeg.S +local Ct,Cs,Cc,P,C,S=lpeg.Ct,lpeg.Cs,lpeg.Cc,lpeg.P,lpeg.C,lpeg.S local type,next=type,next local ostype=os.type local collapsepath=file.collapsepath @@ -12289,6 +11833,20 @@ local trace_locating=false trackers.register("resolvers.locating",function(v) tr local trace_expansions=false trackers.register("resolvers.expansions",function(v) trace_expansions=v end) local report_expansions=logs.reporter("resolvers","expansions") local resolvers=resolvers +local function f_first(a,b) + local t,n={},0 + for s in gmatch(b,"[^,]+") do + n=n+1;t[n]=a..s + end + return concat(t,",") +end +local function f_second(a,b) + local t,n={},0 + for s in gmatch(a,"[^,]+") do + n=n+1;t[n]=s..b + end + return concat(t,",") +end local function f_both(a,b) local t,n={},0 for sb in gmatch(b,"[^,]+") do @@ -12298,15 +11856,6 @@ local function f_both(a,b) end return concat(t,",") end -local comma=P(",") -local nocomma=(1-comma)^1 -local docomma=comma^1/"," -local before=Cs((nocomma*Carg(1)+docomma)^0) -local after=Cs((Carg(1)*nocomma+docomma)^0) -local both=Cs(((C(nocomma)*Carg(1))/function(a,b) return lpegmatch(before,b,1,a) end+docomma)^0) -local function f_first (a,b) return lpegmatch(after,b,1,a) end -local function f_second(a,b) return lpegmatch(before,a,1,b) end -local function f_both (a,b) return lpegmatch(both,b,1,a) end local left=P("{") local right=P("}") local var=P((1-S("{}" ))^0) @@ -12894,7 +12443,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-tmp"] = package.loaded["data-tmp"] or true --- original size: 15532, stripped down to: 11648 +-- original size: 14615, stripped down to: 11208 if not modules then modules={} end modules ['data-tmp']={ version=1.100, @@ -13108,22 +12657,6 @@ function caches.getfirstreadablefile(filename,...) end return caches.setfirstwritablefile(filename,...) end -function caches.getfirstreadablefile_TEST_ME_FIRST(filename,...) - local fullname,path=caches.setfirstwritablefile(filename,...) - if is_readable(fullname) then - return fullname,path - end - local rd=getreadablepaths(...) - for i=1,#rd do - local path=rd[i] - local fullname=file.join(path,filename) - if is_readable(fullname) then - usedreadables[i]=true - return fullname,path - end - end - return fullname,path -end function caches.setfirstwritablefile(filename,...) local wr=getwritablepath(...) local fullname=file.join(wr,filename) @@ -13269,7 +12802,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-met"] = package.loaded["data-met"] or true --- original size: 5453, stripped down to: 4007 +-- original size: 5137, stripped down to: 4007 if not modules then modules={} end modules ['data-met']={ version=1.100, @@ -13388,7 +12921,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-res"] = package.loaded["data-res"] or true --- original size: 61782, stripped down to: 42959 +-- original size: 61759, stripped down to: 42959 if not modules then modules={} end modules ['data-res']={ version=1.001, @@ -16563,8 +16096,8 @@ end -- of closure -- used libraries : l-lua.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-mrg.lua util-tpl.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 680476 --- stripped bytes : 240933 +-- original bytes : 670212 +-- stripped bytes : 245255 -- end library merge @@ -16732,9 +16265,11 @@ end -- verbosity ------ e_verbose = environment.arguments["verbose"] +local e_verbose = environment.arguments["verbose"] -local e_verbose = false +if e_verbose then + trackers.enable("resolvers.locating") +end -- some common flags (also passed through environment) @@ -17455,22 +16990,12 @@ environment.initializearguments(before) instance.lsrmode = environment.argument("lsr") or false -e_verbose = environment.arguments["verbose"] -- delayed till here (we need the ones before script) - -if e_verbose then - trackers.enable("resolvers.locating") -end - -- maybe the unset has to go to this level local is_mkii_stub = runners.registered[file.removesuffix(file.basename(filename))] local e_argument = environment.argument -if e_argument("timedlog") then - logs.settimedlog() -end - if e_argument("usekpse") or e_argument("forcekpse") or is_mkii_stub then resolvers.load_tree(e_argument('tree'),true) -- force resolve of TEXMFCNF @@ -17553,23 +17078,6 @@ else end --- joke .. reminds me of messing with gigi terminals - -if e_argument("ansi") then - - local formatters = string.formatters - - logs.setformatters { - report_yes = formatters["[1;32m%-15s [0;1m|[0m %s"], - report_nop = formatters["[1;32m%-15s [0;1m|[0m"], - subreport_yes = formatters["[1;32m%-15s [0;1m|[1;31m %s [0;1m|[0m %s"], - subreport_nop = formatters["[1;32m%-15s [0;1m|[1;31m %s [0;1m|[0m"], - status_yes = formatters["[1;32m%-15s [0;1m:[0m %s\n"], - status_nop = formatters["[1;32m%-15s [0;1m:[0m\n"], - } - -end - if e_argument("script") or e_argument("scripts") then -- run a script by loading it (using libs), pass args |