parsav  Diff

Differences From Artifact [c7f162fae3]:

To Artifact [bad20dd1d0]:


     5      5   		local helpstr = 'usage: parsav [-' .. flags .. '] [<arg>...]\n'
     6      6   		options.entries = {
     7      7   			{field = 'arglist', type = lib.mem.ptr(rawstring)}
     8      8   		}
     9      9   		local shortcases, longcases, init = {}, {}, {}
    10     10   		local self = symbol(&options)
    11     11   		local arg = symbol(rawstring)
           12  +		local idxo = symbol(uint)
    12     13   		local skip = label()
           14  +		local sanitize = function(s) return s:gsub('_','-') end
    13     15   		for o,desc in pairs(tbl) do
           16  +			local consume = desc[3] or 0
    14     17   			options.entries[#options.entries + 1] = {
    15         -				field = o, type = bool
           18  +				field = o, type = (consume > 0) and uint or bool
    16     19   			}
    17     20   			helpstr = helpstr .. string.format('    -%s --%s: %s\n',
    18         -				desc[1], o, desc[2])
           21  +				desc[1], sanitize(o), desc[2])
    19     22   		end
    20     23   		for o,desc in pairs(tbl) do
    21     24   			local flag = desc[1]
    22         -			init[#init + 1] = quote [self].[o] = false end
           25  +			local consume = desc[3] or 0
           26  +			init[#init + 1] = quote [self].[o] = [consume > 0 and 0 or false] end
           27  +			local ch if consume > 0 then ch = quote
           28  +				[self].[o] = idxo
           29  +				idxo = idxo + consume
           30  +			end else ch = quote
           31  +				[self].[o] = true
           32  +			end end
    23     33   			shortcases[#shortcases + 1] = quote
    24         -				case [int8]([string.byte(flag)]) then [self].[o] = true end
           34  +				case [int8]([string.byte(flag)]) then [ch] end
    25     35   			end
    26     36   			longcases[#longcases + 1] = quote
    27         -				if lib.str.cmp([arg]+2, o) == 0 then
    28         -					[self].[o] = true
    29         -					goto [skip]
    30         -				end
           37  +				if lib.str.cmp([arg]+2, [sanitize(o)]) == 0 then [ch] goto [skip] end
    31     38   			end
    32     39   		end
           40  +		terra options:free() self.arglist:free() end
    33     41   		options.methods.parse = terra([self], argc: int, argv: &rawstring)
    34     42   			[init]
    35     43   			var parseopts = true
           44  +			var [idxo] = 1
    36     45   			self.arglist = lib.mem.heapa(rawstring, argc)
    37     46   			var finalargc = 0
    38         -			for i=0,argc do
           47  +			for i=1,argc do
    39     48   				var [arg] = argv[i]
    40     49   				if arg[0] == ('-')[0] and parseopts then
    41     50   					if arg[1] == ('-')[0] then -- long option
    42     51   						if arg[2] == 0 then -- last option
    43     52   							parseopts = false
    44     53   						else [longcases] end
    45     54   					else -- short options