lint.lua revision 1.3
11.1Srillig#! /usr/bin/lua
21.3Srillig-- $NetBSD: lint.lua,v 1.3 2021/06/13 18:11:44 rillig Exp $
31.1Srillig
41.1Srillig--[[
51.1Srillig
61.1Srilligusage: lua ./lint.lua
71.1Srillig
81.1SrilligCheck that the boilerplate code does not contain unintended
91.1Srilliginconsistencies.
101.1Srillig
111.1Srillig]]
121.1Srillig
131.3Srillig---@return string[]
141.1Srilliglocal function load_lines(fname)
151.1Srillig  local lines = {}
161.1Srillig
171.1Srillig  local f = assert(io.open(fname, "r"))
181.1Srillig  for line in f:lines() do
191.1Srillig    table.insert(lines, line)
201.1Srillig  end
211.1Srillig
221.1Srillig  f:close()
231.1Srillig
241.1Srillig  return lines
251.1Srilligend
261.1Srillig
271.1Srillig
281.1Srilliglocal function new_errors()
291.1Srillig  local errors = {}
301.1Srillig  errors.add = function(self, fmt, ...)
311.1Srillig    table.insert(self, string.format(fmt, ...))
321.1Srillig  end
331.1Srillig  errors.print = function(self)
341.1Srillig    for _, msg in ipairs(self) do
351.1Srillig      print(msg)
361.1Srillig    end
371.1Srillig  end
381.1Srillig  return errors
391.1Srilligend
401.1Srillig
411.1Srillig
421.1Srilliglocal function num(s)
431.1Srillig  if s == nil then return nil end
441.1Srillig  return tonumber(s)
451.1Srilligend
461.1Srillig
471.1Srillig
481.1Srillig-- After each macro ARGC, there must be the corresponding macros for ARG.
491.1Srilliglocal function check_args(errors)
501.1Srillig  local fname = "curses_commands.c"
511.1Srillig  local lines = load_lines(fname)
521.1Srillig  local argi, argc
531.1Srillig
541.1Srillig  for lineno, line in ipairs(lines) do
551.1Srillig
561.1Srillig    local c = num(line:match("^\tARGC%((%d)"))
571.3Srillig    if c and c > 0 then
581.1Srillig      argc, argi = c, 0
591.1Srillig    end
601.1Srillig
611.3Srillig    local arg = line:match("^\tARG_[%w_]+%(")
621.3Srillig    if arg and not argi then
631.1Srillig      errors:add("%s:%d: ARG without preceding ARGC", fname, lineno)
641.1Srillig    end
651.1Srillig
661.3Srillig    if not arg and argi and not c then
671.1Srillig      errors:add("%s:%d: expecting ARG %d, got %s", fname, lineno, argi, line)
681.1Srillig      argc, argi = nil, nil
691.1Srillig    end
701.1Srillig
711.3Srillig    if arg and argi then
721.1Srillig      argi = argi + 1
731.1Srillig      if argi == argc then
741.1Srillig        argc, argi = nil, nil
751.1Srillig      end
761.1Srillig    end
771.1Srillig  end
781.1Srilligend
791.1Srillig
801.1Srillig
811.1Srilliglocal function main(arg)
821.1Srillig  local errors = new_errors()
831.1Srillig  check_args(errors)
841.1Srillig  errors:print()
851.1Srillig  return #errors == 0
861.1Srilligend
871.1Srillig
881.1Srillig
891.1Srilligos.exit(main(arg))
90