summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/l3build/l3build.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/latex/l3build/l3build.lua')
-rw-r--r--Master/texmf-dist/tex/latex/l3build/l3build.lua742
1 files changed, 381 insertions, 361 deletions
diff --git a/Master/texmf-dist/tex/latex/l3build/l3build.lua b/Master/texmf-dist/tex/latex/l3build/l3build.lua
index b3d55b0fb00..f514429cf7d 100644
--- a/Master/texmf-dist/tex/latex/l3build/l3build.lua
+++ b/Master/texmf-dist/tex/latex/l3build/l3build.lua
@@ -22,8 +22,8 @@ for those people who are interested.
--]]
--- Version information: should be identical to that in l3build.dtx
-release_date = "2017/04/01"
+-- Version information
+release_date = "2017/05/13"
-- "module" is a deprecated function in Lua 5.2: as we want the name
-- for other purposes, and it should eventually be 'free', simply
@@ -38,7 +38,7 @@ bundle = bundle or ""
-- Sanity check
if module == "" and bundle == "" then
- if string.match(arg[0], ".*l3build%.lua$") then
+ if string.match(arg[0], "l3build%.lua$") then
print(
"\n"
.. "Error: Call l3build using a configuration file, not directly.\n"
@@ -57,7 +57,7 @@ end
maindir = maindir or "."
-- Substructure for tests and support files
-testfiledir = testfiledir or "testfiles" -- Set to "" to cancel any tests
+testfiledir = testfiledir or "testfiles"
testsuppdir = testsuppdir or testfiledir .. "/support"
supportdir = supportdir or maindir .. "/support"
@@ -113,7 +113,7 @@ unpackdeps = unpackdeps or { }
-- Executable names plus following options
typesetexe = typesetexe or "pdflatex"
unpackexe = unpackexe or "tex"
-zipexe = "zip"
+zipexe = zipexe or "zip"
checkopts = checkopts or "-interaction=nonstopmode"
cmdchkopts = cmdchkopts or "-interaction=batchmode"
@@ -128,7 +128,6 @@ stdengine = stdengine or "pdftex"
-- Enable access to trees outside of the repo
-- As these may be set false, a more elaborate test than normal is needed
--- here
if checksearch == nil then
checksearch = true
end
@@ -156,8 +155,8 @@ asciiengines = asciiengines or {"pdftex"}
checkruns = checkruns or 1
epoch = epoch or 1463734800
maxprintline = maxprintline or 79
-packtdszip = packtdszip or false -- Not actually needed but clearer
-scriptname = scriptname or "build.lua" -- Script used in each directory
+packtdszip = packtdszip or false
+scriptname = scriptname or "build.lua"
typesetcmds = typesetcmds or ""
versionform = versionform or ""
@@ -171,11 +170,50 @@ pdfext = pdfext or ".pdf"
psext = psext or ".ps"
tlgext = tlgext or ".tlg"
--- Run time options
--- These are parsed into a global table, and all optional args
--- are made available as a related global var
-
-function argparse()
+-- File operations are aided by the LuaFileSystem module
+local lfs = require("lfs")
+
+-- Local access to functions
+local assert = assert
+local ipairs = ipairs
+local next = next
+local print = print
+local select = select
+local tonumber = tonumber
+local close = io.close
+local lines = io.lines
+local open = io.open
+local output = io.output
+local stderr = io.stderr
+local write = io.write
+local set_program_name = kpse.set_program_name
+local var_value = kpse.var_value
+local lfs_attributes = lfs.attributes
+local lfs_dir = lfs.dir
+local os_date = os.date
+local execute = os.execute
+local exit = os.exit
+local getenv = os.getenv
+local os_remove = os.remove
+local os_type = os.type
+local luatex_revision = status.luatex_revision
+local luatex_version = status.luatex_version
+local char = string.char
+local find = string.find
+local format = string.format
+local gmatch = string.gmatch
+local gsub = string.gsub
+local len = string.len
+local match = string.match
+local sub = string.sub
+local concat = table.concat
+local insert = table.insert
+local utf8_char = unicode.utf8.char
+
+-- Parse command line options
+-- This is done as a function (rather than do ... end) as it allows early
+-- termination (break)
+local function argparse()
local result = { }
local files = { }
local long_options =
@@ -212,6 +250,7 @@ function argparse()
release = true,
testfiledir = true
}
+ local args = args
-- arg[1] is a special case: must be a command or "-h"/"--help"
-- Deal with this by assuming help and storing only apparently-valid
-- input
@@ -219,7 +258,7 @@ function argparse()
result["target"] = "help"
if a then
-- No options are allowed in position 1, so filter those out
- if not string.match(a, "^%-") then
+ if not match(a, "^%-") then
result["target"] = a
end
end
@@ -231,7 +270,7 @@ function argparse()
local function remainder(num)
local files = { }
for i = num, #arg do
- table.insert(files, arg[i])
+ insert(files, arg[i])
end
return files
end
@@ -247,25 +286,26 @@ function argparse()
break
end
-- Look for optionals
- local opt, optarg
+ local opt
+ local optarg
local opts
-- Look for and option and get it into a variable
- if string.match(a, "^%-") then
- if string.match(a, "^%-%-") then
+ if match(a, "^%-") then
+ if match(a, "^%-%-") then
opts = long_options
- local pos = string.find(a, "=", 1, true)
+ local pos = find(a, "=", 1, true)
if pos then
- opt = string.sub(a, 3, pos - 1)
- optarg = string.sub(a, pos + 1)
+ opt = sub(a, 3, pos - 1)
+ optarg = sub(a, pos + 1)
else
- opt = string.sub(a,3)
+ opt = sub(a, 3)
end
else
opts = short_options
- opt = string.sub(a, 2, 2)
+ opt = sub(a, 2, 2)
-- Only set optarg if it is there
if #a > 2 then
- optarg = string.sub(a, 3)
+ optarg = sub(a, 3)
end
end
-- Now check that the option is valid and sort out the argument
@@ -277,25 +317,24 @@ function argparse()
if reqarg and not optarg then
optarg = arg[i + 1]
if not optarg then
- io.stderr:write("Missing value for option " .. a .."\n")
+ stderr:write("Missing value for option " .. a .."\n")
return {"help"}
end
i = i + 1
end
if not reqarg and optarg then
- io.stderr:write("Value not allowed for option " .. a .."\n")
+ stderr:write("Value not allowed for option " .. a .."\n")
return {"help"}
end
else
- io.stderr:write("Unknown option " .. a .."\n")
+ stderr:write("Unknown option " .. a .."\n")
return {"help"}
end
-- Store the result
if optarg then
local opts = result[optname] or { }
- local match
- for match in string.gmatch(optarg, "([^,%s]+)") do
- table.insert(opts, match)
+ for hit in gmatch(optarg, "([^,%s]+)") do
+ insert(opts, hit)
end
result[optname] = opts
else
@@ -312,15 +351,14 @@ function argparse()
return result
end
-userargs = argparse()
+options = argparse()
-optdate = userargs["date"]
-optengines = userargs["engine"]
-opthalt = userargs["halt"]
-opthelp = userargs["help"]
-optpdf = userargs["pdf"]
-optquiet = userargs["quiet"]
-optrelease = userargs["release"]
+local optdate = options["date"]
+local optengines = options["engine"]
+local opthalt = options["halt"]
+local optpdf = options["pdf"]
+local optquiet = options["quiet"]
+local optrelease = options["release"]
-- Convert a file glob into a pattern for use by e.g. string.gub
-- Based on https://github.com/davidm/lua-glob-pattern
@@ -353,7 +391,7 @@ optrelease = userargs["release"]
(end license)
--]]
-function glob_to_pattern(glob)
+local function glob_to_pattern(glob)
local pattern = "^" -- pattern being built
local i = 0 -- index in glob
@@ -361,13 +399,13 @@ function glob_to_pattern(glob)
-- escape pattern char
local function escape(char)
- return string.match(char, "^%w$") and char or "%" .. char
+ return match(char, "^%w$") and char or "%" .. char
end
-- Convert tokens.
while true do
i = i + 1
- char = string.sub(glob, i, i)
+ char = sub(glob, i, i)
if char == "" then
pattern = pattern .. "$"
break
@@ -380,7 +418,7 @@ function glob_to_pattern(glob)
print("[...] syntax not supported in globs!")
elseif char == "\\" then
i = i + 1
- char = string.sub(glob, i, i)
+ char = sub(glob, i, i)
if char == "" then
pattern = pattern .. "\\$"
break
@@ -393,52 +431,41 @@ function glob_to_pattern(glob)
return pattern
end
--- File operation support
--- Much of this is OS-dependent as Lua offers a very limited range of file
--- operations 'natively'.
-
-- Detect the operating system in use
-- Support items are defined here for cases where a single string can cover
-- both Windows and Unix cases: more complex situations are handled inside
-- the support functions
-if os.type == "windows" then
- os_ascii = "@echo."
- os_cmpexe = os.getenv("cmpexe") or "fc /b"
- os_cmpext = os.getenv("cmpext") or ".cmp"
- os_concat = "&"
- os_diffext = os.getenv("diffext") or ".fc"
- os_diffexe = os.getenv("diffexe") or "fc /n"
- os_grepexe = "findstr /r"
- os_newline = "\n"
- if tonumber(status.luatex_version) < 100 or
- (tonumber(status.luatex_version) == 100
- and tonumber(status.luatex_revision) < 4) then
+os_concat = ";"
+os_null = "/dev/null"
+os_pathsep = ":"
+os_setenv = "export"
+os_yes = "printf 'y\\n%.0s' {1..200}"
+local os_ascii = "echo \"\""
+local os_cmpexe = getenv("cmpexe") or "cmp"
+local os_cmpext = getenv("cmpext") or ".cmp"
+local os_diffext = getenv("diffext") or ".diff"
+local os_diffexe = getenv("diffexe") or "diff -c --strip-trailing-cr"
+local os_grepexe = "grep"
+local os_newline = "\n"
+if os_type == "windows" then
+ os_ascii = "@echo."
+ os_cmpexe = getenv("cmpexe") or "fc /b"
+ os_cmpext = getenv("cmpext") or ".cmp"
+ os_concat = "&"
+ os_diffext = getenv("diffext") or ".fc"
+ os_diffexe = getenv("diffexe") or "fc /n"
+ os_grepexe = "findstr /r"
+ os_newline = "\n"
+ if tonumber(luatex_version) < 100 or
+ (tonumber(luatex_version) == 100
+ and tonumber(luatex_revision) < 4) then
os_newline = "\r\n"
end
- os_null = "nul"
- os_pathsep = ";"
- os_setenv = "set"
- os_windows = true
- os_yes = "for /l %I in (1,1,200) do @echo y"
-else
- os_ascii = "echo \"\""
- os_cmpexe = os.getenv("cmpexe") or "cmp"
- os_cmpext = os.getenv("cmpext") or ".cmp"
- os_concat = ";"
- os_diffext = os.getenv("diffext") or ".diff"
- os_diffexe = os.getenv("diffexe") or "diff -c --strip-trailing-cr"
- os_grepexe = "grep"
- os_newline = "\n"
- os_null = "/dev/null"
- os_pathsep = ":"
- os_setenv = "export"
- os_windows = false
- os_yes = "printf 'y\\n%.0s' {1..200}"
-end
-
--- File operations are aided by the LuaFileSystem module, which is available
--- within texlua
-lfs = require("lfs")
+ os_null = "nul"
+ os_pathsep = ";"
+ os_setenv = "set"
+ os_yes = "for /l %I in (1,1,200) do @echo y"
+end
-- For cleaning out a directory, which also ensures that it exists
function cleandir(dir)
@@ -454,20 +481,20 @@ function cp(glob, source, dest)
local errorlevel
for _,i in ipairs(filelist(source, glob)) do
local source = source .. "/" .. i
- if os_windows then
- if lfs.attributes(source)["mode"] == "directory" then
- errorlevel = os.execute(
+ if os_type == "windows" then
+ if lfs_attributes(source)["mode"] == "directory" then
+ errorlevel = execute(
"xcopy /y /e /i " .. unix_to_win(source) .. " "
.. unix_to_win(dest .. "/" .. i) .. " > nul"
)
else
- errorlevel = os.execute(
+ errorlevel = execute(
"xcopy /y " .. unix_to_win(source) .. " "
.. unix_to_win(dest) .. " > nul"
)
end
else
- errorlevel = os.execute("cp -rf " .. source .. " " .. dest)
+ errorlevel = execute("cp -rf " .. source .. " " .. dest)
end
if errorlevel ~=0 then
return errorlevel
@@ -479,11 +506,11 @@ end
-- OS-dependent test for a directory
function direxists(dir)
local errorlevel
- if os_windows then
+ if os_type == "windows" then
errorlevel =
- os.execute("if not exist \"" .. unix_to_win(dir) .. "\" exit 1")
+ execute("if not exist \"" .. unix_to_win(dir) .. "\" exit 1")
else
- errorlevel = os.execute("[ -d " .. dir .. " ]")
+ errorlevel = execute("[ -d " .. dir .. " ]")
end
if errorlevel ~= 0 then
return false
@@ -492,9 +519,9 @@ function direxists(dir)
end
function fileexists(file)
- local f = io.open(file, "r")
+ local f = open(file, "r")
if f ~= nil then
- io.close(f)
+ close(f)
return true
else
return false
@@ -503,7 +530,6 @@ end
-- Generate a table containing all file names of the given glob or all files
-- if absent
--- Not actually OS-dependent but in the same area
function filelist(path, glob)
local files = { }
local pattern
@@ -511,14 +537,14 @@ function filelist(path, glob)
pattern = glob_to_pattern(glob)
end
if direxists(path) then
- for entry in lfs.dir(path) do
+ for entry in lfs_dir(path) do
if pattern then
- if string.match(entry, pattern) then
- table.insert(files, entry)
+ if match(entry, pattern) then
+ insert(files, entry)
end
else
if entry ~= "." and entry ~= ".." then
- table.insert(files, entry)
+ insert(files, entry)
end
end
end
@@ -527,57 +553,43 @@ function filelist(path, glob)
end
function mkdir(dir)
- if os_windows then
+ if os_type == "windows" then
-- Windows (with the extensions) will automatically make directory trees
-- but issues a warning if the dir already exists: avoid by including a test
local dir = unix_to_win(dir)
- return os.execute(
+ return execute(
"if not exist " .. dir .. "\\nul " .. "mkdir " .. dir
)
else
- return os.execute("mkdir -p " .. dir)
+ return execute("mkdir -p " .. dir)
end
end
--- Find the relationship between two directories
-function relpath(target, source)
- -- A shortcut for the case where the two are the same
- if target == source then
- return ""
- end
- local resultdir = ""
- local trimpattern = "^[^/]*/"
- -- Trim off identical leading directories
- while
- (string.match(target, trimpattern) or "X") ==
- (string.match(target, trimpattern) or "Y") do
- target = string.gsub(target, trimpattern, "")
- source = string.gsub(source, trimpattern, "")
- end
- -- Go up from the source
- for i = 0, select(2, string.gsub(target, "/", "")) do
- resultdir = resultdir .. "../"
- end
- -- Return the relative part plus the unique part of the target
- return resultdir .. target
+-- Return an absolute path from a relative one
+function abspath(path)
+ local oldpwd = lfs.currentdir()
+ lfs.chdir(path)
+ local result = lfs.currentdir()
+ lfs.chdir(oldpwd)
+ return result
end
-- Rename
function ren(dir, source, dest)
local dir = dir .. "/"
- if os_windows then
- return os.execute("ren " .. unix_to_win(dir) .. source .. " " .. dest)
+ if os_type == "windows" then
+ return execute("ren " .. unix_to_win(dir) .. source .. " " .. dest)
else
- return os.execute("mv " .. dir .. source .. " " .. dir .. dest)
+ return execute("mv " .. dir .. source .. " " .. dir .. dest)
end
end
-- Remove file(s) based on a glob
function rm(source, glob)
for _,i in ipairs(filelist(source, glob)) do
- os.remove(source .. "/" .. i)
+ os_remove(source .. "/" .. i)
end
- -- os.remove doesn't give a sensible errorlevel
+ -- os_remove doesn't give a sensible errorlevel
return 0
end
@@ -585,21 +597,21 @@ end
function rmdir(dir)
-- First, make sure it exists to avoid any errors
mkdir(dir)
- if os_windows then
- return os.execute("rmdir /s /q " .. unix_to_win(dir))
+ if os_type == "windows" then
+ return execute("rmdir /s /q " .. unix_to_win(dir))
else
- return os.execute("rm -r " .. dir)
+ return execute("rm -r " .. dir)
end
end
-- Run a command in a given directory
function run(dir, cmd)
- return os.execute("cd " .. dir .. os_concat .. cmd)
+ return execute("cd " .. dir .. os_concat .. cmd)
end
-- Deal with the fact that Windows and Unix use different path separators
function unix_to_win(path)
- return string.gsub(path, "/", "\\")
+ return gsub(path, "/", "\\")
end
--
@@ -607,25 +619,25 @@ end
--
-- Do some subtarget for all modules in a bundle
-function allmodules(target)
+local function allmodules(target)
+ local date = ""
+ if optdate then
+ date = " --date=" .. optdate[1]
+ end
+ local engines = ""
+ if optengines then
+ engines = " --engine=" .. concat(optengines, ",")
+ end
+ local release = ""
+ if optrelease then
+ release = " --release=" .. optrelease[1]
+ end
for _,i in ipairs(modules) do
print(
"Running script " .. scriptname .. " with target \"" .. target
.. "\" for module "
.. i
)
- local date = ""
- if optdate then
- date = " --date=" .. optdate[1]
- end
- local engines = ""
- if optengines then
- engines = " --engine=" .. table.concat(optengines, ",")
- end
- local release = ""
- if optrelease then
- release = " --release=" .. optrelease[1]
- end
local errorlevel = run(
i,
"texlua " .. scriptname .. " " .. target
@@ -645,7 +657,7 @@ end
-- Set up the check system files: needed for checking one or more tests and
-- for saving the test files
-function checkinit()
+local function checkinit()
cleandir(testdir)
depinstall(checkdeps)
-- Copy dependencies to the test directory itself: this makes the paths
@@ -669,7 +681,7 @@ function checkinit()
for _,i in ipairs(checksuppfiles) do
cp(i, supportdir, testdir)
end
- os.execute(os_ascii .. ">" .. testdir .. "/ascii.tcx")
+ execute(os_ascii .. ">" .. testdir .. "/ascii.tcx")
end
-- Copy files to the main CTAN release directory
@@ -709,18 +721,18 @@ function copytds()
moduledir = module
end
end
- local installdir = tdsdir .. "/" .. dest .. "/" .. moduledir
-- Convert the file table(s) to a list of individual files
local filenames = { }
for _,i in ipairs(files) do
for _,j in ipairs(i) do
for _,k in ipairs(filelist(source, j)) do
- table.insert(filenames, k)
+ insert(filenames, k)
end
end
end
-- The target is only created if there are actual files to install
if next(filenames) ~= nil then
+ local installdir = tdsdir .. "/" .. dest .. "/" .. moduledir
mkdir(installdir)
for _,i in ipairs(filenames) do
cp(i, source, installdir)
@@ -753,21 +765,21 @@ end
-- Convert the raw log file into one for comparison/storage: keeps only
-- the 'business' part from the tests and removes system-dependent stuff
-function formatlog(logfile, newfile, engine)
+local function formatlog(logfile, newfile, engine)
local maxprintline = maxprintline
if engine == "luatex" or engine == "luajittex" then
maxprintline = maxprintline + 1 -- Deal with an out-by-one error
end
local function killcheck(line)
-- Skip lines containing file dates
- if string.match(line, "[^<]%d%d%d%d/%d%d/%d%d") then
+ if match(line, "[^<]%d%d%d%d/%d%d/%d%d") then
return true
elseif
-- Skip \openin/\openout lines in web2c 7.x
-- As Lua doesn't allow "(in|out)", a slightly complex approach:
-- do a substitution to check the line is exactly what is required!
- string.match(
- string.gsub(line, "^\\openin", "\\openout"), "^\\openout%d%d? = "
+ match(
+ gsub(line, "^\\openin", "\\openout"), "^\\openout%d%d? = "
) then
return true
end
@@ -777,13 +789,13 @@ function formatlog(logfile, newfile, engine)
local function normalize(line, lastline)
-- Zap line numbers from \show, \showbox, \box_show and the like:
-- do this before wrapping lines
- line = string.gsub(line, "^l%.%d+ ", "l. ...")
+ line = gsub(line, "^l%.%d+ ", "l. ...")
-- Also from lua stack traces.
- line = string.gsub(line, "lua:%d+: in function", "lua:...: in function")
+ line = gsub(line, "lua:%d+: in function", "lua:...: in function")
-- Allow for wrapped lines: preserve the content and wrap
-- Skip lines that have an explicit marker for truncation
- if string.len(line) == maxprintline and
- not string.match(line, "%.%.%.$") then
+ if len(line) == maxprintline and
+ not match(line, "%.%.%.$") then
return "", (lastline or "") .. line
end
local line = (lastline or "") .. line
@@ -792,77 +804,76 @@ function formatlog(logfile, newfile, engine)
-- This needs to extract the base name from the log name,
-- and one to allow for the case that there might be "-" chars
-- in the name (other cases are ignored)
- line = string.gsub(
+ line = gsub(
line,
- string.gsub(
- string.match("/" .. logfile, ".*/(.*)%" .. logext .. "$"),
+ gsub(
+ match("/" .. logfile, ".*/(.*)%" .. logext .. "$"),
"-",
"%%-"
),
""
)
-- Zap ./ at begin of filename
- line = string.gsub(line, "%(%.%/", "(")
+ line = gsub(line, "%(%.%/", "(")
-- Zap paths if places other than 'here' are accessible
if checksearch then
local pattern = "%w?:?/[^ ]*/([^/%(%)]*%.%w*)"
-- Files loaded from TeX: all start ( -- )
- line = string.gsub(line, "%(" .. pattern, "(../%1")
+ line = gsub(line, "%(" .. pattern, "(../%1")
-- luaotfload files start with keywords
- line = string.gsub(line, "from " .. pattern .. "%(", "from. ./%1(")
- line = string.gsub(line, ": " .. pattern .. "%)", ": ../%1)")
+ line = gsub(line, "from " .. pattern .. "%(", "from. ./%1(")
+ line = gsub(line, ": " .. pattern .. "%)", ": ../%1)")
end
-- Deal with the fact that "(.aux)" may have still a leading space
- line = string.gsub(line, "^ %(%.aux%)", "(.aux)")
+ line = gsub(line, "^ %(%.aux%)", "(.aux)")
-- Merge all of .fd data into one line so will be removed later
- if string.match(line, "^ *%([%.%/%w]+%.fd[^%)]*$") then
+ if match(line, "^ *%([%.%/%w]+%.fd[^%)]*$") then
lastline = (lastline or "") .. line
return "", (lastline or "") .. line
end
-- TeX90/XeTeX knows only the smaller set of dimension units
- line = string.gsub(
+ line = gsub(
line,
"cm, mm, dd, cc, bp, or sp", "cm, mm, dd, cc, nd, nc, bp, or sp"
)
-- Normalise a case where fixing a TeX bug changes the message text
- line = string.gsub(line, "\\csname\\endcsname ", "\\csname\\endcsname")
+ line = gsub(line, "\\csname\\endcsname ", "\\csname\\endcsname")
-- Zap "on line <num>" and replace with "on line ..."
-- Two similar cases, Lua patterns mean we need to do them separately
- line = string.gsub(line, "on line %d*", "on line ...")
- line = string.gsub(line, "on input line %d*", "on input line ...")
+ line = gsub(line, "on line %d*", "on line ...")
+ line = gsub(line, "on input line %d*", "on input line ...")
-- Tidy up to ^^ notation
for i = 0, 31 do
- line = string.gsub(line, string.char(i), "^^" .. string.char(64 + i))
+ line = gsub(line, char(i), "^^" .. char(64 + i))
end
-- Remove 'normal' direction information on boxes with (u)pTeX
- line = string.gsub(line, ",? yoko direction,?", "")
+ line = gsub(line, ",? yoko direction,?", "")
-- Remove the \special line that in DVI mode keeps PDFs comparable
- if string.match(line, "^%.*\\special%{pdf: docinfo << /Creator") then
+ if match(line, "^%.*\\special%{pdf: docinfo << /Creator") then
return ""
end
-- Remove the \special line possibly present in DVI mode for paper size
- if string.match(line, "^%.*\\special%{papersize") then
+ if match(line, "^%.*\\special%{papersize") then
return ""
end
-- Remove ConTeXt stuff
- if string.match(line, "^backend >") or
- string.match(line, "^close source >") or
- string.match(line, "^mkiv lua stats >") or
- string.match(line, "^pages >") or
- string.match(line, "^system >") or
- string.match(line, "^used file >") or
- string.match(line, "^used option >") or
- string.match(line, "^used structure >") then
+ if match(line, "^backend >") or
+ match(line, "^close source >") or
+ match(line, "^mkiv lua stats >") or
+ match(line, "^pages >") or
+ match(line, "^system >") or
+ match(line, "^used file >") or
+ match(line, "^used option >") or
+ match(line, "^used structure >") then
return ""
end
-- A tidy-up to keep LuaTeX and other engines in sync
- local utf8_char = unicode.utf8.char
- line = string.gsub(line, utf8_char(127), "^^?")
+ line = gsub(line, utf8_char(127), "^^?")
-- Unicode engines display chars in the upper half of the 8-bit range:
-- tidy up to match pdfTeX if an ASCII engine is in use
if next(asciiengines) then
for i = 128, 255 do
- line = string.gsub(line, utf8_char(i), "^^" .. string.format("%02x", i))
+ line = gsub(line, utf8_char(i), "^^" .. format("%02x", i))
end
end
return line, lastline
@@ -872,74 +883,74 @@ function formatlog(logfile, newfile, engine)
local prestart = true
local skipping = false
-- Read the entire log file as a binary: deals with ^@/^[, etc.
- local file = assert(io.open(logfile, "rb"))
- local contents = string.gsub(file:read("*all") .. "\n", "\r\n", "\n")
- io.close(file)
- for line in string.gmatch(contents, "([^\n]*)\n") do
+ local file = assert(open(logfile, "rb"))
+ local contents = gsub(file:read("*all") .. "\n", "\r\n", "\n")
+ close(file)
+ for line in gmatch(contents, "([^\n]*)\n") do
if line == "START-TEST-LOG" then
prestart = false
elseif line == "END-TEST-LOG" then
break
elseif line == "OMIT" then
skipping = true
- elseif string.match(line, "^%)?TIMO$") then
+ elseif match(line, "^%)?TIMO$") then
skipping = false
elseif not prestart and not skipping then
line, lastline = normalize(line, lastline)
- if not string.match(line, "^ *$") and not killcheck(line) then
+ if not match(line, "^ *$") and not killcheck(line) then
newlog = newlog .. line .. os_newline
end
end
end
- local newfile = io.open(newfile, "w")
- io.output(newfile)
- io.write(newlog)
- io.close(newfile)
+ local newfile = open(newfile, "w")
+ output(newfile)
+ write(newlog)
+ close(newfile)
end
-- Additional normalization for LuaTeX
-function formatlualog(logfile, newfile)
+local function formatlualog(logfile, newfile)
local function normalize(line, lastline, dropping)
-- Find \discretionary or \whatsit lines:
-- These may come back later
- if string.match(line, "^%.+\\discretionary$") or
- string.match(line, "^%.+\\discretionary %(penalty 50%)$") or
- string.match(line, "^%.+\\discretionary50%|$") or
- string.match(line, "^%.+\\discretionary50%| replacing $") or
- string.match(line, "^%.+\\whatsit$") then
+ if match(line, "^%.+\\discretionary$") or
+ match(line, "^%.+\\discretionary %(penalty 50%)$") or
+ match(line, "^%.+\\discretionary50%|$") or
+ match(line, "^%.+\\discretionary50%| replacing $") or
+ match(line, "^%.+\\whatsit$") then
return "", line
end
-- For \mathon, we always need this line but the next
-- may be affected
- if string.match(line, "^%.+\\mathon$") then
+ if match(line, "^%.+\\mathon$") then
return line, line
end
-- LuaTeX has a flexible output box
- line = string.gsub(line,"\\box\\outputbox", "\\box255")
+ line = gsub(line,"\\box\\outputbox", "\\box255")
-- LuaTeX identifies spaceskip glue
- line = string.gsub(line,"%(\\spaceskip%) ", " ")
+ line = gsub(line,"%(\\spaceskip%) ", " ")
-- Remove 'display' at end of display math boxes:
-- LuaTeX omits this as it includes direction in all cases
- line = string.gsub(line, "(\\hbox%(.*), display$", "%1")
+ line = gsub(line, "(\\hbox%(.*), display$", "%1")
-- Remove 'normal' direction information on boxes:
-- any bidi/vertical stuff will still show
- line = string.gsub(line, ", direction TLT", "")
+ line = gsub(line, ", direction TLT", "")
-- Find glue setting and round out the last place
local function round_digits(l, m)
- return string.gsub(
+ return gsub(
l,
m .. " (%-?)%d+%.%d+",
m .. " %1"
- .. string.format(
+ .. format(
"%.3f",
- string.match(line, m .. " %-?(%d+%.%d+)") or 0
+ match(line, m .. " %-?(%d+%.%d+)") or 0
)
)
end
- if string.match(line, "glue set %-?%d+%.%d+") then
+ if match(line, "glue set %-?%d+%.%d+") then
line = round_digits(line, "glue set")
end
- if string.match(
+ if match(
line, "glue %-?%d+%.%d+ plus %-?%d+%.%d+ minus %-?%d+%.%d+$"
)
then
@@ -948,35 +959,35 @@ function formatlualog(logfile, newfile)
line = round_digits(line, "minus")
end
-- LuaTeX writes ^^M as a new line, which we lose
- line = string.gsub(line, "%^%^M", "")
+ line = gsub(line, "%^%^M", "")
-- Remove U+ notation in the "Missing character" message
- line = string.gsub(
+ line = gsub(
line,
"Missing character: There is no (%^%^..) %(U%+(....)%)",
"Missing character: There is no %1"
)
-- A function to handle the box prefix part
local function boxprefix(s)
- return string.gsub(string.match(s, "^(%.+)"), "%.", "%%.")
+ return gsub(match(s, "^(%.+)"), "%.", "%%.")
end
-- 'Recover' some discretionary data
- if string.match(lastline, "^%.+\\discretionary %(penalty 50%)$") and
- string.match(line, boxprefix(lastline) .. "%.= ") then
- return string.gsub(line, "%.= ", ""),""
+ if match(lastline, "^%.+\\discretionary %(penalty 50%)$") and
+ match(line, boxprefix(lastline) .. "%.= ") then
+ return gsub(line, "%.= ", ""),""
end
-- Where the last line was a discretionary, looks for the
-- info one level in about what it represents
- if string.match(lastline, "^%.+\\discretionary$") or
- string.match(lastline, "^%.+\\discretionary %(penalty 50%)$") or
- string.match(lastline, "^%.+\\discretionary50%|$") or
- string.match(lastline, "^%.+\\discretionary50%| replacing $") then
+ if match(lastline, "^%.+\\discretionary$") or
+ match(lastline, "^%.+\\discretionary %(penalty 50%)$") or
+ match(lastline, "^%.+\\discretionary50%|$") or
+ match(lastline, "^%.+\\discretionary50%| replacing $") then
local prefix = boxprefix(lastline)
- if string.match(line, prefix .. "%.") or
- string.match(line, prefix .. "%|") then
- if string.match(lastline, " replacing $") and
+ if match(line, prefix .. "%.") or
+ match(line, prefix .. "%|") then
+ if match(lastline, " replacing $") and
not dropping then
-- Modify the return line
- return string.gsub(line, "^%.", ""), lastline, true
+ return gsub(line, "^%.", ""), lastline, true
else
return "", lastline, true
end
@@ -986,11 +997,11 @@ function formatlualog(logfile, newfile)
return line, ""
else
-- Not quite a normal discretionary
- if string.match(lastline, "^%.+\\discretionary50%|$") then
- lastline = string.gsub(lastline, "50%|$", "")
+ if match(lastline, "^%.+\\discretionary50%|$") then
+ lastline = gsub(lastline, "50%|$", "")
end
-- Remove some info that TeX90 lacks
- lastline = string.gsub(lastline, " %(penalty 50%)$", "")
+ lastline = gsub(lastline, " %(penalty 50%)$", "")
-- A normal (TeX90) discretionary:
-- add with the line break reintroduced
return lastline .. os_newline .. line, ""
@@ -999,13 +1010,13 @@ function formatlualog(logfile, newfile)
end
-- Look for another form of \discretionary, replacing a "-"
pattern = "^%.+\\discretionary replacing *$"
- if string.match(line, pattern) then
+ if match(line, pattern) then
return "", line
else
- if string.match(lastline, pattern) then
+ if match(lastline, pattern) then
local prefix = boxprefix(lastline)
- if string.match(line, prefix .. "%.\\kern") then
- return string.gsub(line, "^%.", ""), lastline, true
+ if match(line, prefix .. "%.\\kern") then
+ return gsub(line, "^%.", ""), lastline, true
elseif dropping then
return "", ""
else
@@ -1015,26 +1026,26 @@ function formatlualog(logfile, newfile)
end
-- For \mathon, if the current line is an empty \hbox then
-- drop it
- if string.match(lastline, "^%.+\\mathon$") then
+ if match(lastline, "^%.+\\mathon$") then
local prefix = boxprefix(lastline)
- if string.match(line, prefix .. "\\hbox%(0%.0%+0%.0%)x0%.0$") then
+ if match(line, prefix .. "\\hbox%(0%.0%+0%.0%)x0%.0$") then
return "", ""
end
end
-- Various \local... things that other engines do not do:
-- Only remove the no-op versions
- if string.match(line, "^%.+\\localpar$") or
- string.match(line, "^%.+\\localinterlinepenalty=0$") or
- string.match(line, "^%.+\\localbrokenpenalty=0$") or
- string.match(line, "^%.+\\localleftbox=null$") or
- string.match(line, "^%.+\\localrightbox=null$") then
+ if match(line, "^%.+\\localpar$") or
+ match(line, "^%.+\\localinterlinepenalty=0$") or
+ match(line, "^%.+\\localbrokenpenalty=0$") or
+ match(line, "^%.+\\localleftbox=null$") or
+ match(line, "^%.+\\localrightbox=null$") then
return "", ""
end
-- Older LuaTeX versions set the above up as a whatsit
-- (at some stage this can therefore go)
- if string.match(lastline, "^%.+\\whatsit$") then
+ if match(lastline, "^%.+\\whatsit$") then
local prefix = boxprefix(lastline)
- if string.match(line, prefix .. "%.") then
+ if match(line, prefix .. "%.") then
return "", lastline, true
else
-- End of a \whatsit block
@@ -1044,44 +1055,44 @@ function formatlualog(logfile, newfile)
-- Wrap some cases that can be picked out
-- In some places LuaTeX does use max_print_line, then we
-- get into issues with different wrapping approaches
- if string.len(line) == maxprintline then
+ if len(line) == maxprintline then
return "", lastline .. line
- elseif string.len(lastline) == maxprintline then
- if string.match(line, "\\ETC%.%}$") then
+ elseif len(lastline) == maxprintline then
+ if match(line, "\\ETC%.%}$") then
-- If the line wrapped at \ETC we might have lost a space
return lastline
- .. ((string.match(line, "^\\ETC%.%}$") and " ") or "")
+ .. ((match(line, "^\\ETC%.%}$") and " ") or "")
.. line, ""
- elseif string.match(line, "^%}%}%}$") then
+ elseif match(line, "^%}%}%}$") then
return lastline .. line, ""
else
return lastline .. os_newline .. line, ""
end
-- Return all of the text for a wrapped (multi)line
- elseif string.len(lastline) > maxprintline then
+ elseif len(lastline) > maxprintline then
return lastline .. line, ""
end
-- Remove spaces at the start of lines: deals with the fact that LuaTeX
-- uses a different number to the other engines
- return string.gsub(line, "^%s+", ""), ""
+ return gsub(line, "^%s+", ""), ""
end
local newlog = ""
local lastline = ""
local dropping = false
-- Read the entire log file as a binary: deals with ^@/^[, etc.
- local file = assert(io.open(logfile, "rb"))
- local contents = string.gsub(file:read("*all") .. "\n", "\r\n", "\n")
- io.close(file)
- for line in string.gmatch(contents, "([^\n]*)\n") do
+ local file = assert(open(logfile, "rb"))
+ local contents = gsub(file:read("*all") .. "\n", "\r\n", "\n")
+ close(file)
+ for line in gmatch(contents, "([^\n]*)\n") do
line, lastline, dropping = normalize(line, lastline, dropping)
- if not string.match(line, "^ *$") then
+ if not match(line, "^ *$") then
newlog = newlog .. line .. os_newline
end
end
- local newfile = io.open(newfile, "w")
- io.output(newfile)
- io.write(newlog)
- io.close(newfile)
+ local newfile = open(newfile, "w")
+ output(newfile)
+ write(newlog)
+ close(newfile)
end
-- Look for files, directory by directory, and return the first existing
@@ -1100,13 +1111,13 @@ end
function listmodules()
local modules = { }
local exclmodules = exclmodules or { }
- for entry in lfs.dir(".") do
+ for entry in lfs_dir(".") do
if entry ~= "." and entry ~= ".." then
- local attr = lfs.attributes(entry)
+ local attr = lfs_attributes(entry)
assert(type(attr) == "table")
if attr.mode == "directory" then
if not exclmodules[entry] then
- table.insert(modules, entry)
+ insert(modules, entry)
end
end
end
@@ -1167,7 +1178,7 @@ function setup_check(name, engine)
"Error: failed to find " .. pdfext .. ", " .. tlgext .. " or "
.. lveext .. " file for " .. name .. "!"
)
- os.exit(1)
+ exit(1)
end
runtest(name, engine, true, lveext, true)
pdffile = testdir .. "/" .. testname .. pdfext
@@ -1181,19 +1192,19 @@ function setup_check(name, engine)
for _,v in pairs({pdffile, tlgfile}) do
if v then
cp(
- string.match(v, ".*/(.*)"),
- string.match(v, "(.*)/.*"),
+ match(v, ".*/(.*)"),
+ match(v, "(.*)/.*"),
testdir
)
end
end
end
if pdffile then
- local pdffile = string.match(pdffile, ".*/(.*)")
+ local pdffile = match(pdffile, ".*/(.*)")
ren(
testdir,
pdffile,
- string.gsub(pdffile, pdfext .. "$", ".ref" .. pdfext)
+ gsub(pdffile, pdfext .. "$", ".ref" .. pdfext)
)
return true
else
@@ -1212,14 +1223,14 @@ function compare_pdf(name, engine)
if not refpdffile then
return
end
- if os_windows then
+ if os_type == "windows" then
refpdffile = unix_to_win(refpdffile)
end
- errorlevel = os.execute(
+ errorlevel = execute(
os_cmpexe .. " " .. refpdffile .. " " .. pdffile .. " > " .. cmpfile
)
if errorlevel == 0 then
- os.remove(cmpfile)
+ os_remove(cmpfile)
end
return errorlevel
end
@@ -1233,18 +1244,18 @@ function compare_tlg(name, engine)
if not tlgfile then
return
end
- if os_windows then
+ if os_type == "windows" then
tlgfile = unix_to_win(tlgfile)
end
-- Do additional log formatting if the engine is LuaTeX, there is no
-- LuaTeX-specific .tlg file and the default engine is not LuaTeX
if engine == "luatex"
- and not string.match(tlgfile, "%.luatex" .. "%" .. tlgext)
+ and not match(tlgfile, "%.luatex" .. "%" .. tlgext)
and stdengine ~= "luatex"
and stdengine ~= "luajittex"
then
local luatlgfile = testdir .. "/" .. name .. ".luatex" .. tlgext
- if os_windows then
+ if os_type == "windows" then
luatlgfile = unix_to_win(luatlgfile)
end
formatlualog(tlgfile, luatlgfile)
@@ -1252,11 +1263,11 @@ function compare_tlg(name, engine)
-- This allows code sharing below: we only need the .tlg name in one place
tlgfile = luatlgfile
end
- errorlevel = os.execute(
+ errorlevel = execute(
os_diffexe .. " " .. tlgfile .. " " .. logfile .. " > " .. difffile
)
if errorlevel == 0 then
- os.remove(difffile)
+ os_remove(difffile)
end
return errorlevel
end
@@ -1272,31 +1283,31 @@ function runtest(name, engine, hide, ext, makepdf)
local realengine = engine
local format
if
- string.match(checkformat, "tex$") and
- not string.match(engine, checkformat) then
- format = " -fmt=" .. string.gsub(engine, "(.*)tex$", "%1") .. checkformat
+ match(checkformat, "tex$") and
+ not match(engine, checkformat) then
+ format = " -fmt=" .. gsub(engine, "(.*)tex$", "%1") .. checkformat
else
format = ""
end
-- Special casing for e-LaTeX format
if
- string.match(checkformat, "^latex$") and
- string.match(engine, "^etex$") then
+ match(checkformat, "^latex$") and
+ match(engine, "^etex$") then
format = " -fmt=latex"
end
-- Special casing for (u)pTeX LaTeX formats
if
- string.match(checkformat, "^latex$") and
- string.match(engine, "^u?ptex$") then
+ match(checkformat, "^latex$") and
+ match(engine, "^u?ptex$") then
realengine = "e" .. engine
end
-- Special casing for XeTeX engine
local checkopts = checkopts
- if string.match(engine, "xetex") and not makepdf then
+ if match(engine, "xetex") and not makepdf then
checkopts = checkopts .. " -no-pdf"
end
-- Special casing for ConTeXt
- if string.match(checkformat, "^context$") then
+ if match(checkformat, "^context$") then
format = ""
if engine == "luatex" or engine == "luajittex" then
realengine = "context"
@@ -1306,7 +1317,7 @@ function runtest(name, engine, hide, ext, makepdf)
realengine = "texexec --xetex"
else
print("Engine incompatible with format")
- os.exit(1)
+ exit(1)
end
end
local logfile = testdir .. "/" .. name .. logext
@@ -1349,12 +1360,12 @@ function runtest(name, engine, hide, ext, makepdf)
formatlog(logfile, newfile, engine)
-- Store secondary files for this engine
for _,i in ipairs(filelist(testdir, name .. ".???")) do
- local ext = string.match(i, "%....")
+ local ext = match(i, "%....")
if ext ~= lvtext and ext ~= tlgext and ext ~= lveext and ext ~= logext then
if not fileexists(testsuppdir .. "/" .. i) then
ren(
- testdir, i, string.gsub(
- i, string.gsub(name, "%-", "%%-"), name .. "." .. engine
+ testdir, i, gsub(
+ i, gsub(name, "%-", "%%-"), name .. "." .. engine
)
)
end
@@ -1368,7 +1379,7 @@ runtest_tasks = runtest_tasks or function(name)
end
function dvitopdf(name, dir, engine, hide)
- if string.match(engine, "^u?ptex$") then
+ if match(engine, "^u?ptex$") then
run(
dir,
os_setenv .. " SOURCE_DATE_EPOCH=" .. epoch
@@ -1392,7 +1403,13 @@ end
-- Strip the extension from a file name (if present)
function stripext(file)
- local name = string.match(file, "^(.*)%.")
+ local name = match(file, "^(.*)%.")
+ return name or file
+end
+
+-- Strip the path from a file name (if present)
+function basename(file)
+ local name = match(file, "^.*/([^/]*)$")
return name or file
end
@@ -1411,7 +1428,7 @@ function runtool(envvar, command)
run(
typesetdir,
os_setenv .. " " .. envvar .. "=." .. os_pathsep
- .. relpath(localdir, typesetdir)
+ .. abspath(localdir)
.. (typesetsearch and os_pathsep or "") ..
os_concat ..
command
@@ -1433,7 +1450,7 @@ function bibtex(name)
-- LaTeX always generates an .aux file, so there is a need to
-- look inside it for a \citation line
local grep
- if os_windows then
+ if os_type == "windows" then
grep = "\\\\"
else
grep = "\\\\\\\\"
@@ -1452,7 +1469,7 @@ function bibtex(name)
runtool(
"BIBINPUTS",
os_setenv .. " BSTINPUTS=." .. os_pathsep
- .. relpath(localdir, typesetdir)
+ .. abspath(localdir)
.. (typesetsearch and os_pathsep or "") ..
os_concat ..
bibtexexe .. " " .. bibtexopts .. " " .. name
@@ -1488,11 +1505,11 @@ function tex(file)
end
function typesetpdf(file)
- local name = stripext(file)
+ local name = stripext(basename(file))
print("Typesetting " .. name)
local errorlevel = typeset(file)
if errorlevel == 0 then
- os.remove(name .. ".pdf")
+ os_remove(name .. ".pdf")
cp(name .. ".pdf", typesetdir, ".")
else
print(" ! Compilation failed")
@@ -1505,7 +1522,7 @@ typeset = typeset or function(file)
if errorlevel ~= 0 then
return errorlevel
else
- local name = stripext(file)
+ local name = stripext(basename(file))
errorlevel = biber(name) + bibtex(name)
if errorlevel == 0 then
local function cycle(name)
@@ -1572,14 +1589,14 @@ function check(names)
-- No names passed: find all test files
if not next(names) then
for _,i in pairs(filelist(testfiledir, "*" .. lvtext)) do
- table.insert(names, stripext(i))
+ insert(names, stripext(i))
end
for _,i in ipairs(filelist(unpackdir, "*" .. lvtext)) do
if fileexists(testfiledir .. "/" .. i) then
print("Duplicate test file: " .. i)
return 1
else
- table.insert(names, stripext(i))
+ insert(names, stripext(i))
end
end
end
@@ -1623,7 +1640,7 @@ function showfaileddiff()
for _,i in ipairs(filelist(testdir, "*" .. os_diffext)) do
print(" - " .. testdir .. "/" .. i)
print("")
- local f = io.open(testdir .. "/" .. i,"r")
+ local f = open(testdir .. "/" .. i,"r")
local content = f:read("*all")
f:close()
print("-----------------------------------------------------------------------------------")
@@ -1678,8 +1695,8 @@ function cmdcheck()
for _,i in ipairs(typesetsuppfiles) do
cp(i, supportdir, testdir)
end
- local engine = string.gsub(stdengine, "tex$", "latex")
- local localdir = relpath(localdir, testdir)
+ local engine = gsub(stdengine, "tex$", "latex")
+ local localdir = abspath(localdir)
print("Checking source files")
for _,i in ipairs(cmdchkfiles) do
for _,j in ipairs(filelist(".", i)) do
@@ -1693,9 +1710,9 @@ function cmdcheck()
" \"\\PassOptionsToClass{check}{l3doc} \\input " .. j .. "\""
.. " > " .. os_null
)
- for line in io.lines(testdir .. "/" .. stripext(j) .. ".cmds") do
- if string.match(line, "^%!") then
- print(" - " .. string.match(line, "^%! (.*)"))
+ for line in lines(testdir .. "/" .. stripext(j) .. ".cmds") do
+ if match(line, "^%!") then
+ print(" - " .. match(line, "^%! (.*)"))
end
end
end
@@ -1793,7 +1810,7 @@ function bundlectan()
for _,i in ipairs(include) do
for _,j in ipairs(filelist(".", i)) do
if not excludelist[j] then
- table.insert(includelist, j)
+ insert(includelist, j)
end
end
end
@@ -1805,7 +1822,7 @@ function bundlectan()
-- Work out what PDF files are available
pdffiles = { }
for _,i in ipairs(typesetfiles) do
- table.insert(pdffiles, (string.gsub(i, "%.%w+$", ".pdf")))
+ insert(pdffiles, (gsub(i, "%.%w+$", ".pdf")))
end
typesetlist = excludelist(typesetfiles, {sourcefiles})
sourcelist = excludelist(
@@ -1834,22 +1851,24 @@ function doc(files)
unpack()
-- Main loop for doc creation
for _,i in ipairs(typesetfiles) do
- for _,j in ipairs(filelist(".", i)) do
- -- Allow for command line selection of files
- local typeset = true
- if files and next(files) then
- typeset = false
- for _,k in ipairs(files) do
- if k == stripext(j) then
- typeset = true
- break
+ for _, dir in ipairs({unpackdir, typesetdir}) do
+ for _,j in ipairs(filelist(dir, i)) do
+ -- Allow for command line selection of files
+ local typeset = true
+ if files and next(files) then
+ typeset = false
+ for _,k in ipairs(files) do
+ if k == stripext(j) then
+ typeset = true
+ break
+ end
end
end
- end
- if typeset then
- local errorlevel = typesetpdf(j)
- if errorlevel ~= 0 then
- return errorlevel
+ if typeset then
+ local errorlevel = typesetpdf(abspath(dir) .. "/" .. j)
+ if errorlevel ~= 0 then
+ return errorlevel
+ end
end
end
end
@@ -1863,8 +1882,8 @@ function install()
if errorlevel ~= 0 then
return errorlevel
end
- kpse.set_program_name("latex")
- local texmfhome = kpse.var_value("TEXMFHOME")
+ set_program_name("latex")
+ local texmfhome = var_value("TEXMFHOME")
local installdir = texmfhome .. "/tex/" .. moduledir
errorlevel = cleandir(installdir)
if errorlevel ~= 0 then
@@ -1928,13 +1947,13 @@ if versionform ~= "" and not setversion_update_line then
function setversion_update_line(line, date, release)
-- No real regex so do it one type at a time
for _,i in pairs({"Class", "File", "Package"}) do
- if string.match(
+ if match(
line,
"^\\Provides" .. i .. "{[a-zA-Z0-9%-%.]+}%[[^%]]*%]$"
) then
- line = string.gsub(line, "%[%d%d%d%d/%d%d/%d%d", "["
- .. string.gsub(date, "%-", "/"))
- line = string.gsub(
+ line = gsub(line, "%[%d%d%d%d/%d%d/%d%d", "["
+ .. gsub(date, "%-", "/"))
+ line = gsub(
line, "(%[%d%d%d%d/%d%d/%d%d) [^ ]*", "%1 " .. release
)
break
@@ -1946,14 +1965,14 @@ if versionform ~= "" and not setversion_update_line then
function setversion_update_line(line, date, release)
-- No real regex so do it one type at a time
for _,i in pairs({"Class", "File", "Package"}) do
- if string.match(
+ if match(
line,
"^\\ProvidesExpl" .. i .. " *{[a-zA-Z0-9%-%.]+}"
) then
- line = string.gsub(
+ line = gsub(
line,
"{%d%d%d%d/%d%d/%d%d}( *){[^}]*}",
- "{" .. string.gsub(date, "%-", "/") .. "}%1{" .. release .. "}"
+ "{" .. gsub(date, "%-", "/") .. "}%1{" .. release .. "}"
)
break
end
@@ -1962,20 +1981,20 @@ if versionform ~= "" and not setversion_update_line then
end
elseif versionform == "filename" then
function setversion_update_line(line, date, release)
- if string.match(line, "^\\def\\filedate{%d%d%d%d/%d%d/%d%d}$") then
- line = "\\def\\filedate{" .. string.gsub(date, "%-", "/") .. "}"
+ if match(line, "^\\def\\filedate{%d%d%d%d/%d%d/%d%d}$") then
+ line = "\\def\\filedate{" .. gsub(date, "%-", "/") .. "}"
end
- if string.match(line, "^\\def\\fileversion{[^}]+}$") then
+ if match(line, "^\\def\\fileversion{[^}]+}$") then
line = "\\def\\fileversion{" .. release .. "}"
end
return line
end
elseif versionform == "ExplFileDate" then
function setversion_update_line(line, date, release)
- if string.match(line, "^\\def\\ExplFileDate{%d%d%d%d/%d%d/%d%d}$") then
- line = "\\def\\ExplFileDate{" .. string.gsub(date, "%-", "/") .. "}"
+ if match(line, "^\\def\\ExplFileDate{%d%d%d%d/%d%d/%d%d}$") then
+ line = "\\def\\ExplFileDate{" .. gsub(date, "%-", "/") .. "}"
end
- if string.match(line, "^\\def\\ExplFileVersion{[^}]+}$") then
+ if match(line, "^\\def\\ExplFileVersion{[^}]+}$") then
line = "\\def\\ExplFileVersion{" .. release .. "}"
end
return line
@@ -1988,36 +2007,36 @@ setversion_update_line = setversion_update_line or function(line, date, release)
return line
end
-function setversion()
- local function rewrite(file, date, version)
+function setversion(dir)
+ local function rewrite(dir, file, date, release)
local changed = false
- local lines = ""
- for line in io.lines(file) do
- local newline = setversion_update_line(line, date, version)
+ local result = ""
+ for line in lines(dir .. "/" .. file) do
+ local newline = setversion_update_line(line, date, release)
if newline ~= line then
line = newline
changed = true
end
- lines = lines .. line .. os_newline
+ result = result .. line .. os_newline
end
if changed then
-- Avoid adding/removing end-of-file newline
- local f = io.open(file, "rb")
+ local f = open(dir .. "/" .. file, "rb")
local content = f:read("*all")
- io.close(f)
- if not string.match(content, os_newline .. "$") then
- string.gsub(lines, os_newline .. "$", "")
+ close(f)
+ if not match(content, os_newline .. "$") then
+ gsub(result, os_newline .. "$", "")
end
-- Write the new file
- ren(".", file, file .. bakext)
- local f = io.open(file, "w")
- io.output(f)
- io.write(lines)
- io.close(f)
- rm(".", file .. bakext)
+ ren(dir, file, file .. bakext)
+ local f = open(dir .. "/" .. file, "w")
+ output(f)
+ write(result)
+ close(f)
+ rm(dir, file .. bakext)
end
end
- local date = os.date("%Y-%m-%d")
+ local date = os_date("%Y-%m-%d")
if optdate then
date = optdate[1] or date
end
@@ -2025,9 +2044,10 @@ function setversion()
if optrelease then
release = optrelease[1] or release
end
+ local dir = dir or "."
for _,i in pairs(versionfiles) do
- for _,j in pairs(filelist(".", i)) do
- rewrite(j, date, release)
+ for _,j in pairs(filelist(dir, i)) do
+ rewrite(dir, j, date, release)
end
end
return 0
@@ -2083,10 +2103,10 @@ bundleunpack = bundleunpack or function(sourcedir)
-- This 'yes' business is needed to pass a series of "y\n" to
-- TeX if \askforoverwrite is true
-- That is all done using a file as it's the only way on Windows and
- -- on Unix the "yes" command can't be used inside os.execute (it never
+ -- on Unix the "yes" command can't be used inside execute (it never
-- stops, which confuses Lua)
- os.execute(os_yes .. ">>" .. localdir .. "/yes")
- local localdir = relpath(localdir, unpackdir)
+ execute(os_yes .. ">>" .. localdir .. "/yes")
+ local localdir = abspath(localdir)
errorlevel = run(
unpackdir,
os_setenv .. " TEXINPUTS=." .. os_pathsep
@@ -2107,7 +2127,7 @@ end
function version()
print(
"\n"
- .. "l3build Release " .. string.gsub(release_date, "/", "-") .. "\n"
+ .. "l3build Release " .. gsub(release_date, "/", "-") .. "\n"
)
end
@@ -2187,9 +2207,9 @@ function stdmain(target, files)
end
end
if errorlevel ~= 0 then
- os.exit(1)
+ exit(1)
else
- os.exit(0)
+ exit(0)
end
end
@@ -2197,9 +2217,9 @@ end
main = main or stdmain
-- Pick up and read any per-run testfiledir
-if userargs["testfiledir"] then
- if #userargs["testfiledir"] == 1 then
- testfiledir = userargs["testfiledir"][1]
+if options["testfiledir"] then
+ if #options["testfiledir"] == 1 then
+ testfiledir = options["testfiledir"][1]
if fileexists(testfiledir .. "/config.lua") then
dofile(testfiledir .. "/config.lua")
end
@@ -2210,4 +2230,4 @@ if userargs["testfiledir"] then
end
-- Call the main function
-main(userargs["target"], userargs["files"])
+main(options["target"], options["files"])