summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scripts/mkimport135
-rw-r--r--src/fontloader/misc/fontloader-l-lpeg.lua40
-rw-r--r--src/fontloader/misc/fontloader-util-str.lua28
-rw-r--r--src/fontloader/runtime/fontloader-fontloader.lua50
4 files changed, 211 insertions, 42 deletions
diff --git a/scripts/mkimport b/scripts/mkimport
index 2f64d62..a430587 100644
--- a/scripts/mkimport
+++ b/scripts/mkimport
@@ -20,6 +20,8 @@
---
-------------------------------------------------------------------------------
+local debug = false
+
kpse.set_program_name "luatex"
local lfs = require "lfs"
@@ -27,10 +29,17 @@ local md5 = require "md5"
require "lualibs"
-local ioloaddata = io.loaddata
-local iowrite = io.write
-local md5sumhexa = md5.sumhexa
-local stringformat = string.format
+local fileiswritable = file.is_writable
+local ioloaddata = io.loaddata
+local iopopen = io.popen
+local iowrite = io.write
+local lfschdir = lfs.chdir
+local lfsisdir = lfs.isdir
+local lfsisfile = lfs.isfile
+local md5sumhexa = md5.sumhexa
+local osgettimeofday = os.gettimeofday
+local stringformat = string.format
+local tableconcat = table.concat
-------------------------------------------------------------------------------
-- config
@@ -212,7 +221,7 @@ local imports = {
} --[[ [imports] ]]
local hash_file = function (fname)
- if not lfs.isfile (fname) then
+ if not lfsisfile (fname) then
die ("cannot find %s.", fname)
end
local raw = ioloaddata (fname)
@@ -225,7 +234,7 @@ end
local derive_category_path = function (cat)
local subpath = origin_paths[cat] or die ("category " .. cat .. " unknown")
local location = file.join (context_root, subpath)
- if not lfs.isdir (location) then
+ if not lfsisdir (location) then
die ("invalid base path defined for category "
.. cat .. " at " .. location)
end
@@ -331,7 +340,7 @@ local news = function ()
status.missing[#status.missing + 1] = ourname
else
--- Source file exists and is readable.
- if not lfs.isdir (fontloader_subdir) then
+ if not lfsisdir (fontloader_subdir) then
die ("path for fontloader tree ("
.. fontloader_subdir .. ") is not a directory")
end
@@ -428,12 +437,12 @@ local import_file = function (name, kind, def, cat)
local ourpath = file.join (fontloader_subdir, subdir)
local src = file.join (srcdir, fullname)
local dst = file.join (ourpath, ourname)
- local new = not lfs.isfile (dst)
+ local new = not lfsisfile (dst)
if not new and hash_file (src) == hash_file (dst) then
status ("file %s is unchanged, skipping", fullname)
return import_skipped
end
- if not (lfs.isdir (ourpath) or not lfs.mkdirs (ourpath)) then
+ if not (lfsisdir (ourpath) or not lfs.mkdirs (ourpath)) then
die ("failed to create directory %s for file %s",
ourpath, ourname)
end
@@ -475,7 +484,7 @@ end --[[ [local import = function (arg)] ]]
local find_in_path = function (root, subdir, target)
local file = file.join (root, subdir, target)
- if lfs.isfile (file) then
+ if lfsisfile (file) then
return file
end
end
@@ -554,7 +563,7 @@ end
local search = function (target)
local look_for
--- pick a file
- if lfs.isfile (target) then --- absolute path given
+ if lfsisfile (target) then --- absolute path given
look_for = target
goto found
else
@@ -632,6 +641,100 @@ local tell = function (arg)
return describe (target, location)
end
+--[[doc--
+
+ Packaging works as follows:
+
+ * Files are looked up the usual way, allowing us to override the
+ distribution-supplied scripts with our own alternatives in the
+ local path.
+
+ * The merged package is written to the same directory as the
+ packaging script (not ``$PWD``).
+
+ There is some room for improvements: Instead of reading a file with
+ fixed content from disk, the merge script could be composed
+ on-the-fly from a list of files and then written to memory (not sure
+ though if we can access shm_open or memfd and the likes from Lua).
+
+--doc]]--
+
+local package = function (args)
+ local t0 = osgettimeofday ()
+ local orig_dir = lfs.currentdir ()
+ local base_dir = orig_dir .. "/src/fontloader/"
+ local merge_name = base_dir .. "luaotfload-package.lua"
+ --- output name is fixed so we have to deal with it but maybe we can
+ --- get a patch to mtx-package upstreamed in the future
+ local output_name = base_dir .. "luaotfload-package-merged.lua"
+ local target_name = stringformat ("fontloader-%s.lua",
+ os.date ("%F"))
+ status ("assuming fontloader source in %s", base_dir)
+ status ("reading merge instructions from %s", merge_name)
+ status ("writing output to %s", target_name)
+
+ --- check preconditions
+
+ if not lfsisdir (base_dir) then die ("directory %s does not exist", emphasis (base_dir )) end
+ if not lfsisfile (merge_name) then die ("missing merge file at %s", emphasis (merge_name )) end
+ if not fileiswritable (output_name) then die ("cannot write to %s", emphasis (output_name)) end
+ if not fileiswritable (target_name) then die ("cannot write to %s", emphasis (target_name)) end
+ if not lfschdir (base_dir) then die ("failed to cd into %s", emphasis (base_dir )) end
+
+ if lfsisfile (output_name) then
+ status ("output file already exists at “%s”, unlinking", output_name)
+ local ret, err = os.remove (output_name)
+ if ret == nil then
+ if not lfschdir (orig_dir) then
+ status ("warning: failed to cd retour into %s", emphasis (orig_dir))
+ end
+ die ("failed to remove existing merge package")
+ end
+ end
+ --die ("missing merge file at %s", emphasis (merge_name )) end
+
+ --- perform merge
+
+ local cmd = { "mtxrun", "--script", "package", "--merge", merge_name }
+ local shl = tableconcat (cmd, " ")
+
+ status ("invoking %s as “%s”", emphasis "mtx-package", shl)
+
+ local fh = iopopen (shl, "r")
+
+ if not fh then
+ if not lfschdir (orig_dir) then
+ status ("warning: failed to cd retour into %s", emphasis (orig_dir))
+ end
+ die ("merge failed; failed to invoke mtxrun")
+ end
+
+ local junk = fh.read (fh, "*all")
+ if not junk then
+ status ("warning: received no output from mtxrun; this is strange")
+ end
+
+ fh.close (fh)
+
+ if debug then print (junk) end
+
+ --- clean up
+
+ if not lfschdir (orig_dir) then
+ status ("warning: failed to cd retour into %s", emphasis (orig_dir))
+ end
+
+ --- check postconditions
+
+ if not lfsisfile (output_name) then die ("merge failed; package not found at " .. output_name) end
+
+ --- at this point we know that mtxrun was invoked correctly and the
+ --- result file has been created
+
+ status ("merge complete; operation finished in %.0f ms",
+ (osgettimeofday() - t0) * 1000)
+end
+
local help = function ()
iowrite "usage: mkimport <command> [<args>]\n"
iowrite "\n"
@@ -640,14 +743,16 @@ local help = function ()
iowrite " tell Display information about a file’s integration\n"
iowrite " news Check Context for updated files\n"
iowrite " import Update with files from Context\n"
+ iowrite " package Invoke mtx-package on the current fontloader\n"
iowrite "\n"
end
local job_kind = table.mirrored {
- news = news,
- import = import,
- tell = tell,
- help = help,
+ help = help,
+ import = import,
+ news = news,
+ package = package,
+ tell = tell,
}
-------------------------------------------------------------------------------
diff --git a/src/fontloader/misc/fontloader-l-lpeg.lua b/src/fontloader/misc/fontloader-l-lpeg.lua
index 4aadadb..55a0d89 100644
--- a/src/fontloader/misc/fontloader-l-lpeg.lua
+++ b/src/fontloader/misc/fontloader-l-lpeg.lua
@@ -10,6 +10,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
-- if i can use new features like capture / 2 and .B (at first sight the xml
-- parser is some 5% slower)
+-- lpeg.P("abc") is faster than lpeg.P("a") * lpeg.P("b") * lpeg.P("c")
+
-- a new lpeg fails on a #(1-P(":")) test and really needs a + P(-1)
-- move utf -> l-unicode
@@ -19,7 +21,7 @@ lpeg = require("lpeg")
-- The latest lpeg doesn't have print any more, and even the new ones are not
-- available by default (only when debug mode is enabled), which is a pitty as
--- as it helps nailign down bottlenecks. Performance seems comparable: some 10%
+-- as it helps nailing down bottlenecks. Performance seems comparable: some 10%
-- slower pattern compilation, same parsing speed, although,
--
-- local p = lpeg.C(lpeg.P(1)^0 * lpeg.P(-1))
@@ -841,7 +843,6 @@ local function make(t)
local function making(t)
local p = p_false
local keys = sortedkeys(t)
--- local okay = t[""]
for i=1,#keys do
local k = keys[i]
if k ~= "" then
@@ -850,8 +851,6 @@ local function make(t)
p = p + P(k) * p_true
elseif v == false then
-- can't happen
--- elseif okay then
--- p = p + P(k) * (making(v) + p_true)
else
p = p + P(k) * making(v)
end
@@ -872,8 +871,6 @@ local function make(t)
p = p + P(k) * p_true
elseif v == false then
-- can't happen
--- elseif v[""] then
--- p = p + P(k) * (making(v) + p_true)
else
p = p + P(k) * making(v)
end
@@ -882,6 +879,33 @@ local function make(t)
return p
end
+local function collapse(t,x)
+ if type(t) ~= "table" then
+ return t, x
+ else
+ local n = next(t)
+ if n == nil then
+ return t, x
+ elseif next(t,n) == nil then
+ -- one entry
+ local k = n
+ local v = t[k]
+ if type(v) == "table" then
+ return collapse(v,x..k)
+ else
+ return v, x .. k
+ end
+ else
+ local tt = { }
+ for k, v in next, t do
+ local vv, kk = collapse(v,k)
+ tt[kk] = vv
+ end
+ return tt, x
+ end
+ end
+end
+
function lpeg.utfchartabletopattern(list) -- goes to util-lpg
local tree = { }
local n = #list
@@ -955,10 +979,14 @@ function lpeg.utfchartabletopattern(list) -- goes to util-lpg
end
end
end
+-- collapse(tree,"") -- needs testing, maybe optional, slightly faster because P("x")*P("X") seems slower than P"(xX") (why)
-- inspect(tree)
return make(tree)
end
+-- local t = { "start", "stoep", "staart", "paard" }
+-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1)
+
-- local t = { "a", "abc", "ac", "abe", "abxyz", "xy", "bef","aa" }
-- local p = lpeg.Cs((lpeg.utfchartabletopattern(t)/string.upper + 1)^1)
diff --git a/src/fontloader/misc/fontloader-util-str.lua b/src/fontloader/misc/fontloader-util-str.lua
index a677a82..de4a87e 100644
--- a/src/fontloader/misc/fontloader-util-str.lua
+++ b/src/fontloader/misc/fontloader-util-str.lua
@@ -44,7 +44,12 @@ end
if not number then number = { } end -- temp hack for luatex-fonts
-local stripper = patterns.stripzeros
+local stripper = patterns.stripzeros
+local newline = patterns.newline
+local endofstring = patterns.endofstring
+local whitespace = patterns.whitespace
+local spacer = patterns.spacer
+local spaceortab = patterns.spaceortab
local function points(n)
n = tonumber(n)
@@ -62,12 +67,12 @@ number.basepoints = basepoints
-- str = " \n \ntest \n test\ntest "
-- print("["..string.gsub(string.collapsecrlf(str),"\n","+").."]")
-local rubish = patterns.spaceortab^0 * patterns.newline
-local anyrubish = patterns.spaceortab + patterns.newline
+local rubish = spaceortab^0 * newline
+local anyrubish = spaceortab + newline
local anything = patterns.anything
-local stripped = (patterns.spaceortab^1 / "") * patterns.newline
+local stripped = (spaceortab^1 / "") * newline
local leading = rubish^0 / ""
-local trailing = (anyrubish^1 * patterns.endofstring) / ""
+local trailing = (anyrubish^1 * endofstring) / ""
local redundant = rubish^3 / "\n"
local pattern = Cs(leading * (trailing + redundant + stripped + anything)^0)
@@ -129,7 +134,7 @@ local pattern =
return ""
end
end
- + patterns.newline * Cp() / function(position)
+ + newline * Cp() / function(position)
extra, start = 0, position
end
+ patterns.anything
@@ -162,11 +167,6 @@ end
-- return str
-- end
-local newline = patterns.newline
-local endofstring = patterns.endofstring
-local whitespace = patterns.whitespace
-local spacer = patterns.spacer
-
local space = spacer^0
local nospace = space/""
local endofline = nospace * newline
@@ -1117,3 +1117,9 @@ local pattern =
function string.optionalquoted(str)
return lpegmatch(pattern,str) or str
end
+
+local pattern = Cs((newline / os.newline + 1)^0)
+
+function string.replacenewlines(str)
+ return lpegmatch(pattern,str)
+end
diff --git a/src/fontloader/runtime/fontloader-fontloader.lua b/src/fontloader/runtime/fontloader-fontloader.lua
index 1d6509a..c46c168 100644
--- a/src/fontloader/runtime/fontloader-fontloader.lua
+++ b/src/fontloader/runtime/fontloader-fontloader.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 04/18/15 14:41:50
+-- merge date : 05/04/15 19:00:43
do -- begin closure to overcome local limits and interference
@@ -699,6 +699,31 @@ local function make(t)
end
return p
end
+local function collapse(t,x)
+ if type(t)~="table" then
+ return t,x
+ else
+ local n=next(t)
+ if n==nil then
+ return t,x
+ elseif next(t,n)==nil then
+ local k=n
+ local v=t[k]
+ if type(v)=="table" then
+ return collapse(v,x..k)
+ else
+ return v,x..k
+ end
+ else
+ local tt={}
+ for k,v in next,t do
+ local vv,kk=collapse(v,k)
+ tt[kk]=vv
+ end
+ return tt,x
+ end
+ end
+end
function lpeg.utfchartabletopattern(list)
local tree={}
local n=#list
@@ -2773,6 +2798,11 @@ else
end
if not number then number={} end
local stripper=patterns.stripzeros
+local newline=patterns.newline
+local endofstring=patterns.endofstring
+local whitespace=patterns.whitespace
+local spacer=patterns.spacer
+local spaceortab=patterns.spaceortab
local function points(n)
n=tonumber(n)
return (not n or n==0) and "0pt" or lpegmatch(stripper,format("%.5fpt",n/65536))
@@ -2783,12 +2813,12 @@ local function basepoints(n)
end
number.points=points
number.basepoints=basepoints
-local rubish=patterns.spaceortab^0*patterns.newline
-local anyrubish=patterns.spaceortab+patterns.newline
+local rubish=spaceortab^0*newline
+local anyrubish=spaceortab+newline
local anything=patterns.anything
-local stripped=(patterns.spaceortab^1/"")*patterns.newline
+local stripped=(spaceortab^1/"")*newline
local leading=rubish^0/""
-local trailing=(anyrubish^1*patterns.endofstring)/""
+local trailing=(anyrubish^1*endofstring)/""
local redundant=rubish^3/"\n"
local pattern=Cs(leading*(trailing+redundant+stripped+anything)^0)
function strings.collapsecrlf(str)
@@ -2834,17 +2864,13 @@ local pattern=Carg(1)/function(t)
else
return ""
end
- end+patterns.newline*Cp()/function(position)
+ end+newline*Cp()/function(position)
extra,start=0,position
end+patterns.anything
)^1)
function strings.tabtospace(str,tab)
return lpegmatch(pattern,str,1,tab or 7)
end
-local newline=patterns.newline
-local endofstring=patterns.endofstring
-local whitespace=patterns.whitespace
-local spacer=patterns.spacer
local space=spacer^0
local nospace=space/""
local endofline=nospace*newline
@@ -3413,6 +3439,10 @@ local pattern=Cs(dquote*(equote-P(-2))^0*dquote)
function string.optionalquoted(str)
return lpegmatch(pattern,str) or str
end
+local pattern=Cs((newline/os.newline+1)^0)
+function string.replacenewlines(str)
+ return lpegmatch(pattern,str)
+end
end -- closure