aboutsummaryrefslogtreecommitdiff
path: root/unit-tests/check-expect.lua
diff options
context:
space:
mode:
authorSimon J. Gerraty <sjg@FreeBSD.org>2025-06-28 02:38:49 +0000
committerSimon J. Gerraty <sjg@FreeBSD.org>2025-06-28 02:38:49 +0000
commit4f8f2bc2946615330eaa2cc1f6b37d97865fa58a (patch)
treeaa7729a97d1faeb358c9d981caadfad466f997a7 /unit-tests/check-expect.lua
parent284d1f7d496806b18558ab55e4654fd5e96d6a3e (diff)
Import bmake-20250618vendor/NetBSD/bmake/20250618
Intersting/relevant changes since bmake-20250414 ChangeLog since bmake-20250414 2025-06-18 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250618 Merge with NetBSD make, pick up o parse.c: in a warning without location information, print the stack trace 2025-06-15 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250615 Merge with NetBSD make, pick up o add on-demand inter-process stack traces o job.c,meta.c: do not discard empty lines in the output of a command o job.c: add job prefix if necessary in non-default filtered mode o parse.c,var.c: skip inter-process stack trace when MAKE_STACK_TRACE=no 2025-06-12 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250612 Merge with NetBSD make, pick up o use a common style for unexpected error messages o parse.c: add program name to stack traces from sub-makes add quotes to "in directory" line in stack traces o var.c: check variable names for invalid characters when there are no modifiers to apply. This detects and warns about gmake syntax like: $(addprefix -I, $(LIST)) 2025-06-09 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250606 Merge with NetBSD make, pick up o main.c: fix bug in handling of output of children in jobs mode 2025-05-28 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250528 Merge with NetBSD make, pick up o show contents of MAKEFLAGS in the stack trace. o main.c: delay warning about bogus -J flag, if we end up in compat mode before the call to InitMaxJobs, the warning isn't necessary. 2025-05-25 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250525 Merge with NetBSD make, pick up o main.c: set .CURDIR earlier so it can be reported in some errors. 2025-05-20 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250520 Merge with NetBSD make, pick up o rename variables, remove now-redundant comments o job.c: clean up building the shell commands in parallel mode remove timeout for polling in parallel mode o main.c: clean up error message for malformed internal -J option 2025-05-11 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250511 Merge with NetBSD make, pick up o job.c: rename token pool variables to be more descriptive move ContinueJobs further up, to eliminate a forward declaration error out if writing to an internal pipe fails clean up constant names and function names use uniform debug log messages for the token pool in the debug log, replace magic numbers with identifiers o main.c: clean up error message for malformed internal -J option o make.c: replace bitset in trace output with descriptive node attributes o targ.c: add end marker for -dg1, -dg2 and -dg3 debug log o var.c: fix order of error messages in the ":?" modifier 2025-04-25 Simon J Gerraty <sjg@beast.crufty.net> * VERSION (_MAKE_VERSION): 20250424 Merge with NetBSD make, pick up o cleanup; replace unsigned int with just unsigned Inline the TMPPAT macro, as it is only needed in a single place o move struct Job from job.h to job.c o job.c: group the code for handling the job token pool avoid excessive values of -j o make.c: fix grammar in debug log message mk/ChangeLog since bmake-20250414 2025-05-28 Simon J Gerraty <sjg@beast.crufty.net> * install-mk (MK_VERSION): 20250528 * add dirdeps2dplibs.mk 2025-05-18 Simon J Gerraty <sjg@beast.crufty.net> * install-mk (MK_VERSION): 20250518 * meta.autodep.mk (META_FILES): re-work to fix filtering. if OPTIMIZE_OBJECT_META_FILES==yes provide a default META_FILE_OBJ_FILTER that selects a valid .SUFFIX to match *o.meta, there's no guarantee that it will be as simple as .o or .So etc. We have to defer evaluation until the target script is run for any of these filters to have any effect. Use :S,${.OBJDIR}/,, rather than :T incase there are objects in sub-dirs. * lib.mk: leverage ${.SUFFIXES} when setting dependencies. * add UPDATE_DEPENDFILE as a dependent option - follows DIRDEPS_BUILD and use MK_UPDATE_DEPENDFILE as default for UPDATE_DEPENDFILE when we think it should be yes. This allows override with -DWITH[OUT]_UPDATE_DEPENDFILE without overriding UPDATE_DEPENDFILE directly - which can lead to trouble. 2025-05-16 Simon J Gerraty <sjg@beast.crufty.net> * install-mk (MK_VERSION): 20250515 * meta2deps.py: resolve the target of a Move or Link first and track the last path resolved, then if the src is a relative path we can easily use that last path to resolve the src correctly. * meta2deps.sh: for a Move or Link add the dir of target path to the list used to resolve the src path.
Diffstat (limited to 'unit-tests/check-expect.lua')
-rw-r--r--unit-tests/check-expect.lua190
1 files changed, 190 insertions, 0 deletions
diff --git a/unit-tests/check-expect.lua b/unit-tests/check-expect.lua
new file mode 100644
index 000000000000..218056fbc021
--- /dev/null
+++ b/unit-tests/check-expect.lua
@@ -0,0 +1,190 @@
+#! /usr/bin/lua
+-- $NetBSD: check-expect.lua,v 1.13 2025/04/13 09:29:32 rillig Exp $
+
+--[[
+
+usage: lua ./check-expect.lua *.mk
+
+Check that the various 'expect' comments in the .mk files produce the
+expected text in the corresponding .exp file.
+
+# expect: <line>
+ All of these lines must occur in the .exp file, in the same order as
+ in the .mk file.
+
+# expect-reset
+ Search the following 'expect:' comments from the top of the .exp
+ file again.
+
+# expect[+-]offset: <message>
+ Each message must occur in the .exp file and refer back to the
+ source line in the .mk file.
+
+# expect-not: <substring>
+ The substring must not occur as part of any line of the .exp file.
+
+# expect-not-matches: <pattern>
+ The pattern (see https://lua.org/manual/5.4/manual.html#6.4.1)
+ must not occur as part of any line of the .exp file.
+]]
+
+
+local had_errors = false
+---@param fmt string
+function print_error(fmt, ...)
+ print(fmt:format(...))
+ had_errors = true
+end
+
+
+---@return nil | string[]
+local function load_lines(fname)
+ local lines = {}
+
+ local f = io.open(fname, "r")
+ if f == nil then return nil end
+
+ for line in f:lines() do
+ table.insert(lines, line)
+ end
+ f:close()
+
+ return lines
+end
+
+
+---@param exp_lines string[]
+local function collect_lineno_diagnostics(exp_lines)
+ ---@type table<string, string[]>
+ local by_location = {}
+
+ for _, line in ipairs(exp_lines) do
+ ---@type string | nil, string, string
+ local l_fname, l_lineno, l_msg =
+ line:match('^make: ([^:]+):(%d+): (.*)')
+ if l_fname ~= nil then
+ local location = ("%s:%d"):format(l_fname, l_lineno)
+ if by_location[location] == nil then
+ by_location[location] = {}
+ end
+ table.insert(by_location[location], l_msg)
+ end
+ end
+
+ return by_location
+end
+
+
+local function missing(by_location)
+ ---@type {filename: string, lineno: number, location: string, message: string}[]
+ local missing_expectations = {}
+
+ for location, messages in pairs(by_location) do
+ for _, message in ipairs(messages) do
+ if message ~= "" and location:find(".mk:") then
+ local filename, lineno = location:match("^(%S+):(%d+)$")
+ table.insert(missing_expectations, {
+ filename = filename,
+ lineno = tonumber(lineno),
+ location = location,
+ message = message
+ })
+ end
+ end
+ end
+ table.sort(missing_expectations, function(a, b)
+ if a.filename ~= b.filename then
+ return a.filename < b.filename
+ end
+ return a.lineno < b.lineno
+ end)
+ return missing_expectations
+end
+
+
+local function check_mk(mk_fname)
+ local exp_fname = mk_fname:gsub("%.mk$", ".exp")
+ local mk_lines = load_lines(mk_fname)
+ local exp_lines = load_lines(exp_fname)
+ if exp_lines == nil then return end
+ local by_location = collect_lineno_diagnostics(exp_lines)
+ local prev_expect_line = 0
+
+ for mk_lineno, mk_line in ipairs(mk_lines) do
+
+ for text in mk_line:gmatch("#%s*expect%-not:%s*(.*)") do
+ local i = 1
+ while i <= #exp_lines and not exp_lines[i]:find(text, 1, true) do
+ i = i + 1
+ end
+ if i <= #exp_lines then
+ print_error("error: %s:%d: %s must not contain '%s'",
+ mk_fname, mk_lineno, exp_fname, text)
+ end
+ end
+
+ for text in mk_line:gmatch("#%s*expect%-not%-matches:%s*(.*)") do
+ local i = 1
+ while i <= #exp_lines and not exp_lines[i]:find(text) do
+ i = i + 1
+ end
+ if i <= #exp_lines then
+ print_error("error: %s:%d: %s must not match '%s'",
+ mk_fname, mk_lineno, exp_fname, text)
+ end
+ end
+
+ for text in mk_line:gmatch("#%s*expect:%s*(.*)") do
+ local i = prev_expect_line
+ -- As of 2022-04-15, some lines in the .exp files contain trailing
+ -- whitespace. If possible, this should be avoided by rewriting the
+ -- debug logging. When done, the trailing gsub can be removed.
+ -- See deptgt-phony.exp lines 14 and 15.
+ while i < #exp_lines and text ~= exp_lines[i + 1]:gsub("^%s*", ""):gsub("%s*$", "") do
+ i = i + 1
+ end
+ if i < #exp_lines then
+ prev_expect_line = i + 1
+ else
+ print_error("error: %s:%d: '%s:%d+' must contain '%s'",
+ mk_fname, mk_lineno, exp_fname, prev_expect_line + 1, text)
+ end
+ end
+ if mk_line:match("^#%s*expect%-reset$") then
+ prev_expect_line = 0
+ end
+
+ ---@param text string
+ for offset, text in mk_line:gmatch("#%s*expect([+%-]%d+):%s*(.*)") do
+ local location = ("%s:%d"):format(mk_fname, mk_lineno + tonumber(offset))
+
+ local found = false
+ if by_location[location] ~= nil then
+ for i, message in ipairs(by_location[location]) do
+ if message == text then
+ by_location[location][i] = ""
+ found = true
+ break
+ elseif message ~= "" then
+ print_error("error: %s:%d: out-of-order '%s'",
+ mk_fname, mk_lineno, message)
+ end
+ end
+ end
+
+ if not found then
+ print_error("error: %s:%d: %s must contain '%s'",
+ mk_fname, mk_lineno, exp_fname, text)
+ end
+ end
+ end
+
+ for _, m in ipairs(missing(by_location)) do
+ print_error("missing: %s: # expect+1: %s", m.location, m.message)
+ end
+end
+
+for _, fname in ipairs(arg) do
+ check_mk(fname)
+end
+os.exit(not had_errors)