123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454(************************************************************************)(* * 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) *)(************************************************************************)leterror_wrong_argmsg=prerr_endlinemsg;exit1leterror_missing_args=prerr_endline("Error: extra argument expected after option "^s^".");prerr_endline"See -help for the syntax of supported options.";exit1leterror_debug()=prerr_endline"Error: The -debug option has been removed.";prerr_endline"Use the -d option for enabling debug output.";prerr_endline"For an OCaml backtrace use -bt instead.";prerr_endline"See -help for the syntax of supported options.";exit1(******************************************************************************)typenative_compiler=Coq_config.native_compiler=NativeOff|NativeOnof{ondemand:bool}typetop=TopLogicalofstring|TopPhysicalofstringtypeoption_command=|OptionSetofstringoption|OptionUnset|OptionAppendofstringtypeexport_flag=Export|Importtyperequire_injection={lib:string;prefix:stringoption;export:export_flagoption;allow_failure:bool}typeinjection_command=|OptionInjectionof(stringlist*option_command)|RequireInjectionofrequire_injection|WarnNoNativeofstring|WarnNativeDeprecatedtypecoqargs_logic_config={impredicative_set:bool;indices_matter:bool;type_in_type:bool;rewrite_rules:bool;toplevel_name:top;}typetime_config=ToFeedback|ToFileofstringtypecoqargs_config={logic:coqargs_logic_config;rcfile:stringoption;coqlib:stringoption;enable_VM:bool;native_compiler:native_compiler;native_output_dir:CUnix.physical_path;native_include_dirs:CUnix.physical_pathlist;output_directory:CUnix.physical_pathoption;exclude_dirs:CUnix.physical_pathlist;beautify:bool;quiet:bool;time:time_configoption;test_mode:bool;profile:stringoption;print_emacs:bool;}typevo_path={implicit:bool;unix_path:string;rocq_path:string;}typecoqargs_pre={boot:bool;load_init:bool;load_rcfile:bool;ml_includes:stringlist;vo_includes:vo_pathlist;load_vernacular_list:(string*bool)list;injections:injection_commandlist;}typecoqargs_query=|PrintWhere|PrintConfig|PrintVersion|PrintMachineReadableVersion|PrintHelptypecoqargs_main=|Queriesofcoqargs_querylist|Runtypecoqargs_post={memory_stat:bool;}typet={config:coqargs_config;pre:coqargs_pre;main:coqargs_main;post:coqargs_post;}letdefault_toplevel="Top"letdefault_native=Coq_config.native_compilerletdefault_logic_config={impredicative_set=false;indices_matter=false;type_in_type=false;rewrite_rules=false;toplevel_name=TopLogicaldefault_toplevel;}letdefault_config={logic=default_logic_config;rcfile=None;coqlib=None;enable_VM=true;native_compiler=default_native;native_output_dir=".coq-native";native_include_dirs=[];output_directory=None;exclude_dirs=[];beautify=false;quiet=false;time=None;test_mode=false;profile=None;print_emacs=false;(* Quiet / verbosity options should be here *)}letdefault_pre={boot=false;load_init=true;load_rcfile=true;ml_includes=[];vo_includes=[];load_vernacular_list=[];injections=[];}letdefault_queries=[]letdefault_post={memory_stat=false;}letdefault={config=default_config;pre=default_pre;main=Run;post=default_post;}(******************************************************************************)(* Functional arguments *)(******************************************************************************)letadd_ml_includeoptss={optswithpre={opts.prewithml_includes=s::opts.pre.ml_includes}}letadd_vo_includeoptsunix_pathrocq_pathimplicit=letv={unix_path;rocq_path;implicit;}in{optswithpre={opts.prewithvo_includes=v::opts.pre.vo_includes}}letadd_vo_requireoptsd?(allow_failure=false)pexport={optswithpre={opts.prewithinjections=RequireInjection{lib=d;prefix=p;export;allow_failure}::opts.pre.injections}}letadd_load_vernacularoptsverbs={optswithpre={opts.prewithload_vernacular_list=(CUnix.make_suffixs".v",verb)::opts.pre.load_vernacular_list}}letadd_set_optionoptsopt_namevalue={optswithpre={opts.prewithinjections=OptionInjection(opt_name,value)::opts.pre.injections}}letadd_set_debugoptsflags=add_set_optionopts["Debug"](OptionAppendflags)(** Options for proof general *)letset_emacsopts=letopts=add_set_optionopts["Printing";"Goal";"Tags"](OptionSetNone)in{optswithconfig={opts.configwithprint_emacs=true}}letset_logicfoval={ovalwithconfig={oval.configwithlogic=foval.config.logic}}letset_queryoptsq={optswithmain=matchopts.mainwith|Run->Queries(default_queries@[q])|Queriesqueries->Queries(queries@[q])}(******************************************************************************)(* Parsing helpers *)(******************************************************************************)letget_bool~opt=function|"yes"|"on"->true|"no"|"off"->false|_->error_wrong_arg("Error: yes/no expected after option "^opt^".")letget_int~optn=tryint_of_stringnwithFailure_->error_wrong_arg("Error: integer expected after option "^opt^".")letget_int_opt~optn=ifn=""thenNoneelseSome(get_int~optn)letget_float~optn=tryfloat_of_stringnwithFailure_->error_wrong_arg("Error: float expected after option "^opt^".")letto_opt_key=Str.(split(regexp" +"))letparse_option_setopt=matchString.index_optopt'='with|None->to_opt_keyopt,None|Someeqi->letlen=String.lengthoptinletv=String.subopt(eqi+1)(len-eqi-1)into_opt_key(String.subopt0eqi),Somevletget_native_compilers=(* We use two boolean flags because the four states make sense, even if
only three are accessible to the user at the moment. The selection of the
produced artifact(s) (`.vo`, `.coq-native`, ...) should be done by
a separate flag, and the "ondemand" value removed. Once this is done, use
[get_bool] here. *)letn=matchswith|("yes"|"on")->NativeOn{ondemand=false}|"ondemand"->NativeOn{ondemand=true}|("no"|"off")->NativeOff|_->error_wrong_arg("Error: (yes|no|ondemand) expected after option -native-compiler.")inifn=NativeOffthenn,[]elseifCoq_config.native_compiler=NativeOffthenNativeOff,[WarnNativeDeprecated;WarnNoNatives]elsen,[WarnNativeDeprecated](* Main parsing routine *)(*s Parsing of the command line *)letparse_args~initarglist:t*stringlist=letargs=refarglistinletextras=ref[]inletrecparseoval=match!argswith|[]->(oval,List.rev!extras)|opt::rem->args:=rem;letnext()=match!argswith|x::rem->args:=rem;x|[]->error_missing_argoptinletnoval=beginmatchoptwith(* Complex options with many args *)|"-I"|"-include"->add_ml_includeoval(next())|"-Q"->letd=next()inletp=next()inletp=ifString.equalp"Coq"then"Corelib"elsepinadd_vo_includeovaldpfalse|"-R"->letd=next()inletp=next()inletp=ifString.equalp"Coq"then"Corelib"elsepin(* -R Coq ... is only used by Dune in conjunction with the -boot
option. The above line should be removed once we require an
updated version of Dune. *)add_vo_includeovaldptrue(* Options with one arg *)|"-coqlib"->{ovalwithconfig={oval.configwithcoqlib=Some(next())}}|"-compat"->letarg=String.split_on_char'.'(next())inletrocq_name=matchargwith"8"::_->"Coq"|_->"Rocq"in(* remove the above and replace by "Rocq" once theories/Compat/Coq820.v is removed *)letxy=String.concat""(rocq_name::arg)inadd_vo_requireovalxy~allow_failure:true(Some"Stdlib")(SomeImport)|"-exclude-dir"->{ovalwithconfig={oval.configwithexclude_dirs=next()::oval.config.exclude_dirs}}|"-init-file"->{ovalwithconfig={oval.configwithrcfile=Some(next());}}|"-load-vernac-source"|"-l"->add_load_vernacularovalfalse(next())|"-load-vernac-source-verbose"|"-lv"->add_load_vernacularovaltrue(next())|"-mangle-names"->letoval=add_set_optionoval["Mangle";"Names"](OptionSetNone)inadd_set_optionoval["Mangle";"Names";"Prefix"](OptionSet(Some(next())))|"-profile-ltac-cutoff"->letoval=add_set_optionoval["Ltac";"Profiling"](OptionSetNone)inadd_set_optionoval["Ltac";"Profiling";"Cutoff"](OptionSet(Some(next())))|"-load-vernac-object"|"-require"->add_vo_requireoval(next())NoneNone|"-require-import"|"-ri"->add_vo_requireoval(next())None(SomeImport)|"-require-export"|"-re"->add_vo_requireoval(next())None(SomeExport)|"-require-from"|"-rfrom"->letfrom=next()inadd_vo_requireoval(next())(Somefrom)None|"-compat-from"->letfrom=next()inadd_vo_requireoval(next())~allow_failure:true(Somefrom)(SomeImport)|"-require-import-from"|"-rifrom"->letfrom=next()inadd_vo_requireoval(next())(Somefrom)(SomeImport)|"-require-export-from"|"-refrom"->letfrom=next()inadd_vo_requireoval(next())(Somefrom)(SomeExport)|"-top"->lettopname=next()inifCString.is_emptytopnamethenerror_wrong_arg"Need a non empty toplevel module name.";{ovalwithconfig={oval.configwithlogic={oval.config.logicwithtoplevel_name=TopLogicaltopname}}}|"-topfile"->{ovalwithconfig={oval.configwithlogic={oval.config.logicwithtoplevel_name=TopPhysical(next())}}}|"-w"|"-W"->letw=next()inifw="none"thenadd_set_optionoval["Warnings"](OptionSet(Somew))elseadd_set_optionoval["Warnings"](OptionAppendw)|"-bytecode-compiler"->{ovalwithconfig={oval.configwithenable_VM=get_bool~opt(next())}}|"-native-compiler"->letnative_compiler,warn=get_native_compiler(next())in{ovalwithconfig={oval.configwithnative_compiler};pre={oval.prewithinjections=warn@oval.pre.injections}}|"-set"->letopt,v=parse_option_set@@next()inadd_set_optionovalopt(OptionSetv)|"-unset"->add_set_optionoval(to_opt_key@@next())OptionUnset|"-native-output-dir"->letnative_output_dir=next()in{ovalwithconfig={oval.configwithnative_output_dir}}|"-output-dir"|"-output-directory"->letdir=next()inletdir=ifFilename.is_relativedirthenFilename.concat(Sys.getcwd())direlsedirin{ovalwithconfig={oval.configwithoutput_directory=Somedir}}|"-nI"->letinclude_dir=next()in{ovalwithconfig={oval.configwithnative_include_dirs=include_dir::oval.config.native_include_dirs}}(* Options with zero arg *)|"-test-mode"->{ovalwithconfig={oval.configwithtest_mode=true}}|"-beautify"->{ovalwithconfig={oval.configwithbeautify=true}}|"-config"|"--config"->set_queryovalPrintConfig|"-bt"->add_set_debugoval"backtrace"(* -debug is deprecated *)|"-debug"->error_debug()|"-d"|"-D"->add_set_debugoval(next())|"-diffs"->add_set_optionoval["Diffs"]@@OptionSet(Some(next()))|"-emacs"->set_emacsoval|"-impredicative-set"->set_logic(funo->{owithimpredicative_set=true})oval|"-allow-sprop"->add_set_optionoval["Allow";"StrictProp"](OptionSetNone)|"-disallow-sprop"->add_set_optionoval["Allow";"StrictProp"]OptionUnset|"-allow-rewrite-rules"->set_logic(funo->{owithrewrite_rules=true})oval|"-indices-matter"->set_logic(funo->{owithindices_matter=true})oval|"-m"|"--memory"->{ovalwithpost={memory_stat=true}}|"-noinit"|"-nois"->{ovalwithpre={oval.prewithload_init=false}}|"-boot"->{ovalwithpre={oval.prewithboot=true}}|"-profile-ltac"->add_set_optionoval["Ltac";"Profiling"](OptionSetNone)|"-q"->{ovalwithpre={oval.prewithload_rcfile=false;}}|"-quiet"|"-silent"->{ovalwithconfig={oval.configwithquiet=true}}|"-time"->{ovalwithconfig={oval.configwithtime=SomeToFeedback}}|"-time-file"->{ovalwithconfig={oval.configwithtime=Some(ToFile(next()))}}|"-profile"->{ovalwithconfig={oval.configwithprofile=Some(next())}}|"-type-in-type"->set_logic(funo->{owithtype_in_type=true})oval|"-unicode"->add_vo_requireoval"Utf8_core"None(SomeImport)|"-where"->set_queryovalPrintWhere|"-h"|"-H"|"-?"|"-help"|"--help"->set_queryovalPrintHelp|"-v"|"--version"->set_queryovalPrintVersion|"-print-version"|"--print-version"->set_queryovalPrintMachineReadableVersion(* Unknown option *)|s->extras:=s::!extras;ovalendinparsenovalinparseinit(* We need to reverse a few lists *)letparse_args~initargs=letopts,extra=parse_args~initargsinletopts={optswithpre={opts.prewithml_includes=List.revopts.pre.ml_includes;vo_includes=List.revopts.pre.vo_includes;load_vernacular_list=List.revopts.pre.load_vernacular_list;injections=List.revopts.pre.injections}}inopts,extra(******************************************************************************)(* Startup LoadPath and Modules *)(******************************************************************************)(* prelude_data == From Corelib Require Import Prelude. *)letprelude_data=RequireInjection{lib="Prelude";prefix=Some"Corelib";export=SomeImport;allow_failure=false}letinjection_commandsopts=ifopts.pre.load_initthenprelude_data::opts.pre.injectionselseopts.pre.injections