fix varargs support
authorMichael Wallner <mike@php.net>
Mon, 15 Feb 2016 13:44:06 +0000 (14:44 +0100)
committerMichael Wallner <mike@php.net>
Mon, 15 Feb 2016 13:44:06 +0000 (14:44 +0100)
src/engine.c
src/marshal.c
src/parser.h
tests/stdio/printf001.phpt [new file with mode: 0644]

index 447e0d7f2b8983d6d4092401c9b7389e88b09408..aa4feeb87d1e0e5ef66e0cede6d1fe1c76bf2ab3 100644 (file)
@@ -449,7 +449,8 @@ static inline impl_vararg *psi_do_varargs(impl *impl) {
        for (i = 0, j = 0; i < vacount; ++i) {
                impl_arg *vaarg = va->args->args[i];
                void *to_free = NULL;
-               token_t let_fn, vatype = va->name->type->type;
+               token_t vatype = va->name->type->type;
+               let_func_handler let_fn;
 
                if (vatype == PSI_T_MIXED) {
                        switch (Z_TYPE_P(vaarg->_zv)) {
@@ -463,17 +464,19 @@ static inline impl_vararg *psi_do_varargs(impl *impl) {
 
 
                switch (vatype) {
-               case PSI_T_BOOL:        let_fn = PSI_T_BOOLVAL; break;
-               case PSI_T_INT:         let_fn = PSI_T_INTVAL;  break;
+               case PSI_T_BOOL:        let_fn = psi_let_boolval;       break;
+               case PSI_T_INT:         let_fn = psi_let_intval;        break;
                case PSI_T_FLOAT:
-               case PSI_T_DOUBLE:      let_fn = PSI_T_FLOATVAL;break;
-               case PSI_T_STRING:      let_fn = PSI_T_STRVAL;  break;
+               case PSI_T_DOUBLE:      let_fn = psi_let_floatval;      break;
+               case PSI_T_STRING:      let_fn = psi_let_strval;        break;
                EMPTY_SWITCH_DEFAULT_CASE();
                }
 
                va->types[i] = vatype;
+
                /* FIXME: varargs with struct-by-value :) */
-               if (!psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free)) {
+               //if (!psi_let_val(let_fn, vaarg, &va->values[i], NULL, &to_free)) {
+               if (!let_fn(&va->values[i], NULL, vaarg, &to_free)) {
                        return NULL;
                }
 
index f204753bfbf9190c13a0eb96f5bea4769a46f5b1..2ec332953e250ec3a24c989e578d1566d8bda569 100644 (file)
@@ -106,9 +106,10 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo
        case PSI_T_UINT16:              tmp->u16 = intval;              break;
        case PSI_T_INT32:               tmp->i32 = intval;              break;
        case PSI_T_UINT32:              tmp->u32 = intval;              break;
-       case PSI_T_INT:                 tmp->ival = intval;             break;
        case PSI_T_INT64:               tmp->i64 = intval;              break;
        case PSI_T_UINT64:              tmp->u64 = intval;              break;
+       case PSI_T_INT:                 tmp->ival = intval;             break;
+       case PSI_T_LONG:                tmp->lval = intval;             break;
        case PSI_T_FLOAT:               tmp->fval = intval;             break;
        case PSI_T_DOUBLE:              tmp->dval = intval;             break;
 #ifdef HAVE_LONG_DOUBLE
@@ -123,7 +124,7 @@ static inline impl_val *psi_val_intval(impl_val *tmp, token_t real_type, zend_lo
 impl_val *psi_let_intval(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free)
 {
        zend_long intval;
-       token_t real_type = type ? real_decl_type(type)->type : PSI_T_INT;
+       token_t real_type = type ? real_decl_type(type)->type : PSI_T_LONG;
 
        if (iarg->type->type == PSI_T_INT) {
                intval = iarg->val.zend.lval;
index 34e849e712dc38a4ed4e90f90ce3df985592b4db..c9e9f752bb8f8747693229f4b79751f68f7aa1fa 100644 (file)
@@ -919,11 +919,13 @@ static inline void free_let_callback(let_callback *cb) {
        free(cb);
 }
 
+typedef impl_val *(*let_func_handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free);
+
 typedef struct let_func {
        token_t type;
        char *name;
        impl_var *var;
-       impl_val *(*handler)(impl_val *tmp, decl_type *type, impl_arg *iarg, void **to_free);
+       let_func_handler handler;
 } let_func;
 
 static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
diff --git a/tests/stdio/printf001.phpt b/tests/stdio/printf001.phpt
new file mode 100644 (file)
index 0000000..cd1527d
--- /dev/null
@@ -0,0 +1,20 @@
+--TEST--
+printf
+--SKIPIF--
+<?php 
+extension_loaded("psi") or die("skip - need ext/psi");
+?>
+--ENV--
+LC_ALL=C
+--INI--
+psi.directory={PWD}/../../psi.d:{PWD}
+--FILE--
+===TEST===
+<?php
+psi\printf("%.*s %ld %f\n", 5, "hello world", 123456789, .987654321);
+?>
+===DONE===
+--EXPECT--
+===TEST===
+hello 123456789 0.987654
+===DONE===