|
1 | 1 | (*--------------------------------------------------------------------------- |
2 | 2 | Copyright (c) 2011 Daniel C. Bünzli. All rights reserved. |
3 | 3 | Distributed under the ISC license, see terms at the end of the file. |
4 | | - cmdliner v1.0.4-3-ga5ff0e8 |
| 4 | + cmdliner v1.0.4-12-gfb7fa13 |
5 | 5 | ---------------------------------------------------------------------------*) |
6 | 6 |
|
7 | 7 | module Manpage = Cmdliner_manpage |
@@ -216,7 +216,7 @@ module Term = struct |
216 | 216 | ?err:(err_ppf = Format.err_formatter) |
217 | 217 | ?(catch = true) ?(env = env_default) ?(argv = Sys.argv) ((al, f), ti) = |
218 | 218 | let term = Cmdliner_info.term_add_args ti al in |
219 | | - let ei = Cmdliner_info.eval ~term ~main:term ~choices:[] ~env in |
| 219 | + let ei = Cmdliner_info.eval ~env (Simple term) in |
220 | 220 | let args = remove_exec argv in |
221 | 221 | let ei, res = term_eval ~catch ei f args in |
222 | 222 | do_result help_ppf err_ppf ei res |
@@ -257,20 +257,111 @@ module Term = struct |
257 | 257 | let main = fst main_f in |
258 | 258 | match choose_term main_f choices_f (remove_exec argv) with |
259 | 259 | | Error err -> |
260 | | - let ei = Cmdliner_info.eval ~term:main ~main ~choices ~env in |
| 260 | + let ei = Cmdliner_info.eval ~env |
| 261 | + (Sub_command { term = main ; path = [main] ; main |
| 262 | + ; sibling_terms = choices}) |
| 263 | + in |
261 | 264 | Cmdliner_msg.pp_err_usage err_ppf ei ~err_lines:false ~err; |
262 | 265 | `Error `Parse |
263 | 266 | | Ok ((chosen, f), args) -> |
264 | | - let ei = Cmdliner_info.eval ~term:chosen ~main ~choices ~env in |
| 267 | + let ei = Cmdliner_info.eval ~env |
| 268 | + (Sub_command { term = chosen ; path = [main; chosen] ; main; |
| 269 | + sibling_terms = choices }) in |
| 270 | + let ei, res = term_eval ~catch ei f args in |
| 271 | + do_result help_ppf err_ppf ei res |
| 272 | + |
| 273 | + module Group = struct |
| 274 | + type 'a node = |
| 275 | + | Term of 'a Cmdliner_term.t |
| 276 | + | Group of 'a t list |
| 277 | + |
| 278 | + and 'a t = 'a node * info |
| 279 | + |
| 280 | + let term_add_args (al, f) info = |
| 281 | + Cmdliner_info.term_add_args info al |
| 282 | + |
| 283 | + let rec add_args (node, info) = |
| 284 | + match node with |
| 285 | + | Term (al, f) -> (Term (al, f), term_add_args (al, f) info) |
| 286 | + | Group subs -> (Group (List.map add_args subs), info) |
| 287 | + |
| 288 | + let (>>=) res f = |
| 289 | + match res with |
| 290 | + | Error e -> Error e |
| 291 | + | Ok x -> f x |
| 292 | + |
| 293 | + let parse_arg_cmd = function |
| 294 | + | [] -> Error `No_args |
| 295 | + | cmd :: args -> |
| 296 | + if String.length cmd >= 1 && cmd.[0] = '-' then |
| 297 | + Error `No_args |
| 298 | + else |
| 299 | + Ok (cmd, args) |
| 300 | + |
| 301 | + let cmd_name (_, info) = Cmdliner_info.term_name info |
| 302 | + |
| 303 | + let one_of (cmd, choices, path, args) = |
| 304 | + match List.find (fun t -> cmd_name t = cmd) choices with |
| 305 | + | exception Not_found -> Error (`Invalid_command (cmd, path, choices)) |
| 306 | + | (choice, info) -> Ok ((choice, info), choices, info :: path, args) |
| 307 | + |
| 308 | + let try_one_of choices path args = |
| 309 | + match parse_arg_cmd args with |
| 310 | + | Ok (cmd, args) -> one_of (cmd, choices, path, args) |
| 311 | + | Error `No_args -> Error (`No_args (path, choices)) |
| 312 | + |
| 313 | + let rec try_choose_term choices path args = |
| 314 | + try_one_of choices path args >>= choose_term |
| 315 | + |
| 316 | + and choose_term ((t, info), choices, path, args) = |
| 317 | + match t with |
| 318 | + | Term t -> Ok ((t, info), choices, path, args) |
| 319 | + | Group subs -> try_choose_term subs path args |
| 320 | + |
| 321 | + let choose_term main choices args = |
| 322 | + match parse_arg_cmd args with |
| 323 | + | Error `No_args -> Ok (main, choices, [], args) |
| 324 | + | Ok (cmd, args) -> one_of (cmd, choices, [snd main], args) >>= choose_term |
| 325 | + |
| 326 | + let eval |
| 327 | + ?help:(help_ppf = Format.std_formatter) |
| 328 | + ?err:(err_ppf = Format.err_formatter) |
| 329 | + ?(catch = true) ?(env = env_default) ?(argv = Sys.argv) main choices = |
| 330 | + let choices_f = List.map add_args choices in |
| 331 | + let to_term_f ((al, f), ti) = Cmdliner_info.term_add_args ti al, f in |
| 332 | + let main_args = fst main in |
| 333 | + let main_f = to_term_f main in |
| 334 | + let main = fst main_f in |
| 335 | + match choose_term (main_args, (fst main_f)) choices_f (remove_exec argv) with |
| 336 | + | Error (`No_args (path, choices)) -> |
| 337 | + let sibling_terms = List.map snd choices in |
| 338 | + let ei = Cmdliner_info.eval ~env |
| 339 | + (Sub_command { term = main ; path ; main ; sibling_terms}) in |
| 340 | + let _, _, ei = add_stdopts ei in |
| 341 | + Cmdliner_docgen.pp_man ~errs:err_ppf `Auto help_ppf ei; |
| 342 | + `Help |
| 343 | + | Error (`Invalid_command (maybe, path, _choices)) -> |
| 344 | + let err = Cmdliner_base.err_unknown ~kind:"command" maybe ~hints:[] in |
| 345 | + let sibling_terms = List.map snd choices in |
| 346 | + let ei = Cmdliner_info.eval ~env |
| 347 | + (Sub_command { term = main ; path ; main ; sibling_terms}) |
| 348 | + in |
| 349 | + Cmdliner_msg.pp_err_usage err_ppf ei ~err_lines:false ~err; |
| 350 | + `Error `Parse |
| 351 | + | Ok (((_, f), info), sibling_terms, path, args) -> |
| 352 | + let sibling_terms = List.map snd sibling_terms in |
| 353 | + let ei = Cmdliner_info.eval ~env |
| 354 | + (Sub_command { main ; term = info ; path ; sibling_terms }) in |
265 | 355 | let ei, res = term_eval ~catch ei f args in |
266 | 356 | do_result help_ppf err_ppf ei res |
| 357 | + end |
267 | 358 |
|
268 | 359 | let eval_peek_opts |
269 | 360 | ?(version_opt = false) ?(env = env_default) ?(argv = Sys.argv) |
270 | 361 | ((args, f) : 'a t) = |
271 | 362 | let version = if version_opt then Some "dummy" else None in |
272 | 363 | let term = Cmdliner_info.term ~args ?version "dummy" in |
273 | | - let ei = Cmdliner_info.eval ~term ~main:term ~choices:[] ~env in |
| 364 | + let ei = Cmdliner_info.eval ~env (Simple term) in |
274 | 365 | (term_eval_peek_opts ei f (remove_exec argv) :> 'a option * 'a result) |
275 | 366 |
|
276 | 367 | (* Exits *) |
|
0 commit comments