argparse.lua 26 KB

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