blob: de19c7708673f01ba36db9dd6a8d08bec56b5c27 (
plain)
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
|
local function help(opts)
io.write(Path:new(arg[0]):name())
io.write(" ")
for _, v in ipairs(opts) do
if v.kind == nil then
io.write("[" .. v.name .. "] ")
end
end
io.write("\n")
local max_width = 0
for _, v in ipairs(opts) do
if v.kind ~= nil then
max_width = math.max(v.name:len(), max_width)
end
end
for _, v in ipairs(opts) do
if v.kind == nil then
goto next
end
if v.kind == 'property' then
io.write("\t" .. "--" .. v.name .. " <value>")
elseif v.kind == 'flag' then
io.write("\t" .. "--" .. v.name .. " ")
end
if v.description ~= nil then
io.write(string.rep(" ", max_width - v.name:len()) .. " " .. "-- ")
if v.required then
io.write("(required) ")
end
io.write(v.description)
end
io.write("\n")
::next::
end
os.exit()
end
return function (opts)
local args = {}
local current_index = 1
local current_flag = nil
local params = {}
for _, v in ipairs(opts) do
if v.kind ~= nil then
params[v.name] = v
args[v.name] = v.default
else
params[#params + 1] = v
end
end
for _, value in ipairs(arg) do
local key = nil
if current_flag == nil then
local flag = value:flag_name()
if flag == nil then
local option = params[current_index]
current_index = current_index + 1
if option == nil then
print("error: too many arguments")
help(opts)
end
key = option.name
else
local option = params[flag]
if option == nil and opts.strict then
print("error: unknown flag '" .. flag .. "'")
help(opts)
elseif option == nil then
option = { name = flag, kind = 'property' }
params[flag] = option
end
if option.kind == 'flag' then
key = flag
value = true
else
current_flag = flag
goto next
end
end
else
local option = params[current_flag]
key = option.name
current_flag = nil
end
args[key] = value
::next::
end
for _, option in ipairs(opts) do
if (option.kind == nil or option.required) and args[option.name] == nil then
print("error: missing argument '" .. option.name .. "'")
help(opts)
end
end
return args
end
|