]> matita.cs.unibo.it Git - helm.git/blob - matita/matitadep.ml
cf1519eae7511cb2fb6aceeb2127c19984192e24
[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          let roots = List.map (HExtlib.chop_prefix (Sys.getcwd()^"/")) roots in
80          prerr_endline ("Too many roots found:\n\t" ^ String.concat "\n\t" roots);
81          prerr_endline ("\nEnter one of these directories and retry");
82          exit 1
83   in
84   let ma_files = args in
85   (* here we go *)
86   (* fills:
87               Hashtbl.add include_deps     ma_file ma_file
88               Hashtbl.add include_deps_dot ma_file baseuri
89   *)
90   List.iter (fun ma_file -> ignore (baseuri_of_script ma_file)) ma_files;
91   List.iter
92    (fun ma_file -> 
93       let ma_baseuri = baseuri_of_script ma_file in
94       let dependencies = DependenciesParser.deps_of_file ma_file in
95       List.iter 
96        (function
97          | DependenciesParser.UriDep uri -> 
98             let uri = UriManager.string_of_uri uri in
99             if not (Http_getter_storage.is_legacy uri) then
100               let dep = resolve uri ma_baseuri in
101               (match dep with 
102               | None -> ()
103               | Some u -> Hashtbl.add include_deps ma_file (script_of_baseuri u))
104          | DependenciesParser.IncludeDep path -> 
105                 Hashtbl.add include_deps ma_file path)
106        dependencies)
107    ma_files;
108   (* dot generation *)
109   if !dot_file <> "" then 
110     begin
111       let oc = open_out !dot_file in
112       let fmt = Format.formatter_of_out_channel oc in 
113       GraphvizPp.Dot.header fmt;
114       List.iter
115        (fun ma_file -> 
116         let deps = Hashtbl.find_all include_deps ma_file in
117         let deps = 
118           HExtlib.filter_map 
119             (fun u -> 
120               try Some (Hashtbl.find baseuri_of_inv u) 
121               with Not_found -> None) 
122             deps 
123         in
124         let deps = List.fast_sort Pervasives.compare deps in
125         let deps = HExtlib.list_uniq deps in
126         GraphvizPp.Dot.node ma_file fmt;
127         List.iter (fun dep -> GraphvizPp.Dot.edge ma_file dep fmt) deps)
128        ma_files;
129       GraphvizPp.Dot.trailer fmt;
130       close_out oc
131     end;
132   (* generate regular depend output *)
133   let fix_name f =
134     let f = 
135       if Pcre.pmatch ~pat:"^\\./" f then
136         String.sub f 2 (String.length f - 2)
137       else 
138         f
139     in 
140       HExtlib.normalize_path f
141   in
142   let deps =
143     List.fold_left
144      (fun acc ma_file -> 
145       let deps = Hashtbl.find_all include_deps ma_file in
146       let deps = List.fast_sort Pervasives.compare deps in
147       let deps = HExtlib.list_uniq deps in
148       let deps = List.map fix_name deps in
149       (fix_name ma_file, deps) :: acc)
150      [] ma_files
151   in
152   let extern = 
153     List.fold_left
154       (fun acc (_,d) -> 
155         List.fold_left 
156           (fun a x -> 
157              if List.exists (fun (t,_) -> x=t) deps then a 
158              else x::a) 
159           acc d)
160       [] deps
161   in
162   Librarian.write_deps_file (Sys.getcwd()) (deps@List.map (fun x -> x,[]) extern)
163 ;;
164