mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-22 07:03:38 +00:00
generator: Add Pointer parameter type to the generator.
This allows generic "foo *bar" pointers to be passed to library functions (not to daemon functions). In the language bindings (except Perl) these are handled as generic int64s with the assumption being that any pointer can be converted to and from this. There is room to add specific support for some pointer types in future by specializing the match cases. However this is inherently tricky because it depends on the implementation details of other bindings (eg. to support virDomainPtr in OCaml depends on the implementation details of the ocaml-libvirt project). Perl is slightly different in that you have to supply a typemap. Again this would depend on the implementation detail of an external library unless you supplied a generic typemap for int64.
This commit is contained in:
committed by
Richard W.M. Jones
parent
eaedf025f5
commit
4ada0a7815
@@ -89,6 +89,7 @@ print_strings (char *const *argv)
|
||||
| Bool n -> pr " printf (\"%%s\\n\", %s ? \"true\" : \"false\");\n" n
|
||||
| Int n -> pr " printf (\"%%d\\n\", %s);\n" n
|
||||
| Int64 n -> pr " printf (\"%%\" PRIi64 \"\\n\", %s);\n" n
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
pr " /* Java changes stdout line buffering so we need this: */\n";
|
||||
pr " fflush (stdout);\n";
|
||||
|
||||
@@ -116,6 +116,9 @@ let rec generate_prototype ?(extern = true) ?(static = false)
|
||||
pr "const char *%s" n;
|
||||
next ();
|
||||
pr "size_t %s_size" n
|
||||
| Pointer (t, n) ->
|
||||
next ();
|
||||
pr "%s %s" t n
|
||||
) args;
|
||||
if is_RBufferOut then (next (); pr "size_t *size_r");
|
||||
if optargs <> [] then (
|
||||
@@ -536,7 +539,8 @@ check_state (guestfs_h *g, const char *caller)
|
||||
| BufferIn n
|
||||
| StringList n
|
||||
| DeviceList n
|
||||
| Key n ->
|
||||
| Key n
|
||||
| Pointer (_, n) ->
|
||||
pr " if (%s == NULL) {\n" n;
|
||||
pr " error (g, \"%%s: %%s: parameter cannot be NULL\",\n";
|
||||
pr " \"%s\", \"%s\");\n" shortname n;
|
||||
@@ -639,6 +643,8 @@ check_state (guestfs_h *g, const char *caller)
|
||||
| BufferIn n -> (* RHBZ#646822 *)
|
||||
pr " fputc (' ', stderr);\n";
|
||||
pr " guestfs___print_BufferIn (stderr, %s, %s_size);\n" n n
|
||||
| Pointer (t, n) ->
|
||||
pr " fprintf (stderr, \" (%s)%%p\", %s);\n" t n
|
||||
) args;
|
||||
|
||||
(* Optional arguments. *)
|
||||
@@ -770,6 +776,7 @@ check_state (guestfs_h *g, const char *caller)
|
||||
pr " }\n";
|
||||
pr " args.%s.%s_val = (char *) %s;\n" n n n;
|
||||
pr " args.%s.%s_len = %s_size;\n" n n n
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
pr " serial = guestfs___send (g, GUESTFS_PROC_%s,\n"
|
||||
(String.uppercase shortname);
|
||||
|
||||
@@ -744,6 +744,9 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
|
||||
) strs;
|
||||
pr " NULL\n";
|
||||
pr " };\n";
|
||||
| Pointer _, _ ->
|
||||
(* Difficult to make these pointers in order to run a test. *)
|
||||
assert false
|
||||
) (List.combine (snd style) args);
|
||||
|
||||
let error_code =
|
||||
@@ -799,6 +802,7 @@ and generate_test_command_call ?(expect_error = false) ?test test_name cmd =
|
||||
pr ", %Ld" i
|
||||
| Bool _, arg ->
|
||||
let b = bool_of_string arg in pr ", %d" (if b then 1 else 0)
|
||||
| Pointer _, _ -> assert false
|
||||
) (List.combine (snd style) args);
|
||||
|
||||
(match fst style with
|
||||
|
||||
@@ -129,6 +129,19 @@ let () =
|
||||
) optargs
|
||||
) all_functions;
|
||||
|
||||
(* Some parameter types not supported for daemon functions. *)
|
||||
List.iter (
|
||||
fun (name, (_, args, optargs), _, _, _, _, _) ->
|
||||
let check_arg_type = function
|
||||
| Pointer _ ->
|
||||
failwithf "Pointer is not supported for daemon function %s."
|
||||
name
|
||||
| _ -> ()
|
||||
in
|
||||
List.iter check_arg_type args;
|
||||
List.iter check_arg_type optargs;
|
||||
) daemon_functions;
|
||||
|
||||
(* Check short descriptions. *)
|
||||
List.iter (
|
||||
fun (name, _, _, _, _, shortdesc, _) ->
|
||||
|
||||
@@ -197,7 +197,7 @@ namespace Guestfs
|
||||
pr ", bool %s" n
|
||||
| Int n ->
|
||||
pr ", int %s" n
|
||||
| Int64 n ->
|
||||
| Int64 n | Pointer (_, n) ->
|
||||
pr ", long %s" n
|
||||
) args;
|
||||
pr ");\n"
|
||||
@@ -222,7 +222,7 @@ namespace Guestfs
|
||||
next (); pr "bool %s" n
|
||||
| Int n ->
|
||||
next (); pr "int %s" n
|
||||
| Int64 n ->
|
||||
| Int64 n | Pointer (_, n) ->
|
||||
next (); pr "long %s" n
|
||||
) args;
|
||||
pr ")\n"
|
||||
|
||||
@@ -105,6 +105,7 @@ and generate_daemon_actions () =
|
||||
| BufferIn n ->
|
||||
pr " const char *%s;\n" n;
|
||||
pr " size_t %s_size;\n" n
|
||||
| Pointer _ -> assert false
|
||||
) args
|
||||
);
|
||||
pr "\n";
|
||||
@@ -174,6 +175,7 @@ and generate_daemon_actions () =
|
||||
| BufferIn n ->
|
||||
pr " %s = args.%s.%s_val;\n" n n n;
|
||||
pr " %s_size = args.%s.%s_len;\n" n n n
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
pr "\n"
|
||||
);
|
||||
|
||||
@@ -323,6 +323,7 @@ Guestfish will prompt for these separately."
|
||||
| Bool n -> pr " int %s;\n" n
|
||||
| Int n -> pr " int %s;\n" n
|
||||
| Int64 n -> pr " int64_t %s;\n" n
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
|
||||
if optargs <> [] then (
|
||||
@@ -423,6 +424,7 @@ Guestfish will prompt for these separately."
|
||||
parse_integer "argv[i++]" "xstrtoll" "long long" "int" range name
|
||||
| Int64 name ->
|
||||
parse_integer "argv[i++]" "xstrtoll" "long long" "int64_t" None name
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
|
||||
(* Optional arguments are prefixed with <argname>:<value> and
|
||||
@@ -506,6 +508,7 @@ Guestfish will prompt for these separately."
|
||||
pr " free_file_in (%s);\n" name
|
||||
| StringList name | DeviceList name ->
|
||||
pr " free_strings (%s);\n" name
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
|
||||
(* Any output flags? *)
|
||||
@@ -810,6 +813,7 @@ and generate_fish_actions_pod () =
|
||||
| FileIn n | FileOut n -> pr " (%s|-)" n
|
||||
| BufferIn n -> pr " %s" n
|
||||
| Key _ -> () (* keys are entered at a prompt *)
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
List.iter (
|
||||
function
|
||||
|
||||
@@ -148,7 +148,7 @@ last_error h = do
|
||||
pr "withCStringLen %s $ \\(%s, %s_size) -> " n n n
|
||||
| OptString n -> pr "maybeWith withCString %s $ \\%s -> " n n
|
||||
| StringList n | DeviceList n -> pr "withMany withCString %s $ \\%s -> withArray0 nullPtr %s $ \\%s -> " n n n n
|
||||
| Bool _ | Int _ | Int64 _ -> ()
|
||||
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
|
||||
) args;
|
||||
(* Convert integer arguments. *)
|
||||
let args =
|
||||
@@ -156,7 +156,7 @@ last_error h = do
|
||||
function
|
||||
| Bool n -> sprintf "(fromBool %s)" n
|
||||
| Int n -> sprintf "(fromIntegral %s)" n
|
||||
| Int64 n -> sprintf "(fromIntegral %s)" n
|
||||
| Int64 n | Pointer (_, n) -> sprintf "(fromIntegral %s)" n
|
||||
| FileIn n | FileOut n
|
||||
| Pathname n | Device n | Dev_or_Path n
|
||||
| String n | OptString n
|
||||
@@ -222,6 +222,7 @@ and generate_haskell_prototype ~handle ?(hs = false) (ret, args, optargs) =
|
||||
| Bool _ -> pr "%s" bool
|
||||
| Int _ -> pr "%s" int
|
||||
| Int64 _ -> pr "%s" int
|
||||
| Pointer _ -> pr "%s" int
|
||||
| FileIn _ -> pr "%s" string
|
||||
| FileOut _ -> pr "%s" string
|
||||
);
|
||||
|
||||
@@ -217,7 +217,7 @@ and generate_java_prototype ?(public=false) ?(privat=false) ?(native=false)
|
||||
pr "boolean %s" n
|
||||
| Int n ->
|
||||
pr "int %s" n
|
||||
| Int64 n ->
|
||||
| Int64 n | Pointer (_, n) ->
|
||||
pr "long %s" n
|
||||
) args;
|
||||
|
||||
@@ -347,7 +347,7 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
|
||||
pr ", jboolean j%s" n
|
||||
| Int n ->
|
||||
pr ", jint j%s" n
|
||||
| Int64 n ->
|
||||
| Int64 n | Pointer (_, n) ->
|
||||
pr ", jlong j%s" n
|
||||
) args;
|
||||
if optargs <> [] then
|
||||
@@ -410,6 +410,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
|
||||
pr " int %s;\n" n
|
||||
| Int64 n ->
|
||||
pr " int64_t %s;\n" n
|
||||
| Pointer (t, n) ->
|
||||
pr " %s %s;\n" t n
|
||||
) args;
|
||||
|
||||
let needs_i =
|
||||
@@ -458,6 +460,8 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
|
||||
| Int n
|
||||
| Int64 n ->
|
||||
pr " %s = j%s;\n" n n
|
||||
| Pointer (t, n) ->
|
||||
pr " %s = (%s) j%s;\n" n t n
|
||||
) args;
|
||||
|
||||
if optargs <> [] then (
|
||||
@@ -497,9 +501,10 @@ Java_com_redhat_et_libguestfs_GuestFS__1close
|
||||
pr " (*env)->ReleaseStringUTFChars (env, o, %s[i]);\n" n;
|
||||
pr " }\n";
|
||||
pr " free (%s);\n" n
|
||||
| Bool n
|
||||
| Int n
|
||||
| Int64 n -> ()
|
||||
| Bool _
|
||||
| Int _
|
||||
| Int64 _
|
||||
| Pointer _ -> ()
|
||||
) args;
|
||||
|
||||
(* Check for errors. *)
|
||||
|
||||
@@ -198,6 +198,7 @@ and generate_ocaml_c () =
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <caml/config.h>
|
||||
#include <caml/alloc.h>
|
||||
@@ -400,6 +401,8 @@ copy_table (char * const * argv)
|
||||
pr " int %s = Int_val (%sv);\n" n n
|
||||
| Int64 n ->
|
||||
pr " int64_t %s = Int64_val (%sv);\n" n n
|
||||
| Pointer (t, n) ->
|
||||
pr " %s %s = (%s) (intptr_t) Int64_val (%sv);\n" t n t n
|
||||
) args;
|
||||
|
||||
(* Optional arguments. *)
|
||||
@@ -471,7 +474,7 @@ copy_table (char * const * argv)
|
||||
pr " free (%s);\n" n
|
||||
| StringList n | DeviceList n ->
|
||||
pr " ocaml_guestfs_free_strings (%s);\n" n;
|
||||
| Bool _ | Int _ | Int64 _ -> ()
|
||||
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
|
||||
) args;
|
||||
List.iter (
|
||||
function
|
||||
@@ -481,7 +484,7 @@ copy_table (char * const * argv)
|
||||
| Bool _ | Int _ | Int64 _
|
||||
| Pathname _ | Device _ | Dev_or_Path _ | OptString _
|
||||
| FileIn _ | FileOut _ | BufferIn _ | Key _
|
||||
| StringList _ | DeviceList _ -> ()
|
||||
| StringList _ | DeviceList _ | Pointer _ -> ()
|
||||
) optargs;
|
||||
|
||||
pr " if (r == %s)\n" error_code;
|
||||
@@ -592,7 +595,7 @@ and generate_ocaml_function_type (ret, args, optargs) =
|
||||
| StringList _ | DeviceList _ -> pr "string array -> "
|
||||
| Bool _ -> pr "bool -> "
|
||||
| Int _ -> pr "int -> "
|
||||
| Int64 _ -> pr "int64 -> "
|
||||
| Int64 _ | Pointer _ -> pr "int64 -> "
|
||||
) args;
|
||||
(match ret with
|
||||
| RErr -> pr "unit" (* all errors are turned into exceptions *)
|
||||
|
||||
@@ -242,6 +242,7 @@ clear_progress_callback (g)
|
||||
| Bool n -> pr " int %s;\n" n
|
||||
| Int n -> pr " int %s;\n" n
|
||||
| Int64 n -> pr " int64_t %s;\n" n
|
||||
| Pointer (t, n) -> pr " %s %s;\n" t n
|
||||
) args;
|
||||
|
||||
(* PREINIT section (local variable declarations). *)
|
||||
@@ -362,7 +363,7 @@ clear_progress_callback (g)
|
||||
| Pathname _ | Device _ | Dev_or_Path _ | String _ | OptString _
|
||||
| Bool _ | Int _ | Int64 _
|
||||
| FileIn _ | FileOut _
|
||||
| BufferIn _ | Key _ -> ()
|
||||
| BufferIn _ | Key _ | Pointer _ -> ()
|
||||
| StringList n | DeviceList n -> pr " free (%s);\n" n
|
||||
) args;
|
||||
|
||||
@@ -751,7 +752,7 @@ and generate_perl_prototype name (ret, args, optargs) =
|
||||
match arg with
|
||||
| Pathname n | Device n | Dev_or_Path n | String n
|
||||
| OptString n | Bool n | Int n | Int64 n | FileIn n | FileOut n
|
||||
| BufferIn n | Key n ->
|
||||
| BufferIn n | Key n | Pointer (_, n) ->
|
||||
pr "$%s" n
|
||||
| StringList n | DeviceList n ->
|
||||
pr "\\@%s" n
|
||||
|
||||
@@ -200,7 +200,7 @@ PHP_FUNCTION (guestfs_last_error)
|
||||
pr " char **%s;\n" n;
|
||||
| Bool n ->
|
||||
pr " zend_bool %s;\n" n
|
||||
| Int n | Int64 n ->
|
||||
| Int n | Int64 n | Pointer (_, n) ->
|
||||
pr " long %s;\n" n
|
||||
) args;
|
||||
|
||||
@@ -236,7 +236,7 @@ PHP_FUNCTION (guestfs_last_error)
|
||||
| OptString n -> "s!"
|
||||
| StringList n | DeviceList n -> "a"
|
||||
| Bool n -> "b"
|
||||
| Int n | Int64 n -> "l"
|
||||
| Int n | Int64 n | Pointer (_, n) -> "l"
|
||||
) args
|
||||
) in
|
||||
|
||||
@@ -267,7 +267,7 @@ PHP_FUNCTION (guestfs_last_error)
|
||||
pr ", &z_%s" n
|
||||
| Bool n ->
|
||||
pr ", &%s" n
|
||||
| Int n | Int64 n ->
|
||||
| Int n | Int64 n | Pointer (_, n) ->
|
||||
pr ", &%s" n
|
||||
) args;
|
||||
List.iter (
|
||||
@@ -330,7 +330,7 @@ PHP_FUNCTION (guestfs_last_error)
|
||||
pr " %s[c] = NULL;\n" n;
|
||||
pr " }\n";
|
||||
pr "\n"
|
||||
| Bool n | Int n | Int64 n -> ()
|
||||
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
|
||||
) args;
|
||||
|
||||
(* Optional arguments. *)
|
||||
@@ -406,7 +406,7 @@ PHP_FUNCTION (guestfs_last_error)
|
||||
pr " efree (%s);\n" n;
|
||||
pr " }\n";
|
||||
pr "\n"
|
||||
| Bool n | Int n | Int64 n -> ()
|
||||
| Bool _ | Int _ | Int64 _ | Pointer _ -> ()
|
||||
) args;
|
||||
|
||||
(* Check for errors. *)
|
||||
|
||||
@@ -324,6 +324,9 @@ py_guestfs_close (PyObject *self, PyObject *args)
|
||||
| Bool n -> pr " int %s;\n" n
|
||||
| Int n -> pr " int %s;\n" n
|
||||
| Int64 n -> pr " long long %s;\n" n
|
||||
| Pointer (t, n) ->
|
||||
pr " long long %s_int64;\n" n;
|
||||
pr " %s %s;\n" t n
|
||||
) args;
|
||||
|
||||
if optargs <> [] then (
|
||||
@@ -360,9 +363,11 @@ py_guestfs_close (PyObject *self, PyObject *args)
|
||||
| StringList _ | DeviceList _ -> pr "O"
|
||||
| Bool _ -> pr "i" (* XXX Python has booleans? *)
|
||||
| Int _ -> pr "i"
|
||||
| Int64 _ -> pr "L" (* XXX Whoever thought it was a good idea to
|
||||
* emulate C's int/long/long long in Python?
|
||||
*)
|
||||
| Int64 _ | Pointer _ ->
|
||||
(* XXX Whoever thought it was a good idea to
|
||||
* emulate C's int/long/long long in Python?
|
||||
*)
|
||||
pr "L"
|
||||
| BufferIn _ -> pr "s#"
|
||||
) args;
|
||||
|
||||
@@ -388,6 +393,7 @@ py_guestfs_close (PyObject *self, PyObject *args)
|
||||
| Bool n -> pr ", &%s" n
|
||||
| Int n -> pr ", &%s" n
|
||||
| Int64 n -> pr ", &%s" n
|
||||
| Pointer (_, n) -> pr ", &%s_int64" n
|
||||
| BufferIn n -> pr ", &%s, &%s_size" n n
|
||||
) args;
|
||||
|
||||
@@ -409,6 +415,8 @@ py_guestfs_close (PyObject *self, PyObject *args)
|
||||
| StringList n | DeviceList n ->
|
||||
pr " %s = get_string_list (py_%s);\n" n n;
|
||||
pr " if (!%s) return NULL;\n" n
|
||||
| Pointer (t, n) ->
|
||||
pr " %s = (%s) (intptr_t) %s_int64;\n" n t n
|
||||
) args;
|
||||
|
||||
pr "\n";
|
||||
@@ -444,7 +452,7 @@ py_guestfs_close (PyObject *self, PyObject *args)
|
||||
function
|
||||
| Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _
|
||||
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
|
||||
| BufferIn _ -> ()
|
||||
| BufferIn _ | Pointer _ -> ()
|
||||
| StringList n | DeviceList n ->
|
||||
pr " free (%s);\n" n
|
||||
) args;
|
||||
|
||||
@@ -148,6 +148,8 @@ static VALUE ruby_guestfs_close (VALUE gv)
|
||||
pr " int %s = NUM2INT (%sv);\n" n n
|
||||
| Int64 n ->
|
||||
pr " long long %s = NUM2LL (%sv);\n" n n
|
||||
| Pointer (t, n) ->
|
||||
pr " %s %s = (%s) (intptr_t) NUM2LL (%sv);\n" t n t n
|
||||
) args;
|
||||
pr "\n";
|
||||
|
||||
@@ -210,7 +212,7 @@ static VALUE ruby_guestfs_close (VALUE gv)
|
||||
function
|
||||
| Pathname _ | Device _ | Dev_or_Path _ | String _ | Key _
|
||||
| FileIn _ | FileOut _ | OptString _ | Bool _ | Int _ | Int64 _
|
||||
| BufferIn _ -> ()
|
||||
| BufferIn _ | Pointer _ -> ()
|
||||
| StringList n | DeviceList n ->
|
||||
pr " free (%s);\n" n
|
||||
) args;
|
||||
|
||||
@@ -185,6 +185,23 @@ and argt =
|
||||
*)
|
||||
| FileIn of string
|
||||
| FileOut of string
|
||||
(* This specifies an opaque pointer that is passed through
|
||||
* untouched. Only non-daemon functions are supported.
|
||||
*
|
||||
* Pointer ("foo *", "bar") translates to "foo *bar" in the
|
||||
* C API. The pointer ("bar") cannot be NULL.
|
||||
*
|
||||
* This is less well supported in other language bindings:
|
||||
* if the pointer type is known then we may be able to produce
|
||||
* a suitable binding, otherwise this is translated into a 64
|
||||
* bit int.
|
||||
*
|
||||
* Functions with this parameter type are not supported at all
|
||||
* in guestfish (the function must be declared "NotInFish" else
|
||||
* you will get an error). Also the function cannot contain
|
||||
* tests, although we should fix this in future.
|
||||
*)
|
||||
| Pointer of (string * string)
|
||||
|
||||
type flags =
|
||||
| ProtocolLimitWarning (* display warning about protocol size limits *)
|
||||
|
||||
@@ -230,7 +230,7 @@ let map_chars f str =
|
||||
let name_of_argt = function
|
||||
| Pathname n | Device n | Dev_or_Path n | String n | OptString n
|
||||
| StringList n | DeviceList n | Bool n | Int n | Int64 n
|
||||
| FileIn n | FileOut n | BufferIn n | Key n -> n
|
||||
| FileIn n | FileOut n | BufferIn n | Key n | Pointer (_, n) -> n
|
||||
|
||||
let seq_of_test = function
|
||||
| TestRun s | TestOutput (s, _) | TestOutputList (s, _)
|
||||
|
||||
@@ -86,6 +86,7 @@ let generate_xdr () =
|
||||
| BufferIn n ->
|
||||
pr " opaque %s<>;\n" n
|
||||
| FileIn _ | FileOut _ -> ()
|
||||
| Pointer _ -> assert false
|
||||
) args;
|
||||
pr "};\n\n"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user