X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fimpl_def_val.c;h=eec90e6783ea123dac39de26f5eb058a25b92909;hp=fe11b269f6e3a02d6883f07fb7db3e5c5ce9f590;hb=a7ac1c0a3c855321f21682c127a4b707de33a303;hpb=a88d91ed2154bdb6d2198e44c6f3868a5b398287 diff --git a/src/types/impl_def_val.c b/src/types/impl_def_val.c index fe11b26..eec90e6 100644 --- a/src/types/impl_def_val.c +++ b/src/types/impl_def_val.c @@ -29,9 +29,11 @@ #include #include +#define PSI_IMPL_DEF_VAL_DEBUG 0 + 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)); + struct psi_impl_def_val *def = pecalloc(1, sizeof(*def), 1); switch ((def->type = t)) { case PSI_T_TRUE: @@ -44,7 +46,7 @@ struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data) /* no break */ case PSI_T_STRING: if (data) { - def->ival.zend.str = zend_string_init(data, strlen(data), 1); + def->ival.zend.str = zend_string_copy(data); } break; @@ -65,9 +67,7 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr) struct psi_impl_def_val *def = *def_ptr; *def_ptr = NULL; - if (def->token) { - free(def->token); - } + psi_token_free(&def->token); switch (def->type) { case PSI_T_NUMBER: psi_num_exp_free(&def->data.num); @@ -97,15 +97,16 @@ bool psi_impl_def_val_validate(struct psi_data *data, } } - switch (type->type) { + switch (type ? type->type : PSI_T_MIXED) { case PSI_T_BOOL: val->ival.zend.bval = val->type == PSI_T_TRUE ? 1 : 0; + return true; 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); + token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp); switch (typ) { case PSI_T_FLOAT: @@ -114,12 +115,21 @@ bool psi_impl_def_val_validate(struct psi_data *data, case PSI_T_DOUBLE: val->type = PSI_T_FLOAT; type->type = PSI_T_FLOAT; - strcpy(type->name, "float"); + zend_string_release(type->name); + type->name = zend_string_init_interned(ZEND_STRL("float"), 1); break; + case PSI_T_UINT64: + if (val->ival.u64 > ZEND_LONG_MAX) { + data->error(data, val->token, PSI_WARNING, + "Integer too big for signed representation: '%" PRIu64 "'", + val->ival.u64); + } default: + /* FIXME big integers */ val->type = PSI_T_INT; type->type = PSI_T_INT; - strcpy(type->name, "int"); + zend_string_release(type->name); + type->name = zend_string_init_interned(ZEND_STRL("int"), 1); break; } psi_num_exp_free(&val->data.num); @@ -130,7 +140,12 @@ bool psi_impl_def_val_validate(struct psi_data *data, 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); + val->ival.zend.lval = psi_num_exp_get_long(val->data.num, NULL, scope->cpp); +#if PSI_IMPL_DEF_VAL_DEBUG + PSI_DEBUG_PRINT(data, "PSI: NUMBER (long) %" PRIi64 " from ", val->ival.zend.lval); + PSI_DEBUG_DUMP(data, psi_num_exp_dump, val->data.num); + PSI_DEBUG_PRINT(data, "\n"); +#endif psi_num_exp_free(&val->data.num); } if (val->type == PSI_T_INT) { @@ -142,7 +157,12 @@ bool psi_impl_def_val_validate(struct psi_data *data, 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); + val->ival.dval = psi_num_exp_get_double(val->data.num, NULL, scope->cpp); +#if PSI_IMPL_DEF_VAL_DEBUG + PSI_DEBUG_PRINT(data, "PSI: NUMBER (double) %" PRIdval " from ", val->ival.dval); + PSI_DEBUG_DUMP(data, psi_num_exp_dump, val->data.num); + PSI_DEBUG_PRINT(data, "\n"); +#endif psi_num_exp_free(&val->data.num); } if (val->type == PSI_T_DOUBLE) { @@ -156,11 +176,62 @@ bool psi_impl_def_val_validate(struct psi_data *data, } break; + case PSI_T_MIXED: + switch (val->type) { + case PSI_T_TRUE: + case PSI_T_FALSE: + case PSI_T_NULL: + case PSI_T_STRING: + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + case PSI_T_INT: + return true; + default: + break; + } + if (val->type == PSI_T_NUMBER) { + token_t typ = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp); + + switch (typ) { + case PSI_T_FLOAT: +#if HAVE_LONG_DOUBLE + case PSI_T_LONG_DOUBLE: +#endif + promote_double: ; + psi_calc_cast(typ, &val->ival, PSI_T_DOUBLE, &val->ival); + /* no break */ + case PSI_T_DOUBLE: + val->type = PSI_T_DOUBLE; + return true; + case PSI_T_UINT64: + if (val->ival.u64 > (uint64_t) ZEND_LONG_MAX) { + if (val->ival.u64 > (1LU<<53)) { + char buf[0x20]; + + /* convert to string */ + char *res = zend_print_ulong_to_buf(buf + sizeof(buf) - 1, val->ival.u64); + val->type = PSI_T_STRING; + val->ival.zend.str = zend_string_init(res, buf + sizeof(buf) - 1 - res, 1); + + return true; + } + goto promote_double; + } + /* no break */ + default: + psi_calc_cast(typ, &val->ival, PSI_T_INT64, &val->ival); + /* no break */ + case PSI_T_INT64: + val->type = PSI_T_INT; + return true; + } + } + /* no break */ default: data->error(data, val->token, PSI_WARNING, "Invalid default value type '%s', " "expected one of bool, int, float, string.", - type->name); + type ? type->name->val : "mixed"); } return false; @@ -181,7 +252,7 @@ void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) { dprintf(fd, "%s", val->ival.zend.bval ? "true" : "false"); break; case PSI_T_INT: - dprintf(fd, "%ld", val->ival.zend.lval); + dprintf(fd, ZEND_LONG_FMT, val->ival.zend.lval); break; case PSI_T_FLOAT: case PSI_T_DOUBLE: @@ -196,6 +267,9 @@ void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) { case PSI_T_STRING: dprintf(fd, "\"%s\"", val->ival.zend.str->val); break; + case PSI_T_NUMBER: + psi_num_exp_dump(fd, val->data.num); + break; default: assert(0); }