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