From 0ad1b14f16262f77372620992a72dd3f12c5e24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Andr=C3=A9=20dos=20Santos=20Lopes?= Date: Sun, 6 May 2012 18:12:53 +0200 Subject: Accept numeric strings for dates. Refactored umsg_helper_zval_to_millis in the process. --- ext/intl/msgformat/msgformat_helpers.cpp | 49 ++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'ext/intl/msgformat/msgformat_helpers.cpp') diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index 1a7dc89c87..7a2770133e 100755 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,14 @@ extern "C" { #include "ext/date/php_date.h" } +#ifndef INFINITY +#define INFINITY (DBL_MAX+DBL_MAX) +#endif + +#ifndef NAN +#define NAN (INFINITY-INFINITY) +#endif + U_NAMESPACE_BEGIN /** * This class isolates our access to private internal methods of @@ -72,14 +81,33 @@ U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt) return fmt_count; } -double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC) { - double rv = 0.0; - if (Z_TYPE_P(z) == IS_DOUBLE) { - rv = U_MILLIS_PER_SECOND * Z_DVAL_P(z); - } else if (Z_TYPE_P(z) == IS_LONG) { +static double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC) { + double rv = NAN; + long lv; + int type; + + if (U_FAILURE(*status)) { + return NAN; + } + + switch (Z_TYPE_P(z)) { + case IS_STRING: + type = is_numeric_string(Z_STRVAL_P(z), Z_STRLEN_P(z), &lv, &rv, 0); + if (type == IS_DOUBLE) { + rv *= U_MILLIS_PER_SECOND; + } else if (type == IS_LONG) { + rv = U_MILLIS_PER_SECOND * (double)lv; + } else { + *status = U_ILLEGAL_ARGUMENT_ERROR; + } + break; + case IS_LONG: rv = U_MILLIS_PER_SECOND * (double)Z_LVAL_P(z); - } else if (Z_TYPE_P(z) == IS_OBJECT) { - /* Borrowed from datefmt_format() in intl/dateformat/dateformat_format.c */ + break; + case IS_DOUBLE: + rv = U_MILLIS_PER_SECOND * Z_DVAL_P(z); + break; + case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(z), php_date_get_date_ce() TSRMLS_CC)) { zval retval; zval *zfuncname; @@ -88,15 +116,20 @@ double umsg_helper_zval_to_millis(zval *z, UErrorCode *status TSRMLS_DC) { ZVAL_STRING(zfuncname, "getTimestamp", 1); if (call_user_function(NULL, &(z), zfuncname, &retval, 0, NULL TSRMLS_CC) != SUCCESS || Z_TYPE(retval) != IS_LONG) { - *status = U_RESOURCE_TYPE_MISMATCH; + *status = U_INTERNAL_PROGRAM_ERROR; } else { rv = U_MILLIS_PER_SECOND * (double)Z_LVAL(retval); } zval_ptr_dtor(&zfuncname); } else { + /* TODO: try with cast(), get() to obtain a number */ *status = U_ILLEGAL_ARGUMENT_ERROR; } + break; + default: + *status = U_ILLEGAL_ARGUMENT_ERROR; } + return rv; } -- cgit v1.2.1