+ltjb.get_cs = get_cs
+
+-------------------- common error message
+do
+ local function in_unicode(c, admit_math)
+ local low = admit_math and -1 or 0
+ if type(c)~='number' or c<low or c>0x10FFFF then
+ local s = 'A character number must be between ' .. tostring(low)
+ .. ' and 0x10ffff.\n'
+ .. (admit_math and "(-1 is used for denoting `math boundary')\n" or '')
+ .. 'So I changed this one to zero.'
+ package_error('luatexja',
+ 'bad character code (' .. tostring(c) .. ')', s)
+ c=0
+ end
+ return c
+ end
+ ltjb.in_unicode = in_unicode
+end
+
+-------------------- cache management
+-- load_cache (filename, outdate)
+-- * filename: without suffix '.lua'
+-- * outdate(t): return true iff the cache is outdated
+-- * return value: non-nil iff the cache is up-to-date
+-- save_cache (filename, t): no return value
+-- save_cache_luc (filename, t): no return value
+-- save_cache always calls save_cache_luc.
+-- But sometimes we want to create only the precompiled cache,
+-- when its 'text' version is already present in LuaTeX-ja distribution.
+
+require('lualibs-lpeg') -- string.split
+require('lualibs-os') -- os.type
+
+do
+ local kpse_var_value = kpse.var_value
+ local path, pathtmp = kpse_var_value("TEXMFVAR")
+ pathtmp = kpse_var_value("TEXMFSYSVAR")
+ if pathtmp then path = (path and path .. ';' or '') .. pathtmp end
+ pathtmp = kpse_var_value("TEXMFCACHE")
+ if pathtmp then path = (path and path .. ';' or '') .. pathtmp end
+
+ if os.type~='windows' then path = string.gsub(path, ':', ';') end
+ path = table.unique(string.split(path, ';'))
+
+ local cache_dir = '/luatexja'
+ local find_file = kpse.find_file
+ local join, isreadable = file.join, file.isreadable
+ local tofile, serialize = table.tofile, table.serialize
+ local luc_suffix = jit and '.lub' or '.luc'
+
+ -- determine save path
+ local savepath = ''
+ for _,v in pairs(path) do
+ local testpath = join(v, cache_dir)
+ if not lfs.isdir(testpath) then dir.mkdirs(testpath) end
+ if lfs.isdir(testpath) then savepath = testpath; break end
+ end
+
+ save_cache_luc = function (filename, t, serialized)
+ local fullpath = savepath .. '/' .. filename .. luc_suffix
+ local s = serialized or serialize(t, 'return', false)
+ if s then
+ local sa = load(s)
+ local f = io.open(fullpath, 'wb')
+ if f and sa then
+ f:write(string.dump(sa, true))
+ texio.write('(save cache: ' .. fullpath .. ')')
+ end
+ f:close()
+ end
+ end
+
+ save_cache = function (filename, t)
+ local fullpath = savepath .. '/' .. filename .. '.lua'
+ local s = serialize(t, 'return', false)
+ if s then
+ local f = io.open(fullpath, 'w')
+ if f then
+ f:write(s)
+ texio.write('(save cache: ' .. fullpath .. ')')
+ end
+ f:close()
+ save_cache_luc(filename, t, s)
+ end
+ end
+
+ local function load_cache_a (filename, outdate)
+ local result
+ for _,v in pairs(path) do
+ local fn = join(v, cache_dir, filename)
+ if isreadable(fn) then
+ texio.write('(load cache: ' .. fn .. ')')
+ result = loadfile(fn)
+ result = result and result(); break
+ end
+ end
+ if (not result) or outdate(result) then
+ return nil
+ else
+ return result
+ end
+ end
+
+ load_cache = function (filename, outdate)
+ local r = load_cache_a(filename .. luc_suffix, outdate)
+ if r then
+ return r
+ else
+ local r = load_cache_a(filename .. '.lua', outdate)
+ if r then save_cache_luc(filename, r) end -- update the precompiled cache
+ return r
+ end
+ end
+
+ ltjb.load_cache = load_cache
+ ltjb.save_cache_luc = save_cache_luc
+ ltjb.save_cache = save_cache
+end
+
+ltjb._error_set_break = _error_set_break
+ltjb._error_set_message = _error_set_message
+ltjb._error_show = _error_show
+ltjb._generic_warn_info = _generic_warn_info
+
+ltjb.package_error = package_error
+ltjb.package_warning = package_warning
+ltjb.package_warning_no_line = package_warning_no_line
+ltjb.package_info = package_info
+ltjb.package_info_no_line = package_info_no_line
+
+ltjb.generic_error = generic_error
+ltjb.generic_warning = generic_warning
+ltjb.generic_warning_no_line = generic_warning_no_line
+ltjb.generic_info = generic_info
+ltjb.generic_info_no_line = generic_info_no_line
+
+ltjb.ltj_warning_no_line = ltj_warning_no_line
+ltjb.ltj_error = ltj_error
+
+-------------------- mock of debug logger
+if not ltjb.out_debug then
+ local function no_op() end
+ ltjb.start_time_measure = no_op
+ ltjb.stop_time_measure = no_op
+ ltjb.out_debug = no_op
+ ltjb.package_debug = no_op
+ ltjb.debug_logger = function() return no_op end
+ ltjb.show_term = no_op
+ ltjb.show_log = no_op
+end