(************************************************************************) (* * 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) *) (************************************************************************)
open Pp open CErrors open Util open System open Names open Environ
let () = at_exit flush_all
let fatal_error info anomaly =
flush_all (); Format.eprintf "@[Fatal Error: @[%a@]@]@\n%!" Pp.pp_with info; flush_all ();
exit (if anomaly then 129 else 1)
let rocq_root = Id.of_string "Corelib" let parse_dir s = let len = String.length s in let rec decoupe_dirs dirs n = if n>=len then dirs else let pos = try String.index_from s n '.' with Not_found -> len in let dir = String.sub s n (pos-n) in
decoupe_dirs (dir::dirs) (pos+1) in
decoupe_dirs [] 0 let dirpath_of_string s = match parse_dir s with
| [] -> CheckLibrary.default_root_prefix
| dir -> DirPath.make (List.map Id.of_string dir) let path_of_string s = if Filename.check_suffix s ".vo"then CheckLibrary.PhysicalFile s elsematch parse_dir s with
| [] -> invalid_arg "path_of_string"
| l::dir -> CheckLibrary.LogicalFile {dirpath=dir; basename=l}
let get_version env () = match env with
| Boot.Env.Boot -> Coq_config.version
| Env env -> try let revision = Boot.Env.(Path.to_string (revision env)) in let ch = open_in revision in let ver = input_line ch in let rev = input_line ch in let () = close_in ch in
Printf.sprintf "%s (%s)" ver rev with Sys_error _ | End_of_file -> Coq_config.version
let print_header env () =
Printf.printf "Welcome to Chicken %s\n%!" (get_version env ())
(* Adding files to Rocq loadpath *)
let add_path ~unix_path:dir ~rocq_root:rocq_dirpath = if exists_dir dir then begin
CheckLibrary.add_load_path (dir,rocq_dirpath) end else
Feedback.msg_warning (str "Cannot open " ++ str dir)
let convert_string d = try Id.of_string d with CErrors.UserError _ ->
Flags.if_verbose Feedback.msg_warning
(str "Directory " ++ str d ++ str " cannot be used as a Rocq identifier (skipped)");
raise_notrace Exit
let add_rec_path ~unix_path ~rocq_root = if exists_dir unix_path then let dirs = all_subdirs ~unix_path in let prefix = DirPath.repr rocq_root in let convert_dirs (lp, cp) = try let path = List.rev_map convert_string cp @ prefix in
Some (lp, Names.DirPath.make path) with Exit -> None in let dirs = List.map_filter convert_dirs dirs in List.iter CheckLibrary.add_load_path dirs;
CheckLibrary.add_load_path (unix_path, rocq_root) else
Feedback.msg_warning (str "Cannot open " ++ str unix_path)
(* By the option -R/-Q of the command line *) let includes = ref [] let push_include (s, alias) = includes := (s,alias) :: !includes
let set_include d p = let p = ifString.equal p "Coq"then"Corelib"else p in let p = dirpath_of_string p in
push_include (d,p)
(* Initializes the LoadPath *) let init_load_path rocqenv = (* the to_string casting won't be necessary once Boot handles
include paths *) let plugins = Boot.Env.plugins rocqenv |> Boot.Path.to_string in let theories = Boot.Env.corelib rocqenv |> Boot.Path.to_string in let user_contrib = Boot.Env.user_contrib rocqenv |> Boot.Path.to_string in let xdg_dirs = Envars.xdg_dirs in let rocqpath = Envars.coqpath in (* NOTE: These directories are searched from last to first *) (* first standard library *)
add_rec_path ~unix_path:theories ~rocq_root:(Names.DirPath.make[rocq_root]); (* then plugins *)
add_rec_path ~unix_path:plugins ~rocq_root:(Names.DirPath.make [rocq_root]); (* then user-contrib *) if Sys.file_exists user_contrib then
add_rec_path ~unix_path:user_contrib ~rocq_root:CheckLibrary.default_root_prefix; (* then directories in XDG_DATA_DIRS and XDG_DATA_HOME *) List.iter (fun s -> add_rec_path ~unix_path:s ~rocq_root:CheckLibrary.default_root_prefix)
(xdg_dirs ~warn:(fun x -> Feedback.msg_warning (str x))); (* then directories in ROCQPATH *) List.iter (fun s -> add_rec_path ~unix_path:s ~rocq_root:CheckLibrary.default_root_prefix) (rocqpath()); (* then current directory *)
add_path ~unix_path:"." ~rocq_root:CheckLibrary.default_root_prefix
let init_load_path env : unit =
NewProfile.profile "init_load_path"
(fun () -> init_load_path env)
()
let impredicative_set = reffalse let set_impredicative_set () = impredicative_set := true
let boot = reffalse let set_boot () = boot := true
let coqlib = ref None let set_coqlib v = coqlib := Some v
let indices_matter = reffalse
let enable_vm = reffalse
let make_senv () = let senv = Safe_typing.empty_environment in let senv = Safe_typing.set_impredicative_set !impredicative_set senv in let senv = Safe_typing.set_indices_matter !indices_matter senv in let senv = Safe_typing.set_VM !enable_vm senv in let senv = Safe_typing.set_allow_sprop true senv in(* be smarter later *)
Safe_typing.set_native_compiler false senv
let admit_list = ref ([] : CheckLibrary.object_file list) let add_admit s =
admit_list := path_of_string s :: !admit_list
let norec_list = ref ([] : CheckLibrary.object_file list) let add_norec s =
norec_list := path_of_string s :: !norec_list
let compile_list = ref ([] : CheckLibrary.object_file list) let add_compile s =
compile_list := path_of_string s :: !compile_list
(*s Parsing of the command line. We no longer use [Arg.parse], in order to use share [Usage.print_usage]
between coqtop and coqc. *)
let version () =
Printf.printf "The Rocq Proof Checker, version %s\n" Coq_config.version;
exit 0
(* print the usage of coqtop (or coqc) on channel co *)
let print_usage_channel co command =
output_string co command;
output_string co "coqchk options are:\n";
output_string co "\
\n -Q dir coqdir map physical dir to logical coqdir\
\n -R dir coqdir synonymous for -Q\
\n -coqlib dir set coqchk's standard library location\
\n -boot don't initialize the library paths automatically\
\n\
\n -admit module load module and dependencies without checking\
\n -norec module check module but admit dependencies without checking\
\n\
\n -d (d1,..,dn) enable specified debug messages\
\n -debug enable all debug messages\
\n -profile file output profiling info to file\
\n -where print coqchk's standard library location and exit\
\n -v, --version print coqchk version and exit\
\n -o, --output-context print the listof assumptions\
\n -m, --memory print the maximum heap size\
\n -silent disable trace of constants being checked\
\n\
\n -impredicative-set set sort Set impredicative\
\n -indices-matter levels of indices (and nonuniform parameters)\
\n contribute to the level of inductives\
\n -bytecode-compiler (yes|no) enable the vm_compute reduction machine (default is no)\
\n\
\n -h, --help print this listof options\
\n"
(* print the usage on standard error *)
let print_usage = print_usage_channel stderr
let print_usage_rocqtop () =
print_usage "Usage: coqchk modules\n\n"
let usage exitcode =
print_usage_rocqtop ();
flush stderr;
exit exitcode
open Type_errors
let anomaly_string () = str "Anomaly: " let report () = strbrk (". Please report at " ^ Coq_config.wwwbugtracker ^ ".")
| ("-v"|"--version") :: _ -> version ()
| ("-m" | "--memory") :: rem -> Check_stat.memory_stat := true; parse rem
| ("-o" | "--output-context") :: rem ->
Check_stat.output_context := true; parse rem
| "-admit" :: s :: rem -> add_admit s; parse rem
| "-admit" :: [] -> usage 1
| "-norec" :: s :: rem -> add_norec s; parse rem
| "-norec" :: [] -> usage 1
| "-silent" :: rem ->
Flags.quiet := true; parse rem
| s :: _ when s<>"" && s.[0]='-' ->
fatal_error (str "Unknown option " ++ str s) false
| s :: rem -> add_compile s; parse rem in
parse (List.tl (Array.to_list argv))
let init_profile ~file = let ch = open_out file in let fname = Filename.basename file in
NewProfile.init { output = Format.formatter_of_out_channel ch; fname; };
at_exit (fun () ->
NewProfile.finish ();
close_out ch)
(* XXX: At some point we need to either port the checker to use the
feedback system or to remove its use completely. *) let init_with_argv argv = let _fhandle = Feedback.(add_feeder (console_feedback_listener Format.err_formatter)) in try
parse_args argv; Option.iter (fun file -> init_profile ~file) !profile; if CDebug.(get_flag misc) then Printexc.record_backtrace true; let coqenv = Boot.Env.maybe_init ~boot:!boot ~coqlib:!coqlib
~warn_ignored_coqlib:CWarnings.warn_ignored_coqlib in
Flags.if_verbose (fun () -> print_header coqenv ()) (); let () = match coqenv with
| Boot -> ()
| Env coqenv -> init_load_path coqenv in (* additional loadpath, given with -R/-Q options *)
NewProfile.profile "add_load_paths" (fun () -> List.iter
(fun (unix_path, rocq_root) -> add_rec_path ~unix_path ~rocq_root)
(List.rev !includes))
();
includes := [];
make_senv () with e ->
fatal_error (str "Error during initialization :" ++ (explain_exn e)) (is_anomaly e)
let init() = init_with_argv Sys.argv
let run senv = try let senv = compile_files senv in
flush_all(); senv with e -> if CDebug.(get_flag misc) then Printexc.print_backtrace stderr;
fatal_error (explain_exn e) (is_anomaly e)
let main () = let senv = init() in let senv, opac = run senv in
Check_stat.stats (Safe_typing.env_of_safe_env senv) opac;
exit 0
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.