+ (* Functions which have optional arguments have two generated variants. *)
+ List.iter (
+ function
+ | shortname, (ret, args, (_::_ as optargs) as style), _, _, _, _, _ ->
+ let uc_shortname = String.uppercase shortname in
+
+ (* Get the name of the last regular argument. *)
+ let last_arg =
+ match args with
+ | [] -> "g"
+ | args -> name_of_argt (List.hd (List.rev args)) in
+
+ let rerrcode, rtype =
+ match ret with
+ | RErr | RInt _ | RBool _ -> "-1", "int "
+ | RInt64 _ -> "-1", "int64_t "
+ | RConstString _ | RConstOptString _ -> "NULL", "const char *"
+ | RString _ | RBufferOut _ -> "NULL", "char *"
+ | RStringList _ | RHashtable _ -> "NULL", "char **"
+ | RStruct (_, typ) -> "NULL", sprintf "struct guestfs_%s *" typ
+ | RStructList (_, typ) ->
+ "NULL", sprintf "struct guestfs_%s_list *" typ in
+
+ (* The regular variable args function, just calls the _va variant. *)
+ generate_prototype ~extern:false ~semicolon:false ~newline:true
+ ~handle:"g" ~prefix:"guestfs_" shortname style;
+ pr "{\n";
+ pr " va_list optargs;\n";
+ pr "\n";
+ pr " va_start (optargs, %s);\n" last_arg;
+ pr " %sr = guestfs_%s_va " rtype shortname;
+ generate_c_call_args ~handle:"g" style;
+ pr ";\n";
+ pr " va_end (optargs);\n";
+ pr "\n";
+ pr " return r;\n";
+ pr "}\n\n";
+
+ generate_prototype ~extern:false ~semicolon:false ~newline:true
+ ~handle:"g" ~prefix:"guestfs_" ~suffix:"_va" ~optarg_proto:VA
+ shortname style;
+ pr "{\n";
+ pr " struct guestfs_%s_argv optargs_s;\n" shortname;
+ pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" shortname;
+ pr " int i;\n";
+ pr "\n";
+ pr " optargs_s.bitmask = 0;\n";
+ pr "\n";
+ pr " while ((i = va_arg (args, int)) >= 0) {\n";
+ pr " switch (i) {\n";
+
+ List.iter (
+ fun argt ->
+ let n = name_of_argt argt in
+ let uc_n = String.uppercase n in
+ pr " case GUESTFS_%s_%s:\n" uc_shortname uc_n;
+ pr " optargs_s.%s = va_arg (args, " n;
+ (match argt with
+ | Bool _ | Int _ -> pr "int"
+ | Int64 _ -> pr "int64_t"
+ | String _ -> pr "const char *"
+ | _ -> assert false
+ );
+ pr ");\n";
+ pr " break;\n";
+ ) optargs;
+
+ pr " default:\n";
+ pr " error (g, \"%%s: unknown option %%d (this can happen if a program is compiled against a newer version of libguestfs, then dynamically linked to an older version)\",\n";
+ pr " \"%s\", i);\n" shortname;
+ pr " return %s;\n" rerrcode;
+ pr " }\n";
+ pr "\n";
+ pr " uint64_t i_mask = UINT64_C(1) << i;\n";
+ pr " if (optargs_s.bitmask & i_mask) {\n";
+ pr " error (g, \"%%s: same optional argument specified more than once\",\n";
+ pr " \"%s\");\n" shortname;
+ pr " return %s;\n" rerrcode;
+ pr " }\n";
+ pr " optargs_s.bitmask |= i_mask;\n";
+ pr " }\n";
+ pr "\n";
+ pr " return guestfs_%s_argv " shortname;
+ generate_c_call_args ~handle:"g" style;
+ pr ";\n";
+ pr "}\n\n"
+ | _ -> ()
+ ) all_functions_sorted
+