xref: /src/tools/tools/git/sanitize.lua (revision 7951411672fab14367d9e785bfc6fe7d9a29668c)
1-- SPDX-License-Identifier: BSD-2-Clause
2-- Copyright 2026 Warner Losh <imp@FreeBSD.org>
3
4--
5-- Removes all comments, blank lines and extra whitespace from a C header file
6-- and inserts a generated from comment at the top. Generally, this extracts the
7-- smallest subset of the file that describes the interface that is necessary to
8-- interoperate with that software. The user of this program should check the
9-- results, however, to ensure the result minimally describes the public
10-- interface.
11--
12-- When applied to device-tree binding files, this will result in the #defines
13-- being extracted, which are needed to generate the .dtb files, as well as for
14-- code to interpret the .dtb files. The device-tree files must be written this
15-- way to be used for this dual purpose. Other header files may not be so
16-- constrained, which makes review necessary for those context.
17--
18
19--
20-- Useage lua sanitize.lua fn description
21--
22-- fn will be read in, sanitized and the results printed on stdout.
23-- The description will be all remaining args and will be inserted
24-- in the first line comment to describe where the source file was
25-- obtained from.
26--
27
28-- Open the file from the command line
29local fn = arg[1]
30if not fn then
31	print("Usage: sanitize fn")
32	os.exit(1)
33end
34
35-- read it all in
36local f = assert(io.open(fn))
37local content = f:read("*all")
38f:close()
39
40-- Transform
41content = content:gsub("/%*.-%*/", "")		-- Remove block comments, .- is lazy, not greed, match
42content = content:gsub("//[^\n]*", "")		-- Remove single line comments
43content = content:gsub("%s*\n", "\n")		-- Remove trailing white space
44content = content:gsub("\t+", " ")		-- Convert blocks of tabs to a space
45content = content:gsub("\n+", "\n")		-- Remove blank lines
46content = content:gsub("\n+$", "")		-- Strip blank lines at the end (print adds one)
47content = content:gsub("^\n+", "")		-- Strip leading blank lines
48
49print("/* @" .. "generated from the interface found in " .. fn .. " -- result is in public domain */")
50if arg[2] then
51	print("/* from " .. table.concat(table.pack(table.unpack(arg, 2)), ' ') .. " */")
52end
53print(content)
54