123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255(************************************************************************)(* * The Coq Proof Assistant / The Coq 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) *)(************************************************************************)openPpopenCoqargs(** This file provides generic support for Coq executables + specific
support for the coqtop executable *)let()=at_exitflush_alllet(/)=Filename.concatletget_version()=tryletch=open_in(Envars.coqlib()/"revision")inletver=input_linechinletrev=input_linechinlet()=close_inchinPrintf.sprintf"%s (%s)"verrevwith_->Coq_config.versionletprint_header()=Feedback.msg_info(str"Welcome to Coq "++str(get_version()));flush_all()(******************************************************************************)(* Fatal Errors *)(******************************************************************************)(** Prints info which is either an error or an anomaly and then exits
with the appropriate error code *)letfatal_error_exnexn=Topfmt.(in_phase~phase:Initializationprint_err_exnexn);flush_all();letexit_code=if(CErrors.is_anomalyexn)then129else1inexitexit_codetype('a,'b)custom_toplevel={parse_extra:stringlist->'a*stringlist;usage:Usage.specific_usage;init_extra:'a->Coqargs.injection_commandlist->opts:Coqargs.t->'b;initial_args:Coqargs.t;run:'a->opts:Coqargs.t->'b->unit}(** Main init routine *)letinit_toplevel{parse_extra;init_extra;usage;initial_args}=Coqinit.init_ocaml();letopts,customopts=Coqinit.parse_arguments~parse_extra~usage~initial_args()inStm.init_process(sndcustomopts);letinjections=Coqinit.init_runtimeoptsin(* This state will be shared by all the documents *)Stm.init_core();letcustomstate=init_extra~optscustomoptsinjectionsinopts,customopts,customstateletstart_coqcustom=letinit_feeder=Feedback.add_feederCoqloop.coqloop_feedin(* Init phase *)letopts,custom_opts,state=tryinit_toplevelcustomwithany->flush_all();fatal_error_exnanyinFeedback.del_feederinit_feeder;(* Run phase *)custom.run~optscustom_optsstate(** ****************************************)(** Specific support for coqtop executable *)typecolor=[`ON|`AUTO|`EMACS|`OFF]letinit_coloropts=lethas_color=matchoptswith|`OFF->false|`EMACS->false|`ON->true|`AUTO->Terminal.has_styleUnix.stdout&&Terminal.has_styleUnix.stderr&&(* emacs compilation buffer does not support colors by default,
its TERM variable is set to "dumb". *)trySys.getenv"TERM"<>"dumb"withNot_found->falseinletterm_color=ifhas_colorthenbeginletcolors=trySome(Sys.getenv"COQ_COLORS")withNot_found->Noneinmatchcolorswith|None->Topfmt.default_styles();true(* Default colors *)|Some""->false(* No color output *)|Somes->Topfmt.parse_color_configs;true(* Overwrite all colors *)endelsebeginTopfmt.default_styles();false(* textual markers, no color *)endinifopts=`EMACSthenTopfmt.set_emacs_print_strings()elseifnotterm_colorthenbeginProof_diffs.write_color_enabledterm_color;ifProof_diffs.show_diffs()then(prerr_endline"Error: -diffs requires enabling -color";exit1)end;Topfmt.init_terminal_output~color:term_colorletprint_style_tagsopts=let()=init_coloroptsinlettags=Topfmt.dump_tags()inletiter(t,st)=letopt=Terminal.evalst^t^Terminal.reset^"\n"inprint_stringoptinletmake(t,st)=lettags=List.mapstring_of_int(Terminal.reprst)in(t^"="^String.concat";"tags)inletrepr=List.mapmaketagsinlet()=Printf.printf"COQ_COLORS=\"%s\"\n"(String.concat":"repr)inlet()=List.iteritertagsinflush_all()letltac_debug_answer=letopenDebugHook.Answerinfunction|Promptprompt->(* No newline *)Format.fprintf!Topfmt.err_ft"@[%a@]%!"Pp.pp_withprompt|Goalg->Format.fprintf!Topfmt.err_ft"@[%a@]@\n%!"Pp.pp_with(str"Goal:"++fnl()++g)|Outputo->Format.fprintf!Topfmt.err_ft"@[%a@]@\n%!"Pp.pp_witholetltac_debug_parse()=letopenDebugHookinletact=tryAction.parse(read_line())withEnd_of_file->OkAction.Exitinmatchactwith|Okact->act|Errorerror->ltac_debug_answer(Answer.Output(strerror));Action.Failedtypequery=PrintTags|PrintModUidofstringlisttyperun_mode=Interactive|Batch|Queryofquerytypetoplevel_options={run_mode:run_mode;color_mode:color;}letinit_documentoptsstm_optionsinjections=(* Coq init process, phase 3: Stm initialization, backtracking state.
It is essential that the module system is in a consistent
state before we take the first snapshot. This was not
guaranteed in the past, but now is thanks to the STM API.
*)(* Next line allows loading .vos files when in interactive mode *)Flags.load_vos_libraries:=true;letopenVernac.Stateinletdoc,sid=Stm.(new_doc{doc_type=Interactiveopts.config.logic.toplevel_name;injections;stm_options;})in{doc;sid;proof=None;time=opts.config.time}letinit_toploopoptsstm_optsinjections=letstate=init_documentoptsstm_optsinjectionsinletstate=Ccompile.load_init_vernacularsopts~stateinstateletcoqtop_init({run_mode;color_mode},async_opts)injections~opts=ifrun_mode!=InteractivethenFlags.quiet:=true;init_color(ifopts.config.print_emacsthen`EMACSelsecolor_mode);Flags.if_verboseprint_header();DebugHook.Intf.(set{read_cmd=ltac_debug_parse;submit_answer=ltac_debug_answer});init_toploopoptsasync_optsinjectionsletset_color=function|"yes"|"on"->`ON|"no"|"off"->`OFF|"auto"->`AUTO|_->error_wrong_arg("Error: on/off/auto expected after option color")letparse_extra_colorsextras=letrecparse_extracolor_mode=function|"-color"::next::rest->parse_extra(set_colornext)rest|"-list-tags"::rest->parse_extracolor_moderest|x::rest->letcolor_mode,rest=parse_extracolor_moderestincolor_mode,x::rest|[]->color_mode,[]inparse_extra`AUTOextrasletcoqtop_parse_extraextras=letrecparse_extrarun_mode=function|"-batch"::rest->parse_extraBatchrest|"-print-mod-uid"::rest->Query(PrintModUidrest),[]|x::rest->letrun_mode,rest=parse_extrarun_moderestinrun_mode,x::rest|[]->run_mode,[]inletrun_mode,extras=parse_extraInteractiveextrasinletcolor_mode,extras=parse_extra_colorsextrasinletasync_opts,extras=Stmargs.parse_args~init:Stm.AsyncOpts.default_optsextrasin({run_mode;color_mode},async_opts),extrasletget_native_names=(* We ignore even critical errors because this mode has to be super silent *)tryFilename.(List.fold_leftconcat(dirnames)[!Nativelib.output_dir;Library.native_name_from_filenames])with_->""letcoqtop_run({run_mode;color_mode},_)~optsstate=matchrun_modewith|Interactive->Coqloop.loop~opts~state;|QueryPrintTags->print_style_tagscolor_mode;exit0|Query(PrintModUidsl)->lets=String.concat" "(List.mapget_native_namesl)inprint_endlines;exit0|Batch->exit0letcoqtop_specific_usage=Usage.{executable_name="coqtop";extra_args="";extra_options="\n\
coqtop specific options:\n\
\n -batch batch mode (exits after interpretation of command line)\
\n"}letcoqtop_toplevel={parse_extra=coqtop_parse_extra;usage=coqtop_specific_usage;init_extra=coqtop_init;run=coqtop_run;initial_args=Coqargs.default}