diff options
| -rw-r--r-- | NEWS | 1 | ||||
| -rw-r--r-- | filegraph.dot | 3 | ||||
| -rw-r--r-- | luaotfload-auxiliary.lua | 61 | ||||
| -rw-r--r-- | luaotfload-database.lua | 142 | ||||
| -rw-r--r-- | luaotfload-diagnostics.lua | 3 | ||||
| -rw-r--r-- | luaotfload-features.lua | 3 | ||||
| -rw-r--r-- | luaotfload-letterspace.lua | 11 | ||||
| -rw-r--r-- | luaotfload-log.lua | 404 | ||||
| -rw-r--r-- | luaotfload-main.lua | 62 | ||||
| -rw-r--r-- | luaotfload-override.lua | 399 | ||||
| -rw-r--r-- | luaotfload-parsers.lua | 4 | ||||
| -rwxr-xr-x | luaotfload-tool.lua | 113 | ||||
| -rw-r--r-- | luaotfload-tool.rst | 4 | ||||
| -rwxr-xr-x | mkstatus | 1 | ||||
| -rwxr-xr-x | mktests | 2 | 
15 files changed, 658 insertions, 555 deletions
@@ -11,6 +11,7 @@ Change History      * Move the heavier LPEG parsers from luaotfload-features (syntax) and        luaotfload-database (fontconfig) into the new file        luaotfload-parsers.lua. +    * Move logging routines from luaotfload-override in to luaotfload-log.  2013/12/31, luaotfload v2.4      * Additional self-tests, now in separate file (luaotfload-diagnostics.lua) diff --git a/filegraph.dot b/filegraph.dot index 90e6e5c..47db9ea 100644 --- a/filegraph.dot +++ b/filegraph.dot @@ -200,8 +200,9 @@ strict digraph luaotfload_files { //looks weird with circo ...                  <th> <td colspan="2"> <font point-size="12" face="Iwona Italic">Luaotfload Libraries</font> </td> </th>                  <tr> <td>luaotfload-auxiliary.lua</td>    <td>luaotfload-features.lua</td>    </tr>                  <tr> <td>luaotfload-override.lua</td>     <td>luaotfload-loaders.lua</td>     </tr> +                <tr> <td>luaotfload-log.lua</td>          <td>luaotfload-letterspace.lua</td> </tr>                  <tr> <td>luaotfload-parsers.lua</td>      <td>luaotfload-database.lua</td>    </tr> -                <tr> <td>luaotfload-color.lua</td>        <td>luaotfload-letterspace.lua</td> </tr> +                <tr> <td>luaotfload-color.lua</td>                                            </tr>              </table>          >,      ] diff --git a/luaotfload-auxiliary.lua b/luaotfload-auxiliary.lua index 334ac47..716af98 100644 --- a/luaotfload-auxiliary.lua +++ b/luaotfload-auxiliary.lua @@ -17,7 +17,7 @@ luaotfload.aux              = luaotfload.aux or { }  local aux                   = luaotfload.aux  local log                   = luaotfload.log -local warning               = luaotfload.log +local report                = log.report  local fonthashes            = fonts.hashes  local identifiers           = fonthashes.identifiers @@ -54,8 +54,8 @@ local start_rewrite_fontname = function ()        rewrite_fontname,        "luaotfload.rewrite_fontname")      rewriting = true -    logs.names_report ("log", 0, "aux", -                       "start rewriting tfmdata.name field") +    report ("log", 0, "aux", +            "start rewriting tfmdata.name field")    end  end @@ -66,8 +66,8 @@ local stop_rewrite_fontname = function ()      luatexbase.remove_fromt_callback        ("luaotfload.patch_font", "luaotfload.rewrite_fontname")      rewriting = false -    logs.names_report ("log", 0, "aux", -                       "stop rewriting tfmdata.name field") +    report ("log", 0, "aux", +            "stop rewriting tfmdata.name field")    end  end @@ -366,7 +366,7 @@ do    local load_chardef = function () -    log ("Loading character metadata from %s.", chardef) +    report ("both", 1, "aux", "Loading character metadata from %s.", chardef)      chardata = dofile (kpse.find_file (chardef, "lua"))      if chardata == nil then @@ -424,19 +424,19 @@ local provides_script = function (font_id, asked_script)          --- where method: "gpos" | "gsub"          for feature, data in next, featuredata do            if data[asked_script] then -            log(stringformat( -              "font no %d (%s) defines feature %s for script %s", -              font_id, fontname, feature, asked_script)) +            report ("log", 1, "aux", +                    "font no %d (%s) defines feature %s for script %s", +                    font_id, fontname, feature, asked_script)              return true            end          end        end -      log(stringformat( -        "font no %d (%s) defines no feature for script %s", -        font_id, fontname, asked_script)) +      report ("log", 0, "aux", +              "font no %d (%s) defines no feature for script %s", +              font_id, fontname, asked_script)      end    end -  log(stringformat("no font with id %d", font_id)) +  report ("log", 0, "aux", "no font with id %d", font_id)    return false  end @@ -463,20 +463,22 @@ local provides_language = function (font_id, asked_script, asked_language)          for feature, data in next, featuredata do            local scriptdata = data[asked_script]            if scriptdata and scriptdata[asked_language] then -            log(stringformat("font no %d (%s) defines feature %s " -                          .. "for script %s with language %s", -                             font_id, fontname, feature, -                             asked_script, asked_language)) +            report ("log", 1, "aux", +                    "font no %d (%s) defines feature %s " +                    .. "for script %s with language %s", +                    font_id, fontname, feature, +                    asked_script, asked_language)              return true            end          end        end -      log(stringformat( -        "font no %d (%s) defines no feature for script %s with language %s", -        font_id, fontname, asked_script, asked_language)) +      report ("log", 0, "aux", +              "font no %d (%s) defines no feature " +              .. "for script %s with language %s", +              font_id, fontname, asked_script, asked_language)      end    end -  log(stringformat("no font with id %d", font_id)) +  report ("log", 0, "aux", "no font with id %d", font_id)    return false  end @@ -534,20 +536,21 @@ local provides_feature = function (font_id,        asked_script,          if feature then            local scriptdata = feature[asked_script]            if scriptdata and scriptdata[asked_language] then -            log(stringformat("font no %d (%s) defines feature %s " -                          .. "for script %s with language %s", -                             font_id, fontname, asked_feature, -                             asked_script, asked_language)) +            report ("log", 1, "aux", +                    "font no %d (%s) defines feature %s " +                    .. "for script %s with language %s", +                    font_id, fontname, asked_feature, +                    asked_script, asked_language)              return true            end          end        end -      log(stringformat( -        "font no %d (%s) does not define feature %s for script %s with language %s", -        font_id, fontname, asked_feature, asked_script, asked_language)) +      report ("log", 0, "aux", +              "font no %d (%s) does not define feature %s for script %s with language %s", +              font_id, fontname, asked_feature, asked_script, asked_language)      end    end -  log(stringformat("no font with id %d", font_id)) +  report ("log", 0, "aux", "no font with id %d", font_id)    return false  end diff --git a/luaotfload-database.lua b/luaotfload-database.lua index 77a7162..c69fc03 100644 --- a/luaotfload-database.lua +++ b/luaotfload-database.lua @@ -44,6 +44,13 @@ local read_fonts_conf          = parsers.read_fonts_conf  local stripslashes             = parsers.stripslashes  local splitcomma               = parsers.splitcomma +local log                      = luaotfload.log +local report                   = log.report +local report_status            = log.names_status +local report_status_start      = log.names_status_start +local report_status_stop       = log.names_status_stop + +  --- Luatex builtins  local load                     = load  local next                     = next @@ -151,11 +158,6 @@ local make_luanames = function (path)             filereplacesuffix(path, "luc")  end -local report                = logs.names_report -local report_status         = logs.names_status -local report_status_start   = logs.names_status_start -local report_status_stop    = logs.names_status_stop -  --- The “termwidth” value is only considered when printing  --- short status messages, e.g. when building the database  --- online. @@ -231,7 +233,11 @@ if not runasscript then      index.lua, index.luc     = make_luanames (index_file)  else --- running as script, inject some dummies      caches = { } -    logs   = { report = function () end } +    local dummy_function = function () end +    log   = { report                = dummy_function, +              report_status         = dummy_function, +              report_status_start   = dummy_function, +              report_status_stop    = dummy_function, }  end @@ -1373,23 +1379,7 @@ local get_size_info = function (metadata)      return false  end -local get_english_names = function (metadata, basename) -    local validation_state = metadata.validation_state -    if validation_state -        and tablecontains (validation_state, "bad_ps_fontname") -    then -        report("both", 3, "db", -               "%s has invalid postscript font names, using dummies.", -               basename) -        --- Broken names table, e.g. avkv.ttf with UTF-16 strings; -        --- we put some dummies in place like the fontloader -        --- (font-otf.lua) does. -        return { -            fontname = "bad-fontname-" .. basename, -            fullname = "bad-fullname-" .. basename, -        } -    end - +local get_english_names = function (metadata)      local names = metadata.names      local english_names @@ -1397,34 +1387,78 @@ local get_english_names = function (metadata, basename)          --inspect(names)          for _, raw_namedata in next, names do              if raw_namedata.lang == "English (US)" then -                english_names = raw_namedata.names +                return raw_namedata.names              end          end      end -    if not english_names then -        -- no (English) names table, probably a broken font +    -- no (English) names table, probably a broken font +    report("both", 3, "db", +            "%s: missing or broken English names table.", basename) +    return { fontname = metadata.fontname, +             fullname = metadata.fullname, } +end + +--[[-- +    In case of broken PS names we set some dummies. However, we cannot +    directly modify the font data as returned by fontloader.open() because +    it is a userdata object. + +    For this reason we copy what is necessary whilst keeping the table +    structure the same as in the tfmdata. +--]]-- +local get_raw_info = function (metadata, basename) +    local fullname +    local fontname +    local psname + +    local validation_state = metadata.validation_state +    if validation_state +        and tablecontains (validation_state, "bad_ps_fontname") +    then +        --- Broken names table, e.g. avkv.ttf with UTF-16 strings; +        --- we put some dummies in place like the fontloader +        --- (font-otf.lua) does.          report("both", 3, "db", -               "%s: missing or broken names table.", basename) +               "%s has invalid postscript font names, using dummies.", +               basename) +        fontname = "bad-fontname-" .. basename +        fullname = "bad-fullname-" .. basename +    else +        fontname = metadata.fontname +        fullname = metadata.fullname      end -    return english_names or { } +    return { +        familyname          = metadata.familyname, +        fontname            = fontname, +        fontstyle_name      = metadata.fontstyle_name, +        fullname            = fullname, +        italicangle         = metadata.italicangle, +        names               = metadata.names, +        pfminfo             = metadata.pfminfo, +        units_per_em        = metadata.units_per_em, +        version             = metadata.version, +        design_size         = metadata.design_size, +        design_range_top    = metadata.design_range_top, +        design_range_bottom = metadata.design_range_bottom, +    }  end -local organize_namedata = function (metadata, +local organize_namedata = function (rawinfo,                                      english_names,                                      basename,                                      info)      local default_name = english_names.compatfull                        or english_names.fullname                        or english_names.postscriptname -                      or metadata.fullname -                      or metadata.fontname +                      or rawinfo.fullname +                      or rawinfo.fontname                        or info.fullname                        or info.fontname      local default_family = english_names.preffamily                          or english_names.family -                        or metadata.familyname +                        or rawinfo.familyname                          or info.familyname  --    local default_modifier = english_names.prefmodifiers  --                          or english_names.subfamily @@ -1458,9 +1492,9 @@ local organize_namedata = function (metadata,          },          metadata = { -            fullname      = metadata.fullname, -            fontname      = metadata.fontname, -            familyname    = metadata.familyname, +            fullname      = rawinfo.fullname, +            fontname      = rawinfo.fontname, +            familyname    = rawinfo.familyname,          },          info = { @@ -1471,14 +1505,14 @@ local organize_namedata = function (metadata,      }      -- see http://www.microsoft.com/typography/OTSPEC/features_pt.htm#size -    if metadata.fontstyle_name then +    if rawinfo.fontstyle_name then          --- not present in all fonts, often differs from the preferred          --- subfamily as well as subfamily fields, e.g. with          --- LMSans10-BoldOblique:          ---     subfamily:      “Bold Italic”          ---     prefmodifiers:  “10 Bold Oblique”          ---     fontstyle_name: “Bold Oblique” -        for _, name in next, metadata.fontstyle_name do +        for _, name in next, rawinfo.fontstyle_name do              if name.lang == 1033 then --- I hate magic numbers                  fontnames.fontstyle_name = name.name              end @@ -1487,9 +1521,9 @@ local organize_namedata = function (metadata,      return {          sanitized     = sanitize_fontnames (fontnames), -        fontname      = metadata.fontname, -        fullname      = metadata.fullname, -        familyname    = metadata.familyname, +        fontname      = rawinfo.fontname, +        fullname      = rawinfo.fullname, +        familyname    = rawinfo.familyname,      }  end @@ -1546,13 +1580,18 @@ ot_fullinfo = function (filename,          return nil      end -    local english_names = get_english_names (metadata, basename) -    local namedata      = organize_namedata (metadata, +    local rawinfo = get_raw_info (metadata, basename) +    --- Closing the file manually is a tad faster and more memory +    --- efficient than having it closed by the gc +    fontloaderclose (metadata) + +    local english_names = get_english_names (rawinfo) +    local namedata      = organize_namedata (rawinfo,                                               english_names,                                               basename,                                               info)      local style         = organize_styledata (namedata.fontname, -                                              metadata, +                                              rawinfo,                                                english_names,                                                info) @@ -1564,11 +1603,8 @@ ot_fullinfo = function (filename,          format          = format,          names           = namedata,          style           = style, -        version         = metadata.version, +        version         = rawinfo.version,      } -    --- Closing the file manually is a tad faster and more memory -    --- efficient than having it closed by the gc -    fontloaderclose (metadata)      return res  end @@ -2254,7 +2290,7 @@ local scan_texmf_fonts = function (currentnames, targetnames, dry_run)          report ("info", 1, "db", "Scanning TEXMF fonts...")      else          report ("info", 1, "db", "Scanning TEXMF and OS fonts...") -        if logs.get_loglevel () > 3 then +        if log.get_loglevel () > 3 then              local osdirs = filesplitpath (osfontdir)              report ("info", 0, "db",                      "$OSFONTDIR has %d entries:", #osdirs) @@ -2577,7 +2613,7 @@ local pull_values = function (entry)      --- pull name info ...      entry.psname            = english.psname -    entry.fontname          = info.fontname +    entry.fontname          = info.fontname or metadata.fontname      entry.fullname          = english.fullname or info.fullname      entry.splainname        = metadata.fullname      entry.prefmodifiers     = english.prefmodifiers @@ -2949,7 +2985,7 @@ local collect_statistics = function (mappings)      local n_fullname = setsize (fullname)      local n_family   = setsize (family) -    if logs.get_loglevel () > 1 then +    if log.get_loglevel () > 1 then          local pprint_top = function (hash, n, set)              local freqs = { } @@ -3135,7 +3171,7 @@ update_names = function (currentnames, force, dry_run)          if success then              local success = save_lookups ()              if success then -                logs.names_report ("info", 2, "cache", +                report ("info", 2, "cache",                                     "Lookup cache emptied.")                  return targetnames              end @@ -3324,7 +3360,7 @@ end  local purge_cache = function ( )      local writable_path = getwritablecachepath ()      local luanames, lucnames, rest = collect_cache(writable_path) -    if logs.get_loglevel() > 1 then +    if log.get_loglevel() > 1 then          print_cache("writable path", writable_path, luanames, lucnames, rest)      end      local success = purge_from_cache("writable path", writable_path, luanames, false) @@ -3335,7 +3371,7 @@ end  local erase_cache = function ( )      local writable_path = getwritablecachepath ()      local luanames, lucnames, rest, all = collect_cache(writable_path) -    if logs.get_loglevel() > 1 then +    if log.get_loglevel() > 1 then          print_cache("writable path", writable_path, luanames, lucnames, rest)      end      local success = purge_from_cache("writable path", writable_path, all, true) diff --git a/luaotfload-diagnostics.lua b/luaotfload-diagnostics.lua index 1ae9a90..67119de 100644 --- a/luaotfload-diagnostics.lua +++ b/luaotfload-diagnostics.lua @@ -49,8 +49,9 @@ local lpeg                     = require "lpeg"  local C, Cg, Ct                = lpeg.C, lpeg.Cg, lpeg.Ct  local lpegmatch                = lpeg.match +local report                   = luaotfload.log.report  local out = function (...) -    logs.names_report (false, 0, "diagnose", ...) +    report (false, 0, "diagnose", ...)  end  local parsers                  = luaotfload.parsers diff --git a/luaotfload-features.lua b/luaotfload-features.lua index 5172f4b..4237d71 100644 --- a/luaotfload-features.lua +++ b/luaotfload-features.lua @@ -48,7 +48,8 @@ function fonts.definers.getspecification(str)      return "", str, "", ":", str  end -local report = logs.names_report +local log              = luaotfload.log +local report           = log.report  local stringfind       = string.find  local stringlower      = string.lower diff --git a/luaotfload-letterspace.lua b/luaotfload-letterspace.lua index 1957f9a..20f29f5 100644 --- a/luaotfload-letterspace.lua +++ b/luaotfload-letterspace.lua @@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['letterspace'] = {      license   = "see context related readme files"  } +local log                = luaotfload.log +local report             = log.report +  local getmetatable       = getmetatable  local require            = require  local setmetatable       = setmetatable @@ -512,10 +515,10 @@ otffeatures.register {  local initializecompatfontkerning = function (tfmdata, percentage)    local factor = tonumber (percentage)    if not factor then -    logs.names_report ("both", 0, "letterspace", -                       "Invalid argument to letterspace: %s (type %q), " .. -                       "was expecting percentage as Lua number instead.", -                       percentage, type (percentage)) +    report ("both", 0, "letterspace", +            "Invalid argument to letterspace: %s (type %q), " .. +            "was expecting percentage as Lua number instead.", +            percentage, type (percentage))      return    end    return initializefontkerning (tfmdata, factor * 0.01) diff --git a/luaotfload-log.lua b/luaotfload-log.lua new file mode 100644 index 0000000..5698c84 --- /dev/null +++ b/luaotfload-log.lua @@ -0,0 +1,404 @@ +if not modules then modules = { } end modules ["luaotfload-log"] = { +    version   = "2.5", +    comment   = "companion to Luaotfload", +    author    = "Khaled Hosny, Elie Roux, Philipp Gesang", +    copyright = "Luaotfload Development Team", +    license   = "GNU GPL v2.0" +} + +--[[doc-- +The logging system is slow in general, as we always have the function +call overhead even if we aren’t going to output anything. On the other +hand, the more efficient approach followed by Context isn’t an option +because we lack a user interface to toggle per-subsystem tracing. +--doc]]-- + +local module_name       = "luaotfload" --- prefix for messages + +luaotfload              = luaotfload or { } +luaotfload.log          = luaotfload.log or { } +local log               = luaotfload.log + +local ioopen            = io.open +local iowrite           = io.write +local lfsisdir          = lfs.isdir +local lfsisfile         = lfs.isfile +local osdate            = os.date +local ostime            = os.time +local osuuid            = os.uuid +local select            = select +local stringformat      = string.format +local stringsub         = string.sub +local tableconcat       = table.concat +local texiowrite_nl     = texio.write_nl +local texiowrite        = texio.write +local type              = type + +local dummyfunction     = function () end + +local texjob = false +if tex and (tex.jobname or tex.formatname) then +    --- TeX +    texjob = true +end + +local loglevel = 0 --- default +local logout   = "log" + +--- int -> bool +local set_loglevel = function (n) +    if type(n) == "number" then +        loglevel = n +    end +    return true +end +log.set_loglevel   = set_loglevel + +--- unit -> int +local get_loglevel = function ( ) +    return loglevel +end +log.get_loglevel   = get_loglevel + +local writeln  --- pointer to terminal/log writer +local statusln --- terminal writer that reuses the current line +local first_status = true --- indicate the begin of a status region + +local log_msg = [[ +logging output redirected to %s +to monitor the progress run "tail -f %s" in another terminal +]] + +local tmppath = os.getenv "TMPDIR" or "/tmp" + +local choose_logfile = function ( ) +    if lfsisdir (tmppath) then +        local fname +        repeat --- ensure that file of that name doesn’t exist +            fname = tmppath .. "/luaotfload-log-" .. osuuid() +        until not lfsisfile (fname) +        iowrite (stringformat (log_msg, fname, fname)) +        return ioopen (fname, "w") +    end +    --- missing /tmp +    return false +end + +local set_logout = function (s, finalizers) +    if s == "stdout" then +        logout = "redirect" +    elseif s == "file" then --- inject custom logger +        logout = "redirect" +        local chan = choose_logfile () +        chan:write (stringformat ("logging initiated at %s", +                                  osdate ("%F %T", ostime ()))) +        local writefile = function (...) +            if select ("#", ...) == 2 then +                chan:write (select (2, ...)) +            else +                chan:write (select (1, ...)) +            end +        end +        local writefile_nl= function (...) +            chan:write "\n" +            if select ("#", ...) == 2 then +                chan:write (select (2, ...)) +            else +                chan:write (select (1, ...)) +            end +        end + +        local writeln_orig = writeln + +        texiowrite    = writefile +        texiowrite_nl = writefile_nl +        writeln       = writefile_nl +        statusln      = dummyfunction + +        finalizers[#finalizers+1] = function () +            chan:write (stringformat ("\nlogging finished at %s\n", +                                      osdate ("%F %T", ostime ()))) +            chan:close () +            texiowrite    = texio.write +            texiowrite_nl = texio.write_nl +            writeln       = writeln_orig +        end +    --else --- remains “log” +    end +    return finalizers +end + +log.set_logout = set_logout + +local basic_logger = function (category, fmt, ...) +    local res = { module_name, "|", category, ":" } +    if fmt then +        res [#res + 1] = stringformat (fmt, ...) +    end +    texiowrite_nl (logout, tableconcat(res, " ")) +end + +--- with faux db update with maximum verbosity: +--- +---     ---------   -------- +---     buffering   time (s) +---     ---------   -------- +---     full        4.12 +---     line        4.20 +---     none        4.39 +---     ---------   -------- +--- + +io.stdout:setvbuf "no" +io.stderr:setvbuf "no" + +local kill_line = "\r\x1b[K" + +if texjob == true then +    --- We imitate the texio.* functions so the output is consistent. +    writeln = function (str) +        iowrite "\n" +        iowrite(str) +    end +    statusln = function (str) +        if first_status == false then +            iowrite (kill_line) +        else +            iowrite "\n" +        end +        iowrite (str) +    end +else +    writeln = function (str) +        iowrite(str) +        iowrite "\n" +    end +    statusln = function (str) +        if first_status == false then +            iowrite (kill_line) +        end +        iowrite (str) +    end +end + +stdout = function (writer, category, ...) +    local res = { module_name, "|", category, ":" } +    local nargs = select("#", ...) +    if nargs == 0 then +        --writeln tableconcat(res, " ") +        --return +    elseif nargs == 1 then +        res[#res+1] = select(1, ...) -- around 30% faster than unpack() +    else +        res[#res+1] = stringformat(...) +    end +    writer (tableconcat(res, " ")) +end + +--- at default (zero), we aim to be quiet +local level_ids = { common  = 1, loading = 2, search  = 3 } + +--[[doc-- + +    The report() logger is used more or less all over luaotfload. +    Its requirements are twofold: + +    1) Provide two logging channels, the terminal and the log file; +    2) Allow for control over verbosity levels. + +    The first part is addressed by specifying the log *mode* as the +    first argument that can be either “log”, meaning the log file, or +    “both”: log file and stdout. Anything else is taken as referring to +    stdout only. + +    Verbosity levels, though not as fine-grained as e.g. Context’s +    system of tracers, allow keeping the logging spam caused by +    different subsystems manageable. By default, luaotfload will not +    emit anything if things are running smoothly on level zero. Only +    warning messages are relayed, while the other messages are skipped +    over. (This is a little sub-optimal performance-wise since the +    function calls to the logger are executed regardless.) The log +    level during a Luatex run can be adjusted by setting the “loglevel” +    field in config.luaotfload, or by calling log.set_loglevel() as +    defined above. + +--doc]]-- + +local report = function (mode, lvl, ...) +    if type(lvl) == "string" then +        lvl = level_ids[lvl] +    end +    if not lvl then lvl = 0 end + +    if loglevel >= lvl then +        if mode == "log" then +            basic_logger (...) +        elseif mode == "both" and logout ~= "redirect" then +            basic_logger (...) +            stdout (writeln, ...) +        else +            stdout (writeln, ...) +        end +    end +end + +log.report = report + +--[[doc-- + +    status_logger -- Overwrites the most recently printed line of the +    terminal. Its purpose is to provide feedback without spamming +    stdout with irrelevant messages, i.e. when building the database. + +    Status logging must be initialized by calling status_start() and +    properly reset via status_stop(). + +    The arguments low and high indicate the loglevel threshold at which +    linewise and full logging is triggered, respectively. E.g. + +            names_status (1, 4, "term", "Hello, world!") + +    will print nothing if the loglevel is less than one, reuse the +    current line if the loglevel ranges from one to three inclusively, +    and output the message on a separate line otherwise. + +--doc]]-- + +local status_logger = function (mode, ...) +    if mode == "log" then +        basic_logger (...) +    else +        if mode == "both" and logout ~= "redirect" then +            basic_logger (...) +            stdout (statusln, ...) +        else +            stdout (statusln, ...) +        end +        first_status = false +    end +end + +--[[doc-- + +    status_start -- Initialize status logging. This installs the status +        logger if the loglevel is in the specified range, and the normal +        logger otherwise.  It also resets the first line state which +        causing the next line printed using the status logger to not kill +        the current line. + +--doc]]-- + +local status_writer +local status_low  = 99 +local status_high = 99 + +local status_start = function (low, high) +    first_status = true +    status_low   = low +    status_high  = high + +    if os.type == "windows" --- Assume broken terminal. +    or os.getenv "TERM" == "dumb" +    then +        status_writer = function (mode, ...) +            report (mode, high, ...) +        end +        return +    end + +    if low <= loglevel and loglevel < high then +        status_writer = status_logger +    else +        status_writer = function (mode, ...) +            report (mode, high, ...) +        end +    end +end + +--[[doc-- + +    status_stop -- Finalize a status region by outputting a newline and +    printing a message. + +--doc]]-- + +local status_stop = function (...) +    if first_status == false then +        status_writer(...) +        if texjob == false then +            writeln "" +        end +    end +end + +log.names_status = function (...) status_writer (...) end +log.names_status_start = status_start +log.names_status_stop  = status_stop + +--[[doc-- + +    The fontloader comes with the Context logging mechanisms +    inaccessible. Instead, it provides dumb fallbacks based +    on the functions in texio.write*() that can be overridden +    by providing a function texio.reporter(). + +    The fontloader output can be quite verbose, so we disable +    it entirely by default. + +--doc]]-- + +local texioreporter = function (message) +    report ("log", 2, message) +end + +texio.reporter = texioreporter + +--[[doc-- + +    Adobe Glyph List. +    ------------------------------------------------------------------- + +    Context provides a somewhat different font-age.lua from an unclear +    origin. Unfortunately, the file name it reads from is hard-coded +    in font-enc.lua, so we have to replace the entire table. + +    This shouldn’t cause any complications. Due to its implementation +    the glyph list will be loaded upon loading a OTF or TTF for the +    first time during a TeX run. (If one sticks to TFM/OFM then it is +    never read at all.) For this reason we can install a metatable that +    looks up the file of our choosing and only falls back to the +    Context one in case it cannot be found. + +--doc]]-- + +if fonts then --- need to be running TeX +    if next(fonts.encodings.agl) then +        --- unnecessary because the file shouldn’t be loaded at this time +        --- but we’re just making sure +        fonts.encodings.agl = nil +        collectgarbage"collect" +    end + + +    fonts.encodings.agl = { } + +    setmetatable(fonts.encodings.agl, { __index = function (t, k) +        if k == "unicodes" then +            local glyphlist = resolvers.findfile"luaotfload-glyphlist.lua" +            if glyphlist then +                report ("log", 1, "load", "loading the Adobe glyph list") +            else +                glyphlist = resolvers.findfile"font-age.lua" +                report ("both", 0, "load", +                    "loading the extended glyph list from ConTeXt") +            end +            local unicodes      = dofile(glyphlist) +            fonts.encodings.agl = { unicodes = unicodes } +            return unicodes +        else +            return nil +        end +    end }) +end + +-- vim:tw=71:sw=4:ts=4:expandtab diff --git a/luaotfload-main.lua b/luaotfload-main.lua index 27f0a99..f5f012d 100644 --- a/luaotfload-main.lua +++ b/luaotfload-main.lua @@ -4,7 +4,7 @@  -- REQUIREMENTS:  luatex v.0.78 or later, the lualibs package  --       AUTHOR:  Élie Roux, Khaled Hosny, Philipp Gesang  --      VERSION:  same as Luaotfload ---     MODIFIED:  2014-01-16 06:51:20+0100 +--     MODIFIED:  2014-02-09 14:42:22+0100  -----------------------------------------------------------------------  --  --- Note: @@ -45,6 +45,7 @@ if not modules then modules = { } end modules ["luaotfload-main"] = {  luaotfload                        = luaotfload or { }  local luaotfload                  = luaotfload +luaotfload.log                    = luaotfload.log or { }  config                            = config or { }  config.luaotfload                 = config.luaotfload or { } @@ -91,10 +92,12 @@ local dummy_function = function () end  local error, warning, info, log =      luatexbase.provides_module(luaotfload.module) -luaotfload.error        = error -luaotfload.warning      = warning -luaotfload.info         = info -luaotfload.log          = log +luaotfload.log.tex        = { +    error        = error, +    warning      = warning, +    info         = info, +    log          = log, +}  --[[doc-- @@ -143,6 +146,12 @@ local loadmodule = function (name)      require(fl_prefix .."-"..name)  end +loadmodule "log.lua"        --- messages; used to be part of -override +local log             = luaotfload.log +local report          = log.report + +log.set_loglevel(config.luaotfload.loglevel) +  --[[doc--    Before \TeX Live 2013 version, \LUATEX had a bug that made ofm fonts @@ -167,7 +176,8 @@ local find_vf_file = function (name)          fullname = kpsefind_file(lpegmatch(p_removesuffix, name), "ovf")      end      if fullname then -        log("loading virtual font file %s.", fullname) +        report ("log", 0, "main", +                "loading virtual font file %s.", fullname)      end      return fullname  end @@ -251,7 +261,7 @@ end  local context_environment = { }  local push_namespaces = function () -    log("push namespace for font loader") +    report ("log", 1, "main", "push namespace for font loader")      local normalglobal = { }      for k, v in next, _G do          normalglobal[k] = v @@ -264,7 +274,7 @@ local pop_namespaces = function (normalglobal, isolate)          local _G = _G          local mode = "non-destructive"          if isolate then mode = "destructive" end -        log("pop namespace from font loader -- " .. mode) +        report ("log", 1, "main", "pop namespace from font loader -- " .. mode)          for k, v in next, _G do              if not normalglobal[k] then                  context_environment[k] = v @@ -279,7 +289,8 @@ local pop_namespaces = function (normalglobal, isolate)          -- just to be sure:          setmetatable(context_environment,_G)      else -        log("irrecoverable error during pop_namespace: no globals to restore") +        report ("both", 0, "main", +                "irrecoverable error during pop_namespace: no globals to restore")          os.exit()      end  end @@ -312,13 +323,13 @@ loadmodule "fontloader.lua"  if fonts then      if not fonts._merge_loaded_message_done_ then -        log [["I am using the merged fontloader here.]] -        log [[ If you run into problems or experience unexpected]] -        log [[ behaviour, and if you have ConTeXt installed you can try]] -        log [[ to delete the file 'luaotfload-fontloader.lua' as I might]] -        log [[ then use the possibly updated libraries. The merged]] -        log [[ version is not supported as it is a frozen instance.]] -        log [[ Problems can be reported to the ConTeXt mailing list."]] +        report ("log", 0, "main", [["I am using the merged fontloader here.]]) +        report ("log", 0, "main", [[ If you run into problems or experience unexpected]]) +        report ("log", 0, "main", [[ behaviour, and if you have ConTeXt installed you can try]]) +        report ("log", 0, "main", [[ to delete the file 'luaotfload-fontloader.lua' as I might]]) +        report ("log", 0, "main", [[ then use the possibly updated libraries. The merged]]) +        report ("log", 0, "main", [[ version is not supported as it is a frozen instance.]]) +        report ("log", 0, "main", [[ Problems can be reported to the ConTeXt mailing list."]])      end      fonts._merge_loaded_message_done_ = true @@ -376,7 +387,8 @@ end --- non-merge fallback scope  pop_namespaces(our_environment, false)-- true) -log("fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime) +report ("both", 0, "main", +        "fontloader loaded in %0.3f seconds", os.gettimeofday()-starttime)  --[[doc-- @@ -409,9 +421,7 @@ add_to_callback("hpack_filter",  add_to_callback("find_vf_file",                  find_vf_file, "luaotfload.find_vf_file") -loadmodule "override.lua"   --- “luat-ovr” - -logs.set_loglevel(config.luaotfload.loglevel) +loadmodule "override.lua"   --- load glyphlist on demand  --[[doc-- @@ -534,9 +544,9 @@ request_resolvers.anon = function (specification)      local exists, _ = lfsisfile(name)      if exists then --- garbage; we do this because we are nice,                     --- not because it is correct -        logs.names_report("log", 1, "load", "file %q exists", name) -        logs.names_report("log", 1, "load", -          "... overriding borked anon: lookup with path: lookup") +        report ("log", 1, "load", "file %q exists", name) +        report ("log", 1, "load", +                "... overriding borked anon: lookup with path: lookup")          specification.name = name          request_resolvers.path(specification)          return @@ -558,9 +568,9 @@ request_resolvers.path = function (specification)      local name       = specification.name      local exists, _  = lfsisfile(name)      if not exists then -- resort to file: lookup -        logs.names_report("log", 1, "load", -          "path lookup of %q unsuccessful, falling back to file:", -          name) +        report ("log", 1, "load", +                "path lookup of %q unsuccessful, falling back to file:", +                name)          file_resolver (specification)      else          local suffix = filesuffix (name) diff --git a/luaotfload-override.lua b/luaotfload-override.lua index 7cb9c5d..b75530b 100644 --- a/luaotfload-override.lua +++ b/luaotfload-override.lua @@ -1,4 +1,4 @@ -if not modules then modules = { } end modules ['luat-ovr'] = { +if not modules then modules = { } end modules ["luaotfload-override"] = {      version   = "2.5",      comment   = "companion to Luaotfload",      author    = "Khaled Hosny, Elie Roux, Philipp Gesang", @@ -6,355 +6,11 @@ if not modules then modules = { } end modules ['luat-ovr'] = {      license   = "GNU GPL v2.0"  } ---[[doc-- -The logging system is slow in general, as we always have the function -call overhead even if we aren’t going to output anything. On the other -hand, the more efficient approach followed by Context isn’t an option -because we lack a user interface to toggle per-subsystem tracing. ---doc]]-- - -local module_name       = "luaotfload" - -local ioopen            = io.open -local iowrite           = io.write -local lfsisdir          = lfs.isdir -local lfsisfile         = lfs.isfile -local md5sumhexa        = md5.sumhexa -local osdate            = os.date -local ostime            = os.time -local select            = select -local stringformat      = string.format -local stringsub         = string.sub -local tableconcat       = table.concat -local texio_write_nl    = texio.write_nl -local texiowrite_nl     = texio.write_nl -local texio_write       = texio.write -local texiowrite        = texio.write -local type              = type - -local dummyfunction     = function () end - -local texjob = false -if tex and (tex.jobname or tex.formatname) then -    --- TeX -    texjob = true -end - -local loglevel = 0 --- default -local logout   = "log" - ---- int -> bool -local set_loglevel = function (n) -    if type(n) == "number" then -        loglevel = n -    end -    return true -end -logs.setloglevel    = set_loglevel -logs.set_loglevel   = set_loglevel -logs.set_log_level  = set_loglevel --- accomodating lazy typists - ---- unit -> int -local get_loglevel = function ( ) -    return loglevel -end -logs.getloglevel    = get_loglevel -logs.get_loglevel   = get_loglevel -logs.get_log_level  = get_loglevel - -local writeln  --- pointer to terminal/log writer -local statusln --- terminal writer that reuses the current line -local first_status = true --- indicate the begin of a status region - -local log_msg = [[ -logging output redirected to %s -to monitor the progress run "tail -f %s" in another terminal -]] - -local tmppath = os.getenv "TMPDIR" or "/tmp" - -local choose_logfile = function ( ) -    if lfsisdir (tmppath) then -        local fname -        repeat --- ensure that file of that name doesn’t exist -            fname = tmppath .. "/luaotfload-log-" -                            .. stringsub (md5sumhexa (ostime ()), 1, 8) -        until not lfsisfile (fname) -        iowrite (stringformat (log_msg, fname, fname)) -        return ioopen (fname, "w") -    end -    --- missing /tmp -    return false -end - -local set_logout = function (s, finalizers) -    if s == "stdout" then -        logout = "redirect" -    elseif s == "file" then --- inject custom logger -        logout = "redirect" -        local chan = choose_logfile () -        chan:write (stringformat ("logging initiated at %s", -                                  osdate ("%F %T", ostime ()))) -        local writefile = function (...) -            if select ("#", ...) == 2 then -                chan:write (select (2, ...)) -            else -                chan:write (select (1, ...)) -            end -        end -        local writefile_nl= function (...) -            chan:write "\n" -            if select ("#", ...) == 2 then -                chan:write (select (2, ...)) -            else -                chan:write (select (1, ...)) -            end -        end - -        local writeln_orig = writeln - -        texiowrite    = writefile -        texiowrite_nl = writefile_nl -        writeln       = writefile_nl -        statusln      = dummyfunction - -        finalizers[#finalizers+1] = function () -            chan:write (stringformat ("\nlogging finished at %s\n", -                                      osdate ("%F %T", ostime ()))) -            chan:close () -            texiowrite    = texio.write -            texiowrite_nl = texio.write_nl -            writeln       = writeln_orig -        end -    --else --- remains “log” -    end -    return finalizers -end - -logs.set_logout = set_logout - -local log = function (category, fmt, ...) -    local res = { module_name, "|", category, ":" } -    if fmt then -        res [#res + 1] = stringformat (fmt, ...) -    end -    texiowrite_nl (logout, tableconcat(res, " ")) -end - ---- with faux db update with maximum verbosity: ---- ----     ---------   -------- ----     buffering   time (s) ----     ---------   -------- ----     full        4.12 ----     line        4.20 ----     none        4.39 ----     ---------   -------- ---- - -io.stdout:setvbuf "no" -io.stderr:setvbuf "no" - -local kill_line = "\r\x1b[K" - -if texjob == true then -    --- We imitate the texio.* functions so the output is consistent. -    writeln = function (str) -        iowrite "\n" -        iowrite(str) -    end -    statusln = function (str) -        if first_status == false then -            iowrite (kill_line) -        else -            iowrite "\n" -        end -        iowrite (str) -    end -else -    writeln = function (str) -        iowrite(str) -        iowrite "\n" -    end -    statusln = function (str) -        if first_status == false then -            iowrite (kill_line) -        end -        iowrite (str) -    end -end - -stdout = function (writer, category, ...) -    local res = { module_name, "|", category, ":" } -    local nargs = select("#", ...) -    if nargs == 0 then -        --writeln tableconcat(res, " ") -        --return -    elseif nargs == 1 then -        res[#res+1] = select(1, ...) -- around 30% faster than unpack() -    else -        res[#res+1] = stringformat(...) -    end -    writer (tableconcat(res, " ")) -end - ---- at default (zero), we aim to be quiet -local level_ids = { common  = 1, loading = 2, search  = 3 } - ---[[doc-- - -    The names_report logger is used more or less all over luaotfload. -    Its requirements are twofold: - -    1) Provide two logging channels, the terminal and the log file; -    2) Allow for control over verbosity levels. - -    The first part is addressed by specifying the log *mode* as the -    first argument that can be either “log”, meaning the log file, or -    “both”: log file and stdout. Anything else is taken as referring to -    stdout only. - -    Verbosity levels, though not as fine-grained as e.g. Context’s -    system of tracers, allow keeping the logging spam caused by -    different subsystems manageable. By default, luaotfload will not -    emit anything if things are running smoothly on level zero. Only -    warning messages are relayed, while the other messages are skipped -    over. (This is a little sub-optimal performance-wise since the -    function calls to the logger are executed regardless.) The log -    level during a Luatex run can be adjusted by setting the “loglevel” -    field in config.luaotfload, or by calling logs.set_loglevel() as -    defined above. - ---doc]]-- - -local names_report = function (mode, lvl, ...) -    if type(lvl) == "string" then -        lvl = level_ids[lvl] -    end -    if not lvl then lvl = 0 end - -    if loglevel >= lvl then -        if mode == "log" then -            log (...) -        elseif mode == "both" and logout ~= "redirect" then -            log (...) -            stdout (writeln, ...) -        else -            stdout (writeln, ...) -        end -    end -end - -logs.names_report = names_report - ---[[doc-- - -    status_logger -- Overwrites the most recently printed line of the -    terminal. Its purpose is to provide feedback without spamming -    stdout with irrelevant messages, i.e. when building the database. - -    Status logging must be initialized by calling status_start() and -    properly reset via status_stop(). - -    The arguments low and high indicate the loglevel threshold at which -    linewise and full logging is triggered, respectively. E.g. - -            names_status (1, 4, "term", "Hello, world!") - -    will print nothing if the loglevel is less than one, reuse the -    current line if the loglevel ranges from one to three inclusively, -    and output the message on a separate line otherwise. - ---doc]]-- - -local status_logger = function (mode, ...) -    if mode == "log" then -        log (...) -    else -        if mode == "both" and logout ~= "redirect" then -            log (...) -            stdout (statusln, ...) -        else -            stdout (statusln, ...) -        end -        first_status = false -    end -end - ---[[doc-- - -    status_start -- Initialize status logging. This installs the status -        logger if the loglevel is in the specified range, and the normal -        logger otherwise.  It also resets the first line state which -        causing the next line printed using the status logger to not kill -        the current line. - ---doc]]-- - -local status_writer -local status_low  = 99 -local status_high = 99 - -local status_start = function (low, high) -    first_status = true -    status_low   = low -    status_high  = high - -    if os.type == "windows" --- Assume broken terminal. -    or os.getenv "TERM" == "dumb" -    then -        status_writer = function (mode, ...) -            names_report (mode, high, ...) -        end -        return -    end +local findfile      = resolvers.findfile +local encodings     = fonts.encodings -    if low <= loglevel and loglevel < high then -        status_writer = status_logger -    else -        status_writer = function (mode, ...) -            names_report (mode, high, ...) -        end -    end -end - ---[[doc-- - -    status_stop -- Finalize a status region by outputting a newline and -    printing a message. - ---doc]]-- - -local status_stop = function (...) -    if first_status == false then -        status_writer(...) -        if texjob == false then -            writeln "" -        end -    end -end - -logs.names_status = function (...) status_writer (...) end -logs.names_status_start = status_start -logs.names_status_stop  = status_stop - ---[[doc-- - -    The fontloader comes with the Context logging mechanisms -    inaccessible. Instead, it provides dumb fallbacks based -    on the functions in texio.write*() that can be overridden -    by providing a function texio.reporter(). - -    The fontloader output can be quite verbose, so we disable -    it entirely by default. - ---doc]]-- - -local texioreporter = function (message) -    names_report("log", 2, message) -end - -texio.reporter = texioreporter +local log           = luaotfload.log +local report        = log.report  --[[doc-- @@ -374,34 +30,23 @@ texio.reporter = texioreporter  --doc]]-- -if fonts then --- need to be running TeX -    if next(fonts.encodings.agl) then -        --- unnecessary because the file shouldn’t be loaded at this time -        --- but we’re just making sure -        fonts.encodings.agl = nil -        collectgarbage"collect" -    end - - -    fonts.encodings.agl = { } +encodings.agl = { } -    setmetatable(fonts.encodings.agl, { __index = function (t, k) -        if k == "unicodes" then -            local glyphlist = resolvers.findfile"luaotfload-glyphlist.lua" -            if glyphlist then -                names_report("log", 1, "load", "loading the Adobe glyph list") -            else -                glyphlist = resolvers.findfile"font-age.lua" -                names_report("both", 0, "load", -                    "loading the extended glyph list from ConTeXt") -            end -            local unicodes      = dofile(glyphlist) -            fonts.encodings.agl = { unicodes = unicodes } -            return unicodes -        else -            return nil -        end -    end }) -end +setmetatable(fonts.encodings.agl, { __index = function (t, k) +    if k ~= "unicodes" then +        return nil +    end +    local glyphlist = findfile "luaotfload-glyphlist.lua" +    if glyphlist then +        report ("log", 1, "load", "loading the Adobe glyph list") +    else +        glyphlist = findfile "font-age.lua" +        report ("both", 0, "load", +                "loading the extended glyph list from ConTeXt") +    end +    local unicodes = dofile(glyphlist) +    encodings.agl  = { unicodes = unicodes } +    return unicodes +end })  -- vim:tw=71:sw=4:ts=4:expandtab diff --git a/luaotfload-parsers.lua b/luaotfload-parsers.lua index 51d251c..5145ca0 100644 --- a/luaotfload-parsers.lua +++ b/luaotfload-parsers.lua @@ -38,8 +38,8 @@ local filedirname       = file.dirname  local io                = io  local ioopen            = io.open -local logs              = logs -local report            = logs.report +local log               = luaotfload.log +local report            = log.report  local string            = string  local stringsub         = string.sub diff --git a/luaotfload-tool.lua b/luaotfload-tool.lua index 8bc590a..35765b5 100755 --- a/luaotfload-tool.lua +++ b/luaotfload-tool.lua @@ -9,7 +9,10 @@  --     MODIFIED:  2014-01-14 13:17:04+0100  ----------------------------------------------------------------------- -local version = "2.5" --- <int: major>.<int: minor><alpha: fixes> +luaotfload          = luaotfload or { } +local version       = "2.5" --- <int: major>.<int: minor>-<int: fixes> +luaotfload.version  = version +luaotfload.self     = "luaotfload-tool"  --[[doc-- @@ -104,8 +107,6 @@ if not luaotfloadconfig.strip then      luaotfloadconfig.strip = true  end -luaotfloadconfig.self           = "luaotfload-tool" -  config.lualibs                  = config.lualibs or { }  config.lualibs.verbose          = false  config.lualibs.prefer_merged    = true @@ -141,23 +142,24 @@ require"luaotfload-basics-gen.lua"  texio.write, texio.write_nl          = backup.write, backup.write_nl  utilities                            = backup.utilities -require"luaotfload-override.lua"  --- this populates the logs.* namespace +require"luaotfload-log.lua"       --- this populates the luaotfload.log.* namespace  require"luaotfload-parsers"       --- fonts.conf and request syntax  require"luaotfload-database"  require"alt_getopt" -local names = fonts.names - +local names                          = fonts.names  local status_file                    = "luaotfload-status"  local luaotfloadstatus               = require (status_file)  luaotfloadconfig.status              = luaotfloadstatus -  local sanitize_fontname              = names.sanitize_fontname -local pathdata      = names.path -local names_plain   = pathdata.index.lua -local names_gzip    = names_plain .. ".gz" -local names_bin     = pathdata.index.luc +local log                            = luaotfload.log +local report                         = log.report + +local pathdata                       = names.path +local names_plain                    = pathdata.index.lua +local names_gzip                     = names_plain .. ".gz" +local names_bin                      = pathdata.index.luc  local help_messages = {      ["luaotfload-tool"] = [[ @@ -248,7 +250,7 @@ Enter 'luaotfload-tool --help' for a larger list of options.  local help_msg = function (version)      local template = help_messages[version]      iowrite(stringformat(template, -                         luaotfloadconfig.self, +                         luaotfload.self,  --                         names_plain,                           names_gzip,                           names_bin, @@ -265,8 +267,8 @@ local about = [[  local version_msg = function ( )      local out = function (...) texiowrite_nl (stringformat (...)) end -    out (about, luaotfloadconfig.self) -    out ("%s version %q", luaotfloadconfig.self, version) +    out (about, luaotfload.self) +    out ("%s version %q", luaotfload.self, version)      out ("revision %q", luaotfloadstatus.notes.revision)      out ("database version %q", names.version)      out ("Lua interpreter: %s; version %q", runtime[1], runtime[2]) @@ -681,9 +683,9 @@ local show_font_info = function (basename, askedname, detail, warnings)          if nfonts > 0 then -- true type collection              local subfont              if askedname then -                logs.names_report(true, 1, "resolve", -                    [[%s is part of the font collection %s]], -                    askedname, basename) +                report (true, 1, "resolve", +                        [[%s is part of the font collection %s]], +                        askedname, basename)                  subfont = subfont_by_name(shortinfo, askedname)              end              if subfont then @@ -692,11 +694,11 @@ local show_font_info = function (basename, askedname, detail, warnings)                      show_full_info(fullname, subfont, warnings)                  end              else -- list all subfonts -                logs.names_report(true, 1, "resolve", -                    [[%s is a font collection]], basename) +                report (true, 1, "resolve", +                        [[%s is a font collection]], basename)                  for subfont = 1, nfonts do -                    logs.names_report(true, 1, "resolve", -                        [[Showing info for font no. %d]], n) +                    report (true, 1, "resolve", +                            [[Showing info for font no. %d]], n)                      show_info_items(shortinfo[subfont])                      if detail == true then                          show_full_info(fullname, subfont, warnings) @@ -710,8 +712,7 @@ local show_font_info = function (basename, askedname, detail, warnings)              end          end      else -        logs.names_report(true, 1, "resolve", -            "Font %s not found", filename) +        report (true, 1, "resolve", "Font %s not found", filename)      end  end @@ -735,10 +736,9 @@ action_pending.generate = false --- this is the default action  local actions = { } --- (jobspec -> (bool * bool)) list  actions.loglevel = function (job) -    logs.set_loglevel(job.log_level) -    logs.names_report("info", 3, "util", -                      "Setting log level", "%d", job.log_level) -    logs.names_report("log", 2, "util", "Lua=%s", _VERSION) +    log.set_loglevel(job.log_level) +    report ("info", 3, "util", "Setting log level", "%d", job.log_level) +    report ("log", 2, "util", "Lua=%q", _VERSION)      return true, true  end @@ -764,8 +764,7 @@ end  actions.generate = function (job)      local fontnames, savedname      fontnames = names.update(fontnames, job.force_reload, job.dry_run) -    logs.names_report("info", 2, "db", -        "Fonts in the database: %i", #fontnames.mappings) +    report ("info", 2, "db", "Fonts in the database: %i", #fontnames.mappings)      if names.data() then          return true, true      end @@ -777,7 +776,7 @@ actions.flush = function (job)      if success then          local success = names.save_lookups()          if success then -            logs.names_report("info", 2, "cache", "Lookup cache emptied") +            report ("info", 2, "cache", "Lookup cache emptied")              return true, true          end      end @@ -793,8 +792,8 @@ local cache_directives = {  actions.cache = function (job)      local directive = cache_directives[job.cache]      if not directive or type(directive) ~= "function" then -        logs.names_report("info", 2, "cache", -                          "Invalid font cache directive %s.", job.cache) +        report ("info", 2, "cache", +                "Invalid font cache directive %s.", job.cache)          return false, false      end      if directive() then @@ -838,28 +837,27 @@ actions.query = function (job)      end      if success then -        logs.names_report(false, 0, -            "resolve", "Font %q found!", query) +        report (false, 0, "resolve", "Font %q found!", query)          if subfont then -            logs.names_report(false, 0, "resolve", -                "Resolved file name %q, subfont nr. %q", +            report (false, 0, "resolve", +                    "Resolved file name %q, subfont nr. %q",                  foundname, subfont)          else -            logs.names_report(false, 0, "resolve", -                              "Resolved file name %q", foundname) +            report (false, 0, "resolve", +                    "Resolved file name %q", foundname)          end          if job.show_info then              show_font_info (foundname, query, job.full_info, job.warnings)              iowrite "\n"          end      else -        logs.names_report(false, 0, -            "resolve", "Cannot find %q in index.", query) -        logs.names_report(false, 0, -            "resolve", "Hint: use the --fuzzy option to display suggestions.", query) +        report (false, 0, "resolve", "Cannot find %q in index.", query) +        report (false, 0, "resolve", +                "Hint: use the --fuzzy option to display suggestions.", +                query)          if job.fuzzy == true then -            logs.names_report(false, 0, -                "resolve", "Looking for close matches, this may take a while ...") +            report (false, 0, "resolve", +                    "Looking for close matches, this may take a while ...")              local _success = names.find_closest(query, job.fuzzy_limit)          end      end @@ -957,7 +955,7 @@ actions.list = function (job)      local nmappings = #mappings      if criterion == "*" then -        logs.names_report(false, 1, "list", "All %d entries", nmappings) +        report (false, 1, "list", "All %d entries", nmappings)          for i=1, nmappings do              local entry     = mappings[i]              local fields    = get_fields(entry, asked_fields) @@ -972,12 +970,12 @@ actions.list = function (job)          criterion          = criterion[1]          asked_fields       = set_primary_field(asked_fields, criterion) -        logs.names_report(false, 1, "list", "By %s", criterion) +        report (false, 1, "list", "By %s", criterion)          --- firstly, build a list of fonts to operate on          local targets = { }          if asked_value then --- only those whose value matches -            logs.names_report(false, 2, "list", "Restricting to value %s", asked_value) +            report (false, 2, "list", "Restricting to value %s", asked_value)              for i=1, nmappings do                  local entry = mappings[i]                  if  entry[criterion] @@ -1022,7 +1020,7 @@ actions.list = function (job)              end          end          local ntargets = #targets -        logs.names_report(false, 2, "list", "%d entries", ntargets) +        report (false, 2, "list", "%d entries", ntargets)          --- now, output the collection          for i=1, ntargets do @@ -1150,7 +1148,7 @@ local process_cmdline = function ( ) -- unit -> jobspec          elseif v == "log" then              local str = optarg[n]              if str then -                finalizers = logs.set_logout(str, finalizers) +                finalizers = log.set_logout(str, finalizers)              end          elseif v == "find" then              action_pending["query"] = true @@ -1230,24 +1228,23 @@ local main = function ( ) -- unit -> int          local actionname = action_sequence[i]          local exit       = false          if action_pending[actionname] then -            logs.names_report("log", 3, "util", "Preparing for task", -                              "%s", actionname) +            report ("log", 3, "util", "Preparing for task", "%s", actionname)              local action             = actions[actionname]              local success, continue  = action(job)              if not success then -                logs.names_report(false, 0, "util", -                    "Could not finish task", "%s", actionname) +                report (false, 0, "util", +                        "Could not finish task", "%s", actionname)                  retval = -1                  exit   = true              elseif not continue then -                logs.names_report(false, 3, "util", -                    "Task completed, exiting", "%s", actionname) -                exit   = true +                report (false, 3, "util", +                        "Task completed, exiting", "%s", actionname) +                exit = true              else -                logs.names_report(false, 3, "util", -                    "Task completed successfully", "%s", actionname) +                report (false, 3, "util", +                        "Task completed successfully", "%s", actionname)              end          end          if exit then break end diff --git a/luaotfload-tool.rst b/luaotfload-tool.rst index 2ac206f..6863918 100644 --- a/luaotfload-tool.rst +++ b/luaotfload-tool.rst @@ -188,10 +188,10 @@ miscellaneous                          troubleshooting), where *CHANNEL* can be                          1) ``stdout`` -> all output will be -                           dumped to the terminal; or +                           dumped to the terminal (default); or                          2) ``file`` -> write to a file to the temporary                             directory (the name will be chosen -                           automatically (**experimental!**). +                           automatically.  --version, -V           Show version numbers of components as well as                          some basic information and exit. @@ -50,6 +50,7 @@ local names = {    "luaotfload-glyphlist.lua",    "luaotfload-letterspace.lua",    "luaotfload-loaders.lua", +  "luaotfload-log.lua",    "luaotfload-main.lua",    "luaotfload-fontloader.lua",    "luaotfload-override.lua", @@ -30,7 +30,7 @@ kpse.set_program_name "luatex"  require "lualibs"  require "luaotfload-basics-gen.lua" -require "luaotfload-override.lua" +require "luaotfload-log.lua"  require "luaotfload-parsers"  require "luaotfload-database"  | 
