commit after reset fuckup
authorMichael Wallner <mike@php.net>
Tue, 20 Nov 2018 14:33:57 +0000 (15:33 +0100)
committerMichael Wallner <mike@php.net>
Tue, 4 Dec 2018 11:13:48 +0000 (12:13 +0100)
86 files changed:
.gdbinit
php_psi.h
src/call.c
src/context.c
src/cpp.c
src/cpp.h
src/cpp_tokiter.c
src/data.c
src/data.h
src/error.h
src/marshal.c
src/marshal.h
src/module.c
src/parser.c
src/token.c
src/token.h
src/types/assert_stmt.c
src/types/assert_stmt.h
src/types/const.c
src/types/const.h
src/types/cpp_exp.c
src/types/cpp_exp.h
src/types/cpp_macro_call.c
src/types/cpp_macro_call.h
src/types/cpp_macro_decl.c
src/types/cpp_macro_decl.h
src/types/decl.c
src/types/decl.h
src/types/decl_abi.c
src/types/decl_abi.h
src/types/decl_arg.h
src/types/decl_enum.c
src/types/decl_enum.h
src/types/decl_enum_item.c
src/types/decl_enum_item.h
src/types/decl_extvar.c
src/types/decl_extvar.h
src/types/decl_struct.c
src/types/decl_struct.h
src/types/decl_type.c
src/types/decl_type.h
src/types/decl_union.c
src/types/decl_union.h
src/types/decl_var.c
src/types/decl_var.h
src/types/free_exp.c
src/types/free_exp.h
src/types/free_stmt.c
src/types/free_stmt.h
src/types/impl.c
src/types/impl.h
src/types/impl_arg.c
src/types/impl_arg.h
src/types/impl_def_val.c
src/types/impl_def_val.h
src/types/impl_func.c
src/types/impl_func.h
src/types/impl_type.c
src/types/impl_type.h
src/types/impl_val.h
src/types/impl_var.c
src/types/impl_var.h
src/types/let_callback.c
src/types/let_callback.h
src/types/let_calloc.c
src/types/let_calloc.h
src/types/let_exp.c
src/types/let_exp.h
src/types/let_func.c
src/types/let_func.h
src/types/let_stmt.c
src/types/let_stmt.h
src/types/num_exp.c
src/types/num_exp.h
src/types/number.c
src/types/number.h
src/types/return_exp.c
src/types/return_exp.h
src/types/return_stmt.c
src/types/return_stmt.h
src/types/set_exp.c
src/types/set_exp.h
src/types/set_func.c
src/types/set_func.h
src/types/set_stmt.c
src/types/set_stmt.h

index 3956ad1..9aad1bc 100644 (file)
--- a/.gdbinit
+++ b/.gdbinit
@@ -40,7 +40,7 @@ define psi_decl_type_dump
 end
 define psi_decl_type_dump_args_with_layout
        call psi_decl_type_dump_args_with_layout(1, $arg0, 0)
-        echo \n
+       echo \n
 end
 define psi_decl_union_dump
        call psi_decl_union_dump(1, $arg0)
index 01582c5..8d7649c 100644 (file)
--- a/php_psi.h
+++ b/php_psi.h
@@ -50,6 +50,51 @@ static inline int psi_check_env(const char *var) {
        return (set && *set && (*set != '0' || set[1]));
 }
 
+#include "php_network.h"
+
+static inline int psi_fdopen(const char *desc)
+{
+       int fd = -1;
+
+       if (desc) {
+               char *addr = strstr(desc, "://");
+
+               if (addr) {
+                       addr += 3;
+               }
+               if (addr && *addr) {
+                       struct sockaddr_storage sa = {0};
+                       socklen_t ss = 0;
+                       int rc = php_network_parse_network_address_with_port(addr,
+                                       strlen(addr), (struct sockaddr *) &sa, &ss);
+
+                       if (SUCCESS == rc) {
+                               int styp = strncmp(desc, "udp:", 4)
+                                               ? SOCK_STREAM
+                                               : SOCK_DGRAM;
+                               int sfam = sa.ss_family == AF_INET6
+                                               ? ((struct sockaddr_in6 *) &sa)->sin6_family
+                                               : ((struct sockaddr_in *) &sa)->sin_family;
+
+                               fd = socket(sfam, styp, 0);
+
+                               if (fd > 0 && 0 != connect(fd, (struct sockaddr *) &sa, ss)) {
+                                       perror(desc);
+                                       close(fd);
+                                       fd = -1;
+                               }
+                       }
+               } else if (!strcmp(desc, "stdout")) {
+                       fd = STDOUT_FILENO;
+               } else if (!strcmp(desc, "stderr")) {
+                       fd = STDERR_FILENO;
+               } else if (!(fd = atoi(desc)) || -1 == fcntl(fd, F_GETFD)) {
+                       fd = open(desc, O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0664);
+               }
+       }
+       return fd;
+}
+
 typedef struct psi_object {
        void *data;
        void (*dtor)(void *data);
index 22516c7..57b57f0 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "php.h"
 #include "zend_exceptions.h"
-#include "ext/spl/spl_exceptions.h"
 
 struct psi_call_frame_argument *psi_call_frame_argument_init(struct psi_impl_arg *spec,
                impl_val *ival, zval *zptr, int is_vararg) {
@@ -427,11 +426,7 @@ ZEND_RESULT_CODE psi_call_frame_do_assert(struct psi_call_frame *frame, enum psi
        while (psi_plist_get(frame->impl->stmts.ass, i++, &ass)) {
                if (ass->kind == kind) {
                        if (!psi_assert_stmt_exec(ass, frame)) {
-                               char *message = psi_assert_stmt_message(ass);
-                               zend_throw_exception(kind == PSI_ASSERT_PRE
-                                               ? spl_ce_InvalidArgumentException
-                                               : spl_ce_UnexpectedValueException, message, 0);
-                               free(message);
+                               psi_assert_stmt_throw(ass);
                                return FAILURE;
                        }
                }
index be8bae9..febe0bb 100644 (file)
@@ -235,29 +235,7 @@ zend_function_entry *psi_context_compile(struct psi_context *C)
                        }
 
                        zc.name = zend_string_copy(c->name);
-
-                       switch (c->type ? c->type->type : c->val->type) {
-                       case PSI_T_BOOL:
-                               ZVAL_BOOL(&zc.value, c->val->ival.zend.bval);
-                               break;
-                       case PSI_T_INT:
-                               ZVAL_LONG(&zc.value, c->val->ival.zend.lval);
-                               break;
-                       case PSI_T_FLOAT:
-                       case PSI_T_DOUBLE:
-                               ZVAL_DOUBLE(&zc.value, c->val->ival.dval);
-                               break;
-                       case PSI_T_STRING:
-                       case PSI_T_QUOTED_STRING:
-                               ZVAL_NEW_STR(&zc.value, zend_string_copy(c->val->ival.zend.str));
-                               if (ZSTR_IS_INTERNED(Z_STR(zc.value))) {
-                                       Z_TYPE_FLAGS(zc.value) = 0;
-                               }
-                               break;
-                       default:
-                               assert(0);
-                               break;
-                       }
+                       psi_impl_def_val_get_zval(c->val, c->type ? c->type->type : PSI_T_MIXED , &zc.value);
 
                        zend_register_constant(&zc);
                }
@@ -380,8 +358,6 @@ void psi_context_free(struct psi_context **C)
 
 void psi_context_dump(struct psi_dump *dump, struct psi_context *C)
 {
-       size_t i;
-
        PSI_DUMP(dump, "// psi.engine=%s\n// %lu files\n",
                        (char *) C->ops->query(C, PSI_CONTEXT_QUERY_SELF, NULL),
                        C->count);
@@ -390,8 +366,10 @@ void psi_context_dump(struct psi_dump *dump, struct psi_context *C)
 
 #if 0
        if (C->flags & PSI_DEBUG) {
+               size_t i;
+
                for (i = 0; i < C->count; ++i) {
-                       psi_data_dump(fd, &C->data[i]);
+                       psi_data_dump(dump, &C->data[i]);
                }
        }
 #endif
index 4982c78..9daca1b 100644 (file)
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -114,28 +114,11 @@ static char *include_flavor[] = {
                "include once"
 };
 
-#if PSI_CPP_DEBUG > 1
-static int dump_def(zval *p)
-{
-       struct psi_cpp_macro_decl *decl = Z_PTR_P(p);
-
-       if (decl) {
-               dprintf(2, "PSI: CPP decl -> #define ");
-               psi_cpp_macro_decl_dump(2, decl);
-               dprintf(2, "\n");
-       }
-       return ZEND_HASH_APPLY_KEEP;
-}
-#endif
-
 void psi_cpp_free(struct psi_cpp **cpp_ptr)
 {
        if (*cpp_ptr) {
                struct psi_cpp *cpp = *cpp_ptr;
 
-#if PSI_CPP_DEBUG > 1
-               zend_hash_apply(&cpp->defs, dump_def);
-#endif
                *cpp_ptr = NULL;
                zend_hash_destroy(&cpp->defs);
                zend_hash_destroy(&cpp->once);
index ed766e3..671d2da 100644 (file)
--- a/src/cpp.h
+++ b/src/cpp.h
@@ -29,7 +29,7 @@
 #include "data.h"
 
 #ifndef PSI_CPP_DEBUG
-# define PSI_CPP_DEBUG 1
+# define PSI_CPP_DEBUG 0
 #endif
 
 struct psi_cpp {
@@ -68,7 +68,7 @@ bool psi_cpp_include(struct psi_cpp *cpp, const struct psi_token *file, unsigned
 void psi_cpp_tokiter_reset(struct psi_cpp *cpp);
 bool psi_cpp_tokiter_seek(struct psi_cpp *cpp, size_t index);
 #if PSI_CPP_DEBUG > 1
-void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp);
+void psi_cpp_tokiter_dump(struct psi_dump *dump, struct psi_cpp *cpp);
 #endif
 struct psi_token *psi_cpp_tokiter_current(struct psi_cpp *cpp);
 size_t psi_cpp_tokiter_index(struct psi_cpp *cpp);
index c2bcb95..4f9eee3 100644 (file)
@@ -28,7 +28,7 @@
 #include "cpp.h"
 #include "parser.h"
 
-void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp)
+void psi_cpp_tokiter_dump(struct psi_dump *dump, struct psi_cpp *cpp)
 {
        size_t i = cpp->index;
        struct psi_token *T;
@@ -39,14 +39,14 @@ void psi_cpp_tokiter_dump(int fd, struct psi_cpp *cpp)
                i = 0;
        }
        while (psi_plist_get(cpp->tokens.iter, i, &T)) {
-               dprintf(fd, "PSI: CPP tokens %5zu %c ", i, cpp->index == i ? '*' : ' ');
+               PSI_DUMP(dump, "PSI: CPP tokens %5zu %c ", i, cpp->index == i ? '*' : ' ');
                if (T) {
-                       psi_token_dump(fd, T);
+                       psi_token_dump(dump, T);
                } else {
-                       dprintf(fd, "TOKEN deleted\n");
+                       PSI_DUMP(dump, "TOKEN deleted\n");
                }
                if (i >= cpp->index + 40) {
-                       dprintf(fd, "PSI: CPP tokens .....\n");
+                       PSI_DUMP(dump, "PSI: CPP tokens .....\n");
                        break;
                }
                ++i;
index 0fb9816..fb94d30 100644 (file)
@@ -27,7 +27,6 @@
 #include "data.h"
 
 #include "php_globals.h"
-#include "php_network.h"
 
 #include <dlfcn.h>
 #include <ctype.h>
@@ -39,50 +38,12 @@ static void psi_data_ctor_internal(struct psi_data *data,
        data->flags = flags;
 
        if (data->flags & PSI_DEBUG) {
-               char *debug = getenv("PSI_DEBUG");
+               int fd = psi_fdopen(getenv("PSI_DEBUG"));
 
-               if (debug) {
-                       int fd = -1;
-                       char *addr = strstr(debug, "://");
-
-                       if (addr) {
-                               addr += 3;
-                       }
-                       if (addr && *addr) {
-                               struct sockaddr_storage sa = {0};
-                               socklen_t ss = 0;
-                               int rc = php_network_parse_network_address_with_port(addr,
-                                               strlen(addr), (struct sockaddr *) &sa, &ss);
-
-                               if (SUCCESS == rc) {
-                                       int styp = strncmp(debug, "udp:", 4)
-                                                       ? SOCK_STREAM
-                                                       : SOCK_DGRAM;
-                                       int sfam = sa.ss_family == AF_INET6
-                                                       ? ((struct sockaddr_in6 *) &sa)->sin6_family
-                                                       : ((struct sockaddr_in *) &sa)->sin_family;
-
-                                       fd = socket(sfam, styp, 0);
-
-                                       if (fd > 0 && 0 != connect(fd, (struct sockaddr *) &sa, ss)) {
-                                               perror(debug);
-                                               close(fd);
-                                               fd = -1;
-                                       }
-                               }
-                       } else if (!strcmp(debug, "stdout")) {
-                               fd = STDOUT_FILENO;
-                       } else if (!strcmp(debug, "stderr")) {
-                               fd = STDERR_FILENO;
-                       } else if (!(fd = atoi(debug))) {
-                               fd = open(debug, O_WRONLY|O_APPEND|O_CREAT|O_CLOEXEC, 0664);
-                       }
-
-                       if (fd > 0) {
-                               data->debug_fd = fd;
-                       } else {
-                               data->debug_fd = STDERR_FILENO;
-                       }
+               if (fd > 0) {
+                       data->debug_fd = fd;
+               } else {
+                       data->debug_fd = STDERR_FILENO;
                }
        }
 }
@@ -244,7 +205,7 @@ void psi_data_dump(struct psi_dump *dump, struct psi_data *D)
 
                while (psi_plist_get(D->unions, i++, &unn)) {
                        if (!psi_decl_type_is_anon(unn->name, "union")) {
-                               psi_decl_union_dump(fd, unn);
+                               psi_decl_union_dump(dump, unn);
                                PSI_DUMP(dump, "\n");
                        }
                }
index 1d8414f..ca7bf90 100644 (file)
 #include "plist.h"
 #include "validate.h"
 
-#define PSI_DEBUG 0x1
-#define PSI_SILENT 0x2
+#include "php_network.h"
 
 #include <stdarg.h>
 #include <dlfcn.h>
 
+#define PSI_DEBUG 0x1
+#define PSI_SILENT 0x2
+
 #ifndef RTLD_NEXT
 # define RTLD_NEXT ((void *) -1l)
 #endif
@@ -80,7 +82,9 @@ again:
 } while(0)
 #define PSI_DEBUG_DUMP(ctx, dump_func, ...) do { \
        if ((ctx) && (PSI_DATA(ctx)->flags & PSI_DEBUG)) { \
-               dump_func(PSI_DATA(ctx)->debug_fd, __VA_ARGS__); \
+               struct psi_dump dump_ = {{ .fd = PSI_DATA(ctx)->debug_fd}, \
+                               .fun = (psi_dump_cb) dprintf}; \
+               dump_func(&dump_, __VA_ARGS__); \
        } \
 } while (0)
 
@@ -121,6 +125,6 @@ struct psi_data *psi_data_ctor(struct psi_data *data, psi_error_cb error, unsign
 struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data, psi_error_cb error, unsigned flags);
 struct psi_data *psi_data_exchange(struct psi_data *dest, struct psi_data *src);
 void psi_data_dtor(struct psi_data *data);
-void psi_data_dump(int fd, struct psi_data *data);
+void psi_data_dump(struct psi_dump *dump, struct psi_data *data);
 
 #endif
index ebbd60b..c155d39 100644 (file)
@@ -41,9 +41,4 @@ void psi_error_wrapper(struct psi_data *context, struct psi_token *t, int type,
 void psi_error(int type, const char *fn, unsigned ln, const char *msg, ...);
 void psi_verror(int type, const char *fn, unsigned ln, const char *msg, va_list argv);
 
-union psi_debug_ctx {
-       FILE *stdio;
-       int socket;
-};
-
 #endif /* PSI_ERROR_H */
index 14f0dca..ff1ddcc 100644 (file)
@@ -226,52 +226,6 @@ impl_val *psi_let_boolval(impl_val *tmp, struct psi_decl_arg *spec, token_t impl
        return psi_val_boolval(tmp, real_type, boolval);
 }
 
-#if HAVE_INT128
-static inline char *psi_u128_to_buf(char *buf, unsigned __int128 u128)
-{
-       for (*buf = 0; u128 > 0; u128 /= 10) {
-               *--buf = ((u128 % 10) + '0') & 0xff;
-       }
-       return buf;
-}
-
-static inline char *psi_i128_to_buf(char *buf, __int128 i128)
-{
-       if (i128 < 0) {
-               char *res = psi_u128_to_buf(buf, ~((unsigned __int128) i128) + 1);
-
-               *--res = '-';
-               return res;
-       }
-       return psi_u128_to_buf(buf, i128);
-}
-
-# define RETVAL_LONG_STR(V, s) do {\
-               char buf[0x30] = {0}; \
-               if (s && V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \
-                       RETVAL_LONG(V); \
-               } else if (!s && V <= ZEND_LONG_MAX) { \
-                       RETVAL_LONG(V); \
-               } else if (!s && V <= ZEND_ULONG_MAX) { \
-                       RETVAL_STRING(zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \
-               } else if (s && V >= INT128_MIN && V <= INT128_MAX) { \
-                       RETVAL_STRING(psi_i128_to_buf(&buf[sizeof(buf) - 1], V)); \
-               } else { \
-                       RETVAL_STRING(psi_u128_to_buf(&buf[sizeof(buf) - 1], V)); \
-               } \
-       } while (0)
-#else
-# define RETVAL_LONG_STR(V, s) do {\
-               char buf[0x20] = {0}; \
-               if (s && V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \
-                       RETVAL_LONG(V); \
-               } else if (!s && V <= ZEND_LONG_MAX) { \
-                       RETVAL_LONG(V); \
-               } else { \
-                       RETVAL_STRING(zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \
-               } \
-       } while (0)
-#endif
 /*
  * set $ivar = to_int(*dvar)
  */
@@ -290,10 +244,10 @@ void psi_set_to_int(zval *return_value, struct psi_set_exp *set, impl_val *ret_v
        case PSI_T_INT32:               RETVAL_LONG(v->i32);                            break;
        case PSI_T_UINT32:              RETVAL_LONG(v->u32);                            break;
        case PSI_T_INT64:               RETVAL_LONG(v->i64);                            break;
-       case PSI_T_UINT64:              RETVAL_LONG_STR(v->u64, 0);                     break;
+       case PSI_T_UINT64:              RETVAL_LONG_DOUBLE_STR(v->u64,);        break;
 #ifdef HAVE_INT128
-       case PSI_T_INT128:              RETVAL_LONG_STR(v->i128, 1);            break;
-       case PSI_T_UINT128:             RETVAL_LONG_STR(v->u128, 0);            break;
+       case PSI_T_INT128:              RETVAL_LONG_DOUBLE_STR(v->i128, is_signed=true);        break;
+       case PSI_T_UINT128:             RETVAL_LONG_DOUBLE_STR(v->u128,);       break;
 #endif
        case PSI_T_FLOAT:
                RETVAL_DOUBLE((double) v->fval);
index be5b3c6..a7777d3 100644 (file)
@@ -36,6 +36,60 @@ struct psi_call_frame;
 struct psi_impl;
 struct psi_impl_type;
 
+#if HAVE_INT128
+static inline char *psi_u128_to_buf(char *buf, unsigned __int128 u128)
+{
+       for (*buf = 0; u128 > 0; u128 /= 10) {
+               *--buf = ((u128 % 10) + '0') & 0xff;
+       }
+       return buf;
+}
+
+static inline char *psi_i128_to_buf(char *buf, __int128 i128)
+{
+       if (i128 < 0) {
+               char *res = psi_u128_to_buf(buf, ~((unsigned __int128) i128) + 1);
+
+               *--res = '-';
+               return res;
+       }
+       return psi_u128_to_buf(buf, i128);
+}
+#else
+# define psi_u128_to_buf(b,u) zend_print_ulong_to_buf(b,u)
+# define psi_i128_to_buf(b,i) zend_print_long_to_buf(b,i)
+#endif
+
+
+#define RETVAL_LONG_DOUBLE_STR(V, flags) ZVAL_LONG_DOUBLE_STR(return_value, V, flags)
+# define ZVAL_LONG_DOUBLE_STR(z, V, flags) do { \
+       char buf[0x20] = {0}; \
+       bool is_signed = false, persistent = false; \
+       flags; \
+       if (is_signed) { \
+               if (V >= ZEND_LONG_MIN && V <= ZEND_LONG_MAX) { \
+                       ZVAL_LONG(z, V); \
+               } else if (V >= -(1L<<52) && V <= (1L<<53)) { \
+                       ZVAL_DOUBLE(z, V); \
+               } else if (V < ZEND_LONG_MIN || V > ZEND_LONG_MAX) { \
+                       ZVAL_STRING(z, psi_i128_to_buf(&buf[sizeof(buf) - 1], V)); \
+               } else { \
+                       ZVAL_STRING(z, zend_print_long_to_buf(&buf[sizeof(buf) - 1], V)); \
+               } \
+       } else { \
+               if (V <= ZEND_LONG_MAX) { \
+                       ZVAL_LONG(z, V); \
+               } else if (V <= (1L<<53)) { \
+                       ZVAL_DOUBLE(z, V); \
+               } else if (V > ZEND_ULONG_MAX) { \
+                       ZVAL_STRING(z, psi_u128_to_buf(&buf[sizeof(buf) - 1], V)); \
+               } else { \
+                       ZVAL_STRING(z, zend_print_ulong_to_buf(&buf[sizeof(buf) - 1], V)); \
+               } \
+       } \
+} while (0)
+
+
 zend_long psi_zval_count(zval *zvalue);
 zend_internal_arg_info *psi_internal_arginfo(struct psi_impl *impl);
 int psi_internal_type(struct psi_impl_type *type);
index 0edd74f..08db814 100644 (file)
@@ -166,19 +166,18 @@ static PHP_FUNCTION(psi_dump)
 {
        php_stream *s;
        zval *r = NULL;
-       int fd = STDOUT_FILENO;
+       struct psi_dump dump = {.fun = php_stream_printf};
 
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &r)) {
                return;
        }
        if (r) {
                php_stream_from_zval(s, r);
-
-               if (SUCCESS != php_stream_cast(s, PHP_STREAM_AS_FD | PHP_STREAM_CAST_INTERNAL, (void **)&fd, 1)) {
-                       RETURN_FALSE;
-               }
+               dump.ctx.hn = s;
+       } else {
+               dump.ctx.hn = php_stream_open_wrapper("php://output", "w", REPORT_ERRORS, NULL);
        }
-       psi_context_dump(PSI_G(context), fd);
+       psi_context_dump(&dump, PSI_G(context));
 }
 
 ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate, 0, 0, 1)
index e747ed2..9475ff9 100644 (file)
@@ -145,7 +145,7 @@ static inline zend_string *macro_to_constant(struct psi_parser *parser,
        size_t i = 0;
        struct psi_token *tok;
 
-       smart_str_append_printf(&str, "\nconst psi\\%s = ", name->val);
+       smart_str_append_printf(&str, "const psi\\%s = ", name->val);
        if (scope->macro->exp) {
                impl_val res = {0};
                token_t typ = psi_num_exp_exec(scope->macro->exp, &res, NULL, scope->cpp);
@@ -179,7 +179,7 @@ void psi_parser_postprocess(struct psi_parser *P)
        scope.cpp = P->preproc;
 
        flags = P->flags;
-       //P->flags |= PSI_SILENT;
+       P->flags |= PSI_SILENT;
 
        ZEND_HASH_FOREACH_STR_KEY_PTR(&P->preproc->defs, name, scope.macro)
        {
index 7b303e7..1b4cc5e 100644 (file)
@@ -48,7 +48,7 @@ struct psi_token *psi_token_init(token_t token_typ, const char *token_txt,
        T->file = zend_string_copy(file);
        T->text = zend_string_init_interned(token_txt, token_len, 1);
 #if PSI_DEBUG_TOKEN_ALLOC
-       fprintf(stderr, "PSI: token_init %p\n", T);
+       PSI_DEBUG_PRINT(cpp->parser, "PSI: token_init %p\n", T);
 #endif
        return T;
 }
@@ -57,7 +57,7 @@ void psi_token_free(struct psi_token **token_ptr) {
        if (*token_ptr) {
                struct psi_token *token = *token_ptr;
 #if PSI_DEBUG_TOKEN_ALLOC
-               fprintf(stderr, "PSI: token_free %p\n", token);
+               PSI_DEBUG_PRINT(cpp->parser, "PSI: token_free %p\n", token);
 #endif
                *token_ptr = NULL;
                zend_string_release(token->text);
@@ -71,7 +71,7 @@ struct psi_token *psi_token_copy(struct psi_token *src) {
 
        *ptr = *src;
 #if PSI_DEBUG_TOKEN_ALLOC
-       fprintf(stderr, "PSI: token_copy %p <= %p\n", ptr, src);
+       PSI_DEBUG_PRINT(cpp->parser, "PSI: token_copy %p <= %p\n", ptr, src);
 #endif
        ptr->text = zend_string_copy(ptr->text);
        ptr->file = zend_string_copy(ptr->file);
@@ -110,7 +110,7 @@ struct psi_token *psi_token_cat(const char *sep, unsigned argc, ...) {
        T->text = smart_str_extract(&text);
 
 #if PSI_DEBUG_TOKEN_ALLOC
-       fprintf(stderr, "PSI: token_cat  %p\n", T);
+       PSI_DEBUG_PRINT(cpp->parser, "PSI: token_cat  %p\n", T);
 #endif
        return T;
 }
@@ -185,54 +185,54 @@ uint64_t psi_token_hash(struct psi_token *t, char *digest_buf) {
        return psi_hash(digest_buf, t->file->val, loc_buf, (char *) NULL);
 }
 
-void psi_token_dump(int fd, struct psi_token *t)
+void psi_token_dump(struct psi_dump *dump, struct psi_token *t)
 {
        size_t i;
 
-       dprintf(fd, "TOKEN %p (%u) ", t, t->type);
+       PSI_DUMP(dump, "TOKEN %p (%u) ", t, t->type);
        if (t->type == PSI_T_EOF) {
-               dprintf(fd, "EOF");
+               PSI_DUMP(dump, "EOF");
        } else {
-               dprintf(fd, "\"");
+               PSI_DUMP(dump, "\"");
                for (i = 0; i < t->text->len; ++i) {
                        switch (t->text->val[i]) {
                        case '\0':
-                               dprintf(fd, "\\0");
+                               PSI_DUMP(dump, "\\0");
                                break;
                        case '\a':
-                               dprintf(fd, "\\a");
+                               PSI_DUMP(dump, "\\a");
                                break;
                        case '\b':
-                               dprintf(fd, "\\b");
+                               PSI_DUMP(dump, "\\b");
                                break;
                        case '\f':
-                               dprintf(fd, "\\f");
+                               PSI_DUMP(dump, "\\f");
                                break;
                        case '\n':
-                               dprintf(fd, "\\n");
+                               PSI_DUMP(dump, "\\n");
                                break;
                        case '\r':
-                               dprintf(fd, "\\r");
+                               PSI_DUMP(dump, "\\r");
                                break;
                        case '\t':
-                               dprintf(fd, "\\t");
+                               PSI_DUMP(dump, "\\t");
                                break;
                        case '\v':
-                               dprintf(fd, "\\v");
+                               PSI_DUMP(dump, "\\v");
                                break;
                        case '"':
-                               dprintf(fd, "\\\"");
+                               PSI_DUMP(dump, "\\\"");
                                break;
                        default:
                                if (isprint(t->text->val[i])) {
-                                       dprintf(fd, "%c", t->text->val[i]);
+                                       PSI_DUMP(dump, "%c", t->text->val[i]);
                                } else {
-                                       dprintf(fd, "\\x%02hhX", t->text->val[i]);
+                                       PSI_DUMP(dump, "\\x%02hhX", t->text->val[i]);
                                }
                                break;
                        }
                }
-               dprintf(fd, "\"");
+               PSI_DUMP(dump, "\"");
        }
-       dprintf(fd, " at col %u in %s on line %u\n", t->col, t->file->val, t->line);
+       PSI_DUMP(dump, " at col %u in %s on line %u\n", t->col, t->file->val, t->line);
 }
index 368fba9..e87a16d 100644 (file)
@@ -174,6 +174,8 @@ static inline const char *psi_t_indirection(unsigned pointer_level) {
        return &indir[32 - MIN(32, pointer_level)];
 }
 
+struct psi_dump;
+
 struct psi_token {
        token_t type;
        unsigned line;
@@ -193,7 +195,7 @@ struct psi_token *psi_token_cat(const char *sep, unsigned argc, ...);
 struct psi_token *psi_token_append(const char *sep, struct psi_token *T, unsigned argc, ...);
 struct psi_token *psi_token_translit(struct psi_token *T, char *from, char *to);
 uint64_t psi_token_hash(struct psi_token *t, char *digest_buf);
-void psi_token_dump(int fd, struct psi_token *t);
+void psi_token_dump(struct psi_dump *dump, struct psi_token *t);
 void psi_token_free(struct psi_token **token);
 
 #endif
index e65efae..6909191 100644 (file)
 #include "data.h"
 #include "calc.h"
 
+#include "zend_smart_str.h"
+#include "zend_exceptions.h"
+#include "ext/spl/spl_exceptions.h"
+
 struct psi_assert_stmt *psi_assert_stmt_init(enum psi_assert_kind kind, struct psi_num_exp *exp)
 {
        struct psi_assert_stmt *stmt = pecalloc(1, sizeof(*stmt), 1);
@@ -50,11 +54,11 @@ void psi_assert_stmt_free(struct psi_assert_stmt **stmt_ptr)
        }
 }
 
-void psi_assert_stmt_dump(int fd, struct psi_assert_stmt *stmt)
+void psi_assert_stmt_dump(struct psi_dump *dump, struct psi_assert_stmt *stmt)
 {
-       dprintf(fd, "\t%s_assert ", stmt->kind == PSI_ASSERT_PRE ? "pre" : "post");
-       psi_num_exp_dump(fd, stmt->exp);
-       dprintf(fd, ";\n");
+       PSI_DUMP(dump, "\t%s_assert ", stmt->kind == PSI_ASSERT_PRE ? "pre" : "post");
+       psi_num_exp_dump(dump, stmt->exp);
+       PSI_DUMP(dump, ";\n");
 }
 
 bool psi_assert_stmt_exec(struct psi_assert_stmt *stmt, struct psi_call_frame *frame)
@@ -81,20 +85,20 @@ bool psi_assert_stmts_validate(struct psi_data *data, struct psi_validate_scope
        return true;
 }
 
-char *psi_assert_stmt_message(struct psi_assert_stmt *stmt)
+void psi_assert_stmt_throw(struct psi_assert_stmt *stmt)
 {
-       /* FIXME */
-       struct stat sb;
-       char *message, template[] = "psi.assert.XXXXXX";
-       int fd = mkstemp(template);
-
-       dprintf(fd, "Failed asserting that ");
-       psi_num_exp_dump(fd, stmt->exp);
-       fstat(fd, &sb);
-       message = pemalloc(sb.st_size + 1, 1);
-       lseek(fd, 0, SEEK_SET);
-       read(fd, message, sb.st_size);
-       close(fd);
-       message[sb.st_size] = '\0';
-       return message;
+       struct psi_dump dump;
+       smart_str str = {0};
+       zend_string *message;
+
+       dump.ctx.hn = &str;
+       dump.fun = (psi_dump_cb) smart_str_append_printf;
+
+       PSI_DUMP(&dump, "Failed asserting that ");
+       psi_num_exp_dump(&dump, stmt->exp);
+       smart_str_0(&str);
+       zend_throw_exception(stmt->kind == PSI_ASSERT_PRE
+                       ? spl_ce_InvalidArgumentException
+                       : spl_ce_UnexpectedValueException, str.s->val, 0);
+       smart_str_free(&str);
 }
index 7bfa74a..e8a7b19 100644 (file)
@@ -46,11 +46,11 @@ struct psi_assert_stmt {
 struct psi_assert_stmt *psi_assert_stmt_init(enum psi_assert_kind kind, struct psi_num_exp *exp);
 bool psi_assert_stmt_exec(struct psi_assert_stmt *stmt, struct psi_call_frame *frame);
 
-void psi_assert_stmt_dump(int fd, struct psi_assert_stmt *stmt);
+void psi_assert_stmt_dump(struct psi_dump *dump, struct psi_assert_stmt *stmt);
 void psi_assert_stmt_free(struct psi_assert_stmt **stmt);
 
 bool psi_assert_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope);
 
-char *psi_assert_stmt_message(struct psi_assert_stmt *stmt);
+void psi_assert_stmt_throw(struct psi_assert_stmt *stmt);
 
 #endif
index b839d5f..fd1a165 100644 (file)
@@ -55,20 +55,36 @@ void psi_const_free(struct psi_const **constant_ptr)
        }
 }
 
-void psi_const_dump(int fd, struct psi_const *cnst)
+void psi_const_dump(struct psi_dump *dump, struct psi_const *cnst)
 {
-       dprintf(fd, "const ");
+       PSI_DUMP(dump, "const ");
        if (cnst->type) {
-               psi_impl_type_dump(fd, cnst->type);
+               psi_impl_type_dump(dump, cnst->type);
        }
-       dprintf(fd, " %s = ", cnst->name->val);
-       psi_impl_def_val_dump(fd, cnst->val);
-       dprintf(fd, ";");
+       PSI_DUMP(dump, " %s = ", cnst->name->val);
+       psi_impl_def_val_dump(dump, cnst->val);
+       PSI_DUMP(dump, ";");
 }
 
 bool psi_const_validate(struct psi_data *data, struct psi_const *c,
                struct psi_validate_scope *scope)
 {
+       if (c->type) {
+               switch (c->type->type) {
+               case PSI_T_BOOL:
+               case PSI_T_INT:
+               case PSI_T_FLOAT:
+               case PSI_T_DOUBLE:
+               case PSI_T_STRING:
+                       break;
+               default:
+                       data->error(data, val->token, PSI_WARNING,
+                                       "Invalid default value type '%s', "
+                                       "expected one of bool, int, float/double or string.",
+                                       type->name->val);
+               return false;
+               }
+       }
        if (!psi_impl_def_val_validate(data, c->val, c->type, scope)) {
                return false;
        }
index 4dbb171..da06071 100644 (file)
@@ -41,7 +41,7 @@ struct psi_const {
 struct psi_const *psi_const_init(struct psi_impl_type *type, zend_string *name,
                struct psi_impl_def_val *val);
 void psi_const_free(struct psi_const **constant_ptr);
-void psi_const_dump(int fd, struct psi_const *cnst);
+void psi_const_dump(struct psi_dump *dump, struct psi_const *cnst);
 bool psi_const_validate(struct psi_data *data, struct psi_const *c,
                struct psi_validate_scope *scope);
 
index bfff0d1..aa70c63 100644 (file)
@@ -101,9 +101,9 @@ void psi_cpp_exp_free(struct psi_cpp_exp **exp_ptr)
        }
 }
 
-void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp)
+void psi_cpp_exp_dump(struct psi_dump *dump, struct psi_cpp_exp *exp)
 {
-       dprintf(fd, "#%s ", exp->token->text->val);
+       PSI_DUMP(dump, "#%s ", exp->token->text->val);
        switch (exp->type) {
        case PSI_T_WARNING:
        case PSI_T_ERROR:
@@ -114,23 +114,23 @@ void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp)
        case PSI_T_UNDEF:
        case PSI_T_IFDEF:
        case PSI_T_IFNDEF:
-               dprintf(fd, "%s", exp->data.tok->text->val);
+               PSI_DUMP(dump, "%s", exp->data.tok->text->val);
                break;
        case PSI_T_IMPORT:
        case PSI_T_INCLUDE:
        case PSI_T_INCLUDE_NEXT:
                if (exp->data.tok->type == PSI_T_CPP_HEADER) {
-                       dprintf(fd, "<%s>", exp->data.tok->text->val);
+                       PSI_DUMP(dump, "<%s>", exp->data.tok->text->val);
                } else {
-                       dprintf(fd, "\"%s\"", exp->data.tok->text->val);
+                       PSI_DUMP(dump, "\"%s\"", exp->data.tok->text->val);
                }
                break;
        case PSI_T_DEFINE:
-               psi_cpp_macro_decl_dump(fd, exp->data.decl);
+               psi_cpp_macro_decl_dump(dump, exp->data.decl);
                break;
        case PSI_T_IF:
        case PSI_T_ELIF:
-               psi_num_exp_dump(fd, exp->data.num);
+               psi_num_exp_dump(dump, exp->data.num);
                break;
        case PSI_T_ENDIF:
        case PSI_T_ELSE:
@@ -140,7 +140,7 @@ void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp)
                assert(0);
                break;
        }
-       dprintf(fd, "\n");
+       PSI_DUMP(dump, "\n");
 }
 
 
index f2706bb..d9b3a39 100644 (file)
@@ -45,7 +45,7 @@ struct psi_cpp_exp {
 
 struct psi_cpp_exp *psi_cpp_exp_init(token_t type, void *data);
 void psi_cpp_exp_free(struct psi_cpp_exp **exp_ptr);
-void psi_cpp_exp_dump(int fd, struct psi_cpp_exp *exp);
+void psi_cpp_exp_dump(struct psi_dump *dump, struct psi_cpp_exp *exp);
 void psi_cpp_exp_exec(struct psi_cpp_exp *exp, struct psi_cpp *cpp, struct psi_data *D);
 
 #endif
index e1277ca..04e0ea4 100644 (file)
@@ -68,17 +68,17 @@ void psi_cpp_macro_call_free(struct psi_cpp_macro_call **call_ptr)
        }
 }
 
-void psi_cpp_macro_call_dump(int fd, struct psi_cpp_macro_call *call)
+void psi_cpp_macro_call_dump(struct psi_dump *dump, struct psi_cpp_macro_call *call)
 {
        size_t i = 0;
        struct psi_num_exp *num;
 
-       dprintf(fd, "%s(", call->name->val);
+       PSI_DUMP(dump, "%s(", call->name->val);
        while (psi_plist_get(call->args, i++, &num)) {
                if (i > 1) {
-                       dprintf(fd, ", ");
+                       PSI_DUMP(dump, ", ");
                }
-               psi_num_exp_dump(fd, num);
+               psi_num_exp_dump(dump, num);
        }
-       dprintf(fd, ")");
+       PSI_DUMP(dump, ")");
 }
index 11e2be9..ecb0ea6 100644 (file)
@@ -43,6 +43,6 @@ struct psi_cpp_macro_call *psi_cpp_macro_call_init(zend_string *name,
 struct psi_cpp_macro_call *psi_cpp_macro_call_copy(
                struct psi_cpp_macro_call *call);
 void psi_cpp_macro_call_free(struct psi_cpp_macro_call **call_ptr);
-void psi_cpp_macro_call_dump(int fd, struct psi_cpp_macro_call *call);
+void psi_cpp_macro_call_dump(struct psi_dump *dump, struct psi_cpp_macro_call *call);
 
 #endif
index 4f21d60..25bafd8 100644 (file)
@@ -58,24 +58,24 @@ void psi_cpp_macro_decl_free(struct psi_cpp_macro_decl **macro_ptr)
        }
 }
 
-void psi_cpp_macro_decl_dump(int fd, struct psi_cpp_macro_decl *macro)
+void psi_cpp_macro_decl_dump(struct psi_dump *dump, struct psi_cpp_macro_decl *macro)
 {
-       dprintf(fd, "%s", macro->token->text->val);
+       PSI_DUMP(dump, "%s", macro->token->text->val);
 
        if (macro->sig) {
                size_t i = 0;
                struct psi_token *tok;
 
-               dprintf(fd, "(");
+               PSI_DUMP(dump, "(");
                while (psi_plist_get(macro->sig, i++, &tok)) {
-                       dprintf(fd, "%s%s", i>1?",":"", tok->text->val);
+                       PSI_DUMP(dump, "%s%s", i>1?",":"", tok->text->val);
                }
-               dprintf(fd, ")");
+               PSI_DUMP(dump, ")");
        }
 
        if (macro->exp) {
-               dprintf(fd, " ");
-               psi_num_exp_dump(fd, macro->exp);
+               PSI_DUMP(dump, " ");
+               psi_num_exp_dump(dump, macro->exp);
 
                assert(macro->tokens);
 
@@ -86,13 +86,13 @@ void psi_cpp_macro_decl_dump(int fd, struct psi_cpp_macro_decl *macro)
                while (psi_plist_get(macro->tokens, i++, &tok)) {
                        switch (tok->type) {
                        case PSI_T_QUOTED_STRING:
-                               dprintf(fd, " \"%s\"", tok->text->val);
+                               PSI_DUMP(dump, " \"%s\"", tok->text->val);
                                break;
                        case PSI_T_QUOTED_CHAR:
-                               dprintf(fd, " '%s'", tok->text->val);
+                               PSI_DUMP(dump, " '%s'", tok->text->val);
                                break;
                        default:
-                               dprintf(fd, " %s", tok->text->val);
+                               PSI_DUMP(dump, " %s", tok->text->val);
                        }
                }
        }
index e8ab300..f7cac26 100644 (file)
@@ -40,7 +40,7 @@ struct psi_cpp_macro_decl {
 struct psi_cpp_macro_decl *psi_cpp_macro_decl_init(struct psi_plist *sig,
                struct psi_plist *tokens, struct psi_num_exp *exp);
 void psi_cpp_macro_decl_free(struct psi_cpp_macro_decl **macro_ptr);
-void psi_cpp_macro_decl_dump(int fd, struct psi_cpp_macro_decl *decl);
+void psi_cpp_macro_decl_dump(struct psi_dump *dump, struct psi_cpp_macro_decl *decl);
 bool psi_cpp_macro_decl_equal(struct psi_cpp_macro_decl *d1, struct psi_cpp_macro_decl *d2);
 
 #endif
index 780b924..42eeb43 100644 (file)
@@ -65,36 +65,36 @@ void psi_decl_free(struct psi_decl **d_ptr)
        }
 }
 
-void psi_decl_dump(int fd, struct psi_decl *decl)
+void psi_decl_dump(struct psi_dump *dump, struct psi_decl *decl)
 {
        if (decl->abi) {
-               psi_decl_abi_dump(fd, decl->abi);
+               psi_decl_abi_dump(dump, decl->abi);
        }
-       dprintf(fd, " ");
+       PSI_DUMP(dump, " ");
        /* FIXME: functions returning arrays */
-       psi_decl_arg_dump(fd, decl->func, 0);
-       dprintf(fd, "(");
+       psi_decl_arg_dump(dump, decl->func, 0);
+       PSI_DUMP(dump, "(");
        if (decl->args) {
                size_t i;
                struct psi_decl_arg *arg;
 
                for (i = 0; psi_plist_get(decl->args, i, &arg); ++i) {
                        if (i) {
-                               dprintf(fd, ", ");
+                               PSI_DUMP(dump, ", ");
                        }
-                       psi_decl_arg_dump(fd, arg, 0);
+                       psi_decl_arg_dump(dump, arg, 0);
                }
                if (decl->varargs) {
-                       dprintf(fd, ", ...");
+                       PSI_DUMP(dump, ", ...");
                }
        }
        if (decl->func->var->array_size) {
-               dprintf(fd, ")[%u]", decl->func->var->array_size);
+               PSI_DUMP(dump, ")[%u]", decl->func->var->array_size);
        }
        if (decl->redir) {
-               dprintf(fd, ") __asm__ (\"%s\");", decl->redir->val);
+               PSI_DUMP(dump, ") __asm__ (\"%s\");", decl->redir->val);
        } else {
-               dprintf(fd, ");");
+               PSI_DUMP(dump, ");");
        }
 }
 
index 11e72a8..08380b1 100644 (file)
@@ -44,7 +44,7 @@ struct psi_decl {
 
 struct psi_decl *psi_decl_init(struct psi_decl_arg *func, struct psi_plist *args);
 void psi_decl_free(struct psi_decl **d_ptr);
-void psi_decl_dump(int fd, struct psi_decl *decl);
+void psi_decl_dump(struct psi_dump *dump, struct psi_decl *decl);
 
 bool psi_decl_validate(struct psi_data *data, struct psi_decl *decl, struct psi_validate_scope *scope);
 bool psi_decl_validate_nodl(struct psi_data *data, struct psi_decl *decl, struct psi_validate_scope *scope);
index 7efa2ef..a92c8ad 100644 (file)
@@ -47,9 +47,9 @@ void psi_decl_abi_free(struct psi_decl_abi **abi_ptr)
        }
 }
 
-void psi_decl_abi_dump(int fd, struct psi_decl_abi *abi)
+void psi_decl_abi_dump(struct psi_dump *dump, struct psi_decl_abi *abi)
 {
-       dprintf(fd, "%s", abi->convention->val);
+       PSI_DUMP(dump, "%s", abi->convention->val);
 }
 
 static const char * const abi_ccs[] = {
index 331ee92..fe2d16c 100644 (file)
@@ -36,7 +36,7 @@ struct psi_decl_abi {
 
 struct psi_decl_abi *psi_decl_abi_init(zend_string *convention);
 void psi_decl_abi_free(struct psi_decl_abi **abi_ptr);
-void psi_decl_abi_dump(int fd, struct psi_decl_abi *abi);
+void psi_decl_abi_dump(struct psi_dump *dump, struct psi_decl_abi *abi);
 bool psi_decl_abi_validate(struct psi_data *data, struct psi_decl_abi *abi);
 
 #endif
index 325d7c7..b48125b 100644 (file)
@@ -43,7 +43,7 @@ struct psi_decl_arg {
 
 struct psi_decl_arg *psi_decl_arg_init(struct psi_decl_type *type, struct psi_decl_var *var);
 void psi_decl_arg_free(struct psi_decl_arg **arg_ptr);
-void psi_decl_arg_dump(int fd, struct psi_decl_arg *arg, unsigned level);
+void psi_decl_arg_dump(struct psi_dump *dump, struct psi_decl_arg *arg, unsigned level);
 
 bool psi_decl_arg_validate(struct psi_data *data, struct psi_decl_arg *arg, struct psi_validate_scope *scope);
 bool psi_decl_arg_validate_typedef(struct psi_data *data, struct psi_decl_arg *def, struct psi_validate_scope *scope);
index 310b7e3..68d644a 100644 (file)
@@ -49,22 +49,22 @@ void psi_decl_enum_free(struct psi_decl_enum **e_ptr)
        }
 }
 
-void psi_decl_enum_dump(int fd, struct psi_decl_enum *e, unsigned level)
+void psi_decl_enum_dump(struct psi_dump *dump, struct psi_decl_enum *e, unsigned level)
 {
-       dprintf(fd, "enum %s {\n", e->name->val);
+       PSI_DUMP(dump, "enum %s {\n", e->name->val);
        if (e->items) {
                size_t i = 0;
                struct psi_decl_enum_item *item;
 
                while (psi_plist_get(e->items, i++, &item)) {
                        if (i > 1) {
-                               dprintf(fd, ",\n");
+                               PSI_DUMP(dump, ",\n");
                        }
-                       dprintf(fd, "%s", psi_t_indent(level + 1));
-                       psi_decl_enum_item_dump(fd, item);
+                       PSI_DUMP(dump, "%s", psi_t_indent(level + 1));
+                       psi_decl_enum_item_dump(dump, item);
                }
        }
-       dprintf(fd, "\n}");
+       PSI_DUMP(dump, "\n}");
 }
 
 bool psi_decl_enum_validate(struct psi_data *data, struct psi_decl_enum *e)
index fd51d71..037f21d 100644 (file)
@@ -38,7 +38,7 @@ struct psi_decl_enum {
 
 struct psi_decl_enum *psi_decl_enum_init(zend_string *name, struct psi_plist *l);
 void psi_decl_enum_free(struct psi_decl_enum **e_ptr);
-void psi_decl_enum_dump(int fd, struct psi_decl_enum *e, unsigned level);
+void psi_decl_enum_dump(struct psi_dump *dump, struct psi_decl_enum *e, unsigned level);
 bool psi_decl_enum_validate(struct psi_data *data, struct psi_decl_enum *e);
 
 #endif
index f20eaa6..4992000 100644 (file)
@@ -64,12 +64,12 @@ void psi_decl_enum_item_free(struct psi_decl_enum_item **i_ptr)
        }
 }
 
-void psi_decl_enum_item_dump(int fd, struct psi_decl_enum_item *item)
+void psi_decl_enum_item_dump(struct psi_dump *dump, struct psi_decl_enum_item *item)
 {
-       dprintf(fd, "%s", item->name->val);
+       PSI_DUMP(dump, "%s", item->name->val);
        if (item->num && item->num != &item->inc) {
-               dprintf(fd, " = ");
-               psi_num_exp_dump(fd, item->num);
+               PSI_DUMP(dump, " = ");
+               psi_num_exp_dump(dump, item->num);
        }
 }
 
index c465ed1..86e4dc8 100644 (file)
@@ -42,7 +42,7 @@ struct psi_decl_enum_item {
 
 struct psi_decl_enum_item *psi_decl_enum_item_init(zend_string *name, struct psi_num_exp *num);
 void psi_decl_enum_item_free(struct psi_decl_enum_item **i_ptr);
-void psi_decl_enum_item_dump(int fd, struct psi_decl_enum_item *item);
+void psi_decl_enum_item_dump(struct psi_dump *dump, struct psi_decl_enum_item *item);
 bool psi_decl_enum_item_validate(struct psi_data *data, struct psi_decl_enum *enm, struct psi_decl_enum_item *item, size_t seq);
 
 #endif
index 2430454..446a28e 100644 (file)
@@ -91,11 +91,11 @@ bool psi_decl_extvar_validate(struct psi_data *data,
        return true;
 }
 
-void psi_decl_extvar_dump(int fd, struct psi_decl_extvar *evar)
+void psi_decl_extvar_dump(struct psi_dump *dump, struct psi_decl_extvar *evar)
 {
-       dprintf(fd, "extern ");
-       psi_decl_arg_dump(fd, evar->arg, 0);
-       dprintf(fd, ";\n");
+       PSI_DUMP(dump, "extern ");
+       psi_decl_arg_dump(dump, evar->arg, 0);
+       PSI_DUMP(dump, ";\n");
 }
 
 struct psi_decl *psi_decl_extvar_setter(struct psi_decl_extvar *evar)
index 696567e..9d3b9d9 100644 (file)
@@ -46,7 +46,7 @@ struct psi_decl_extvar *psi_decl_extvar_init(struct psi_decl_arg *arg);
 void psi_decl_extvar_free(struct psi_decl_extvar **evar);
 bool psi_decl_extvar_validate(struct psi_data *data, struct psi_decl_extvar *evar,
                struct psi_validate_scope *scope);
-void psi_decl_extvar_dump(int fd, struct psi_decl_extvar *evar);
+void psi_decl_extvar_dump(struct psi_dump *dump, struct psi_decl_extvar *evar);
 
 bool psi_decl_extvar_is_blacklisted(const char *name);
 
index 14076c6..44f8b4c 100644 (file)
@@ -55,14 +55,14 @@ void psi_decl_struct_free(struct psi_decl_struct **s_ptr)
        }
 }
 
-void psi_decl_struct_dump(int fd, struct psi_decl_struct *strct)
+void psi_decl_struct_dump(struct psi_dump *dump, struct psi_decl_struct *strct)
 {
-       dprintf(fd, "struct %s::(%zu, %zu)", strct->name->val, strct->align,
+       PSI_DUMP(dump, "struct %s::(%zu, %zu)", strct->name->val, strct->align,
                        strct->size);
        if (psi_plist_count(strct->args)) {
                psi_decl_type_dump_args_with_layout(fd, strct->args, 0);
        } else {
-               dprintf(fd, ";");
+               PSI_DUMP(dump, ";");
        }
 }
 
index 51cdbe2..01f6595 100644 (file)
@@ -46,7 +46,7 @@ struct psi_decl_struct {
 
 struct psi_decl_struct *psi_decl_struct_init(zend_string *name, struct psi_plist *args);
 void psi_decl_struct_free(struct psi_decl_struct **s_ptr);
-void psi_decl_struct_dump(int fd, struct psi_decl_struct *strct);
+void psi_decl_struct_dump(struct psi_dump *dump, struct psi_decl_struct *strct);
 
 bool psi_decl_struct_validate(struct psi_data *data, struct psi_decl_struct *s, struct psi_validate_scope *scope);
 
index 51795b0..164f33f 100644 (file)
@@ -294,60 +294,60 @@ void psi_decl_type_dump_args_with_layout(int fd, struct psi_plist *args,
 {
        size_t i = 0;
 
-       dprintf(fd, " {\n");
+       PSI_DUMP(dump, " {\n");
        if (args) {
                struct psi_decl_arg *sarg;
 
                ++level;
                while (psi_plist_get(args, i++, &sarg)) {
-                       dprintf(fd, "%s", psi_t_indent(level));
-                       psi_decl_arg_dump(fd, sarg, level);
+                       PSI_DUMP(dump, "%s", psi_t_indent(level));
+                       psi_decl_arg_dump(dump, sarg, level);
                        if (sarg->layout) {
                                if (sarg->layout->bfw) {
-                                       dprintf(fd, ":%zu", sarg->layout->bfw->len);
+                                       PSI_DUMP(dump, ":%zu", sarg->layout->bfw->len);
                                }
-                               dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos,
+                               PSI_DUMP(dump, "::(%zu, %zu);\n", sarg->layout->pos,
                                                sarg->layout->len);
                        } else {
-                               dprintf(fd, ";\n");
+                               PSI_DUMP(dump, ";\n");
                        }
                }
                --level;
        }
-       dprintf(fd, "%s", psi_t_indent(level));
-       dprintf(fd, "}");
+       PSI_DUMP(dump, "%s", psi_t_indent(level));
+       PSI_DUMP(dump, "}");
 }
 
-void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level)
+void psi_decl_type_dump(struct psi_dump *dump, struct psi_decl_type *t, unsigned level)
 {
        switch (t->type) {
        case PSI_T_POINTER:
-               dprintf(fd, "%s *", t->name->val);
+               PSI_DUMP(dump, "%s *", t->name->val);
                return;
 
        case PSI_T_ENUM:
-               dprintf(fd, "enum ");
+               PSI_DUMP(dump, "enum ");
                if (psi_decl_type_is_anon(t->name, "enum")) {
                        size_t i = 0, c = psi_plist_count(t->real.enm->items);
                        struct psi_decl_enum_item *item;
 
-                       dprintf(fd, "{\n");
+                       PSI_DUMP(dump, "{\n");
                        ++level;
                        while (psi_plist_get(t->real.enm->items, i++, &item)) {
-                               dprintf(fd, "%s", psi_t_indent(level));
-                               psi_decl_enum_item_dump(fd, item);
+                               PSI_DUMP(dump, "%s", psi_t_indent(level));
+                               psi_decl_enum_item_dump(dump, item);
                                if (i < c) {
-                                       dprintf(fd, "%s\n", i < c ? "," : "");
+                                       PSI_DUMP(dump, "%s\n", i < c ? "," : "");
                                }
                        }
                        --level;
-                       dprintf(fd, "%s\n} ", psi_t_indent(level));
+                       PSI_DUMP(dump, "%s\n} ", psi_t_indent(level));
                        return;
                }
                break;
 
        case PSI_T_STRUCT:
-               dprintf(fd, "struct ");
+               PSI_DUMP(dump, "struct ");
                if (psi_decl_type_is_anon(t->name, "struct")) {
                        psi_decl_type_dump_args_with_layout(fd, t->real.strct->args, level);
                        return;
@@ -355,7 +355,7 @@ void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level)
                break;
 
        case PSI_T_UNION:
-               dprintf(fd, "union ");
+               PSI_DUMP(dump, "union ");
                if (psi_decl_type_is_anon(t->name, "union")) {
                        psi_decl_type_dump_args_with_layout(fd, t->real.unn->args, level);
                        return;
@@ -363,14 +363,14 @@ void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level)
                break;
 
        case PSI_T_FUNCTION:
-               psi_decl_type_dump(fd, t->real.func->func->type, level);
+               psi_decl_type_dump(dump, t->real.func->func->type, level);
                return;
 
        default:
                break;
        }
 
-       dprintf(fd, "%s", t->name->val);
+       PSI_DUMP(dump, "%s", t->name->val);
 }
 
 int psi_decl_type_is_weak(struct psi_decl_type *type)
index da95e64..d51220d 100644 (file)
@@ -57,7 +57,7 @@ struct psi_decl_type {
 struct psi_decl_type *psi_decl_type_init(token_t type, zend_string *name);
 struct psi_decl_type *psi_decl_type_copy(struct psi_decl_type *src);
 void psi_decl_type_free(struct psi_decl_type **type_ptr);
-void psi_decl_type_dump(int fd, struct psi_decl_type *t, unsigned level);
+void psi_decl_type_dump(struct psi_dump *dump, struct psi_decl_type *t, unsigned level);
 bool psi_decl_type_validate(struct psi_data *data, struct psi_decl_type *type,
                struct psi_decl_arg *def, struct psi_validate_scope *scope);
 
index 3ab8f69..a2daf2c 100644 (file)
@@ -52,13 +52,13 @@ void psi_decl_union_free(struct psi_decl_union **u_ptr)
        }
 }
 
-void psi_decl_union_dump(int fd, struct psi_decl_union *unn)
+void psi_decl_union_dump(struct psi_dump *dump, struct psi_decl_union *unn)
 {
-       dprintf(fd, "union %s::(%zu, %zu)", unn->name->val, unn->align, unn->size);
+       PSI_DUMP(dump, "union %s::(%zu, %zu)", unn->name->val, unn->align, unn->size);
        if (psi_plist_count(unn->args)) {
                psi_decl_type_dump_args_with_layout(fd, unn->args, 0);
        } else {
-               dprintf(fd, ";");
+               PSI_DUMP(dump, ";");
        }
 }
 
index 1227ed1..9d7fcc5 100644 (file)
@@ -41,7 +41,7 @@ struct psi_decl_union {
 
 struct psi_decl_union *psi_decl_union_init(zend_string *name, struct psi_plist *args);
 void psi_decl_union_free(struct psi_decl_union **u_ptr);
-void psi_decl_union_dump(int fd, struct psi_decl_union *unn);
+void psi_decl_union_dump(struct psi_dump *dump, struct psi_decl_union *unn);
 
 bool psi_decl_union_validate(struct psi_data *data, struct psi_decl_union *u, struct psi_validate_scope *scope);
 
index 49bc58f..376bb13 100644 (file)
@@ -75,13 +75,13 @@ void psi_decl_var_free(struct psi_decl_var **var_ptr)
        }
 }
 
-void psi_decl_var_dump(int fd, struct psi_decl_var *var)
+void psi_decl_var_dump(struct psi_dump *dump, struct psi_decl_var *var)
 {
-       dprintf(fd, "%s%s",
+       PSI_DUMP(dump, "%s%s",
                        psi_t_indirection(var->pointer_level - !!var->array_size),
                        var->name ? var->name->val : "/**/");
        if (var->array_size && var->arg->type->type != PSI_T_FUNCTION) {
-               dprintf(fd, "[%u]", var->array_size);
+               PSI_DUMP(dump, "[%u]", var->array_size);
        }
 }
 
index ca9a5fd..08f4b14 100644 (file)
@@ -44,7 +44,7 @@ struct psi_decl_var {
 struct psi_decl_var *psi_decl_var_init(zend_string *name, unsigned pl, unsigned as);
 struct psi_decl_var *psi_decl_var_copy(struct psi_decl_var *src);
 void psi_decl_var_free(struct psi_decl_var **var_ptr);
-void psi_decl_var_dump(int fd, struct psi_decl_var *var);
+void psi_decl_var_dump(struct psi_dump *dump, struct psi_decl_var *var);
 
 bool psi_decl_var_validate(struct psi_data *data, struct psi_decl_var *dvar,
                struct psi_validate_scope *scope);
index 7d17756..1a29cd2 100644 (file)
@@ -51,19 +51,19 @@ void psi_free_exp_free(struct psi_free_exp **f_ptr)
        }
 }
 
-void psi_free_exp_dump(int fd, struct psi_free_exp *call)
+void psi_free_exp_dump(struct psi_dump *dump, struct psi_free_exp *call)
 {
        size_t l = 0, c = psi_plist_count(call->vars);
        struct psi_decl_var *fvar;
 
-       dprintf(fd, "%s(", call->func->val);
+       PSI_DUMP(dump, "%s(", call->func->val);
        while (psi_plist_get(call->vars, l++, &fvar)) {
-               psi_decl_var_dump(fd, fvar);
+               psi_decl_var_dump(dump, fvar);
                if (l < c) {
-                       dprintf(fd, ", ");
+                       PSI_DUMP(dump, ", ");
                }
        }
-       dprintf(fd, ")");
+       PSI_DUMP(dump, ")");
 }
 
 static inline struct psi_decl *locate_free_decl(struct psi_plist *decls,
index a615868..01bbf28 100644 (file)
@@ -44,7 +44,7 @@ struct psi_free_exp {
 
 struct psi_free_exp *psi_free_exp_init(zend_string *func, struct psi_plist *vars);
 void psi_free_exp_free(struct psi_free_exp **f_ptr);
-void psi_free_exp_dump(int fd, struct psi_free_exp *call);
+void psi_free_exp_dump(struct psi_dump *dump, struct psi_free_exp *call);
 
 bool psi_free_exp_validate(struct psi_data *data, struct psi_free_exp *fc, struct psi_validate_scope *scope);
 
index 526f22d..b6254b3 100644 (file)
@@ -45,19 +45,19 @@ void psi_free_stmt_free(struct psi_free_stmt **f_ptr)
        }
 }
 
-void psi_free_stmt_dump(int fd, struct psi_free_stmt *fre)
+void psi_free_stmt_dump(struct psi_dump *dump, struct psi_free_stmt *fre)
 {
        size_t i;
        struct psi_free_exp *exp;
 
-       dprintf(fd, "\tfree ");
+       PSI_DUMP(dump, "\tfree ");
        for (i = 0; psi_plist_get(fre->exps, i, &exp); ++i) {
                if (i) {
-                       dprintf(fd, ", ");
+                       PSI_DUMP(dump, ", ");
                }
-               psi_free_exp_dump(fd, exp);
+               psi_free_exp_dump(dump, exp);
        }
-       dprintf(fd, ";\n");
+       PSI_DUMP(dump, ";\n");
 }
 
 bool psi_free_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope)
index f490f01..542fe6e 100644 (file)
@@ -38,7 +38,7 @@ struct psi_free_stmt {
 
 struct psi_free_stmt *psi_free_stmt_init(struct psi_plist *calls);
 void psi_free_stmt_free(struct psi_free_stmt **f_ptr);
-void psi_free_stmt_dump(int fd, struct psi_free_stmt *fre);
+void psi_free_stmt_dump(struct psi_dump *dump, struct psi_free_stmt *fre);
 
 bool psi_free_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope);
 void psi_free_stmt_exec(struct psi_free_stmt *fre, struct psi_call_frame *frame);
index 84bff97..c1b9b9a 100644 (file)
@@ -87,7 +87,7 @@ void psi_impl_free(struct psi_impl **impl_ptr)
        }
 }
 
-void psi_impl_dump(int fd, struct psi_impl *impl)
+void psi_impl_dump(struct psi_dump *dump, struct psi_impl *impl)
 {
        size_t i;
        struct psi_return_stmt *ret;
@@ -96,24 +96,24 @@ void psi_impl_dump(int fd, struct psi_impl *impl)
        struct psi_free_stmt *fre;
        struct psi_assert_stmt *ass;
 
-       psi_impl_func_dump(fd, impl->func);
-       dprintf(fd, " {\n");
+       psi_impl_func_dump(dump, impl->func);
+       PSI_DUMP(dump, " {\n");
        for (i = 0; psi_plist_get(impl->stmts.let, i, &let); ++i) {
-               psi_let_stmt_dump(fd, let);
+               psi_let_stmt_dump(dump, let);
        }
        for (i = 0; psi_plist_get(impl->stmts.ass, i, &ass); ++i) {
-               psi_assert_stmt_dump(fd, ass);
+               psi_assert_stmt_dump(dump, ass);
        }
        for (i = 0; psi_plist_get(impl->stmts.ret, i, &ret); ++i) {
-               psi_return_stmt_dump(fd, ret);
+               psi_return_stmt_dump(dump, ret);
        }
        for (i = 0; psi_plist_get(impl->stmts.set, i, &set); ++i) {
-               psi_set_stmt_dump(fd, set);
+               psi_set_stmt_dump(dump, set);
        }
        for (i = 0; psi_plist_get(impl->stmts.fre, i, &fre); ++i) {
-               psi_free_stmt_dump(fd, fre);
+               psi_free_stmt_dump(dump, fre);
        }
-       dprintf(fd, "}\n");
+       PSI_DUMP(dump, "}\n");
 }
 
 bool psi_impl_validate(struct psi_data *data, struct psi_impl *impl,
index fd1c9d0..7123922 100644 (file)
@@ -49,7 +49,7 @@ struct psi_impl {
 
 struct psi_impl *psi_impl_init(struct psi_impl_func *func, struct psi_plist *stmts);
 void psi_impl_free(struct psi_impl **impl_ptr);
-void psi_impl_dump(int fd, struct psi_impl *impl);
+void psi_impl_dump(struct psi_dump *dump, struct psi_impl *impl);
 bool psi_impl_validate(struct psi_data *data, struct psi_impl *impl,
                struct psi_validate_scope *scope);
 
index 5de6161..12e09b6 100644 (file)
@@ -52,14 +52,14 @@ void psi_impl_arg_free(struct psi_impl_arg **arg_ptr)
        }
 }
 
-void psi_impl_arg_dump(int fd, struct psi_impl_arg *iarg, bool vararg)
+void psi_impl_arg_dump(struct psi_dump *dump, struct psi_impl_arg *iarg, bool vararg)
 {
-       psi_impl_type_dump(fd, iarg->type);
-       dprintf(fd, " ");
-       psi_impl_var_dump(fd, iarg->var, vararg);
+       psi_impl_type_dump(dump, iarg->type);
+       PSI_DUMP(dump, " ");
+       psi_impl_var_dump(dump, iarg->var, vararg);
        if (iarg->def) {
-               dprintf(fd, " = ");
-               psi_impl_def_val_dump(fd, iarg->def);
+               PSI_DUMP(dump, " = ");
+               psi_impl_def_val_dump(dump, iarg->def);
        }
 
 }
index d3e470a..4aea333 100644 (file)
@@ -40,6 +40,6 @@ struct psi_impl_arg {
 
 struct psi_impl_arg *psi_impl_arg_init(struct psi_impl_type *type, struct psi_impl_var *var, struct psi_impl_def_val *def);
 void psi_impl_arg_free(struct psi_impl_arg **arg_ptr);
-void psi_impl_arg_dump(int fd, struct psi_impl_arg *iarg, bool vararg);
+void psi_impl_arg_dump(struct psi_dump *dump, struct psi_impl_arg *iarg, bool vararg);
 
 #endif
index eec90e6..8b2d37b 100644 (file)
@@ -26,6 +26,8 @@
 #include "php_psi_stdinc.h"
 #include "data.h"
 
+#include "zend_smart_str.h"
+
 #include <assert.h>
 #include <math.h>
 
@@ -37,7 +39,11 @@ struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data)
 
        switch ((def->type = t)) {
        case PSI_T_TRUE:
+               def->ival.zend.bval = 1;
+               /* no break */
        case PSI_T_FALSE:
+               def->ityp = PSI_T_UINT8;
+               /* no break */
        case PSI_T_NULL:
                break;
        case PSI_T_QUOTED_STRING:
@@ -85,25 +91,271 @@ void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr)
        }
 }
 
+void psi_impl_def_val_get_zval(struct psi_impl_def_val *val, token_t typ, zval *zv)
+{
+       impl_val tmp = val->ival;
+
+       /* c->val has already been forced to the type of the containing constant or impl_arg */
+       switch (typ) {
+       case PSI_T_BOOL:
+               ZVAL_BOOL(zv, tmp.zend.bval);
+               break;
+       case PSI_T_INT:
+               ZVAL_LONG(zv, tmp.zend.lval);
+               break;
+       case PSI_T_FLOAT:
+       case PSI_T_DOUBLE:
+       is_double: ;
+               ZVAL_DOUBLE(zv, tmp.dval);
+               break;
+       case PSI_T_STRING:
+       is_string: ;
+               ZVAL_NEW_STR(zv, zend_string_copy(tmp.zend.str));
+               if (ZSTR_IS_INTERNED(Z_STR_P(zv))) {
+                       Z_TYPE_FLAGS_P(zv) = 0;
+               }
+               break;
+       case PSI_T_MIXED:
+               switch (val->type) {
+               case PSI_T_NULL:
+                       ZVAL_NULL(zv);
+                       break;
+               case PSI_T_TRUE:
+                       ZVAL_TRUE(zv);
+                       break;
+               case PSI_T_FALSE:
+                       ZVAL_FALSE(zv);
+                       break;
+               case PSI_T_STRING:
+                       goto is_string;
+                       break;
+               case PSI_T_NUMBER:
+                       switch (val->ityp) {
+                       case PSI_T_INT8:
+                       case PSI_T_UINT8:
+                       case PSI_T_INT16:
+                       case PSI_T_UINT16:
+                       case PSI_T_INT32:
+                       case PSI_T_UINT32:
+                               psi_calc_cast(val->ityp, &tmp, PSI_T_INT64, &tmp);
+                               /* no break */
+                       case PSI_T_INT64:
+                               ZVAL_LONG(zv, tmp.i64);
+                               break;
+                       case PSI_T_UINT64:
+                               ZVAL_LONG_DOUBLE_STR(zv, tmp.u64, is_signed=false;persistent=true);
+                               break;
+#if HAVE_INT128
+                       case PSI_T_INT128:
+                               ZVAL_LONG_DOUBLE_STR(zv, tmp.i128, is_signed=true;persistent=true);
+                               break;
+                       case PSI_T_UINT128:
+                               ZVAL_LONG_DOUBLE_STR(zv, tmp.u128, is_signed=false;persistent=true);
+#endif
+                               break;
+                       case PSI_T_FLOAT:
+                               ZVAL_DOUBLE(zv, tmp.fval);
+                               break;
+                       case PSI_T_DOUBLE:
+                               goto is_double;
+                               break;
+#if HAVE_LONG_DOUBLE
+                       case PSI_T_LONG_DOUBLE:
+                               ZVAL_DOUBLE(zv, tmp.ldval);
+                               break;
+#endif
+                       default:
+                               assert(0);
+                       }
+                       break;
+               default:
+                       assert(0);
+                       break;
+               }
+               break;
+       default:
+               assert(0);
+               break;
+       }
+
+}
+/*
+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,
+               struct psi_validate_scope *scope)
+{
+       switch (type->type) {
+       case PSI_T_BOOL:
+               switch (val->type) {
+               case PSI_T_TRUE:
+               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;
+                       }
+                       val->ityp = PSI_T_UINT8;
+                       return true;
+               default:
+                       assert(0);
+                       break;
+               }
+               break;
+       case PSI_T_INT:
+               if (val->type == PSI_T_STRING) {
+                       zend_string *str = val->ival.zend.str;
+                       switch (is_numeric_str_function(str, &val->ival.zend.lval, &val->ival.dval)) {
+                       case IS_DOUBLE:
+                               val->ival.zend.lval = zend_dval_to_lval_cap(val->ival.dval);
+                               /* no break */
+                       case IS_LONG:
+                               break;
+                       default:
+                               val->ival.zend.lval = 0;
+                       }
+                       zend_string_release(str);
+                       val->ityp = PSI_T_INT64;
+                       return true;
+               }
+               psi_calc_cast(val->ityp, &val->ival, PSI_T_INT64, &val->ival);
+               val->type = val->ityp = PSI_T_INT64;
+               return true;
+       case PSI_T_FLOAT:
+       case PSI_T_DOUBLE:
+               if (val->type == PSI_T_STRING) {
+                       zend_string *str = val->ival.zend.str;
+                       switch (is_numeric_str_function(str, &val->ival.zend.lval, &val->ival.dval)) {
+                       case IS_LONG:
+                               val->ival.dval = val->ival.zend.lval;
+                               /* no break */
+                       case IS_DOUBLE:
+                               break;
+                       default:
+                               val->ival.dval = 0;
+                       }
+                       zend_string_release(str);
+                       val->type = val->ityp = PSI_T_DOUBLE;
+                       return true;
+               }
+               psi_calc_cast(val->ityp, &val->ival, PSI_T_DOUBLE, &val->ival);
+               val->ityp = PSI_T_DOUBLE;
+               return true;
+       case PSI_T_STRING:
+               if (val->type == PSI_T_STRING) {
+                       return true;
+               } else {
+                       smart_str str = {0};
+
+                       switch (val->ityp) {
+                       CASE_IMPLVAL_NUM_PRINTF(smart_str_append_printf, &str, val->ival, false);
+                       default:
+                               assert(0);
+                       }
+                       val->ival.zend.str = smart_str_extract(&str);
+                       val->type = PSI_T_STRING;
+                       return true;
+               }
+               break;
+       default:
+               data->error(data, val->token, PSI_WARNING,
+                               "Invalid default value type '%s', "
+                               "expected one of bool, int, float/double or string.",
+                               type->name->val);
+
+       }
+       return false;
+}
+
 bool psi_impl_def_val_validate(struct psi_data *data,
                struct psi_impl_def_val *val, struct psi_impl_type *type,
                struct psi_validate_scope *scope)
 {
+       /* NULL can be anything */
        if (val->type == PSI_T_NULL) {
                return true;
-       } else if (val->type == PSI_T_NUMBER) {
+       }
+
+       /* a number can be anything */
+       if (val->type == PSI_T_NUMBER) {
                if (!psi_num_exp_validate(data, val->data.num, scope)) {
                        return false;
                }
+               val->ityp = psi_num_exp_exec(val->data.num, &val->ival, NULL, scope->cpp);
+       }
+
+       /* forced type, like `const <type> foo`, or function param `<type> $xyz` */
+       if (type) {
+               return psi_impl_def_val_validate_impl_type(data, val, type, scope);
+       }
+
+       switch (val->type) {
+       case PSI_T_NUMBER:
+       case PSI_T_NULL:
+       case PSI_T_TRUE:
+       case PSI_T_FALSE:
+       case PSI_T_STRING:
+               return true;
+       default:
+               assert(0);
+               break;
        }
 
+       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 */
+       // 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);
@@ -111,7 +363,7 @@ bool psi_impl_def_val_validate(struct psi_data *data,
                        switch (typ) {
                        case PSI_T_FLOAT:
                                val->ival.dval = val->ival.fval;
-                               /* no break */
+                               // no break
                        case PSI_T_DOUBLE:
                                val->type = PSI_T_FLOAT;
                                type->type = PSI_T_FLOAT;
@@ -125,7 +377,7 @@ bool psi_impl_def_val_validate(struct psi_data *data,
                                                        val->ival.u64);
                                }
                        default:
-                               /* FIXME big integers */
+                               // FIXME big integers
                                val->type = PSI_T_INT;
                                type->type = PSI_T_INT;
                                zend_string_release(type->name);
@@ -172,105 +424,58 @@ bool psi_impl_def_val_validate(struct psi_data *data,
 
        case PSI_T_STRING:
                if (val->type == PSI_T_STRING) {
-                       return true;
+                       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:
-               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 */
+               // no break
        default:
-               data->error(data, val->token, PSI_WARNING,
-                               "Invalid default value type '%s', "
-                               "expected one of bool, int, float, string.",
-                               type ? type->name->val : "mixed");
        }
-
-       return false;
+*/
 }
 
-void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val) {
+void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val) {
        switch (val->type) {
        case PSI_T_NULL:
-               dprintf(fd, "NULL");
+               PSI_DUMP(dump, "NULL");
                break;
        case PSI_T_TRUE:
-               dprintf(fd, "true");
+               PSI_DUMP(dump, "true");
                break;
        case PSI_T_FALSE:
-               dprintf(fd, "false");
+               PSI_DUMP(dump, "false");
                break;
        case PSI_T_BOOL:
-               dprintf(fd, "%s", val->ival.zend.bval ? "true" : "false");
+               PSI_DUMP(dump, "%s", val->ival.zend.bval ? "true" : "false");
                break;
        case PSI_T_INT:
-               dprintf(fd, ZEND_LONG_FMT, val->ival.zend.lval);
+               PSI_DUMP(dump, ZEND_LONG_FMT, val->ival.zend.lval);
                break;
        case PSI_T_FLOAT:
        case PSI_T_DOUBLE:
                if (isinf(val->ival.dval)) {
-                       dprintf(fd, "\\INF");
+                       PSI_DUMP(dump, "\\INF");
                } else if (isnan(val->ival.dval)) {
-                       dprintf(fd, "\\NAN");
+                       PSI_DUMP(dump, "\\NAN");
                } else {
-                       dprintf(fd, "%" PRIdval, val->ival.dval);
+                       PSI_DUMP(dump, "%" PRIdval, val->ival.dval);
                }
                break;
        case PSI_T_STRING:
-               dprintf(fd, "\"%s\"", val->ival.zend.str->val);
+               PSI_DUMP(dump, "\"%s\"", val->ival.zend.str->val);
                break;
        case PSI_T_NUMBER:
-               psi_num_exp_dump(fd, val->data.num);
+               psi_num_exp_dump(dump, val->data.num);
                break;
        default:
                assert(0);
        }
+       PSI_DUMP(dump, "\t/* t=%d */ ", val->type);
 }
index e597745..1345005 100644 (file)
@@ -31,6 +31,7 @@
 
 struct psi_data;
 struct psi_impl_type;
+struct psi_dump;
 
 struct psi_impl_def_val {
        struct psi_token *token;
@@ -38,13 +39,14 @@ struct psi_impl_def_val {
        union {
                struct psi_num_exp *num;
        } data;
+       token_t ityp;
        impl_val ival;
 };
 
 struct psi_impl_def_val *psi_impl_def_val_init(token_t t, void *data);
 void psi_impl_def_val_free(struct psi_impl_def_val **def_ptr);
-void psi_impl_def_val_dump(int fd, struct psi_impl_def_val *val);
+void psi_impl_def_val_dump(struct psi_dump *dump, struct psi_impl_def_val *val);
 bool psi_impl_def_val_validate(struct psi_data *data, struct psi_impl_def_val *def,
                struct psi_impl_type *cmp, struct psi_validate_scope *scope);
-
+token_t psi_impl_def_val_get_zend(struct psi_impl_def_val *val, impl_val *res);
 #endif
index a6f45e6..56c61d8 100644 (file)
@@ -85,25 +85,25 @@ bool psi_impl_func_validate(struct psi_data *data, struct psi_impl_func *func,
        return true;
 }
 
-void psi_impl_func_dump(int fd, struct psi_impl_func *func)
+void psi_impl_func_dump(struct psi_dump *dump, struct psi_impl_func *func)
 {
-       dprintf(fd, "function %s(", func->name->val);
+       PSI_DUMP(dump, "function %s(", func->name->val);
        if (func->args) {
                size_t i = 0;
                struct psi_impl_arg *iarg;
 
                while (psi_plist_get(func->args, i++, &iarg)) {
                        if (i > 1) {
-                               dprintf(fd, ", ");
+                               PSI_DUMP(dump, ", ");
                        }
-                       psi_impl_arg_dump(fd, iarg, false);
+                       psi_impl_arg_dump(dump, iarg, false);
                }
 
                if (func->vararg) {
-                       dprintf(fd, ", ");
-                       psi_impl_arg_dump(fd, func->vararg, true);
+                       PSI_DUMP(dump, ", ");
+                       psi_impl_arg_dump(dump, func->vararg, true);
                }
        }
-       dprintf(fd, ") : %s%s", func->return_reference ? "&" : "",
+       PSI_DUMP(dump, ") : %s%s", func->return_reference ? "&" : "",
                        func->return_type->name->val);
 }
index 38ebf68..f55f10c 100644 (file)
@@ -46,7 +46,7 @@ struct psi_impl_func {
 struct psi_impl_func *psi_impl_func_init(zend_string *name,
                struct psi_plist *args, struct psi_impl_type *return_type);
 void psi_impl_func_free(struct psi_impl_func **f_ptr);
-void psi_impl_func_dump(int fd, struct psi_impl_func *func);
+void psi_impl_func_dump(struct psi_dump *dump, struct psi_impl_func *func);
 bool psi_impl_func_validate(struct psi_data *data, struct psi_impl_func *func,
                struct psi_validate_scope *scope);
 
index be173aa..41baf1c 100644 (file)
@@ -36,9 +36,9 @@ struct psi_impl_type *psi_impl_type_init(token_t type, zend_string *name)
        return t;
 }
 
-void psi_impl_type_dump(int fd, struct psi_impl_type *type)
+void psi_impl_type_dump(struct psi_dump *dump, struct psi_impl_type *type)
 {
-       dprintf(fd, "%s", type->name->val);
+       PSI_DUMP(dump, "%s", type->name->val);
 }
 
 void psi_impl_type_free(struct psi_impl_type **type_ptr)
index 7c5a6fe..4a60e02 100644 (file)
@@ -36,6 +36,6 @@ struct psi_impl_type {
 
 struct psi_impl_type *psi_impl_type_init(token_t type, zend_string *name);
 void psi_impl_type_free(struct psi_impl_type **type_ptr);
-void psi_impl_type_dump(int fd, struct psi_impl_type *type);
+void psi_impl_type_dump(struct psi_dump *dump, struct psi_impl_type *type);
 
 #endif
index 9b28a7d..186a080 100644 (file)
@@ -69,21 +69,42 @@ typedef union impl_val {
 #      define isnanl isnan
 #endif
 #if HAVE_LONG_DOUBLE
-#      define CASE_IMPLVAL_LD_PRINTF(fun, to, ival) \
+#      define CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix) \
        case PSI_T_LONG_DOUBLE: \
                if (isinfl(ival.ldval)) { \
                        fun(to, "\\INF"); \
                } else if (isnanl(ival.ldval)) { \
                        fun(to, "\\NAN"); \
                } else { \
-                       fun(to, "%" PRIldval "L", ival.ldval); \
+                       fun(to, "%" PRIldval "%s", ival.ldval, (with_suffix) ? "L" : ""); \
                } \
                break;
 #else
 #      define CASE_IMPLVAL_LD_PRINTF(fun, to, ival)
 #endif
 
-#define CASE_IMPLVAL_NUM_PRINTF(fun, to, ival) \
+#define CASE_IMPLVAL_FLOAT_PRINTF(fun, to, ival, with_suffix) \
+       CASE_IMPLVAL_LD_PRINTF(fun, to, ival, with_suffix); \
+       case PSI_T_FLOAT: \
+               if (isinf(ival.dval)) { \
+                       fun(to, "\\INF"); \
+               } else if (isnan(ival.dval)) { \
+                       fun(to, "\\NAN"); \
+               } else { \
+                       fun(to, "%" PRIfval "%s", ival.dval, (with_suffix) ? "F" : ""); \
+               } \
+               break; \
+       case PSI_T_DOUBLE: \
+               if (isinf(ival.dval)) { \
+                       fun(to, "\\INF"); \
+               } else if (isnan(ival.dval)) { \
+                       fun(to, "\\NAN"); \
+               } else { \
+                       fun(to, "%" PRIdval, ival.dval); \
+               } \
+               break
+
+#define CASE_IMPLVAL_INT_PRINTF(fun, to, ival, with_suffix) \
        case PSI_T_INT8: \
                fun(to, "%" PRId8, ival.i8); \
                break; \
@@ -100,32 +121,17 @@ typedef union impl_val {
                fun(to, "%" PRId32, ival.i32); \
                break; \
        case PSI_T_UINT32: \
-               fun(to, "%" PRIu32 "U", ival.u32); \
+               fun(to, "%" PRIu32 "%s", ival.u32, (with_suffix) ? "U" : ""); \
                break; \
        case PSI_T_INT64: \
-               fun(to, "%" PRId64 "L", ival.i64); \
+               fun(to, "%" PRId64 "%s", ival.i64, (with_suffix) ? "L" : ""); \
                break; \
        case PSI_T_UINT64: \
-               fun(to, "%" PRIu64 "UL", ival.u64); \
-               break; \
-       case PSI_T_FLOAT: \
-               if (isinf(ival.dval)) { \
-                       fun(to, "\\INF"); \
-               } else if (isnan(ival.dval)) { \
-                       fun(to, "\\NAN"); \
-               } else { \
-                       fun(to, "%" PRIfval "F", ival.dval); \
-               } \
-               break; \
-       case PSI_T_DOUBLE: \
-               if (isinf(ival.dval)) { \
-                       fun(to, "\\INF"); \
-               } else if (isnan(ival.dval)) { \
-                       fun(to, "\\NAN"); \
-               } else { \
-                       fun(to, "%" PRIdval, ival.dval); \
-               } \
-               break; \
-       CASE_IMPLVAL_LD_PRINTF(fun, to, ival)
+               fun(to, "%" 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)
 
 #endif
index d3ab4f8..7d727af 100644 (file)
@@ -67,9 +67,9 @@ void psi_impl_var_free(struct psi_impl_var **var_ptr)
        }
 }
 
-void psi_impl_var_dump(int fd, struct psi_impl_var *var, bool vararg)
+void psi_impl_var_dump(struct psi_dump *dump, struct psi_impl_var *var, bool vararg)
 {
-       dprintf(fd, "%s%s%s",
+       PSI_DUMP(dump, "%s%s%s",
                var->reference ? "&" : "",
                vararg ? "..." : "",
                var->name->val);
index 2a179ad..aaab32d 100644 (file)
@@ -41,7 +41,7 @@ struct psi_impl_var {
 struct psi_impl_var *psi_impl_var_init(zend_string *name, bool is_reference);
 struct psi_impl_var *psi_impl_var_copy(struct psi_impl_var *var);
 void psi_impl_var_free(struct psi_impl_var **var_ptr);
-void psi_impl_var_dump(int fd, struct psi_impl_var *var, bool vararg);
+void psi_impl_var_dump(struct psi_dump *dump, struct psi_impl_var *var, bool vararg);
 
 bool psi_impl_var_validate(struct psi_data *data, struct psi_impl_var *ivar,
                struct psi_validate_scope *scope);
index 4d65df4..abe2141 100644 (file)
@@ -125,22 +125,22 @@ bool psi_let_callback_validate(struct psi_data *data, struct psi_let_callback *c
        return true;
 }
 
-void psi_let_callback_dump(int fd, struct psi_let_callback *callback,
+void psi_let_callback_dump(struct psi_dump *dump, struct psi_let_callback *callback,
                unsigned level)
 {
-       dprintf(fd, "callback(");
+       PSI_DUMP(dump, "callback(");
        if (callback->cb_args) {
                size_t i = 0;
                struct psi_decl_var *cb_arg;
 
                while (psi_plist_get(callback->cb_args, i++, &cb_arg)) {
                        if (i > 1) {
-                               dprintf(fd, ", ");
+                               PSI_DUMP(dump, ", ");
                        }
-                       psi_decl_var_dump(fd, cb_arg);
+                       psi_decl_var_dump(dump, cb_arg);
                }
        }
-       dprintf(fd, ") as %s(%s(",
+       PSI_DUMP(dump, ") as %s(%s(",
                        callback->func->name->val,
                        callback->func->var->name->val);
 
@@ -148,14 +148,14 @@ void psi_let_callback_dump(int fd, struct psi_let_callback *callback,
                size_t i = 0, last = psi_plist_count(callback->args);
                struct psi_set_exp *set;
 
-               dprintf(fd, "\n");
+               PSI_DUMP(dump, "\n");
                ++level;
                while (psi_plist_get(callback->args, i++, &set)) {
-                       psi_set_exp_dump(fd, set, level, i == last);
-                       dprintf(fd, "\n");
+                       psi_set_exp_dump(dump, set, level, i == last);
+                       PSI_DUMP(dump, "\n");
                }
                --level;
-               dprintf(fd, "%s", psi_t_indent(level));
+               PSI_DUMP(dump, "%s", psi_t_indent(level));
        }
-       dprintf(fd, "))");
+       PSI_DUMP(dump, "))");
 }
index e10b32a..d545359 100644 (file)
@@ -44,7 +44,7 @@ struct psi_let_callback {
 
 struct psi_let_callback *psi_let_callback_init(struct psi_let_func *func, struct psi_plist *args, struct psi_plist *cb_args);
 void psi_let_callback_free(struct psi_let_callback **cb_ptr);
-void psi_let_callback_dump(int fd, struct psi_let_callback *cb, unsigned level);
+void psi_let_callback_dump(struct psi_dump *dump, struct psi_let_callback *cb, unsigned level);
 bool psi_let_callback_validate(struct psi_data *data, struct psi_let_callback *cb, struct psi_validate_scope *scope);
 
 #endif
index 152e5c8..46badc0 100644 (file)
@@ -50,11 +50,11 @@ void psi_let_calloc_free(struct psi_let_calloc **alloc_ptr)
        }
 }
 
-void psi_let_calloc_dump(int fd, struct psi_let_calloc *alloc)
+void psi_let_calloc_dump(struct psi_dump *dump, struct psi_let_calloc *alloc)
 {
-       dprintf(fd, "calloc(");
-       psi_num_exp_dump(fd, alloc->nmemb);
-       dprintf(fd, ", ");
-       psi_num_exp_dump(fd, alloc->size);
-       dprintf(fd, ")");
+       PSI_DUMP(dump, "calloc(");
+       psi_num_exp_dump(dump, alloc->nmemb);
+       PSI_DUMP(dump, ", ");
+       psi_num_exp_dump(dump, alloc->size);
+       PSI_DUMP(dump, ")");
 }
index 6caeb8d..04bfa41 100644 (file)
@@ -38,6 +38,6 @@ struct psi_let_calloc {
 
 struct psi_let_calloc *psi_let_calloc_init(struct psi_num_exp *nmemb, struct psi_num_exp *size);
 void psi_let_calloc_free(struct psi_let_calloc **alloc_ptr);
-void psi_let_calloc_dump(int fd, struct psi_let_calloc *alloc);
+void psi_let_calloc_dump(struct psi_dump *dump, struct psi_let_calloc *alloc);
 
 #endif
index 97eec8f..55bf576 100644 (file)
@@ -102,42 +102,42 @@ void psi_let_exp_free(struct psi_let_exp **let_ptr)
        }
 }
 
-void psi_let_exp_dump(int fd, struct psi_let_exp *val, unsigned level, int last)
+void psi_let_exp_dump(struct psi_dump *dump, struct psi_let_exp *val, unsigned level, int last)
 {
        if (level > 1) {
                /* only if not directly after `set ...` */
-               dprintf(fd, "%s", psi_t_indent(level));
+               PSI_DUMP(dump, "%s", psi_t_indent(level));
        }
 
        if (val->var) {
                if (val->var->token) {
-                       psi_decl_var_dump(fd, val->var);
-                       dprintf(fd, " = ");
+                       psi_decl_var_dump(dump, val->var);
+                       PSI_DUMP(dump, " = ");
                }
        }
        if (val->is_reference) {
-               dprintf(fd, "&");
+               PSI_DUMP(dump, "&");
        }
 
        switch (val->kind) {
        case PSI_LET_NULL:
-               dprintf(fd, "NULL");
+               PSI_DUMP(dump, "NULL");
                break;
        case PSI_LET_TMP:
-               psi_decl_var_dump(fd, val->data.var);
-               dprintf(fd, "\t/* fqn=%s */", val->data.var->fqn->val);
+               psi_decl_var_dump(dump, val->data.var);
+               PSI_DUMP(dump, "\t/* fqn=%s */", val->data.var->fqn->val);
                break;
        case PSI_LET_CALLOC:
-               psi_let_calloc_dump(fd, val->data.alloc);
+               psi_let_calloc_dump(dump, val->data.alloc);
                break;
        case PSI_LET_CALLBACK:
-               psi_let_callback_dump(fd, val->data.callback, level);
+               psi_let_callback_dump(dump, val->data.callback, level);
                break;
        case PSI_LET_FUNC:
-               psi_let_func_dump(fd, val->data.func, level);
+               psi_let_func_dump(dump, val->data.func, level);
                break;
        case PSI_LET_NUMEXP:
-               psi_num_exp_dump(fd, val->data.num);
+               psi_num_exp_dump(dump, val->data.num);
                break;
 
        default:
@@ -145,15 +145,15 @@ void psi_let_exp_dump(int fd, struct psi_let_exp *val, unsigned level, int last)
        }
 
        if (val->var) {
-               dprintf(fd, "\t/* fqn=%s */", val->var->fqn->val);
+               PSI_DUMP(dump, "\t/* fqn=%s */", val->var->fqn->val);
        }
 
        if (level > 1) {
                if (!last) {
-                       dprintf(fd, ",");
+                       PSI_DUMP(dump, ",");
                }
        } else {
-               dprintf(fd, ";");
+               PSI_DUMP(dump, ";");
        }
 }
 
index 91cb1ef..caa6cff 100644 (file)
@@ -62,7 +62,7 @@ struct psi_let_exp {
 struct psi_let_exp *psi_let_exp_init(enum psi_let_exp_kind kind, void *data);
 struct psi_let_exp *psi_let_exp_init_ex(struct psi_decl_var *var, enum psi_let_exp_kind kind, void *data);
 void psi_let_exp_free(struct psi_let_exp **let_ptr);
-void psi_let_exp_dump(int fd, struct psi_let_exp *exp, unsigned level, int last);
+void psi_let_exp_dump(struct psi_dump *dump, struct psi_let_exp *exp, unsigned level, int last);
 
 void *psi_let_exp_exec(struct psi_let_exp *exp, struct psi_decl_arg *darg, void *actual_location, size_t actual_size, struct psi_call_frame *frame);
 bool psi_let_exp_validate(struct psi_data *data, struct psi_let_exp *exp, struct psi_validate_scope *scope);
index fd8b49f..4a61632 100644 (file)
@@ -58,26 +58,26 @@ void psi_let_func_free(struct psi_let_func **func_ptr)
        }
 }
 
-void psi_let_func_dump(int fd, struct psi_let_func *func, unsigned level)
+void psi_let_func_dump(struct psi_dump *dump, struct psi_let_func *func, unsigned level)
 {
-       dprintf(fd, "%s(%s\t/* fqn=%s */", func->name->val, func->var->name->val,
+       PSI_DUMP(dump, "%s(%s\t/* fqn=%s */", func->name->val, func->var->name->val,
                        func->var->fqn->val);
 
        if (func->inner) {
                size_t i = 0, count = psi_plist_count(func->inner);
                struct psi_let_exp *inner;
 
-               dprintf(fd, ",");
+               PSI_DUMP(dump, ",");
                ++level;
                while (psi_plist_get(func->inner, i++, &inner)) {
-                       dprintf(fd, "\n");
-                       psi_let_exp_dump(fd, inner, level, i == count);
+                       PSI_DUMP(dump, "\n");
+                       psi_let_exp_dump(dump, inner, level, i == count);
                }
                --level;
-               dprintf(fd, "\n");
-               dprintf(fd, "%s", psi_t_indent(level));
+               PSI_DUMP(dump, "\n");
+               PSI_DUMP(dump, "%s", psi_t_indent(level));
        }
-       dprintf(fd, ")");
+       PSI_DUMP(dump, ")");
 }
 
 static inline int validate_let_func_type(struct psi_data *data,
index 5313a93..957bd97 100644 (file)
@@ -45,7 +45,7 @@ struct psi_let_func {
 
 struct psi_let_func *psi_let_func_init(token_t type, zend_string *name, struct psi_impl_var *var);
 void psi_let_func_free(struct psi_let_func **func_ptr);
-void psi_let_func_dump(int fd, struct psi_let_func *func, unsigned level);
+void psi_let_func_dump(struct psi_dump *dump, struct psi_let_func *func, unsigned level);
 
 void *psi_let_func_exec(struct psi_let_exp *func_val, struct psi_let_func *func, struct psi_decl_arg *darg, struct psi_call_frame *frame);
 bool psi_let_func_validate(struct psi_data *data, struct psi_let_func *func, struct psi_validate_scope *scope);
index c64856b..776d206 100644 (file)
@@ -48,11 +48,11 @@ void psi_let_stmt_free(struct psi_let_stmt **stmt_ptr)
        }
 }
 
-void psi_let_stmt_dump(int fd, struct psi_let_stmt *let)
+void psi_let_stmt_dump(struct psi_dump *dump, struct psi_let_stmt *let)
 {
-       dprintf(fd, "\t%s ", let->exp->kind == PSI_LET_TMP ? "temp" : "let");
-       psi_let_exp_dump(fd, let->exp, 1, 1);
-       dprintf(fd, "\n");
+       PSI_DUMP(dump, "\t%s ", let->exp->kind == PSI_LET_TMP ? "temp" : "let");
+       psi_let_exp_dump(dump, let->exp, 1, 1);
+       PSI_DUMP(dump, "\n");
 }
 
 bool psi_let_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope)
index 37ef118..ab657bc 100644 (file)
@@ -39,7 +39,7 @@ struct psi_let_stmt {
 
 struct psi_let_stmt *psi_let_stmt_init(struct psi_let_exp *exp);
 void psi_let_stmt_free(struct psi_let_stmt **stmt_ptr);
-void psi_let_stmt_dump(int fd, struct psi_let_stmt *stmt);
+void psi_let_stmt_dump(struct psi_dump *dump, struct psi_let_stmt *stmt);
 
 void *psi_let_stmt_exec(struct psi_let_stmt *stmt, struct psi_call_frame *frame);
 bool psi_let_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope);
index ab99dd9..ce89de5 100644 (file)
@@ -380,30 +380,30 @@ struct psi_plist *psi_num_exp_tokens(struct psi_num_exp *exp,
        return list;
 }
 
-void psi_num_exp_dump(int fd, struct psi_num_exp *exp)
+void psi_num_exp_dump(struct psi_dump *dump, struct psi_num_exp *exp)
 {
        switch (exp->op) {
        case PSI_T_NUMBER:
-               psi_number_dump(fd, exp->data.n);
+               psi_number_dump(dump, exp->data.n);
                break;
 
        case PSI_T_CAST:
-               dprintf(fd, "(");
+               PSI_DUMP(dump, "(");
                psi_decl_type_dump(1, exp->data.c.typ, 0);
-               dprintf(fd, ")");
+               PSI_DUMP(dump, ")");
                break;
 
        case PSI_T_NOT:
        case PSI_T_TILDE:
        unary:
-               dprintf(fd, "%s", psi_num_exp_op_tok(exp->op));
-               psi_num_exp_dump(fd, exp->data.u);
+               PSI_DUMP(dump, "%s", psi_num_exp_op_tok(exp->op));
+               psi_num_exp_dump(dump, exp->data.u);
                break;
 
        case PSI_T_LPAREN:
-               dprintf(fd, "(");
-               psi_num_exp_dump(fd, exp->data.u);
-               dprintf(fd, ")");
+               PSI_DUMP(dump, "(");
+               psi_num_exp_dump(dump, exp->data.u);
+               PSI_DUMP(dump, ")");
                break;
 
        case PSI_T_PLUS:
@@ -429,17 +429,17 @@ void psi_num_exp_dump(int fd, struct psi_num_exp *exp)
        case PSI_T_CMP_GE:
        case PSI_T_RCHEVR:
        case PSI_T_LCHEVR:
-               psi_num_exp_dump(fd, exp->data.b.lhs);
-               dprintf(fd, " %s ", psi_num_exp_op_tok(exp->op));
-               psi_num_exp_dump(fd, exp->data.b.rhs);
+               psi_num_exp_dump(dump, exp->data.b.lhs);
+               PSI_DUMP(dump, " %s ", psi_num_exp_op_tok(exp->op));
+               psi_num_exp_dump(dump, exp->data.b.rhs);
                break;
 
        case PSI_T_IIF:
-               psi_num_exp_dump(fd, exp->data.t.cond);
-               dprintf(fd, " ? ");
-               psi_num_exp_dump(fd, exp->data.t.truthy);
-               dprintf(fd, " : ");
-               psi_num_exp_dump(fd, exp->data.t.falsy);
+               psi_num_exp_dump(dump, exp->data.t.cond);
+               PSI_DUMP(dump, " ? ");
+               psi_num_exp_dump(dump, exp->data.t.truthy);
+               PSI_DUMP(dump, " : ");
+               psi_num_exp_dump(dump, exp->data.t.falsy);
                break;
 
        default:
index df7c6f5..db3aaf0 100644 (file)
@@ -77,7 +77,7 @@ void psi_num_exp_free(struct psi_num_exp **c_ptr);
 struct psi_num_exp *psi_num_exp_copy(struct psi_num_exp *exp);
 void psi_num_exp_copy_ctor(struct psi_num_exp **exp_ptr);
 
-void psi_num_exp_dump(int fd, struct psi_num_exp *exp);
+void psi_num_exp_dump(struct psi_dump *dump, struct psi_num_exp *exp);
 bool psi_num_exp_validate(struct psi_data *data, struct psi_num_exp *exp,
                struct psi_validate_scope *scope);
 
index 840eb03..7c05c85 100644 (file)
@@ -292,37 +292,37 @@ struct psi_plist *psi_number_tokens(struct psi_number *exp,
        return list;
 }
 
-void psi_number_dump(int fd, struct psi_number *exp)
+void psi_number_dump(struct psi_dump *dump, struct psi_number *exp)
 {
        switch (exp->type) {
        case PSI_T_DEFINED:
-       CASE_IMPLVAL_NUM_PRINTF(dprintf, fd, exp->data.ival)
+       CASE_IMPLVAL_NUM_PRINTF(dump->fun, dump->ctx, exp->data.ival, 1);
        case PSI_T_NULL:
-               dprintf(fd, "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:
-               dprintf(fd, "%s", exp->data.numb->val);
+               PSI_DUMP(dump, "%s", exp->data.numb->val);
                break;
        case PSI_T_FUNCTION:
-               psi_cpp_macro_call_dump(fd, exp->data.call);
+               psi_cpp_macro_call_dump(dump, exp->data.call);
                break;
        case PSI_T_CONST:
-               dprintf(fd, "%s", exp->data.cnst->name->val);
+               PSI_DUMP(dump, "%s", exp->data.cnst->name->val);
                break;
        case PSI_T_ENUM:
-               dprintf(fd, "%s", exp->data.enm->name->val);
+               PSI_DUMP(dump, "%s", exp->data.enm->name->val);
                break;
        case PSI_T_NAME:
-               psi_decl_var_dump(fd, exp->data.dvar);
+               psi_decl_var_dump(dump, exp->data.dvar);
                break;
        case PSI_T_SIZEOF:
-               dprintf(fd, "sizeof(");
-               psi_decl_type_dump(fd, exp->data.dtyp, 0);
-               dprintf(fd, ")");
+               PSI_DUMP(dump, "sizeof(");
+               psi_decl_type_dump(dump, exp->data.dtyp, 0);
+               PSI_DUMP(dump, ")");
                break;
        default:
                assert(0);
@@ -493,7 +493,6 @@ static inline bool psi_number_validate_number(struct psi_data *data, struct psi_
                case PSI_NUMBER_FLT:
                        switch (exp->flags & 0x0ff00) {
                        case PSI_NUMBER_F:
-                       case PSI_NUMBER_DF:
                                tmp.fval = strtof(exp->data.numb->val, NULL);
                                zend_string_release(exp->data.numb);
                                exp->type = PSI_T_FLOAT;
@@ -510,6 +509,7 @@ static inline bool psi_number_validate_number(struct psi_data *data, struct psi_
 #endif
                        case PSI_NUMBER_DD:
                        default:
+                       case PSI_NUMBER_DF:
                                tmp.dval = strtod(exp->data.numb->val, NULL);
                                zend_string_release(exp->data.numb);
                                exp->type = PSI_T_DOUBLE;
@@ -606,6 +606,10 @@ bool psi_number_validate(struct psi_data *data, struct psi_number *exp,
        case PSI_T_UINT32:
        case PSI_T_INT64:
        case PSI_T_UINT64:
+#if HAVE_INT128
+       case PSI_T_INT128:
+       case PSI_T_UINT128:
+#endif
        case PSI_T_FLOAT:
        case PSI_T_DOUBLE:
 #if HAVE_LONG_DOUBLE
@@ -873,7 +877,16 @@ token_t psi_number_eval(struct psi_number *exp, impl_val *res,
                *res = exp->data.ival;
                if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu64, res->u64);
                return PSI_T_UINT64;
-
+#if HAVE_INT128
+       case PSI_T_INT128:
+               *res = exp->data.ival;
+               //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIi128, res->i128);
+               return PSI_T_INT128;
+       case PSI_T_UINT128:
+               *res = exp->data.ival;
+               //if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIu128, res->u128);
+               return PSI_T_UINT128;
+#endif
        case PSI_T_FLOAT:
                *res = exp->data.ival;
                if (frame) PSI_DEBUG_PRINT(frame->context, " %" PRIfval, res->fval);
index b2a61cc..5d73b5e 100644 (file)
@@ -76,7 +76,7 @@ struct psi_number {
 struct psi_number *psi_number_init(token_t t, void *num, unsigned flags);
 struct psi_number *psi_number_copy(struct psi_number *exp);
 void psi_number_free(struct psi_number **exp_ptr);
-void psi_number_dump(int fd, struct psi_number *exp);
+void psi_number_dump(struct psi_dump *dump, struct psi_number *exp);
 
 bool psi_number_validate(struct psi_data *data, struct psi_number *exp,
                struct psi_validate_scope *scope);
index d66c55c..5d2795a 100644 (file)
@@ -60,30 +60,30 @@ void psi_return_exp_free(struct psi_return_exp **exp_ptr)
        }
 }
 
-void psi_return_exp_dump(int fd, struct psi_return_exp *exp)
+void psi_return_exp_dump(struct psi_dump *dump, struct psi_return_exp *exp)
 {
        if (exp->func) {
-               psi_decl_var_dump(fd, exp->func);
-               dprintf(fd, "(");
+               psi_decl_var_dump(dump, exp->func);
+               PSI_DUMP(dump, "(");
                if (exp->args) {
                        size_t i = 0;
                        struct psi_decl_var *arg;
 
                        while (psi_plist_get(exp->args, i++, &arg)) {
                                if (i > 1) {
-                                       dprintf(fd, ", ");
+                                       PSI_DUMP(dump, ", ");
                                }
-                               psi_decl_var_dump(fd, arg);
+                               psi_decl_var_dump(dump, arg);
                        }
                }
-               dprintf(fd, ")");
+               PSI_DUMP(dump, ")");
        }
        if (exp->set) {
                if (exp->func) {
-                       dprintf(fd, " as ");
+                       PSI_DUMP(dump, " as ");
                }
 
-               psi_set_exp_dump(fd, exp->set, 1, 1);
+               psi_set_exp_dump(dump, exp->set, 1, 1);
        }
 }
 
index b76313a..ead554a 100644 (file)
@@ -36,7 +36,7 @@ struct psi_return_exp {
 struct psi_return_exp *psi_return_exp_init(struct psi_decl_var *func,
                struct psi_plist *args, struct psi_set_exp *set);
 void psi_return_exp_free(struct psi_return_exp **exp_ptr);
-void psi_return_exp_dump(int fd, struct psi_return_exp *exp);
+void psi_return_exp_dump(struct psi_dump *dump, struct psi_return_exp *exp);
 void psi_return_exp_exec(struct psi_return_exp *exp, zval *return_value,
                struct psi_call_frame *frame);
 bool psi_return_exp_validate(struct psi_data *data, struct psi_return_exp *exp,
index 0c4df36..41a17ee 100644 (file)
@@ -52,11 +52,11 @@ void psi_return_stmt_free(struct psi_return_stmt **ret_ptr)
        }
 }
 
-void psi_return_stmt_dump(int fd, struct psi_return_stmt *ret)
+void psi_return_stmt_dump(struct psi_dump *dump, struct psi_return_stmt *ret)
 {
-       dprintf(fd, "\treturn ");
-       psi_return_exp_dump(fd, ret->exp);
-       dprintf(fd, ";\n");
+       PSI_DUMP(dump, "\treturn ");
+       psi_return_exp_dump(dump, ret->exp);
+       PSI_DUMP(dump, ";\n");
 }
 
 bool psi_return_stmt_validate(struct psi_data *data,
index 7d088a6..c030427 100644 (file)
@@ -41,7 +41,7 @@ struct psi_return_stmt {
 
 struct psi_return_stmt *psi_return_stmt_init(struct psi_return_exp *exp);
 void psi_return_stmt_free(struct psi_return_stmt **ret_ptr);
-void psi_return_stmt_dump(int fd, struct psi_return_stmt *ret);
+void psi_return_stmt_dump(struct psi_dump *dump, struct psi_return_stmt *ret);
 void psi_return_stmt_exec(struct psi_return_stmt *ret, zval *return_value, struct psi_call_frame *frame);
 bool psi_return_stmt_validate(struct psi_data *data, struct psi_validate_scope *impl);
 
index aea0747..80c166c 100644 (file)
@@ -123,37 +123,37 @@ void psi_set_exp_free(struct psi_set_exp **exp_ptr)
        }
 }
 
-void psi_set_exp_dump(int fd, struct psi_set_exp *set, unsigned level, int last)
+void psi_set_exp_dump(struct psi_dump *dump, struct psi_set_exp *set, unsigned level, int last)
 {
        if (level > 1) {
                /* only if not directly after `set ...` */
-               dprintf(fd, "%s", psi_t_indent(level));
+               PSI_DUMP(dump, "%s", psi_t_indent(level));
        }
 
        if (set->var) {
                /* parsed, or generated */
                if (set->var->token) {
-                       dprintf(fd, "%s = ", set->var->name->val);
+                       PSI_DUMP(dump, "%s = ", set->var->name->val);
                }
        }
 
        switch (set->kind) {
        case PSI_SET_FUNC:
-               psi_set_func_dump(fd, set->data.func, level);
+               psi_set_func_dump(dump, set->data.func, level);
                break;
        case PSI_SET_NUMEXP:
-               psi_num_exp_dump(fd, set->data.num);
+               psi_num_exp_dump(dump, set->data.num);
                break;
        default:
                assert(0);
        }
 
        if (!last) {
-               dprintf(fd, ",");
+               PSI_DUMP(dump, ",");
        }
 
        if (set->var) {
-               dprintf(fd, "\t/* fqn=%s */", set->var->fqn->val);
+               PSI_DUMP(dump, "\t/* fqn=%s */", set->var->fqn->val);
        }
 }
 
index cf19ff9..151736e 100644 (file)
@@ -54,7 +54,7 @@ struct psi_set_exp {
 
 struct psi_set_exp *psi_set_exp_init(enum psi_set_exp_kind kind, void *data);
 void psi_set_exp_free(struct psi_set_exp **exp_ptr);
-void psi_set_exp_dump(int fd, struct psi_set_exp *set, unsigned level, int last);
+void psi_set_exp_dump(struct psi_dump *dump, struct psi_set_exp *set, unsigned level, int last);
 void psi_set_exp_exec(struct psi_set_exp *val, struct psi_call_frame *frame);
 void psi_set_exp_exec_ex(struct psi_set_exp *val, zval *zv, impl_val *iv, struct psi_call_frame *frame);
 bool psi_set_exp_validate(struct psi_data *data, struct psi_set_exp *set, struct psi_validate_scope *scope);
index caf32ff..96ab6a1 100644 (file)
@@ -51,30 +51,30 @@ void psi_set_func_free(struct psi_set_func **func_ptr)
        }
 }
 
-void psi_set_func_dump(int fd, struct psi_set_func *func, unsigned level)
+void psi_set_func_dump(struct psi_dump *dump, struct psi_set_func *func, unsigned level)
 {
-       dprintf(fd, "%s(", func->name->val);
-       psi_decl_var_dump(fd, func->var);
-       dprintf(fd, "\t/* fqn=%s */", func->var->fqn->val);
+       PSI_DUMP(dump, "%s(", func->name->val);
+       psi_decl_var_dump(dump, func->var);
+       PSI_DUMP(dump, "\t/* fqn=%s */", func->var->fqn->val);
        if (func->inner && !func->recursive) {
                size_t i = 0, count = psi_plist_count(func->inner);
                struct psi_set_exp *inner;
 
-               dprintf(fd, ",");
+               PSI_DUMP(dump, ",");
                ++level;
                while (psi_plist_get(func->inner, i++, &inner)) {
-                       dprintf(fd, "\n");
-                       psi_set_exp_dump(fd, inner, level, i == count);
+                       PSI_DUMP(dump, "\n");
+                       psi_set_exp_dump(dump, inner, level, i == count);
                }
                --level;
        }
        if (func->recursive) {
-               dprintf(fd, ", ...");
+               PSI_DUMP(dump, ", ...");
        }
        if (func->inner && !func->recursive) {
-               dprintf(fd, "\n%s", psi_t_indent(level));
+               PSI_DUMP(dump, "\n%s", psi_t_indent(level));
        }
-       dprintf(fd, ")");
+       PSI_DUMP(dump, ")");
 }
 
 static inline bool psi_set_func_validate_to_string(struct psi_data *data,
index 3f6ef25..8b3b2d4 100644 (file)
@@ -45,7 +45,7 @@ struct psi_set_func {
 
 struct psi_set_func *psi_set_func_init(token_t type, zend_string *name, struct psi_decl_var *var);
 void psi_set_func_free(struct psi_set_func **func_ptr);
-void psi_set_func_dump(int fd, struct psi_set_func *func, unsigned level);
+void psi_set_func_dump(struct psi_dump *dump, struct psi_set_func *func, unsigned level);
 bool psi_set_func_validate(struct psi_data *data, struct psi_set_func *func,
                struct psi_validate_scope *scope);
 
index 1917571..fca2519 100644 (file)
@@ -51,11 +51,11 @@ void psi_set_stmt_free(struct psi_set_stmt **set_ptr)
        }
 }
 
-void psi_set_stmt_dump(int fd, struct psi_set_stmt *set)
+void psi_set_stmt_dump(struct psi_dump *dump, struct psi_set_stmt *set)
 {
-       dprintf(fd, "\tset ");
-       psi_set_exp_dump(fd, set->exp, 1, 1);
-       dprintf(fd, ";\n");
+       PSI_DUMP(dump, "\tset ");
+       psi_set_exp_dump(dump, set->exp, 1, 1);
+       PSI_DUMP(dump, ";\n");
 }
 
 
index a4e40fa..1ca7f93 100644 (file)
@@ -39,7 +39,7 @@ struct psi_set_stmt {
 
 struct psi_set_stmt *psi_set_stmt_init(struct psi_set_exp *val);
 void psi_set_stmt_free(struct psi_set_stmt **set_ptr);
-void psi_set_stmt_dump(int fd, struct psi_set_stmt *set);
+void psi_set_stmt_dump(struct psi_dump *dump, struct psi_set_stmt *set);
 void psi_set_stmt_exec(struct psi_set_stmt *set, struct psi_call_frame *frame);
 bool psi_set_stmts_validate(struct psi_data *data, struct psi_validate_scope *scope);