From: Michael Wallner Date: Thu, 7 Jan 2016 09:34:38 +0000 (+0100) Subject: flush X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=c2dc24a4967dd767fc4a240f93ca0de4600a8c62;p=m6w6%2Fext-psi flush --- diff --git a/php_psi.h b/php_psi.h index 31e6565..8bac826 100644 --- a/php_psi.h +++ b/php_psi.h @@ -55,6 +55,7 @@ void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val); void psi_to_int(zval *return_value, set_value *set, impl_val *ret_val); void psi_to_double(zval *return_value, set_value *set, impl_val *ret_val); void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val); +void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val); void psi_to_array(zval *return_value, set_value *set, impl_val *ret_val); void psi_to_object(zval *return_value, set_value *set, impl_val *ret_val); diff --git a/psi.d/netdb.psi b/psi.d/netdb.psi index 8186a7d..df34547 100644 --- a/psi.d/netdb.psi +++ b/psi.d/netdb.psi @@ -28,11 +28,8 @@ function psi\getaddrinfo(string $node, string $service, array $hints, object &$r to_int(ai_socktype), to_int(ai_protocol), to_int(ai_addrlen), - to_array(ai_addr, - to_int(sa_family), - to_string(sa_data, ai_addrlen) - ), - to_string(ai_canonname) - // FIXME ai_next + to_string(ai_addr, ai_addrlen), + to_string(ai_canonname), + to_array(ai_next, ...) ); } \ No newline at end of file diff --git a/src/context.c b/src/context.c index 3d20920..ee79c8f 100644 --- a/src/context.c +++ b/src/context.c @@ -524,6 +524,12 @@ static inline int validate_set_value_handler(set_value *set) { case PSI_T_VOID: set->func->handler = psi_to_void; break; + case PSI_T_ELLIPSIS: + if (set->outer.set && set->outer.set->func->type == PSI_T_TO_ARRAY) { + set->func->handler = psi_to_recursive; + break; + } + /* no break */ default: return 0; } @@ -548,14 +554,14 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg decl_var *set_var = set->vars->vars[0]; if (!validate_set_value_handler(set)) { - data->error(set->func->token, PSI_WARNING, "Invalid cast '%s'", set->func->name); + data->error(set->func->token, PSI_WARNING, "Invalid cast '%s' in `set` statement", set->func->name); return 0; } for (i = 0; i < set->vars->count; ++i) { decl_var *svar = set->vars->vars[i]; if (!svar->arg && !locate_decl_var_arg(svar, ref_list, NULL)) { - data->error(svar->token, PSI_WARNING, "Unknown variable '%s'", svar->name); + data->error(svar->token, PSI_WARNING, "Unknown variable '%s' in `set` statement", svar->name); return 0; } } @@ -587,7 +593,6 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg decl_var *sub_var = set->inner[i]->vars->vars[0]; decl_arg *sub_ref = locate_struct_member(ref_type->strct, sub_var); - set->inner[i]->outer.set = set; if (sub_ref) { if (!validate_set_value_ex(data, set->inner[i], sub_ref, ref_type->strct->args)) { return 0; @@ -599,7 +604,6 @@ static inline int validate_set_value_ex(PSI_Data *data, set_value *set, decl_arg decl_var *sub_var = set->inner[0]->vars->vars[0]; decl_arg *sub_ref = locate_decl_var_arg(sub_var, ref_list, ref); - set->inner[0]->outer.set = set; if (sub_ref) { if (strcmp(sub_var->name, set_var->name)) { data->error(sub_var->token, E_WARNING, "Inner `set` statement casts on pointers must reference the same variable"); @@ -1312,14 +1316,20 @@ static inline void dump_num_exp(int fd, num_exp *exp) { exp = exp->operand; } } + static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) { - size_t i; + size_t i, j; if (level > 1) { /* only if not directly after `set ...` */ dump_level(fd, level); } - dprintf(fd, "%s(", set->func->name); + + if (set->func->type == PSI_T_ELLIPSIS) { + dprintf(fd, "%s(", set->outer.set->func->name); + } else { + dprintf(fd, "%s(", set->func->name); + } for (i = 0; i < set->vars->count; ++i) { decl_var *svar = set->vars->vars[i]; @@ -1328,6 +1338,10 @@ static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) { } dump_decl_var(fd, svar); } + + if (set->func->type == PSI_T_ELLIPSIS) { + dprintf(fd, ", ..."); + } if (set->num) { dprintf(fd, ", "); dump_num_exp(fd, set->num); diff --git a/src/module.c b/src/module.c index 39d1291..607015d 100644 --- a/src/module.c +++ b/src/module.c @@ -297,6 +297,13 @@ void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val) token_t t = real_decl_type(var->arg->type)->type; switch (t) { + case PSI_T_FLOAT: + RETVAL_DOUBLE((double) deref_impl_val(ret_val, var)->fval); + break; + case PSI_T_DOUBLE: + RETVAL_DOUBLE(deref_impl_val(ret_val, var)->dval); + break; + default: case PSI_T_VOID: case PSI_T_INT8: case PSI_T_UINT8: @@ -315,13 +322,6 @@ void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val) } } return; - case PSI_T_FLOAT: - RETVAL_DOUBLE((double) deref_impl_val(ret_val, var)->fval); - break; - case PSI_T_DOUBLE: - RETVAL_DOUBLE(deref_impl_val(ret_val, var)->dval); - break; - default: psi_to_int(return_value, set, ret_val); break; } @@ -386,6 +386,11 @@ void *psi_array_to_struct(decl_struct *s, HashTable *arr) return mem; } +void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val) +{ + set->outer.set->func->handler(return_value, set->outer.set, r_val->ptr); +} + void psi_to_array(zval *return_value, set_value *set, impl_val *r_val) { size_t i; diff --git a/src/parser.h b/src/parser.h index aadb31c..2ea0ec8 100644 --- a/src/parser.h +++ b/src/parser.h @@ -822,12 +822,17 @@ static inline set_value *init_set_value(set_func *func, decl_vars *vars) { static inline set_value *add_inner_set_value(set_value *val, set_value *inner) { val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner)); val->inner[val->count-1] = inner; + inner->outer.set = val; return val; } static inline void free_set_value(set_value *val) { - free_set_func(val->func); - free_decl_vars(val->vars); + if (val->func) { + free_set_func(val->func); + } + if (val->vars) { + free_decl_vars(val->vars); + } if (val->inner) { size_t i; for (i = 0; i < val->count; ++i) { diff --git a/src/parser_proc.y b/src/parser_proc.y index 80a0519..5713c85 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -440,6 +440,11 @@ set_value(val) ::= set_func(func) LPAREN decl_var(var) COMMA num_exp(num_) RPARE val = init_set_value(func, init_decl_vars(var)); val->num = num_; } +set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA ELLIPSIS(T) RPAREN. { + free_set_func(func_); + val = init_set_value(init_set_func(T->type, T->text), init_decl_vars(var)); + val->func->token = T; +} set_value(val) ::= set_func(func_) LPAREN decl_var(var) COMMA set_vals(vals) RPAREN. { val = vals; val->func = func_;