";
List.iter (
- fun (shortname, style, _, _, _, _, _) ->
+ fun (shortname, _, _, _, _, _, _) ->
pr "PHP_FUNCTION (guestfs_%s);\n" shortname
) all_functions_sorted;
";
List.iter (
- fun (shortname, style, _, _, _, _, _) ->
+ fun (shortname, _, _, _, _, _, _) ->
pr " PHP_FE (guestfs_%s, NULL)\n" shortname
) all_functions_sorted;
(* Now generate the PHP bindings for each action. *)
List.iter (
- fun (shortname, style, _, _, _, _, _) ->
+ fun (shortname, (ret, args, optargs as style), _, _, _, _, _) ->
pr "PHP_FUNCTION (guestfs_%s)\n" shortname;
pr "{\n";
pr " zval *z_g;\n";
pr " char **%s;\n" n;
| Bool n ->
pr " zend_bool %s;\n" n
- | Int n | Int64 n ->
+ | Int n | Int64 n | Pointer (_, n) ->
pr " long %s;\n" n
- ) (snd style);
+ ) args;
+
+ if optargs <> [] then (
+ pr " struct guestfs_%s_argv optargs_s = { .bitmask = 0 };\n" shortname;
+ pr " struct guestfs_%s_argv *optargs = &optargs_s;\n" shortname;
+
+ (* XXX Ugh PHP doesn't have proper optional arguments, so we
+ * have to use sentinel values.
+ *)
+ (* Since we don't know if PHP types will exactly match structure
+ * types, declare some local variables here.
+ *)
+ List.iter (
+ function
+ | Bool n -> pr " zend_bool optargs_t_%s = -1;\n" n
+ | Int n | Int64 n -> pr " long optargs_t_%s = -1;\n" n
+ | String n ->
+ pr " char *optargs_t_%s = NULL;\n" n;
+ pr " int optargs_t_%s_size = -1;\n" n
+ | _ -> assert false
+ ) optargs
+ );
pr "\n";
| OptString n -> "s!"
| StringList n | DeviceList n -> "a"
| Bool n -> "b"
- | Int n | Int64 n -> "l"
- ) (snd style)
+ | Int n | Int64 n | Pointer (_, n) -> "l"
+ ) args
) in
+ let param_string =
+ if optargs <> [] then
+ param_string ^ "|" ^
+ String.concat "" (
+ List.map (
+ function
+ | Bool _ -> "b"
+ | Int _ | Int64 _ -> "l"
+ | String _ -> "s"
+ | _ -> assert false
+ ) optargs
+ )
+ else param_string in
+
pr " if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, \"r%s\",\n"
param_string;
pr " &z_g";
pr ", &z_%s" n
| Bool n ->
pr ", &%s" n
- | Int n | Int64 n ->
+ | Int n | Int64 n | Pointer (_, n) ->
pr ", &%s" n
- ) (snd style);
+ ) args;
+ List.iter (
+ function
+ | Bool n | Int n | Int64 n ->
+ pr ", &optargs_t_%s" n
+ | String n ->
+ pr ", &optargs_t_%s, &optargs_t_%s_size" n n
+ | _ -> assert false
+ ) optargs;
pr ") == FAILURE) {\n";
pr " RETURN_FALSE;\n";
pr " }\n";
pr " %s[c] = NULL;\n" n;
pr " }\n";
pr "\n"
- | Bool n | Int n | Int64 n -> ()
- ) (snd style);
+ | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
+ ) args;
+
+ (* Optional arguments. *)
+ if optargs <> [] then (
+ let uc_shortname = String.uppercase shortname in
+ List.iter (
+ fun argt ->
+ let n = name_of_argt argt in
+ let uc_n = String.uppercase n in
+ pr " if (optargs_t_%s != " n;
+ (match argt with
+ | Bool _ -> pr "((zend_bool)-1)"
+ | Int _ | Int64 _ -> pr "-1"
+ | String _ -> pr "NULL"
+ | _ -> assert false
+ );
+ pr ") {\n";
+ pr " optargs_s.%s = optargs_t_%s;\n" n n;
+ pr " optargs_s.bitmask |= GUESTFS_%s_%s_BITMASK;\n"
+ uc_shortname uc_n;
+ pr " }\n"
+ ) optargs;
+ pr "\n"
+ );
(* Return value. *)
- let error_code =
- match fst style with
- | RErr -> pr " int r;\n"; "-1"
- | RBool _
- | RInt _ -> pr " int r;\n"; "-1"
- | RInt64 _ -> pr " int64_t r;\n"; "-1"
- | RConstString _ -> pr " const char *r;\n"; "NULL"
- | RConstOptString _ -> pr " const char *r;\n"; "NULL"
- | RString _ ->
- pr " char *r;\n"; "NULL"
- | RStringList _ ->
- 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"
- | RHashtable _ ->
- pr " char **r;\n"; "NULL"
- | RBufferOut _ ->
- pr " char *r;\n";
- pr " size_t size;\n";
- "NULL" in
+ (match ret with
+ | RErr -> pr " int r;\n"
+ | RBool _
+ | RInt _ -> pr " int r;\n"
+ | RInt64 _ -> pr " int64_t r;\n"
+ | RConstString _ -> pr " const char *r;\n"
+ | RConstOptString _ -> pr " const char *r;\n"
+ | RString _ ->
+ pr " char *r;\n"
+ | RStringList _ ->
+ pr " char **r;\n"
+ | RStruct (_, typ) ->
+ pr " struct guestfs_%s *r;\n" typ
+ | RStructList (_, typ) ->
+ pr " struct guestfs_%s_list *r;\n" typ
+ | RHashtable _ ->
+ pr " char **r;\n"
+ | RBufferOut _ ->
+ pr " char *r;\n";
+ pr " size_t size;\n"
+ );
(* Call the function. *)
- pr " r = guestfs_%s " shortname;
+ if optargs = [] then
+ pr " r = guestfs_%s " shortname
+ else
+ pr " r = guestfs_%s_argv " shortname;
generate_c_call_args ~handle:"g" style;
pr ";\n";
pr "\n";
pr " efree (%s);\n" n;
pr " }\n";
pr "\n"
- | Bool n | Int n | Int64 n -> ()
- ) (snd style);
+ | Bool _ | Int _ | Int64 _ | Pointer _ -> ()
+ ) args;
(* Check for errors. *)
- pr " if (r == %s) {\n" error_code;
- pr " RETURN_FALSE;\n";
- pr " }\n";
+ (match errcode_of_ret ret with
+ | `CannotReturnError -> ()
+ | `ErrorIsMinusOne ->
+ pr " if (r == -1) {\n";
+ pr " RETURN_FALSE;\n";
+ pr " }\n"
+ | `ErrorIsNULL ->
+ pr " if (r == NULL) {\n";
+ pr " RETURN_FALSE;\n";
+ pr " }\n"
+ );
pr "\n";
(* Convert the return value. *)
- (match fst style with
+ (match ret with
| RErr ->
pr " RETURN_TRUE;\n"
| RBool _ ->