summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2022-08-05 21:34:16 +0000
committerKarl Berry <karl@freefriends.org>2022-08-05 21:34:16 +0000
commitff9132493e098d65f121944f67b3f52769155e2e (patch)
treecee7a4213ac13e84f4815b9e0d9646c4b1c6df8c
parent168e2e89b88f33f5f4940a07636b697f9a69dac6 (diff)
texlogsieve (5aug22)
git-svn-id: svn://tug.org/texlive/trunk@64060 c570f23f-e606-0410-a88d-b1316a301751
-rwxr-xr-xBuild/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve340
-rw-r--r--Master/texmf-dist/doc/man/man1/texlogsieve.143
-rw-r--r--Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdfbin40199 -> 41838 bytes
-rw-r--r--Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdfbin59279 -> 60077 bytes
-rw-r--r--Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex64
-rwxr-xr-xMaster/texmf-dist/scripts/texlogsieve/texlogsieve340
6 files changed, 567 insertions, 220 deletions
diff --git a/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve b/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve
index 3520efd7448..331651fd55f 100755
--- a/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve
+++ b/Build/source/texk/texlive/linked_scripts/texlogsieve/texlogsieve
@@ -176,7 +176,13 @@ in the LaTeX log file:
is indented to start after the end of the first, as in the example
above. If the content of a line does not fit, a part of it (the
beginning for the first line and the end for the second line) may
- be replaced by "...".
+ be replaced by "...". error_line must be < 255 and half_error_line
+ must be < error_line -15. If error_line >= max_print_line or
+ half_error_line >= max_print_line, TeX does line wrapping as usual
+ (see below). If either is exactly max_print_line (which is true
+ for the default values), things get confusing, so TeX may add a
+ blank line when wrapping.
+
LaTeX errors usually follow the format
@@ -620,10 +626,8 @@ function moreData()
while Lines:numLines() < 15 do
tmp = logfile:read("*line")
if tmp == nil then break end
- -- We *need* to remove blank lines here because
- -- sometimes a wrapped line is followed by a blank
- -- line, which messes our detection of wrapped lines.
- if tmp ~= "" then Lines:append(tmp) end
+ -- Do not skip blank lines here, we need to do it in Lines:append()
+ Lines:append(tmp)
end
-- proceed to the next line
@@ -744,6 +748,9 @@ function initializeGlobals()
-- messages, this is set to true (used in showSummary)
SHOULD_RERUN_LATEX = false
+ -- If there were parse errors, we should say so in showSummary
+ PARSE_ERROR = false
+
-- Did we detect any error messages?
ERRORS_DETECTED = false
@@ -898,42 +905,7 @@ function detectEngine()
Lines:append(line)
end
-function processCommandLine(args)
- HEARTBEAT = true
- PAGE_DELAY = true
- ONLY_SUMMARY = false
- SHOW_SUMMARY = true
- SHOW_SHIPOUTS = false
- RAW = false
- SILENCE_REPETITIONS = true
- MINLEVEL = WARNING
- BE_REDUNDANT = false
- FILE_BANNER = true
- DETAILED_UNDEROVER_SUMMARY = true
- DETAILED_REFERENCE_SUMMARY = true
- DETAILED_CITATION_SUMMARY = true
-
- COLOR = false
-
- SILENCE_STRINGS = {}
- SILENCE_PKGS = {} -- just the package names
- SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
- SILENCE_FILES_RECURSIVE = {} -- same
-
- -- The user may redefine the severity level of some messages.
- FORCED_DEBUG = {}
- FORCED_INFO = {}
- FORCED_WARNING = {}
- FORCED_CRITICAL = {}
-
- -- "-l level -c configFile"
- local optionsWithArgs = "lc"
- local vars = simpleGetopt(args, optionsWithArgs)
-
- --help
- -- "-h"
- if vars.help or vars.h then
- local msg = [[
+helpmsg = [[
Usage: texlogsieve [OPTION]... [INPUT FILE]
texlogsieve reads a LaTeX log file (or the standard input), filters
out less relevant messages, and displays a summary report.
@@ -994,23 +966,60 @@ Options:
text EXCERPT to CRITICAL; can be used
multiple times
-c cfgfile, --config-file=cfgfile read options from given config file
- in addition to texlogsieverc
+ in addition to default config files
+ -v, --verbose Display info on texlogsieve config
-h, --help give this help list
--version print program version]]
- for _, line in ipairs(linesToTable(msg)) do print(line) end
+versionmsg = [[
+texlogsieve 1.3.0
+Copyright (C) 2021, 2022 Nelson Lago <lago@ime.usp.br>
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.]]
+
+function processCommandLine(args)
+ HEARTBEAT = true
+ PAGE_DELAY = true
+ ONLY_SUMMARY = false
+ SHOW_SUMMARY = true
+ SHOW_SHIPOUTS = false
+ RAW = false
+ SILENCE_REPETITIONS = true
+ MINLEVEL = WARNING
+ BE_REDUNDANT = false
+ FILE_BANNER = true
+ DETAILED_UNDEROVER_SUMMARY = true
+ DETAILED_REFERENCE_SUMMARY = true
+ DETAILED_CITATION_SUMMARY = true
+
+ COLOR = false
+
+ SILENCE_STRINGS = {}
+ SILENCE_PKGS = {} -- just the package names
+ SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
+ SILENCE_FILES_RECURSIVE = {} -- same
+
+ -- The user may redefine the severity level of some messages.
+ FORCED_DEBUG = {}
+ FORCED_INFO = {}
+ FORCED_WARNING = {}
+ FORCED_CRITICAL = {}
+
+ -- "-l level -c configFile"
+ local optionsWithArgs = "lc"
+ local vars = simpleGetopt(args, optionsWithArgs)
+
+ --help
+ -- "-h"
+ if vars.help or vars.h then
+ for _, line in ipairs(linesToTable(helpmsg)) do print(line) end
os.exit(0)
end
--version
if vars.version then
- print("texlogsieve 1.2.0")
- print("Copyright (C) 2021, 2022 Nelson Lago <lago@ime.usp.br>")
- print("License GPLv3+: GNU GPL version 3 or later "
- .. "<https://gnu.org/licenses/gpl.html>.")
- print("This is free software: you are free to change "
- .. "and redistribute it.")
- print("There is NO WARRANTY, to the extent permitted by law.")
+ for _, line in ipairs(linesToTable(versionmsg)) do print(line) end
os.exit(0)
end
@@ -1029,6 +1038,21 @@ Options:
local filename = kpse.find_file('texlogsieverc')
if filename ~= nil then table.insert(configFileNames, 1, filename) end
+ if os.type == "unix" then
+ filename = kpse.find_file(os.getenv("HOME") .. "/.texlogsieverc")
+ else
+ -- https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
+ -- %LOCALAPPDATA% corresponds to C:\Users\<username>\AppData\Local .
+ filename = kpse.find_file(os.getenv("%LOCALAPPDATA%") .. "/texlogsieverc")
+ if filename == nil then
+ -- %APPDATA% is "C:\Users\<username>\AppData\Roaming" or
+ -- "C:\Documents and Settings\<username>\Application Data"
+ filename = kpse.find_file(os.getenv("%APPDATA%") .. "/texlogsieverc")
+ end
+ end
+
+ if filename ~= nil then table.insert(configFileNames, 1, filename) end
+
for _, filename in ipairs(configFileNames) do
local configFile = assert(io.open(filename, "r"))
vars = processConfigFile(configFile, vars)
@@ -1353,6 +1377,39 @@ Options:
vars['set-to-level-critical'] = nil
+ --verbose
+ -- "-v"
+ if vars['verbose'] or vars.v then
+ local msg = ""
+
+ for _, name in ipairs(configFileNames) do msg = msg .. name .. ", " end
+
+ if msg == "" then
+ print("texlogsieve: no config files, using defaults")
+ else
+ msg = string.sub(msg, 1, -3)
+ print("texlogsieve: using config files: " .. msg)
+ end
+
+ msg = "texlogsieve: minlevel is "
+ if MINLEVEL == 0 then msg = msg .. 'DEBUG'
+ elseif MINLEVEL == 1 then msg = msg .. 'INFO'
+ elseif MINLEVEL == 2 then msg = msg .. 'WARNING'
+ elseif MINLEVEL == 3 then msg = msg .. 'CRITICAL'
+ else msg = msg .. 'UNKNOWN'
+ end
+
+ print(msg)
+
+ if RAW then
+ print("texlogsieve: using raw (unwrap-only) mode")
+ end
+ end
+
+ vars['verbose'] = nil
+ vars.v = nil
+
+
local unknown_options = false
for k, v in pairs(vars) do
print(' texlogsieve: unknown option "' .. k .. '"')
@@ -1581,13 +1638,13 @@ function finishProcessingMessages()
end
function showFileBanner(msg)
+ if msg.filename == "DUMMY" then PARSE_ERROR = true end
+
if not FILE_BANNER then return end
if msg.filename ~= nil
and msg.filename ~= ""
and msg.filename ~= lastFileBanner
- -- TODO: "DUMMY" should never happen, but
- -- what should we do if it does?
then
lastFileBanner = msg.filename
local txt = "From file " .. msg.filename .. ":"
@@ -1674,7 +1731,7 @@ end
function showSummary()
local somethingInSummary = false
- if SHOULD_RERUN_LATEX or ERRORS_DETECTED then
+ if SHOULD_RERUN_LATEX or ERRORS_DETECTED or PARSE_ERROR then
somethingInSummary = true
else
for _, summary in ipairs(summaries) do
@@ -1716,6 +1773,15 @@ function showSummary()
print()
end
+ if PARSE_ERROR then
+ local txt = "** texlogsieve got confused during log processing **" ..
+ "\n" .. " messages may be missing or filenames may be" ..
+ "\n" .. " incorrect, check the LaTeX logfile directly"
+ if COLOR then txt = red(txt) end
+ print(txt)
+ print()
+ end
+
if ERRORS_DETECTED then
local txt = "** There were errors during processing! Generated PDF is probably defective **"
if COLOR then txt = red(txt) end
@@ -2169,8 +2235,10 @@ function fpHandler:process()
else
-- This should never happen, but if it does
-- we will probably end up in an endless loop
- io.stderr:write(" texlogsieve: parsing error in "
- .. "fpHandler:process()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum .. " (fpHandler:process)\n")
+
+ PARSE_ERROR = true
dispatch(self.message)
self.message = nil
@@ -2199,8 +2267,10 @@ function fpHandler:processClose(last)
Lines:handledChars(last)
if self.stack:pop() == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "fpHandler:processClose()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum .. " (fpHandler:processClose)\n")
+
+ PARSE_ERROR = true
end
if self.stack:empty() then
@@ -2276,8 +2346,11 @@ function underOverFullBoxHandler:handleFirstLine()
end
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "underOverFullBoxHandler:handleFirstLine()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (underOverFullBoxHandler:handleFirstLine)\n")
+
+ PARSE_ERROR = true
self.doit = self.handleFirstLine
dispatch(self.message)
@@ -2439,8 +2512,11 @@ function stringsHandler:handleLines()
for _, val in ipairs(tmp) do table.insert(self.captures, val) end
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "stringsHandler:handleLines()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (stringsHandler:handleLines)\n")
+
+ PARSE_ERROR = true
dispatch(self.message)
self.message = nil
@@ -3570,9 +3646,11 @@ function openParensHandler:doit()
flushUnrecognizedMessages()
local last = unwrapUntilStringMatches(data.filename)
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "openParensHandler:doit()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (openParensHandler:doit)\n")
+ PARSE_ERROR = true
else
Lines:handledChars(last)
end
@@ -3772,9 +3850,11 @@ function openSquareBracketHandler:doit()
flushUnrecognizedMessages()
local last = unwrapUntilStringMatches(data.latexPage)
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "openSquareBracketHandler:doit()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (openSquareBracketHandler:doit)\n")
+ PARSE_ERROR = true
else
Lines:handledChars(last)
end
@@ -3993,9 +4073,11 @@ function utf8FontMapHandler:handleSecondLine()
-- "processing UTF-8 mapping" - this should never happen
dispatch(self.message)
self.message = nil
- io.stderr:write(" texlogsieve: parsing error in "
- .. "utf8FontMapHandler:handleSecondLine()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (utf8FontMapHandler:handleSecondLine)\n")
+ PARSE_ERROR = true
Lines:handledChars()
self.doit = self.handleFirstLine
return true
@@ -4025,9 +4107,11 @@ function utf8FontMapHandler:handleOtherLines()
dispatch(self.message)
self.message = nil
flushUnrecognizedMessages()
- io.stderr:write(" texlogsieve: parsing error in "
- .. "utf8FontMapHandler:handleOtherLines()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (utf8FontMapHandler:handleOtherLines)\n")
+ PARSE_ERROR = true
self.numTries = 0
self.foundOtherLines = false
self.doit = self.handleFirstLine
@@ -4972,8 +5056,8 @@ function SummaryPrototype:pageAndFileList(messages)
if files[msg.filename] == nil then
files[msg.filename] = {}
end
- if msg.linenum ~= "" then
- table.insert(files[msg.filename], msg.linenum)
+ if tonumber(msg.linenum) then
+ table.insert(files[msg.filename], tonumber(msg.linenum))
end
end
end
@@ -5147,22 +5231,6 @@ end
unusedLabelsSummary = citationsSummary:new()
unusedLabelsSummary.header = 'Unused labels:'
-function unusedLabelsSummary:processSingleMessageList(messages)
- local text = ""
- local pages, files = self:pageAndFileList(messages)
- local key = messages[1].key
- if key == "" then key = '???' end
-
- if self:detailed() then
- if COLOR then key = red(key) end
- text = key .. ' in ' .. pages .. " (" .. files .. ")"
- else
- text = key
- end
-
- return text
-end
-
-- This is a little different from the others; we do not want to
-- treat different messages differently, only report that there were
@@ -5371,6 +5439,66 @@ function Stack:empty()
end
+--[[ ##### QUEUE ##### ]]--
+-- Adapted from https://www.lua.org/pil/11.4.html (in 2022)
+-- We use this for the input line counter
+
+Queue = {}
+
+function Queue:new()
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.first = 0
+ o.last = -1
+ return o
+end
+
+function Queue:pushleft(val)
+ self.first = self.first -1
+ self[self.first] = val
+end
+
+function Queue:pushright(val)
+ self.last = self.last +1
+ self[self.last] = val
+end
+
+function Queue:popleft()
+ if self.first > self.last then return nil end
+ local val = self[self.first]
+ self[self.first] = nil
+ self.first = self.first +1
+ return val
+end
+
+function Queue:popright()
+ if self.first > self.last then return nil end
+ local val = self[self.last]
+ self[self.last] = nil
+ self.last = self.last -1
+ return val
+end
+
+function Queue:peekleft()
+ if self.first > self.last then return nil end
+ return self[self.first]
+end
+
+function Queue:peekright()
+ if self.first > self.last then return nil end
+ return self[self.last]
+end
+
+function Queue:size()
+ return self.last - self.first +1
+end
+
+function Queue:empty()
+ return self.first > self.last
+end
+
+
--[[ ##### GLOBTOPATTERN ##### ]]--
-- convert a file glob to a lua pattern
@@ -5644,12 +5772,20 @@ original length was max_print_line characters).
Lines = {}
Lines.wrapped = {} -- memoization
+Lines.linenum = 0
+Lines.blankLines = Queue:new()
function Lines:gotoNextLine()
self.current = table.remove(self, 1)
self.currentWrapped = table.remove(self.wrapped, 1)
self.atBeginningOfLine = true
+ self.linenum = self.linenum +1
+ -- blank lines have to be counted too
+ if not self.blankLines:empty() then
+ self.linenum = self.linenum + self.blankLines:popleft()
+ end
+
-- When unwrapping lines, we need to check whether a line is of
-- the "right" size. However, we modify the content of currentLine
-- during processing, so we capture its initial length here. See
@@ -5691,8 +5827,23 @@ function Lines:len(n)
end
function Lines:append(x)
- table.insert(self, x)
- table.insert(self.wrapped, "unknown") -- cannot use "nil"
+ -- We *need* to remove blank lines here because sometimes a wrapped
+ -- line is followed by a blank line, which messes our detection of
+ -- wrapped lines. However, the line we skip here is not the line we
+ -- are processing right now; we will encounter it in the future. So,
+ -- to keep line numbers right, we need to adjust the count later too.
+ if x == "" then
+ if not self.blankLines:empty() then
+ self.blankLines:pushright(self.blankLines:popright() +1)
+ else
+ self.blankLines:pushright(1)
+ end
+ else
+ self.blankLines:pushright(0)
+
+ table.insert(self, x)
+ table.insert(self.wrapped, "unknown") -- cannot use "nil"
+ end
end
function Lines:get(n)
@@ -5847,9 +5998,11 @@ function unwrapUntilPatternMatches(pat)
if Lines:seemsWrapped() then
Lines:unwrapOneLine()
else
- io.stderr:write(" texlogsieve: parsing error in "
- .. "unwrapUntilPatternMatches()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (unwrapUntilPatternMatches)\n")
+ PARSE_ERROR = true
break
end
end
@@ -6008,9 +6161,10 @@ function guessQuotedFilename(line, position)
-- no closing quote or the line is too short; can we unwrap this line?
if not Lines:seemsWrapped(position) then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "guessQuotedFilename()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum .. " (guessQuotedFilename)\n")
+ PARSE_ERROR = true
return true, nil
end
diff --git a/Master/texmf-dist/doc/man/man1/texlogsieve.1 b/Master/texmf-dist/doc/man/man1/texlogsieve.1
index 4628d1ec54f..b39e33eff2f 100644
--- a/Master/texmf-dist/doc/man/man1/texlogsieve.1
+++ b/Master/texmf-dist/doc/man/man1/texlogsieve.1
@@ -1,4 +1,4 @@
-.TH TEXLOGSIEVE "1" "July 2022" "texlogsieve 1.2.0" "User Commands"
+.TH TEXLOGSIEVE "1" "August 2022" "texlogsieve 1.3.0" "User Commands"
.SH NAME
@@ -198,8 +198,13 @@ severity level of many different messages.
.TP
\fB\-c\fR \fI\,CFGFILE\/\fR, \fB\-\-config\-file\fR=\fI\,CFGFILE\/\fR
-Read options from the given configuration file in addition to
-\fI\,texlogsieverc\/\fR.
+Read options from the given configuration file in addition to the
+default config files (see the \fBCONFIGURATION FILE\fR section).
+
+.TP
+\fB\-v\fR, \fB\-\-verbose\fR
+Print the list of configuration files read and a short summary of the
+most important active configuration options.
.TP
\fB\-h\fR, \fB\-\-help\fR
@@ -226,13 +231,14 @@ list of messages known to the program.
.SH CONFIGURATION FILE
texlogsieve always searches automatically for the (optional)
-\fI\,texlogsieverc\/\fR configuration file in the TeX path (i.e., it searches
-using Kpathsea). In the default configuration, the current directory is in
-the search path, so adding a config file with that name to the project
-directory is enough to make it work. Options in the config file are exactly
-the same as the long command-line options described above, but without the
-preceding \[lq]\-\-\[rq] characters. Lines starting with a \[lq]#\[rq] sign
-are comments. An example configuration file:
+\fI\,texlogsieverc\/\fR configuration file in \fI\,$TEXINPUTS\/\fR (i.e.,
+it searches using Kpathsea). In the default configuration, the current
+directory is in \fI\,$TEXINPUTS\/\fR, so adding a config file with that
+name to the project directory is enough to make it work. Options in
+the config file are exactly the same as the long command-line options
+described above, but without the preceding \[lq]\-\-\[rq] characters.
+Lines starting with a \[lq]#\[rq] sign are comments. An example
+configuration file:
.RS
.EX
@@ -256,13 +262,22 @@ silence\-files = *.sty
.EE
.RE
+If you'd like to also have a generic configuration file for all your projects
+(a good idea), put it at \fI\,$HOME/.texlogsieverc\/\fR in unix-like systems;
+in Windows, put it either at \fI\,%LOCALAPPDATA%\etexlogsieverc\/\fR
+(\fI\,C:\eUsers\e<username>\eAppData\eLocal\/\fR)
+or \fI\,%APPDATA%\etexlogsieverc\/\fR (\fI\,C:\eDocuments and
+Settings\e<username>\eApplication Data\/\fR or
+\fI\,C:\eUsers\e<username>\eAppData\eRoaming).
+
.SH LIMITATIONS
texlogsieve does not try to do anything smart about error messages (but it
-shows a warning in the summary if one is detected); if there is an error,
-you probably want to take a look directly at the log file anyway. It also
-cannot detect if LaTeX stops for user input, so you should \fBreally\fR
-run LaTeX in \fI\,nonstopmode\/\fR when texlogsieve is reading from a pipe.
+shows a warning in the summary if one is detected; check the \fBTIPS\fR
+section of the pdf documentation regarding this); if there is an error, you
+probably want to take a look directly at the log file anyway. It also cannot
+detect if LaTeX stops for user input, so you should \fBreally\fR run LaTeX
+in \fI\,nonstopmode\/\fR when texlogsieve is reading from a pipe.
Since it needs to know what messages to expect, texlogsieve is currently
geared towards LaTeX; I have no idea how it would work with ConTeXt or plain
diff --git a/Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdf b/Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdf
index f65d3e70087..099832b51db 100644
--- a/Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdf
+++ b/Master/texmf-dist/doc/man/man1/texlogsieve.man1.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdf b/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdf
index f37bc1ab309..1891667c3d6 100644
--- a/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdf
+++ b/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex b/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex
index 6270e27ffe1..40323ceb2ac 100644
--- a/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex
+++ b/Master/texmf-dist/doc/support/texlogsieve/texlogsieve.tex
@@ -37,6 +37,8 @@
\usepackage{microtype}
\usepackage{metalogo}
+\hyphenation{tex-log-sieve tex-log-sieverc}
+
\RecordChanges
\changes{1.0.0-beta-1}{2021/12/16}{First public prerelease}
@@ -84,12 +86,18 @@
\changes{1.2.0}{2022/07/21}{Summary messages use singular and plural
for pages and files}
\changes{1.2.0}{2022/07/21}{Add unused labels to summary}
+\changes{1.3.0}{2022/08/05}{Sort line numbers in summary}
+\changes{1.3.0}{2022/08/05}{Indicate whether there were parse errors
+ in summary}
+\changes{1.3.0}{2022/08/05}{Add line number to parse error messages}
+\changes{1.3.0}{2022/08/05}{Add \texttt{-\/-verbose} option}
+\changes{1.3.0}{2022/08/05}{Search for a config file in the user's homedir too}
\begin{document}
\title{\textsf{texlogsieve}:\thanks{This document
-corresponds to \textsf{texlogsieve}~1.2.0,
-dated~2022-07-21.}\\[.3\baselineskip]
+corresponds to \textsf{texlogsieve}~1.3.0,
+dated~2022-08-05.}\\[.3\baselineskip]
{\normalsize(yet another program to)\\[-.6\baselineskip]}
{\large filter and summarize \LaTeX\ log files}
}
@@ -138,12 +146,12 @@ spirit to tools such as \href{https://ctan.org/pkg/texfot}{\texttt{texfot}},
\href{https://gricad-gitlab.univ-grenoble-alpes.fr/labbeju/latex-packages}
{\texttt{texlogfilter}}, and others.
-Note that it does not try to do anything smart about error messages
-(but it shows a warning in the summary if one is detected); if there
-is an error, you probably want to take a look directly at the log file
-anyway. It also cannot detect if \LaTeX{} stops for user input, so
-you should \textbf{really} run \LaTeX\ in \texttt{nonstopmode} when
-\texttt{texlogsieve} is reading from a pipe.
+Note that it does not try to do anything smart about error messages (but
+it shows a warning in the summary if one is detected; check the ``Tips''
+section regarding this); if there is an error, you probably want to take
+a look directly at the log file anyway. It also cannot detect if \LaTeX{}
+stops for user input, so you should \textbf{really} run \LaTeX\ in
+\texttt{nonstopmode} when \texttt{texlogsieve} is reading from a pipe.
\texttt{texlogsieve} \textbf{must} be run from the same directory as
\verb/[pdf|lua|xe]latex/, because it searches for the files used during
@@ -223,13 +231,14 @@ options to add it to the list of messages known to the program.
\section{Configuration File}
\texttt{texlogsieve} always searches automatically for the (optional)
-\texttt{texlogsieverc} configuration file in the \TeX\ path (i.e., it
-searches using \texttt{Kpathsea}). In the default configuration, the
-current directory is in the search path, so adding a config file with that
-name to the project directory is enough to make it work. Options in the
-config file are exactly the same as the long command-line options described
-below, but without the preceding ``\texttt{-\/-}'' characters. Lines
-starting with a ``\#'' sign are comments. An example configuration file:
+\texttt{texlogsieverc} configuration file in \texttt{\$TEXINPUTS} (i.e.,
+it searches using \texttt{Kpathsea}). In the default configuration, the
+current directory is in \texttt{\$TEXINPUTS}, so adding a config file
+with that name to the project directory is enough to make it work.
+Options in the config file are exactly the same as the long command-line
+options described below, but without the preceding ``\texttt{-\/-}''
+characters. Lines starting with a ``\#'' sign are comments. An example
+configuration file:
\begin{quote}
\begin{verbatim}
@@ -246,6 +255,16 @@ silence-files = *.sty
\end{verbatim}
\end{quote}
+If you'd like to also have a generic configuration file for all your projects
+(a good idea), put it at \texttt{\$HOME/.texlogsieverc} in unix-like systems;
+in Windows, put it either at \texttt{\%LOCALAPPDATA\%\textbackslash{}%
+texlogsieverc} (\texttt{C:\textbackslash{}Users\textbackslash{}<username>%
+\textbackslash{}AppData\textbackslash{}Local}) or \texttt{\%APPDATA\%%
+\textbackslash{}texlogsieverc} (\texttt{C:\textbackslash{}Documents and
+Settings\textbackslash{}<username>\textbackslash{}Application Data} or
+\texttt{C:\textbackslash{}Users\textbackslash{}<username>\textbackslash{}%
+AppData\textbackslash{}Roaming}).
+
\section{Options}
\begin{description}
@@ -426,8 +445,14 @@ the severity level of many different messages.
\begin{description}
\item[\texttt{-c CFGFILE}, \texttt{-\/-config-file=CFGFILE}]~\\
-Read options from the given configuration file in addition to
-\texttt{texlogsieverc}.
+Read options from the given configuration file in addition to the
+default config files (see the ``Configuration File'' section).
+\end{description}
+
+\begin{description}
+\item[\texttt{-v}, \texttt{-\/-verbose}]~\\
+Print the list of configuration files read and a short summary of the
+most important active configuration options.
\end{description}
\begin{description}
@@ -449,9 +474,8 @@ Print program version.
\texttt{silence-[something]} and \texttt{set-to-level-[something]} options:
You will get reasonably quiet output but still be notified of problems. Since
you probably always use essentially the same set of packages and classes,
- the file will be useable in other \LaTeX\ projects too (you may even put
- it somewhere in your \TeX\ path, like \texttt{\$HOME/texmf/tex/latex} on
- Unix-like systems).
+ the file will be useable in other \LaTeX\ projects too; just put it in one
+ of the places discussed in the ``Configuration File'' section.
\item \texttt{texlogsieve} has no smarts to deal with error messages, but
you may use options \texttt{-l unknown -\/-no-page-delay -\/-no-summary
diff --git a/Master/texmf-dist/scripts/texlogsieve/texlogsieve b/Master/texmf-dist/scripts/texlogsieve/texlogsieve
index 3520efd7448..331651fd55f 100755
--- a/Master/texmf-dist/scripts/texlogsieve/texlogsieve
+++ b/Master/texmf-dist/scripts/texlogsieve/texlogsieve
@@ -176,7 +176,13 @@ in the LaTeX log file:
is indented to start after the end of the first, as in the example
above. If the content of a line does not fit, a part of it (the
beginning for the first line and the end for the second line) may
- be replaced by "...".
+ be replaced by "...". error_line must be < 255 and half_error_line
+ must be < error_line -15. If error_line >= max_print_line or
+ half_error_line >= max_print_line, TeX does line wrapping as usual
+ (see below). If either is exactly max_print_line (which is true
+ for the default values), things get confusing, so TeX may add a
+ blank line when wrapping.
+
LaTeX errors usually follow the format
@@ -620,10 +626,8 @@ function moreData()
while Lines:numLines() < 15 do
tmp = logfile:read("*line")
if tmp == nil then break end
- -- We *need* to remove blank lines here because
- -- sometimes a wrapped line is followed by a blank
- -- line, which messes our detection of wrapped lines.
- if tmp ~= "" then Lines:append(tmp) end
+ -- Do not skip blank lines here, we need to do it in Lines:append()
+ Lines:append(tmp)
end
-- proceed to the next line
@@ -744,6 +748,9 @@ function initializeGlobals()
-- messages, this is set to true (used in showSummary)
SHOULD_RERUN_LATEX = false
+ -- If there were parse errors, we should say so in showSummary
+ PARSE_ERROR = false
+
-- Did we detect any error messages?
ERRORS_DETECTED = false
@@ -898,42 +905,7 @@ function detectEngine()
Lines:append(line)
end
-function processCommandLine(args)
- HEARTBEAT = true
- PAGE_DELAY = true
- ONLY_SUMMARY = false
- SHOW_SUMMARY = true
- SHOW_SHIPOUTS = false
- RAW = false
- SILENCE_REPETITIONS = true
- MINLEVEL = WARNING
- BE_REDUNDANT = false
- FILE_BANNER = true
- DETAILED_UNDEROVER_SUMMARY = true
- DETAILED_REFERENCE_SUMMARY = true
- DETAILED_CITATION_SUMMARY = true
-
- COLOR = false
-
- SILENCE_STRINGS = {}
- SILENCE_PKGS = {} -- just the package names
- SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
- SILENCE_FILES_RECURSIVE = {} -- same
-
- -- The user may redefine the severity level of some messages.
- FORCED_DEBUG = {}
- FORCED_INFO = {}
- FORCED_WARNING = {}
- FORCED_CRITICAL = {}
-
- -- "-l level -c configFile"
- local optionsWithArgs = "lc"
- local vars = simpleGetopt(args, optionsWithArgs)
-
- --help
- -- "-h"
- if vars.help or vars.h then
- local msg = [[
+helpmsg = [[
Usage: texlogsieve [OPTION]... [INPUT FILE]
texlogsieve reads a LaTeX log file (or the standard input), filters
out less relevant messages, and displays a summary report.
@@ -994,23 +966,60 @@ Options:
text EXCERPT to CRITICAL; can be used
multiple times
-c cfgfile, --config-file=cfgfile read options from given config file
- in addition to texlogsieverc
+ in addition to default config files
+ -v, --verbose Display info on texlogsieve config
-h, --help give this help list
--version print program version]]
- for _, line in ipairs(linesToTable(msg)) do print(line) end
+versionmsg = [[
+texlogsieve 1.3.0
+Copyright (C) 2021, 2022 Nelson Lago <lago@ime.usp.br>
+License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law.]]
+
+function processCommandLine(args)
+ HEARTBEAT = true
+ PAGE_DELAY = true
+ ONLY_SUMMARY = false
+ SHOW_SUMMARY = true
+ SHOW_SHIPOUTS = false
+ RAW = false
+ SILENCE_REPETITIONS = true
+ MINLEVEL = WARNING
+ BE_REDUNDANT = false
+ FILE_BANNER = true
+ DETAILED_UNDEROVER_SUMMARY = true
+ DETAILED_REFERENCE_SUMMARY = true
+ DETAILED_CITATION_SUMMARY = true
+
+ COLOR = false
+
+ SILENCE_STRINGS = {}
+ SILENCE_PKGS = {} -- just the package names
+ SEMISILENCE_FILES = {} -- filenames (without leading path), file globs work
+ SILENCE_FILES_RECURSIVE = {} -- same
+
+ -- The user may redefine the severity level of some messages.
+ FORCED_DEBUG = {}
+ FORCED_INFO = {}
+ FORCED_WARNING = {}
+ FORCED_CRITICAL = {}
+
+ -- "-l level -c configFile"
+ local optionsWithArgs = "lc"
+ local vars = simpleGetopt(args, optionsWithArgs)
+
+ --help
+ -- "-h"
+ if vars.help or vars.h then
+ for _, line in ipairs(linesToTable(helpmsg)) do print(line) end
os.exit(0)
end
--version
if vars.version then
- print("texlogsieve 1.2.0")
- print("Copyright (C) 2021, 2022 Nelson Lago <lago@ime.usp.br>")
- print("License GPLv3+: GNU GPL version 3 or later "
- .. "<https://gnu.org/licenses/gpl.html>.")
- print("This is free software: you are free to change "
- .. "and redistribute it.")
- print("There is NO WARRANTY, to the extent permitted by law.")
+ for _, line in ipairs(linesToTable(versionmsg)) do print(line) end
os.exit(0)
end
@@ -1029,6 +1038,21 @@ Options:
local filename = kpse.find_file('texlogsieverc')
if filename ~= nil then table.insert(configFileNames, 1, filename) end
+ if os.type == "unix" then
+ filename = kpse.find_file(os.getenv("HOME") .. "/.texlogsieverc")
+ else
+ -- https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables
+ -- %LOCALAPPDATA% corresponds to C:\Users\<username>\AppData\Local .
+ filename = kpse.find_file(os.getenv("%LOCALAPPDATA%") .. "/texlogsieverc")
+ if filename == nil then
+ -- %APPDATA% is "C:\Users\<username>\AppData\Roaming" or
+ -- "C:\Documents and Settings\<username>\Application Data"
+ filename = kpse.find_file(os.getenv("%APPDATA%") .. "/texlogsieverc")
+ end
+ end
+
+ if filename ~= nil then table.insert(configFileNames, 1, filename) end
+
for _, filename in ipairs(configFileNames) do
local configFile = assert(io.open(filename, "r"))
vars = processConfigFile(configFile, vars)
@@ -1353,6 +1377,39 @@ Options:
vars['set-to-level-critical'] = nil
+ --verbose
+ -- "-v"
+ if vars['verbose'] or vars.v then
+ local msg = ""
+
+ for _, name in ipairs(configFileNames) do msg = msg .. name .. ", " end
+
+ if msg == "" then
+ print("texlogsieve: no config files, using defaults")
+ else
+ msg = string.sub(msg, 1, -3)
+ print("texlogsieve: using config files: " .. msg)
+ end
+
+ msg = "texlogsieve: minlevel is "
+ if MINLEVEL == 0 then msg = msg .. 'DEBUG'
+ elseif MINLEVEL == 1 then msg = msg .. 'INFO'
+ elseif MINLEVEL == 2 then msg = msg .. 'WARNING'
+ elseif MINLEVEL == 3 then msg = msg .. 'CRITICAL'
+ else msg = msg .. 'UNKNOWN'
+ end
+
+ print(msg)
+
+ if RAW then
+ print("texlogsieve: using raw (unwrap-only) mode")
+ end
+ end
+
+ vars['verbose'] = nil
+ vars.v = nil
+
+
local unknown_options = false
for k, v in pairs(vars) do
print(' texlogsieve: unknown option "' .. k .. '"')
@@ -1581,13 +1638,13 @@ function finishProcessingMessages()
end
function showFileBanner(msg)
+ if msg.filename == "DUMMY" then PARSE_ERROR = true end
+
if not FILE_BANNER then return end
if msg.filename ~= nil
and msg.filename ~= ""
and msg.filename ~= lastFileBanner
- -- TODO: "DUMMY" should never happen, but
- -- what should we do if it does?
then
lastFileBanner = msg.filename
local txt = "From file " .. msg.filename .. ":"
@@ -1674,7 +1731,7 @@ end
function showSummary()
local somethingInSummary = false
- if SHOULD_RERUN_LATEX or ERRORS_DETECTED then
+ if SHOULD_RERUN_LATEX or ERRORS_DETECTED or PARSE_ERROR then
somethingInSummary = true
else
for _, summary in ipairs(summaries) do
@@ -1716,6 +1773,15 @@ function showSummary()
print()
end
+ if PARSE_ERROR then
+ local txt = "** texlogsieve got confused during log processing **" ..
+ "\n" .. " messages may be missing or filenames may be" ..
+ "\n" .. " incorrect, check the LaTeX logfile directly"
+ if COLOR then txt = red(txt) end
+ print(txt)
+ print()
+ end
+
if ERRORS_DETECTED then
local txt = "** There were errors during processing! Generated PDF is probably defective **"
if COLOR then txt = red(txt) end
@@ -2169,8 +2235,10 @@ function fpHandler:process()
else
-- This should never happen, but if it does
-- we will probably end up in an endless loop
- io.stderr:write(" texlogsieve: parsing error in "
- .. "fpHandler:process()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum .. " (fpHandler:process)\n")
+
+ PARSE_ERROR = true
dispatch(self.message)
self.message = nil
@@ -2199,8 +2267,10 @@ function fpHandler:processClose(last)
Lines:handledChars(last)
if self.stack:pop() == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "fpHandler:processClose()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum .. " (fpHandler:processClose)\n")
+
+ PARSE_ERROR = true
end
if self.stack:empty() then
@@ -2276,8 +2346,11 @@ function underOverFullBoxHandler:handleFirstLine()
end
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "underOverFullBoxHandler:handleFirstLine()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (underOverFullBoxHandler:handleFirstLine)\n")
+
+ PARSE_ERROR = true
self.doit = self.handleFirstLine
dispatch(self.message)
@@ -2439,8 +2512,11 @@ function stringsHandler:handleLines()
for _, val in ipairs(tmp) do table.insert(self.captures, val) end
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "stringsHandler:handleLines()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (stringsHandler:handleLines)\n")
+
+ PARSE_ERROR = true
dispatch(self.message)
self.message = nil
@@ -3570,9 +3646,11 @@ function openParensHandler:doit()
flushUnrecognizedMessages()
local last = unwrapUntilStringMatches(data.filename)
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "openParensHandler:doit()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (openParensHandler:doit)\n")
+ PARSE_ERROR = true
else
Lines:handledChars(last)
end
@@ -3772,9 +3850,11 @@ function openSquareBracketHandler:doit()
flushUnrecognizedMessages()
local last = unwrapUntilStringMatches(data.latexPage)
if last == nil then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "openSquareBracketHandler:doit()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (openSquareBracketHandler:doit)\n")
+ PARSE_ERROR = true
else
Lines:handledChars(last)
end
@@ -3993,9 +4073,11 @@ function utf8FontMapHandler:handleSecondLine()
-- "processing UTF-8 mapping" - this should never happen
dispatch(self.message)
self.message = nil
- io.stderr:write(" texlogsieve: parsing error in "
- .. "utf8FontMapHandler:handleSecondLine()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (utf8FontMapHandler:handleSecondLine)\n")
+ PARSE_ERROR = true
Lines:handledChars()
self.doit = self.handleFirstLine
return true
@@ -4025,9 +4107,11 @@ function utf8FontMapHandler:handleOtherLines()
dispatch(self.message)
self.message = nil
flushUnrecognizedMessages()
- io.stderr:write(" texlogsieve: parsing error in "
- .. "utf8FontMapHandler:handleOtherLines()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (utf8FontMapHandler:handleOtherLines)\n")
+ PARSE_ERROR = true
self.numTries = 0
self.foundOtherLines = false
self.doit = self.handleFirstLine
@@ -4972,8 +5056,8 @@ function SummaryPrototype:pageAndFileList(messages)
if files[msg.filename] == nil then
files[msg.filename] = {}
end
- if msg.linenum ~= "" then
- table.insert(files[msg.filename], msg.linenum)
+ if tonumber(msg.linenum) then
+ table.insert(files[msg.filename], tonumber(msg.linenum))
end
end
end
@@ -5147,22 +5231,6 @@ end
unusedLabelsSummary = citationsSummary:new()
unusedLabelsSummary.header = 'Unused labels:'
-function unusedLabelsSummary:processSingleMessageList(messages)
- local text = ""
- local pages, files = self:pageAndFileList(messages)
- local key = messages[1].key
- if key == "" then key = '???' end
-
- if self:detailed() then
- if COLOR then key = red(key) end
- text = key .. ' in ' .. pages .. " (" .. files .. ")"
- else
- text = key
- end
-
- return text
-end
-
-- This is a little different from the others; we do not want to
-- treat different messages differently, only report that there were
@@ -5371,6 +5439,66 @@ function Stack:empty()
end
+--[[ ##### QUEUE ##### ]]--
+-- Adapted from https://www.lua.org/pil/11.4.html (in 2022)
+-- We use this for the input line counter
+
+Queue = {}
+
+function Queue:new()
+ local o = {}
+ setmetatable(o, self)
+ self.__index = self
+ o.first = 0
+ o.last = -1
+ return o
+end
+
+function Queue:pushleft(val)
+ self.first = self.first -1
+ self[self.first] = val
+end
+
+function Queue:pushright(val)
+ self.last = self.last +1
+ self[self.last] = val
+end
+
+function Queue:popleft()
+ if self.first > self.last then return nil end
+ local val = self[self.first]
+ self[self.first] = nil
+ self.first = self.first +1
+ return val
+end
+
+function Queue:popright()
+ if self.first > self.last then return nil end
+ local val = self[self.last]
+ self[self.last] = nil
+ self.last = self.last -1
+ return val
+end
+
+function Queue:peekleft()
+ if self.first > self.last then return nil end
+ return self[self.first]
+end
+
+function Queue:peekright()
+ if self.first > self.last then return nil end
+ return self[self.last]
+end
+
+function Queue:size()
+ return self.last - self.first +1
+end
+
+function Queue:empty()
+ return self.first > self.last
+end
+
+
--[[ ##### GLOBTOPATTERN ##### ]]--
-- convert a file glob to a lua pattern
@@ -5644,12 +5772,20 @@ original length was max_print_line characters).
Lines = {}
Lines.wrapped = {} -- memoization
+Lines.linenum = 0
+Lines.blankLines = Queue:new()
function Lines:gotoNextLine()
self.current = table.remove(self, 1)
self.currentWrapped = table.remove(self.wrapped, 1)
self.atBeginningOfLine = true
+ self.linenum = self.linenum +1
+ -- blank lines have to be counted too
+ if not self.blankLines:empty() then
+ self.linenum = self.linenum + self.blankLines:popleft()
+ end
+
-- When unwrapping lines, we need to check whether a line is of
-- the "right" size. However, we modify the content of currentLine
-- during processing, so we capture its initial length here. See
@@ -5691,8 +5827,23 @@ function Lines:len(n)
end
function Lines:append(x)
- table.insert(self, x)
- table.insert(self.wrapped, "unknown") -- cannot use "nil"
+ -- We *need* to remove blank lines here because sometimes a wrapped
+ -- line is followed by a blank line, which messes our detection of
+ -- wrapped lines. However, the line we skip here is not the line we
+ -- are processing right now; we will encounter it in the future. So,
+ -- to keep line numbers right, we need to adjust the count later too.
+ if x == "" then
+ if not self.blankLines:empty() then
+ self.blankLines:pushright(self.blankLines:popright() +1)
+ else
+ self.blankLines:pushright(1)
+ end
+ else
+ self.blankLines:pushright(0)
+
+ table.insert(self, x)
+ table.insert(self.wrapped, "unknown") -- cannot use "nil"
+ end
end
function Lines:get(n)
@@ -5847,9 +5998,11 @@ function unwrapUntilPatternMatches(pat)
if Lines:seemsWrapped() then
Lines:unwrapOneLine()
else
- io.stderr:write(" texlogsieve: parsing error in "
- .. "unwrapUntilPatternMatches()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum
+ .. " (unwrapUntilPatternMatches)\n")
+ PARSE_ERROR = true
break
end
end
@@ -6008,9 +6161,10 @@ function guessQuotedFilename(line, position)
-- no closing quote or the line is too short; can we unwrap this line?
if not Lines:seemsWrapped(position) then
- io.stderr:write(" texlogsieve: parsing error in "
- .. "guessQuotedFilename()\n")
+ io.stderr:write(" texlogsieve: parsing error near input line "
+ .. Lines.linenum .. " (guessQuotedFilename)\n")
+ PARSE_ERROR = true
return true, nil
end