X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=generator%2Fgenerator_c.ml;h=28cecdba47367183b8619ceeff6a0f94735c7630;hp=dad3ac308c4e60e39161c9047a35af74c21894f7;hb=6283982e36eeb3d19940618dc0aec88da08c7516;hpb=9332031543563fd2ae6e0e8731fc770f5a5931db diff --git a/generator/generator_c.ml b/generator/generator_c.ml index dad3ac3..28cecdb 100644 --- a/generator/generator_c.ml +++ b/generator/generator_c.ml @@ -24,6 +24,7 @@ open Generator_types open Generator_utils open Generator_pr open Generator_docstrings +open Generator_api_versions open Generator_optgroups open Generator_actions open Generator_structs @@ -35,27 +36,41 @@ type optarg_proto = Dots | VA | Argv (* 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; @@ -69,7 +84,12 @@ let rec generate_prototype ?(extern = true) ?(static = false) ); 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 @@ -152,8 +172,7 @@ and generate_actions_pod () = 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 @@ -236,20 +255,20 @@ L for more information.\n\n"; | None -> () | Some txt -> pr "%s\n\n" txt ); + let version = lookup_api_version name in + pr "(Added in %s)\n\n" version; (* 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.\n\n" name; pr "See L.\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"; @@ -438,6 +457,7 @@ and generate_client_actions () = #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 @@ -590,10 +610,12 @@ check_state (guestfs_h *g, const char *caller) | 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" @@ -802,8 +824,18 @@ check_state (guestfs_h *g, const char *caller) 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"; pr " return %s;\n" error_code; pr " }\n"; @@ -994,6 +1026,7 @@ and generate_linker_script () = "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";