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