diff --git a/generator/generator_bindtests.ml b/generator/generator_bindtests.ml index 02b068096..ebe2e246f 100644 --- a/generator/generator_bindtests.ml +++ b/generator/generator_bindtests.ml @@ -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"; diff --git a/generator/generator_c.ml b/generator/generator_c.ml index 4480200a1..a2f40da30 100644 --- a/generator/generator_c.ml +++ b/generator/generator_c.ml @@ -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); diff --git a/generator/generator_capitests.ml b/generator/generator_capitests.ml index 325b37c5c..190e10f7e 100644 --- a/generator/generator_capitests.ml +++ b/generator/generator_capitests.ml @@ -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 diff --git a/generator/generator_checks.ml b/generator/generator_checks.ml index 347404703..0fb8ea423 100644 --- a/generator/generator_checks.ml +++ b/generator/generator_checks.ml @@ -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, _) -> diff --git a/generator/generator_csharp.ml b/generator/generator_csharp.ml index e178945a8..5cc71c35a 100644 --- a/generator/generator_csharp.ml +++ b/generator/generator_csharp.ml @@ -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" diff --git a/generator/generator_daemon.ml b/generator/generator_daemon.ml index df9f965a7..e3d87e50e 100644 --- a/generator/generator_daemon.ml +++ b/generator/generator_daemon.ml @@ -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" ); diff --git a/generator/generator_fish.ml b/generator/generator_fish.ml index 76b4c7aad..f59c520ab 100644 --- a/generator/generator_fish.ml +++ b/generator/generator_fish.ml @@ -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 : 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 diff --git a/generator/generator_haskell.ml b/generator/generator_haskell.ml index b49e385bc..88e4f7fd2 100644 --- a/generator/generator_haskell.ml +++ b/generator/generator_haskell.ml @@ -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 ); diff --git a/generator/generator_java.ml b/generator/generator_java.ml index b55174088..5ac92f740 100644 --- a/generator/generator_java.ml +++ b/generator/generator_java.ml @@ -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. *) diff --git a/generator/generator_ocaml.ml b/generator/generator_ocaml.ml index 888a15274..860242c7e 100644 --- a/generator/generator_ocaml.ml +++ b/generator/generator_ocaml.ml @@ -198,6 +198,7 @@ and generate_ocaml_c () = #include #include #include +#include #include #include @@ -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 *) diff --git a/generator/generator_perl.ml b/generator/generator_perl.ml index 96b8dd18b..72f978df6 100644 --- a/generator/generator_perl.ml +++ b/generator/generator_perl.ml @@ -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 diff --git a/generator/generator_php.ml b/generator/generator_php.ml index b71d5c354..d405656db 100644 --- a/generator/generator_php.ml +++ b/generator/generator_php.ml @@ -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. *) diff --git a/generator/generator_python.ml b/generator/generator_python.ml index f85f5d6c1..bc570a88a 100644 --- a/generator/generator_python.ml +++ b/generator/generator_python.ml @@ -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; diff --git a/generator/generator_ruby.ml b/generator/generator_ruby.ml index d0a7cd209..6d627b052 100644 --- a/generator/generator_ruby.ml +++ b/generator/generator_ruby.ml @@ -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; diff --git a/generator/generator_types.ml b/generator/generator_types.ml index 262fb2057..a480aac97 100644 --- a/generator/generator_types.ml +++ b/generator/generator_types.ml @@ -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 *) diff --git a/generator/generator_utils.ml b/generator/generator_utils.ml index 425a57941..6dc11bfd8 100644 --- a/generator/generator_utils.ml +++ b/generator/generator_utils.ml @@ -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, _) diff --git a/generator/generator_xdr.ml b/generator/generator_xdr.ml index b44e2ef10..c6d8a4d01 100644 --- a/generator/generator_xdr.ml +++ b/generator/generator_xdr.ml @@ -86,6 +86,7 @@ let generate_xdr () = | BufferIn n -> pr " opaque %s<>;\n" n | FileIn _ | FileOut _ -> () + | Pointer _ -> assert false ) args; pr "};\n\n" );