X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fcontext.c;h=0242b77ae3c5bd2844c12862f762ef3d01a6faf0;hp=3f94d422e8f00848bac0bdca970c71c10729fe3b;hb=7e3b009ddee1508720d3493c3985654e8f21ea0e;hpb=772c1e688a51b32331fae7993429b3a03d766d8d diff --git a/src/context.c b/src/context.c index 3f94d42..0242b77 100644 --- a/src/context.c +++ b/src/context.c @@ -173,6 +173,35 @@ static inline int validate_decl_arg(PSI_Data *data, decl_arg *arg) { return 1; } +static int psi_sort_struct_arg_cmp(const void *_a, const void *_b) { + decl_arg *a = *(decl_arg **)_a, *b = *(decl_arg **)_b; + + if (a->layout->pos == b->layout->pos) { + if (a->layout->len == b->layout->len) { + return 0; + } else if (a->layout->len > b->layout->len) { + return -1; + } else { + return 1; + } + } else if (a->layout->pos > b->layout->pos) { + return 1; + } else { + return -1; + } +} +static void psi_sort_struct_arg_swp(void *a, void *b) { + decl_arg **_a = a, **_b = b, *_c; + + _c = *_b; + *_b = *_a; + *_a = _c; +} +static inline void psi_sort_struct_args(decl_struct *s) { + zend_insert_sort(s->args->args, s->args->count, sizeof(*s->args->args), + psi_sort_struct_arg_cmp, psi_sort_struct_arg_swp); +} + static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) { size_t i; @@ -192,7 +221,31 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) { ZEND_ASSERT(!darg->var->arg || darg->var->arg == darg); darg->var->arg = darg; - if (!darg->layout) { + if (darg->layout) { + size_t size; + + if (darg->var->array_size) { + size = psi_t_size(real_decl_type(darg->type)->type) * darg->var->array_size; + } else if (darg->var->pointer_level) { + size = psi_t_size(PSI_T_POINTER); + } else { + decl_type *real = real_decl_type(darg->type); + + if (real->type == PSI_T_STRUCT) { + size = real->strct->size; + } else { + size = psi_t_size(real->type); + } + } + if (darg->layout->len != size) { + data->error(darg->token, PSI_WARNING, + "Computed length %zu of %s.%s does not match" + " pre-defined length %zu of type '%s'", + darg->layout->len, s->name, darg->var->name, size, + darg->type->name); + return 0; + } + } else { token_t t; if (darg->var->pointer_level && (!darg->var->array_size || darg->var->pointer_level == 1)) { @@ -214,6 +267,9 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) { s->size = darg->layout->pos + darg->layout->len; } } + + psi_sort_struct_args(s); + return 1; } @@ -1243,7 +1299,7 @@ static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) { dprintf(fd, ", "); dump_num_exp(fd, set->num); } - if (set->inner) { + if (set->inner && set->func->type != PSI_T_ELLIPSIS) { dprintf(fd, ",\n"); for (i = 0; i < set->count; ++i) { dump_impl_set_value(fd, set->inner[i], level+1); @@ -1391,6 +1447,9 @@ void PSI_ContextDump(PSI_Context *C, int fd) dprintf(fd, "%s($%s)", let->val->data.func->name, let->val->data.func->var->name); break; + case PSI_LET_NUMEXP: + dump_num_exp(fd, let->val->data.num); + break; EMPTY_SWITCH_DEFAULT_CASE(); }