From 0acf9a04ff947deb9c7593e4ed87efab5d0e98a7 Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg@phi-gamma.net>
Date: Thu, 23 Jul 2015 08:14:18 +0200
Subject: [main,init,db,resolvers] separate resolvers from main into separate
 file

---
 src/luaotfload-database.lua  |  63 +++++------
 src/luaotfload-init.lua      |   2 +
 src/luaotfload-main.lua      | 234 +--------------------------------------
 src/luaotfload-resolvers.lua | 256 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 295 insertions(+), 260 deletions(-)
 create mode 100644 src/luaotfload-resolvers.lua

diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua
index 1831ca3..381185b 100644
--- a/src/luaotfload-database.lua
+++ b/src/luaotfload-database.lua
@@ -454,22 +454,19 @@ end
 --- define locals in scope
 local access_font_index
 local collect_families
-local font_file_lookup
 local find_closest
 local flush_lookup_cache
 local generate_filedata
 local get_font_filter
 local group_modifiers
-local load_lookups
 local load_names
+local lookup_font_name
 local getmetadata
 local order_design_sizes
 local ot_fullinfo
 local read_blacklist
 local reload_db
-local resolve_cached
-local resolve_fullpath
-local resolve_name
+local lookup_fullpath
 local save_lookups
 local save_names
 local set_font_filter
@@ -558,6 +555,7 @@ getmetadata = function ()
 end
 
 --- unit -> unit
+local load_lookups
 load_lookups = function ( )
     local foundname, data = load_lua_file(config.luaotfload.paths.lookup_path_lua)
     if data then
@@ -638,7 +636,7 @@ end
 
 --[[doc--
 
-    font_file_lookup -- The ``file:`` are ultimately delegated here.
+    lookup_font_file -- The ``file:`` are ultimately delegated here.
     The lookups are kind of a blunt instrument since they try locating
     the file using every conceivable method, which is quite
     inefficient. Nevertheless, resolving files that way is rarely the
@@ -647,7 +645,8 @@ end
 --doc]]--
 
 --- string -> string * string * bool
-font_file_lookup = function (filename)
+local lookup_font_file
+lookup_font_file = function (filename)
     local found = lookup_filename (filename)
 
     if not found then
@@ -667,7 +666,7 @@ font_file_lookup = function (filename)
 
     if not fonts_reloaded and config.luaotfload.db.update_live == true then
         return reload_db (stringformat ("File not found: %s.", filename),
-                          font_file_lookup,
+                          lookup_font_file,
                           filename)
     end
     return filename, nil, false
@@ -715,7 +714,7 @@ font managment we have to check both the system path and the texmf.
 --doc]]--
 
 local verify_font_file = function (basename)
-    local path = resolve_fullpath (basename)
+    local path = lookup_fullpath (basename)
     if path and lfsisfile(path) then
         return true
     end
@@ -748,7 +747,7 @@ Idk what the “spec” resolver is for.
         spec:       name, sub           resolved, sub, name, forced
 
 [*] name: contains both the name resolver from luatex-fonts and
-    resolve_name() below
+    lookup_font_name () below
 
 From my reading of font-def.lua, what a resolver does is
 basically rewrite the “name” field of the specification record
@@ -777,7 +776,8 @@ local hash_request = function (specification)
 end
 
 --- 'a -> 'a -> table -> (string * int|boolean * boolean)
-resolve_cached = function (specification)
+local lookup_font_name_cached
+lookup_font_name_cached = function (specification)
     if not lookup_cache then load_lookups () end
     local request = hash_request(specification)
     report("both", 4, "cache", "Looking for %q in cache ...",
@@ -801,7 +801,7 @@ resolve_cached = function (specification)
 
     --- case 2) cache negative ----------------------------------------
     --- first we resolve normally ...
-    local filename, subfont = resolve_name (specification)
+    local filename, subfont = lookup_font_name (specification)
     if not filename then
         return nil, nil
     end
@@ -935,13 +935,13 @@ end
 
 --[[doc--
 
-    resolve_familyname -- Query the families table for an entry
+    lookup_familyname -- Query the families table for an entry
     matching the specification.
     The parameters “name” and “style” are pre-sanitized.
 
 --doc]]--
 --- spec -> string -> string -> int -> string * int
-local resolve_familyname = function (specification, name, style, askedsize)
+local lookup_familyname = function (specification, name, style, askedsize)
     local families   = name_index.families
     local mappings   = name_index.mappings
     local candidates = nil
@@ -978,7 +978,7 @@ local resolve_familyname = function (specification, name, style, askedsize)
     return resolved, subfont
 end
 
-local resolve_fontname = function (specification, name, style)
+local lookup_fontname = function (specification, name, style)
     local mappings    = name_index.mappings
     local fallback    = nil
     local lastresort  = nil
@@ -1021,7 +1021,7 @@ end
 
 --[[doc--
 
-    resolve_name -- Perform a name: lookup. This first queries the
+    lookup_font_name -- Perform a name: lookup. This first queries the
     font families table and, if there is no match for the spec, the
     font names table.
     The return value is a pair consisting of the file name and the
@@ -1059,7 +1059,7 @@ end
     multiple design sizes to a given font/style combination, we put a
     workaround in place that chooses that unmarked version.
 
-    The first return value of “resolve_name” is the file name of the
+    The first return value of “lookup_font_name” is the file name of the
     requested font (string). It can be passed to the fullname resolver
     get_font_file().
     The second value is either “false” or an integer indicating the
@@ -1068,7 +1068,7 @@ end
 --doc]]--
 
 --- table -> string * (int | bool)
-resolve_name = function (specification)
+lookup_font_name = function (specification)
     local resolved, subfont
     if not name_index then name_index = load_names () end
     local name      = sanitize_fontname (specification.name)
@@ -1086,28 +1086,28 @@ resolve_name = function (specification)
         end
     end
 
-    resolved, subfont = resolve_familyname (specification,
-                                            name,
-                                            style,
-                                            askedsize)
+    resolved, subfont = lookup_familyname (specification,
+                                           name,
+                                           style,
+                                           askedsize)
     if not resolved then
-        resolved, subfont = resolve_fontname (specification,
-                                              name,
-                                              style)
+        resolved, subfont = lookup_fontname (specification,
+                                             name,
+                                             style)
     end
 
     if not resolved then
         if not fonts_reloaded and config.luaotfload.db.update_live == true then
             return reload_db (stringformat ("Font %s not found.",
                                             specification.name or "<?>"),
-                              resolve_name,
+                              lookup_font_name,
                               specification)
         end
     end
     return resolved, subfont
 end
 
-resolve_fullpath = function (fontname, ext) --- getfilename()
+lookup_fullpath = function (fontname, ext) --- getfilename()
     if not name_index then name_index = load_names () end
     local files = name_index.files
     local basedata = files.base
@@ -3449,17 +3449,18 @@ names.access_font_index           = access_font_index
 names.data                        = function () return name_index end
 names.save                        = save_names
 names.update                      = update_names
-names.font_file_lookup            = font_file_lookup
+names.lookup_font_file            = lookup_font_file
+names.lookup_font_name            = lookup_font_name
+names.lookup_font_name_cached     = lookup_font_name_cached
+names.getfilename                 = lookup_fullpath
+names.lookup_fullpath             = lookup_fullpath
 names.read_blacklist              = read_blacklist
 names.sanitize_fontname           = sanitize_fontname
-names.getfilename                 = resolve_fullpath
 names.getmetadata                 = getmetadata
 names.set_location_precedence     = set_location_precedence
 names.count_font_files            = count_font_files
 names.nth_font_filename           = nth_font_filename
 names.font_slice                  = font_slice
-names.resolve_cached              = resolve_cached
-names.resolve_name                = resolve_name
 
 --- font cache
 names.purge_cache    = purge_cache
diff --git a/src/luaotfload-init.lua b/src/luaotfload-init.lua
index 0ef968d..a493cc1 100644
--- a/src/luaotfload-init.lua
+++ b/src/luaotfload-init.lua
@@ -9,6 +9,8 @@
 -----------------------------------------------------------------------
 --
 
+local setmetatable = setmetatable
+
 --[[doc--
 
   Initialization phases:
diff --git a/src/luaotfload-main.lua b/src/luaotfload-main.lua
index 5ac1421..b633ed7 100644
--- a/src/luaotfload-main.lua
+++ b/src/luaotfload-main.lua
@@ -65,16 +65,8 @@ luaotfload.module = {
 --doc]]--
 
 local luatexbase       = luatexbase
-
 local require          = require
-local setmetatable     = setmetatable
-local type, next       = type, next
-local stringlower      = string.lower
-local stringformat     = string.format
-
-local kpsefind_file    = kpse.find_file
-local lfsisfile        = lfs.isfile
-
+local type             = type
 local add_to_callback  = luatexbase.add_to_callback
 local create_callback  = luatexbase.create_callback
 local reset_callback   = luatexbase.reset_callback
@@ -177,228 +169,12 @@ load_luaotfload_module "loaders"         --- Type1 font wrappers
 load_luaotfload_module "database"        --- Font management.
 load_luaotfload_module "colors"          --- Per-font colors.
 
-if not config.actions.reconfigure () then
-    logreport ("log", 0, "load", "Post-configuration hooks failed.")
-end
-
---[[doc--
-
-    Relying on the \verb|name:| resolver for everything has been the
-    source of permanent trouble with the database.
-    With the introduction of the new syntax parser we now have enough
-    granularity to distinguish between the \XETEX emulation layer and
-    the genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts.
-    Another benefit is that we can now easily plug in or replace new
-    lookup behaviors if necessary.
-    The name resolver remains untouched, but it calls
-    \luafunction{fonts.names.resolve()} internally anyways (see
-    \fileent{luaotfload-database.lua}).
-
---doc]]--
-
-local filesuffix          = file.suffix
-local fileremovesuffix    = file.removesuffix
-local request_resolvers   = fonts.definers.resolvers
-local formats             = fonts.formats
-local names               = fonts.names
-formats.ofm               = "type1"
-
-fonts.encodings.known     = fonts.encodings.known or { }
-
---[[doc--
+luaotfload.resolvers = load_luaotfload_module "resolvers" --- Font lookup
 
-    \identifier{luaotfload} promises easy access to system fonts.
-    Without additional precautions, this cannot be achieved by
-    \identifier{kpathsea} alone, because it searches only the
-    \fileent{texmf} directories by default.
-    Although it is possible for \identifier{kpathsea} to include extra
-    paths by adding them to the \verb|OSFONTDIR| environment variable,
-    this is still short of the goal »\emphasis{it just works!}«.
-    When building the font database \identifier{luaotfload} scans
-    system font directories anyways, so we already have all the
-    information for looking sytem fonts.
-    With the release version 2.2 the file names are indexed in the
-    database as well and we are ready to resolve \verb|file:| lookups
-    this way.
-    Thus we no longer need to call the \identifier{kpathsea} library in
-    most cases when looking up font files, only when generating the
-    database, and when verifying the existence of a file in the
-    \fileent{texmf} tree.
-
---doc]]--
-
-local resolve_file        = names.font_file_lookup
-
-local file_resolver = function (specification)
-    local name    = resolve_file (specification.name)
-    local suffix  = filesuffix(name)
-    if formats[suffix] then
-        specification.forced      = stringlower (suffix)
-        specification.forcedname  = file.removesuffix(name)
-    else
-        specification.name = name
-    end
-end
-
-request_resolvers.file = file_resolver
-
---[[doc--
-
-    We classify as \verb|anon:| those requests that have neither a
-    prefix nor brackets. According to Khaled\footnote{%
-        \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}.
-    }
-    they are the \XETEX equivalent of a \verb|name:| request, so we
-    will be treating them as such.
-
---doc]]--
-
---request_resolvers.anon = request_resolvers.name
-
---[[doc--
-
-    There is one drawback, though.
-    This syntax is also used for requesting fonts in \identifier{Type1}
-    (\abbrev{tfm}, \abbrev{ofm}) format.
-    These are essentially \verb|file:| lookups and must be caught
-    before the \verb|name:| resolver kicks in, lest they cause the
-    database to update.
-    Even if we were to require the \verb|file:| prefix for all
-    \identifier{Type1} requests, tests have shown that certain fonts
-    still include further fonts (e.~g. \fileent{omlgcb.ofm} will ask
-    for \fileent{omsecob.tfm}) \emphasis{using the old syntax}.
-    For this reason, we introduce an extra check with an early return.
-
---doc]]--
-
-local type1_formats = { "tfm", "ofm", "TFM", "OFM", }
-
-request_resolvers.anon = function (specification)
-    local name = specification.name
-    for i=1, #type1_formats do
-        local format = type1_formats[i]
-        local suffix = filesuffix (name)
-        if resolvers.findfile(name, format) then
-            local usename = suffix == format and file.removesuffix (name) or name
-            specification.forcedname = file.addsuffix (usename, format)
-            specification.forced     = format
-            return
-        end
-    end
-    --- under some weird circumstances absolute paths get
-    --- passed to the definer; we have to catch them
-    --- before the name: resolver misinterprets them.
-    name = specification.specification
-    local exists, _ = lfsisfile(name)
-    if exists then --- garbage; we do this because we are nice,
-                   --- not because it is correct
-        logreport ("log", 1, "load", "file %q exists", name)
-        logreport ("log", 1, "load",
-                   "... overriding borked anon: lookup with path: lookup")
-        specification.name = name
-        request_resolvers.path(specification)
-        return
-    end
-    request_resolvers.name(specification)
-end
+luaotfload.resolvers.install ()
 
---[[doc--
-
-    Prior to version 2.2, \identifier{luaotfload} did not distinguish
-    \verb|file:| and \verb|path:| lookups, causing complications with
-    the resolver.
-    Now we test if the requested name is an absolute path in the file
-    system, otherwise we fall back to the \verb|file:| lookup.
-
---doc]]--
-
-request_resolvers.path = function (specification)
-    local name       = specification.name
-    local exists, _  = lfsisfile(name)
-    if not exists then -- resort to file: lookup
-        logreport ("log", 0, "load",
-                   "path lookup of %q unsuccessful, falling back to file:",
-                   name)
-        file_resolver (specification)
-    else
-        local suffix = filesuffix (name)
-        if formats[suffix] then
-            specification.forced      = stringlower (suffix)
-            specification.name        = file.removesuffix(name)
-            specification.forcedname  = name
-        else
-            specification.name = name
-        end
-    end
-end
-
---[[doc--
-
-    {\bfseries EXPERIMENTAL}:
-    \identifier{kpse}-only resolver, for those who can do without
-    system fonts.
-
---doc]]--
-
-request_resolvers.kpse = function (specification)
-    local name       = specification.name
-    local suffix     = filesuffix(name)
-    if suffix and formats[suffix] then
-        name = file.removesuffix(name)
-        if resolvers.findfile(name, suffix) then
-            specification.forced       = stringlower (suffix)
-            specification.forcedname   = name
-            return
-        end
-    end
-    for t, format in next, formats do --- brute force
-        if kpse.find_file (name, format) then
-            specification.forced = t
-            specification.name   = name
-            return
-        end
-    end
-end
-
---[[doc--
-
-    The \verb|name:| resolver.
-
---doc]]--
-
---- fonts.names.resolvers.name -- Customized version of the
---- generic name resolver.
-
-request_resolvers.name = function (specification)
-    local resolver = names.resolve_cached
-    if config.luaotfload.run.resolver == "normal" then
-        resolver = names.resolve_name
-    end
-    local resolved, subfont = resolver (specification)
-    if resolved then
-        logreport ("log", 0, "load", "Lookup/name: %q -> \"%s%s\"",
-                   specification.name,
-                   resolved,
-                   subfont and stringformat ("(%d)", subfont) or "")
-        specification.resolved   = resolved
-        specification.sub        = subfont
-        specification.forced     = stringlower (filesuffix (resolved) or "")
-        specification.forcedname = resolved
-        specification.name       = fileremovesuffix (resolved)
-    else
-        file_resolver (specification)
-    end
-end
-
---[[doc--
-
-    Also {\bfseries EXPERIMENTAL}: custom file resolvers via callback.
-
---doc]]--
-create_callback("luaotfload.resolve_font", "simple", dummy_function)
-
-request_resolvers.my = function (specification)
-    call_callback("luaotfload.resolve_font", specification)
+if not config.actions.reconfigure () then
+    logreport ("log", 0, "load", "Post-configuration hooks failed.")
 end
 
 --[[doc--
diff --git a/src/luaotfload-resolvers.lua b/src/luaotfload-resolvers.lua
new file mode 100644
index 0000000..42ea2fd
--- /dev/null
+++ b/src/luaotfload-resolvers.lua
@@ -0,0 +1,256 @@
+#!/usr/bin/env texlua
+-----------------------------------------------------------------------
+--         FILE:  luaotfload-resolvers.lua
+--        USAGE:  ./luaotfload-resolvers.lua 
+--  DESCRIPTION:  Resolvers for hooking into the fontloader
+-- REQUIREMENTS:  Luaotfload and a decent bit of courage
+--       AUTHOR:  Philipp Gesang (Phg), <phg@phi-gamma.net>
+--      VERSION:  1.0
+--      CREATED:  2015-07-23 07:31:50+0200
+-----------------------------------------------------------------------
+--
+--- The bare fontloader uses a set of simplistic file name resolvers
+--- that must be overloaded by the user (i. e. us).
+
+if not lualibs    then error "this module requires Luaotfload" end
+if not luaotfload then error "this module requires Luaotfload" end
+
+--[[doc--
+
+    Relying on the \verb|name:| resolver for everything has been the
+    source of permanent trouble with the database.
+    With the introduction of the new syntax parser we now have enough
+    granularity to distinguish between the \XETEX emulation layer and
+    the genuine \verb|name:| and \verb|file:| lookups of \LUATEX-Fonts.
+    Another benefit is that we can now easily plug in or replace new
+    lookup behaviors if necessary.
+    The name resolver remains untouched, but it calls
+    \luafunction{fonts.names.resolve()} internally anyways (see
+    \fileent{luaotfload-database.lua}).
+
+--doc]]--
+
+local next                = next
+local kpsefind_file       = kpse.find_file
+local lfsisfile           = lfs.isfile
+local stringlower         = string.lower
+local stringformat        = string.format
+local filesuffix          = file.suffix
+local fileremovesuffix    = file.removesuffix
+local formats             = fonts.formats
+local names               = fonts.names
+local encodings           = fonts.encodings
+local luatexbase          = luatexbase
+local logreport           = luaotfload.log.report
+
+formats.ofm               = "type1"
+encodings.known           = encodings.known or { }
+
+--[[doc--
+
+    \identifier{luaotfload} promises easy access to system fonts.
+    Without additional precautions, this cannot be achieved by
+    \identifier{kpathsea} alone, because it searches only the
+    \fileent{texmf} directories by default.
+    Although it is possible for \identifier{kpathsea} to include extra
+    paths by adding them to the \verb|OSFONTDIR| environment variable,
+    this is still short of the goal »\emphasis{it just works!}«.
+    When building the font database \identifier{luaotfload} scans
+    system font directories anyways, so we already have all the
+    information for looking sytem fonts.
+    With the release version 2.2 the file names are indexed in the
+    database as well and we are ready to resolve \verb|file:| lookups
+    this way.
+    Thus we no longer need to call the \identifier{kpathsea} library in
+    most cases when looking up font files, only when generating the
+    database, and when verifying the existence of a file in the
+    \fileent{texmf} tree.
+
+--doc]]--
+
+local resolve_file
+resolve_file = function (specification)
+    local name   = names.lookup_font_file (specification.name)
+    local suffix = filesuffix (name)
+    if formats[suffix] then
+        specification.forced      = stringlower (suffix)
+        specification.forcedname  = fileremovesuffix(name)
+    else
+        specification.name = name
+    end
+end
+
+--[[doc--
+
+    Prior to version 2.2, \identifier{luaotfload} did not distinguish
+    \verb|file:| and \verb|path:| lookups, causing complications with
+    the resolver.
+    Now we test if the requested name is an absolute path in the file
+    system, otherwise we fall back to the \verb|file:| lookup.
+
+--doc]]--
+
+local resolve_path
+resolve_path = function (specification)
+    local name       = specification.name
+    local exists, _  = lfsisfile(name)
+    if not exists then -- resort to file: lookup
+        logreport ("log", 0, "load",
+                   "path lookup of %q unsuccessful, falling back to file:",
+                   name)
+        resolve_file (specification)
+    else
+        local suffix = filesuffix (name)
+        if formats[suffix] then
+            specification.forced      = stringlower (suffix)
+            specification.name        = fileremovesuffix(name)
+            specification.forcedname  = name
+        else
+            specification.name = name
+        end
+    end
+end
+
+--[[doc--
+
+    The \verb|name:| resolver.
+
+--doc]]--
+
+--- fonts.names.resolvers.name -- Customized version of the
+--- generic name resolver.
+
+local resolve_name
+resolve_name = function (specification)
+    local resolver = names.lookup_font_name_cached
+    if config.luaotfload.run.resolver == "normal" then
+        resolver = names.lookup_font_name
+    end
+    local resolved, subfont = resolver (specification)
+    if resolved then
+        logreport ("log", 0, "load", "Lookup/name: %q -> \"%s%s\"",
+                   specification.name,
+                   resolved,
+                   subfont and stringformat ("(%d)", subfont) or "")
+        specification.resolved   = resolved
+        specification.sub        = subfont
+        specification.forced     = stringlower (filesuffix (resolved) or "")
+        specification.forcedname = resolved
+        specification.name       = fileremovesuffix (resolved)
+    else
+        resolve_file (specification)
+    end
+end
+
+--[[doc--
+
+    We classify as \verb|anon:| those requests that have neither a
+    prefix nor brackets. According to Khaled\footnote{%
+        % XXX dead link‽
+        \url{https://github.com/phi-gamma/luaotfload/issues/4#issuecomment-17090553}.
+    }
+    they are the \XETEX equivalent of a \verb|name:| request, so we
+    will be treating them as such or, at least, in a similar fashion.
+
+    Not distinguishing between “anon” and “name” requests has a serious
+    drawback: The syntax is overloaded for requesting fonts in
+    \identifier{Type1} (\abbrev{tfm}, \abbrev{ofm}) format.
+    These are essentially \verb|file:| lookups and must be caught
+    before the \verb|name:| resolver kicks in, lest they cause the
+    database to update.
+    Even if we were to require the \verb|file:| prefix for all
+    \identifier{Type1} requests, tests have shown that certain fonts
+    still include further fonts (e.~g. \fileent{omlgcb.ofm} will ask
+    for \fileent{omsecob.tfm}) \emphasis{using the old syntax}.
+    For this reason, we introduce an extra check with an early return.
+
+--doc]]--
+
+local type1_formats = { "tfm", "ofm", "TFM", "OFM", }
+
+local resolve_anon
+resolve_anon = function (specification)
+    local name = specification.name
+    for i=1, #type1_formats do
+        local format = type1_formats[i]
+        local suffix = filesuffix (name)
+        if resolvers.findfile(name, format) then
+            local usename = suffix == format and fileremovesuffix (name) or name
+            specification.forcedname = file.addsuffix (usename, format)
+            specification.forced     = format
+            return
+        end
+    end
+    --- under some weird circumstances absolute paths get
+    --- passed to the definer; we have to catch them
+    --- before the name: resolver misinterprets them.
+    name = specification.specification
+    local exists, _ = lfsisfile(name)
+    if exists then --- garbage; we do this because we are nice,
+                   --- not because it is correct
+        logreport ("log", 1, "load", "file %q exists", name)
+        logreport ("log", 1, "load",
+                   "... overriding borked anon: lookup with path: lookup")
+        specification.name = name
+        resolve_path (specification)
+        return
+    end
+    resolve_name (specification)
+end
+
+--[[doc--
+
+    {\bfseries EXPERIMENTAL}:
+    \identifier{kpse}-only resolver, for those who can do without
+    system fonts.
+
+--doc]]--
+
+local resolve_kpse
+resolve_kpse = function (specification)
+    local name       = specification.name
+    local suffix     = filesuffix (name)
+    if suffix and formats[suffix] then
+        name = fileremovesuffix (name)
+        if resolvers.findfile (name, suffix) then
+            specification.forced       = stringlower (suffix)
+            specification.forcedname   = name
+            return
+        end
+    end
+    for t, format in next, formats do --- brute force
+        if kpsefind_file (name, format) then
+            specification.forced = t
+            specification.name   = name
+            return
+        end
+    end
+end
+
+--[[doc--
+
+    Also {\bfseries EXPERIMENTAL}: custom file resolvers via callback.
+
+--doc]]--
+
+local resolve_my = function (specification)
+    luatexbase.call_callback ("luaotfload.resolve_font", specification)
+end
+
+return {
+    install = function ( )
+        luatexbase.create_callback ("luaotfload.resolve_font", "simple", function () end)
+        logreport ("log", 5, "resolvers", "installing font resolvers", name)
+        local request_resolvers = fonts.definers.resolvers
+        request_resolvers.file = resolve_file
+        request_resolvers.name = resolve_name
+        request_resolvers.anon = resolve_anon
+        request_resolvers.path = resolve_path
+        request_resolvers.kpse = resolve_kpse
+        request_resolvers.my   = resolve_my
+        return true
+    end, --- [.install]
+}
+
+--- vim:ft=lua:ts=8:sw=4:et
+
-- 
cgit v1.2.3


From 6fd86e4bb55ed30438fae708c93490485e53db9b Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg@phi-gamma.net>
Date: Sun, 26 Jul 2015 15:19:29 +0200
Subject: [db] write database if some files no longer exist on disk

Addresses issue #278: https://github.com/lualatex/luaotfload/issues/278

ATM only files whose full path is stored in the db are considered. Needs
checking whether this works for TEXMF fonts too.
---
 src/luaotfload-database.lua | 47 +++++++++++++++++++++++++++++++++------------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/luaotfload-database.lua b/src/luaotfload-database.lua
index 381185b..f4aab16 100644
--- a/src/luaotfload-database.lua
+++ b/src/luaotfload-database.lua
@@ -2239,6 +2239,28 @@ local function get_os_dirs ()
     return {}
 end
 
+--[[doc--
+
+    count_removed -- Count paths that do not exist in the file system.
+
+--doc]]--
+
+--- string list -> size_t
+local count_removed = function (old)
+    report("log", 4, "db", "Checking removed files.")
+    local nrem = 0
+    local nold = #old
+    for i = 1, nold do
+        local f = old[i]
+        if not kpsereadable_file (f) then
+            report("log", 2, "db",
+                   "File %s does not exist in file system.")
+            nrem = nrem + 1
+        end
+    end
+    return nrem
+end
+
 --[[doc--
 
     retrieve_namedata -- Scan the list of collected fonts and populate
@@ -2253,7 +2275,7 @@ end
 
 --doc]]--
 
---- string * string list -> dbobj -> dbobj -> bool? -> int
+--- string * string list -> dbobj -> dbobj -> bool? -> int * int
 local retrieve_namedata = function (files, currentnames, targetnames, dry_run)
 
     local nfiles    = #files
@@ -2348,10 +2370,7 @@ local collect_font_filenames_local = function ()
     return files
 end
 
---- dbobj -> dbobj -> int * int
-
 --- fontentry list -> filemap
-
 generate_filedata = function (mappings)
 
     report ("both", 2, "db", "Creating filename map.")
@@ -2383,7 +2402,6 @@ generate_filedata = function (mappings)
 
     for index = 1, nmappings do
         local entry    = mappings [index]
-
         local filedata = entry.file
         local format
         local location
@@ -2473,7 +2491,7 @@ generate_filedata = function (mappings)
         --- 3) add to fullpath map
 
         full [index] = fullpath
-    end
+    end --- mapping traversal
 
     return files
 end
@@ -2849,7 +2867,7 @@ end
 
 --doc]]--
 
---- unit -> string * bool list
+--- unit -> string * string list
 local collect_font_filenames = function ()
 
     report ("info", 4, "db", "Scanning the filesystem for font files.")
@@ -3098,6 +3116,8 @@ end
 --- dbobj? -> bool? -> bool? -> dbobj
 update_names = function (currentnames, force, dry_run)
     local targetnames
+    local n_new = 0
+    local n_rem = 0
 
     local conf = config.luaotfload
     if conf.run.live ~= false and conf.db.update_live == false then
@@ -3149,13 +3169,16 @@ update_names = function (currentnames, force, dry_run)
         --- pass 2: read font files (normal case) or reuse information
         --- present in index
 
+        n_rem = count_removed (currentnames.files.full)
+
         n_new = retrieve_namedata (font_filenames,
                                    currentnames,
                                    targetnames,
                                    dry_run)
+
         report ("info", 3, "db",
-                "Found %d font files; %d new entries.",
-                #font_filenames, n_new)
+                "Found %d font files; %d new, %d stale entries.",
+                #font_filenames, n_new, n_rem)
     end
 
     --- pass 3 (optional): collect some stats about the raw font info
@@ -3181,7 +3204,6 @@ update_names = function (currentnames, force, dry_run)
     --- pass 7: order design size tables
     targetnames.families    = order_design_sizes (targetnames.families)
 
-
     report ("info", 3, "db",
             "Rebuilt in %0.f ms.",
             1000 * (osgettimeofday () - starttime))
@@ -3189,8 +3211,9 @@ update_names = function (currentnames, force, dry_run)
 
     if dry_run ~= true then
 
-        if n_new == 0 then
-            report ("info", 2, "db", "No new fonts found, skip saving to disk.")
+        if n_new + n_rem == 0 then
+            report ("info", 2, "db",
+                    "No new or removed fonts, skip saving to disk.")
         else
             local success, reason = save_names ()
             if not success then
-- 
cgit v1.2.3


From 43031f08720cd2cd305e7c7b1eb5f40b52d0b36b Mon Sep 17 00:00:00 2001
From: Philipp Gesang <phg@phi-gamma.net>
Date: Sun, 26 Jul 2015 15:26:15 +0200
Subject: [*] update news

Looks like it works with TEXMF fonts just as well.
---
 NEWS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/NEWS b/NEWS
index c36825b..a1ffb1e 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,7 @@ Change History
     * Colorization was moved to the ``post_linebreak_filter`` stage
     * Move remaining functionality from ``luaotfload-override`` into
       initialization
+    * Write names index if fonts were removed
 
 2014/07/13, luaotfload v2.5
     * Remove legacy code.
-- 
cgit v1.2.3