From: Michael Wallner Date: Wed, 21 Nov 2018 13:16:17 +0000 (+0100) Subject: fix float formats; fix sime defval edge cases X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=commitdiff_plain;h=d9f1274417f65d980e143700726d1527462123d3 fix float formats; fix sime defval edge cases --- diff --git a/src/calc.h b/src/calc.h index 6361ce8..3aa949c 100644 --- a/src/calc.h +++ b/src/calc.h @@ -29,9 +29,15 @@ #include "token.h" #include "types/impl_val.h" -#define PRIfval ".6g" -#define PRIdval ".16g" -#define PRIldval ".29Lg" +#include + +#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); diff --git a/src/data.c b/src/data.c index 9bcd493..e09c472 100644 --- a/src/data.c +++ b/src/data.c @@ -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"); } diff --git a/src/parser.c b/src/parser.c index cf576d5..2402816 100644 --- a/src/parser.c +++ b/src/parser.c @@ -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); diff --git a/src/types/decl_enum.c b/src/types/decl_enum.c index 68d644a..df35339 100644 --- a/src/types/decl_enum.c +++ b/src/types/decl_enum.c @@ -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; diff --git a/src/types/impl_def_val.c b/src/types/impl_def_val.c index 8b2d37b..e8d7b46 100644 --- a/src/types/impl_def_val.c +++ b/src/types/impl_def_val.c @@ -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 } diff --git a/src/types/impl_val.h b/src/types/impl_val.h index 0e52318..48fdc78 100644 --- a/src/types/impl_val.h +++ b/src/types/impl_val.h @@ -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 diff --git a/src/types/num_exp.c b/src/types/num_exp.c index 9388ad3..0053a23 100644 --- a/src/types/num_exp.c +++ b/src/types/num_exp.c @@ -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: diff --git a/src/types/number.c b/src/types/number.c index 7c05c85..c3ec31b 100644 --- a/src/types/number.c +++ b/src/types/number.c @@ -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; } diff --git a/tests/parser/dump001.phpt b/tests/parser/dump001.phpt index 441bec3..0f17beb 100644 --- a/tests/parser/dump001.phpt +++ b/tests/parser/dump001.phpt @@ -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--