[Libguestfs] [PATCH 3/4] generator: Generalize the code used to split actions across files.

Richard W.M. Jones rjones at redhat.com
Fri Sep 2 14:21:28 UTC 2016


Previously we used an awkward hack to split up the large src/actions.c
into smaller files (which can benefit from being compiled in
parallel).  This commit generalizes that code, so that we pass a
subsetted actions list to certain generator functions.

The output of the generator is identical after this commit and the
previous commit, except for the UUID encoded into tests/c-api/tests.c
since that is derived from the MD5 hash of generator/actions.ml.
---
 generator/c.ml    | 16 +++-------------
 generator/c.mli   |  4 +---
 generator/main.ml | 21 +++++++++++++++------
 3 files changed, 19 insertions(+), 22 deletions(-)

diff --git a/generator/c.ml b/generator/c.ml
index 35e08e3..6f5a517 100644
--- a/generator/c.ml
+++ b/generator/c.ml
@@ -33,16 +33,6 @@ let generate_header = generate_header ~inputs:["generator/c.ml"]
 
 (* Generate C API. *)
 
-(* The actions are split across this many C files.  You can increase
- * this number in order to reduce the number of lines in each file
- * (hence making compilation faster), but you also have to modify
- * src/Makefile.am.
- *)
-let nr_actions_files = 7
-let hash_matches h { name = name } =
-  let h' = Hashtbl.hash name mod nr_actions_files in
-  h = h'
-
 type optarg_proto = Dots | VA | Argv
 
 let is_public { visibility = v } = match v with
@@ -1335,7 +1325,7 @@ and generate_client_structs_print_h () =
 "
 
 (* Generate the client-side dispatch stubs. *)
-and generate_client_actions hash () =
+and generate_client_actions actions () =
   generate_header CStyle LGPLv2plus;
 
   pr "\
@@ -1782,7 +1772,7 @@ and generate_client_actions hash () =
   List.iter (
     function
     | { wrapper = true } as f ->
-      if hash_matches hash f then generate_non_daemon_wrapper f
+      generate_non_daemon_wrapper f
     | { wrapper = false } ->
       () (* no wrapper *)
   ) (actions |> non_daemon_functions);
@@ -2082,7 +2072,7 @@ and generate_client_actions hash () =
 
   List.iter (
     fun f ->
-      if hash_matches hash f then generate_daemon_stub f
+      generate_daemon_stub f
   ) (actions |> daemon_functions)
 
 (* Functions which have optional arguments have two or three
diff --git a/generator/c.mli b/generator/c.mli
index 156b244..8c4e86c 100644
--- a/generator/c.mli
+++ b/generator/c.mli
@@ -22,11 +22,9 @@ val generate_prototype : ?extern:bool -> ?static:bool -> ?semicolon:bool -> ?sin
 
 val generate_c_call_args : ?handle:string -> ?implicit_size_ptr:string -> ?in_daemon:bool -> Types.ret * Types.args * Types.optargs -> unit
 
-val nr_actions_files : int
-
 val generate_actions_pod : unit -> unit
 val generate_availability_pod : unit -> unit
-val generate_client_actions : int -> unit -> unit
+val generate_client_actions : Types.action list -> unit -> unit
 val generate_client_actions_variants : unit -> unit
 val generate_client_structs_cleanup : unit -> unit
 val generate_client_structs_compare : unit -> unit
diff --git a/generator/main.ml b/generator/main.ml
index 69c625b..edf106a 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -54,6 +54,20 @@ let perror msg = function
   | exn ->
       eprintf "%s: %s\n" msg (Printexc.to_string exn)
 
+(* In some directories the actions are split across this many C
+ * files.  You can increase this number in order to reduce the number
+ * of lines in each file (hence making compilation faster), but you
+ * also have to modify .../Makefile.am.
+ *)
+let nr_actions_files = 7
+let actions_subsets =
+  let h i { name = name } = i = Hashtbl.hash name mod nr_actions_files in
+  Array.init nr_actions_files (fun i -> List.filter (h i) actions)
+let output_to_subset fs f =
+  for i = 0 to nr_actions_files-1 do
+    ksprintf (fun filename -> output_to filename (f actions_subsets.(i))) fs i
+  done
+
 (* Main program. *)
 let () =
   let lock_fd =
@@ -103,12 +117,7 @@ Run it from the top source directory using the command
   output_to "src/structs-print.c" generate_client_structs_print_c;
   output_to "src/structs-print.h" generate_client_structs_print_h;
   output_to "src/actions-variants.c" generate_client_actions_variants;
-
-  for i = 0 to nr_actions_files-1 do
-    let filename = sprintf "src/actions-%d.c" i in
-    output_to filename (generate_client_actions i)
-  done;
-
+  output_to_subset "src/actions-%d.c" generate_client_actions;
   output_to "daemon/actions.h" generate_daemon_actions_h;
   output_to "daemon/stubs.c" generate_daemon_actions;
   output_to "daemon/names.c" generate_daemon_names;
-- 
2.9.3




More information about the Libguestfs mailing list