diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua | 127 |
1 files changed, 68 insertions, 59 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua index 9b81f6a3d0e..f1b59fcc7ba 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-database", - version = "3.26", --TAGVERSION - date = "2023-08-31", --TAGDATE + version = "3.27", --TAGVERSION + date = "2024-02-14", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", @@ -150,7 +150,6 @@ local kpsefind_file = kpse.find_file local kpselookup = kpse.lookup local kpsereadable_file = kpse.readable_file local lfsattributes = lfs.attributes -local lfschdir = lfs.chdir local lfscurrentdir = lfs.currentdir local lfsdir = lfs.dir local mathabs = math.abs @@ -202,6 +201,7 @@ local resolversfindfile = context_environment.resolvers.findfile --- some of our own local unicode = require'luaotfload-unicode' local casefold = require'lua-uni-case'.casefold +local realpath = require'luaotfload-realpath'.realpath local alphnum_only = unicode.alphnum_only local name_index = nil --> upvalue for names.data @@ -318,49 +318,53 @@ local function sanitize_fontnames (rawnames) return result end -local function find_files_indeed (acc, dirs, filter) - if not next (dirs) then --- done - return acc +local list_dir_or_empty do + local function inner_list_dir_or_empty (dir, success, ...) + if success then + return ... + else + -- Skipping unreadable directory. + -- TODO: Print warning + return next, {} + end + end + function list_dir_or_empty (dir) + return inner_list_dir_or_empty(dir, pcall(lfsdir, dir)) end +end - local pwd = lfscurrentdir () - local dir = dirs[#dirs] - dirs[#dirs] = nil +local function dummyfilter () return true end + +--- the optional filter function receives the full path of a file +--- system entity. a filter applies if the first argument it returns is +--- true. + +--- string -> function? -> string list +local function find_files (root, filter) + if not lfsisdir (root) then return end + + local files = {} + local dirs = { root } + filter = filter or dummyfilter - if lfschdir (dir) then - lfschdir (pwd) + while dirs[1] do + local dir = dirs[#dirs] + dirs[#dirs] = nil - local newfiles = { } - for ent in lfsdir (dir) do + for ent in list_dir_or_empty (dir) do if ent ~= "." and ent ~= ".." then local fullpath = dir .. "/" .. ent if filter (fullpath) == true then if lfsisdir (fullpath) then dirs[#dirs+1] = fullpath elseif lfsisfile (fullpath) then - newfiles[#newfiles+1] = fullpath + files[#files+1] = fullpath end end end end - return find_files_indeed (tableappend (acc, newfiles), - dirs, filter) - end - --- could not cd into, so we skip it - return find_files_indeed (acc, dirs, filter) -end - -local function dummyfilter () return true end - ---- the optional filter function receives the full path of a file ---- system entity. a filter applies if the first argument it returns is ---- true. - ---- string -> function? -> string list -local function find_files (root, filter) - if lfsisdir (root) then - return find_files_indeed ({}, { root }, filter or dummyfilter) end + return files end @@ -2177,17 +2181,19 @@ local function process_dir_tree (acc, dirs, done) return acc end - local pwd = lfscurrentdir () local dir = dirs[#dirs] dirs[#dirs] = nil - if not lfschdir (dir) then - --- Cannot cd; skip. + local mode_or_err + dir, mode_or_err = realpath(dir) + if not dir then + logreport ("both", 1, "db", "Skipping font directory: %s", mode_or_err) + return process_dir_tree (acc, dirs, done) + elseif mode_or_err ~= 'directory' then + logreport ("both", 1, "db", "Skipping non-directory while searching fonts: %q (%s)", dir, mode_or_err) return process_dir_tree (acc, dirs, done) end - dir = lfscurrentdir () --- resolve symlinks - lfschdir (pwd) if tablecontains (done, dir) then --- Already traversed. Note that it’d be unsafe to rely on the --- hash part above due to Lua only processing up to 32 bytes @@ -2226,35 +2232,38 @@ local function process_dir_tree (acc, dirs, done) end local function process_dir (dir) - local pwd = lfscurrentdir () - if lfschdir (dir) then - dir = lfscurrentdir () --- resolve symlinks - lfschdir (pwd) - - local files = { } - local blacklist = names.blacklist - for ent in lfsdir (dir) do - if ent ~= "." and ent ~= ".." and not blacklist[ent] then - local fullpath = dir .. "/" .. ent - if lfsisfile (fullpath) then - ent = stringlower (ent) - if lpegmatch (p_font_filter, ent) - then - if filesuffix (ent) == "afm" then - local pfbpath = locate_matching_pfb (ent, dir) - if pfbpath then - files[#files+1] = pfbpath - end - else - files[#files+1] = fullpath + local mode_or_err + dir, mode_or_err = realpath(dir) + if not dir then + logreport ("both", 1, "db", "Skipping font directory: %s", mode_or_err) + return {} + elseif mode_or_err ~= 'directory' then + logreport ("both", 1, "db", "Skipping non-directory while searching fonts: %q (%s)", dir, mode_or_err) + return {} + end + + local files = { } + local blacklist = names.blacklist + for ent in lfsdir (dir) do + if ent ~= "." and ent ~= ".." and not blacklist[ent] then + local fullpath = dir .. "/" .. ent + if lfsisfile (fullpath) then + ent = stringlower (ent) + if lpegmatch (p_font_filter, ent) + then + if filesuffix (ent) == "afm" then + local pfbpath = locate_matching_pfb (ent, dir) + if pfbpath then + files[#files+1] = pfbpath end + else + files[#files+1] = fullpath end end end end - return files end - return { } + return files end --- string -> bool -> string list |