[Libguestfs] [PATCH] RFC: php: support PHP 7

Richard W.M. Jones rjones at redhat.com
Mon Apr 11 16:55:02 UTC 2016


On Mon, Apr 11, 2016 at 05:16:20PM +0200, Pino Toscano wrote:
> Adapt to the API changes in the newer versions of the Zend framework, in
> particular regarding:
> - strings handling
> - resources handling (used for the guestfs_h pointer)
> - iterating in hash maps
> - data types for function arguments
> 
> Introduce helper macros to reduce greatly the amount of #if's all around
> the generated C code.
> ---
>  generator/php.ml | 96 +++++++++++++++++++++++++++++++++++++++++++-------------
>  1 file changed, 74 insertions(+), 22 deletions(-)
> 
> diff --git a/generator/php.ml b/generator/php.ml
> index 926ac4f..5f06c0f 100644
> --- a/generator/php.ml
> +++ b/generator/php.ml
> @@ -93,6 +93,32 @@ and generate_php_c () =
>  
>  static int res_guestfs_h;
>  
> +#if ZEND_MODULE_API_NO >= 20151012
> +# define GUESTFS_RETURN_STRING(x, duplicate) \\
> +    do { if (duplicate) RETURN_STRING(x) else { RETVAL_STRING(x); efree ((char *)x); return; } } while (0)
> +# define guestfs_add_assoc_string(arg, key, str, dup) \\
> +    add_assoc_string(arg, key, str)
> +# define guestfs_add_assoc_stringl(arg, key, str, len, dup) \\
> +    add_assoc_stringl(arg, key, str, len)
> +# define guestfs_add_next_index_string(retval, val, x) \\
> +    add_next_index_string (retval, val)
> +# define GUESTFS_ZEND_FETCH_RESOURCE(rsrc, rsrc_type, passed_id, resource_type_name, resource_type) \\
> +    (rsrc) = (rsrc_type) zend_fetch_resource (Z_RES_P(passed_id), resource_type_name, resource_type)
> +typedef size_t guestfs_string_length;
> +#else
> +# define GUESTFS_RETURN_STRING(x, duplicate) \\
> +    RETURN_STRING(x, duplicate)
> +# define guestfs_add_assoc_string(arg, key, str, dup) \\
> +    add_assoc_string(arg, key, str, dup)
> +# define guestfs_add_assoc_stringl(arg, key, str, len, dup) \\
> +    add_assoc_stringl(arg, key, str, len, dup)
> +# define guestfs_add_next_index_string(retval, val, x) \\
> +    add_next_index_string (retval, val, x)
> +# define GUESTFS_ZEND_FETCH_RESOURCE(rsrc, rsrc_type, passed_id, resource_type_name, resource_type) \\
> +  ZEND_FETCH_RESOURCE(rsrc, rsrc_type, &(passed_id), -1, resource_type_name, resource_type)
> +typedef int guestfs_string_length;
> +#endif
> +
>  /* Convert array to list of strings.
>   * http://marc.info/?l=pecl-dev&m=112205192100631&w=2
>   */
> @@ -103,16 +129,28 @@ get_stringlist (zval *val)
>    HashTable *a;
>    int n;
>    HashPosition p;
> +#if ZEND_MODULE_API_NO >= 20151012
> +  zval *d;
> +#else
>    zval **d;
> +#endif
>    size_t c = 0;
>  
>    a = Z_ARRVAL_P (val);
>    n = zend_hash_num_elements (a);
>    ret = safe_emalloc (n + 1, sizeof (char *), 0);
>    for (zend_hash_internal_pointer_reset_ex (a, &p);
> +#if ZEND_MODULE_API_NO >= 20151012
> +       d = zend_hash_get_current_data_ex (a, &p);
> +#else
>         zend_hash_get_current_data_ex (a, (void **) &d, &p) == SUCCESS;
> +#endif
>         zend_hash_move_forward_ex (a, &p)) {
> +#if ZEND_MODULE_API_NO >= 20151012
> +    zval t = *d;
> +#else
>      zval t = **d;
> +#endif
>      zval_copy_ctor (&t);
>      convert_to_string (&t);
>      ret[c] = estrndup (Z_STRVAL(t), Z_STRLEN (t));
> @@ -133,8 +171,13 @@ guestfs_efree_stringlist (char **p)
>    efree (p);
>  }
>  
> +#if ZEND_MODULE_API_NO >= 20151012
> +static void
> +guestfs_php_handle_dtor (zend_resource *rsrc)
> +#else
>  static void
>  guestfs_php_handle_dtor (zend_rsrc_list_entry *rsrc TSRMLS_DC)
> +#endif
>  {
>    guestfs_h *g = (guestfs_h *) rsrc->ptr;
>    if (g != NULL)
> @@ -191,7 +234,11 @@ PHP_FUNCTION (guestfs_create)
>  
>    guestfs_set_error_handler (g, NULL, NULL);
>  
> +#if ZEND_MODULE_API_NO >= 20151012
> +  ZVAL_RES(return_value, zend_register_resource(g, res_guestfs_h));
> +#else
>    ZEND_REGISTER_RESOURCE (return_value, g, res_guestfs_h);
> +#endif
>  }
>  
>  PHP_FUNCTION (guestfs_last_error)
> @@ -204,15 +251,15 @@ PHP_FUNCTION (guestfs_last_error)
>      RETURN_FALSE;
>    }
>  
> -  ZEND_FETCH_RESOURCE (g, guestfs_h *, &z_g, -1, PHP_GUESTFS_HANDLE_RES_NAME,
> -                       res_guestfs_h);
> +  GUESTFS_ZEND_FETCH_RESOURCE (g, guestfs_h *, z_g,
> +                               PHP_GUESTFS_HANDLE_RES_NAME, res_guestfs_h);
>    if (g == NULL) {
>      RETURN_FALSE;
>    }
>  
>    const char *err = guestfs_last_error (g);
>    if (err) {
> -    RETURN_STRING (err, 1);
> +    GUESTFS_RETURN_STRING (err, 1);
>    } else {
>      RETURN_NULL ();
>    }
> @@ -237,10 +284,10 @@ PHP_FUNCTION (guestfs_last_error)
>          | BufferIn n
>          | GUID n ->
>              pr "  char *%s;\n" n;
> -            pr "  int %s_size;\n" n
> +            pr "  guestfs_string_length %s_size;\n" n
>          | OptString n ->
>              pr "  char *%s = NULL;\n" n;
> -            pr "  int %s_size;\n" n
> +            pr "  guestfs_string_length %s_size;\n" n
>          | StringList n
>          | DeviceList n
>          | FilenameList n ->
> @@ -270,7 +317,7 @@ PHP_FUNCTION (guestfs_last_error)
>            | OInt n | OInt64 n -> pr "  long optargs_t_%s = -1;\n" n
>            | OString n ->
>                pr "  char *optargs_t_%s = NULL;\n" n;
> -              pr "  int optargs_t_%s_size = -1;\n" n
> +              pr "  guestfs_string_length optargs_t_%s_size = -1;\n" n
>            | OStringList n ->
>                pr "  zval *optargs_t_%s = NULL;\n" n
>          ) optargs
> @@ -343,8 +390,8 @@ PHP_FUNCTION (guestfs_last_error)
>        pr "    RETURN_FALSE;\n";
>        pr "  }\n";
>        pr "\n";
> -      pr "  ZEND_FETCH_RESOURCE (g, guestfs_h *, &z_g, -1, PHP_GUESTFS_HANDLE_RES_NAME,\n";
> -      pr "                       res_guestfs_h);\n";
> +      pr "  GUESTFS_ZEND_FETCH_RESOURCE (g, guestfs_h *, z_g,\n";
> +      pr "                               PHP_GUESTFS_HANDLE_RES_NAME, res_guestfs_h);\n";
>        pr "  if (g == NULL) {\n";
>        pr "    RETURN_FALSE;\n";
>        pr "  }\n";
> @@ -499,23 +546,23 @@ PHP_FUNCTION (guestfs_last_error)
>         | RInt64 _ ->
>             pr "  RETURN_LONG (r);\n"
>         | RConstString _ ->
> -           pr "  RETURN_STRING (r, 1);\n"
> +           pr "  GUESTFS_RETURN_STRING (r, 1);\n"
>         | RConstOptString _ ->
> -           pr "  if (r) { RETURN_STRING (r, 1); }\n";
> +           pr "  if (r) { GUESTFS_RETURN_STRING (r, 1); }\n";
>             pr "  else { RETURN_NULL (); }\n"
>         | RString _ ->
>             pr "  char *r_copy = estrdup (r);\n";
>             pr "  free (r);\n";
> -           pr "  RETURN_STRING (r_copy, 0);\n"
> +           pr "  GUESTFS_RETURN_STRING (r_copy, 0);\n"
>         | RBufferOut _ ->
>             pr "  char *r_copy = estrndup (r, size);\n";
>             pr "  free (r);\n";
> -           pr "  RETURN_STRING (r_copy, 0);\n"
> +           pr "  GUESTFS_RETURN_STRING (r_copy, 0);\n"
>         | RStringList _ ->
>             pr "  size_t c = 0;\n";
>             pr "  array_init (return_value);\n";
>             pr "  for (c = 0; r[c] != NULL; ++c) {\n";
> -           pr "    add_next_index_string (return_value, r[c], 1);\n";
> +           pr "    guestfs_add_next_index_string (return_value, r[c], 1);\n";
>             pr "    free (r[c]);\n";
>             pr "  }\n";
>             pr "  free (r);\n";
> @@ -523,7 +570,7 @@ PHP_FUNCTION (guestfs_last_error)
>             pr "  size_t c = 0;\n";
>             pr "  array_init (return_value);\n";
>             pr "  for (c = 0; r[c] != NULL; c += 2) {\n";
> -           pr "    add_assoc_string (return_value, r[c], r[c+1], 1);\n";
> +           pr "    guestfs_add_assoc_string (return_value, r[c], r[c+1], 1);\n";
>             pr "    free (r[c]);\n";
>             pr "    free (r[c+1]);\n";
>             pr "  }\n";
> @@ -545,18 +592,18 @@ and generate_php_struct_code typ cols =
>    List.iter (
>      function
>      | name, FString ->
> -        pr "  add_assoc_string (return_value, \"%s\", r->%s, 1);\n" name name
> +        pr "  guestfs_add_assoc_string (return_value, \"%s\", r->%s, 1);\n" name name
>      | name, FBuffer ->
> -        pr "  add_assoc_stringl (return_value, \"%s\", r->%s, r->%s_len, 1);\n"
> +        pr "  guestfs_add_assoc_stringl (return_value, \"%s\", r->%s, r->%s_len, 1);\n"
>            name name name
>      | name, FUUID ->
> -        pr "  add_assoc_stringl (return_value, \"%s\", r->%s, 32, 1);\n"
> +        pr "  guestfs_add_assoc_stringl (return_value, \"%s\", r->%s, 32, 1);\n"
>            name name
>      | name, (FBytes|FUInt64|FInt64|FInt32|FUInt32) ->
>          pr "  add_assoc_long (return_value, \"%s\", r->%s);\n"
>            name name
>      | name, FChar ->
> -        pr "  add_assoc_stringl (return_value, \"%s\", &r->%s, 1, 1);\n"
> +        pr "  guestfs_add_assoc_stringl (return_value, \"%s\", &r->%s, 1, 1);\n"
>            name name
>      | name, FOptPercent ->
>          pr "  add_assoc_double (return_value, \"%s\", r->%s);\n"
> @@ -568,25 +615,30 @@ and generate_php_struct_list_code typ cols =
>    pr "  array_init (return_value);\n";
>    pr "  size_t c = 0;\n";
>    pr "  for (c = 0; c < r->len; ++c) {\n";
> +  pr "#if ZEND_MODULE_API_NO >= 20151012\n";
> +  pr "    zval elem;\n";
> +  pr "    zval *z_elem = &elem;\n";
> +  pr "#else\n";
>    pr "    zval *z_elem;\n";
>    pr "    ALLOC_INIT_ZVAL (z_elem);\n";
> +  pr "#endif\n";
>    pr "    array_init (z_elem);\n";
>    List.iter (
>      function
>      | name, FString ->
> -        pr "    add_assoc_string (z_elem, \"%s\", r->val[c].%s, 1);\n"
> +        pr "    guestfs_add_assoc_string (z_elem, \"%s\", r->val[c].%s, 1);\n"
>            name name
>      | name, FBuffer ->
> -        pr "    add_assoc_stringl (z_elem, \"%s\", r->val[c].%s, r->val[c].%s_len, 1);\n"
> +        pr "    guestfs_add_assoc_stringl (z_elem, \"%s\", r->val[c].%s, r->val[c].%s_len, 1);\n"
>            name name name
>      | name, FUUID ->
> -        pr "    add_assoc_stringl (z_elem, \"%s\", r->val[c].%s, 32, 1);\n"
> +        pr "    guestfs_add_assoc_stringl (z_elem, \"%s\", r->val[c].%s, 32, 1);\n"
>            name name
>      | name, (FBytes|FUInt64|FInt64|FInt32|FUInt32) ->
>          pr "    add_assoc_long (z_elem, \"%s\", r->val[c].%s);\n"
>            name name
>      | name, FChar ->
> -        pr "    add_assoc_stringl (z_elem, \"%s\", &r->val[c].%s, 1, 1);\n"
> +        pr "    guestfs_add_assoc_stringl (z_elem, \"%s\", &r->val[c].%s, 1, 1);\n"
>            name name
>      | name, FOptPercent ->
>          pr "    add_assoc_double (z_elem, \"%s\", r->val[c].%s);\n"

Bleah PHP.  ACK.

Rich.

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html




More information about the Libguestfs mailing list