argparse.lua 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114
  1. local Parser, Command, Argument, Option
  2. local function require_30log()
  3. -------------------------------------------------------------------------------
  4. local assert = assert
  5. local pairs = pairs
  6. local type = type
  7. local tostring = tostring
  8. local setmetatable = setmetatable
  9. local baseMt = {}
  10. local _instances = setmetatable({},{__mode='k'})
  11. local _classes = setmetatable({},{__mode='k'})
  12. local class
  13. local function deep_copy(t, dest, aType)
  14. local t = t or {}
  15. local r = dest or {}
  16. for k,v in pairs(t) do
  17. if aType and type(v)==aType then
  18. r[k] = v
  19. elseif not aType then
  20. if type(v) == 'table' and k ~= "__index" then
  21. r[k] = deep_copy(v)
  22. else
  23. r[k] = v
  24. end
  25. end
  26. end
  27. return r
  28. end
  29. local function instantiate(self,...)
  30. assert(_classes[self], 'new() should be called from a class.')
  31. local instance = deep_copy(self)
  32. _instances[instance] = tostring(instance)
  33. setmetatable(instance,self)
  34. if self.__init then
  35. if type(self.__init) == 'table' then
  36. deep_copy(self.__init, instance)
  37. else
  38. self.__init(instance, ...)
  39. end
  40. end
  41. return instance
  42. end
  43. local function extends(self,extra_params)
  44. local heir = {}
  45. _classes[heir] = tostring(heir)
  46. deep_copy(extra_params, deep_copy(self, heir))
  47. heir.__index = heir
  48. heir.super = self
  49. return setmetatable(heir,self)
  50. end
  51. baseMt = {
  52. __call = function (self,...)
  53. return self:new(...)
  54. end,
  55. __tostring = function(self,...)
  56. if _instances[self] then
  57. return
  58. ('object(of %s):<%s>')
  59. :format((rawget(getmetatable(self),'__name') or '?'), _instances[self])
  60. end
  61. return
  62. _classes[self] and
  63. ('class(%s):<%s>')
  64. :format((rawget(self,'__name') or '?'),_classes[self]) or
  65. self
  66. end
  67. }
  68. class = function(attr)
  69. local c = deep_copy(attr)
  70. _classes[c] = tostring(c)
  71. c.include = function(self,include)
  72. assert(_classes[self], 'Mixins can only be used on classes.')
  73. return deep_copy(include, self, 'function')
  74. end
  75. c.new = instantiate
  76. c.extends = extends
  77. c.__index = c
  78. c.__call = baseMt.__call
  79. c.__tostring = baseMt.__tostring
  80. c.is = function(self, kind)
  81. local super
  82. while true do
  83. super = getmetatable(super or self)
  84. if super == kind or super == nil then break end
  85. end
  86. return kind and (super == kind)
  87. end
  88. return setmetatable(c, baseMt)
  89. end
  90. return class
  91. -------------------------------------------------------------------------------
  92. end
  93. do -- Create classes with setters
  94. local class = require_30log()
  95. local function add_setters(cl, fields)
  96. for field, setter in pairs(fields) do
  97. cl[field] = function(self, value)
  98. setter(self, value)
  99. self["_"..field] = value
  100. return self
  101. end
  102. end
  103. cl.__init = function(self, ...)
  104. return self(...)
  105. end
  106. cl.__call = function(self, ...)
  107. local name_or_options
  108. for i=1, select("#", ...) do
  109. name_or_options = select(i, ...)
  110. if type(name_or_options) == "string" then
  111. if self._aliases then
  112. table.insert(self._aliases, name_or_options)
  113. end
  114. if not self._aliases or not self._name then
  115. self._name = name_or_options
  116. end
  117. elseif type(name_or_options) == "table" then
  118. for field in pairs(fields) do
  119. if name_or_options[field] ~= nil then
  120. self[field](self, name_or_options[field])
  121. end
  122. end
  123. end
  124. end
  125. return self
  126. end
  127. return cl
  128. end
  129. local typecheck = setmetatable({}, {
  130. __index = function(self, type_)
  131. local typechecker_factory = function(field)
  132. return function(_, value)
  133. if type(value) ~= type_ then
  134. error(("bad field '%s' (%s expected, got %s)"):format(field, type_, type(value)))
  135. end
  136. end
  137. end
  138. self[type_] = typechecker_factory
  139. return typechecker_factory
  140. end
  141. })
  142. local function aliased_name(self, name)
  143. typecheck.string "name" (self, name)
  144. table.insert(self._aliases, name)
  145. end
  146. local function aliased_aliases(self, aliases)
  147. typecheck.table "aliases" (self, aliases)
  148. if not self._name then
  149. self._name = aliases[1]
  150. end
  151. end
  152. local function parse_boundaries(boundaries)
  153. if tonumber(boundaries) then
  154. return tonumber(boundaries), tonumber(boundaries)
  155. end
  156. if boundaries == "*" then
  157. return 0, math.huge
  158. end
  159. if boundaries == "+" then
  160. return 1, math.huge
  161. end
  162. if boundaries == "?" then
  163. return 0, 1
  164. end
  165. if boundaries:match "^%d+%-%d+$" then
  166. local min, max = boundaries:match "^(%d+)%-(%d+)$"
  167. return tonumber(min), tonumber(max)
  168. end
  169. if boundaries:match "^%d+%+$" then
  170. local min = boundaries:match "^(%d+)%+$"
  171. return tonumber(min), math.huge
  172. end
  173. end
  174. local function boundaries(field)
  175. return function(self, value)
  176. local min, max = parse_boundaries(value)
  177. if not min then
  178. error(("bad field '%s'"):format(field))
  179. end
  180. self["_min"..field], self["_max"..field] = min, max
  181. end
  182. end
  183. local function convert(self, value)
  184. if type(value) ~= "function" then
  185. if type(value) ~= "table" then
  186. error(("bad field 'convert' (function or table expected, got %s)"):format(type(value)))
  187. end
  188. end
  189. end
  190. local function argname(self, value)
  191. if type(value) ~= "string" then
  192. if type(value) ~= "table" then
  193. error(("bad field 'argname' (string or table expected, got %s)"):format(type(value)))
  194. end
  195. end
  196. end
  197. local function add_help(self, param)
  198. if self._has_help then
  199. table.remove(self._options)
  200. self._has_help = false
  201. end
  202. if param then
  203. local help = self:flag()
  204. :description "Show this help message and exit. "
  205. :action(function()
  206. io.stdout:write(self:get_help() .. "\r\n")
  207. os.exit(0)
  208. end)(param)
  209. if not help._name then
  210. help "-h" "--help"
  211. end
  212. self._has_help = true
  213. end
  214. end
  215. Parser = add_setters(class {
  216. __name = "Parser",
  217. _arguments = {},
  218. _options = {},
  219. _commands = {},
  220. _mutexes = {},
  221. _require_command = true
  222. }, {
  223. name = typecheck.string "name",
  224. description = typecheck.string "description",
  225. epilog = typecheck.string "epilog",
  226. require_command = typecheck.boolean "require_command",
  227. usage = typecheck.string "usage",
  228. help = typecheck.string "help",
  229. add_help = add_help
  230. })
  231. Command = add_setters(Parser:extends {
  232. __name = "Command",
  233. _aliases = {}
  234. }, {
  235. name = aliased_name,
  236. aliases = aliased_aliases,
  237. description = typecheck.string "description",
  238. epilog = typecheck.string "epilog",
  239. target = typecheck.string "target",
  240. require_command = typecheck.boolean "require_command",
  241. action = typecheck["function"] "action",
  242. usage = typecheck.string "usage",
  243. help = typecheck.string "help",
  244. add_help = add_help
  245. })
  246. Argument = add_setters(class {
  247. __name = "Argument",
  248. _minargs = 1,
  249. _maxargs = 1,
  250. _mincount = 1,
  251. _maxcount = 1,
  252. _defmode = "unused",
  253. _show_default = true
  254. }, {
  255. name = typecheck.string "name",
  256. description = typecheck.string "description",
  257. target = typecheck.string "target",
  258. args = boundaries "args",
  259. default = typecheck.string "default",
  260. defmode = typecheck.string "defmode",
  261. convert = convert,
  262. argname = argname,
  263. show_default = typecheck.boolean "show_default"
  264. })
  265. Option = add_setters(Argument:extends {
  266. __name = "Option",
  267. _aliases = {},
  268. _mincount = 0,
  269. _overwrite = true
  270. }, {
  271. name = aliased_name,
  272. aliases = aliased_aliases,
  273. description = typecheck.string "description",
  274. target = typecheck.string "target",
  275. args = boundaries "args",
  276. count = boundaries "count",
  277. default = typecheck.string "default",
  278. defmode = typecheck.string "defmode",
  279. convert = convert,
  280. overwrite = typecheck.boolean "overwrite",
  281. action = typecheck["function"] "action",
  282. argname = argname,
  283. show_default = typecheck.boolean "show_default"
  284. })
  285. end
  286. function Argument:_get_argument_list()
  287. local buf = {}
  288. local i = 1
  289. while i <= math.min(self._minargs, 3) do
  290. local argname = self:_get_argname(i)
  291. if self._default and self._defmode:find "a" then
  292. argname = "[" .. argname .. "]"
  293. end
  294. table.insert(buf, argname)
  295. i = i+1
  296. end
  297. while i <= math.min(self._maxargs, 3) do
  298. table.insert(buf, "[" .. self:_get_argname(i) .. "]")
  299. i = i+1
  300. if self._maxargs == math.huge then
  301. break
  302. end
  303. end
  304. if i < self._maxargs then
  305. table.insert(buf, "...")
  306. end
  307. return buf
  308. end
  309. function Argument:_get_usage()
  310. local usage = table.concat(self:_get_argument_list(), " ")
  311. if self._default and self._defmode:find "u" then
  312. if self._maxargs > 1 or (self._minargs == 1 and not self._defmode:find "a") then
  313. usage = "[" .. usage .. "]"
  314. end
  315. end
  316. return usage
  317. end
  318. function Argument:_get_type()
  319. if self._maxcount == 1 then
  320. if self._maxargs == 0 then
  321. return "flag"
  322. elseif self._maxargs == 1 and (self._minargs == 1 or self._mincount == 1) then
  323. return "arg"
  324. else
  325. return "multiarg"
  326. end
  327. else
  328. if self._maxargs == 0 then
  329. return "counter"
  330. elseif self._maxargs == 1 and self._minargs == 1 then
  331. return "multicount"
  332. else
  333. return "twodimensional"
  334. end
  335. end
  336. end
  337. -- Returns placeholder for `narg`-th argument.
  338. function Argument:_get_argname(narg)
  339. local argname = self._argname or self:_get_default_argname()
  340. if type(argname) == "table" then
  341. return argname[narg]
  342. else
  343. return argname
  344. end
  345. end
  346. function Argument:_get_default_argname()
  347. return "<" .. self._name .. ">"
  348. end
  349. function Option:_get_default_argname()
  350. return "<" .. self:_get_default_target() .. ">"
  351. end
  352. -- Returns label to be shown in the help message.
  353. function Argument:_get_label()
  354. return self._name
  355. end
  356. function Option:_get_label()
  357. local variants = {}
  358. local argument_list = self:_get_argument_list()
  359. table.insert(argument_list, 1, nil)
  360. for _, alias in ipairs(self._aliases) do
  361. argument_list[1] = alias
  362. table.insert(variants, table.concat(argument_list, " "))
  363. end
  364. return table.concat(variants, ", ")
  365. end
  366. function Command:_get_label()
  367. return table.concat(self._aliases, ", ")
  368. end
  369. function Argument:_get_description()
  370. if self._default and self._show_default then
  371. if self._description then
  372. return ("%s (default: %s)"):format(self._description, self._default)
  373. else
  374. return ("default: %s"):format(self._default)
  375. end
  376. else
  377. return self._description or ""
  378. end
  379. end
  380. function Command:_get_description()
  381. return self._description or ""
  382. end
  383. function Option:_get_usage()
  384. local usage = self:_get_argument_list()
  385. table.insert(usage, 1, self._name)
  386. usage = table.concat(usage, " ")
  387. if self._mincount == 0 or self._default then
  388. usage = "[" .. usage .. "]"
  389. end
  390. return usage
  391. end
  392. function Option:_get_default_target()
  393. local res
  394. for _, alias in ipairs(self._aliases) do
  395. if alias:sub(1, 1) == alias:sub(2, 2) then
  396. res = alias:sub(3)
  397. break
  398. end
  399. end
  400. res = res or self._name:sub(2)
  401. return (res:gsub("-", "_"))
  402. end
  403. function Option:_is_vararg()
  404. return self._maxargs ~= self._minargs
  405. end
  406. function Parser:_get_fullname()
  407. local parent = self._parent
  408. local buf = {self._name}
  409. while parent do
  410. table.insert(buf, 1, parent._name)
  411. parent = parent._parent
  412. end
  413. return table.concat(buf, " ")
  414. end
  415. function Parser:_update_charset(charset)
  416. charset = charset or {}
  417. for _, command in ipairs(self._commands) do
  418. command:_update_charset(charset)
  419. end
  420. for _, option in ipairs(self._options) do
  421. for _, alias in ipairs(option._aliases) do
  422. charset[alias:sub(1, 1)] = true
  423. end
  424. end
  425. return charset
  426. end
  427. function Parser:argument(...)
  428. local argument = Argument:new(...)
  429. table.insert(self._arguments, argument)
  430. return argument
  431. end
  432. function Parser:option(...)
  433. local option = Option:new(...)
  434. if self._has_help then
  435. table.insert(self._options, #self._options, option)
  436. else
  437. table.insert(self._options, option)
  438. end
  439. return option
  440. end
  441. function Parser:flag(...)
  442. return self:option():args(0)(...)
  443. end
  444. function Parser:command(...)
  445. local command = Command:new():add_help(true)(...)
  446. command._parent = self
  447. table.insert(self._commands, command)
  448. return command
  449. end
  450. function Parser:mutex(...)
  451. local options = {...}
  452. for i, option in ipairs(options) do
  453. assert(getmetatable(option) == Option, ("bad argument #%d to 'mutex' (Option expected)"):format(i))
  454. end
  455. table.insert(self._mutexes, options)
  456. return self
  457. end
  458. local max_usage_width = 70
  459. local usage_welcome = "Usage: "
  460. function Parser:get_usage()
  461. if self._usage then
  462. return self._usage
  463. end
  464. local lines = {usage_welcome .. self:_get_fullname()}
  465. local function add(s)
  466. if #lines[#lines]+1+#s <= max_usage_width then
  467. lines[#lines] = lines[#lines] .. " " .. s
  468. else
  469. lines[#lines+1] = (" "):rep(#usage_welcome) .. s
  470. end
  471. end
  472. -- This can definitely be refactored into something cleaner
  473. local mutex_options = {}
  474. local vararg_mutexes = {}
  475. -- First, put mutexes which do not contain vararg options and remember those which do
  476. for _, mutex in ipairs(self._mutexes) do
  477. local buf = {}
  478. local is_vararg = false
  479. for _, option in ipairs(mutex) do
  480. if option:_is_vararg() then
  481. is_vararg = true
  482. end
  483. table.insert(buf, option:_get_usage())
  484. mutex_options[option] = true
  485. end
  486. local repr = "(" .. table.concat(buf, " | ") .. ")"
  487. if is_vararg then
  488. table.insert(vararg_mutexes, repr)
  489. else
  490. add(repr)
  491. end
  492. end
  493. -- Second, put regular options
  494. for _, option in ipairs(self._options) do
  495. if not mutex_options[option] and not option:_is_vararg() then
  496. add(option:_get_usage())
  497. end
  498. end
  499. -- Put positional arguments
  500. for _, argument in ipairs(self._arguments) do
  501. add(argument:_get_usage())
  502. end
  503. -- Put mutexes containing vararg options
  504. for _, mutex_repr in ipairs(vararg_mutexes) do
  505. add(mutex_repr)
  506. end
  507. for _, option in ipairs(self._options) do
  508. if not mutex_options[option] and option:_is_vararg() then
  509. add(option:_get_usage())
  510. end
  511. end
  512. if #self._commands > 0 then
  513. if self._require_command then
  514. add("<command>")
  515. else
  516. add("[<command>]")
  517. end
  518. add("...")
  519. end
  520. return table.concat(lines, "\r\n")
  521. end
  522. local margin_len = 3
  523. local margin_len2 = 25
  524. local margin = (" "):rep(margin_len)
  525. local margin2 = (" "):rep(margin_len2)
  526. local function make_two_columns(s1, s2)
  527. if s2 == "" then
  528. return margin .. s1
  529. end
  530. s2 = s2:gsub("[\r\n][\r\n]?", function(sub)
  531. if #sub == 1 or sub == "\r\n" then
  532. return "\r\n" .. margin2
  533. else
  534. return "\r\n\r\n" .. margin2
  535. end
  536. end)
  537. if #s1 < (margin_len2-margin_len) then
  538. return margin .. s1 .. (" "):rep(margin_len2-margin_len-#s1) .. s2
  539. else
  540. return margin .. s1 .. "\r\n" .. margin2 .. s2
  541. end
  542. end
  543. function Parser:get_help()
  544. if self._help then
  545. return self._help
  546. end
  547. local blocks = {self:get_usage()}
  548. if self._description then
  549. table.insert(blocks, self._description)
  550. end
  551. local labels = {"Arguments: ", "Options: ", "Commands: "}
  552. for i, elements in ipairs{self._arguments, self._options, self._commands} do
  553. if #elements > 0 then
  554. local buf = {labels[i]}
  555. for _, element in ipairs(elements) do
  556. table.insert(buf, make_two_columns(element:_get_label(), element:_get_description()))
  557. end
  558. table.insert(blocks, table.concat(buf, "\r\n"))
  559. end
  560. end
  561. if self._epilog then
  562. table.insert(blocks, self._epilog)
  563. end
  564. return table.concat(blocks, "\r\n\r\n")
  565. end
  566. local function get_tip(context, wrong_name)
  567. local context_pool = {}
  568. local possible_name
  569. local possible_names = {}
  570. for name in pairs(context) do
  571. for i=1, #name do
  572. possible_name = name:sub(1, i-1) .. name:sub(i+1)
  573. if not context_pool[possible_name] then
  574. context_pool[possible_name] = {}
  575. end
  576. table.insert(context_pool[possible_name], name)
  577. end
  578. end
  579. for i=1, #wrong_name+1 do
  580. possible_name = wrong_name:sub(1, i-1) .. wrong_name:sub(i+1)
  581. if context[possible_name] then
  582. possible_names[possible_name] = true
  583. elseif context_pool[possible_name] then
  584. for _, name in ipairs(context_pool[possible_name]) do
  585. possible_names[name] = true
  586. end
  587. end
  588. end
  589. local first = next(possible_names)
  590. if first then
  591. if next(possible_names, first) then
  592. local possible_names_arr = {}
  593. for name in pairs(possible_names) do
  594. table.insert(possible_names_arr, "'" .. name .. "'")
  595. end
  596. table.sort(possible_names_arr)
  597. return "\r\nDid you mean one of these: " .. table.concat(possible_names_arr, " ") .. "?"
  598. else
  599. return "\r\nDid you mean '" .. first .. "'?"
  600. end
  601. else
  602. return ""
  603. end
  604. end
  605. local function plural(x)
  606. if x == 1 then
  607. return ""
  608. end
  609. return "s"
  610. end
  611. -- Compatibility with strict.lua and other checkers:
  612. local default_cmdline = rawget(_G, "arg") or {}
  613. function Parser:_parse(args, errhandler)
  614. args = args or default_cmdline
  615. local parser
  616. local charset
  617. local options = {}
  618. local arguments = {}
  619. local commands
  620. local option_mutexes = {}
  621. local used_mutexes = {}
  622. local opt_context = {}
  623. local com_context
  624. local result = {}
  625. local invocations = {}
  626. local passed = {}
  627. local cur_option
  628. local cur_arg_i = 1
  629. local cur_arg
  630. local targets = {}
  631. local function error_(fmt, ...)
  632. return errhandler(parser, fmt:format(...))
  633. end
  634. local function assert_(assertion, ...)
  635. return assertion or error_(...)
  636. end
  637. local function convert(element, data)
  638. if element._convert then
  639. local ok, err
  640. if type(element._convert) == "function" then
  641. ok, err = element._convert(data)
  642. else
  643. ok, err = element._convert[data]
  644. end
  645. assert_(ok ~= nil, "%s", err or "malformed argument '" .. data .. "'")
  646. data = ok
  647. end
  648. return data
  649. end
  650. local invoke, pass, close
  651. function invoke(element)
  652. local overwrite = false
  653. if invocations[element] == element._maxcount then
  654. if element._overwrite then
  655. overwrite = true
  656. else
  657. error_("option '%s' must be used at most %d time%s", element._name, element._maxcount, plural(element._maxcount))
  658. end
  659. else
  660. invocations[element] = invocations[element]+1
  661. end
  662. passed[element] = 0
  663. local type_ = element:_get_type()
  664. local target = targets[element]
  665. if type_ == "flag" then
  666. result[target] = true
  667. elseif type_ == "multiarg" then
  668. result[target] = {}
  669. elseif type_ == "counter" then
  670. if not overwrite then
  671. result[target] = result[target]+1
  672. end
  673. elseif type_ == "multicount" then
  674. if overwrite then
  675. table.remove(result[target], 1)
  676. end
  677. elseif type_ == "twodimensional" then
  678. table.insert(result[target], {})
  679. if overwrite then
  680. table.remove(result[target], 1)
  681. end
  682. end
  683. if element._maxargs == 0 then
  684. close(element)
  685. end
  686. end
  687. function pass(element, data)
  688. passed[element] = passed[element]+1
  689. data = convert(element, data)
  690. local type_ = element:_get_type()
  691. local target = targets[element]
  692. if type_ == "arg" then
  693. result[target] = data
  694. elseif type_ == "multiarg" or type_ == "multicount" then
  695. table.insert(result[target], data)
  696. elseif type_ == "twodimensional" then
  697. table.insert(result[target][#result[target]], data)
  698. end
  699. if passed[element] == element._maxargs then
  700. close(element)
  701. end
  702. end
  703. local function complete_invocation(element)
  704. while passed[element] < element._minargs do
  705. pass(element, element._default)
  706. end
  707. end
  708. function close(element)
  709. if passed[element] < element._minargs then
  710. if element._default and element._defmode:find "a" then
  711. complete_invocation(element)
  712. else
  713. error_("too few arguments")
  714. end
  715. else
  716. if element == cur_option then
  717. cur_option = nil
  718. elseif element == cur_arg then
  719. cur_arg_i = cur_arg_i+1
  720. cur_arg = arguments[cur_arg_i]
  721. end
  722. end
  723. end
  724. local function switch(p)
  725. parser = p
  726. for _, option in ipairs(parser._options) do
  727. table.insert(options, option)
  728. for _, alias in ipairs(option._aliases) do
  729. opt_context[alias] = option
  730. end
  731. local type_ = option:_get_type()
  732. targets[option] = option._target or option:_get_default_target()
  733. if type_ == "counter" then
  734. result[targets[option]] = 0
  735. elseif type_ == "multicount" or type_ == "twodimensional" then
  736. result[targets[option]] = {}
  737. end
  738. invocations[option] = 0
  739. end
  740. for _, mutex in ipairs(parser._mutexes) do
  741. for _, option in ipairs(mutex) do
  742. if not option_mutexes[option] then
  743. option_mutexes[option] = {mutex}
  744. else
  745. table.insert(option_mutexes[option], mutex)
  746. end
  747. end
  748. end
  749. for _, argument in ipairs(parser._arguments) do
  750. table.insert(arguments, argument)
  751. invocations[argument] = 0
  752. targets[argument] = argument._target or argument._name
  753. invoke(argument)
  754. end
  755. cur_arg = arguments[cur_arg_i]
  756. commands = parser._commands
  757. com_context = {}
  758. for _, command in ipairs(commands) do
  759. targets[command] = command._target or command._name
  760. for _, alias in ipairs(command._aliases) do
  761. com_context[alias] = command
  762. end
  763. end
  764. end
  765. local function get_option(name)
  766. return assert_(opt_context[name], "unknown option '%s'%s", name, get_tip(opt_context, name))
  767. end
  768. local function do_action(element)
  769. if element._action then
  770. element._action()
  771. end
  772. end
  773. local function handle_argument(data)
  774. if cur_option then
  775. pass(cur_option, data)
  776. elseif cur_arg then
  777. pass(cur_arg, data)
  778. else
  779. local com = com_context[data]
  780. if not com then
  781. if #commands > 0 then
  782. error_("unknown command '%s'%s", data, get_tip(com_context, data))
  783. else
  784. error_("too many arguments")
  785. end
  786. else
  787. result[targets[com]] = true
  788. do_action(com)
  789. switch(com)
  790. end
  791. end
  792. end
  793. local function handle_option(data)
  794. if cur_option then
  795. close(cur_option)
  796. end
  797. cur_option = opt_context[data]
  798. if option_mutexes[cur_option] then
  799. for _, mutex in ipairs(option_mutexes[cur_option]) do
  800. if used_mutexes[mutex] and used_mutexes[mutex] ~= cur_option then
  801. error_("option '%s' can not be used together with option '%s'", data, used_mutexes[mutex]._name)
  802. else
  803. used_mutexes[mutex] = cur_option
  804. end
  805. end
  806. end
  807. do_action(cur_option)
  808. invoke(cur_option)
  809. end
  810. local function mainloop()
  811. local handle_options = true
  812. for _, data in ipairs(args) do
  813. local plain = true
  814. local first, name, option
  815. if handle_options then
  816. first = data:sub(1, 1)
  817. if charset[first] then
  818. if #data > 1 then
  819. plain = false
  820. if data:sub(2, 2) == first then
  821. if #data == 2 then
  822. if cur_option then
  823. close(cur_option)
  824. end
  825. handle_options = false
  826. else
  827. local equal = data:find "="
  828. if equal then
  829. name = data:sub(1, equal-1)
  830. option = get_option(name)
  831. assert_(option._maxargs > 0, "option '%s' does not take arguments", name)
  832. handle_option(data:sub(1, equal-1))
  833. handle_argument(data:sub(equal+1))
  834. else
  835. get_option(data)
  836. handle_option(data)
  837. end
  838. end
  839. else
  840. for i = 2, #data do
  841. name = first .. data:sub(i, i)
  842. option = get_option(name)
  843. handle_option(name)
  844. if i ~= #data and option._minargs > 0 then
  845. handle_argument(data:sub(i+1))
  846. break
  847. end
  848. end
  849. end
  850. end
  851. end
  852. end
  853. if plain then
  854. handle_argument(data)
  855. end
  856. end
  857. end
  858. switch(self)
  859. charset = parser:_update_charset()
  860. mainloop()
  861. if cur_option then
  862. close(cur_option)
  863. end
  864. while cur_arg do
  865. if passed[cur_arg] == 0 and cur_arg._default and cur_arg._defmode:find "u" then
  866. complete_invocation(cur_arg)
  867. else
  868. close(cur_arg)
  869. end
  870. end
  871. if parser._require_command and #commands > 0 then
  872. error_("a command is required")
  873. end
  874. for _, option in ipairs(options) do
  875. if invocations[option] == 0 then
  876. if option._default and option._defmode:find "u" then
  877. invoke(option)
  878. complete_invocation(option)
  879. close(option)
  880. end
  881. end
  882. if invocations[option] < option._mincount then
  883. if option._default and option._defmode:find "a" then
  884. while invocations[option] < option._mincount do
  885. invoke(option)
  886. close(option)
  887. end
  888. else
  889. error_("option '%s' must be used at least %d time%s", option._name, option._mincount, plural(option._mincount))
  890. end
  891. end
  892. end
  893. return result
  894. end
  895. function Parser:error(msg)
  896. io.stderr:write(("%s\r\n\r\nError: %s\r\n"):format(self:get_usage(), msg))
  897. os.exit(1)
  898. end
  899. function Parser:parse(args)
  900. return self:_parse(args, Parser.error)
  901. end
  902. function Parser:pparse(args)
  903. local errmsg
  904. local ok, result = pcall(function()
  905. return self:_parse(args, function(_, err)
  906. errmsg = err
  907. return error()
  908. end)
  909. end)
  910. if ok then
  911. return true, result
  912. else
  913. assert(errmsg, result)
  914. return false, errmsg
  915. end
  916. end
  917. return function(...)
  918. return Parser(default_cmdline[0]):add_help(true)(...)
  919. end