1#! /usr/bin/lua 2-- $NetBSD: check-msgs.lua,v 1.3 2024/11/30 18:17:11 rillig Exp $ 3 4--[[ 5 6usage: lua ./check-msgs.lua *.c 7 8Check that the message text in the comments of the C source code matches the 9actual user-visible message text in msg.c. 10 11]] 12 13 14local function load_messages(fname) 15 local msgs = {} ---@type table<number>string 16 17 local f = assert(io.open(fname, "r")) 18 for line in f:lines() do 19 local msg, id = line:match("%s*\"(.+)\",%s*// (%d+)$") 20 if msg ~= nil then 21 msgs[tonumber(id)] = msg 22 end 23 end 24 25 f:close() 26 27 return msgs 28end 29 30 31local had_errors = false 32---@param fmt string 33function print_error(fmt, ...) 34 print(fmt:format(...)) 35 had_errors = true 36end 37 38 39local function check_message(fname, lineno, id, comment, msgs) 40 local msg = msgs[id] 41 42 if msg == nil then 43 print_error("%s:%d: id=%d not found", fname, lineno, id) 44 return 45 end 46 47 msg = msg:gsub("/%*", "**") 48 msg = msg:gsub("%*/", "**") 49 msg = msg:gsub("\\t", "\\\\t") -- for lint2 50 msg = msg:gsub("\\(.)", "%1") 51 52 if comment == msg then 53 return 54 end 55 56 local prefix = comment:match("^(.-)%s*%.%.%.$") 57 if prefix ~= nil and msg:find(prefix, 1, 1) == 1 then 58 return 59 end 60 61 print_error("%s:%d: id=%-3d msg=%-40s comment=%s", 62 fname, lineno, id, msg, comment) 63end 64 65 66local function check_file(fname, msgs) 67 local f = assert(io.open(fname, "r")) 68 local lineno = 0 69 local prev = "" 70 for line in f:lines() do 71 lineno = lineno + 1 72 73 local func, id = line:match("^%s+(%w+)%((%d+)[),]") 74 id = tonumber(id) 75 if func == "msg" then 76 local comment = prev:match("^%s+/%* (.+) %*/$") 77 if comment ~= nil then 78 check_message(fname, lineno, id, comment, msgs) 79 else 80 print_error("%s:%d: missing comment for %d: /* %s */", 81 fname, lineno, id, msgs[id]) 82 end 83 end 84 85 prev = line 86 end 87 88 f:close() 89end 90 91 92local function main(arg) 93 local msgs = load_messages("msg.c") 94 for _, fname in ipairs(arg) do 95 check_file(fname, msgs) 96 end 97end 98 99main(arg) 100os.exit(not had_errors) 101