perror (\"md5sum: fread\");
exit (EXIT_FAILURE);
}
- if (pclose (pp) == -1) {
+ if (pclose (pp) != 0) {
perror (\"pclose\");
exit (EXIT_FAILURE);
}
result[32] = '\\0';
}
+/* Return the value for a key in a hashtable.
+ * Note: the return value is part of the hash and should not be freed.
+ */
+static const char *
+get_key (char **hash, const char *key)
+{
+ size_t i;
+
+ for (i = 0; hash[i] != NULL; i += 2) {
+ if (STREQ (hash[i], key))
+ return hash[i+1];
+ }
+
+ return NULL; /* key not found */
+}
+
";
(* Generate a list of commands which are not tested anywhere. *)
in
List.iter (generate_test_command_call test_name) seq;
generate_test_command_call ~test test_name last
+ | TestOutputHashtable (seq, fields) ->
+ pr " /* TestOutputHashtable for %s (%d) */\n" name i;
+ pr " const char *key, *expected, *value;\n";
+ let seq, last = get_seq_last seq in
+ let test () =
+ List.iter (
+ fun (key, value) ->
+ pr " key = \"%s\";\n" (c_quote key);
+ pr " expected = \"%s\";\n" (c_quote value);
+ pr " value = get_key (r, key);\n";
+ pr " if (value == NULL) {\n";
+ pr " fprintf (stderr, \"%s: key \\\"%%s\\\" not found in hash: expecting \\\"%%s\\\"\\n\", key, expected);\n" test_name;
+ pr " return -1;\n";
+ pr " }\n";
+ pr " if (STRNEQ (value, expected)) {\n";
+ pr " fprintf (stderr, \"%s: key \\\"%%s\\\": expected \\\"%%s\\\" but got \\\"%%s\\\"\\n\", key, expected, value);\n" test_name;
+ pr " return -1;\n";
+ pr " }\n";
+ ) fields
+ in
+ List.iter (generate_test_command_call test_name) seq;
+ generate_test_command_call ~test test_name last
| TestLastFail seq ->
pr " /* TestLastFail for %s (%d) */\n" name i;
let seq, last = get_seq_last seq in
assert false
) args;
- (* Currently can only deal with a complete, in-order list of optargs. *)
if optargs <> [] then (
pr " struct guestfs_%s_argv optargs;\n" name;
- let len = List.length style_optargs in
- let bitmask = Int64.pred (Int64.shift_left 1L len) in
+ let _, bitmask = List.fold_left (
+ fun (shift, bitmask) optarg ->
+ let is_set =
+ match optarg with
+ | Bool n, "" -> false
+ | Bool n, "true" ->
+ pr " optargs.%s = 1;\n" n; true
+ | Bool n, "false" ->
+ pr " optargs.%s = 0;\n" n; true
+ | Bool n, arg ->
+ failwithf "boolean optional arg '%s' should be empty string or \"true\" or \"false\"" n
+ | Int n, "" -> false
+ | Int n, i ->
+ let i =
+ try int_of_string i
+ with Failure _ -> failwithf "integer optional arg '%s' should be empty string or number" n in
+ pr " optargs.%s = %d;\n" n i; true
+ | Int64 n, "" -> false
+ | Int64 n, i ->
+ let i =
+ try Int64.of_string i
+ with Failure _ -> failwithf "int64 optional arg '%s' should be empty string or number" n in
+ pr " optargs.%s = %Ld;\n" n i; true
+ | String n, "NOARG" -> false
+ | String n, arg ->
+ pr " optargs.%s = \"%s\";\n" n (c_quote arg); true
+ | _ -> assert false in
+ let bit = if is_set then Int64.shift_left 1L shift else 0L in
+ let bitmask = Int64.logor bitmask bit in
+ let shift = shift + 1 in
+ (shift, bitmask)
+ ) (0, 0L) optargs in
pr " optargs.bitmask = UINT64_C(0x%Lx);\n" bitmask;
- List.iter (
- function
- | Bool n, arg
- | Int n, arg
- | Int64 n, arg ->
- pr " optargs.%s = %s;\n" n arg
- | String n, arg ->
- pr " optargs.%s = \"%s\";\n" n (c_quote arg);
- | _ -> assert false
- ) optargs;
);
- let error_code =
- match style_ret 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";
- pr " size_t i;\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
+ (match style_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";
+ pr " size_t i;\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"
+ );
pr " suppress_error = %d;\n" (if expect_error then 1 else 0);
if optargs = [] then
pr ");\n";
- if not expect_error then
- pr " if (r == %s)\n" error_code
- else
- pr " if (r != %s)\n" error_code;
- pr " return -1;\n";
+ (match errcode_of_ret style_ret, expect_error with
+ | `CannotReturnError, _ -> ()
+ | `ErrorIsMinusOne, false ->
+ pr " if (r == -1)\n";
+ pr " return -1;\n";
+ | `ErrorIsMinusOne, true ->
+ pr " if (r != -1)\n";
+ pr " return -1;\n";
+ | `ErrorIsNULL, false ->
+ pr " if (r == NULL)\n";
+ pr " return -1;\n";
+ | `ErrorIsNULL, true ->
+ pr " if (r != NULL)\n";
+ pr " return -1;\n";
+ );
(* Insert the test code. *)
(match test with