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
|
local lpeg = require "lpeg"
local PKGBASE = "pkgbase"
local PKGNAME = "pkgname"
local modes = {
[PKGBASE] = PKGBASE,
[PKGNAME] = PKGNAME,
}
function apply (state, method, ...)
if state[method] then
return state[method](state, ...)
end
return nil
end
local identifier = lpeg.R"az" + lpeg.R"09" + lpeg.S"@+_"
identifier = identifier * (identifier + lpeg.S".-")^0
local whitespace = lpeg.S" \t"^0
local newline = lpeg.P"\r\n" + "\n"
local rest = (1 - newline)^0
local definition = lpeg.Cc"definition" * whitespace * lpeg.C(identifier) * whitespace * "=" * whitespace * lpeg.C(rest)
local comment = lpeg.Cc"comment" * lpeg.P"#" * whitespace * lpeg.C(rest)
local empty = lpeg.Cc"empty" * whitespace
local invalid = lpeg.Cc"invalid" * lpeg.C(rest)
local line = lpeg.Carg(1) * (definition + comment + empty + invalid) / apply * newline
local capture = lpeg.Ct(line^0) * -lpeg.P(1)
local
function srcinfo (text, options)
options = options or {}
mode = modes[options.mode] or PKGNAME
return capture:match(
text,
nil,
{
mode = mode,
base = nil,
current = nil,
definition = function (self, name, value)
if name == PKGBASE then
self.base = {name=value}
self.current = self.base
if self.mode == PKGBASE then
self.base.packages = {}
return self.current
end
elseif name == PKGNAME then
self.current = {name=value}
if self.mode == PKGNAME then
self.current.base = self.base
return self.current
else
table.insert(self.base.packages, self.current)
end
else
local current_value = self.current[name]
if type(current_value) == "table" then
table.insert(current_value, value)
elseif current_value ~= nil then
self.current[name] = {current_value, value}
else
self.current[name] = value
end
end
end,
comment = function (self, text) end,
empty = function (self) end,
invalid = function (self, text) return text end,
}
)
end
return srcinfo
|