Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file goptions.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634(************************************************************************)(* * The Rocq Prover / The Rocq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)(* This module manages customization parameters at the vernacular level *)openUtilopenSummary.Stagetypeoption_name=stringlisttype_option_kind=|BoolKind:booloption_kind|IntKind:intoptionoption_kind|StringKind:stringoption_kind|StringOptKind:stringoptionoption_kindtypeoption_value=|BoolValueofbool|IntValueofintoption|StringValueofstring|StringOptValueofstringoptiontypetable_value=|StringRefValueofstring|QualidRefValueofLibnames.qualid(** Summary of an option status *)typeoption_state={opt_depr:Deprecation.toption;opt_value:option_value;}(****************************************************************************)(* 0- Common things *)letnicknametable=String.concat" "tableleterror_no_table_of_this_type~kindkey=CErrors.user_errPp.(str("There is no "^kind^"-valued table with this name: \""^nicknamekey^"\"."))leterror_undeclared_keykey=CErrors.user_errPp.(str("There is no flag, option or table with this name: \""^nicknamekey^"\"."))(****************************************************************************)(* 1- Tables *)type'atable_of_A={add:Environ.env->Libobject.locality->'a->unit;remove:Environ.env->Libobject.locality->'a->unit;mem:Environ.env->'a->unit;print:unit->unit;}letopts_cat=Libobject.create_category"options"moduleMakeTable=functor(A:sigtypettypekeymoduleSet:CSig.USetSwithtypeelt=tvaltable:(string*keytable_of_A)listrefvalencode:Environ.env->key->tvalsubst:Mod_subst.substitution->t->tvalcheck_local:Libobject.locality->t->unitvaldischarge:t->tvalprinter:t->Pp.tvalkey:option_namevaltitle:stringvalmember_message:t->bool->Pp.tend)->structtypeoption_mark=|GOadd|GOrmvletnick=nicknameA.keylet()=ifString.List.mem_assocnick!A.tablethenCErrors.anomalyPp.(strbrk"Sorry, this table name ("++strnick++strbrk") is already used.")moduleMySet=A.Setlett=Summary.ref~stage:InterpMySet.empty~name:nickletinGo:Libobject.locality*(option_mark*A.t)->Libobject.obj=letcache(f,p)=matchfwith|GOadd->t:=MySet.addp!t|GOrmv->t:=MySet.removep!tinletsubst(subst,(f,pasobj))=letp'=A.substsubstpinifp'==pthenobjelse(f,p')inLibobject.declare_object@@Libobject.object_with_locality~cat:opts_catnick~cache~subst:(Somesubst)~discharge:(on_sndA.discharge)letadd_optionlocalc=A.check_locallocalc;Lib.add_leaf(inGo(local,(GOadd,c)))letremove_optionlocalc=A.check_locallocalc;Lib.add_leaf(inGo(local,(GOrmv,c)))letprint_tabletable_nameprintertable=letopenPpinletpp=ifMySet.is_emptytablethenstrtable_name++str" is empty."elsestrtable_name++str":"++spc()++(hov0(prlist_with_sepspcprinter(MySet.elementstable)))++str"."inFeedback.msg_noticepplettable_of_A={add=(funenvlocalx->add_optionlocal(A.encodeenvx));remove=(funenvlocalx->remove_optionlocal(A.encodeenvx));mem=(funenvx->lety=A.encodeenvxinletanswer=MySet.memy!tinFeedback.msg_info(A.member_messageyanswer));print=(fun()->print_tableA.titleA.printer!t);}let()=A.table:=(nick,table_of_A)::!A.tableletv()=!tletactivex=A.Set.memx!tletsetlocalxb=ifbthenadd_optionlocalxelseremove_optionlocalxendletstring_table=ref[]letget_string_tablek=String.List.assoc(nicknamek)!string_tablemoduletypeStringConvertArg=sigvalkey:option_namevaltitle:stringvalmember_message:string->bool->Pp.tendmoduleStringConvert=functor(A:StringConvertArg)->structtypet=stringtypekey=stringmoduleSet=CString.Setlettable=string_tableletencode_envx=xletsubst_x=xletcheck_local__=()letdischargex=xletprinter=Pp.strletkey=A.keylettitle=A.titleletmember_message=A.member_messageendmoduleMakeStringTable=functor(A:StringConvertArg)->MakeTable(StringConvert(A))letref_table=ref[]letget_ref_tablek=String.List.assoc(nicknamek)!ref_tablemoduletypeRefConvertArg=sigtypetmoduleSet:CSig.USetSwithtypeelt=tvalencode:Environ.env->Libnames.qualid->tvalsubst:Mod_subst.substitution->t->tvalcheck_local:Libobject.locality->t->unitvaldischarge:t->tvalprinter:t->Pp.tvalkey:option_namevaltitle:stringvalmember_message:t->bool->Pp.tendmoduleRefConvert=functor(A:RefConvertArg)->structtypet=A.ttypekey=Libnames.qualidmoduleSet=A.Setlettable=ref_tableletencode=A.encodeletsubst=A.substletcheck_local=A.check_localletdischarge=A.dischargeletprinter=A.printerletkey=A.keylettitle=A.titleletmember_message=A.member_messageendmoduleMakeRefTable=functor(A:RefConvertArg)->MakeTable(RefConvert(A))typeiter_table_aux={aux:'a.'atable_of_A->Environ.env->'a->unit}letiter_tableenvfkeylv=letaux=function|StringRefValues->begintryf.aux(get_string_tablekey)envswithNot_found->error_no_table_of_this_type~kind:"string"keyend|QualidRefValuelocqid->begintryf.aux(get_ref_tablekey)envlocqidwithNot_found->error_no_table_of_this_type~kind:"qualid"keyendinList.iterauxlv(****************************************************************************)(* 2- Flags. *)typeoption_locality=OptDefault|OptLocal|OptExport|OptGlobalmoduleOptionOrd=structtypet=option_nameletcompareopt1opt2=List.compareString.compareopt1opt2endmoduleOptionMap=Map.Make(OptionOrd)moduleRawOpt=structtype'at={kind:'aoption_kind;depr:Deprecation.toption;stage:Summary.Stage.t;read:unit->'a;write:option_locality->'a->unit;}endtypeany_opt=AnyOpt:'aRawOpt.t->any_optletvalue_tab=refOptionMap.empty(* This raises Not_found if option of key [key] is unknown *)letget_optionkey=OptionMap.findkey!value_tabletcheck_keykey=trylet_=get_optionkeyinCErrors.user_errPp.(str"Sorry, this option name ("++str(nicknamekey)++str") is already used.")withNot_found->ifString.List.mem_assoc(nicknamekey)!string_table||String.List.mem_assoc(nicknamekey)!ref_tablethenCErrors.user_errPp.(str"Sorry, this option name ("++str(nicknamekey)++str") is already used.")letdeclare_rawnamev=value_tab:=OptionMap.addname(AnyOptv)!value_tab(* not quite the same as RawOpt.t: write takes a option_locality, optkey field present *)type'aoption_sig={optstage:Summary.Stage.t;optdepr:Deprecation.toption;optkey:option_name;optread:unit->'a;optwrite:'a->unit}openLibobjectletwarn_deprecated_option=Deprecation.create_warning~object_name:"Option"~warning_name_if_no_since:"deprecated-option"(funkey->Pp.str(nicknamekey))letoption_objectnamestageact=letcache_option(l,v)=actvinletload_optioni(l,_aso)=matchlwith|OptGlobal->cache_optiono|OptExport->()|OptLocal|OptDefault->(* Ruled out by classify_function *)assertfalseinletopen_option(l,_aso)=matchlwith|OptExport->cache_optiono|OptGlobal->()|OptLocal|OptDefault->(* Ruled out by classify_function *)assertfalseinletdischarge_option(l,_aso)=matchlwithOptLocal->None|(OptExport|OptGlobal|OptDefault)->Someoinletclassify_option(l,_)=matchlwith(OptExport|OptGlobal)->Substitute|(OptLocal|OptDefault)->Disposein{(Libobject.default_objectname)withobject_stage=stage;cache_function=cache_option;load_function=load_option;open_function=simple_open~cat:opts_catopen_option;subst_function=(fun(_,o)->o);discharge_function=discharge_option;classify_function=classify_option;}letdeclare_option?(preprocess=funx->x)?(no_summary=false)~kind{optstage=stage;optdepr=depr;optkey=key;optread=read;optwrite=write}=check_keykey;let()=ifnotno_summarythenbeginletdefault=read()inSummary.declare_summary(nicknamekey){stage;Summary.freeze_function=read;Summary.unfreeze_function=write;Summary.init_function=(fun()->writedefault)}endinletchange=letoptions:option_locality*_->obj=declare_object(option_object(nicknamekey)stagewrite)in(funlv->letv=preprocessvinLib.add_leaf(options(l,v)))inletwarn()=depr|>Option.iter(fundepr->warn_deprecated_option(key,depr))inletcwritelv=warn();changelvindeclare_rawkey{kind;stage;depr;read;write=cwrite;}letdeclare_append_only_option?(preprocess=funx->x)~sep{optstage=stage;optdepr=depr;optkey=key;optread=read;optwrite=write}=check_keykey;letdefault=read()inlet()=Summary.declare_summary(nicknamekey){stage;Summary.freeze_function=read;Summary.unfreeze_function=write;Summary.init_function=(fun()->writedefault)}inletappendx=write(read()^sep^x)inletchange=letoptions:option_locality*_->obj=declare_object(option_object(nicknamekey)stageappend)in(funlv->letv=preprocessvinLib.add_leaf(options(l,v)))inletwarn()=depr|>Option.iter(fundepr->warn_deprecated_option(key,depr))inletcwritelv=warn();changelvindeclare_rawkey{kind=StringKind;stage;depr;read;write=cwrite;}type'agetter={get:unit->'a}type'aopt_decl=?stage:Summary.Stage.t->?depr:Deprecation.t->key:option_name->value:'a->unit->'agetterletdeclare_int_option_and_ref?(stage=Interp)?depr~key~(value:int)()=letr_opt=refvalueinletoptwritev=r_opt:=Option.defaultvaluevinletoptread()=Some!r_optinlet()=declare_option~kind:IntKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite;}in{get=fun()->!r_opt}letdeclare_intopt_option_and_ref?(stage=Interp)?depr~key~value()=letr_opt=refvalueinletoptwritev=r_opt:=vinletoptread()=!r_optinlet()=declare_option~kind:IntKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite}in{get=optread}letdeclare_nat_option_and_ref?(stage=Interp)?depr~key~(value:int)()=assert(value>=0);letr_opt=refvalueinletoptwritev=letv=Option.defaultvaluevinifv<0thenCErrors.user_errPp.(str"This option expects a non-negative value.");r_opt:=vinletoptread()=Some!r_optinlet()=declare_option~kind:IntKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite}in{get=fun()->!r_opt}letdeclare_bool_option_and_ref?(stage=Interp)?depr~key~(value:bool)()=letr_opt=refvalueinletoptwritev=r_opt:=vinletoptread()=!r_optinlet()=declare_option~kind:BoolKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite}in{get=optread}letdeclare_string_option_and_ref?(stage=Interp)?depr~key~(value:string)()=letr_opt=refvalueinletoptwritev=r_opt:=Option.defaultvaluevinletoptread()=Some!r_optinlet()=declare_option~kind:StringOptKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite}in{get=fun()->!r_opt}letdeclare_stringopt_option_and_ref?(stage=Interp)?depr~key~value()=letr_opt=refvalueinletoptwritev=r_opt:=vinletoptread()=!r_optinlet()=declare_option~kind:StringOptKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite}in{get=optread}letdeclare_interpreted_string_option_and_reffrom_stringto_string?(stage=Interp)?depr~key~(value:'a)()=letr_opt=refvalueinletoptwritev=r_opt:=Option.defaultvalue@@Option.mapfrom_stringvinletoptread()=Some(to_string!r_opt)inlet()=declare_option~kind:StringOptKind{optstage=stage;optdepr=depr;optkey=key;optread;optwrite}in{get=fun()->!r_opt}(* 3- User accessible commands *)(* Setting values of options *)letwarn_unknown_option=CWarnings.create~name:"unknown-option"Pp.(funkey->strbrk"There is no flag or option with this name: \""++str(nicknamekey)++str"\".")letto_option_value(typea)(k:aoption_kind)(v:a):option_value=matchkwith|BoolKind->BoolValuev|IntKind->IntValuev|StringKind->StringValuev|StringOptKind->StringOptValuevletget_option_valuekey=tryletAnyOptopt=get_optionkeyinSome(fun()->to_option_valueopt.kind(opt.read()))withNot_found->Noneletbad_type_error~expected~got=CErrors.user_errPp.(strbrk"Bad type of value for this option:"++spc()++str"expected "++strexpected++str", got "++strgot++str".")leterror_flag()=CErrors.user_errPp.(str"This is a flag. It does not take a value.")type'acheck_and_cast={check_and_cast:'b.'a->'boption_kind->'b}(** Sets the option only if [stage] matches the option declaration or if [stage]
is omitted. If the option is not found, a warning is emitted only if the stage
is [Interp] or omitted. *)letset_option_value?(locality=OptDefault)?stage{check_and_cast}keyv=matchget_optionkeywith|exceptionNot_found->beginmatchstagewithNone|SomeSummary.Stage.Interp->warn_unknown_optionkey|_->()end|AnyOptopt->ifOption.cata(funs->s=opt.stage)truestagethenopt.writelocality(check_and_castvopt.kind)letcheck_int_value(typea)(v:intoption)(k:aoption_kind):a=matchkwith|BoolKind->error_flag()|IntKind->v|StringKind|StringOptKind->bad_type_error~expected:"string"~got:"int"letcheck_bool_value(typea)(v:bool)(k:aoption_kind):a=matchkwith|BoolKind->v|_->CErrors.user_errPp.(str"This is an option. A value must be provided.")letcheck_string_value(typea)(v:string)(k:aoption_kind):a=matchkwith|BoolKind->error_flag()|IntKind->bad_type_error~expected:"int"~got:"string"|StringKind->v|StringOptKind->(Somev)letcheck_unset_value(typea)()(k:aoption_kind):a=matchkwith|BoolKind->false|IntKind->None|StringOptKind->None|StringKind->CErrors.user_errPp.(str"This option does not support the \"Unset\" command.")(* Nota: For compatibility reasons, some errors are treated as
warnings. This allows a script to refer to an option that doesn't
exist anymore *)letset_int_option_value_gen?locality?stage=set_option_value?locality?stage{check_and_cast=check_int_value}letset_bool_option_value_gen?locality?stagekeyv=set_option_value?locality?stage{check_and_cast=check_bool_value}keyvletset_string_option_value_gen?locality?stage=set_option_value?locality?stage{check_and_cast=check_string_value}letunset_option_value_gen?locality?stagekey=set_option_value?locality?stage{check_and_cast=check_unset_value}key()letset_int_option_value?stageoptv=set_int_option_value_gen?stageoptvletset_bool_option_value?stageoptv=set_bool_option_value_gen?stageoptvletset_string_option_value?stageoptv=set_string_option_value_gen?stageoptv(* Printing options/tables *)letmsg_option_value=Pp.(function|BoolValuetrue->str"on"|BoolValuefalse->str"off"|IntValue(Somen)->intn|IntValueNone->str"undefined"|StringValues->quote(strs)|StringOptValueNone->str"undefined"|StringOptValue(Somes)->quote(strs))letprint_option_valuekey=letAnyOptopt=get_optionkeyinlets=opt.read()inmatchto_option_valueopt.kindswith|BoolValueb->Feedback.msg_noticePp.(prlist_with_sepspcstrkey++str" is "++str(ifbthen"on"else"off"))|s->Feedback.msg_noticePp.(str"Current value of "++prlist_with_sepspcstrkey++str" is "++msg_option_values)letget_tables()=lettables=!value_tabinletfoldkey(AnyOptopt)accu=letstate={opt_depr=opt.depr;opt_value=to_option_valueopt.kind(opt.read());}inOptionMap.addkeystateaccuinOptionMap.foldfoldtablesOptionMap.emptyletprint_tables()=letopenPpinletprint_optionkeyvaluedepr=letmsg=str" "++str(nicknamekey)++str": "++msg_option_valuevalueinletdepr=pr_opt(fundepr->hov2(str"[DEPRECATED"++pr_opt(funsince->str"since "++strsince)depr.Deprecation.since++pr_optstrdepr.Deprecation.note++str"]"))deprinmsg++depr++fnl()instr"Options:"++fnl()++OptionMap.fold(funkey(AnyOptopt)p->p++print_optionkey(to_option_valueopt.kind(opt.read()))opt.depr)!value_tab(mt())++str"Tables:"++fnl()++List.fold_right(fun(nickkey,_)p->p++str" "++strnickkey++fnl())!string_table(mt())++List.fold_right(fun(nickkey,_)p->p++str" "++strnickkey++fnl())!ref_table(mt())++fnl()(* Compat *)letdeclare_int_option?preprocessosig=declare_option?preprocess~kind:IntKindosigletdeclare_bool_option?preprocessosig=declare_option?preprocess~kind:BoolKindosigletdeclare_string_option?preprocessosig=declare_option?preprocess~kind:StringKindosigletdeclare_stringopt_option?preprocessosig=declare_option?preprocess~kind:StringOptKindosig