Commit | Line | Data |
---|---|---|
34e49164 C |
1 | open Common |
2 | ||
3 | ||
4 | ||
5 | type kbuild_info = directory list | |
6 | and directory = Directory of string (*dirname*) * group list | |
7 | and group = Group of filename list | |
8 | ||
ae4735db | 9 | let directories_to_assoc xs = |
34e49164 | 10 | xs +> List.map (function (Directory (s, ys)) -> s, ys) |
ae4735db | 11 | let directories_to_hash xs = |
34e49164 | 12 | xs +> directories_to_assoc +> Common.hash_of_list |
ae4735db | 13 | let files_of_groups xs = |
34e49164 C |
14 | xs +> List.map (function Group ys -> ys) +> Common.union_all |
15 | ||
16 | ||
17 | ||
ae4735db C |
18 | let adjust_dirs dirs = |
19 | dirs +> Common.map_filter (fun s -> | |
34e49164 C |
20 | match s with |
21 | | s when s =~ "^\\.$" -> None | |
22 | | s when s =~ "^\\./\\.git" -> None | |
23 | | s when s =~ "^\\./\\.tmp_versions" -> None | |
24 | | s when s =~ "^\\./include/config/" -> None | |
25 | | s when s =~ "^\\./usr/include" -> None | |
26 | | s when s =~ "^\\./\\(.*\\)" -> Some (matched1 s) | |
27 | | s -> Some s | |
28 | ) | |
29 | ||
30 | ||
31 | ||
ae4735db C |
32 | let unparse_kbuild_info xs filename = |
33 | Common.with_open_outfile filename (fun (pr_no_nl,chan) -> | |
34e49164 C |
34 | let pr s = pr_no_nl (s ^ "\n") in |
35 | ||
ae4735db | 36 | xs +> List.iter (function Directory (s, ys) -> |
34e49164 | 37 | pr s; |
ae4735db | 38 | ys +> List.iter (function Group zs -> |
34e49164 C |
39 | pr (" " ^ (join " " zs)); |
40 | ); | |
41 | pr ""; | |
42 | ) | |
43 | ) | |
44 | ||
ae4735db | 45 | let parse_kbuild_info filename = |
34e49164 C |
46 | let xs = cat filename in |
47 | let xs = xs +> List.map (Str.global_replace (Str.regexp "#.*") "" ) in | |
48 | let xs = xs +> List.filter (fun s -> not (s =~ "^[ \t]*$")) in | |
49 | ||
50 | (* split by header of section *) | |
51 | let xs = xs +> Common.split_list_regexp "^[^ ]" in | |
52 | ||
ae4735db C |
53 | xs +> List.map (fun (s, xs) -> |
54 | let groups = xs +> List.map (fun s -> | |
34e49164 C |
55 | assert (s =~ "^[ ]+\\(.*\\)"); |
56 | let files = matched1 s in | |
57 | let cfiles = Common.split " +" files in | |
58 | Group cfiles | |
59 | ) in | |
60 | ||
61 | Directory (s, groups) | |
62 | ) | |
63 | ||
ae4735db C |
64 | let generate_naive_kbuild_info dirs = |
65 | dirs +> List.map (fun s -> | |
34e49164 C |
66 | let files = Common.readdir_to_file_list s in |
67 | let files_ext = files +> List.map Common.dbe_of_filename_safe in | |
ae4735db C |
68 | let cfiles = files_ext +> Common.map_filter |
69 | (function | |
70 | | Left (d,base, "c") -> | |
34e49164 | 71 | if base =~ ".*\\.mod$" then None |
ae4735db | 72 | else Some base |
34e49164 C |
73 | | _ -> None |
74 | ) in | |
75 | let ys = cfiles +> List.map (fun c -> Group [c ^ ".c"]) in | |
76 | Directory (s, ys) | |
77 | ) | |
78 | ||
79 | ||
80 | ||
81 | ||
ae4735db C |
82 | let generate_kbuild_info_from_depcocci dirs outfile = |
83 | Common.with_open_outfile outfile (fun (pr_no_nl, chan) -> | |
84 | dirs +> List.iter (fun s -> | |
34e49164 C |
85 | pr_no_nl (s ^ "\n"); |
86 | let depcocci = Common.cat (Filename.concat s "depcocci.dep") in | |
87 | depcocci +> List.iter (fun s -> pr_no_nl (s ^ "\n")); | |
88 | pr_no_nl "\n"; | |
89 | ) | |
90 | ) | |
91 | (* | |
ae4735db | 92 | dirs +> List.map (fun s -> |
34e49164 C |
93 | let groups = depcocci +> List.map (fun s -> Group (Common.split " +" s)) |
94 | in | |
95 | Directory (s, groups) | |
96 | ) | |
97 | *) | |
98 | ||
99 | ||
ae4735db C |
100 | type makefile = |
101 | { | |
34e49164 C |
102 | obj_dirs : string stack ref; |
103 | obj_config: (string list) stack ref; | |
104 | obj_objs: (string * (string list)) stack ref; | |
105 | } | |
106 | let empty_makefile () = | |
107 | failwith "empty_makefile" | |
108 | ||
ae4735db C |
109 | let parse_makefile file = |
110 | let xs = Common.cat file in | |
111 | let s = Common.unlines xs in | |
34e49164 C |
112 | let s = Str.global_replace (Str.regexp "\\\\\n") "" s in |
113 | let xs = Common.lines_with_nl s in | |
114 | let xs = xs +> List.map (Str.global_replace (Str.regexp "#.*") "" ) in | |
115 | let xs = xs +> List.filter (fun s -> not (s =~ "^[ \t]*$")) in | |
116 | let _m = empty_makefile () in | |
117 | ||
ae4735db | 118 | xs +> List.iter (fun s -> |
34e49164 | 119 | match s with |
ae4735db | 120 | | s when s =~ "obj-\\$(CONFIG_.*)[ \t]*[\\+:]=\\(.*/\\)" -> |
34e49164 | 121 | pr2_no_nl ("DIR: " ^ s) |
ae4735db | 122 | | s when s =~ "obj-y[ \t]*\\+=\\(.*/\\)" -> |
34e49164 | 123 | pr2_no_nl ("DIR: " ^ s) |
ae4735db | 124 | | s when s =~ "obj-\\$(CONFIG_.*)[ \t]*[\\+:]=\\(.*\\)" -> |
34e49164 C |
125 | let s = matched1 s in |
126 | let objs = Common.split "[ \t]+" s in | |
b1b2de81 | 127 | assert(List.for_all (fun s -> thd3 (Common.dbe_of_filename s) =$= "o") |
34e49164 | 128 | objs); |
ae4735db | 129 | |
34e49164 C |
130 | pr2 ("OBJS: " ^ (join "|" objs)) |
131 | ||
ae4735db | 132 | | s when s =~ "[a-zA-Z0-9_]+-objs[ \t]*[\\+:]=\\(.*\\)" -> |
34e49164 C |
133 | let s = matched1 s in |
134 | let objs = Common.split "[ \t]+" s in | |
135 | ||
136 | pr2 ("OBJSMODULE: " ^ (join "|" objs)) | |
137 | ||
ae4735db | 138 | | s -> |
34e49164 C |
139 | pr2_no_nl ("OTHER: " ^ s) |
140 | ||
141 | ) | |
142 | ||
143 | ||
ae4735db C |
144 | let generate_less_naive_kbuild_info dirs = |
145 | dirs +> List.map (fun s -> | |
34e49164 C |
146 | let files = Common.readdir_to_file_list s in |
147 | let files_ext = files +> List.map Common.dbe_of_filename_safe in | |
ae4735db C |
148 | let cfiles = files_ext +> Common.map_filter |
149 | (function | |
150 | | Left (d,base, "c") -> | |
34e49164 | 151 | if base =~ ".*\\.mod$" then None |
ae4735db | 152 | else Some base |
34e49164 C |
153 | | _ -> None |
154 | ) in | |
155 | match cfiles with | |
156 | | [] -> Directory (s, []) | |
ae4735db | 157 | | _::_ -> |
34e49164 C |
158 | if Common.lfile_exists (Filename.concat s "Makefile") |
159 | then | |
160 | let _res = parse_makefile (Filename.concat s "Makefile") in | |
161 | let ys = cfiles +> List.map (fun c -> Group [c ^ ".c"]) in | |
162 | Directory (s, ys) | |
ae4735db | 163 | else |
34e49164 | 164 | failwith ("no Makefile found in: " ^ s) |
ae4735db | 165 | |
34e49164 C |
166 | ) |
167 | ||
168 | ||
169 | ||
170 | (* a = current info file, in general manually extended; b = generated one *) | |
171 | let check_up_to_date a b = | |
172 | let das = directories_to_assoc a in | |
173 | let dbs = directories_to_assoc b in | |
174 | let all_dirs = (das +> List.map fst) $+$ (dbs +> List.map fst) in | |
ae4735db C |
175 | all_dirs +> List.iter (fun dir -> |
176 | match | |
34e49164 C |
177 | optionise (fun () -> List.assoc dir das), |
178 | optionise (fun () -> List.assoc dir dbs) | |
179 | with | |
abad11c5 | 180 | | None, None -> raise (Impossible 57) |
34e49164 C |
181 | | None, Some gbs -> pr2 ("new directory appeared:" ^ dir) |
182 | | Some gas, None -> pr2 ("old directory disappeared:" ^ dir) | |
ae4735db | 183 | | Some gas, Some gbs -> |
34e49164 C |
184 | let afiles = files_of_groups gas in |
185 | let bfiles = files_of_groups gbs in | |
186 | let all_files = afiles $+$ bfiles in | |
ae4735db | 187 | all_files +> List.iter (fun file -> |
34e49164 | 188 | match List.mem file afiles, List.mem file bfiles with |
abad11c5 | 189 | | false, false -> raise (Impossible 58) |
34e49164 C |
190 | | false, true -> pr2 ("new file appeared:" ^ file ^ " in " ^ dir) |
191 | | true, false -> pr2 ("old file disappeared:" ^ file ^ " in " ^ dir) | |
192 | | true, true -> () | |
193 | ) | |
194 | ) | |
34e49164 | 195 | |
ae4735db C |
196 | |
197 | let files_in_dirs dirs kbuild_info = | |
198 | dirs +> List.map (fun dir -> | |
34e49164 C |
199 | let dir = Common.chop_dirsymbol dir in |
200 | (* could use assoc, but we accept "parasite" prefix *) | |
ae4735db C |
201 | let gooddirs = |
202 | kbuild_info +> Common.map_filter (function (Directory (s, groups)) -> | |
34e49164 C |
203 | if dir =~ ("\\(.*\\)" ^ s ^ "$") |
204 | then | |
205 | let prefix = matched1 dir in | |
206 | Some (prefix, s, groups) | |
207 | else None | |
208 | ) | |
209 | in | |
210 | ||
211 | (match gooddirs with | |
ae4735db C |
212 | | [prefix, dir, groups] -> |
213 | groups +> List.map (function (Group xs) -> | |
214 | Group (xs +> List.map (fun s -> | |
34e49164 C |
215 | Filename.concat (prefix ^ dir) s)) |
216 | ) | |
ae4735db C |
217 | |
218 | | [] -> | |
34e49164 C |
219 | pr2 ("can't find kbuild info for directory :" ^ dir); |
220 | [] | |
ae4735db | 221 | | x::y::ys -> |
34e49164 C |
222 | pr2 ("too much kbuild info candidate for directory :" ^ dir); |
223 | [] | |
224 | ) | |
225 | ) +> List.concat | |
226 | ||
227 | ||
ae4735db | 228 | |
34e49164 | 229 |