123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225(*---------------------------------------------------------------------------
Copyright (c) 2011 The cmdliner programmers. All rights reserved.
SPDX-License-Identifier: ISC
---------------------------------------------------------------------------*)(* Exit codes *)moduleExit=structtypecode=intletok=0letsome_error=123letcli_error=124letinternal_error=125typeinfo={codes:code*code;(* min, max *)doc:string;(* help. *)docs:string;}(* title of help section where listed. *)letinfo?(docs=Cmdliner_manpage.s_exit_status)?(doc="undocumented")?maxmin=letmax=matchmaxwithNone->min|Somemax->maxin{codes=(min,max);doc;docs}letinfo_codesi=i.codesletinfo_codei=fsti.codesletinfo_doci=i.docletinfo_docsi=i.docsletinfo_orderi0i1=comparei0.codesi1.codesletdefaults=[infook~doc:"on success.";infosome_error~doc:"on indiscriminate errors reported on standard error.";infocli_error~doc:"on command line parsing errors.";infointernal_error~doc:"on unexpected internal errors (bugs).";]end(* Environment variables *)moduleEnv=structtypevar=stringtypeinfo=(* information about an environment variable. *){id:int;(* unique id for the env var. *)deprecated:stringoption;var:string;(* the variable. *)doc:string;(* help. *)docs:string;}(* title of help section where listed. *)letinfo?deprecated?(docs=Cmdliner_manpage.s_environment)?(doc="See option $(opt).")var={id=Cmdliner_base.uid();deprecated;var;doc;docs}letinfo_deprecatedi=i.deprecatedletinfo_vari=i.varletinfo_doci=i.docletinfo_docsi=i.docsletinfo_comparei0i1=Int.comparei0.idi1.idmoduleSet=Set.Make(structtypet=infoletcompare=info_compareend)end(* Arguments *)moduleArg=structtypeabsence=Err|ValofstringLazy.t|Docofstringtypeopt_kind=Flag|Opt|Opt_voptofstringtypepos_kind=(* information about a positional argument. *){pos_rev:bool;(* if [true] positions are counted from the end. *)pos_start:int;(* start positional argument. *)pos_len:intoption}(* number of arguments or [None] if unbounded. *)letpos~rev:pos_rev~start:pos_start~len:pos_len={pos_rev;pos_start;pos_len}letpos_revp=p.pos_revletpos_startp=p.pos_startletpos_lenp=p.pos_lentypet=(* information about a command line argument. *){id:int;(* unique id for the argument. *)deprecated:stringoption;(* deprecation message *)absent:absence;(* behaviour if absent. *)env:Env.infooption;(* environment variable for default value. *)doc:string;(* help. *)docv:string;(* variable name for the argument in help. *)docs:string;(* title of help section where listed. *)pos:pos_kind;(* positional arg kind. *)opt_kind:opt_kind;(* optional arg kind. *)opt_names:stringlist;(* names (for opt args). *)opt_all:bool;}(* repeatable (for opt args). *)letdumb_pos=pos~rev:false~start:(-1)~len:Noneletv?deprecated?(absent="")?docs?(docv="")?(doc="")?envnames=letdashn=ifString.lengthn=1then"-"^nelse"--"^ninletopt_names=List.mapdashnamesinletdocs=matchdocswith|Somes->s|None->matchnameswith|[]->Cmdliner_manpage.s_arguments|_->Cmdliner_manpage.s_optionsin{id=Cmdliner_base.uid();deprecated;absent=Docabsent;env;doc;docv;docs;pos=dumb_pos;opt_kind=Flag;opt_names;opt_all=false;}letida=a.idletdeprecateda=a.deprecatedletabsenta=a.absentletenva=a.envletdoca=a.docletdocva=a.docvletdocsa=a.docsletpos_kinda=a.posletopt_kinda=a.opt_kindletopt_namesa=a.opt_namesletopt_alla=a.opt_allletopt_name_samplea=(* First long or short name (in that order) in the list; this
allows the client to control which name is shown *)letrecfind=function|[]->List.hda.opt_names|n::ns->if(String.lengthn)>2thennelsefindnsinfinda.opt_namesletmake_reqa={awithabsent=Err}letmake_all_optsa={awithopt_all=true}letmake_opt~absent~kind:opt_kinda={awithabsent;opt_kind}letmake_opt_all~absent~kind:opt_kinda={awithabsent;opt_kind;opt_all=true}letmake_pos~posa={awithpos}letmake_pos_abs~absent~posa={awithabsent;pos}letis_opta=a.opt_names<>[]letis_posa=a.opt_names=[]letis_reqa=a.absent=Errletpos_cli_ordera0a1=(* best-effort order on the cli. *)letc=compare(a0.pos.pos_rev)(a1.pos.pos_rev)inifc<>0thencelseifa0.pos.pos_revthencomparea1.pos.pos_starta0.pos.pos_startelsecomparea0.pos.pos_starta1.pos.pos_startletrev_pos_cli_ordera0a1=pos_cli_ordera1a0letcomparea0a1=Int.comparea0.ida1.idmoduleSet=Set.Make(structtypenonrect=tletcompare=compareend)end(* Commands *)moduleCmd=structtypet={name:string;(* name of the cmd. *)version:stringoption;(* version (for --version). *)deprecated:stringoption;(* deprecation message *)doc:string;(* one line description of cmd. *)docs:string;(* title of man section where listed (commands). *)sdocs:string;(* standard options, title of section where listed. *)exits:Exit.infolist;(* exit codes for the cmd. *)envs:Env.infolist;(* env vars that influence the cmd. *)man:Cmdliner_manpage.blocklist;(* man page text. *)man_xrefs:Cmdliner_manpage.xreflist;(* man cross-refs. *)args:Arg.Set.t;(* Command arguments. *)has_args:bool;(* [true] if has own parsing term. *)children:tlist;}(* Children, if any. *)letv?deprecated?(man_xrefs=[`Main])?(man=[])?(envs=[])?(exits=Exit.defaults)?(sdocs=Cmdliner_manpage.s_common_options)?(docs=Cmdliner_manpage.s_commands)?(doc="")?versionname={name;version;deprecated;doc;docs;sdocs;exits;envs;man;man_xrefs;args=Arg.Set.empty;has_args=true;children=[]}letnamet=t.nameletversiont=t.versionletdeprecatedt=t.deprecatedletdoct=t.docletdocst=t.docsletstdopts_docst=t.sdocsletexitst=t.exitsletenvst=t.envsletmant=t.manletman_xrefst=t.man_xrefsletargst=t.argslethas_argst=t.has_argsletchildrent=t.childrenletadd_argstargs={twithargs=Arg.Set.unionargst.args}letwith_childrencmd~args~children=lethas_args,args=matchargswith|None->false,cmd.args|Someargs->true,Arg.Set.unionargscmd.argsin{cmdwithhas_args;args;children}end(* Evaluation *)moduleEval=structtypet=(* information about the evaluation context. *){cmd:Cmd.t;(* cmd being evaluated. *)parents:Cmd.tlist;(* parents of cmd, root is last. *)env:string->stringoption;(* environment variable lookup. *)err_ppf:Format.formatter(* error formatter *)}letv~cmd~parents~env~err_ppf={cmd;parents;env;err_ppf}letcmde=e.cmdletparentse=e.parentsletenv_varev=e.envvleterr_ppfe=e.err_ppfletmaine=matchList.reve.parentswith[]->e.cmd|m::_->mletwith_cmdeicmd={eiwithcmd}end