]> matita.cs.unibo.it Git - helm.git/blob - matita/matitadep.ml
matitadep sould be ok, outputs warning regarding issues 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 = ref [] in
41   let baseuri_of_script s = 
42      try Hashtbl.find baseuri_of s 
43      with Not_found -> 
44        let _,b,_,_ = 
45          Librarian.baseuri_of_script ~include_paths:!include_paths s 
46        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 ma b =
52     try Some (Hashtbl.find baseuri_of_inv b)
53     with Not_found -> 
54       HLog.error ("Skipping dependency of '"^ma^"' over '"^b^"'");
55       HLog.error ("Plase include the file defining such baseuri, or fix");
56       HLog.error ("possibly incorrect verbatim URIs in the .ma file.");
57       None
58   in
59   let buri alias = U.buri_of_uri (U.uri_of_string alias) in
60   let resolve alias current_buri =
61     let buri = buri alias in
62     if buri <> current_buri then Some buri else None 
63   in
64   (* initialization *)
65   MatitaInit.add_cmdline_spec 
66     ["-dot", Arg.Set_string dot_file,
67     "<file> Save dependency graph in dot format to the given file";];
68   MatitaInit.parse_cmdline_and_configuration_file ();
69   MatitaInit.initialize_environment ();
70   let args = 
71       let roots = Librarian.find_roots_in_dir (Sys.getcwd ()) in
72       match roots with
73       | [] -> 
74          prerr_endline ("No roots found in " ^ Sys.getcwd ());
75          exit 1
76       | [x] -> 
77          Sys.chdir (Filename.dirname x);
78          let opts = Librarian.load_root_file "root" in
79          include_paths := 
80            (try Str.split (Str.regexp " ") (List.assoc "include_paths" opts)
81            with Not_found -> []) @ 
82            (Helm_registry.get_list Helm_registry.string "matita.includes");
83          HExtlib.find ~test:(fun x -> Filename.check_suffix x ".ma") "."
84       | _ ->
85          let roots = List.map (HExtlib.chop_prefix (Sys.getcwd()^"/")) roots in
86          prerr_endline ("Too many roots found:\n\t" ^ String.concat "\n\t" roots);
87          prerr_endline ("\nEnter one of these directories and retry");
88          exit 1
89   in
90   let ma_files = args in
91   (* here we go *)
92   (* fills:
93               Hashtbl.add include_deps     ma_file ma_file
94               Hashtbl.add include_deps_dot ma_file baseuri
95   *)
96   List.iter (fun ma_file -> ignore (baseuri_of_script ma_file)) ma_files;
97   List.iter
98    (fun ma_file -> 
99       let ma_baseuri = baseuri_of_script ma_file in
100       let dependencies = DependenciesParser.deps_of_file ma_file in
101       List.iter 
102        (function
103          | DependenciesParser.UriDep uri -> 
104             let uri = UriManager.string_of_uri uri in
105             if not (Http_getter_storage.is_legacy uri) then
106               let dep = resolve uri ma_baseuri in
107               (match dep with 
108               | None -> ()
109               | Some u -> 
110                   match script_of_baseuri ma_file u with
111                   | Some d -> Hashtbl.add include_deps ma_file d
112                   | None -> ())                
113          | DependenciesParser.IncludeDep path -> 
114                 ignore (baseuri_of_script path);
115                 Hashtbl.add include_deps ma_file path)
116        dependencies)
117    ma_files;
118   (* dot generation *)
119   if !dot_file <> "" then 
120     begin
121       let oc = open_out !dot_file in
122       let fmt = Format.formatter_of_out_channel oc in 
123       GraphvizPp.Dot.header fmt;
124       List.iter
125        (fun ma_file -> 
126         let deps = Hashtbl.find_all include_deps ma_file in
127         let deps = 
128           HExtlib.filter_map 
129             (fun u -> 
130               try Some (Hashtbl.find baseuri_of_inv u) 
131               with Not_found -> None) 
132             deps 
133         in
134         let deps = List.fast_sort Pervasives.compare deps in
135         let deps = HExtlib.list_uniq deps in
136         GraphvizPp.Dot.node ma_file fmt;
137         List.iter (fun dep -> GraphvizPp.Dot.edge ma_file dep fmt) deps)
138        ma_files;
139       GraphvizPp.Dot.trailer fmt;
140       close_out oc
141     end;
142   (* generate regular depend output *)
143   let fix_name f =
144     let f = 
145       if Pcre.pmatch ~pat:"^\\./" f then
146         String.sub f 2 (String.length f - 2)
147       else 
148         f
149     in 
150       HExtlib.normalize_path f
151   in
152   let deps =
153     List.fold_left
154      (fun acc ma_file -> 
155       let deps = Hashtbl.find_all include_deps ma_file in
156       let deps = List.fast_sort Pervasives.compare deps in
157       let deps = HExtlib.list_uniq deps in
158       let deps = List.map fix_name deps in
159       (fix_name ma_file, deps) :: acc)
160      [] ma_files
161   in
162   let extern = 
163     List.fold_left
164       (fun acc (_,d) -> 
165         List.fold_left 
166           (fun a x -> 
167              if List.exists (fun (t,_) -> x=t) deps then a 
168              else x::a) 
169           acc d)
170       [] deps
171   in
172   Librarian.write_deps_file (Sys.getcwd()) (deps@List.map (fun x -> x,[]) extern)
173 ;;
174