src: generate code for printing contents of structs

Extend the generator to generate a source (and the header for it) with
functions that print the content of a guestfs struct.  The code is
modelled after the code for it in fish.ml, although made a bit more
generic (destination FILE*, line separator) so it can be used also in
the library, when tracing.

This just introduces the new code and builds it as part of the helper
libutils.la.
This commit is contained in:
Pino Toscano
2016-02-24 12:29:27 +01:00
parent c0c91f96d7
commit 2c0d16e82e
6 changed files with 136 additions and 1 deletions

2
.gitignore vendored
View File

@@ -468,6 +468,8 @@ Makefile.in
/src/structs-compare.c
/src/structs-copy.c
/src/structs-free.c
/src/structs-print.c
/src/structs-print.h
/src/test-utils
/stamp-h1
/sysprep/.depend

View File

@@ -1204,6 +1204,130 @@ and generate_client_structs_cleanup () =
) structs
(* Generate structs-print.c file. *)
and generate_client_structs_print_c () =
generate_header CStyle LGPLv2plus;
pr "\
#include <config.h>
#include <inttypes.h>
#include \"c-ctype.h\"
#include \"guestfs.h\"
#include \"structs-print.h\"
";
let write_structs =
List.iter (
fun { s_name = typ; s_cols = cols } ->
let needs_i =
List.exists (function (_, (FUUID|FBuffer)) -> true | _ -> false) cols in
pr "void\n";
pr "guestfs_int_print_%s_indent (struct guestfs_%s *%s, FILE *dest, const char *linesep, const char *indent)\n"
typ typ typ;
pr "{\n";
if needs_i then (
pr " size_t i;\n";
pr "\n"
);
List.iter (
function
| name, FString ->
pr " fprintf (dest, \"%%s%s: %%s%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FUUID ->
pr " fprintf (dest, \"%%s%s: \", indent);\n" name;
pr " for (i = 0; i < 32; ++i)\n";
pr " fprintf (dest, \"%%c\", %s->%s[i]);\n" typ name;
pr " fprintf (dest, \"%%s\", linesep);\n"
| name, FBuffer ->
pr " fprintf (dest, \"%%s%s: \", indent);\n" name;
pr " for (i = 0; i < %s->%s_len; ++i)\n" typ name;
pr " if (c_isprint (%s->%s[i]))\n" typ name;
pr " fprintf (dest, \"%%c\", %s->%s[i]);\n" typ name;
pr " else\n";
pr " fprintf (dest, \"\\\\x%%02x\", (unsigned) %s->%s[i]);\n"
typ name;
pr " fprintf (dest, \"%%s\", linesep);\n"
| name, (FUInt64|FBytes) ->
pr " fprintf (dest, \"%%s%s: %%\" PRIu64 \"%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FInt64 ->
pr " fprintf (dest, \"%%s%s: %%\" PRIi64 \"%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FUInt32 ->
pr " fprintf (dest, \"%%s%s: %%\" PRIu32 \"%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FInt32 ->
pr " fprintf (dest, \"%%s%s: %%\" PRIi32 \"%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FChar ->
pr " fprintf (dest, \"%%s%s: %%c%%s\", indent, %s->%s, linesep);\n"
name typ name
| name, FOptPercent ->
pr " if (%s->%s >= 0)\n" typ name;
pr " fprintf (dest, \"%%s%s: %%g %%%%%%s\", indent, (double) %s->%s, linesep);\n"
name typ name;
pr " else\n";
pr " fprintf (dest, \"%%s%s: %%s\", indent, linesep);\n" name
) cols;
pr "}\n";
pr "\n";
) in
write_structs external_structs;
pr "\
#if GUESTFS_PRIVATE
";
write_structs internal_structs;
pr "\
#endif /* End of GUESTFS_PRIVATE. */
"
(* Generate structs-print.h file. *)
and generate_client_structs_print_h () =
generate_header CStyle LGPLv2plus;
pr "\
#ifndef GUESTFS_INTERNAL_STRUCTS_PRINT_H_
#define GUESTFS_INTERNAL_STRUCTS_PRINT_H_
#include <stdio.h>
";
let write_structs =
List.iter (
fun { s_name = name } ->
pr "extern void guestfs_int_print_%s_indent (struct guestfs_%s *%s, FILE *dest, const char *linesep, const char *indent);\n"
name name name
) in
write_structs external_structs;
pr "\
#if GUESTFS_PRIVATE
";
write_structs internal_structs;
pr "\
#endif /* End of GUESTFS_PRIVATE. */
#endif /* GUESTFS_INTERNAL_STRUCTS_PRINT_H_ */
"
(* Generate the client-side dispatch stubs. *)
and generate_client_actions hash () =
generate_header CStyle LGPLv2plus;

View File

@@ -32,6 +32,8 @@ val generate_client_structs_cleanup : unit -> unit
val generate_client_structs_compare : unit -> unit
val generate_client_structs_copy : unit -> unit
val generate_client_structs_free : unit -> unit
val generate_client_structs_print_h : unit -> unit
val generate_client_structs_print_c : unit -> unit
val generate_event_string_c : unit -> unit
val generate_guestfs_h : unit -> unit
val generate_internal_actions_h : unit -> unit

View File

@@ -99,6 +99,8 @@ Run it from the top source directory using the command
output_to "src/structs-copy.c" generate_client_structs_copy;
output_to "src/structs-free.c" generate_client_structs_free;
output_to "src/structs-cleanup.c" generate_client_structs_cleanup;
output_to "src/structs-print.c" generate_client_structs_print_c;
output_to "src/structs-print.h" generate_client_structs_print_h;
output_to "src/actions-variants.c" generate_client_actions_variants;
for i = 0 to nr_actions_files-1 do

View File

@@ -353,6 +353,7 @@ src/structs-cleanup.c
src/structs-compare.c
src/structs-copy.c
src/structs-free.c
src/structs-print.c
src/test-utils.c
src/tmpdirs.c
src/utils.c

View File

@@ -46,7 +46,9 @@ generator_built = \
structs-cleanup.c \
structs-compare.c \
structs-copy.c \
structs-free.c
structs-free.c \
structs-print.c \
structs-print.h
BUILT_SOURCES = \
$(generator_built) \
@@ -226,6 +228,8 @@ endif
libutils_la_SOURCES = \
cleanup.c \
structs-cleanup.c \
structs-print.c \
structs-print.h \
utils.c
libutils_la_CPPFLAGS = $(libguestfs_la_CPPFLAGS)
libutils_la_CFLAGS = $(libguestfs_la_CFLAGS)