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
..
49
50
51
52
53
54
55
56
57
58
59
60
61
62
..
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
-- vim: ft=terra
return function(tbl)
local options = terralib.types.newstruct('options') do
local flags = '' for _,d in pairs(tbl) do flags = flags .. d[1] end
local helpstr = 'usage: parsav [-' .. flags .. '] [<arg>...]\n'
options.entries = {
{field = 'arglist', type = lib.mem.ptr(rawstring)}
}
local shortcases, longcases, init, verifiers = {}, {}, {}, {}
local self = symbol(&options)
local arg = symbol(rawstring)
local idx = symbol(uint)
local argv = symbol(&rawstring)
local argc = symbol(int)
local optstack = symbol(intptr)
local skip = label()
local sanitize = function(s) return s:gsub('_','-') end
for o,desc in pairs(tbl) do
local consume = desc[3] or 0
options.entries[#options.entries + 1] = {
field = o, type = (consume > 0) and &rawstring or bool
}
helpstr = helpstr .. string.format(' -%s --%s: %s\n',
desc[1], sanitize(o), desc[2])
end
for o,desc in pairs(tbl) do
local flag = desc[1]
local consume = desc[3] or 0
init[#init + 1] = quote [self].[o] = [(consume > 0 and `nil) or false] end
local ch if consume > 0 then
ch = quote
[self].[o] = argv+(idx+1+optstack)
optstack = optstack + consume
end
verifiers[#verifiers+1] = quote
var terminus = argv + argc
if [self].[o] ~= nil and [self].[o] >= terminus then
lib.bail(['missing argument for command line option ' .. sanitize(o)])
end
end
else ch = quote
[self].[o] = true
end end
shortcases[#shortcases + 1] = quote
case [int8]([string.byte(flag)]) then [ch] end
end
longcases[#longcases + 1] = quote
................................................................................
end
end
terra options:free() self.arglist:free() end
options.methods.parse = terra([self], [argc], [argv])
[init]
var parseopts = true
var [optstack] = 0
self.arglist = lib.mem.heapa(rawstring, argc)
var finalargc = 0
for [idx]=1,argc do
var [arg] = argv[idx]
if optstack > 0 then optstack = optstack - 1 goto [skip] end
if arg[0] == @'-' and parseopts then
if arg[1] == @'-' then -- long option
................................................................................
switch arg[j] do [shortcases] end
j = j + 1
end
end
else
self.arglist.ptr[finalargc] = arg
finalargc = finalargc + 1
end
::[skip]::
end
[verifiers]
if finalargc == 0 then self.arglist:free()
else self.arglist:resize(finalargc) end
end
options.helptxt = helpstr
end
return options
end
|
|
>
>
|
>
|
>
|
>
|
>
|
>
>
>
>
>
>
>
>
>
>
|
|
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
..
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
-- vim: ft=terra
return function(tbl,opts)
opts = opts or {}
local options = terralib.types.newstruct('options') do
local flags = '' for _,d in pairs(tbl) do flags = flags .. d[1] end
local flagstr = '[-' .. flags .. ']'
local helpstr = '\n'
options.entries = {
{field = 'arglist', type = lib.mem.ptr(rawstring)}
}
local shortcases, longcases, init, verifiers = {}, {}, {}, {}
local self = symbol(&options)
local arg = symbol(rawstring)
local idx = symbol(uint)
local argv = symbol(&rawstring)
local argc = symbol(int)
local optstack = symbol(intptr)
local subcmd = symbol(intptr)
local skip = label()
local sanitize = function(s) return s:gsub('_','-') end
for o,desc in pairs(tbl) do
local consume = desc.consume or 0
local incr = desc.inc or 0
options.entries[#options.entries + 1] = {
field = o, type = (consume > 0) and &rawstring or
(incr > 0) and uint or bool
}
helpstr = helpstr .. string.format(' -%s --%s: %s\n',
desc[1], sanitize(o), desc[2])
end
for o,desc in pairs(tbl) do
local flag = desc[1]
local consume = desc.consume or 0
local incr = desc.inc or 0
init[#init + 1] = quote [self].[o] = [
(consume > 0 and `nil) or
(incr > 0 and `0 ) or false
] end
local ch if consume > 0 then
ch = quote
[self].[o] = argv+(idx+1+optstack)
optstack = optstack + consume
end
verifiers[#verifiers+1] = quote
var terminus = argv + argc
if [self].[o] ~= nil and [self].[o] >= terminus then
lib.bail(['missing argument for command line option ' .. sanitize(o)])
end
end
elseif incr > 0 then
ch = quote [self].[o] = [self].[o] + incr end
else ch = quote
[self].[o] = true
end end
shortcases[#shortcases + 1] = quote
case [int8]([string.byte(flag)]) then [ch] end
end
longcases[#longcases + 1] = quote
................................................................................
end
end
terra options:free() self.arglist:free() end
options.methods.parse = terra([self], [argc], [argv])
[init]
var parseopts = true
var [optstack] = 0
var [subcmd] = [ opts.subcmd or 0 ]
self.arglist = lib.mem.heapa(rawstring, argc)
var finalargc = 0
for [idx]=1,argc do
var [arg] = argv[idx]
if optstack > 0 then optstack = optstack - 1 goto [skip] end
if arg[0] == @'-' and parseopts then
if arg[1] == @'-' then -- long option
................................................................................
switch arg[j] do [shortcases] end
j = j + 1
end
end
else
self.arglist.ptr[finalargc] = arg
finalargc = finalargc + 1
if subcmd > 0 then
subcmd = subcmd - 1
if subcmd == 0 then parseopts = false end
end
end
::[skip]::
end
[verifiers]
if finalargc == 0 then self.arglist:free()
else self.arglist:resize(finalargc) end
end
options.helptxt = { opts = helpstr, flags = flagstr }
end
return options
end
|