]> granicus.if.org Git - php/commitdiff
Accept numeric strings for dates.
authorGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 6 May 2012 16:12:53 +0000 (18:12 +0200)
committerGustavo André dos Santos Lopes <cataphract@php.net>
Sun, 13 May 2012 19:53:06 +0000 (20:53 +0100)
Refactored umsg_helper_zval_to_millis in the process.

ext/intl/msgformat/msgformat_helpers.cpp

index 1a7dc89c87b70e72bbeb54f09d237f00c653aeaf..7a2770133e15c43d2bfe638ea205cfcb7b83d5b5 100755 (executable)
@@ -22,6 +22,7 @@
 #include <stdio.h>
 
 #include <math.h>
+#include <limits.h>
 #include <unicode/msgfmt.h>
 #include <unicode/chariter.h>
 #include <unicode/messagepattern.h>
@@ -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;
 }