X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Ftypes%2Fimpl_def_val.c;h=c6778f9bf917716f3e6e0e5af139d69cb004eae1;hp=6d983cddc7e948a24dd388b3e4174c5644af0438;hb=c9384515a81cb64d345b299908b2852f51bb8e6e;hpb=b029005e56a8913fbb3d17ab497b4a37a00a211c diff --git a/src/types/impl_def_val.c b/src/types/impl_def_val.c index 6d983cd..c6778f9 100644 --- a/src/types/impl_def_val.c +++ b/src/types/impl_def_val.c @@ -28,12 +28,32 @@ #include -struct psi_impl_def_val *psi_impl_def_val_init(token_t t, const char *text) +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)); - def->type = t; - def->text = text ? strdup(text) : NULL; + 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_init(data, strlen(data), 1); + } + break; + + case PSI_T_NUMBER: + def->data.num = data; + break; + + default: + assert(0); + } return def; } @@ -48,8 +68,11 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr) free(def->token); } switch (def->type) { + case PSI_T_NUMBER: + psi_num_exp_free(&def->data.num); + break; + case PSI_T_STRING: - case PSI_T_QUOTED_STRING: if (def->ival.zend.str) { zend_string_release(def->ival.zend.str); } @@ -57,44 +80,95 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr) default: break; } - if (def->text) { - free(def->text); - } free(def); } } bool psi_impl_def_val_validate(struct psi_data *data, - struct psi_impl_def_val *def, token_t type_t, const char *type_name) + struct psi_impl_def_val *def, struct psi_impl_type *cmp, + struct psi_validate_scope *scope) { - if (def->type != PSI_T_NULL && def->text) { - switch (type_t) { - case PSI_T_BOOL: - def->ival.zend.bval = def->type == PSI_T_TRUE ? 1 : 0; - break; - case PSI_T_INT: - def->ival.zend.lval = zend_atol(def->text, strlen(def->text)); - break; - case PSI_T_FLOAT: - case PSI_T_DOUBLE: - def->ival.dval = zend_strtod(def->text, NULL); - break; - case PSI_T_STRING: - case PSI_T_QUOTED_STRING: - def->ival.zend.str = zend_string_init(def->text, strlen(def->text), 1); - break; - default: - data->error(data, def->token, PSI_WARNING, - "Invalid default value type '%s', expected one of bool, int, double, string.", - type_name); - return false; + if (def->type == PSI_T_NULL) { + return true; + } + + switch (cmp->type) { + case PSI_T_BOOL: + def->ival.zend.bval = def->type == PSI_T_TRUE ? 1 : 0; + break; + + /* macros */ + case PSI_T_NUMBER: + if (def->type == PSI_T_NUMBER) { + token_t typ = psi_num_exp_exec(def->data.num, &def->ival, NULL, scope->defs); + + switch (typ) { + case PSI_T_FLOAT: + def->ival.dval = def->ival.fval; + /* no break */ + case PSI_T_DOUBLE: + def->type = PSI_T_FLOAT; + cmp->type = PSI_T_FLOAT; + strcpy(cmp->name, "float"); + break; + default: + def->type = PSI_T_INT; + cmp->type = PSI_T_INT; + strcpy(cmp->name, "int"); + break; + } + psi_num_exp_free(&def->data.num); + return true; } + break; + + case PSI_T_INT: + if (def->type == PSI_T_NUMBER) { + def->type = PSI_T_INT; + def->ival.zend.lval = psi_num_exp_get_long(def->data.num, NULL, scope->defs); + psi_num_exp_free(&def->data.num); + } + if (def->type == PSI_T_INT) { + return true; + } + break; + + case PSI_T_FLOAT: + case PSI_T_DOUBLE: + if (def->type == PSI_T_NUMBER) { + def->type = PSI_T_DOUBLE; + def->ival.dval = psi_num_exp_get_double(def->data.num, NULL, scope->defs); + psi_num_exp_free(&def->data.num); + } + if (def->type == PSI_T_DOUBLE) { + return true; + } + break; + + case PSI_T_STRING: + if (def->type == PSI_T_STRING) { + return true; + } + break; + + default: + data->error(data, def->token, PSI_WARNING, + "Invalid default value type '%s', " + "expected one of bool, int, float, string.", + cmp->name); } - return true; + + return false; } void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) { switch (val->type) { + 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; @@ -103,20 +177,12 @@ void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) { break; case PSI_T_FLOAT: case PSI_T_DOUBLE: - dprintf(fd, "%f", val->ival.dval); + dprintf(fd, "%" PRIdval, val->ival.dval); break; case PSI_T_STRING: dprintf(fd, "\"%s\"", val->ival.zend.str->val); break; - case PSI_T_QUOTED_STRING: - dprintf(fd, "\"%s\"", val->text); - break; default: - if (val->text) { - dprintf(fd, "%s", val->text); - } else { - assert(0); - } - break; + assert(0); } }