| 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";
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 (
| 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;
| 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. *)
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);
) 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 =
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
) 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, _) ->
pr ", bool %s" n
| Int n ->
pr ", int %s" n
- | Int64 n ->
+ | Int64 n | Pointer (_, n) ->
pr ", long %s" n
) args;
pr ");\n"
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"
| BufferIn n ->
pr " const char *%s;\n" n;
pr " size_t %s_size;\n" n
+ | Pointer _ -> assert false
) args
);
pr "\n";
| 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"
);
| 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 (
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
pr " free_file_in (%s);\n" name
| StringList name | DeviceList name ->
pr " free_strings (%s);\n" name
+ | Pointer _ -> assert false
) args;
(* Any output flags? *)
| 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
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 =
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
| Bool _ -> pr "%s" bool
| Int _ -> pr "%s" int
| Int64 _ -> pr "%s" int
+ | Pointer _ -> pr "%s" int
| FileIn _ -> pr "%s" string
| FileOut _ -> pr "%s" string
);
pr "boolean %s" n
| Int n ->
pr "int %s" n
- | Int64 n ->
+ | Int64 n | Pointer (_, n) ->
pr "long %s" n
) args;
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
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 =
| 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 (
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. *)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
#include <caml/config.h>
#include <caml/alloc.h>
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. *)
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
| 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;
| 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 *)
| 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). *)
| 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;
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
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;
| 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
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 (
pr " %s[c] = NULL;\n" n;
pr " }\n";
pr "\n"
- | Bool n | Int n | Int64 n -> ()
+ | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
) args;
(* Optional arguments. *)
pr " efree (%s);\n" n;
pr " }\n";
pr "\n"
- | Bool n | Int n | Int64 n -> ()
+ | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
) args;
(* Check for errors. *)
| 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 (
| 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;
| 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;
| 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";
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;
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";
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;
*)
| 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 *)
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, _)
| BufferIn n ->
pr " opaque %s<>;\n" n
| FileIn _ | FileOut _ -> ()
+ | Pointer _ -> assert false
) args;
pr "};\n\n"
);