diff options
-rw-r--r-- | generator/generator_actions.ml | 32 | ||||
-rw-r--r-- | generator/generator_bindtests.ml | 94 | ||||
-rw-r--r-- | src/guestfs-internal.h | 3 | ||||
-rw-r--r-- | src/guestfs.c | 4 |
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; |