Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file key.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218(*
* Copyright (c) 2013-2020 Thomas Gazagnaire <thomas@gazagnaire.org>
* Copyright (c) 2013-2020 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2015-2020 Gabriel Radanne <drupyog@zoho.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openCmdlinermoduleArg=struct(** {1 Arguments} *)letinfo=Arg.infotype'akind=|Opt:'a*'aArg.conv->'akind|Opt_all:'aArg.conv->'alistkind|Required:'aArg.conv->'aoptionkind|Flag:boolkindletpp_convc=sndcletpp_kind:typea.akind->aFmt.t=function|Opt(_,c)->pp_convc|Opt_allc->pp_conv(Arg.listc)|Requiredc->pp_conv(Arg.somec)|Flag->Fmt.boolletcompare_kind:typeab.akind->bkind->int=funab->letdefaultcxx=Fmt.to_to_string(sndcx)xinmatch(a,b)with|Opt(x,cx),Opt(y,cy)->String.compare(defaultcxx)(defaultcyy)|Required_,Required_->0|Opt_all_,Opt_all_->0|Flag,Flag->0|Opt_,_->1|_,Opt_->-1|Required_,_->1|_,Required_->-1|Opt_all_,_->1|_,Opt_all_->-1type'at={info:Arg.info;kind:'akind}letppt=pp_kindt.kindletequalxy=compare_kindx.kindy.kind=0letoptconvdefaultinfo={info;kind=Opt(default,conv)}letflaginfo={info;kind=Flag}letrequiredconvinfo={info;kind=Requiredconv}letopt_allconvinfo={info;kind=Opt_allconv}letdefault(typea)(t:at)=matcht.kindwith|Opt(d,_)->d|Flag->(false:bool)|Required_->(None:_option)|Opt_all_->([]:_list)letmake_opt_cmdlinerwrapidefaultdesc=Arg.(wrap@@opt(some'?none:defaultdesc)Nonei)letmake_opt_all_cmdlinerwrapidesc=Arg.(wrap@@opt_alldesc[]i)(* Wrap terms into an ['a option] to distinguish between default
and absent values. *)letto_cmdliner(typea)(t:at):aoptionCmdliner.Term.t=leti=t.infoinmatcht.kindwith|Flag->Arg.(value&vflagNone[(Sometrue,i)])|Opt(default,desc)->make_opt_cmdlinerArg.valuei(Somedefault)desc|Requireddesc->make_opt_cmdlinerArg.requirediNone(Arg.some(Arg.somedesc))|Opt_alldesc->letlist_to_option=function|[]->None|_::_aslst->Somelstinletwraparg=Term.(constlist_to_option$Arg.valuearg)inmake_opt_all_cmdlinerwrapidescendtype'akey={name:string;arg:'aArg.t;key:'aContext.key}typet=Any:'akey->tletequal(Anyx)(Anyy)=String.equalx.namey.name&&Arg.equalx.argy.arg(* Set of keys, without runtime name conflicts. This is useful to create a
valid cmdliner term. *)moduleNames=Stdlib.Set.Make(structtypenonrect=tletcompare(Anyx)(Anyy)=String.comparex.namey.nameend)(* Set of keys, where keys with the same name but with different
defaults are distinguished. This is useful to build the graph of
devices. *)moduleSet=structmoduleM=structtypenonrect=tletcompare=compareendincludeSet.Make(M)letaddkset=ifmemksetthenifk!=findksetthenmatchkwithAnyk->Fmt.invalid_arg"Duplicate key name: %s"k.nameelsesetelseaddksetletpp_gen=Fmt.iter~sep:(Fmt.any",@ ")iterletpp_eltfmt(Anyk)=Fmt.stringfmtk.nameletpp=pp_genpp_eltendletvx=Anyxletname(Anyk)=k.name(* Key Map *)typecontext=Context.tletadd_to_contextt=Context.addt.keyletfind(typea)ctx(t:akey):aoption=Context.findt.keyctxletgetctxt=matchfindctxtwithSomex->x|None->Arg.defaultt.argletmem_uctxt=Context.memt.keyctx(* {2 Values} *)type+'avalue={deps:Set.t;v:context->'a}letevalpv=v.vpletpurex={deps=Set.empty;v=(fun_->x)}letappfx={deps=Set.unionf.depsx.deps;v=(funp->(evalpf)(evalpx))}letmapfx=app(puref)xletpipexf=mapfxletif_cte=pipec@@funb->ifbthentelseeletmatch_vf=mapfvlet($)=appletvaluek=letvc=getckin{deps=Set.singleton(Anyk);v}letof_depsdeps={(pure())withdeps}letdepsk=k.depsletmempv=Set.for_all(functionAnyx->mem_upx)v.depsletpeekpv=ifmempvthenSome(evalpv)elseNoneletdefaultv=evalContext.emptyv(* {2 Pretty printing} *)letpp=Set.pp_eltletpp_depsfmtv=Set.ppfmtv.depsletppspppfl=letpp'fmtkv=letdefault=ifmem_upkthenFmt.nopelseFmt.any" (default)"inFmt.pffmt"%a=%a%a"Fmt.(styled`Boldstring)k.name(Arg.ppk.arg)vdefault()inletffmt(Anyk)=match(k.arg.Arg.kind,getpk)with|Arg.Required_,None->Fmt.(styled`Boldstring)fmtk.name|Arg.Opt_,v->pp'fmtkv|Arg.Required_,v->pp'fmtkv|Arg.Flag,v->pp'fmtkv|Arg.Opt_all_,v->pp'fmtkv(* Warning 4 and GADT don't interact well. *)inletpp=Fmt.vbox@@funppfs->Set.(pp_genfppf@@s)inppppfl(* {2 Key creation} *)(* Unexposed smart constructor. *)letmake~arg~name=letkey=Context.new_keynamein{arg;name;key}letcreatenamearg=ifname=""theninvalid_arg"Key.create: key name cannot be the empty string";make~arg~name(* {2 Cmdliner interface} *)letcontextl=letnames=Names.of_list(Set.elementsl)inletgather(Anyk)rest=letfvp=matchvwithNone->p|Somev->Context.addk.keyvpinletkey=Arg.to_cmdlinerk.arginmatchk.arg.Arg.kindwith|Arg.Opt_->Cmdliner.Term.(constf$key$rest)|Arg.Required_->Cmdliner.Term.(constf$key$rest)|Arg.Flag->Cmdliner.Term.(constf$key$rest)|Arg.Opt_all_->Cmdliner.Term.(constf$key$rest)inNames.foldgathernames(Cmdliner.Term.constContext.empty)