1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#!/usr/bin/env lua
--- For example:
---
--- $ ./headers.lua db/c.lua C23
--- assert.h
--- ctype.h
--- ...
local public = {}
local private = {}
private.tags = {}
private.tags_lookup = {}
private.headers = {}
local tag do
local methods = {}
function methods:add (header)
table.insert(self.headers_, header)
end
local function headers (self)
local result = {}
for _, value in pairs(self.headers_) do
if type(value) == "function" then
value(result)
else
table.insert(result, value)
end
end
return result
end
local mt = {
__tostring=function (self) return self.name end,
__index=function (self, key)
if key == "headers" then
return headers(self)
end
return methods[key]
end,
}
function tag (name)
return setmetatable({name=name, headers_={}}, mt)
end
end
local alias do
local mt = {
__tostring = function (self) return string.format("%s (%s)", self.name, tostring(self.tag)) end,
__index = function (self, key) return self.tag[key] end,
}
function alias (name, tag)
return setmetatable({name=name, tag=tag}, mt)
end
end
local function include (source)
return function (target)
for _, header in pairs(source.headers) do
table.insert(target, header)
end
end
end
local function remove (header)
return function (target)
for key, value in pairs(target) do
if value == header then
table.remove(target, key)
end
end
end
end
local function get_or_create_tag (name)
local found = private.tags_lookup[name]
if not found then
found = tag(name)
table.insert(private.tags, found)
private.tags_lookup[name] = found
end
return found
end
function public.aliases (name)
local tag = get_or_create_tag(name)
return function (aliases)
for _, name in pairs(aliases) do
private.tags_lookup[name] = alias(name, tag)
end
end
end
function public.headers (name)
local tag = get_or_create_tag(name)
return function (filenames)
for _, header in pairs(filenames) do
tag:add(header)
end
end
end
function public.include (tag)
tag = private.tags_lookup[tag] or error("invalid tag: " .. tag, 2)
return include(tag)
end
function public.remove (header)
return remove(header)
end
local db = loadfile(arg[1], nil, public)
db()
if arg[2] then
local tag = private.tags_lookup[arg[2]]
for _, header in pairs(tag.headers) do
print(header)
end
else
for _, tag in pairs(private.tags_lookup) do
print(tag)
end
end
|