From 6c09dd71fc1b55b7990d439747f090fa57a84b77 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 29 Jul 2015 20:37:53 +0000 Subject: l3build (29jul15) git-svn-id: svn://tug.org/texlive/trunk@37991 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/l3build/l3build.lua | 868 ++++++++++++------------ 1 file changed, 436 insertions(+), 432 deletions(-) (limited to 'Master/texmf-dist/tex') diff --git a/Master/texmf-dist/tex/latex/l3build/l3build.lua b/Master/texmf-dist/tex/latex/l3build/l3build.lua index 4fa185b6f55..f88ec640d16 100644 --- a/Master/texmf-dist/tex/latex/l3build/l3build.lua +++ b/Master/texmf-dist/tex/latex/l3build/l3build.lua @@ -17,13 +17,13 @@ --]] -- Version information: should be identical to that in l3build.dtx -release_date = "2015/06/25" -release_ver = "5639" +release_date = "2015/07/28" +release_ver = "5704" -- "module" is a deprecated function in Lua 5.2: as we want the name -- for other purposes, and it should eventually be 'free', simply -- remove the built-in -if type (module) == "function" then +if type(module) == "function" then module = nil end @@ -33,18 +33,18 @@ bundle = bundle or "" -- Sanity check if module == "" and bundle == "" then - if string.match (arg[0], ".*l3build%.lua$") then - print ( + if string.match(arg[0], ".*l3build%.lua$") then + print( "\n" .. "Error: Call l3build using a configuration file, not directly.\n" ) else - print ( + print( "\n" .. "Error: Specify either bundle or module in configuration script.\n" ) end - os.exit (1) + os.exit(1) end -- Directory structure for the build system @@ -92,9 +92,8 @@ docfiles = docfiles or { } excludefiles = excludefiles or {"*~"} installfiles = installfiles or {"*.sty"} makeindexfiles = makeindexfiles or {"*.ist"} -readmefiles = readmefiles or {"README.md", "README.markdown", "README.txt"} sourcefiles = sourcefiles or {"*.dtx", "*.ins"} -textfiles = textfiles or { } +textfiles = textfiles or {"*.md", "*.txt"} typesetfiles = typesetfiles or {"*.dtx"} typesetsuppfiles = typesetsuppfiles or { } unpackfiles = unpackfiles or {"*.ins"} @@ -166,7 +165,7 @@ tlgext = tlgext or ".tlg" -- License for original globtopattern --[[ - (c) 2008-2011 David Manura. Licensed under the same terms as Lua (MIT). + (c) 2008-2011 David Manura. Licensed under the same terms as Lua (MIT). Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -188,21 +187,21 @@ tlgext = tlgext or ".tlg" (end license) --]] -function glob_to_pattern (glob) +function glob_to_pattern(glob) local pattern = "^" -- pattern being built local i = 0 -- index in glob local char -- char at index i in glob -- escape pattern char - local function escape (char) - return string.match (char, "^%w$") and char or "%" .. char + local function escape(char) + return string.match(char, "^%w$") and char or "%" .. char end -- Convert tokens. while true do i = i + 1 - char = string.sub (glob, i, i) + char = string.sub(glob, i, i) if char == "" then pattern = pattern .. "$" break @@ -212,7 +211,7 @@ function glob_to_pattern (glob) pattern = pattern .. ".*" elseif char == "[" then -- Ignored - print ("[...] syntax not supported in globs!") + print("[...] syntax not supported in globs!") elseif char == "\\" then i = i + 1 char = string.sub(glob, i, i) @@ -220,9 +219,9 @@ function glob_to_pattern (glob) pattern = pattern .. "\\$" break end - pattern = pattern .. escape (char) + pattern = pattern .. escape(char) else - pattern = pattern .. escape (char) + pattern = pattern .. escape(char) end end return pattern @@ -239,7 +238,7 @@ end -- 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 string.sub (package.config, 1, 1) == "\\" then +if string.sub(package.config, 1, 1) == "\\" then os_concat = "&" os_diffext = ".fc" os_diffexe = "fc /n" @@ -263,37 +262,37 @@ end -- File operations are aided by the LuaFileSystem module, which is available -- within texlua -lfs = require ("lfs") +lfs = require("lfs") -- For cleaning out a directory, which also ensures that it exists -function cleandir (dir) - mkdir (dir) - rm (dir, "*") +function cleandir(dir) + mkdir(dir) + rm(dir, "*") end -- Copy files 'quietly' -function cp (glob, source, dest) - for _,i in ipairs (filelist (source, glob)) do +function cp(glob, source, dest) + for _,i in ipairs(filelist(source, glob)) do local source = source .. "/" .. i if os_windows then - os.execute ( - "copy /y " .. unix_to_win (source) .. " " - .. unix_to_win (dest) .. " > nul" + os.execute( + "copy /y " .. unix_to_win(source) .. " " + .. unix_to_win(dest) .. " > nul" ) else - os.execute ("cp -f " .. source .. " " .. dest) + os.execute("cp -f " .. source .. " " .. dest) end end end -- OS-dependent test for a directory -function direxists (dir) +function direxists(dir) local errorlevel if os_windows then errorlevel = - os.execute ("if not exist \"" .. unix_to_win (dir) .. "\" exit 1") + os.execute("if not exist \"" .. unix_to_win(dir) .. "\" exit 1") else - errorlevel = os.execute ("[ -d " .. dir .. " ]") + errorlevel = os.execute("[ -d " .. dir .. " ]") end if errorlevel ~= 0 then return false @@ -301,8 +300,8 @@ function direxists (dir) return true end -function fileexists (file) - local f = io.open (file, "r") +function fileexists(file) + local f = io.open(file, "r") if f ~= nil then io.close(f) return true @@ -314,21 +313,21 @@ 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) +function filelist(path, glob) local files = { } local pattern if glob then - pattern = glob_to_pattern (glob) + pattern = glob_to_pattern(glob) end - if direxists (path) then - for entry in lfs.dir (path) do + if direxists(path) then + for entry in lfs.dir(path) do if pattern then - if string.match (entry, pattern) then - table.insert (files, entry) + if string.match(entry, pattern) then + table.insert(files, entry) end else if entry ~= "." and entry ~= ".." then - table.insert (files, entry) + table.insert(files, entry) end end end @@ -336,19 +335,19 @@ function filelist (path, glob) return files end -function mkdir (dir) +function mkdir(dir) if os_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) - os.execute ("if not exist " .. dir .. "\\nul " .. "mkdir " .. dir) + local dir = unix_to_win(dir) + os.execute("if not exist " .. dir .. "\\nul " .. "mkdir " .. dir) else - os.execute ("mkdir -p " .. dir) + os.execute("mkdir -p " .. dir) end end -- Find the relationship between two directories -function relpath (target, source) +function relpath(target, source) -- A shortcut for the case where the two are the same if target == source then return "" @@ -357,13 +356,13 @@ function relpath (target, source) 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, "") + (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 + for i = 0, select(2, string.gsub(target, "/", "")) do resultdir = resultdir .. "../" end -- Return the relative part plus the unique part of the target @@ -371,42 +370,42 @@ function relpath (target, source) end -- Rename -function ren (dir, source, dest) +function ren(dir, source, dest) local dir = dir .. "/" if os_windows then - os.execute ("ren " .. unix_to_win (dir) .. source .. " " .. dest) + os.execute("ren " .. unix_to_win(dir) .. source .. " " .. dest) else - os.execute ("mv " .. dir .. source .. " " .. dir .. dest) + os.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) +function rm(source, glob) + for _,i in ipairs(filelist(source, glob)) do + os.remove(source .. "/" .. i) end end -- Remove a directory tree -function rmdir (dir) +function rmdir(dir) -- First, make sure it exists to avoid any errors - mkdir (dir) + mkdir(dir) if os_windows then - os.execute ("rmdir /s /q " .. unix_to_win (dir) ) + os.execute("rmdir /s /q " .. unix_to_win(dir) ) else - os.execute ("rm -r " .. dir) + os.execute("rm -r " .. dir) end end -- Run a command in a given directory -function run (dir, cmd) - local errorlevel = os.execute ("cd " .. dir .. os_concat .. cmd) +function run(dir, cmd) + local errorlevel = os.execute("cd " .. dir .. os_concat .. cmd) return errorlevel end -- Deal with the fact that Windows and Unix use different path separators -function unix_to_win (path) - local path = string.gsub (path, "/", "\\") +function unix_to_win(path) + local path = string.gsub(path, "/", "\\") return path end @@ -415,14 +414,14 @@ end -- -- Do some subtarget for all modules in a bundle -function allmodules (target) +function allmodules(target) local errorlevel = 0 - for _,i in ipairs (modules) do - print ( + for _,i in ipairs(modules) do + print( "Running script " .. scriptname .. " with target \"" .. target .. "\" for module " .. i ) - errorlevel = run (i, "texlua " .. scriptname .. " " .. target) + errorlevel = run(i, "texlua " .. scriptname .. " " .. target) if errorlevel > 0 then return errorlevel end @@ -432,36 +431,36 @@ end -- Set up the check system files: needed for checking one or more tests and -- for saving the test files -function checkinit () - cleandir (testdir) - depinstall (checkdeps) +function checkinit() + cleandir(testdir) + depinstall(checkdeps) -- Copy dependencies to the test directory itself: this makes the paths -- a lot easier to manage, and is important for dealing with the log and -- with file input/output tests - for _,i in ipairs (filelist (localdir)) do - cp (i, localdir, testdir) + for _,i in ipairs(filelist(localdir)) do + cp(i, localdir, testdir) end - bundleunpack () - for _,i in ipairs (installfiles) do - cp (i, unpackdir, testdir) + bundleunpack() + for _,i in ipairs(installfiles) do + cp(i, unpackdir, testdir) end - for _,i in ipairs (checkfiles) do - cp (i, unpackdir, testdir) + for _,i in ipairs(checkfiles) do + cp(i, unpackdir, testdir) end - if direxists (testsuppdir) then - for _,i in ipairs (filelist (testsuppdir)) do - cp (i, testsuppdir, testdir) + if direxists(testsuppdir) then + for _,i in ipairs(filelist(testsuppdir)) do + cp(i, testsuppdir, testdir) end end - for _,i in ipairs (checksuppfiles) do - cp (i, supportdir, testdir) + for _,i in ipairs(checksuppfiles) do + cp(i, supportdir, testdir) end end -- Copy files to the main CTAN release directory -function copyctan () +function copyctan() -- Do all of the copying in one go - for _,i in ipairs ( + for _,i in ipairs( { bibfiles, demofiles, @@ -472,15 +471,15 @@ function copyctan () typesetlist } ) do - for _,j in ipairs (i) do - cp (j, ".", ctandir .. "/" .. ctanpkg) + for _,j in ipairs(i) do + cp(j, ".", ctandir .. "/" .. ctanpkg) end end end -- Copy files to the correct places in the TDS tree -function copytds () - local function install (source, dest, files, tool) +function copytds() + local function install(source, dest, files, tool) local moduledir = moduledir -- For material associated with secondary tools (BibTeX, MakeIndex) -- the structure needed is slightly different from those items going @@ -498,111 +497,113 @@ function copytds () 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) + for _,i in ipairs(files) do + for _,j in ipairs(i) do + for _,k in ipairs(filelist(source, j)) do + table.insert(filenames, k) end end end -- The target is only created if there are actual files to install - if next (filenames) ~= nil then - mkdir (installdir) - for _,i in ipairs (filenames) do - cp (i, source, installdir) + if next(filenames) ~= nil then + mkdir(installdir) + for _,i in ipairs(filenames) do + cp(i, source, installdir) end end end - install ( + install( ".", "doc", {bibfiles, demofiles, docfiles, pdffiles, textfiles, typesetlist} ) - install (unpackdir, "makeindex", {makeindexfiles}, true) - install (unpackdir, "bibtex/bst", {bstfiles}, true) - install (".", "source", {sourcelist}) - install (unpackdir, "tex", {installfiles}) + install(unpackdir, "makeindex", {makeindexfiles}, true) + install(unpackdir, "bibtex/bst", {bstfiles}, true) + install(".", "source", {sourcelist}) + install(unpackdir, "tex", {installfiles}) end -- Unpack files needed to support testing/typesetting/unpacking -function depinstall (deps) - for _,i in ipairs (deps) do - print ("Installing dependency: " .. i) - run (i, "texlua " .. scriptname .. " unpack") +function depinstall(deps) + for _,i in ipairs(deps) do + print("Installing dependency: " .. i) + run(i, "texlua " .. scriptname .. " unpack") end 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) - local function killcheck (line) +function formatlog(logfile, newfile) + local function killcheck(line) -- Skip lines containing file dates - if string.match (line, "[^<]%d%d%d%d/%d%d/%d%d") then + if string.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? = " + string.match( + string.gsub(line, "^\\openin", "\\openout"), "^\\openout%d%d? = " ) then return true end return false end -- Substitutions to remove some non-useful changes - local function normalize (line) + local function normalize(line) local line = line -- 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 = string.gsub ( + line = string.gsub( line, - string.gsub ( - string.match ("/" .. logfile, ".*/(.*)%" .. logext .. "$"), + string.gsub( + string.match("/" .. logfile, ".*/(.*)%" .. logext .. "$"), "-", "%%-" ), "" ) -- Zap ./ at begin of filename - line = string.gsub (line, "%(%.%/", "(") + line = string.gsub(line, "%(%.%/", "(") -- Zap paths if places other than 'here' are accessible if checksearch then - line = string.gsub (line, "%(.*/([%w-]+%.[%w-]+)%s*$", "(../%1") + line = string.gsub(line, "%(.*/([%w-]+%.[%w-]+)%s*$", "(../%1") end - -- Zap map loading on first page output - line = string.gsub (line, "%[1{[%w/%-]*/pdftex%.map}%]", "[1]") + -- Zap map loading of map + line = string.gsub(line, "%{[%w/%-]*/pdftex%.map%}", "") -- TeX90/XeTeX knows only the smaller set of dimension units - line = string.gsub ( + line = string.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 = string.gsub(line, "\\csname\\endcsname ", "\\csname\\endcsname") -- Zap "on line " and replace with "on line ..." - line = string.gsub (line, "on line %d*", "on line ...") + line = string.gsub(line, "on line %d*", "on line ...") -- Zap line numbers from \show, \showbox, \box_show and the like - line = string.gsub (line, "^l%.%d+ ", "l. ...") + line = string.gsub(line, "^l%.%d+ ", "l. ...") -- Tidy up to ^^ notation for i = 1, 31, 1 do - line = string.gsub (line, string.char (i), "^^" .. string.char (64 + i)) + line = string.gsub(line, string.char(i), "^^" .. string.char(64 + i)) end -- Remove spaces at the start of lines: deals with the fact that LuaTeX -- uses a different number to the other engines - line = string.gsub (line, "^%s+", "") + line = string.gsub(line, "^%s+", "") + -- Remove 'normal' direction information on boxes with (u)p-TeX + line = string.gsub(line, ", yoko direction", "") -- Unicode engines display chars in the upper half of the 8-bit range: -- tidy up to match pdfTeX local utf8 = unicode.utf8 for i = 128, 255, 1 do - line = string.gsub (line, utf8.char (i), "^^" .. string.format ("%02x", i)) + line = string.gsub(line, utf8.char(i), "^^" .. string.format("%02x", i)) end return line end local newlog = "" local prestart = true local skipping = false - for line in io.lines (logfile) do + for line in io.lines(logfile) do if line == "START-TEST-LOG" then prestart = false elseif line == "END-TEST-LOG" then @@ -611,58 +612,58 @@ function formatlog (logfile, newfile) skipping = true elseif line == "TIMO" then skipping = false - elseif not prestart and not skipping and not killcheck (line) then - line = normalize (line) - if not string.match (line, "^ *$") then + elseif not prestart and not skipping and not killcheck(line) then + line = normalize(line) + if not string.match(line, "^ *$") then newlog = newlog .. line .. "\n" end end end - local newfile = io.open (newfile, "w") - io.output (newfile) - io.write (newlog) - io.close (newfile) + local newfile = io.open(newfile, "w") + io.output(newfile) + io.write(newlog) + io.close(newfile) end -- Additional normalization for LuaTeX -function formatlualog (logfile, newfile) - local function normalize (line, lastline, dropping) +function formatlualog(logfile, newfile) + local function normalize(line, lastline, dropping) local line = line -- Find discretionary lines skip: may get re-added - if string.match (line, "^%.+\\discretionary$") then + if string.match(line, "^%.+\\discretionary$") then return "", line, false end -- Find whatsit lines skip: may get re-added - if string.match (line, "^%.+\\whatsit$") then + if string.match(line, "^%.+\\whatsit$") then return "", line, false end -- 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 = string.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 = string.gsub(line, ", direction TLT", "") -- Find glue setting and round out the last place - line = string.gsub ( + line = string.gsub( line, "glue set (%-? ?)%d+.%d+fil$", - "glue set %1" .. string.format ( - "%.4f", string.match (line, "glue set %-? ?(%d+.%d+)fil$") or 0 + "glue set %1" .. string.format( + "%.4f", string.match(line, "glue set %-? ?(%d+.%d+)fil$") or 0 ) .. "fil" ) -- Remove U+ notation in the "Missing character" message - line = string.gsub ( + line = string.gsub( line, "Missing character: There is no (%^%^..) %(U%+(....)%)", "Missing character: There is no %1" ) -- Where the last line was a discretionary, looks for the -- info one level in about what it represents - if string.match (lastline, "^%.+\\discretionary$") then - prefix = string.gsub (string.match (lastline, "^(%.+)"), "%.", "%%.") - if string.match (line, prefix .. "%.") or - string.match (line, prefix .. "%|") then + if string.match(lastline, "^%.+\\discretionary$") then + prefix = string.gsub(string.match(lastline, "^(%.+)"), "%.", "%%.") + if string.match(line, prefix .. "%.") or + string.match(line, prefix .. "%|") then return "", lastline, true else if dropping then @@ -677,9 +678,9 @@ function formatlualog (logfile, newfile) end -- Much the same idea when the last line was a whatsit, -- but things are simpler in this case - if string.match (lastline, "^%.+\\whatsit$") then - prefix = string.gsub (string.match (lastline, "^(%.+)"), "%.", "%%.") - if string.match (line, prefix .. "%.") then + if string.match(lastline, "^%.+\\whatsit$") then + prefix = string.gsub(string.match(lastline, "^(%.+)"), "%.", "%%.") + if string.match(line, prefix .. "%.") then return "", lastline, true else -- End of a \whatsit block @@ -691,24 +692,24 @@ function formatlualog (logfile, newfile) local newlog = "" local lastline = "" local dropping = false - for line in io.lines (logfile) do - line, lastline, dropping = normalize (line, lastline, dropping) - if not string.match (line, "^ *$") then + for line in io.lines(logfile) do + line, lastline, dropping = normalize(line, lastline, dropping) + if not string.match(line, "^ *$") then newlog = newlog .. line .. "\n" end end - local newfile = io.open (newfile, "w") - io.output (newfile) - io.write (newlog) - io.close (newfile) + local newfile = io.open(newfile, "w") + io.output(newfile) + io.write(newlog) + io.close(newfile) end -- Look for files, directory by directory, and return the first existing -function locate (dirs, names) - for _,i in ipairs (dirs) do - for _,j in ipairs (names) do +function locate(dirs, names) + for _,i in ipairs(dirs) do + for _,j in ipairs(names) do local path = i .. "/" .. j - if fileexists (path) then + if fileexists(path) then return path end end @@ -716,16 +717,16 @@ function locate (dirs, names) end -- List all modules -function listmodules () +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) - assert (type (attr) == "table") + local attr = lfs.attributes(entry) + assert(type(attr) == "table") if attr.mode == "directory" then if not exclmodules[entry] then - table.insert (modules, entry) + table.insert(modules, entry) end end end @@ -735,29 +736,29 @@ end -- Runs a single test: needs the name of the test rather than the .lvt file -- One 'test' here may apply to multiple engines -function runcheck (name, engine, hide) +function runcheck(name, engine, hide) local checkengines = checkengines if engine then checkengines = {engine} end local errorlevel = 0 - for _,i in ipairs (checkengines) do - cp (name .. tlgext, testfiledir, testdir) - runtest (name, i, hide) + for _,i in ipairs(checkengines) do + cp(name .. tlgext, testfiledir, testdir) + runtest(name, i, hide) local testname = name .. "." .. i local difffile = testdir .. "/" .. testname .. os_diffext local newfile = testdir .. "/" .. testname .. logext -- Use engine-specific file if available - local tlgfile = locate ( + local tlgfile = locate( {testfiledir, unpackdir}, {name .. "." .. i .. tlgext, name .. tlgext} ) if not tlgfile then - print ("Error: failed to find " .. tlgext .. " file for " .. name .. "!") - os.exit (1) + print("Error: failed to find " .. tlgext .. " file for " .. name .. "!") + os.exit(1) end if os_windows then - tlgfile = unix_to_win (tlgfile) + tlgfile = unix_to_win(tlgfile) end local errlevel -- Do additional log formatting if the engine is LuaTeX, there is no @@ -767,21 +768,21 @@ function runcheck (name, engine, hide) and stdengine ~= "luatex" then local luatlgfile = testdir .. "/" .. name .. ".luatex" .. tlgext if os_windows then - luatlgfile = unix_to_win (luatlgfile) + luatlgfile = unix_to_win(luatlgfile) end - formatlualog (tlgfile, luatlgfile) - formatlualog (newfile, newfile) - errlevel = os.execute ( + formatlualog(tlgfile, luatlgfile) + formatlualog(newfile, newfile) + errlevel = os.execute( os_diffexe .. " " .. luatlgfile .. " " .. newfile .. " > " .. difffile ) else - errlevel = os.execute ( + errlevel = os.execute( os_diffexe .. " " .. tlgfile .. " " .. newfile .. " > " .. difffile ) end if errlevel == 0 then - os.remove (difffile) + os.remove(difffile) else errorlevel = errlevel end @@ -791,40 +792,49 @@ end -- Run one of the test files: doesn't check the result so suitable for -- both creating and verifying .tlg files -function runtest (name, engine, hide) +function runtest(name, engine, hide) local lvtfile = name .. lvtext - cp (lvtfile, fileexists (testfiledir .. "/" .. lvtfile) + cp(lvtfile, fileexists(testfiledir .. "/" .. lvtfile) and testfiledir or unpackdir, testdir) local engine = engine or stdengine -- Set up the format file name if it's one ending "...tex" + local realengine = engine local format - if string.match (checkformat, "tex$") then - format = " -fmt=" .. string.gsub (engine, "(.*)tex$", "%1") .. checkformat + if + string.match(checkformat, "tex$") and + not string.match(engine, checkformat) then + format = " -fmt=" .. string.gsub(engine, "(.*)tex$", "%1") .. checkformat else format = "" end + -- Special casing for (u)p-TeX LaTeX formats + if + string.match(checkformat, "^latex$") and + string.match(engine, "^u?ptex$") then + realengine = "e" .. engine + end local logfile = testdir .. "/" .. name .. logext local newfile = testdir .. "/" .. name .. "." .. engine .. logext for i = 1, checkruns do - run ( + run( testdir, -- No use of localdir here as the files get copied to testdir: -- avoids any paths in the logs os_setenv .. " TEXINPUTS=." .. (checksearch and os_pathsep or "") .. os_concat .. - engine .. format .. " " .. checkopts .. " " .. lvtfile + realengine .. format .. " " .. checkopts .. " " .. lvtfile .. (hide and (" > " .. os_null) or "") ) end - formatlog (logfile, newfile) + formatlog(logfile, newfile) -- Store secondary files for this engine - for _,i in ipairs (filelist (testdir, name .. ".???")) do - local ext = string.match (i, "%....") + for _,i in ipairs(filelist(testdir, name .. ".???")) do + local ext = string.match(i, "%....") if ext ~= lvtext and ext ~= tlgext and ext ~= logext then - if not fileexists (testsuppdir .. "/" .. i) then - ren ( - testdir, i, string.gsub ( - i, string.gsub (name, "%-", "%%-"), name .. "." .. engine + if not fileexists(testsuppdir .. "/" .. i) then + ren( + testdir, i, string.gsub( + i, string.gsub(name, "%-", "%%-"), name .. "." .. engine ) ) end @@ -833,14 +843,14 @@ function runtest (name, engine, hide) end -- Strip the extension from a file name (if present) -function stripext (file) - local name = string.match (file, "^(.*)%.") +function stripext(file) + local name = string.match(file, "^(.*)%.") return name or file end -- Look for a test: could be in the testfiledir or the unpackdir -function testexists (test) - return (locate ({testfiledir, unpackdir}, {test .. lvtext})) +function testexists(test) + return(locate({testfiledir, unpackdir}, {test .. lvtext})) end -- @@ -848,12 +858,12 @@ end -- -- An auxiliary used to set up the environmental variables -function runtool (envvar, command) - return ( - run ( +function runtool(envvar, command) + return( + run( typesetdir, os_setenv .. " " .. envvar .. "=." .. os_pathsep - .. relpath (localdir, typesetdir) + .. relpath(localdir, typesetdir) .. (typesetsearch and os_pathsep or "") .. os_concat .. command @@ -861,17 +871,17 @@ function runtool (envvar, command) ) end -function biber (name) - if fileexists (typesetdir .. "/" .. name .. ".bcf") then - return ( - runtool ("BIBINPUTS", biberexe .. " " .. biberopts .. " " .. name) +function biber(name) + if fileexists(typesetdir .. "/" .. name .. ".bcf") then + return( + runtool("BIBINPUTS", biberexe .. " " .. biberopts .. " " .. name) ) end return 0 end -function bibtex (name) - if fileexists (typesetdir .. "/" .. name .. ".aux") then +function bibtex(name) + 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 local grep @@ -880,21 +890,21 @@ function bibtex (name) else grep = "\\\\\\\\" end - if run ( + if run( typesetdir, os_grepexe .. " \"^" .. grep .. "citation{\" " .. name .. ".aux > " .. os_null - ) + run ( + ) + run( typesetdir, os_grepexe .. " \"^" .. grep .. "bibdata{\" " .. name .. ".aux > " .. os_null ) == 0 then - return ( + return( -- Cheat slightly as we need to set two variables - runtool ( + runtool( "BIBINPUTS", os_setenv .. " BSTINPUTS=." .. os_pathsep - .. relpath (localdir, typesetdir) + .. relpath(localdir, typesetdir) .. (typesetsearch and os_pathsep or "") .. os_concat .. bibtexexe .. " " .. bibtexopts .. " " .. name @@ -905,10 +915,10 @@ function bibtex (name) return 0 end -function makeindex (name, inext, outext, logext, style) - if fileexists (typesetdir .. "/" .. name .. inext) then - return ( - runtool ( +function makeindex(name, inext, outext, logext, style) + if fileexists(typesetdir .. "/" .. name .. inext) then + return( + runtool( "INDEXSTYLE", makeindexexe .. " " .. makeindexopts .. " " .. " -s " .. style .. " -o " .. name .. outext @@ -919,9 +929,9 @@ function makeindex (name, inext, outext, logext, style) return 0 end -function tex (file) - return ( - runtool ( +function tex(file) + return( + runtool( "TEXINPUTS", typesetexe .. " " .. typesetopts .. " \"" .. typesetcmds .. "\\input " .. file .. "\"" @@ -929,34 +939,34 @@ function tex (file) ) end -function typesetpdf (file) - local name = stripext (file) - print ("Typesetting " .. name) - local errorlevel = typeset (file) +function typesetpdf(file) + local name = stripext(file) + print("Typesetting " .. name) + local errorlevel = typeset(file) if errorlevel == 0 then - os.remove (name .. ".pdf") - cp (name .. ".pdf", typesetdir, ".") + os.remove(name .. ".pdf") + cp(name .. ".pdf", typesetdir, ".") else - print (" ! Compilation failed") + print(" ! Compilation failed") end return errorlevel end -typeset = typeset or function (file) - local errorlevel = tex (file) +typeset = typeset or function(file) + local errorlevel = tex(file) if errorlevel ~= 0 then return errorlevel else - local name = stripext (file) + local name = stripext(file) -- Return a non-zero errorlevel if something goes wrong -- without having loads of nested tests - return ( - biber (name) + - bibtex (name) + - makeindex (name, ".glo", ".gls", ".glg", glossarystyle) + - makeindex (name, ".idx", ".ind", ".ilg", indexstyle) + - tex (file) + - tex (file) + return( + biber(name) + + bibtex(name) + + makeindex(name, ".glo", ".gls", ".glg", glossarystyle) + + makeindex(name, ".idx", ".ind", ".ilg", indexstyle) + + tex(file) + + tex(file) ) end end @@ -964,7 +974,7 @@ end -- Standard versions of the main targets for building modules -- Simply print out how to use the build system -help = help or function () +help = help or function() print "" if testfiledir ~= "" then print " build check - run all automated tests for all engines" @@ -974,7 +984,7 @@ help = help or function () print " build check - check one test file for " end print " build clean - clean out directory tree " - if next (cmdchkfiles) ~= nil then + if next(cmdchkfiles) ~= nil then print " build cmdcheck - check commands documented are defined " end if module == "" or bundle == "" then @@ -989,116 +999,116 @@ help = help or function () print "" end -function check (name, engine) +function check(name, engine) local errorlevel = 0 if name then - errorlevel = checklvt (name, engine) + errorlevel = checklvt(name, engine) else - errorlevel = checkall () + errorlevel = checkall() end return errorlevel end -function checkall () +function checkall() local errorlevel = 0 - if testfiledir ~= "" and direxists (testfiledir) then - local function execute (name) - local name = stripext (name) - print (" " .. name) - local errlevel = runcheck (name, nil, true) + if testfiledir ~= "" and direxists(testfiledir) then + local function execute(name) + local name = stripext(name) + print(" " .. name) + local errlevel = runcheck(name, nil, true) if errlevel ~= 0 then errorlevel = 1 end end - checkinit () - print ("Running checks on") - for _,i in ipairs (filelist (testfiledir, "*" .. lvtext)) do - execute (i) + checkinit() + print("Running checks on") + for _,i in ipairs(filelist(testfiledir, "*" .. lvtext)) do + execute(i) end - for _,i in ipairs (filelist (unpackdir, "*" .. lvtext)) do - if fileexists (testfiledir .. "/" .. i) then - print ("Duplicate test file: " .. i) + for _,i in ipairs(filelist(unpackdir, "*" .. lvtext)) do + if fileexists(testfiledir .. "/" .. i) then + print("Duplicate test file: " .. i) errorlevel = 1 break else - execute (i) + execute(i) end end if errorlevel ~= 0 then - checkdiff () + checkdiff() else - print ("\n All checks passed\n") + print("\n All checks passed\n") end end return errorlevel end -function checklvt (name, engine) - checkinit () - if testexists (name) then - print ("Running checks on " .. name) - local errorlevel = runcheck (name, engine) +function checklvt(name, engine) + checkinit() + if testexists(name) then + print("Running checks on " .. name) + local errorlevel = runcheck(name, engine) if errorlevel ~= 0 then - checkdiff () + checkdiff() else if engine then - print (" Check passes") + print(" Check passes") else - print ("\n All checks passed\n") + print("\n All checks passed\n") end end else - print ("Test \"" .. name .. "\" not set up!") + print("Test \"" .. name .. "\" not set up!") end end -- A short auxiliary to print the list of differences for check -function checkdiff () - print ("\n Check failed with difference files") - for _,i in ipairs (filelist (testdir, "*" .. os_diffext)) do - print (" - " .. testdir .. "/" .. i) +function checkdiff() + print("\n Check failed with difference files") + for _,i in ipairs(filelist(testdir, "*" .. os_diffext)) do + print(" - " .. testdir .. "/" .. i) end - print ("") + print("") end -- Remove all generated files -function clean () +function clean() -- To make sure that distribdir never contains any stray subdirs, -- it is entirely removed then recreated rather than simply deleting -- all of the files - rmdir (distribdir) - mkdir (distribdir) - cleandir (localdir) - cleandir (testdir) - cleandir (typesetdir) - cleandir (unpackdir) - for _,i in ipairs (cleanfiles) do - rm (".", i) + rmdir(distribdir) + mkdir(distribdir) + cleandir(localdir) + cleandir(testdir) + cleandir(typesetdir) + cleandir(unpackdir) + for _,i in ipairs(cleanfiles) do + rm(".", i) end end -function bundleclean () - allmodules ("clean") - for _,i in ipairs (cleanfiles) do - rm (".", i) +function bundleclean() + allmodules("clean") + for _,i in ipairs(cleanfiles) do + rm(".", i) end - rmdir (ctandir) - rmdir (tdsdir) + rmdir(ctandir) + rmdir(tdsdir) end -- Check commands are defined -function cmdcheck () - mkdir (localdir) - cleandir (testdir) - depinstall (checkdeps) - local engine = string.gsub (stdengine, "tex$", "latex") - local localdir = relpath (localdir, testdir) - print ("Checking source files") - for _,i in ipairs (cmdchkfiles) do - for _,j in ipairs (filelist (".", i)) do - print (" " .. stripext (j)) - cp (j, ".", testdir) - run ( +function cmdcheck() + mkdir(localdir) + cleandir(testdir) + depinstall(checkdeps) + local engine = string.gsub(stdengine, "tex$", "latex") + local localdir = relpath(localdir, testdir) + print("Checking source files") + for _,i in ipairs(cmdchkfiles) do + for _,j in ipairs(filelist(".", i)) do + print(" " .. stripext(j)) + cp(j, ".", testdir) + run( testdir, os_setenv .. " TEXINPUTS=." .. os_pathsep .. localdir .. os_pathsep .. @@ -1107,36 +1117,36 @@ 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 io.lines(testdir .. "/" .. stripext(j) .. ".cmds") do + if string.match(line, "^%!") then + print(" - " .. string.match(line, "^%! (.*)")) end end end end end -function ctan (standalone) - local function dirzip (dir, name) +function ctan(standalone) + local function dirzip(dir, name) local zipname = name .. ".zip" - local function tab_to_str (table) + local function tab_to_str(table) local string = "" - for _,i in ipairs (table) do + for _,i in ipairs(table) do string = string .. " " .. "\"" .. i .. "\"" end return string end -- Convert the tables of files to quoted strings - local binfiles = tab_to_str (binaryfiles) - local exclude = tab_to_str (excludefiles) + local binfiles = tab_to_str(binaryfiles) + local exclude = tab_to_str(excludefiles) -- First, zip up all of the text files - run ( + run( dir, zipexe .. " " .. zipopts .. " -ll ".. zipname .. " " .. "." .. " -x" .. binfiles .. " " .. exclude ) -- Then add the binary ones - run ( + run( dir, zipexe .. " " .. zipopts .. " -g ".. zipname .. " " .. ". -i" .. binfiles .. " -x" .. exclude @@ -1144,111 +1154,105 @@ function ctan (standalone) end local errorlevel if standalone then - errorlevel = check () + errorlevel = check() bundle = module else - errorlevel = allmodules ("bundlecheck") + errorlevel = allmodules("bundlecheck") end if errorlevel == 0 then - rmdir (ctandir) - mkdir (ctandir .. "/" .. ctanpkg) - rmdir (tdsdir) - mkdir (tdsdir) + rmdir(ctandir) + mkdir(ctandir .. "/" .. ctanpkg) + rmdir(tdsdir) + mkdir(tdsdir) if standalone then - errorlevel = bundlectan () + errorlevel = bundlectan() else - errorlevel = allmodules ("bundlectan") + errorlevel = allmodules("bundlectan") end else - print ("\n====================") - print ("Tests failed, zip stage skipped!") - print ("====================\n") + print("\n====================") + print("Tests failed, zip stage skipped!") + print("====================\n") return errorlevel end if errorlevel == 0 then - for _,i in ipairs (readmefiles) do - for _,j in ipairs (filelist (".", i)) do - local function installtxt (name, dir) - cp (name, ".", dir) - ren (dir, name, stripext (name)) - end - installtxt (j, ctandir .. "/" .. ctanpkg) - installtxt (j, tdsdir .. "/doc/" .. tdsroot .. "/" .. bundle) - end + for _,i in ipairs(textfiles) do + cp(i, ".", ctandir .. "/" .. ctanpkg) + cp(i, ".", tdsdir .. "/doc/" .. tdsroot .. "/" .. bundle) end - dirzip (tdsdir, ctanpkg .. ".tds") + dirzip(tdsdir, ctanpkg .. ".tds") if packtdszip then - cp (ctanpkg .. ".tds.zip", tdsdir, ctandir) + cp(ctanpkg .. ".tds.zip", tdsdir, ctandir) end - dirzip (ctandir, ctanpkg) - cp (ctanpkg .. ".zip", ctandir, ".") + dirzip(ctandir, ctanpkg) + cp(ctanpkg .. ".zip", ctandir, ".") else - print ("\n====================") - print ("Typesetting failed, zip stage skipped!") - print ("====================\n") + print("\n====================") + print("Typesetting failed, zip stage skipped!") + print("====================\n") end return errorlevel end -function bundlectan () +function bundlectan() -- Generate a list of individual file names excluding those in the second -- argument: the latter is a table - local function excludelist (include, exclude) + local function excludelist(include, exclude) local includelist = { } local excludelist = { } - for _,i in ipairs (exclude) do - for _,j in ipairs (i) do - for _,k in ipairs (filelist (".", j)) do + for _,i in ipairs(exclude) do + for _,j in ipairs(i) do + for _,k in ipairs(filelist(".", j)) do excludelist[k] = true end end end - for _,i in ipairs (include) do - for _,j in ipairs (filelist (".", i)) do + for _,i in ipairs(include) do + for _,j in ipairs(filelist(".", i)) do if not excludelist[j] then - table.insert (includelist, j) + table.insert(includelist, j) end end end return includelist end unpack() - local errorlevel = doc () + local errorlevel = doc() if errorlevel == 0 then -- Work out what PDF files are available pdffiles = { } - for _,i in ipairs (typesetfiles) do - table.insert (pdffiles, (string.gsub (i, "%.%w+$", ".pdf"))) + for _,i in ipairs(typesetfiles) do + table.insert(pdffiles, (string.gsub(i, "%.%w+$", ".pdf"))) end - typesetlist = excludelist (typesetfiles, {sourcefiles}) - sourcelist = excludelist ( + typesetlist = excludelist(typesetfiles, {sourcefiles}) + sourcelist = excludelist( sourcefiles, {bstfiles, installfiles, makeindexfiles} ) - copyctan () - copytds () + copyctan() + copytds() end return errorlevel end -- Typeset all required documents -- Uses a set of dedicated auxiliaries that need to be available to others -function doc () +function doc() -- Set up - cleandir (typesetdir) - for _,i in ipairs ({bibfiles, docfiles, sourcefiles, typesetfiles}) do - for _,j in ipairs (i) do - cp (j, ".", typesetdir) + cleandir(typesetdir) + for _,i in ipairs({bibfiles, docfiles, sourcefiles, typesetfiles}) do + for _,j in ipairs(i) do + cp(j, ".", typesetdir) end end - for _,i in ipairs (typesetsuppfiles) do - cp (i, supportdir, typesetdir) + for _,i in ipairs(typesetsuppfiles) do + cp(i, supportdir, typesetdir) end - depinstall (typesetdeps) - unpack () + depinstall(typesetdeps) + unpack() -- Main loop for doc creation - for _,i in ipairs (typesetfiles) do - for _,j in ipairs (filelist (".", i)) do - local errorlevel = typesetpdf (j) + for _,i in ipairs(typesetfiles) do + for _,j in ipairs(filelist(".", i)) do + local errorlevel = typesetpdf(j) if errorlevel ~= 0 then return errorlevel end @@ -1258,34 +1262,34 @@ function doc () end -- Locally install files: only deals with those extracted, not docs etc. -function install () - unpack () - kpse.set_program_name ("latex") - local texmfhome = kpse.var_value ("TEXMFHOME") +function install() + unpack() + kpse.set_program_name("latex") + local texmfhome = kpse.var_value("TEXMFHOME") local installdir = texmfhome .. "/tex/" .. moduledir - cleandir (installdir) - for _,i in ipairs (installfiles) do - cp (i, unpackdir, installdir) + cleandir(installdir) + for _,i in ipairs(installfiles) do + cp(i, unpackdir, installdir) end end -function save (name, engine) +function save(name, engine) local tlgfile = name .. (engine and ("." .. engine) or "") .. tlgext local newfile = name .. "." .. (engine or stdengine) .. logext - checkinit () - if testexists (name) then - print ("Creating and copying " .. tlgfile) - runtest (name, engine, false) - ren (testdir, newfile, tlgfile) - cp (tlgfile, testdir, testfiledir) - if fileexists (unpackdir .. "/" .. tlgfile) then - print ( + checkinit() + if testexists(name) then + print("Creating and copying " .. tlgfile) + runtest(name, engine, false) + ren(testdir, newfile, tlgfile) + cp(tlgfile, testdir, testfiledir) + if fileexists(unpackdir .. "/" .. tlgfile) then + print( "Saved " .. tlgext .. " file overrides unpacked version of the same name" ) end else - print ( + print( "Test input \"" .. testfiledir .. "/" .. name .. lvtext .. "\" not found" ) @@ -1294,35 +1298,35 @@ 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 () - depinstall (unpackdeps) - bundleunpack () - for _,i in ipairs (installfiles) do - cp (i, unpackdir, localdir) +function unpack() + depinstall(unpackdeps) + bundleunpack() + for _,i in ipairs(installfiles) do + cp(i, unpackdir, localdir) end 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 () - mkdir (localdir) - cleandir (unpackdir) - for _,i in ipairs (sourcefiles) do - cp (i, ".", unpackdir) +bundleunpack = bundleunpack or function() + mkdir(localdir) + cleandir(unpackdir) + for _,i in ipairs(sourcefiles) do + cp(i, ".", unpackdir) end - for _,i in ipairs (unpacksuppfiles) do - cp (i, supportdir, localdir) + for _,i in ipairs(unpacksuppfiles) do + cp(i, supportdir, localdir) end - for _,i in ipairs (unpackfiles) do - for _,j in ipairs (filelist (unpackdir, i)) do + for _,i in ipairs(unpackfiles) do + for _,j in ipairs(filelist(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 os.execute (it never -- stops, which confuses Lua) - os.execute (os_yes .. ">>" .. localdir .. "/yes") - local localdir = relpath (localdir, unpackdir) - run ( + os.execute(os_yes .. ">>" .. localdir .. "/yes") + local localdir = relpath(localdir, unpackdir) + run( unpackdir, os_setenv .. " TEXINPUTS=." .. os_pathsep .. localdir .. (unpacksearch and os_pathsep or "") .. @@ -1334,9 +1338,9 @@ bundleunpack = bundleunpack or function () end end -function version () - print ( - "\nl3build Release " .. string.gsub (release_date, "/", "-") .. +function version() + print( + "\nl3build Release " .. string.gsub(release_date, "/", "-") .. " (SVN r" .. release_ver .. ")\n" ) end @@ -1345,74 +1349,74 @@ end -- The overall main function -- -function stdmain (target, file, engine) +function stdmain(target, file, engine) local errorlevel -- If the module name is empty, the script is running in a bundle: -- apart from ctan all of the targets are then just mappings if module == "" then -- Detect all of the modules - modules = modules or listmodules () + modules = modules or listmodules() if target == "doc" then - errorlevel = allmodules ("doc") + errorlevel = allmodules("doc") elseif target == "check" then - errorlevel = allmodules ("bundlecheck") + errorlevel = allmodules("bundlecheck") if errorlevel ~=0 then - print ("There were errors: checks halted!\n") + print("There were errors: checks halted!\n") end elseif target == "clean" then - errorlevel = bundleclean () - elseif target == "cmdcheck" and next (cmdchkfiles) ~= nil then - errorlevel = allmodules ("cmdcheck") + errorlevel = bundleclean() + elseif target == "cmdcheck" and next(cmdchkfiles) ~= nil then + errorlevel = allmodules("cmdcheck") elseif target == "ctan" then - errorlevel = ctan () + errorlevel = ctan() elseif target == "install" then - errorlevel = allmodules ("install") + errorlevel = allmodules("install") elseif target == "unpack" then - errorlevel = allmodules ("bundleunpack") + errorlevel = allmodules("bundleunpack") elseif target == "version" then - version () + version() else - help () + help() end else if target == "bundleunpack" then -- 'Hidden' as only needed 'higher up' - depinstall (unpackdeps) - errorlevel = bundleunpack () + depinstall(unpackdeps) + errorlevel = bundleunpack() elseif target == "bundlecheck" then - errorlevel = check () + errorlevel = check() elseif target == "bundlectan" then - errorlevel = bundlectan () + errorlevel = bundlectan() elseif target == "doc" then - errorlevel = doc () + errorlevel = doc() elseif target == "check" and testfiledir ~= "" then - errorlevel = check (file, engine) + errorlevel = check(file, engine) elseif target == "clean" then - errorlevel = clean () - elseif target == "cmdcheck" and next (cmdchkfiles) ~= nil then - errorlevel = cmdcheck () + errorlevel = clean() + elseif target == "cmdcheck" and next(cmdchkfiles) ~= nil then + errorlevel = cmdcheck() elseif target == "ctan" and bundle == "" then -- Stand-alone module - errorlevel = ctan (true) + errorlevel = ctan(true) elseif target == "install" then - errorlevel = install () + errorlevel = install() elseif target == "save" and testfiledir ~= "" then if file then - errorlevel = save (file, engine) + errorlevel = save(file, engine) else - help () + help() end elseif target == "unpack" then - unpack () + unpack() elseif target == "version" then - version () + version() else - help () + help() end end - os.exit (errorlevel) + os.exit(errorlevel) end -- Allow main function to be disabled 'higher up' main = main or stdmain -- Call the main function -main (arg[1], arg[2], arg[3]) +main(arg[1], arg[2], arg[3]) -- cgit v1.2.3