interned strings
[m6w6/ext-psi] / src / types / impl_def_val.c
index c5bf7444a0ebb0e8e592f4989880b328dc32d3d8..f78a6b9c0d4355523dd365c24a7e0fd43853b78a 100644 (file)
@@ -27,6 +27,7 @@
 #include "data.h"
 
 #include <assert.h>
+#include <math.h>
 
 struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data)
 {
@@ -43,7 +44,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;
 
@@ -64,9 +65,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);
@@ -85,77 +84,83 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr)
 }
 
 bool psi_impl_def_val_validate(struct psi_data *data,
-               struct psi_impl_def_val *def, struct psi_impl_type *cmp,
+               struct psi_impl_def_val *val, struct psi_impl_type *type,
                struct psi_validate_scope *scope)
 {
-       if (def->type == PSI_T_NULL) {
+       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 (cmp->type) {
+       switch (type->type) {
        case PSI_T_BOOL:
-               def->ival.zend.bval = def->type == PSI_T_TRUE ? 1 : 0;
+               val->ival.zend.bval = val->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);
+               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:
-                               def->ival.dval = def->ival.fval;
+                               val->ival.dval = val->ival.fval;
                                /* no break */
                        case PSI_T_DOUBLE:
-                               def->type = PSI_T_FLOAT;
-                               cmp->type = PSI_T_FLOAT;
-                               strcpy(cmp->name, "float");
+                               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:
-                               def->type = PSI_T_INT;
-                               cmp->type = PSI_T_INT;
-                               strcpy(cmp->name, "int");
+                               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(&def->data.num);
+                       psi_num_exp_free(&val->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 (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 (def->type == PSI_T_INT) {
+               if (val->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 (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 (def->type == PSI_T_DOUBLE) {
+               if (val->type == PSI_T_DOUBLE) {
                        return true;
                }
                break;
 
        case PSI_T_STRING:
-               if (def->type == PSI_T_STRING) {
+               if (val->type == PSI_T_STRING) {
                        return true;
                }
                break;
 
        default:
-               data->error(data, def->token, PSI_WARNING,
+               data->error(data, val->token, PSI_WARNING,
                                "Invalid default value type '%s', "
                                "expected one of bool, int, float, string.",
-                               cmp->name);
+                               type->name->val);
        }
 
        return false;
@@ -180,7 +185,13 @@ 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, "%" PRIdval, val->ival.dval);
+               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);