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

Pino Toscano ptoscano at redhat.com
Mon Apr 11 15:16:20 UTC 2016


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"
-- 
2.5.5




More information about the Libguestfs mailing list