open Generator_utils
open Generator_pr
open Generator_docstrings
+open Generator_api_versions
open Generator_optgroups
open Generator_actions
open Generator_structs
(* Generate a C function prototype. *)
let rec generate_prototype ?(extern = true) ?(static = false)
?(semicolon = true)
- ?(single_line = false) ?(newline = false) ?(in_daemon = false)
+ ?(single_line = false) ?(indent = "") ?(newline = false)
+ ?(in_daemon = false)
?(prefix = "") ?(suffix = "")
?handle
?(optarg_proto = Dots)
name (ret, args, optargs) =
+ pr "%s" indent;
if extern then pr "extern ";
if static then pr "static ";
(match ret with
- | RErr -> pr "int "
- | RInt _ -> pr "int "
- | RInt64 _ -> pr "int64_t "
- | RBool _ -> pr "int "
- | RConstString _ | RConstOptString _ -> pr "const char *"
- | RString _ | RBufferOut _ -> pr "char *"
- | RStringList _ | RHashtable _ -> pr "char **"
+ | RErr
+ | RInt _
+ | RBool _ ->
+ pr "int";
+ if single_line then pr " " else pr "\n%s" indent
+ | RInt64 _ ->
+ pr "int64_t";
+ if single_line then pr " " else pr "\n%s" indent
+ | RConstString _ | RConstOptString _ ->
+ pr "const char *";
+ if not single_line then pr "\n%s" indent
+ | RString _ | RBufferOut _ ->
+ pr "char *";
+ if not single_line then pr "\n%s" indent
+ | RStringList _ | RHashtable _ ->
+ pr "char **";
+ if not single_line then pr "\n%s" indent
| RStruct (_, typ) ->
if not in_daemon then pr "struct guestfs_%s *" typ
- else pr "guestfs_int_%s *" typ
+ else pr "guestfs_int_%s *" typ;
+ if not single_line then pr "\n%s" indent
| RStructList (_, typ) ->
if not in_daemon then pr "struct guestfs_%s_list *" typ
- else pr "guestfs_int_%s_list *" typ
+ else pr "guestfs_int_%s_list *" typ;
+ if not single_line then pr "\n%s" indent
);
let is_RBufferOut = match ret with RBufferOut _ -> true | _ -> false in
pr "%s%s%s (" prefix name suffix;
);
let next () =
if !comma then (
- if single_line then pr ", " else pr ",\n\t\t"
+ if single_line then pr ", "
+ else (
+ let namelen = String.length prefix + String.length name +
+ String.length suffix + 2 in
+ pr ",\n%s%s" indent (spaces namelen)
+ )
);
comma := true
in
if not (List.mem NotInDocs flags) then (
let name = "guestfs_" ^ shortname in
pr "=head2 %s\n\n" name;
- pr " ";
- generate_prototype ~extern:false ~handle:"g" name style;
+ generate_prototype ~extern:false ~indent:" " ~handle:"g" name style;
pr "\n\n";
let uc_shortname = String.uppercase shortname in
| None -> ()
| Some txt -> pr "%s\n\n" txt
);
+ (match lookup_api_version name with
+ | Some version -> pr "(Added in %s)\n\n" version
+ | None -> ()
+ );
(* Handling of optional argument variants. *)
if optargs <> [] then (
pr "=head2 %s_va\n\n" name;
- pr " ";
- generate_prototype ~extern:false ~handle:"g"
+ generate_prototype ~extern:false ~indent:" " ~handle:"g"
~prefix:"guestfs_" ~suffix:"_va" ~optarg_proto:VA
shortname style;
pr "\n\n";
pr "This is the \"va_list variant\" of L</%s>.\n\n" name;
pr "See L</CALLS WITH OPTIONAL ARGUMENTS>.\n\n";
pr "=head2 %s_argv\n\n" name;
- pr " ";
- generate_prototype ~extern:false ~handle:"g"
+ generate_prototype ~extern:false ~indent:" " ~handle:"g"
~prefix:"guestfs_" ~suffix:"_argv" ~optarg_proto:Argv
shortname style;
pr "\n\n";
#include \"guestfs-internal.h\"
#include \"guestfs-internal-actions.h\"
#include \"guestfs_protocol.h\"
+#include \"errnostring.h\"
/* Check the return message from a call for validity. */
static int
| Pathname n
| Dev_or_Path n
| FileIn n
- | FileOut n
- | Key n ->
+ | FileOut n ->
(* guestfish doesn't support string escaping, so neither do we *)
pr " fprintf (stderr, \" \\\"%%s\\\"\", %s);\n" n
+ | Key n ->
+ (* don't print keys *)
+ pr " fprintf (stderr, \" \\\"***\\\"\");\n"
| OptString n -> (* string option *)
pr " if (%s) fprintf (stderr, \" \\\"%%s\\\"\", %s);\n" n n;
pr " else fprintf (stderr, \" null\");\n"
pr "\n";
pr " if (hdr.status == GUESTFS_STATUS_ERROR) {\n";
- pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n" shortname;
+ pr " int errnum = 0;\n";
+ pr " if (err.errno_string[0] != '\\0')\n";
+ pr " errnum = guestfs___string_to_errno (err.errno_string);\n";
+ pr " if (errnum <= 0)\n";
+ pr " error (g, \"%%s: %%s\", \"%s\", err.error_message);\n"
+ shortname;
+ pr " else\n";
+ pr " guestfs_error_errno (g, errnum, \"%%s: %%s\", \"%s\",\n"
+ shortname;
+ pr " err.error_message);\n";
pr " free (err.error_message);\n";
pr " free (err.errno_string);\n";
pr " guestfs___end_busy (g);\n";
"guestfs_get_error_handler";
"guestfs_get_out_of_memory_handler";
"guestfs_get_private";
+ "guestfs_last_errno";
"guestfs_last_error";
"guestfs_set_close_callback";
"guestfs_set_error_handler";