fix leak
[m6w6/ext-psi] / src / data.c
index 9c2cefbea63cc8da9319a9362a2d971ca6b0aecf..c45ddf6507f2e25b9cce464217e0f6d28be5c008 100644 (file)
@@ -29,6 +29,7 @@
 #include "php_globals.h"
 
 #include <dlfcn.h>
+#include <ctype.h>
 
 struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data,
                psi_error_cb error, unsigned flags)
@@ -241,14 +242,18 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
        struct psi_plist *check_structs = src->structs;
        struct psi_plist *check_unions = src->unions;
        struct psi_plist *check_enums = src->enums;
+       struct psi_plist *check_decls = src->decls;
        unsigned flags = dst->flags;
        unsigned errors = src->errors;
+       struct psi_validate_stack type_stack;
 
        /* fail early if library is not found */
        if (!psi_decl_file_validate(dst, src, &dlopened)) {
                return false;
        }
 
+       psi_validate_stack_ctor(&type_stack);
+
        dst->flags |= PSI_SILENT;
 
        while (check_count) {
@@ -256,12 +261,14 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                struct psi_plist *recheck_structs;
                struct psi_plist *recheck_unions;
                struct psi_plist *recheck_enums;
+               struct psi_plist *recheck_decls;
                size_t count_types = psi_plist_count(check_types);
                size_t count_structs = psi_plist_count(check_structs);
                size_t count_unions = psi_plist_count(check_unions);
                size_t count_enums = psi_plist_count(check_enums);
+               size_t count_decls = psi_plist_count(check_decls);
                size_t count_all = count_types + count_structs + count_unions
-                               + count_enums;
+                               + count_enums + count_decls;
 
                if (check_count == count_all) {
                        /* nothing changed; bail out */
@@ -280,6 +287,7 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                        recheck_structs = count_structs ? psi_plist_init(NULL) : NULL;
                        recheck_unions = count_unions ? psi_plist_init(NULL) : NULL;
                        recheck_enums = count_enums ? psi_plist_init(NULL) : NULL;
+                       recheck_decls = count_decls ? psi_plist_init(NULL) : NULL;
 
                        check_count = count_all;
                        src->errors = errors + check_count;
@@ -293,13 +301,14 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
 
                                while (psi_plist_get(check_types, i++, &def)) {
                                        *dst->last_error = 0;
+                                       dst->types = psi_plist_add(dst->types, &def);
                                        PSI_DEBUG_PRINT(dst, "PSI: validate typedef %s ", def->var->name);
-                                       if (psi_decl_arg_validate_typedef(PSI_DATA(dst), def)) {
+                                       if (psi_decl_arg_validate_typedef(PSI_DATA(dst), def, &type_stack)) {
                                                PSI_DEBUG_PRINT(dst, "%s\n", "✔");
-                                               dst->types = psi_plist_add(dst->types, &def);
                                        } else {
                                                PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error);
                                                recheck_types = psi_plist_add(recheck_types, &def);
+                                               psi_plist_pop(dst->types, NULL);
                                        }
                                }
                        }
@@ -311,7 +320,7 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                                        *dst->last_error = 0;
                                        dst->structs = psi_plist_add(dst->structs, &str);
                                        PSI_DEBUG_PRINT(dst, "PSI: validate struct %s ", str->name);
-                                       if (psi_decl_struct_validate(PSI_DATA(dst), str)) {
+                                       if (psi_decl_struct_validate(PSI_DATA(dst), str, &type_stack)) {
                                                PSI_DEBUG_PRINT(dst, "%s ::(%zu, %zu)\n", "✔", str->align, str->size);
                                        } else {
                                                PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error);
@@ -328,9 +337,8 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                                        *dst->last_error = 0;
                                        dst->unions = psi_plist_add(dst->unions, &unn);
                                        PSI_DEBUG_PRINT(dst, "PSI: validate union %s ", unn->name);
-                                       if (psi_decl_union_validate(PSI_DATA(dst), unn)) {
+                                       if (psi_decl_union_validate(PSI_DATA(dst), unn, &type_stack)) {
                                                PSI_DEBUG_PRINT(dst, "%s ::(%zu, %zu)\n", "✔", unn->align, unn->size);
-
                                        } else {
                                                PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error);
                                                recheck_unions = psi_plist_add(recheck_unions, &unn);
@@ -354,6 +362,22 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                                        }
                                }
                        }
+                       if (count_decls) {
+                               size_t i = 0;
+                               struct psi_decl *decl;
+
+                               while (psi_plist_get(check_decls, i++, &decl)) {
+                                       *dst->last_error = 0;
+                                       PSI_DEBUG_PRINT(dst, "PSI: validate decl %s ", decl->func->var->name);
+                                       if (psi_decl_validate(PSI_DATA(dst), decl, dlopened, &type_stack)) {
+                                               PSI_DEBUG_PRINT(dst, "%s\n", "✔");
+                                               dst->decls = psi_plist_add(dst->decls, &decl);
+                                       } else {
+                                               PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error);
+                                               recheck_decls = psi_plist_add(recheck_decls, &decl);
+                                       }
+                               }
+                       }
                }
 
                if (check_types && check_types != src->types) {
@@ -372,11 +396,56 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                        psi_plist_free(check_enums);
                }
                check_enums = recheck_enums;
+               if (check_decls && check_decls != src->decls) {
+                       psi_plist_free(check_decls);
+               }
+               check_decls = recheck_decls;
        }
 
        /* reset original flags */
        dst->flags = flags;
 
+       if (dst->structs) {
+               size_t i = 0;
+               struct psi_decl_struct *str;
+
+               while (psi_plist_get(dst->structs, i++, &str)) {
+                       size_t nlen = strlen(str->name);
+                       size_t slen = sizeof("psi\\SIZEOF_STRUCT_");
+                       size_t alen = sizeof("psi\\ALIGNOF_STRUCT_");
+                       char *nptr = str->name, *sname, *aname;
+                       struct psi_const *cnst;
+                       struct psi_const_type *ctyp;
+                       struct psi_impl_def_val *cval;
+
+                       sname = malloc(slen + nlen + 1);
+                       strcpy(sname, "psi\\SIZEOF_STRUCT_");
+                       aname = malloc(alen + nlen + 1);
+                       strcpy(aname, "psi\\ALIGNOF_STRUCT_");
+
+                       nptr = str->name;
+                       while (*nptr) {
+                               size_t off = nptr - str->name;
+                               sname[slen - 1 + off] = aname[alen - 1 + off] = toupper(*nptr++);
+                       }
+                       sname[slen - 1 + nlen] = aname[alen - 1 + nlen] = 0;
+
+                       ctyp = psi_const_type_init(PSI_T_INT, "int");
+                       cval = psi_impl_def_val_init(PSI_T_INT, NULL);
+                       cval->ival.zend.lval = str->size;
+                       cnst = psi_const_init(ctyp, sname, cval);
+                       src->consts = psi_plist_add(src->consts, &cnst);
+                       free(sname);
+
+                       ctyp = psi_const_type_init(PSI_T_INT, "int");
+                       cval = psi_impl_def_val_init(PSI_T_INT, NULL);
+                       cval->ival.zend.lval = str->align;
+                       cnst = psi_const_init(ctyp, aname, cval);
+                       src->consts = psi_plist_add(src->consts, &cnst);
+                       free(aname);
+               }
+       }
+
        if (src->consts) {
                size_t i = 0;
                struct psi_const *cnst;
@@ -394,23 +463,6 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                }
        }
 
-       if (src->decls) {
-               size_t i = 0;
-               struct psi_decl *decl;
-
-               while (psi_plist_get(src->decls, i++, &decl)) {
-                       *dst->last_error = 0;
-                       PSI_DEBUG_PRINT(dst, "PSI: validate decl %s ", decl->func->var->name);
-                       if (psi_decl_validate(PSI_DATA(dst), decl, dlopened)) {
-                               PSI_DEBUG_PRINT(dst, "%s\n", "✔");
-                               dst->decls = psi_plist_add(dst->decls, &decl);
-                       } else {
-                               PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error);
-                               ++src->errors;
-                       }
-               }
-       }
-
        if (src->impls) {
                size_t i = 0;
                struct psi_impl *impl;
@@ -428,6 +480,8 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src)
                }
        }
 
+       psi_validate_stack_dtor(&type_stack);
+
        return true;
 }