5 type kbuild_info
= directory list
6 and directory
= Directory
of string (*dirname*) * group list
7 and group
= Group
of filename list
9 let directories_to_assoc xs
=
10 xs
+> List.map
(function (Directory
(s
, ys
)) -> s
, ys
)
11 let directories_to_hash xs
=
12 xs
+> directories_to_assoc +> Common.hash_of_list
13 let files_of_groups xs
=
14 xs
+> List.map
(function Group ys
-> ys
) +> Common.union_all
18 let adjust_dirs dirs
=
19 dirs
+> Common.map_filter
(fun s
->
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
)
32 let unparse_kbuild_info xs filename
=
33 Common.with_open_outfile filename
(fun (pr_no_nl
,chan
) ->
34 let pr s
= pr_no_nl
(s ^
"\n") in
36 xs
+> List.iter
(function Directory
(s
, ys
) ->
38 ys
+> List.iter
(function Group zs
->
39 pr (" " ^
(join
" " zs
));
45 let parse_kbuild_info filename
=
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
50 (* split by header of section *)
51 let xs = xs +> Common.split_list_regexp
"^[^ ]" in
53 xs +> List.map
(fun (s
, xs) ->
54 let groups = xs +> List.map
(fun s
->
55 assert (s
=~
"^[ ]+\\(.*\\)");
56 let files = matched1 s
in
57 let cfiles = Common.split
" +" files in
64 let generate_naive_kbuild_info dirs
=
65 dirs
+> List.map
(fun s
->
66 let files = Common.readdir_to_file_list s
in
67 let files_ext = files +> List.map
Common.dbe_of_filename_safe
in
68 let cfiles = files_ext +> Common.map_filter
70 | Left
(d
,base
, "c") ->
71 if base
=~
".*\\.mod$" then None
75 let ys = cfiles +> List.map
(fun c
-> Group
[c ^
".c"]) in
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
->
86 let depcocci = Common.cat
(Filename.concat s
"depcocci.dep") in
87 depcocci +> List.iter
(fun s
-> pr_no_nl
(s ^
"\n"));
92 dirs +> List.map (fun s ->
93 let groups = depcocci +> List.map (fun s -> Group (Common.split " +" s))
102 obj_dirs
: string stack
ref;
103 obj_config
: (string list
) stack
ref;
104 obj_objs
: (string * (string list
)) stack
ref;
106 let empty_makefile () =
107 failwith
"empty_makefile"
109 let parse_makefile file
=
110 let xs = Common.cat file
in
111 let s = Common.unlines
xs in
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
118 xs +> List.iter
(fun s ->
120 | s when s =~
"obj-\\$(CONFIG_.*)[ \t]*[\\+:]=\\(.*/\\)" ->
121 pr2_no_nl
("DIR: " ^
s)
122 | s when s =~
"obj-y[ \t]*\\+=\\(.*/\\)" ->
123 pr2_no_nl
("DIR: " ^
s)
124 | s when s =~
"obj-\\$(CONFIG_.*)[ \t]*[\\+:]=\\(.*\\)" ->
125 let s = matched1
s in
126 let objs = Common.split
"[ \t]+" s in
127 assert(List.for_all
(fun s -> thd3
(Common.dbe_of_filename
s) =$
= "o")
130 pr2
("OBJS: " ^
(join
"|" objs))
132 | s when s =~
"[a-zA-Z0-9_]+-objs[ \t]*[\\+:]=\\(.*\\)" ->
133 let s = matched1
s in
134 let objs = Common.split
"[ \t]+" s in
136 pr2
("OBJSMODULE: " ^
(join
"|" objs))
139 pr2_no_nl
("OTHER: " ^
s)
144 let generate_less_naive_kbuild_info dirs
=
145 dirs
+> List.map
(fun s ->
146 let files = Common.readdir_to_file_list
s in
147 let files_ext = files +> List.map
Common.dbe_of_filename_safe
in
148 let cfiles = files_ext +> Common.map_filter
150 | Left
(d
,base
, "c") ->
151 if base
=~
".*\\.mod$" then None
156 | [] -> Directory
(s, [])
158 if Common.lfile_exists
(Filename.concat
s "Makefile")
160 let _res = parse_makefile (Filename.concat
s "Makefile") in
161 let ys = cfiles +> List.map
(fun c
-> Group
[c ^
".c"]) in
164 failwith
("no Makefile found in: " ^
s)
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
175 all_dirs +> List.iter
(fun dir
->
177 optionise
(fun () -> List.assoc dir
das),
178 optionise
(fun () -> List.assoc dir
dbs)
180 | None
, None
-> raise
(Impossible
57)
181 | None
, Some gbs
-> pr2
("new directory appeared:" ^ dir
)
182 | Some gas
, None
-> pr2
("old directory disappeared:" ^ dir
)
183 | Some gas
, Some gbs
->
184 let afiles = files_of_groups gas
in
185 let bfiles = files_of_groups gbs
in
186 let all_files = afiles $
+$
bfiles in
187 all_files +> List.iter
(fun file
->
188 match List.mem file
afiles, List.mem file
bfiles with
189 | false, false -> raise
(Impossible
58)
190 | false, true -> pr2
("new file appeared:" ^ file ^
" in " ^ dir
)
191 | true, false -> pr2
("old file disappeared:" ^ file ^
" in " ^ dir
)
197 let files_in_dirs dirs kbuild_info
=
198 dirs
+> List.map
(fun dir
->
199 let dir = Common.chop_dirsymbol
dir in
200 (* could use assoc, but we accept "parasite" prefix *)
202 kbuild_info
+> Common.map_filter
(function (Directory
(s, groups)) ->
203 if dir =~
("\\(.*\\)" ^
s ^
"$")
205 let prefix = matched1
dir in
206 Some
(prefix, s, groups)
212 | [prefix, dir, groups] ->
213 groups +> List.map
(function (Group
xs) ->
214 Group
(xs +> List.map
(fun s ->
215 Filename.concat
(prefix ^
dir) s))
219 pr2
("can't find kbuild info for directory :" ^
dir);
222 pr2
("too much kbuild info candidate for directory :" ^
dir);