argparse.lua 29 KB

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