(basename, version, arch)
) infos in
+ let nr_kernels = List.length infos in
+
(* For quick access to the opener strings, build a hash. *)
let openers = Hashtbl.create 13 in
List.iter (
) what;
(* Now read the data files and parse out the structures of interest. *)
- let datas = List.map (
- fun (basename, version, arch) ->
+ let kernels = List.mapi (
+ fun i (basename, version, arch) ->
+ printf "Loading kernel data file %d/%d\r%!" (i+1) nr_kernels;
+
let file_exists name =
try Unix.access name [Unix.F_OK]; true
with Unix.Unix_error _ -> false
in
- let datas = List.map (
+ let kernels = List.map (
fun (basename, version, arch, bodies) ->
let structures = List.filter_map (
fun (struct_name, (_, _, _, wanted_fields)) ->
) what in
(basename, version, arch, structures)
- ) datas in
+ ) kernels in
if debug then
List.iter (
) fields;
printf " } /* %d bytes */\n\n" total_size;
) structures;
- ) datas;
+ ) kernels;
+
+ (* First output file is a simple list of kernels, to support the
+ * 'virt-mem --list-kernels' option.
+ *)
+ let () =
+ let _loc = Loc.ghost in
+
+ let versions = List.map (fun (_, version, _, _) -> version) kernels in
+
+ (* Sort them in reverse because we are going to generate the
+ * final list in reverse.
+ *)
+ let cmp a b = compare b a in
+ let versions = List.sort ~cmp versions in
+
+ let xs =
+ List.fold_left (fun xs version -> <:expr< $str:version$ :: $xs$ >>)
+ <:expr< [] >> versions in
+
+ let code = <:str_item<
+ let kernels = $xs$
+ >> in
+
+ let output_file = outputdir // "virt_mem_kernels.ml" in
+ printf "Writing list of kernels to %s ...\n%!" output_file;
+ Printers.OCaml.print_implem ~output_file code in
(* We'll generate a code file for each structure type (eg. task_struct
- * across all kernel versions), so rearrange 'datas' for that purpose.
+ * across all kernel versions), so rearrange 'kernels' for that purpose.
*
* XXX This loop is O(n^3), luckily n is small!
*)
fun (basename, version, arch, structures) ->
try Some (basename, version, arch, List.assoc name structures)
with Not_found -> None
- ) datas in
+ ) kernels in
(* Sort the kernels, which makes the generated output more stable
* and makes patches more useful.
name, kernels
) what in
- let datas = () in ignore datas; (* garbage collect *)
+ let kernels = () in ignore kernels; (* garbage collect *)
(* Get just the field types. It's plausible that a field with the
* same name has a different type between kernel versions, so we must
(* Code (.ml file). *)
let code = <:str_item<
- let warning = "This code is automatically generated from the kernel database by kerneldb-to-parser program. Any edits you make will be lost."
let zero = 0
let struct_name = $str:struct_name$
let match_err = "failed to match kernel structure"
let ichan = open_in new_output_file in
let ochan = open_out output_file in
+ output_string ochan "\
+(* WARNING: This file and the corresponding mli (interface) are
+ * automatically generated by the extract/codegen/kerneldb_to_parser.ml
+ * program.
+ *
+ * Any edits you make to this file will be lost.
+ *
+ * To update this file from the latest kernel database, it is recommended
+ * that you do 'make update-kernel-structs'.
+ *)
+";
+
let rec loop () =
let line = input_line ichan in
let line =