argparse.lua 29 KB

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