X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fimpl_def_val.c;h=f78a6b9c0d4355523dd365c24a7e0fd43853b78a;hp=0d176f309eea9845d6ff2222243ef761c6d4f98a;hb=2559f07a178b681dc240e20153ff5abdff54cb34;hpb=2f5af21b263403997e154658635d6b6e6eaab453 diff --git a/src/types/impl_def_val.c b/src/types/impl_def_val.c index 0d176f3..f78a6b9 100644 --- a/src/types/impl_def_val.c +++ b/src/types/impl_def_val.c @@ -23,34 +23,180 @@ 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 "php_psi_stdinc.h" +#include "data.h" -#include -#include +#include +#include -#include "impl_def_val.h" +struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data) +{ + struct psi_impl_def_val *def = calloc(1, sizeof(*def)); -void free_impl_def_val(impl_def_val *def) { - free(def->text); - free(def); -} + switch ((def->type = t)) { + case PSI_T_TRUE: + case PSI_T_FALSE: + case PSI_T_NULL: + break; + case PSI_T_QUOTED_STRING: + /* immediate upgrade */ + def->type = PSI_T_STRING; + /* no break */ + case PSI_T_STRING: + if (data) { + def->ival.zend.str = zend_string_copy(data); + } + break; + + case PSI_T_NUMBER: + def->data.num = data; + break; + + default: + assert(0); + } -impl_def_val *init_impl_def_val(token_t t, const char *text) { - impl_def_val *def = calloc(1, sizeof(*def)); - def->type = t; - def->text = strdup(text); return def; } -void dump_impl_def_val(int fd, impl_def_val *val) { - if (val->type == PSI_T_QUOTED_STRING) { - dprintf(fd, "\"%s\"", val->text); - } else { - dprintf(fd, "%s", val->text); +void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr) +{ + if (*def_ptr) { + struct psi_impl_def_val *def = *def_ptr; + + *def_ptr = NULL; + psi_token_free(&def->token); + switch (def->type) { + case PSI_T_NUMBER: + psi_num_exp_free(&def->data.num); + break; + + case PSI_T_STRING: + if (def->ival.zend.str) { + zend_string_release(def->ival.zend.str); + } + break; + default: + break; + } + free(def); + } +} + +bool psi_impl_def_val_validate(struct psi_data *data, + struct psi_impl_def_val *val, struct psi_impl_type *type, + struct psi_validate_scope *scope) +{ + if (val->type == PSI_T_NULL) { + return true; + } else if (val->type == PSI_T_NUMBER) { + if (!psi_num_exp_validate(data, val->data.num, scope)) { + return false; + } + } + + switch (type->type) { + case PSI_T_BOOL: + val->ival.zend.bval = val->type == PSI_T_TRUE ? 1 : 0; + break; + + /* macros */ + case PSI_T_NUMBER: + if (val->type == PSI_T_NUMBER) { + token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->defs); + + switch (typ) { + case PSI_T_FLOAT: + val->ival.dval = val->ival.fval; + /* no break */ + case PSI_T_DOUBLE: + val->type = PSI_T_FLOAT; + type->type = PSI_T_FLOAT; + zend_string_release(type->name); + type->name = zend_string_init_interned(ZEND_STRL("float"), 1); + break; + default: + val->type = PSI_T_INT; + type->type = PSI_T_INT; + zend_string_release(type->name); + type->name = zend_string_init_interned(ZEND_STRL("int"), 1); + break; + } + psi_num_exp_free(&val->data.num); + return true; + } + break; + + case PSI_T_INT: + if (val->type == PSI_T_NUMBER) { + val->type = PSI_T_INT; + val->ival.zend.lval = psi_num_exp_get_long(val->data.num, NULL, scope->defs); + psi_num_exp_free(&val->data.num); + } + if (val->type == PSI_T_INT) { + return true; + } + break; + + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + if (val->type == PSI_T_NUMBER) { + val->type = PSI_T_DOUBLE; + val->ival.dval = psi_num_exp_get_double(val->data.num, NULL, scope->defs); + psi_num_exp_free(&val->data.num); + } + if (val->type == PSI_T_DOUBLE) { + return true; + } + break; + + case PSI_T_STRING: + if (val->type == PSI_T_STRING) { + return true; + } + break; + + default: + data->error(data, val->token, PSI_WARNING, + "Invalid default value type '%s', " + "expected one of bool, int, float, string.", + type->name->val); } + return false; +} + +void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) { + switch (val->type) { + case PSI_T_NULL: + dprintf(fd, "NULL"); + break; + case PSI_T_TRUE: + dprintf(fd, "true"); + break; + case PSI_T_FALSE: + dprintf(fd, "false"); + break; + case PSI_T_BOOL: + dprintf(fd, "%s", val->ival.zend.bval ? "true" : "false"); + break; + case PSI_T_INT: + dprintf(fd, "%ld", val->ival.zend.lval); + break; + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + if (isinf(val->ival.dval)) { + dprintf(fd, "\\INF"); + } else if (isnan(val->ival.dval)) { + dprintf(fd, "\\NAN"); + } else { + dprintf(fd, "%" PRIdval, val->ival.dval); + } + break; + case PSI_T_STRING: + dprintf(fd, "\"%s\"", val->ival.zend.str->val); + break; + default: + assert(0); + } }