- let error_code =
- match fst style with
- | RErr | RInt _ | RBool _ -> pr " int r;\n"; "-1"
- | RInt64 _ -> pr " int64_t r;\n"; "-1"
- | RConstString _ | RConstOptString _ ->
- pr " const char *r;\n"; "NULL"
- | RString _ -> pr " char *r;\n"; "NULL"
- | RStringList _ | RHashtable _ -> pr " char **r;\n"; "NULL"
- | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ; "NULL"
- | RStructList (_, typ) ->
- pr " struct guestfs_%s_list *r;\n" typ; "NULL"
- | RBufferOut _ ->
- pr " char *r;\n";
- pr " size_t size;\n";
- "NULL" in
+ (* Optional arguments are passed in a final hash parameter. *)
+ if optargs <> [] then (
+ let uc_name = String.uppercase name in
+ pr " Check_Type (optargsv, T_HASH);\n";
+ pr " struct guestfs_%s_argv optargs_s = { .bitmask = 0 };\n" name;
+ pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" name;
+ pr " VALUE v;\n";
+ List.iter (
+ fun argt ->
+ let n = name_of_argt argt in
+ let uc_n = String.uppercase n in
+ pr " v = rb_hash_lookup (optargsv, ID2SYM (rb_intern (\"%s\")));\n" n;
+ pr " if (v != Qnil) {\n";
+ (match argt with
+ | Bool n ->
+ pr " optargs_s.%s = RTEST (v);\n" n;
+ | Int n ->
+ pr " optargs_s.%s = NUM2INT (v);\n" n;
+ | Int64 n ->
+ pr " optargs_s.%s = NUM2LL (v);\n" n;
+ | String _ ->
+ pr " Check_Type (v, T_STRING);\n";
+ pr " optargs_s.%s = StringValueCStr (v);\n" n
+ | _ -> assert false
+ );
+ pr " optargs_s.bitmask |= GUESTFS_%s_%s_BITMASK;\n" uc_name uc_n;
+ pr " }\n";
+ ) optargs;
+ pr "\n";
+ );
+
+ (match ret with
+ | RErr | RInt _ | RBool _ -> pr " int r;\n"
+ | RInt64 _ -> pr " int64_t r;\n"
+ | RConstString _ | RConstOptString _ ->
+ pr " const char *r;\n"
+ | RString _ -> pr " char *r;\n"
+ | RStringList _ | RHashtable _ -> pr " char **r;\n"
+ | RStruct (_, typ) -> pr " struct guestfs_%s *r;\n" typ
+ | RStructList (_, typ) ->
+ pr " struct guestfs_%s_list *r;\n" typ
+ | RBufferOut _ ->
+ pr " char *r;\n";
+ pr " size_t size;\n"
+ );