[Libguestfs] [PATCH 1/3] ocaml: dynamically generate the content of Guestfs.Errno

Pino Toscano ptoscano at redhat.com
Mon Aug 24 16:28:28 UTC 2015


Put in a list the errnos to expose, filling the content of the
Guestfs.Errno submodule from that.
Also, generate a separate guestfs-c-errnos.c with the implementations of
the functions returning the errno codes.

Only code motion and refactoring, no actual changes on the content of
the ocaml Guestfs module.
---
 .gitignore         |  1 +
 generator/main.ml  |  1 +
 generator/ocaml.ml | 77 +++++++++++++++++++++++++++++++++++++++++++++---------
 ocaml/Makefile.am  |  2 ++
 ocaml/guestfs-c.c  | 32 -----------------------
 po/POTFILES        |  1 +
 6 files changed, 70 insertions(+), 44 deletions(-)

diff --git a/.gitignore b/.gitignore
index e968399..fb972a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -332,6 +332,7 @@ Makefile.in
 /ocaml/examples/inspect_vm
 /ocaml/examples/stamp-guestfs-ocaml.pod
 /ocaml/guestfs-c-actions.c
+/ocaml/guestfs-c-errnos.c
 /ocaml/guestfs.ml
 /ocaml/guestfs.mli
 /ocamlinit-stamp
diff --git a/generator/main.ml b/generator/main.ml
index 94f0d09..1e0e7d6 100644
--- a/generator/main.ml
+++ b/generator/main.ml
@@ -125,6 +125,7 @@ Run it from the top source directory using the command
   output_to "ocaml/guestfs.mli" generate_ocaml_mli;
   output_to "ocaml/guestfs.ml" generate_ocaml_ml;
   output_to "ocaml/guestfs-c-actions.c" generate_ocaml_c;
+  output_to "ocaml/guestfs-c-errnos.c" generate_ocaml_c_errnos;
   output_to "ocaml/bindtests.ml" generate_ocaml_bindtests;
   output_to "perl/Guestfs.xs" generate_perl_xs;
   output_to "perl/lib/Sys/Guestfs.pm" generate_perl_pm;
diff --git a/generator/ocaml.ml b/generator/ocaml.ml
index 05c7456..7742209 100644
--- a/generator/ocaml.ml
+++ b/generator/ocaml.ml
@@ -30,6 +30,14 @@ open Structs
 open C
 open Events
 
+(* List of errnos to expose on Guestfs.Errno. *)
+let ocaml_errnos = [
+  "EINVAL";
+  "ENOTSUP";
+  "EPERM";
+  "ESRCH";
+]
+
 (* Generate the OCaml bindings interface. *)
 let rec generate_ocaml_mli () =
   generate_header OCamlStyle LGPLv2plus;
@@ -132,10 +140,12 @@ val last_errno : t -> int
     which you can use to test the return value of {!Guestfs.last_errno}. *)
 
 module Errno : sig
-  val errno_EINVAL : int
-  val errno_ENOTSUP : int
-  val errno_EPERM : int
-  val errno_ESRCH : int
+";
+  List.iter (
+    fun e ->
+      pr "  val errno_%s : int\n" e
+  ) ocaml_errnos;
+  pr "\
 end
 
 ";
@@ -287,14 +297,15 @@ external event_to_string : event list -> string
 external last_errno : t -> int = \"ocaml_guestfs_last_errno\"
 
 module Errno = struct
-  external einval : unit -> int = \"ocaml_guestfs_get_EINVAL\" \"noalloc\"
-  let errno_EINVAL = einval ()
-  external enotsup : unit -> int = \"ocaml_guestfs_get_ENOTSUP\" \"noalloc\"
-  let errno_ENOTSUP = enotsup ()
-  external eperm : unit -> int = \"ocaml_guestfs_get_EPERM\" \"noalloc\"
-  let errno_EPERM = eperm ()
-  external esrch : unit -> int = \"ocaml_guestfs_get_ESRCH\" \"noalloc\"
-  let errno_ESRCH = esrch ()
+";
+  List.iter (
+    fun e ->
+      let le = String.lowercase e in
+      pr "  external %s : unit -> int = \"ocaml_guestfs_get_%s\" \"noalloc\"\n"
+        le e;
+      pr "  let errno_%s = %s ()\n" e le
+  ) ocaml_errnos;
+  pr "\
 end
 
 (* Give the exceptions names, so they can be raised from the C code. *)
@@ -717,6 +728,48 @@ copy_table (char * const * argv)
       )
   ) external_functions_sorted
 
+(* Generate the OCaml bindings C errnos. *)
+and generate_ocaml_c_errnos () =
+  generate_header CStyle LGPLv2plus;
+
+  pr "\
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <caml/config.h>
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+
+#include \"guestfs.h\"
+
+#include \"guestfs-c.h\"
+
+/* These prototypes are solely to quiet gcc warnings. */
+";
+  List.iter (
+    fun e ->
+      pr "value ocaml_guestfs_get_%s (value unitv);\n" e
+  ) ocaml_errnos;
+
+  List.iter (
+    fun e ->
+      pr "\
+
+/* NB: \"noalloc\" function. */
+value
+ocaml_guestfs_get_%s (value unitv)
+{
+  return Val_int (%s);
+}
+" e e
+  ) ocaml_errnos
+
 and generate_ocaml_structure_decls () =
   List.iter (
     fun { s_name = typ; s_cols = cols } ->
diff --git a/ocaml/Makefile.am b/ocaml/Makefile.am
index db13a8f..e781363 100644
--- a/ocaml/Makefile.am
+++ b/ocaml/Makefile.am
@@ -21,6 +21,7 @@ generator_built = \
 	guestfs.mli \
 	guestfs.ml \
 	guestfs-c-actions.c \
+	guestfs-c-errnos.c \
 	$(srcdir)/bindtests.ml
 
 EXTRA_DIST = \
@@ -89,6 +90,7 @@ libguestfsocaml_a_CFLAGS = \
 libguestfsocaml_a_SOURCES = \
 	guestfs-c.c \
 	guestfs-c-actions.c \
+	guestfs-c-errnos.c \
 	../src/utils.c
 
 if HAVE_OCAMLDOC
diff --git a/ocaml/guestfs-c.c b/ocaml/guestfs-c.c
index 9603f04..03e3659 100644
--- a/ocaml/guestfs-c.c
+++ b/ocaml/guestfs-c.c
@@ -63,10 +63,6 @@ value ocaml_guestfs_set_event_callback (value gv, value closure, value events);
 value ocaml_guestfs_delete_event_callback (value gv, value eh);
 value ocaml_guestfs_event_to_string (value events);
 value ocaml_guestfs_last_errno (value gv);
-value ocaml_guestfs_get_EINVAL (value unitv);
-value ocaml_guestfs_get_ENOTSUP (value unitv);
-value ocaml_guestfs_get_EPERM (value unitv);
-value ocaml_guestfs_get_ESRCH (value unitv);
 
 /* Allocate handles and deal with finalization. */
 static void
@@ -442,31 +438,3 @@ ocaml_guestfs_last_errno (value gv)
   rv = Val_int (r);
   CAMLreturn (rv);
 }
-
-/* NB: "noalloc" function. */
-value
-ocaml_guestfs_get_EINVAL (value unitv)
-{
-  return Val_int (EINVAL);
-}
-
-/* NB: "noalloc" function. */
-value
-ocaml_guestfs_get_ENOTSUP (value unitv)
-{
-  return Val_int (ENOTSUP);
-}
-
-/* NB: "noalloc" function. */
-value
-ocaml_guestfs_get_EPERM (value unitv)
-{
-  return Val_int (EPERM);
-}
-
-/* NB: "noalloc" function. */
-value
-ocaml_guestfs_get_ESRCH (value unitv)
-{
-  return Val_int (ESRCH);
-}
diff --git a/po/POTFILES b/po/POTFILES
index 7f1580c..6a0a3fc 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -263,6 +263,7 @@ mllib/mkdtemp-c.c
 mllib/progress-c.c
 mllib/uri-c.c
 ocaml/guestfs-c-actions.c
+ocaml/guestfs-c-errnos.c
 ocaml/guestfs-c.c
 p2v/about-authors.c
 p2v/about-license.c
-- 
2.1.0




More information about the Libguestfs mailing list