X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Ftypes%2Fset_value.c;fp=src%2Ftypes%2Fset_value.c;h=0000000000000000000000000000000000000000;hb=9bcb1df0786a8193d65949c857baaba2f4296e84;hp=5defbd76d17ea77c3972599c5c741589112938ef;hpb=5e240548ba570610ce0dbc248a2b7654a0e080fa;p=m6w6%2Fext-psi diff --git a/src/types/set_value.c b/src/types/set_value.c deleted file mode 100644 index 5defbd7..0000000 --- a/src/types/set_value.c +++ /dev/null @@ -1,251 +0,0 @@ -/******************************************************************************* - Copyright (c) 2016, Michael Wallner . - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#else -# include "php_config.h" -#endif - -#include -#include - -#include "data.h" -#include "marshal.h" - -set_value *init_set_value(set_func *func, decl_vars *vars) { - set_value *val = calloc(1, sizeof(*val)); - val->func = func; - val->vars = vars; - return val; -} - -set_value *add_inner_set_value(set_value *val, set_value *inner) { - val->inner = add_set_value(val->inner, inner); - inner->outer.set = val; - return val; -} - -void free_set_value(set_value *val) { - if (val->func) { - free_set_func(val->func); - } - if (val->vars) { - free_decl_vars(val->vars); - } - if (val->inner - && (!val->outer.set || val->outer.set->inner != val->inner)) { - free_set_values(val->inner); - } - if (val->num) { - free_num_exp(val->num); - } - free(val); -} - -void dump_set_value(int fd, set_value *set, unsigned level, int last) { - size_t i; - - if (level > 1) { - /* only if not directly after `set ...` */ - dprintf(fd, "%s", psi_t_indent(level)); - } - - 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]; - if (i) { - dprintf(fd, ", "); - } - 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); - } - if (set->inner && set->inner->vals && set->func->type != PSI_T_ELLIPSIS) { - dprintf(fd, ",\n"); - for (i = 0; i < set->inner->count; ++i) { - dump_set_value(fd, set->inner->vals[i], level+1, i == (set->inner->count - 1)); - } - /* only if inner stmts, i.e. with new lines, were dumped */ - dprintf(fd, "%s", psi_t_indent(level)); - } - if (level > 1) { - dprintf(fd, ")%s\n", last ? "" : ","); - } else { - dprintf(fd, ");"); - } -} - -static inline void decl_var_arg_v(decl_args *args, va_list argp) { - int argc; - decl_arg **argv; - - memset(args, 0, sizeof(*args)); - - while ((argc = va_arg(argp, int))) { - argv = va_arg(argp, decl_arg **); - while (argc--) { - add_decl_arg(args, *argv++); - } - } -} - -static inline int validate_set_value_handler(set_value *set) { - switch (set->func->type) { - case PSI_T_TO_BOOL: set->func->handler = psi_to_bool; break; - case PSI_T_TO_INT: set->func->handler = psi_to_int; break; - case PSI_T_TO_FLOAT: set->func->handler = psi_to_double; break; - case PSI_T_TO_STRING: set->func->handler = psi_to_string; break; - case PSI_T_TO_ARRAY: set->func->handler = psi_to_array; break; - case PSI_T_TO_OBJECT: set->func->handler = psi_to_object; break; - case PSI_T_VOID: set->func->handler = psi_to_void; break; - case PSI_T_ZVAL: set->func->handler = psi_to_zval; break; - case PSI_T_ELLIPSIS: - if (set->outer.set && set->outer.set->func->type == PSI_T_TO_ARRAY) { - set->func->handler = psi_to_recursive; - set->inner = set->outer.set->inner; - break; - } - /* no break */ - default: - return 0; - } - return 1; -} - -int validate_set_value(struct psi_data *data, set_value *set, ...) { - va_list argp; - decl_args args = {0}; - int check; - - va_start(argp, set); - decl_var_arg_v(&args, argp); - va_end(argp); - - check = validate_set_value_ex(data, set, NULL, &args); - if (args.args) { - free(args.args); - } - return check; -} - -int validate_set_value_ex(struct psi_data *data, set_value *set, decl_arg *ref, decl_args *ref_list) { - size_t i; - decl_type *ref_type; - decl_var *set_var = set->vars->vars[0]; - - if (!validate_set_value_handler(set)) { - data->error(data, 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(data, svar->token, PSI_WARNING, "Unknown variable '%s' in `set` statement", svar->name); - return 0; - } - } - - if (!ref) { - ref = set_var->arg; - } - ref_type = real_decl_type(ref->type); - - if (set->inner && set->inner->count) { - int is_to_array = (set->func->type == PSI_T_TO_ARRAY); - int is_pointer_to_struct = (ref_type->type == PSI_T_STRUCT && ref->var->pointer_level); - - if (!is_to_array && !is_pointer_to_struct) { - data->error(data, set->func->token, E_WARNING, "Inner `set` statement casts only work with " - "to_array() casts on structs or pointers: %s(%s...", set->func->name, set->vars->vars[0]->name); - return 0; - } - } - if (set->num) { - if (!validate_num_exp(data, set->num, ref_list, ref, NULL)) { - return 0; - } - } - - if (set->inner && (ref_type->type == PSI_T_STRUCT || ref_type->type == PSI_T_UNION)) { - /* to_array(struct, to_...) */ - if (!set->outer.set || set->outer.set->inner->vals != set->inner->vals) { - for (i = 0; i < set->inner->count; ++i) { - decl_var *sub_var = set->inner->vals[i]->vars->vars[0]; - decl_arg *sub_ref; - - switch (ref_type->type) { - case PSI_T_STRUCT: - sub_ref = locate_decl_struct_member(ref_type->real.strct, sub_var); - break; - case PSI_T_UNION: - sub_ref = locate_decl_union_member(ref_type->real.unn, sub_var); - break; - } - - if (sub_ref) { - if (!validate_set_value_ex(data, set->inner->vals[i], sub_ref, ref_type->real.strct->args)) { - return 0; - } - } - } - } - } else if (set->inner && set->inner->count == 1) { - /* to_array(ptr, to_string(*ptr)) */ - decl_var *sub_var = set->inner->vals[0]->vars->vars[0]; - decl_arg *sub_ref = locate_decl_var_arg(sub_var, ref_list, ref); - - if (sub_ref) { - if (strcmp(sub_var->name, set_var->name)) { - data->error(data, sub_var->token, E_WARNING, "Inner `set` statement casts on pointers must reference the same variable"); - return 0; - } - if (!validate_set_value_ex(data, set->inner->vals[0], sub_ref, ref_list)) { - return 0; - } - } - } else if (set->inner && set->inner->count > 1) { - data->error(data, set->func->token, E_WARNING, - "Inner `set` statement casts on pointers may only occur once, " - "unless the outer type is a struct or union, got '%s%s'", - ref_type->name, psi_t_indirection(ref->var->pointer_level)); - return 0; - } - - return 1; -} -