aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--config/coq_config.mli2
-rwxr-xr-xconfigure2
-rw-r--r--contrib/xml/xmlcommand.ml7
-rw-r--r--lib/system.ml95
-rw-r--r--lib/system.mli24
-rw-r--r--library/library.ml33
-rw-r--r--library/library.mli5
-rw-r--r--parsing/g_basevernac.ml43
-rwxr-xr-xtools/coqdep.ml5
-rw-r--r--toplevel/coqinit.ml36
-rw-r--r--toplevel/coqinit.mli5
-rw-r--r--toplevel/coqtop.ml2
-rw-r--r--toplevel/mltop.ml413
-rw-r--r--toplevel/vernac.ml2
-rw-r--r--toplevel/vernacentries.ml5
16 files changed, 137 insertions, 108 deletions
diff --git a/Makefile b/Makefile
index 144c806fe..50490451d 100644
--- a/Makefile
+++ b/Makefile
@@ -355,13 +355,15 @@ COQDEPCMO=config/coq_config.cmo tools/coqdep_lexer.cmo tools/coqdep.cmo
$(COQDEP): $(COQDEPCMO)
$(OCAMLC) $(BYTEFLAGS) -custom -o $@ unix.cma $(COQDEPCMO) $(OSDEPLIBS)
-beforedepend:: $(COQDEP)
+beforedepend:: tools/coqdep_lexer.ml $(COQDEP)
GALLINACMO=tools/gallina_lexer.cmo tools/gallina.cmo
$(GALLINA): $(GALLINACMO)
$(OCAMLC) $(BYTEFLAGS) -custom -o $@ $(GALLINACMO)
+beforedepend:: tools/gallina_lexer.ml
+
$(COQMAKEFILE): tools/coq_makefile.ml
$(OCAMLC) $(BYTEFLAGS) -custom -o $@ tools/coq_makefile.ml
@@ -415,6 +417,8 @@ install-library:
$(MKDIR) $(COQLIB)/`dirname $$f`; \
cp $$f $(COQLIB)/`dirname $$f`; \
done
+ $(MKDIR) $(COQLIB)/states
+ cp states/*.coq $(COQLIB)/states
$(MKDIR) $(EMACSLIB)
cp tools/coq.el tools/coq.elc $(EMACSLIB)
diff --git a/config/coq_config.mli b/config/coq_config.mli
index be3fd4cbc..b7731b8ab 100644
--- a/config/coq_config.mli
+++ b/config/coq_config.mli
@@ -23,5 +23,5 @@ val date : string (* release date *)
val compile_date : string (* compile date *)
val theories_dirs : string list
-val tactics_dirs : string list
+val contrib_dirs : string list
diff --git a/configure b/configure
index a5f4ad7a9..ec815942a 100755
--- a/configure
+++ b/configure
@@ -473,7 +473,7 @@ echo_e "\nlet theories_dirs = [" >> $mlconfig_file
subdirs theories
echo_e "]\n" >> $mlconfig_file
-echo_e "\nlet tactics_dirs = [" >> $mlconfig_file
+echo_e "\nlet contrib_dirs = [" >> $mlconfig_file
subdirs contrib
echo_e "]\n" >> $mlconfig_file
diff --git a/contrib/xml/xmlcommand.ml b/contrib/xml/xmlcommand.ml
index 47a800b68..a321ce1ab 100644
--- a/contrib/xml/xmlcommand.ml
+++ b/contrib/xml/xmlcommand.ml
@@ -110,7 +110,8 @@ let uri_of_path sp =
match sl with
[] -> assert false (*V7 WHAT NOW? *)
| module_name::_ ->
- trim_wrong_uri_prefix (Library.module_filename module_name)
+ let _,file = Library.module_filename module_name in
+ trim_wrong_uri_prefix file
in
"cic:" ^ module_path ^ "/" ^ (String.concat "/" sl) ^ "/" ^
(N.string_of_id id) ^ "." ^ (ext_of_sp sp)
@@ -786,10 +787,10 @@ let printModule id dn =
let sp = Lib.make_path id N.OBJ in
let ls = L.module_segment (Some str) in
print_if_verbose ("MODULE_BEGIN " ^ str ^ " " ^ N.string_of_path sp ^ " " ^
- L.module_filename str ^ "\n") ;
+ (snd (L.module_filename str)) ^ "\n") ;
print_closed_section str ls dn ;
print_if_verbose ("MODULE_END " ^ str ^ " " ^ N.string_of_path sp ^ " " ^
- L.module_filename str ^ "\n")
+ (snd (L.module_filename str)) ^ "\n")
;;
(* printSection identifier directory_name *)
diff --git a/lib/system.ml b/lib/system.ml
index 8c8dca7ba..fd7e93bd0 100644
--- a/lib/system.ml
+++ b/lib/system.ml
@@ -8,15 +8,23 @@ open Unix
(* Files and load path. *)
(* All subdirectories, recursively *)
+type load_path_entry = {
+ directory : string;
+ root_dir : string;
+ relative_subdir : string }
+
+type load_path = load_path_entry list
+
let exists_dir dir =
try let _ = opendir dir in true
with Unix_error _ -> false
-let all_subdirs dir =
+let all_subdirs root =
let l = ref [] in
- let add f = l := f :: !l in
- let rec traverse dir =
- Printf.printf "%s\n" dir;
+ let add f rel =
+ l := { directory = f; root_dir = root; relative_subdir = rel } :: !l
+ in
+ let rec traverse dir rel =
let dirh =
try opendir dir with Unix_error _ -> invalid_arg "all_subdirs"
in
@@ -26,14 +34,15 @@ let all_subdirs dir =
if f <> "." && f <> ".." then
let file = Filename.concat dir f in
if (stat file).st_kind = S_DIR then begin
- add file;
- traverse file
+ let newrel = Filename.concat rel f in
+ add file newrel;
+ traverse file newrel
end
done
with End_of_file ->
closedir dirh
in
- traverse dir; List.rev !l
+ traverse root ""; List.rev !l
let safe_getenv_def var def =
try
@@ -49,9 +58,9 @@ let glob s = s
let search_in_path path filename =
let rec search = function
- | dir :: rem ->
- let f = glob (Filename.concat dir filename) in
- if Sys.file_exists f then f else search rem
+ | lpe :: rem ->
+ let f = glob (Filename.concat lpe.directory filename) in
+ if Sys.file_exists f then (lpe,f) else search rem
| [] ->
raise Not_found
in
@@ -62,7 +71,8 @@ let where_in_path = search_in_path
let find_file_in_path paths name =
let globname = glob name in
if not (Filename.is_relative globname) then
- globname
+ let root = Filename.dirname globname in
+ { directory = root; root_dir = root; relative_subdir = "" }, globname
else
try
search_in_path paths name
@@ -97,47 +107,40 @@ let marshal_in ch = Marshal.from_channel ch
exception Bad_magic_number of string
-let (raw_extern_intern :
- int -> string ->
- (string -> string * out_channel)
- * (string list -> string -> string * in_channel))
- = fun magic suffix ->
- let extern_state name =
- let (_,channel) as filec =
- open_trapping_failure (fun n -> n,open_out_bin n) name suffix in
- output_binary_int channel magic;
- filec
- and intern_state paths name =
- let fname = find_file_in_path paths (make_suffix name suffix) in
- let channel = open_in_bin fname in
- if input_binary_int channel <> magic then
- raise (Bad_magic_number fname);
- (fname,channel)
- in
- (extern_state,intern_state)
-
-let (extern_intern :
- int -> string -> (string -> 'a -> unit) * (string list -> string -> 'a))
- = fun magic suffix ->
- let (raw_extern,raw_intern) = raw_extern_intern magic suffix in
- let extern_state name val_0 =
- try
- let (fname,channel) = raw_extern name in
- try
- marshal_out channel val_0;
- close_out channel
- with e ->
- begin try_remove fname; raise e end
- with Sys_error s -> error ("System error: " ^ s)
+let raw_extern_intern magic suffix =
+ let extern_state name =
+ let (_,channel) as filec =
+ open_trapping_failure (fun n -> n,open_out_bin n) name suffix in
+ output_binary_int channel magic;
+ filec
+ and intern_state paths name =
+ let lpe,fname = find_file_in_path paths (make_suffix name suffix) in
+ let channel = open_in_bin fname in
+ if input_binary_int channel <> magic then
+ raise (Bad_magic_number fname);
+ (lpe,fname,channel)
+ in
+ (extern_state,intern_state)
+let extern_intern magic suffix =
+ let (raw_extern,raw_intern) = raw_extern_intern magic suffix in
+ let extern_state name val_0 =
+ try
+ let (fname,channel) = raw_extern name in
+ try
+ marshal_out channel val_0;
+ close_out channel
+ with e ->
+ begin try_remove fname; raise e end
+ with Sys_error s -> error ("System error: " ^ s)
and intern_state paths name =
try
- let (fname,channel) = raw_intern paths name in
+ let (_,fname,channel) = raw_intern paths name in
let v = marshal_in channel in
close_in channel;
v
- with Sys_error s -> error("System error: " ^ s)
-
+ with Sys_error s ->
+ error("System error: " ^ s)
in
(extern_state,intern_state)
diff --git a/lib/system.mli b/lib/system.mli
index da5effca8..18dae1915 100644
--- a/lib/system.mli
+++ b/lib/system.mli
@@ -1,11 +1,20 @@
(* $Id$ *)
-(*s Files. *)
+(*s Files and load paths. Load path entries remember the original root
+ given by the user. For efficiency, we keep the full path (field
+ [directory]), the root path and the path relative to the root. *)
-val all_subdirs : string -> string list
-val is_in_path : string list -> string -> bool
-val where_in_path : string list -> string -> string
+type load_path_entry = {
+ directory : string;
+ root_dir : string;
+ relative_subdir : string }
+
+type load_path = load_path_entry list
+
+val all_subdirs : string -> load_path
+val is_in_path : load_path -> string -> bool
+val where_in_path : load_path -> string -> load_path_entry * string
val make_suffix : string -> string -> string
val file_readable_p : string -> bool
@@ -16,7 +25,7 @@ val home : string
val exists_dir : string -> bool
-val find_file_in_path : string list -> string -> string
+val find_file_in_path : load_path -> string -> load_path_entry * string
(*s Generic input and output functions, parameterized by a magic number
and a suffix. The intern functions raise the exception [Bad_magic_number]
@@ -29,11 +38,10 @@ exception Bad_magic_number of string
val raw_extern_intern : int -> string ->
(string -> string * out_channel) *
- (path:string list -> string -> string * in_channel)
+ (load_path -> string -> load_path_entry * string * in_channel)
val extern_intern :
- int -> string -> (string -> 'a -> unit) *
- (path:string list -> string -> 'a)
+ int -> string -> (string -> 'a -> unit) * (load_path -> string -> 'a)
(*s Time stamps. *)
diff --git a/library/library.ml b/library/library.ml
index 4a76bff1c..ca4309634 100644
--- a/library/library.ml
+++ b/library/library.ml
@@ -3,33 +3,28 @@
open Pp
open Util
+open System
open Names
open Environ
open Libobject
open Lib
-(*s Load path. Used for commands Add Path, Remove Path, Print Path *)
+(*s Load path. *)
-let loadpath_name = "LoadPath"
+let load_path = ref ([] : load_path)
-module LoadPath = struct
- let check s = if not (System.exists_dir s) then warning (s^" was not found")
- let key = Goptions.PrimaryTable loadpath_name
- let title = "Load Paths for Coq files"
- let member_message s b =
- if b then s^" is declared in the load path for Coq files"
- else s^" is not declared in the load path for Coq files"
- let synchronous = false
-end
+let get_load_path () = !load_path
-module LoadPathTable = Goptions.MakeStringTable(LoadPath)
+let add_load_path_entry lpe = load_path := lpe :: !load_path
-let get_load_path = LoadPathTable.elements
let add_path dir =
- (Goptions.get_string_table (Goptions.PrimaryTable loadpath_name))#add dir
+ add_load_path_entry { directory = dir; root_dir = dir; relative_subdir = "" }
+
let remove_path dir =
- (Goptions.get_string_table (Goptions.PrimaryTable loadpath_name))#remove dir
-let rec_add_path dir = List.iter add_path (System.all_subdirs dir)
+ load_path := List.filter (fun lpe -> lpe.directory <> dir) !load_path
+
+let rec_add_path dir =
+ load_path := (all_subdirs dir) @ !load_path
(*s Modules on disk contain the following informations (after the magic
number, and before the digest). *)
@@ -45,7 +40,7 @@ type module_disk = {
type module_t = {
module_name : string;
- module_filename : string;
+ module_filename : load_path_entry * string;
module_compiled_env : compiled_env;
module_declarations : library_segment;
mutable module_opened : bool;
@@ -129,12 +124,12 @@ let load_objects decls =
segment_iter load_object decls
let rec load_module_from s f =
- let (fname,ch) = raw_intern_module (get_load_path ()) f in
+ let (lpe,fname,ch) = raw_intern_module (get_load_path ()) f in
let md = System.marshal_in ch in
let digest = System.marshal_in ch in
close_in ch;
let m = { module_name = md.md_name;
- module_filename = fname;
+ module_filename = (lpe,fname);
module_compiled_env = md.md_compiled_env;
module_declarations = md.md_declarations;
module_opened = false;
diff --git a/library/library.mli b/library/library.mli
index 474669452..cac8767d5 100644
--- a/library/library.mli
+++ b/library/library.mli
@@ -38,10 +38,11 @@ val save_module_to : string -> string -> unit
[module_filename] returns the full filename of a loaded module. *)
val module_segment : string option -> Lib.library_segment
-val module_filename : string -> string
+val module_filename : string -> System.load_path_entry * string
(*s Global load path *)
-val get_load_path : unit -> string list
+val get_load_path : unit -> System.load_path
+val add_load_path_entry : System.load_path_entry -> unit
val add_path : string -> unit
val rec_add_path : string -> unit
val remove_path : string -> unit
diff --git a/parsing/g_basevernac.ml4 b/parsing/g_basevernac.ml4
index e8b40ccea..ff6b3e24d 100644
--- a/parsing/g_basevernac.ml4
+++ b/parsing/g_basevernac.ml4
@@ -88,8 +88,7 @@ GEXTEND Gram
| IDENT "AddPath"; dir = stringarg; "." -> <:ast< (ADDPATH $dir) >>
| IDENT "DelPath"; dir = stringarg; "." -> <:ast< (DELPATH $dir) >>
| IDENT "Print"; IDENT "LoadPath"; "." -> <:ast< (PrintPath) >>
- | IDENT "AddRecPath"; dir = stringarg; "." ->
- <:ast< (RECADDPATH $dir) >>
+ | IDENT "AddRecPath"; dir = stringarg; "." -> <:ast< (RECADDPATH $dir) >>
| IDENT "Print"; IDENT "Modules"; "." -> <:ast< (PrintModules) >>
| IDENT "Print"; "Proof"; id = identarg; "." ->
diff --git a/tools/coqdep.ml b/tools/coqdep.ml
index 16b0e4809..0c9407cb2 100755
--- a/tools/coqdep.ml
+++ b/tools/coqdep.ml
@@ -397,9 +397,10 @@ let coqdep () =
Coq_config.theories_dirs;
let tactics = Filename.concat !coqlib "tactics" in
add_coqlib_directory tactics;
+ let contrib = Filename.concat !coqlib "contrib" in
List.iter
- (fun s -> add_coqlib_directory (Filename.concat tactics s))
- Coq_config.tactics_dirs;
+ (fun s -> add_coqlib_directory (Filename.concat contrib s))
+ Coq_config.contrib_dirs;
mliKnown := !mliKnown @ (List.map (fun (f,_,d) -> (f,d)) !mliAccu);
mlKnown := !mlKnown @ (List.map (fun (f,_,d) -> (f,d)) !mlAccu);
vKnown := !vKnown @ !vAccu;
diff --git a/toplevel/coqinit.ml b/toplevel/coqinit.ml
index 96b594106..432f6c5e0 100644
--- a/toplevel/coqinit.ml
+++ b/toplevel/coqinit.ml
@@ -45,10 +45,15 @@ let add_include s =
Mltop.dir_ml_dir s;
Library.add_path s
+let add_rec_include s =
+ let subdirs = all_subdirs s in
+ List.iter (fun lpe -> Mltop.dir_ml_dir lpe.directory) subdirs;
+ List.iter Library.add_load_path_entry subdirs
+
(* By the option -include -I or -R of the command line *)
let includes = ref []
-let push_include s = includes := s :: !includes
-let rec_include s = includes := (all_subdirs s) @ !includes
+let push_include s = includes := (s,false) :: !includes
+let push_rec_include s = includes := (s,true) :: !includes
(* Because find puts "./" and the loadpath is not nicely pretty-printed *)
let hm2 s =
@@ -59,22 +64,31 @@ let getenv_else s dft = try Sys.getenv s with Not_found -> dft
(* Initializes the LoadPath according to COQLIB and Coq_config *)
let init_load_path () =
- if Coq_config.local then
+ if Coq_config.local then begin
(* local use (no installation) *)
List.iter
(fun s -> add_include (Filename.concat Coq_config.coqtop s))
- ("states" :: "dev" ::
- (List.map
- (fun s -> Filename.concat "theories" (hm2 s))
- Coq_config.theories_dirs))
- else begin
- (* default load path; only if COQLIB is defined *)
+ ["states"; "dev"];
+ let theories = Filename.concat Coq_config.coqtop "theories" in
+ List.iter
+ (fun s -> add_include (Filename.concat theories (hm2 s)))
+ Coq_config.theories_dirs;
+ add_include (Filename.concat Coq_config.coqtop "tactics");
+ let contrib = Filename.concat Coq_config.coqtop "contrib" in
+ List.iter
+ (fun s -> add_include (Filename.concat contrib (hm2 s)))
+ Coq_config.contrib_dirs
+ end else begin
+ (* default load path; variable COQLIB overrides the default library *)
let coqlib = getenv_else "COQLIB" Coq_config.coqlib in
- add_include coqlib
+ add_rec_include coqlib
end;
let camlp4 = getenv_else "CAMLP4LIB" Coq_config.camlp4lib in
add_include camlp4;
add_include ".";
(* additional loadpath, given with -I -include -R options *)
- List.iter add_include (List.rev !includes);
+ List.iter
+ (fun (s,reci) -> if reci then add_rec_include s else add_include s)
+ (List.rev !includes);
includes := []
+
diff --git a/toplevel/coqinit.mli b/toplevel/coqinit.mli
index ca74f9ec7..7baa825be 100644
--- a/toplevel/coqinit.mli
+++ b/toplevel/coqinit.mli
@@ -11,10 +11,7 @@ val set_rcuser : string -> unit
val no_load_rc : unit -> unit
val load_rcfile : unit -> unit
-val add_include : string -> unit
val push_include : string -> unit
-val rec_include : string -> unit
-
-val hm2 : string -> string
+val push_rec_include : string -> unit
val init_load_path : unit -> unit
diff --git a/toplevel/coqtop.ml b/toplevel/coqtop.ml
index 564acaee6..456384d90 100644
--- a/toplevel/coqtop.ml
+++ b/toplevel/coqtop.ml
@@ -78,7 +78,7 @@ let parse_args () =
| ("-I"|"-include") :: d :: rem -> push_include d; parse rem
| ("-I"|"-include") :: [] -> usage ()
- | "-R" :: d :: rem -> rec_include d; parse rem
+ | "-R" :: d :: rem -> push_rec_include d; parse rem
| "-R" :: [] -> usage ()
| "-q" :: rem -> no_load_rc (); parse rem
diff --git a/toplevel/mltop.ml4 b/toplevel/mltop.ml4
index c5d628769..66577bea6 100644
--- a/toplevel/mltop.ml4
+++ b/toplevel/mltop.ml4
@@ -3,6 +3,7 @@
open Util
open Pp
+open System
open Libobject
open Library
open System
@@ -33,7 +34,10 @@ open Vernacinterp
(* This path is where we look for .cmo *)
let coq_mlpath_copy = ref []
-let keep_copy_mlpath s = coq_mlpath_copy := (glob s)::!coq_mlpath_copy
+let keep_copy_mlpath s =
+ let dir = glob s in
+ let lpe = { directory = dir; root_dir = dir; relative_subdir = "" } in
+ coq_mlpath_copy := lpe :: !coq_mlpath_copy
(* If there is a toplevel under Coq *)
type toplevel = {
@@ -86,7 +90,7 @@ let dir_ml_load s =
| WithoutTop ->
ifdef Byte then
(if is_in_path !coq_mlpath_copy s then
- let gname = where_in_path !coq_mlpath_copy s in
+ let _,gname = where_in_path !coq_mlpath_copy s in
try
Dynlink.loadfile gname;
Dynlink.add_interfaces
@@ -119,7 +123,8 @@ let dir_ml_dir s =
| _ -> ()
(* For Rec Add ML Path *)
-let rdir_ml_dir dir = List.iter dir_ml_dir (all_subdirs dir)
+let rdir_ml_dir dir =
+ List.iter (fun lpe -> dir_ml_dir lpe.directory) (all_subdirs dir)
(* convertit un nom quelconque en nom de fichier ou de module *)
let mod_of_name name =
@@ -231,7 +236,7 @@ let declare_ml_modules l =
let print_ml_path () =
let l = !coq_mlpath_copy in
pPNL [< 'sTR"ML Load Path:"; 'fNL; 'sTR" ";
- hV 0 (prlist_with_sep pr_fnl (fun s -> [< 'sTR s >]) l) >]
+ hV 0 (prlist_with_sep pr_fnl (fun e -> [< 'sTR e.directory >]) l) >]
let _ = vinterp_add "DeclareMLModule"
(fun l ->
diff --git a/toplevel/vernac.ml b/toplevel/vernac.ml
index c755419df..7997b2451 100644
--- a/toplevel/vernac.ml
+++ b/toplevel/vernac.ml
@@ -51,7 +51,7 @@ let real_error = function
the file we parse seems a bit risky to me. B.B. *)
let open_file_twice_if verbosely fname =
- let longfname = find_file_in_path (Library.get_load_path ()) fname in
+ let _,longfname = find_file_in_path (Library.get_load_path ()) fname in
let in_chan = open_in longfname in
let verb_ch = if verbosely then Some (open_in longfname) else None in
let po = Pcoq.Gram.parsable (Stream.of_channel in_chan) in
diff --git a/toplevel/vernacentries.ml b/toplevel/vernacentries.ml
index 5ae050039..7f584a4b9 100644
--- a/toplevel/vernacentries.ml
+++ b/toplevel/vernacentries.ml
@@ -106,7 +106,8 @@ let show_top_evars () =
let locate_file f =
try
- mSG [< 'sTR (System.where_in_path (get_load_path()) f); 'fNL >]
+ let _,file = System.where_in_path (get_load_path()) f in
+ mSG [< 'sTR file; 'fNL >]
with Not_found ->
mSG (hOV 0 [< 'sTR"Can't find file"; 'sPC; 'sTR f; 'sPC;
'sTR"on loadpath"; 'fNL >])
@@ -120,7 +121,7 @@ let locate_id id =
let print_loadpath () =
let l = get_load_path () in
mSGNL [< 'sTR"Load Path:"; 'fNL; 'sTR" ";
- hV 0 (prlist_with_sep pr_fnl (fun s -> [< 'sTR s >]) l) >]
+ hV 0 (prlist_with_sep pr_fnl (fun s -> [< 'sTR s.directory >]) l) >]
let get_current_context_of_args = function
| [VARG_NUMBER n] -> get_goal_context n