fix float formats; fix sime defval edge cases
authorMichael Wallner <mike@php.net>
Wed, 21 Nov 2018 13:16:17 +0000 (14:16 +0100)
committerMichael Wallner <mike@php.net>
Tue, 4 Dec 2018 11:13:49 +0000 (12:13 +0100)
src/calc.h
src/data.c
src/parser.c
src/types/decl_enum.c
src/types/impl_def_val.c
src/types/impl_val.h
src/types/num_exp.c
src/types/number.c
tests/parser/dump001.phpt

index 6361ce8..3aa949c 100644 (file)
 #include "token.h"
 #include "types/impl_val.h"
 
-#define PRIfval ".6g"
-#define PRIdval ".16g"
-#define PRIldval ".29Lg"
+#include <float.h>
+
+#define PRIfmt_digits(digits) #digits
+#define PRIfmt(digits, fmt) "." PRIfmt_digits(digits) fmt
+#define PRIfval PRIfmt(FLT_DECIMAL_DIG, "g")
+#define PRIdval PRIfmt(DBL_DECIMAL_DIG, "g")
+#if HAVE_LONG_DOUBLE
+# define PRIldval PRIfmt(LDBL_DECIMAL_DIG, "Lg")
+#endif
 
 typedef token_t (*psi_calc)(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res);
 
index 9bcd493..e09c472 100644 (file)
@@ -229,7 +229,7 @@ void psi_data_dump(struct psi_dump *dump, struct psi_data *D)
                struct psi_decl_enum *enm;
 
                while (psi_plist_get(D->enums, i++, &enm)) {
-                       if (!psi_decl_type_is_anon(enm->name, "enum")) {
+                       if (true || !psi_decl_type_is_anon(enm->name, "enum")) {
                                psi_decl_enum_dump(dump, enm, 0);
                                PSI_DUMP(dump, "\n");
                        }
index cf576d5..2402816 100644 (file)
@@ -33,7 +33,8 @@
 
 #include "parser.h"
 
-struct psi_parser *psi_parser_init(struct psi_parser *P, psi_error_cb error, unsigned flags)
+struct psi_parser *psi_parser_init(struct psi_parser *P, psi_error_cb error,
+               unsigned flags)
 {
        if (!P) {
                P = pemalloc(sizeof(*P), 1);
@@ -47,7 +48,8 @@ struct psi_parser *psi_parser_init(struct psi_parser *P, psi_error_cb error, uns
        return P;
 }
 
-struct psi_parser_input *psi_parser_open_file(struct psi_parser *P, const char *filename, bool report_errors)
+struct psi_parser_input *psi_parser_open_file(struct psi_parser *P,
+               const char *filename, bool report_errors)
 {
        struct stat sb;
        FILE *fp;
@@ -101,7 +103,8 @@ struct psi_parser_input *psi_parser_open_file(struct psi_parser *P, const char *
        return fb;
 }
 
-struct psi_parser_input *psi_parser_open_string(struct psi_parser *P, const char *string, size_t length)
+struct psi_parser_input *psi_parser_open_string(struct psi_parser *P,
+               const char *string, size_t length)
 {
        struct psi_parser_input *sb;
 
@@ -121,7 +124,8 @@ struct psi_parser_input *psi_parser_open_string(struct psi_parser *P, const char
        return sb;
 }
 
-struct psi_plist *psi_parser_preprocess(struct psi_parser *P, struct psi_plist **tokens)
+struct psi_plist *psi_parser_preprocess(struct psi_parser *P,
+               struct psi_plist **tokens)
 {
        if (psi_cpp_process(P->preproc, tokens)) {
                return *tokens;
@@ -129,7 +133,8 @@ struct psi_plist *psi_parser_preprocess(struct psi_parser *P, struct psi_plist *
        return NULL;
 }
 
-bool psi_parser_process(struct psi_parser *P, struct psi_plist *tokens, size_t *processed)
+bool psi_parser_process(struct psi_parser *P, struct psi_plist *tokens,
+               size_t *processed)
 {
        if (psi_plist_count(tokens)) {
                return 0 == psi_parser_proc_parse(P, tokens, processed);
@@ -147,7 +152,8 @@ static inline zend_string *macro_to_constant(struct psi_parser *parser,
 
        smart_str_append_printf(&str, "const psi\\%s = ", name->val);
        if (scope->macro->exp) {
-               struct psi_dump dump = {{.hn = &str}, .fun = (psi_dump_cb) smart_str_append_printf};
+               struct psi_dump dump = {{.hn = &str},
+                               .fun = (psi_dump_cb) smart_str_append_printf};
 
                psi_num_exp_dump(&dump, scope->macro->exp);
        } else while (psi_plist_get(scope->macro->tokens, i++, &tok)) {
@@ -203,7 +209,7 @@ void psi_parser_postprocess(struct psi_parser *P)
                if (!cnst) {
                        continue;
                }
-
+//fprintf(stderr, "PARSE: %s", ZSTR_VAL(cnst));
                I = psi_parser_open_string(P, ZSTR_VAL(cnst), ZSTR_LEN(cnst));
                zend_string_release(cnst);
 
index 68d644a..df35339 100644 (file)
@@ -51,7 +51,9 @@ void psi_decl_enum_free(struct psi_decl_enum **e_ptr)
 
 void psi_decl_enum_dump(struct psi_dump *dump, struct psi_decl_enum *e, unsigned level)
 {
-       PSI_DUMP(dump, "enum %s {\n", e->name->val);
+       bool is_anon = psi_decl_type_is_anon(e->name, "enum");
+       PSI_DUMP(dump, "enum %s%s%s {\n",
+                       is_anon ? "/* ":"", e->name->val, is_anon ? " */":"");
        if (e->items) {
                size_t i = 0;
                struct psi_decl_enum_item *item;
index 8b2d37b..e8d7b46 100644 (file)
@@ -179,45 +179,6 @@ void psi_impl_def_val_get_zval(struct psi_impl_def_val *val, token_t typ, zval *
        }
 
 }
-/*
-token_t psi_impl_def_val_get_zend(struct psi_impl_def_val *val, impl_val *res)
-{
-       switch (val->type) {
-       case PSI_T_NULL:
-               return PSI_T_NULL;
-       case PSI_T_TRUE:
-       case PSI_T_FALSE:
-               res->zend.bval = val->ival.zend.bval;
-               return PSI_T_BOOL;
-       case PSI_T_STRING:
-               res->zend.str = val->ival.zend.str
-                       ? zend_string_copy(val->ival.zend.str)
-                       : zend_empty_string;
-               return PSI_T_STRING;
-       case PSI_T_NUMBER:
-               switch (val->ityp) {
-               case PSI_T_FLOAT:
-                       res->dval = val->ival.fval;
-                       return PSI_T_DOUBLE;
-               case PSI_T_DOUBLE:
-                       res->dval = val->ival.dval;
-                       return PSI_T_DOUBLE;
-#if HAVE_LONG_DOUBLE
-               case PSI_T_LONG_DOUBLE:
-                       res->dval = val->ival.ldval;
-                       return PSI_T_DOUBLE;
-#endif
-               default:
-                       psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, res);
-                       return PSI_T_INT;
-               }
-               break;
-       default:
-               assert(0);
-               return 0;
-       }
-}
-*/
 
 static inline bool psi_impl_def_val_validate_impl_type(struct psi_data *data,
                struct psi_impl_def_val *val, struct psi_impl_type *type,
@@ -230,18 +191,14 @@ static inline bool psi_impl_def_val_validate_impl_type(struct psi_data *data,
                case PSI_T_FALSE:
                        return true;
                case PSI_T_STRING:
-                       if (val->ival.zend.str
-                                       && *val->ival.zend.str->val
-                                       && *val->ival.zend.str->val != '0') {
-                               zend_string_release(val->ival.zend.str);
-                               val->ival.zend.bval = 1;
-                       } else {
-                               if (val->ival.zend.str) {
-                                       zend_string_release(val->ival.zend.str);
-                               }
-                               val->ival.zend.bval = 0;
+                       if (val->ival.zend.str) {
+                               zend_string *tmp = val->ival.zend.str;
+
+                               val->ival.zend.bval = (*tmp->val && *tmp->val != '0');
+                               zend_string_release(tmp);
                        }
                        val->ityp = PSI_T_UINT8;
+                       val->type = PSI_T_BOOL;
                        return true;
                default:
                        assert(0);
@@ -265,7 +222,8 @@ static inline bool psi_impl_def_val_validate_impl_type(struct psi_data *data,
                        return true;
                }
                psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, &val->ival);
-               val->type = val->ityp = PSI_T_INT64;
+               val->type = PSI_T_INT;
+               val->ityp = PSI_T_INT64;
                return true;
        case PSI_T_FLOAT:
        case PSI_T_DOUBLE:
@@ -292,9 +250,11 @@ static inline bool psi_impl_def_val_validate_impl_type(struct psi_data *data,
                        return true;
                } else {
                        smart_str str = {0};
+                       struct psi_dump dump = {{.hn = &str},
+                                       .fun = (psi_dump_cb) smart_str_append_printf};
 
                        switch (val->ityp) {
-                       CASE_IMPLVAL_NUM_PRINTF(smart_str_append_printf, &str, val->ival, false);
+                       CASE_IMPLVAL_NUM_DUMP(&dump, val->ival, false);
                        default:
                                assert(0);
                        }
@@ -348,97 +308,6 @@ bool psi_impl_def_val_validate(struct psi_data *data,
        }
 
        return false;
-/*
-       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->cpp);
-
-                       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;
-                       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;
-                               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->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) {
-                       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->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) {
-                       return true;
-               }
-               break;
-
-       case PSI_T_STRING:
-               if (val->type == PSI_T_STRING) {
-                       return true;            data->error(data, val->token, PSI_WARNING,
-                                       "Invalid default value type '%s', "
-                                       "expected one of bool, int, float, string.",
-                                       type ? type->name->val : "mixed");
-
-               }
-               break;
-
-       case PSI_T_MIXED:
-
-               }
-               // no break
-       default:
-       }
-*/
 }
 
 void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val) {
@@ -477,5 +346,7 @@ void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val)
        default:
                assert(0);
        }
-       PSI_DUMP(dump, "\t/* t=%d */ ", val->type);
+#if 0
+       PSI_DUMP(dump, "\t/* impl_def_val.type=%d */ ", val->type);
+#endif
 }
index 0e52318..48fdc78 100644 (file)
@@ -69,69 +69,72 @@ typedef union impl_val {
 #      define isnanl isnan
 #endif
 #if HAVE_LONG_DOUBLE
-#      define CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix) \
+#      define CASE_IMPLVAL_LD_DUMP(dump, ival, with_suffix) \
        case PSI_T_LONG_DOUBLE: \
                if (isinfl(ival.ldval)) { \
-                       fun(to, "\\INF"); \
+                       PSI_DUMP(dump, "\\INF"); \
                } else if (isnanl(ival.ldval)) { \
-                       fun(to, "\\NAN"); \
+                       PSI_DUMP(dump, "\\NAN"); \
                } else { \
-                       fun(to, "%" PRIldval "%s", ival.ldval, (with_suffix) ? "L" : ""); \
+                       /* bug in long double formatting of xbuf_fmt_conv? */ \
+                       char buf[0x100] = {0}; \
+                       snprintf(buf, sizeof(buf) - 1, "%" PRIldval, ival.ldval); \
+                       PSI_DUMP(dump, "%s%s", buf, (with_suffix) ? "L" : ""); \
                } \
-               break;
+               break
 #else
-#      define CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix)
+#      define CASE_IMPLVAL_LD_DUMP(dump, ival, with_suffix)
 #endif
 
-#define CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix) \
-       CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix); \
+#define CASE_IMPLVAL_FLOAT_DUMP(dump, ival, with_suffix) \
+       CASE_IMPLVAL_LD_DUMP(dump, ival, with_suffix); \
        case PSI_T_FLOAT: \
                if (isinf(ival.dval)) { \
-                       fun(to, "\\INF"); \
+                       PSI_DUMP(dump, "\\INF"); \
                } else if (isnan(ival.dval)) { \
-                       fun(to, "\\NAN"); \
+                       PSI_DUMP(dump, "\\NAN"); \
                } else { \
-                       fun(to, "%" PRIfval "%s", ival.dval, (with_suffix) ? "F" : ""); \
+                       PSI_DUMP(dump, "%" PRIfval "%s", ival.fval, (with_suffix) ? "F" : ""); \
                } \
                break; \
        case PSI_T_DOUBLE: \
                if (isinf(ival.dval)) { \
-                       fun(to, "\\INF"); \
+                       PSI_DUMP(dump, "\\INF"); \
                } else if (isnan(ival.dval)) { \
-                       fun(to, "\\NAN"); \
+                       PSI_DUMP(dump, "\\NAN"); \
                } else { \
-                       fun(to, "%" PRIdval, ival.dval); \
+                       PSI_DUMP(dump, "%" PRIdval, ival.dval); \
                } \
                break
 
-#define CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix) \
+#define CASE_IMPLVAL_INT_DUMP(dump, ival, with_suffix) \
        case PSI_T_INT8: \
-               fun(to, "%" PRId8, ival.i8); \
+               PSI_DUMP(dump, "%" PRId8, ival.i8); \
                break; \
        case PSI_T_UINT8: \
-               fun(to, "%" PRIu8, ival.u8); \
+               PSI_DUMP(dump, "%" PRIu8, ival.u8); \
                break; \
        case PSI_T_INT16: \
-               fun(to, "%" PRId16, ival.i16); \
+               PSI_DUMP(dump, "%" PRId16, ival.i16); \
                break; \
        case PSI_T_UINT16: \
-               fun(to, "%" PRIu16, ival.u16); \
+               PSI_DUMP(dump, "%" PRIu16, ival.u16); \
                break; \
        case PSI_T_INT32: \
-               fun(to, "%" PRId32, ival.i32); \
+               PSI_DUMP(dump, "%" PRId32, ival.i32); \
                break; \
        case PSI_T_UINT32: \
-               fun(to, "%" PRIu32 "%s", ival.u32, (with_suffix) ? "U" : ""); \
+               PSI_DUMP(dump, "%" PRIu32 "%s", ival.u32, (with_suffix) ? "U" : ""); \
                break; \
        case PSI_T_INT64: \
-               fun(to, "%" PRId64 "%s", ival.i64, (with_suffix) ? "L" : ""); \
+               PSI_DUMP(dump, "%" PRId64 "%s", ival.i64, (with_suffix) ? "L" : ""); \
                break; \
        case PSI_T_UINT64: \
-               fun(to, "%" PRIu64 "%s", ival.u64, (with_suffix) ? "UL" : ""); \
+               PSI_DUMP(dump, "%" PRIu64 "%s", ival.u64, (with_suffix) ? "UL" : ""); \
                break
 
-#define CASE_IMPLVAL_NUM_PRINTF(fun, to, ival, with_suffix) \
-       CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix); \
-       CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix)
+#define CASE_IMPLVAL_NUM_DUMP(dump, ival, with_suffix) \
+       CASE_IMPLVAL_INT_DUMP(dump, ival, with_suffix); \
+       CASE_IMPLVAL_FLOAT_DUMP(dump, ival, with_suffix)
 
 #endif
index 9388ad3..0053a23 100644 (file)
@@ -391,6 +391,7 @@ void psi_num_exp_dump(struct psi_dump *dump, struct psi_num_exp *exp)
                PSI_DUMP(dump, "(");
                psi_decl_type_dump(dump, exp->data.c.typ, 0);
                PSI_DUMP(dump, ")");
+               psi_num_exp_dump(dump, exp->data.c.num);
                break;
 
        case PSI_T_NOT:
index 7c05c85..c3ec31b 100644 (file)
@@ -296,17 +296,19 @@ void psi_number_dump(struct psi_dump *dump, struct psi_number *exp)
 {
        switch (exp->type) {
        case PSI_T_DEFINED:
-       CASE_IMPLVAL_NUM_PRINTF(dump->fun, dump->ctx, exp->data.ival, 1);
+       CASE_IMPLVAL_NUM_DUMP(dump, exp->data.ival, true);
        case PSI_T_NULL:
                PSI_DUMP(dump, "NULL");
                break;
        case PSI_T_NUMBER:
        case PSI_T_NSNAME:
-       case PSI_T_DEFINE:
        case PSI_T_QUOTED_CHAR:
        case PSI_T_CPP_HEADER:
                PSI_DUMP(dump, "%s", exp->data.numb->val);
                break;
+       case PSI_T_DEFINE:
+               PSI_DUMP(dump, "%s /* DEFINE */", exp->data.numb->val);
+               break;
        case PSI_T_FUNCTION:
                psi_cpp_macro_call_dump(dump, exp->data.call);
                break;
@@ -314,7 +316,7 @@ void psi_number_dump(struct psi_dump *dump, struct psi_number *exp)
                PSI_DUMP(dump, "%s", exp->data.cnst->name->val);
                break;
        case PSI_T_ENUM:
-               PSI_DUMP(dump, "%s", exp->data.enm->name->val);
+               PSI_DUMP(dump, "%s /* ENUM */ ", exp->data.enm->name->val);
                break;
        case PSI_T_NAME:
                psi_decl_var_dump(dump, exp->data.dvar);
@@ -327,6 +329,9 @@ void psi_number_dump(struct psi_dump *dump, struct psi_number *exp)
        default:
                assert(0);
        }
+#if 0
+       PSI_DUMP(dump, "\t/* number.type=%d */ ", exp->type);
+#endif
 }
 
 static inline bool psi_number_validate_enum(struct psi_data *data,
@@ -620,10 +625,10 @@ bool psi_number_validate(struct psi_data *data, struct psi_number *exp,
                return true;
 
        case PSI_T_NAME:
-               if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
-                       exp->type = PSI_T_DEFINE;
-                       goto define;
-               }
+               //if (scope && scope->cpp && zend_hash_exists(&scope->cpp->defs, exp->data.dvar->name)) {
+               //      exp->type = PSI_T_DEFINE;
+               //      goto define;
+               //}
                if (scope && scope->current_enum && psi_number_validate_enum(data, exp, scope)) {
                        return true;
                }
index 441bec3..0f17beb 100644 (file)
@@ -17,7 +17,7 @@ fclose($fd);
 var_dump(file_exists($fn));
 var_dump(psi_validate($fn, 0, $e), $e);
 
-@unlink(__DIR__."/dump001.psi");
+#@unlink(__DIR__."/dump001.psi");
 
 ?>
 ===DONE===
@@ -29,5 +29,5 @@ int(%d)
 ===DONE===
 --CLEAN--
 <?php
-@unlink(__DIR__."/dump001.psi");
+#@unlink(__DIR__."/dump001.psi");
 ?>