tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Consistent layout for file lists in distrib/sets/lists
Hi,
since I regularly add test files to usr.bin/make/unit-tests, I need to
update distrib/sets/lists/tests/mi every few days. As a side task, I
wrote a beautifier for these file lists.
Would src/distrib/sets be a good place for this utility? How would it
fit with the existing tools? I briefly looked at them but couldn't find
anything similar.
I intend to extend the utility with a few command line options, such as
syncing the list with the current state of a directory, automatically
adding new entries and marking deleted entries as obsolete.
Thoughts?
Roland
#! /usr/bin/lua
-- $NetBSD$
--
-- Align the lines of the mi file so that all lines from the same directory
-- have the other fields at the same indentation. Sort the lines and remove
-- duplicate lines.
--
-- The second field is indented to at least column 56 since only few test
-- filenames are shorter. This reduces the number of times that the fields
-- "jump" horizontally.
local function read_mi()
local head = {}
local entries = {}
local mi = assert(io.open("mi", "r"))
local lineno = 0
for line in mi:lines() do
lineno = lineno + 1
local fullname, dirname, basename, category, flags =
line:match("^((%./%g+)/([^/%s]+))%s+(%g+)%s+(%g+)$")
if dirname == nil then
fullname, dirname, basename, category =
line:match("^((%./%g+)/([^/%s]+))%s+(%g+)$")
end
if dirname ~= nil then
table.insert(entries, {
fullname = fullname,
dirname = dirname,
basename = basename,
category = category,
flags = flags
})
elseif line:match("^#") then
table.insert(head, line)
else
error(string.format("line %d: %s\n", lineno, line))
end
end
mi:close()
return head, entries
end
local function roundup(n, mul)
return (n + mul) // mul * mul
end
local function normalize_mi(entries)
-- Calculate the maximum pathname length per directory.
local pathlen = {}
for _, entry in ipairs(entries) do
local len = math.max(pathlen[entry.dirname] or 0, #entry.fullname)
pathlen[entry.dirname] = len
end
-- Calculate the field separators for each entry.
for _, entry in ipairs(entries) do
local entrylen = roundup(#entry.fullname, 8)
local grouplen = math.max(56, roundup(pathlen[entry.dirname], 8))
entry.fullname_sep = string.rep("\t", 1 + (grouplen - entrylen) // 8)
entry.category_sep = string.rep("\t", (24 + 7 - #entry.category) // 8)
end
table.sort(entries, function(a, b)
if a.fullname ~= b.fullname then return a.fullname < b.fullname end
if a.category ~= b.category then return a.category < b.category end
return a.flags < b.flags
end)
end
-- Write the normalized mi file.
--
-- Duplicate lines are skipped. This allows to append arbitrary lines to
-- the end of the file and have them cleaned up automatically.
local function write_mi(head, entries)
local f = assert(io.open("mi.fixed", "w"))
for _, line in ipairs(head) do
f:write(line, "\n")
end
local prev_line = ""
for _, entry in ipairs(entries) do
local fullname = entry.fullname
local category = entry.fullname_sep .. entry.category
local flags = entry.flags and entry.category_sep .. entry.flags or ""
local line = fullname .. category .. flags
if line ~= prev_line then
prev_line = line
f:write(line, "\n")
end
end
f:close()
end
local function format_mi()
local head, entries = read_mi()
normalize_mi(entries)
write_mi(head, entries)
end
format_mi()
Home |
Main Index |
Thread Index |
Old Index