Add --list-kernels option and add a warning to the generated files.
[virt-mem.git] / extract / codegen / kerneldb_to_parser.ml
index e1056c5..a3bb9a1 100644 (file)
@@ -146,6 +146,8 @@ Example (from toplevel of virt-mem source tree):
       (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 (
@@ -154,8 +156,10 @@ Example (from toplevel of virt-mem source tree):
   ) 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
@@ -342,7 +346,7 @@ Example (from toplevel of virt-mem source tree):
 
   in
 
-  let datas = List.map (
+  let kernels = List.map (
     fun (basename, version, arch, bodies) ->
       let structures = List.filter_map (
        fun (struct_name, (_, _, _, wanted_fields)) ->
@@ -385,7 +389,7 @@ Example (from toplevel of virt-mem source tree):
       ) what in
 
       (basename, version, arch, structures)
-  ) datas in
+  ) kernels in
 
   if debug then
     List.iter (
@@ -408,10 +412,36 @@ Example (from toplevel of virt-mem source tree):
            ) 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!
    *)
@@ -423,7 +453,7 @@ Example (from toplevel of virt-mem source tree):
            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.
@@ -433,7 +463,7 @@ Example (from toplevel of virt-mem source tree):
        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
@@ -644,7 +674,6 @@ Example (from toplevel of virt-mem source tree):
 
        (* 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"
@@ -707,6 +736,18 @@ Example (from toplevel of virt-mem source tree):
       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 =