2 -- base class for all inspectors
3 -- every derived class must implement inspect()
7 function inspector
:__init(name
)
12 function inspector
:warning(path
, str
)
13 table.insert( self
.warnings
, { path
, str
} )
16 function inspector
:report()
17 local output
= function(_
,x
)
18 local name
= x
[1]:string()
19 print(name
.. ": " .. x
[2])
22 local cmp
= function(a
,b
)
23 return a
[1]:string() < b
[1]:string()
28 if table.getn(self
.warnings
) ~= 0 then
29 violations
= table.getn(self
.warnings
) .. " violations"
31 violations
= "no violations"
34 print("\n-- " .. self
.name
.. " [" .. violations
.. "]\n")
36 table.sort(self
.warnings
, cmp
)
37 table.foreach(self
.warnings
, output
)
40 inspector
.inspect
= nil
42 -- checks filename length
43 class
'filename_length' (inspector
)
45 function filename_length
:__init(n
)
46 super("filename length (" .. n
.. " characters)")
50 function filename_length
:inspect(path
)
51 local n
= string.len(path
:leaf())
52 if n
> self
.maxlen
then
53 self
:warning(path
, n
.. " characters in filename")
57 -- checks that the filename is all lowercase
58 class
'filename_case' (inspector
)
60 function filename_case
:__init()
61 super("filename case")
64 function filename_case
:inspect(path
)
65 if string.lower(path
:leaf()) ~= path
:leaf() then
66 self
:warning(path
, "uppercase letters")
70 -- checks that the file doesn't contain tabs
71 class
'tab_inspector' (inspector
)
73 function tab_inspector
:__init()
74 super("tab inspector")
77 function tab_inspector
:inspect(path
)
78 if has_endings(path
:leaf(), ".hpp", ".cpp") then
79 for line
in io
.lines(path
:string()) do
80 if string.find(line
, '\t') ~= nil then
81 self
:warning(path
, "tabs in file")
88 -- checks that the file doesn't contain too long lines
89 class
'line_length_inspector' (inspector
)
91 function line_length_inspector
:__init(n
)
92 super("line length inspector (" .. n
.. " characters)")
96 function line_length_inspector
:inspect(path
)
97 if has_endings(path
:leaf(), ".hpp", ".cpp") then
98 for line
in io
.lines(path
:string()) do
99 if string.len(line
) > self
.maxlen
then
100 self
:warning(path
, "lines too long " .. string.len(line
))
107 -- checks that the file doesn't contain too long lines
108 class
'define_inspector' (inspector
)
110 function define_inspector
:__init()
111 super("define inspector")
114 function define_inspector
:inspect(path
)
115 if has_endings(path
:leaf(), ".hpp") then
119 for line
in io
.lines(path
:string()) do
120 local pos
, _
, def
= string.find(line
, "#%s*define%s+([%w_]+)")
121 if pos
~= nil then defs
[def
] = true end
122 local pos
, _
, def
= string.find(line
, "#%s*undef%s+([%w_]+)")
123 if pos
~= nil then defs
[def
] = nil end
126 table.foreach(defs
, function(def
)
127 self
:warning(path
, def
)
134 function file_ending(name
)
135 local pos
= string.find(name
, "%.")
136 if pos
== nil then return ""
138 return string.sub(name
, pos
)
142 function has_endings(name
, ...)
143 local ending
= file_ending(name
)
145 if ending
== i
then return true end
150 function recurse_dir(path
)
151 for i
in path
.contents
do
152 if i
:is_directory() then recurse_dir(i
)
154 table.foreach(inspectors
, function(_
,x
)
157 number_of_files
= number_of_files
+ 1
164 inspectors
= { filename_length(31), filename_case(),
165 tab_inspector(), line_length_inspector(79),
169 if args
.n
>= 3 then root
= filesystem
.path(args
[3])
170 else root
= filesystem
.initial_path() end
172 print("inspecting '" .. root
:string() .. "' ...")
176 print(" ** " .. number_of_files
.. " files was inspected")
178 table.foreach(inspectors
, function(_
,i
)