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 = {}, {}, {}
local self = symbol(&options)
local arg = symbol(rawstring)
local skip = label()
for o,desc in pairs(tbl) do
options.entries[#options.entries + 1] = {
field = o, type = bool
}
helpstr = helpstr .. string.format(' -%s --%s: %s\n',
desc[1], o, desc[2])
end
for o,desc in pairs(tbl) do
local flag = desc[1]
init[#init + 1] = quote [self].[o] = false end
shortcases[#shortcases + 1] = quote
case [int8]([string.byte(flag)]) then [self].[o] = true end
end
longcases[#longcases + 1] = quote
if lib.str.cmp([arg]+2, o) == 0 then
[self].[o] = true
goto [skip]
end
end
end
options.methods.parse = terra([self], argc: int, argv: &rawstring)
[init]
var parseopts = true
self.arglist = lib.mem.heapa(rawstring, argc)
var finalargc = 0
for i=0,argc do
var [arg] = argv[i]
if arg[0] == ('-')[0] and parseopts then
if arg[1] == ('-')[0] then -- long option
if arg[2] == 0 then -- last option
parseopts = false
else [longcases] end
else -- short options
var j = 1
while arg[j] ~= 0 do
switch arg[j] do [shortcases] end
j = j + 1
end
end
else
self.arglist.ptr[finalargc] = arg
finalargc = finalargc + 1
end
::[skip]::
end
if finalargc == 0 then self.arglist:free()
else self.arglist:resize(finalargc) end
end
options.helptxt = helpstr
end
return options
end