From 0baef83f46e61ff1d06c181a1bd8e0df785ff73e Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Sun, 25 Jun 2017 21:51:46 +0000 Subject: l3build (25jun17) git-svn-id: svn://tug.org/texlive/trunk@44698 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/l3build/l3build.lua | 221 ++++++++++++++------- .../tex/latex/l3build/regression-test.tex | 171 ++++++---------- 2 files changed, 204 insertions(+), 188 deletions(-) (limited to 'Master/texmf-dist/tex/latex/l3build') diff --git a/Master/texmf-dist/tex/latex/l3build/l3build.lua b/Master/texmf-dist/tex/latex/l3build/l3build.lua index 44a4783727d..958c30e0d6c 100644 --- a/Master/texmf-dist/tex/latex/l3build/l3build.lua +++ b/Master/texmf-dist/tex/latex/l3build/l3build.lua @@ -23,7 +23,7 @@ for those people who are interested. --]] -- Version information -release_date = "2017/05/29" +release_date = "2017/06/25" -- "module" is a deprecated function in Lua 5.2: as we want the name -- for other purposes, and it should eventually be 'free', simply @@ -85,26 +85,27 @@ end -- File types for various operations -- Use Unix-style globs -- All of these may be set earlier, so a initialised conditionally -bibfiles = bibfiles or {"*.bib"} -binaryfiles = binaryfiles or {"*.pdf", "*.zip"} -bstfiles = bstfiles or {"*.bst"} -checkfiles = checkfiles or { } -checksuppfiles = checksuppfiles or { } -cmdchkfiles = cmdchkfiles or { } -cleanfiles = cleanfiles or {"*.log", "*.pdf", "*.zip"} -demofiles = demofiles or { } -docfiles = docfiles or { } -excludefiles = excludefiles or {"*~"} -installfiles = installfiles or {"*.sty"} -makeindexfiles = makeindexfiles or {"*.ist"} -sourcefiles = sourcefiles or {"*.dtx", "*.ins"} -textfiles = textfiles or {"*.md", "*.txt"} -typesetdemofiles = typesetdemofiles or { } -typesetfiles = typesetfiles or {"*.dtx"} -typesetsuppfiles = typesetsuppfiles or { } -unpackfiles = unpackfiles or {"*.ins"} -unpacksuppfiles = unpacksuppfiles or { } -versionfiles = versionfiles or {"*.dtx"} +bibfiles = bibfiles or {"*.bib"} +binaryfiles = binaryfiles or {"*.pdf", "*.zip"} +bstfiles = bstfiles or {"*.bst"} +checkfiles = checkfiles or { } +checksuppfiles = checksuppfiles or { } +cmdchkfiles = cmdchkfiles or { } +cleanfiles = cleanfiles or {"*.log", "*.pdf", "*.zip"} +demofiles = demofiles or { } +docfiles = docfiles or { } +excludefiles = excludefiles or {"*~"} +installfiles = installfiles or {"*.sty"} +makeindexfiles = makeindexfiles or {"*.ist"} +sourcefiles = sourcefiles or {"*.dtx", "*.ins"} +textfiles = textfiles or {"*.md", "*.txt"} +typesetdemofiles = typesetdemofiles or { } +typesetfiles = typesetfiles or {"*.dtx"} +typesetsuppfiles = typesetsuppfiles or { } +typesetsourcefiles = typesetsourcefiles or { } +unpackfiles = unpackfiles or {"*.ins"} +unpacksuppfiles = unpacksuppfiles or { } +versionfiles = versionfiles or {"*.dtx"} -- Roots which should be unpacked to support unpacking/testing/typesetting checkdeps = checkdeps or { } @@ -489,7 +490,7 @@ end -- Copy files 'quietly' function cp(glob, source, dest) local errorlevel - for _,i in ipairs(filelist(source, glob)) do + for i,_ in pairs(tree(source, glob)) do local source = source .. "/" .. i if os_type == "windows" then if lfs_attributes(source)["mode"] == "directory" then @@ -562,6 +563,58 @@ function filelist(path, glob) return files end +-- Does what filelist does, but can also glob subdirectories. In the returned +-- table, the keys are paths relative to the given starting path, the values +-- are their counterparts relative to the current working directory. +function tree(path, glob) + function cropdots(path) + return gsub(gsub(path, "^%./", ""), "/%./", "/") + end + function always_true() + return true + end + function is_dir(file) + return lfs.attributes(file)["mode"] == "directory" + end + local dirs = {["."]=cropdots(path)} + for pattern, critereon in gmatch(cropdots(glob), "([^/]+)(/?)") do + local critereon = critereon == "/" and is_dir or always_true + function fill(path, dir, table) + for _, file in ipairs(filelist(dir, pattern)) do + local fullpath = path .. "/" .. file + if file ~= "." and file ~= ".." and + fullpath ~= maindir .. "/build" and + (string.sub(pattern, 1, 1) == "." + or string.sub(file, 1, 1) ~= ".") + then + local fulldir = dir .. "/" .. file + if critereon(fulldir) then + table[fullpath] = fulldir + end + end + end + end + local newdirs = {} + if pattern == "**" then + while true do + path, dir = next(dirs) + if not path then + break + end + dirs[path] = nil + newdirs[path] = dir + fill(path, dir, dirs) + end + else + for path, dir in pairs(dirs) do + fill(path, dir, newdirs) + end + end + dirs = newdirs + end + return dirs +end + function mkdir(dir) if os_type == "windows" then -- Windows (with the extensions) will automatically make directory trees @@ -658,7 +711,7 @@ end -- Set up the check system files: needed for checking one or more tests and -- for saving the test files -local function checkinit() +function checkinit() cleandir(testdir) depinstall(checkdeps) -- Copy dependencies to the test directory itself: this makes the paths @@ -801,26 +854,17 @@ local function formatlog(logfile, newfile, engine) end local line = (lastline or "") .. line lastline = "" - -- Remove test file name from lines - -- 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 = gsub( - line, - gsub( - match("/" .. logfile, ".*/(.*)%" .. logext .. "$"), - "-", - "%%-" - ), - "" - ) -- Zap ./ at begin of filename line = gsub(line, "%(%.%/", "(") -- Zap paths if places other than 'here' are accessible if checksearch then - local pattern = "%w?:?/[^ ]*/([^/%(%)]*%.%w*)" + -- The pattern excludes < and > as the image part can have + -- several entries on one line + local pattern = "%w?:?/[^ %<%>]*/([^/%(%)]*%.%w*)" -- Files loaded from TeX: all start ( -- ) line = gsub(line, "%(" .. pattern, "(../%1") + -- Images + line = gsub(line, "<" .. pattern .. ">", "<../%1>") -- luaotfload files start with keywords line = gsub(line, "from " .. pattern .. "%(", "from. ./%1(") line = gsub(line, ": " .. pattern .. "%)", ": ../%1)") @@ -849,6 +893,7 @@ local function formatlog(logfile, newfile, engine) end -- Remove 'normal' direction information on boxes with (u)pTeX line = gsub(line, ",? yoko direction,?", "") + line = gsub(line, ",? yoko%(math%) direction,?", "") -- Remove the \special line that in DVI mode keeps PDFs comparable if match(line, "^%.*\\special%{pdf: docinfo << /Creator") then return "" @@ -1402,15 +1447,28 @@ function dvitopdf(name, dir, engine, hide) end end --- Strip the path from a file name (if present) +-- Split a path into file and directory component +function splitpath(file) + local path, name = match(file, "^(.*)/([^/]*)$") + if path then + return path, name + else + return ".", file + end +end + +-- Arguably clearer names function basename(file) - local name = match(file, "^.*/([^/]*)$") - return name or file + return(select(2, splitpath(file))) +end + +function dirname(file) + return(select(1, splitpath(file))) end -- Strip the extension from a file name (if present) function jobname(file) - local name = match(basename(file), "^(.*)%.") + local name = match(select(2, splitpath(file)), "^(.*)%.") return name or file end @@ -1424,12 +1482,14 @@ end -- -- An auxiliary used to set up the environmental variables -function runtool(envvar, command) +function runtool(subdir, dir, envvar, command) + dir = dir or "." return( run( - typesetdir, + typesetdir .. "/" .. subdir, os_setenv .. " " .. envvar .. "=." .. os_pathsep - .. abspath(localdir) + .. abspath(localdir) .. os_pathsep + .. abspath(dir .. "/" .. subdir) .. (typesetsearch and os_pathsep or "") .. os_concat .. command @@ -1437,16 +1497,17 @@ function runtool(envvar, command) ) end -function biber(name) +function biber(name, dir) if fileexists(typesetdir .. "/" .. name .. ".bcf") then + local path, name = splitpath(name) return( - runtool("BIBINPUTS", biberexe .. " " .. biberopts .. " " .. name) + runtool(path, dir, "BIBINPUTS", biberexe .. " " .. biberopts .. " " .. name) ) end return 0 end -function bibtex(name) +function bibtex(name, dir) if fileexists(typesetdir .. "/" .. name .. ".aux") then -- LaTeX always generates an .aux file, so there is a need to -- look inside it for a \citation line @@ -1456,6 +1517,7 @@ function bibtex(name) else grep = "\\\\\\\\" end + local path, name = splitpath(name) if run( typesetdir, os_grepexe .. " \"^" .. grep .. "citation{\" " .. name .. ".aux > " @@ -1468,6 +1530,7 @@ function bibtex(name) return( -- Cheat slightly as we need to set two variables runtool( + path, dir, "BIBINPUTS", os_setenv .. " BSTINPUTS=." .. os_pathsep .. abspath(localdir) @@ -1481,34 +1544,38 @@ function bibtex(name) return 0 end -function makeindex(name, inext, outext, logext, style) +function makeindex(name, dir, inext, outext, logext, style) if fileexists(typesetdir .. "/" .. name .. inext) then + local path, name = splitpath(name) return( runtool( + path, dir, "INDEXSTYLE", makeindexexe .. " " .. makeindexopts .. " " .. " -s " .. style .. " -o " .. name .. outext - .. " -t " .. name .. logext .. " " .. name .. inext + .. " -t " .. name .. " " .. name .. inext ) ) end return 0 end -function tex(file) +function tex(file, dir) + local path, name = splitpath(file) return( runtool( + path, dir, "TEXINPUTS", typesetexe .. " " .. typesetopts .. " \"" .. typesetcmds - .. "\\input " .. file .. "\"" + .. "\\input " .. name .. "\"" ) ) end -function typesetpdf(file) +function typesetpdf(file, dir) local name = jobname(file) print("Typesetting " .. name) - local errorlevel = typeset(file) + local errorlevel = typeset(file, dir) if errorlevel == 0 then os_remove(name .. ".pdf") cp(name .. ".pdf", typesetdir, ".") @@ -1518,24 +1585,25 @@ function typesetpdf(file) return errorlevel end -typeset = typeset or function(file) - local errorlevel = tex(file) +typeset = typeset or function(file, dir) + dir = dir or "." + local errorlevel = tex(file, dir) if errorlevel ~= 0 then return errorlevel else local name = jobname(file) - errorlevel = biber(name) + bibtex(name) + errorlevel = biber(name, dir) + bibtex(name, dir) if errorlevel == 0 then - local function cycle(name) + local function cycle(name, dir) return( - makeindex(name, ".glo", ".gls", ".glg", glossarystyle) + - makeindex(name, ".idx", ".ind", ".ilg", indexstyle) + - tex(file) + makeindex(name, dir, ".glo", ".gls", ".glg", glossarystyle) + + makeindex(name, dir, ".idx", ".ind", ".ilg", indexstyle) + + tex(file, dir) ) end - errorlevel = cycle(name) + errorlevel = cycle(name, dir) if errorlevel == 0 then - errorlevel = cycle(name) + errorlevel = cycle(name, dir) end end return errorlevel @@ -1859,12 +1927,12 @@ function doc(files) cp(i, supportdir, typesetdir) end depinstall(typesetdeps) - unpack() + unpack({sourcefiles, typesetsourcefiles}) -- Main loop for doc creation for _, typesetfiles in ipairs({typesetdemofiles, typesetfiles}) do for _,i in ipairs(typesetfiles) do for _, dir in ipairs({unpackdir, typesetdir}) do - for _,j in ipairs(filelist(dir, i)) do + for j,_ in pairs(tree(dir, i)) do -- Allow for command line selection of files local typeset = true if files and next(files) then @@ -1877,7 +1945,7 @@ function doc(files) end end if typeset then - local errorlevel = typesetpdf(abspath(dir) .. "/" .. j) + local errorlevel = typesetpdf(j, dir) if errorlevel ~= 0 then return errorlevel end @@ -2068,12 +2136,12 @@ end -- Unpack the package files using an 'isolated' system: this requires -- a copy of the 'basic' DocStrip program, which is used then removed -function unpack() +function unpack(sources) local errorlevel = depinstall(unpackdeps) if errorlevel ~= 0 then return errorlevel end - errorlevel = bundleunpack() + errorlevel = bundleunpack({"."}, sources) if errorlevel ~= 0 then return errorlevel end @@ -2088,7 +2156,7 @@ end -- Split off from the main unpack so it can be used on a bundle and not -- leave only one modules files -bundleunpack = bundleunpack or function(sourcedir) +bundleunpack = bundleunpack or function(sourcedir, sources) local errorlevel = mkdir(localdir) if errorlevel ~=0 then return errorlevel @@ -2098,10 +2166,12 @@ bundleunpack = bundleunpack or function(sourcedir) return errorlevel end for _,i in ipairs(sourcedir or {"."}) do - for _,j in ipairs(sourcefiles) do - errorlevel = cp(j, i, unpackdir) - if errorlevel ~=0 then - return errorlevel + for _,j in ipairs(sources or {sourcefiles}) do + for _,k in ipairs(j) do + errorlevel = cp(k, i, unpackdir) + if errorlevel ~=0 then + return errorlevel + end end end end @@ -2112,20 +2182,21 @@ bundleunpack = bundleunpack or function(sourcedir) end end for _,i in ipairs(unpackfiles) do - for _,j in ipairs(filelist(unpackdir, i)) do + for j,_ in pairs(tree(unpackdir, i)) do -- 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 execute (it never -- stops, which confuses Lua) execute(os_yes .. ">>" .. localdir .. "/yes") + local path, name = splitpath(j) local localdir = abspath(localdir) errorlevel = run( - unpackdir, + unpackdir .. "/" .. path, os_setenv .. " TEXINPUTS=." .. os_pathsep .. localdir .. (unpacksearch and os_pathsep or "") .. os_concat .. - unpackexe .. " " .. unpackopts .. " " .. j .. " < " + unpackexe .. " " .. unpackopts .. " " .. name .. " < " .. localdir .. "/yes" .. (optquiet and (" > " .. os_null) or "") ) diff --git a/Master/texmf-dist/tex/latex/l3build/regression-test.tex b/Master/texmf-dist/tex/latex/l3build/regression-test.tex index b11581fae21..eae274e09f6 100644 --- a/Master/texmf-dist/tex/latex/l3build/regression-test.tex +++ b/Master/texmf-dist/tex/latex/l3build/regression-test.tex @@ -18,10 +18,15 @@ %% This file is part of the "l3build bundle" (The Work in LPPL) %% and all files in that bundle must be distributed together. %% +\begingroup\expandafter\expandafter\expandafter\endgroup +\expandafter\ifx\csname eTeXversion\endcsname\relax + \errmessage{e-TeX is required to use regression-test.tex}% + \expandafter\endinput +\fi \ifx\unprotect\undefined \expandafter\edef\csname reset\string @catcodes\endcsname{% \catcode`\noexpand\@=\the\catcode`\@\relax - } + }% \catcode`\@=11 % \else \unprotect @@ -31,8 +36,11 @@ \errorcontextlines=-1 % \showboxbreadth=\maxdimen \showboxdepth=\maxdimen -\def\loggingoutput{\tracingoutput1 - \showboxbreadth\maxdimen\showboxdepth\maxdimen} +\def\loggingoutput{% + \tracingoutput=1 % + \showboxbreadth=\maxdimen + \showboxdepth=\maxdimen +} \newlinechar=`\^^J \long\def\LONGTYPEOUT#1{% \begingroup @@ -42,146 +50,71 @@ } \let\TYPE\LONGTYPEOUT \def\STARTMESSAGE{This is a generated file for the l3build validation system.} -\def\START{\LONGTYPEOUT{^^JSTART-TEST-LOG^^J^^J% - \STARTMESSAGE% -^^J^^JDon't change this file in any respect.% -^^J^^J}} -\begingroup -\catcode`\^^\=0 -\catcode`\^^A=\catcode`\% -^^\catcode`^^\ =11 -^^\catcode`^^\%=11 -^^\catcode`^^\#=11 -^^\catcode`^^\~=11 -^^\endlinechar=`^^\^^J -^^\catcode`^^\\=11^^A -^^\gdef^^\CTable{ -%% \CharacterTable -%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -%% Digits \0\1\2\3\4\5\6\7\8\9 -%% Exclamation \! Double quote \" Hash (number) \# -%% Dollar \$ Percent \% Ampersand \& -%% Acute accent \' Left paren \( Right paren \) -%% Asterisk \* Plus \+ Comma \, -%% Minus \- Point \. Solidus \/ -%% Colon \: Semicolon \; Less than \< -%% Equals \= Greater than \> Question mark \? -%% Commercial at \@ Left bracket \[ Backslash \\ -%% Right bracket \] Circumflex \^ Underscore \_ -%% Grave accent \` Left brace \{ Vertical bar \| -%% Right brace \} Tilde \~} -%% -}^^A -^^\endgroup{}% +\def\START{% + \LONGTYPEOUT{^^JSTART-TEST-LOG^^J}% + \LONGTYPEOUT{^^J% + \STARTMESSAGE% + ^^J^^JDon't change this file in any respect.% + ^^J^^J% + }% +} \ifx\@@end\@undefined \let\@@@end\end \else \let\@@@end\@@end \fi -\def\END - {% - \ifx\currentiflevel\@undefined\else - \ifnum\currentgrouplevel>0 % - \LONGTYPEOUT{Bad grouping: \the\currentgrouplevel!}% - \fi - \ifnum\currentiflevel>2 % - \LONGTYPEOUT{Bad conditionals: \the\numexpr\currentiflevel-2!}% - \fi - \fi - \LONGTYPEOUT{^^JEND-TEST-LOG^^J}\@@@end - } +\def\END{% + \ifnum\currentgrouplevel>0 % + \LONGTYPEOUT{Bad grouping: \the\currentgrouplevel!}% + \fi + \ifnum\currentiflevel>2 % + \LONGTYPEOUT{Bad conditionals: \the\numexpr\currentiflevel-2!}% + \fi + \LONGTYPEOUT{^^JEND-TEST-LOG^^J}% + \@@@end +} \ifx\@@end\@undefined \let\end\END \else \let\@@end\END \fi -\def\FORMAT#1{\LONGTYPEOUT{Format: #1}% - \def\@tempa{#1}\ifx\@tempa\@EJ\else - \OMIT\TYPE{WARNING: Declared format #1,^^JActual format \@EJ}\TIMO\fi} -\edef\@EJ{\fmtname <\fmtversion>} -\def\AUTHOR#1{\LONGTYPEOUT{Author: #1}} \def\OMIT{\LONGTYPEOUT{OMIT}} \def\TIMO{\LONGTYPEOUT{TIMO}} -\def\CLASS{\@ifnextchar[\OPTCLASS\XCLASS} -\def\OPTCLASS[#1]#2{% - \TYPE{Main Class: #2^^J\space\space\space\space Options: #1}} -\def\XCLASS#1{% - \TYPE{Main Class: #1}} -\def\PACKAGE{\@ifnextchar[\OPTPACKAGE\XPACKAGE} -\def\OPTPACKAGE[#1]#2{% - \TYPE{Package: #2^^J\space\space\space\space Options: #1}} -\def\XPACKAGE#1{% - \TYPE{Package: #1}} -\ifx\@ifnextchar\@undefined -\long\def\@ifnextchar#1#2#3{% - \let\reserved@d=#1% - \def\reserved@a{#2}% - \def\reserved@b{#3}% - \futurelet\@let@token\@ifnch} -\def\@ifnch{% - \ifx\@let@token\@sptoken - \let\reserved@c\@xifnch - \else - \ifx\@let@token\reserved@d - \let\reserved@c\reserved@a +\ifx\InputIfFileExists\@undefined + \newread\@inputcheck + \long\def\InputIfFileExists#1#2#3{% + \openin\@inputcheck#1\relax + \ifeof\@inputcheck + \def\reserved@a{#3}% \else - \let\reserved@c\reserved@b + \def\reserved@a{#2\input #1\relax}% \fi - \fi - \reserved@c} -\def\:{\let\@sptoken= } \: % this makes \@sptoken a space token -\def\:{\@xifnch} \expandafter\def\: {\futurelet\@let@token\@ifnch} -\fi -\def\CHECKCOMMAND#1{% - \ifx#1\@undefined\LONGTYPEOUT{Undefined \string#1}\else - \ifx#1\relax\LONGTYPEOUT{Relaxed \space\space\string#1}\else - \LONGTYPEOUT{Defined \space\space\string#1}\fi\fi} -\ifx\InputIfFileExists\@undefined -\newread\@inputcheck -\long\def\InputIfFileExists#1#2#3{% - \openin\@inputcheck#1\relax - \ifeof\@inputcheck - \def\reserved@a{#3}% - \else - \def\reserved@a{#2\input #1\relax}% - \fi - \closein\@inputcheck - \reserved@a} + \closein\@inputcheck + \reserved@a + }% \fi \InputIfFileExists{regression-test.cfg} - {\LONGTYPEOUT{^^J***^^Jregression-test.cfg in operation^^J***^^J}}{} -\ifdefined\pdfoutput - \ifnum\pdfoutput>0 % - \pdfmapfile{pdftex.map}% - \fi -\else - \ifdefined\outputmode - \ifnum\outputmode>0 % - \pdfextension mapfile{pdftex.map}% - \fi - \fi -\fi -\newcount \gTESTint + {\LONGTYPEOUT{^^J***^^Jregression-test.cfg in operation^^J***^^J}}{} +\newcount\gTESTint \def\SEPARATOR{% \TYPE{% ============================================================% }% } \long\def\TEST#1#2{% - \advance \gTESTint 1 % + \global\advance\gTESTint by 1 % \SEPARATOR - \LONGTYPEOUT{% - TEST \the\gTESTint: \detokenize{#1}}% + \LONGTYPEOUT{TEST \the\gTESTint: \detokenize{#1}}% \SEPARATOR \begingroup \let\TYPE\LONGTYPEOUT #2% \endgroup - \SEPARATOR \LONGTYPEOUT{}% + \SEPARATOR + \LONGTYPEOUT{}% } \long\def\TESTEXP#1#2{% - \advance \gTESTint 1 % + \global\advance\gTESTint by 1 % \SEPARATOR \LONGTYPEOUT{% TEST \the\gTESTint: \detokenize{#1}}% @@ -198,6 +131,18 @@ \def \YES {\TYPE{YES}} \def \NO {\TYPE{NO}} \def \NEWLINE {\TYPE{^^J}} +\ifx\pdfoutput\@undefined + \ifx\outputmode\@undefined + \else + \ifnum\outputmode>0 % + \pdfextension mapfile{pdftex.map}% + \fi + \fi +\else + \ifnum\pdfoutput>0 % + \pdfmapfile{pdftex.map}% + \fi +\fi \ifnum 0% \ifx\pdfoutput\@undefined\else\ifnum\pdfoutput>0 1\fi\fi \ifx\outputmode\@undefined\else\ifnum\outputmode>0 1\fi\fi -- cgit v1.2.3