+ let trace_return ?(indent = 2) shortname (ret, _, _) rv =
+ let indent = spaces indent in
+
+ pr "%sif (trace_flag) {\n" indent;
+
+ let needs_i =
+ match ret with
+ | RStringList _ | RHashtable _ -> true
+ | _ -> false in
+ if needs_i then (
+ pr "%s size_t i;\n" indent;
+ pr "\n"
+ );
+
+ pr "%s trace_fp = trace_open (g);\n" indent;
+
+ pr "%s fprintf (trace_fp, \"%%s = \", \"%s\");\n" indent shortname;
+
+ (match ret with
+ | RErr | RInt _ | RBool _ ->
+ pr "%s fprintf (trace_fp, \"%%d\", %s);\n" indent rv
+ | RInt64 _ ->
+ pr "%s fprintf (trace_fp, \"%%\" PRIi64, %s);\n" indent rv
+ | RConstString _ | RString _ ->
+ pr "%s fprintf (trace_fp, \"\\\"%%s\\\"\", %s);\n" indent rv
+ | RConstOptString _ ->
+ pr "%s fprintf (trace_fp, \"\\\"%%s\\\"\", %s != NULL ? %s : \"NULL\");\n"
+ indent rv rv
+ | RBufferOut _ ->
+ pr "%s guestfs___print_BufferOut (trace_fp, %s, *size_r);\n" indent rv
+ | RStringList _ | RHashtable _ ->
+ pr "%s fputs (\"[\", trace_fp);\n" indent;
+ pr "%s for (i = 0; %s[i]; ++i) {\n" indent rv;
+ pr "%s if (i > 0) fputs (\", \", trace_fp);\n" indent;
+ pr "%s fputs (\"\\\"\", trace_fp);\n" indent;
+ pr "%s fputs (%s[i], trace_fp);\n" indent rv;
+ pr "%s fputs (\"\\\"\", trace_fp);\n" indent;
+ pr "%s }\n" indent;
+ pr "%s fputs (\"]\", trace_fp);\n" indent;
+ | RStruct (_, typ) ->
+ (* XXX There is code generated for guestfish for printing
+ * these structures. We need to make it generally available
+ * for all callers
+ *)
+ pr "%s fprintf (trace_fp, \"<struct guestfs_%s *>\");\n"
+ indent typ (* XXX *)
+ | RStructList (_, typ) ->
+ pr "%s fprintf (trace_fp, \"<struct guestfs_%s_list *>\");\n"
+ indent typ (* XXX *)
+ );
+ pr "%s trace_send_line (g);\n" indent;
+ pr "%s}\n" indent;
+ pr "\n";
+ in
+
+ let trace_return_error ?(indent = 2) shortname (ret, _, _) errcode =
+ let indent = spaces indent in
+
+ pr "%sif (trace_flag)\n" indent;
+
+ pr "%s guestfs___trace (g, \"%%s = %%s (error)\",\n" indent;
+ pr "%s \"%s\", \"%s\");\n"
+ indent shortname (string_of_errcode errcode)
+ in
+