1#! /usr/bin/lua 2-- $NetBSD: lint.lua,v 1.2 2021/02/13 18:24:11 rillig Exp $ 3 4--[[ 5 6usage: lua ./lint.lua 7 8Check that the boilerplate code does not contain unintended 9inconsistencies. 10 11]] 12 13 14local function load_lines(fname) 15 local lines = {} 16 17 local f = assert(io.open(fname, "r")) 18 for line in f:lines() do 19 table.insert(lines, line) 20 end 21 22 f:close() 23 24 return lines 25end 26 27 28local function new_errors() 29 local errors = {} 30 errors.add = function(self, fmt, ...) 31 table.insert(self, string.format(fmt, ...)) 32 end 33 errors.print = function(self) 34 for _, msg in ipairs(self) do 35 print(msg) 36 end 37 end 38 return errors 39end 40 41 42local function num(s) 43 if s == nil then return nil end 44 return tonumber(s) 45end 46 47 48-- After each macro ARGC, there must be the corresponding macros for ARG. 49local function check_args(errors) 50 local fname = "curses_commands.c" 51 local lines = load_lines(fname) 52 local argi, argc 53 54 for lineno, line in ipairs(lines) do 55 56 local c = num(line:match("^\tARGC%((%d)")) 57 if c ~= nil and c > 0 then 58 argc, argi = c, 0 59 end 60 61 local i = num(line:match("^\tARG_[%w_]+%((%d+)")) 62 if i ~= nil and argi == nil then 63 errors:add("%s:%d: ARG without preceding ARGC", fname, lineno) 64 end 65 66 if i == nil and argi ~= nil and c == nil then 67 errors:add("%s:%d: expecting ARG %d, got %s", fname, lineno, argi, line) 68 argc, argi = nil, nil 69 end 70 71 if i ~= nil and argi ~= nil and i ~= argi then 72 errors:add("%s:%d: expecting ARG %d, not %d", fname, lineno, argi, i) 73 argi = i 74 end 75 76 if i ~= nil and argi ~= nil and i == argi then 77 argi = argi + 1 78 if argi == argc then 79 argc, argi = nil, nil 80 end 81 end 82 end 83end 84 85 86local function main(arg) 87 local errors = new_errors() 88 check_args(errors) 89 errors:print() 90 return #errors == 0 91end 92 93 94os.exit(main(arg)) 95