ocaml: dynamically generate the content of Guestfs.Errno

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.
This commit is contained in:
Pino Toscano
2015-08-24 17:57:10 +02:00
parent 0dcb862943
commit 649f439cb7
6 changed files with 70 additions and 44 deletions

1
.gitignore vendored
View File

@@ -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

View File

@@ -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;

View File

@@ -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 } ->

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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