fix gdbinit; postprocessing macros
[m6w6/ext-psi] / src / types / set_func.c
index c6ab80fd0ac091aead128c5ad432751bd62f3fbd..96ab6a19c2da884e17381394badac965366553d4 100644 (file)
 #include "php_psi_stdinc.h"
 #include "data.h"
 
-struct psi_set_func *psi_set_func_init(token_t type, const char *name,
+struct psi_set_func *psi_set_func_init(token_t type, zend_string *name,
                struct psi_decl_var *var)
 {
-       struct psi_set_func *func = calloc(1, sizeof(*func));
+       struct psi_set_func *func = pecalloc(1, sizeof(*func), 1);
 
        func->type = type;
-       func->name = strdup(name);
+       func->name = zend_string_copy(name);
        func->var = var;
 
        return func;
@@ -44,39 +44,37 @@ void psi_set_func_free(struct psi_set_func **func_ptr)
                struct psi_set_func *func = *func_ptr;
 
                *func_ptr = NULL;
-               if (func->token) {
-                       free(func->token);
-               }
+               psi_token_free(&func->token);
                psi_decl_var_free(&func->var);
-               free(func->name);
+               zend_string_release(func->name);
                free(func);
        }
 }
 
-void psi_set_func_dump(int fd, struct psi_set_func *func, unsigned level)
+void psi_set_func_dump(struct psi_dump *dump, struct psi_set_func *func, unsigned level)
 {
-       dprintf(fd, "%s(", func->name);
-       psi_decl_var_dump(fd, func->var);
-       dprintf(fd, "\t/* fqn=%s */", func->var->fqn);
+       PSI_DUMP(dump, "%s(", func->name->val);
+       psi_decl_var_dump(dump, func->var);
+       PSI_DUMP(dump, "\t/* fqn=%s */", func->var->fqn->val);
        if (func->inner && !func->recursive) {
                size_t i = 0, count = psi_plist_count(func->inner);
                struct psi_set_exp *inner;
 
-               dprintf(fd, ",");
+               PSI_DUMP(dump, ",");
                ++level;
                while (psi_plist_get(func->inner, i++, &inner)) {
-                       dprintf(fd, "\n");
-                       psi_set_exp_dump(fd, inner, level, i == count);
+                       PSI_DUMP(dump, "\n");
+                       psi_set_exp_dump(dump, inner, level, i == count);
                }
                --level;
        }
        if (func->recursive) {
-               dprintf(fd, ", ...");
+               PSI_DUMP(dump, ", ...");
        }
        if (func->inner && !func->recursive) {
-               dprintf(fd, "\n%s", psi_t_indent(level));
+               PSI_DUMP(dump, "\n%s", psi_t_indent(level));
        }
-       dprintf(fd, ")");
+       PSI_DUMP(dump, ")");
 }
 
 static inline bool psi_set_func_validate_to_string(struct psi_data *data,
@@ -133,7 +131,7 @@ static inline bool psi_set_func_validate_to_array(struct psi_data *data,
                                        PSI_WARNING, "Expected to_type() cast expression");
                        return false;
                }
-               if (strcmp(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) {
+               if (!zend_string_equals(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) {
                        /* no warning, because of ambiguity with a one-field-struct monstrosity */
                        goto complex;
                }
@@ -151,13 +149,14 @@ static inline bool psi_set_func_validate_to_array(struct psi_data *data,
                                        PSI_WARNING, "Expected to_type() cast expression");
                        return false;
                }
-               if (strcmp(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) {
+               if (!zend_string_equals(set_var->name, psi_set_exp_get_decl_var(sub_exp)->name)) {
                        data->error(data, **(struct psi_token ***) &sub_exp->data,
                                        PSI_WARNING,
                                        "Expected %s(%s) cast expression to reference the same"
                                        " variable like the outer `set` statement, '%s'",
-                                       sub_exp->data.func->name,
-                                       psi_set_exp_get_decl_var(sub_exp)->name, set_var);
+                                       sub_exp->data.func->name->val,
+                                       psi_set_exp_get_decl_var(sub_exp)->name->val,
+                                       set_var->name->val);
                        return false;
                }
                func->handler = psi_set_to_array_counted;
@@ -173,7 +172,7 @@ static inline bool psi_set_func_validate_to_array(struct psi_data *data,
                        data->error(data, func->token, PSI_WARNING,
                                        "Expected struct or union type for complex to_array()"
                                        " cast expression, got '%s'",
-                                       set_var->arg->type->name);
+                                       set_var->arg->type->name->val);
                        return false;
                }
                func->handler = psi_set_to_array;
@@ -191,7 +190,7 @@ static inline bool psi_set_func_validate_to_recursive(struct psi_data *data,
                data->error(data, func->token, PSI_WARNING,
                                "Expected to_array() as parent to recursion in `set` statement"
                                " of implementation '%s'",
-                               impl->func->name);
+                               impl->func->name->val);
                return false;
        }
 
@@ -202,15 +201,15 @@ static inline bool psi_set_func_validate_to_recursive(struct psi_data *data,
 }
 
 bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func,
-               struct psi_set_exp *set, struct psi_impl *impl, struct psi_decl *cb_decl)
+               struct psi_validate_scope *scope)
 {
-       if (!func->var->arg
-                       && !psi_decl_var_validate(data, func->var, impl, impl->decl, NULL, set)
-                       && !psi_decl_var_validate(data, func->var, NULL, cb_decl, NULL, NULL)
-                       && !psi_impl_get_temp_let_arg(impl, func->var)) {
+       struct psi_set_exp *set = scope->current_set;
+
+       if (!psi_decl_var_validate(data, func->var, scope)
+                       && !psi_impl_get_temp_let_arg(scope->impl, func->var)) {
                data->error(data, func->var->token, PSI_WARNING,
                                "Unknown variable '%s' in implementation %s",
-                               func->var->name, impl->func->name);
+                               func->var->name->val, scope->impl->func->name->val);
                return false;
        }
 
@@ -223,7 +222,6 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func,
        }
 
        if (func->inner && (!set->outer || set->outer->inner != func->inner)) {
-
                size_t i = 0;
                struct psi_set_exp *inner;
 
@@ -232,17 +230,26 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func,
                        struct psi_plist *sub_args;
 
                        inner->outer = set;
+                       scope->current_set = inner;
 
+                       /* skip to "fail:" if field does not exists */
                        sub_var = psi_set_exp_get_decl_var(inner);
                        sub_args = psi_decl_type_get_args(func->var->arg->type, NULL);
-                       if (sub_var && sub_args && !psi_decl_arg_get_by_var(sub_var, sub_args, NULL)) {
-                               /* remove expr for portability with different struct members */
-                               psi_plist_del(func->inner, --i, NULL);
-                               psi_set_exp_free(&inner);
-                       } else if (!psi_set_exp_validate(data, inner, impl, cb_decl)) {
-                               /* remove exp for portability */
-                               psi_plist_del(func->inner, --i, NULL);
+                       if (sub_var && sub_args) {
+                               if (!psi_decl_arg_get_by_var(sub_var, sub_args, NULL)) {
+                                       goto fail;
+                               }
+                       }
+
+                       if (psi_set_exp_validate(data, inner, scope)) {
+                               scope->current_set = set;
+                               continue;
                        }
+               fail:
+                       scope->current_set = set;
+                       /* remove expr for portability with different struct members */
+                       psi_plist_del(func->inner, --i, NULL);
+                       psi_set_exp_free(&inner);
                }
        }
 
@@ -266,19 +273,19 @@ bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func,
                func->handler = psi_set_to_object;
                break;
        case PSI_T_TO_STRING:
-               if (!psi_set_func_validate_to_string(data, func, set, impl)) {
+               if (!psi_set_func_validate_to_string(data, func, set, scope->impl)) {
                        return false;
                }
                break;
        case PSI_T_TO_ARRAY:
-               if (!psi_set_func_validate_to_array(data, func, set, impl)) {
+               if (!psi_set_func_validate_to_array(data, func, set, scope->impl)) {
                        return false;
                }
                break;
        default:
                data->error(data, func->token, PSI_WARNING,
                                "Unknown cast '%s' in `set` statement of implementation '%s'",
-                               func->name, impl->func->name);
+                               func->name->val, scope->impl->func->name->val);
                return false;
        }