Posix Get Opt

lua-users home
wiki

If you want real POSIX getopt, use real POSIX! See [luaposix] for a binding to getopt_long.

Pure Lua

The following should behave exactly according to the [POSIX/SUS definition], except that the return value differs slightly so that there's no global state.

Usage

--

-- opt is either the option character, "?", or ":".

--

-- If opt is the option character, arg is either a string or false--if optstring

-- did not specify a required argument.

--

-- If opt is either "?" or ":", then arg is the unknown option or the option

-- lacking the required argument. Like the standard says, there's really only

-- one scenario for ":" to ever be returned. And per the standard, unless

-- optstring begins with a colon, "?" is returned instead.

--

for opt, arg in getopt(":a:b", ...) do

        print("opt:", opt, "arg:", arg)

end

Code

--

-- getopt(":a:b", ...) -- works just like getopt(3).

--

-- Send bug reports to william@25thandClement.com.

--

function getopt(optstring, ...)

	local opts = { }

	local args = { ... }



	for optc, optv in optstring:gmatch"(%a)(:?)" do

		opts[optc] = { hasarg = optv == ":" }

	end



	return coroutine.wrap(function()

		local yield = coroutine.yield

		local i = 1



		while i <= #args do

			local arg = args[i]



			i = i + 1



			if arg == "--" then

				break

			elseif arg:sub(1, 1) == "-" then

				for j = 2, #arg do

					local opt = arg:sub(j, j)



					if opts[opt] then

						if opts[opt].hasarg then

							if j == #arg then

								if args[i] then

									yield(opt, args[i])

									i = i + 1

								elseif optstring:sub(1, 1) == ":" then

									yield(':', opt)

								else

									yield('?', opt)

								end

							else

								yield(opt, arg:sub(j + 1))

							end



							break

						else

							yield(opt, false)

						end

					else

						yield('?', opt)

					end

				end

			else

				yield(false, arg)

			end

		end



		for i = i, #args do

			yield(false, args[i])

		end

	end)

end

See Also


RecentChanges · preferences
edit · history
Last edited April 10, 2013 6:39 am GMT (diff)