]> matita.cs.unibo.it Git - helm.git/blob - matita/matitadep.ml
huge amount of work to make out Make crawl roots and
[helm.git] / matita / matitadep.ml
1 (* Copyright (C) 2005, HELM Team.
2  * 
3  * This file is part of HELM, an Hypertextual, Electronic
4  * Library of Mathematics, developed at the Computer Science
5  * Department, University of Bologna, Italy.
6  * 
7  * HELM is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  * 
12  * HELM is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with HELM; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
20  * MA  02111-1307, USA.
21  * 
22  * For details, see the HELM World-Wide-Web page,
23  * http://helm.cs.unibo.it/
24  *)
25
26 (* $Id$ *)
27
28 open Printf
29
30 module GA = GrafiteAst 
31 module U = UriManager
32                 
33 let main () =
34   (* all are maps from "file" to "something" *)
35   let include_deps = Hashtbl.create 13 in
36   let baseuri_of = Hashtbl.create 13 in
37   let baseuri_of_inv = Hashtbl.create 13 in
38   let dot_file = ref "" in
39   (* helpers *)
40   let include_paths = 
41     Helm_registry.get_list Helm_registry.string "matita.includes" 
42   in
43   let baseuri_of_script s = 
44      try Hashtbl.find baseuri_of s 
45      with Not_found -> 
46        let _,b,_,_ = Librarian.baseuri_of_script ~include_paths s in
47        Hashtbl.add baseuri_of s b; 
48        Hashtbl.add baseuri_of_inv b s; 
49        b
50   in
51   let script_of_baseuri b =
52     try Hashtbl.find baseuri_of_inv b
53     with Not_found -> 
54      assert false 
55     (* should be called only after baseuri_of_script is
56      * called on every file *)
57   in
58   let buri alias = U.buri_of_uri (U.uri_of_string alias) in
59   let resolve alias current_buri =
60     let buri = buri alias in
61     if buri <> current_buri then Some buri else None 
62   in
63   (* initialization *)
64   MatitaInit.add_cmdline_spec 
65     ["-dot", Arg.Set_string dot_file,
66     "<file> Save dependency graph in dot format to the given file";];
67   MatitaInit.parse_cmdline_and_configuration_file ();
68   MatitaInit.initialize_environment ();
69   let args = 
70       let roots = Librarian.find_roots_in_dir (Sys.getcwd ()) in
71       match roots with
72       | [] -> 
73          prerr_endline ("No roots found in " ^ Sys.getcwd ());
74          exit 1
75       | [x] -> 
76          Sys.chdir (Filename.dirname x);
77          HExtlib.find ~test:(fun x -> Filename.check_suffix x ".ma") "."
78       | _ ->
79          prerr_endline ("Too many roots: " ^ String.concat ", " roots);
80          prerr_endline ("Enter one of these directories and retry");
81          exit 1
82   in
83   let ma_files = args in
84   (* here we go *)
85   (* fills:
86               Hashtbl.add include_deps     ma_file ma_file
87               Hashtbl.add include_deps_dot ma_file baseuri
88   *)
89   List.iter (fun ma_file -> ignore (baseuri_of_script ma_file)) ma_files;
90   List.iter
91    (fun ma_file -> 
92       let ma_baseuri = baseuri_of_script ma_file in
93       let dependencies = DependenciesParser.deps_of_file ma_file in
94       List.iter 
95        (function
96          | DependenciesParser.UriDep uri -> 
97             let uri = UriManager.string_of_uri uri in
98             if not (Http_getter_storage.is_legacy uri) then
99               let dep = resolve uri ma_baseuri in
100               (match dep with 
101               | None -> ()
102               | Some u -> Hashtbl.add include_deps ma_file (script_of_baseuri u))
103          | DependenciesParser.IncludeDep path -> 
104                 Hashtbl.add include_deps ma_file path)
105        dependencies)
106    ma_files;
107   (* dot generation *)
108   if !dot_file <> "" then 
109     begin
110       let oc = open_out !dot_file in
111       let fmt = Format.formatter_of_out_channel oc in 
112       GraphvizPp.Dot.header fmt;
113       List.iter
114        (fun ma_file -> 
115         let deps = Hashtbl.find_all include_deps ma_file in
116         let deps = 
117           HExtlib.filter_map 
118             (fun u -> 
119               try Some (Hashtbl.find baseuri_of_inv u) 
120               with Not_found -> None) 
121             deps 
122         in
123         let deps = List.fast_sort Pervasives.compare deps in
124         let deps = HExtlib.list_uniq deps in
125         GraphvizPp.Dot.node ma_file fmt;
126         List.iter (fun dep -> GraphvizPp.Dot.edge ma_file dep fmt) deps)
127        ma_files;
128       GraphvizPp.Dot.trailer fmt;
129       close_out oc
130     end;
131   (* generate regular depend output *)
132   let fix_name f =
133     let f = 
134       if Pcre.pmatch ~pat:"^\\./" f then
135         String.sub f 2 (String.length f - 2)
136       else 
137         f
138     in 
139       HExtlib.normalize_path f
140   in
141   let deps =
142     List.fold_left
143      (fun acc ma_file -> 
144       let deps = Hashtbl.find_all include_deps ma_file in
145       let deps = List.fast_sort Pervasives.compare deps in
146       let deps = HExtlib.list_uniq deps in
147       let deps = List.map fix_name deps in
148       (fix_name ma_file, deps) :: acc)
149      [] ma_files
150   in
151   let extern = 
152     List.fold_left
153       (fun acc (_,d) -> 
154         List.fold_left 
155           (fun a x -> 
156              if List.exists (fun (t,_) -> x=t) deps then a 
157              else x::a) 
158           acc d)
159       [] deps
160   in
161   Librarian.write_deps_file (Sys.getcwd()) (deps@List.map (fun x -> x,[]) extern)
162 ;;
163