]> matita.cs.unibo.it Git - helm.git/blob - matita/components/binaries/matitadep/matitadep.ml
054f90f4a64bac89921c71c81ba7c4bb7c3bc43b
[helm.git] / matita / components / binaries / matitadep / matitadep.ml
1 module StringSet = Set.Make (String) 
2
3 type file = {
4    ddeps: string list;        (* direct dependences *)
5    rdeps: StringSet.t option  (* recursive dependences *)
6 }
7
8 let graph = Hashtbl.create 503
9
10 let debug = ref 0
11
12 let rec purge dname vdeps = match vdeps with
13    | []       -> vdeps
14    | hd :: tl -> if hd = dname then tl else hd :: purge dname tl 
15
16 let add fname =
17    if fname = "" then () else
18    if Hashtbl.mem graph fname then () else
19    Hashtbl.add graph fname {ddeps = []; rdeps = None}
20
21 let add_ddep fname dname =
22    if dname = "" then () else
23    let file = Hashtbl.find graph fname in
24    Hashtbl.replace graph fname {file with ddeps = dname :: file.ddeps} 
25
26 let init fname dname =
27    if !debug land 1 > 0 then Printf.eprintf "init: %s: %s.\n" fname dname;
28    add fname; add dname; add_ddep fname dname 
29
30 (* vdeps: visited dependences for loop detection *)
31 let rec compute_from_file vdeps fname file = match file.rdeps with
32    | Some rdeps -> rdeps
33    | None       ->   
34       if !debug land 2 > 0 then Printf.eprintf "  compute file: %s\n" fname; 
35       let vdeps = fname :: vdeps in
36       List.iter (redundant vdeps fname file.ddeps) file.ddeps;
37       let rdeps = compute_from_ddeps vdeps file.ddeps in
38       Hashtbl.replace graph fname {file with rdeps = Some rdeps};      
39       rdeps
40
41 and compute_from_dname vdeps rdeps dname =
42    if List.mem dname vdeps then begin
43       let loop = purge dname (List.rev vdeps) in
44       Printf.printf "circular: %s\n" (String.concat " " loop);
45       StringSet.add dname rdeps
46    end else
47      let file = Hashtbl.find graph dname in
48      StringSet.add dname (StringSet.union (compute_from_file vdeps dname file) rdeps)
49
50 and compute_from_ddeps vdeps ddeps = 
51    List.fold_left (compute_from_dname vdeps) StringSet.empty ddeps
52
53 and redundant vdeps fname ddeps dname =
54    let rdeps = compute_from_ddeps vdeps (purge dname ddeps) in
55    if StringSet.mem dname rdeps then
56       Printf.printf "%s: redundant %s\n" fname dname
57
58 let check () = 
59    let iter fname file = ignore (compute_from_file [] fname file) in
60    Hashtbl.iter iter graph 
61
62 let get_unions () =
63    let map1 ddeps dname = StringSet.add dname ddeps in 
64    let map2 fname file (fnames, ddeps) =
65       StringSet.add fname fnames, List.fold_left map1 ddeps file.ddeps
66    in
67    Hashtbl.fold map2 graph (StringSet.empty, StringSet.empty)
68
69 let get_leafs () =
70    let map fname file fnames =
71       if file.ddeps = [] then StringSet.add fname fnames else fnames
72    in
73    Hashtbl.fold map graph StringSet.empty
74
75 let top () =
76    let iter fname = Printf.printf "top: %s\n" fname in
77    let fnames, ddeps = get_unions () in
78    StringSet.iter iter (StringSet.diff fnames ddeps) 
79
80 let leaf () =
81    let iter fname = Printf.printf "leaf: %s\n" fname in
82    let fnames = get_leafs () in
83    StringSet.iter iter fnames
84
85 let rec read ich = 
86    let line = input_line ich in
87    begin try Scanf.sscanf line "%s@:include \"%s@\"." init 
88    with Scanf.Scan_failure _ ->
89       begin try Scanf.sscanf line "./%s@:include \"%s@\"." init
90       with Scanf.Scan_failure _ ->   
91          begin try Scanf.sscanf line "%s@:(*%s@*)" (fun _ _ -> ())
92          with Scanf.Scan_failure _ ->
93             Printf.eprintf "unknown line: %s.\n" line
94          end
95       end  
96    end;
97    read ich
98    
99 let _ =
100    let show_check = ref false in
101    let show_top = ref false in
102    let show_leaf = ref false in   
103    let process_file name = () in
104    let show () =
105       if !show_check then check ();
106       if !show_top then top ();
107       if !show_leaf then leaf ()   
108    in
109    let help   = "matitadep [-clt | -d <int> ] < <file>" in
110    let help_c = " Print the redundant and looping arcs of the dependences graph" in
111    let help_d = "<flags>  Set these debug options" in
112    let help_l = " Print the leaf nodes of the dependences graph" in
113    let help_t = " Print the top nodes of the dependences graph" in
114    Arg.parse [
115       "-c", Arg.Set show_check, help_c;
116       "-d", Arg.Int (fun x -> debug := x), help_d;
117       "-l", Arg.Set show_leaf, help_l;
118       "-t", Arg.Set show_top, help_t;
119    ] process_file help;
120    try read stdin with End_of_file -> show ()