summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generator/generator_actions.ml32
-rw-r--r--generator/generator_bindtests.ml94
-rw-r--r--src/guestfs-internal.h3
-rw-r--r--src/guestfs.c4
4 files changed, 111 insertions, 22 deletions
diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml
index 7db88cea..f370b795 100644
--- a/generator/generator_actions.ml
+++ b/generator/generator_actions.ml
@@ -83,7 +83,8 @@ This is an internal test function which is used to test whether
the automatically generated bindings can handle every possible
parameter type correctly.
-It echos the contents of each parameter to stdout.
+It echos the contents of each parameter to stdout (by default)
+or to a file (if C<guestfs_internal_test_set_output> was called).
You probably don't want to call this function." }
] @ List.flatten (
@@ -126,6 +127,35 @@ You probably don't want to call this function." }
let non_daemon_functions = test_functions @ [
{ defaults with
+ name = "internal_test_set_output";
+ style = RErr, [String "filename"], [];
+ in_fish = false; in_docs = false;
+ shortdesc = "internal test function - do not use";
+ longdesc = "\
+This is an internal test function which is used to test whether
+the automatically generated bindings can handle every possible
+parameter type correctly.
+
+It sets the output file used by C<guestfs_internal_test>.
+
+You probably don't want to call this function." };
+
+ { defaults with
+ name = "internal_test_close_output";
+ style = RErr, [], [];
+ in_fish = false; in_docs = false;
+ shortdesc = "internal test function - do not use";
+ longdesc = "\
+This is an internal test function which is used to test whether
+the automatically generated bindings can handle every possible
+parameter type correctly.
+
+It closes the output file previously opened by
+C<guestfs_internal_test_set_output>.
+
+You probably don't want to call this function." };
+
+ { defaults with
name = "launch";
style = RErr, [], [];
fish_alias = ["run"]; progress = true; config_only = true;
diff --git a/generator/generator_bindtests.ml b/generator/generator_bindtests.ml
index 67a5bbac..aaadd370 100644
--- a/generator/generator_bindtests.ml
+++ b/generator/generator_bindtests.ml
@@ -45,20 +45,68 @@ let rec generate_bindtests () =
#include \"guestfs-internal-actions.h\"
#include \"guestfs_protocol.h\"
+int
+guestfs__internal_test_set_output (guestfs_h *g, const char *filename)
+{
+ FILE *fp;
+
+ fp = fopen (filename, \"w\");
+ if (fp == NULL) {
+ perrorf (g, \"cannot open output file %%s\\n\", filename);
+ return -1;
+ }
+
+ if (guestfs_internal_test_close_output (g) == -1) {
+ fclose (fp);
+ return -1;
+ }
+
+ g->test_fp = fp;
+
+ return 0;
+}
+
+int
+guestfs__internal_test_close_output (guestfs_h *g)
+{
+ if (g->test_fp != NULL) {
+ if (fclose (g->test_fp) == EOF) {
+ perrorf (g, \"fclose\");
+ g->test_fp = NULL;
+ return -1;
+ }
+ g->test_fp = NULL;
+ }
+
+ return 0;
+}
+
+static inline FILE *
+get_fp (guestfs_h *g)
+{
+ if (g->test_fp)
+ return g->test_fp;
+ else
+ return stdout;
+}
+
static void
-print_strings (char *const *argv)
+print_strings (guestfs_h *g, char *const *argv)
{
+ FILE *fp = get_fp (g);
size_t argc;
- printf (\"[\");
+ fprintf (fp, \"[\");
for (argc = 0; argv[argc] != NULL; ++argc) {
- if (argc > 0) printf (\", \");
- printf (\"\\\"%%s\\\"\", argv[argc]);
+ if (argc > 0) fprintf (fp, \", \");
+ fprintf (fp, \"\\\"%%s\\\"\", argv[argc]);
}
- printf (\"]\\n\");
+ fprintf (fp, \"]\\n\");
}
-/* The internal_test function prints its parameters to stdout. */
+/* The internal_test function prints its parameters to stdout or the
+ * file set by internal_test_set_output.
+ */
";
let test, tests =
@@ -71,6 +119,9 @@ print_strings (char *const *argv)
generate_prototype ~extern:false ~semicolon:false ~newline:true
~handle:"g" ~prefix:"guestfs__" ~optarg_proto:Argv name style;
pr "{\n";
+ pr " FILE *fp = get_fp (g);\n";
+ pr "\n";
+
List.iter (
function
| Pathname n
@@ -78,28 +129,29 @@ print_strings (char *const *argv)
| String n
| FileIn n
| FileOut n
- | Key n -> pr " printf (\"%%s\\n\", %s);\n" n
+ | Key n -> pr " fprintf (fp, \"%%s\\n\", %s);\n" n
| BufferIn n ->
pr " {\n";
pr " size_t i;\n";
pr " for (i = 0; i < %s_size; ++i)\n" n;
- pr " printf (\"<%%02x>\", %s[i]);\n" n;
- pr " printf (\"\\n\");\n";
+ pr " fprintf (fp, \"<%%02x>\", %s[i]);\n" n;
+ pr " fprintf (fp, \"\\n\");\n";
pr " }\n";
- | OptString n -> pr " printf (\"%%s\\n\", %s ? %s : \"null\");\n" n n
- | StringList n | DeviceList n -> pr " print_strings (%s);\n" n
- | 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
+ | OptString n -> pr " fprintf (fp, \"%%s\\n\", %s ? %s : \"null\");\n" n n
+ | StringList n | DeviceList n -> pr " print_strings (g, %s);\n" n
+ | Bool n -> pr " fprintf (fp, \"%%s\\n\", %s ? \"true\" : \"false\");\n" n
+ | Int n -> pr " fprintf (fp, \"%%d\\n\", %s);\n" n
+ | Int64 n -> pr " fprintf (fp, \"%%\" PRIi64 \"\\n\", %s);\n" n
| Pointer _ -> assert false
) args;
+
let check_optarg n printf_args =
- pr " printf (\"%s: \");\n" n;
+ pr " fprintf (fp, \"%s: \");\n" n;
pr " if (optargs->bitmask & GUESTFS_INTERNAL_TEST_%s_BITMASK) {\n"
(String.uppercase n);
- pr " printf (%s);\n" printf_args;
+ pr " fprintf (fp, %s);\n" printf_args;
pr " } else {\n";
- pr " printf (\"unset\\n\");\n";
+ pr " fprintf (fp, \"unset\\n\");\n";
pr " }\n";
in
List.iter (
@@ -118,16 +170,16 @@ print_strings (char *const *argv)
let printf_args = sprintf "\"%%s\\n\", optargs->%s" n in
check_optarg n printf_args;
| OStringList n ->
- pr " printf (\"%s: \");\n" n;
+ pr " fprintf (fp, \"%s: \");\n" n;
pr " if (optargs->bitmask & GUESTFS_INTERNAL_TEST_%s_BITMASK) {\n"
(String.uppercase n);
- pr " print_strings (optargs->%s);\n" n;
+ pr " print_strings (g, optargs->%s);\n" n;
pr " } else {\n";
- pr " printf (\"unset\\n\");\n";
+ pr " fprintf (fp, \"unset\\n\");\n";
pr " }\n";
) optargs;
pr " /* Java changes stdout line buffering so we need this: */\n";
- pr " fflush (stdout);\n";
+ pr " fflush (fp);\n";
pr " return 0;\n";
pr "}\n";
pr "\n" in
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 37526063..dc6f01a2 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -245,6 +245,9 @@ struct guestfs_h
struct timeval launch_t; /* The time that we called guestfs_launch. */
+ /* Used by bindtests. */
+ FILE *test_fp;
+
/*** Protocol. ***/
int fd[2]; /* Stdin/stdout of qemu. */
int sock; /* Daemon communications socket. */
diff --git a/src/guestfs.c b/src/guestfs.c
index b5874a88..c5062575 100644
--- a/src/guestfs.c
+++ b/src/guestfs.c
@@ -270,6 +270,10 @@ guestfs_close (guestfs_h *g)
/* Remove whole temporary directory. */
guestfs___remove_tmpdir (g->tmpdir);
+ /* Test output file used by bindtests. */
+ if (g->test_fp != NULL)
+ fclose (g->test_fp);
+
/* Mark the handle as dead and then free up all memory. */
g->state = NO_HANDLE;