argparse.lua 28 KB

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