PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/intl/calendar - calendar_methods.cpp (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 452 511 88.5 %
Date: 2016-06-25 Functions: 46 51 90.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | This source file is subject to version 3.01 of the PHP license,      |
       6             :    | that is bundled with this package in the file LICENSE, and is        |
       7             :    | available through the world-wide-web at the following url:           |
       8             :    | http://www.php.net/license/3_01.txt                                  |
       9             :    | If you did not receive a copy of the PHP license and are unable to   |
      10             :    | obtain it through the world-wide-web, please send a note to          |
      11             :    | license@php.net so we can mail you a copy immediately.               |
      12             :    +----------------------------------------------------------------------+
      13             :    | Authors: Gustavo Lopes <cataphract@php.net>                          |
      14             :    +----------------------------------------------------------------------+
      15             : */
      16             : 
      17             : #ifdef HAVE_CONFIG_H
      18             : #include "config.h"
      19             : #endif
      20             : 
      21             : #include "../intl_cppshims.h"
      22             : 
      23             : #include <unicode/locid.h>
      24             : #include <unicode/calendar.h>
      25             : #include <unicode/ustring.h>
      26             : 
      27             : #include "../intl_convertcpp.h"
      28             : #include "../common/common_date.h"
      29             : 
      30             : extern "C" {
      31             : #include "../php_intl.h"
      32             : #define USE_TIMEZONE_POINTER 1
      33             : #include "../timezone/timezone_class.h"
      34             : #define USE_CALENDAR_POINTER 1
      35             : #include "calendar_class.h"
      36             : #include "../intl_convert.h"
      37             : #include <zend_exceptions.h>
      38             : #include <zend_interfaces.h>
      39             : #include <ext/date/php_date.h>
      40             : }
      41             : #include "../common/common_enum.h"
      42             : 
      43           0 : U_CFUNC PHP_METHOD(IntlCalendar, __construct)
      44             : {
      45             :         zend_throw_exception( NULL,
      46             :                 "An object of this type cannot be created with the new operator",
      47           0 :                 0 );
      48           0 : }
      49             : 
      50          35 : U_CFUNC PHP_FUNCTION(intlcal_create_instance)
      51             : {
      52          35 :         zval            *zv_timezone    = NULL;
      53          35 :         const char      *locale_str             = NULL;
      54             :         size_t                  dummy;
      55             :         TimeZone        *timeZone;
      56          35 :         UErrorCode      status                  = U_ZERO_ERROR;
      57          35 :         intl_error_reset(NULL);
      58             : 
      59          35 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "|zs!",
      60             :                         &zv_timezone, &locale_str, &dummy) == FAILURE) {
      61             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
      62           3 :                         "intlcal_create_calendar: bad arguments", 0);
      63           3 :                 RETURN_NULL();
      64             :         }
      65             : 
      66             :         timeZone = timezone_process_timezone_argument(zv_timezone, NULL,
      67          32 :                 "intlcal_create_instance");
      68          32 :         if (timeZone == NULL) {
      69           1 :                 RETURN_NULL();
      70             :         }
      71             : 
      72          31 :         if (!locale_str) {
      73          26 :                 locale_str = intl_locale_get_default();
      74             :         }
      75             : 
      76             :         Calendar *cal = Calendar::createInstance(timeZone,
      77          31 :                 Locale::createFromName(locale_str), status);
      78          31 :         if (cal == NULL) {
      79           0 :                 delete timeZone;
      80           0 :                 intl_error_set(NULL, status, "Error creating ICU Calendar object", 0);
      81           0 :                 RETURN_NULL();
      82             :         }
      83             : 
      84          31 :         calendar_object_create(return_value, cal);
      85             : }
      86             : 
      87             : #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 42
      88             : class BugStringCharEnumeration : public StringEnumeration
      89             : {
      90             : public:
      91           2 :         BugStringCharEnumeration(UEnumeration* _uenum) : uenum(_uenum) {}
      92             : 
      93           4 :         ~BugStringCharEnumeration()
      94           2 :         {
      95           2 :                 uenum_close(uenum);
      96           2 :         }
      97             : 
      98           0 :         int32_t count(UErrorCode& status) const {
      99           0 :                 return uenum_count(uenum, &status);
     100             :         }
     101             : 
     102           0 :         virtual const UnicodeString* snext(UErrorCode& status)
     103             :         {
     104             :                 int32_t length;
     105           0 :                 const UChar* str = uenum_unext(uenum, &length, &status);
     106           0 :                 if (str == 0 || U_FAILURE(status)) {
     107           0 :                         return 0;
     108             :                 }
     109           0 :                 return &unistr.setTo(str, length);
     110             :         }
     111             : 
     112          16 :         virtual const char* next(int32_t *resultLength, UErrorCode &status)
     113             :         {
     114          16 :                 int32_t length = -1;
     115          16 :                 const char* str = uenum_next(uenum, &length, &status);
     116          16 :                 if (str == 0 || U_FAILURE(status)) {
     117           2 :                         return 0;
     118             :                 }
     119          14 :                 if (resultLength) {
     120             :                         //the bug is that uenum_next doesn't set the length
     121          14 :                         *resultLength = (length == -1) ? strlen(str) : length;
     122             :                 }
     123             : 
     124          14 :                 return str;
     125             :         }
     126             : 
     127           2 :         void reset(UErrorCode& status)
     128             :         {
     129           2 :                 uenum_reset(uenum, &status);
     130           2 :         }
     131             : 
     132             :         virtual UClassID getDynamicClassID() const;
     133             : 
     134             :         static UClassID U_EXPORT2 getStaticClassID();
     135             : 
     136             : private:
     137             :         UEnumeration *uenum;
     138             : };
     139           0 : UOBJECT_DEFINE_RTTI_IMPLEMENTATION(BugStringCharEnumeration)
     140             : 
     141           5 : U_CFUNC PHP_FUNCTION(intlcal_get_keyword_values_for_locale)
     142             : {
     143           5 :         UErrorCode      status = U_ZERO_ERROR;
     144             :         char            *key,
     145             :                                 *locale;
     146             :         size_t                  key_len,
     147             :                                 locale_len;
     148             :         zend_bool       commonly_used;
     149           5 :         intl_error_reset(NULL);
     150             : 
     151           5 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssb",
     152             :                         &key, &key_len, &locale, &locale_len, &commonly_used) == FAILURE) {
     153             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     154           3 :                         "intlcal_get_keyword_values_for_locale: bad arguments", 0);
     155           3 :                 RETURN_FALSE;
     156             :         }
     157             : 
     158             :         //does not work; see ICU bug 9194
     159             : #if 0
     160             :         StringEnumeration *se = Calendar::getKeywordValuesForLocale(key,
     161             :                 Locale::createFromName(locale), (UBool)commonly_used,
     162             :                 status);
     163             :         if (se == NULL) {
     164             :                 intl_error_set(NULL, status, "intlcal_get_keyword_values_for_locale: "
     165             :                         "error calling underlying method", 0);
     166             :                 RETURN_FALSE;
     167             :         }
     168             : #else
     169             :     UEnumeration *uenum = ucal_getKeywordValuesForLocale(
     170           2 :                 key, locale, !!commonly_used, &status);
     171           2 :     if (U_FAILURE(status)) {
     172           0 :         uenum_close(uenum);
     173             :                 intl_error_set(NULL, status, "intlcal_get_keyword_values_for_locale: "
     174           0 :                         "error calling underlying method", 0);
     175           0 :         RETURN_FALSE;
     176             :     }
     177             : 
     178           2 :     StringEnumeration *se = new BugStringCharEnumeration(uenum);
     179             : #endif
     180             : 
     181           2 :         IntlIterator_from_StringEnumeration(se, return_value);
     182             : }
     183             : #endif //ICU 4.2 only
     184             : 
     185           4 : U_CFUNC PHP_FUNCTION(intlcal_get_now)
     186             : {
     187           4 :         intl_error_reset(NULL);
     188             : 
     189           4 :         if (zend_parse_parameters_none() == FAILURE) {
     190             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     191           2 :                         "intlcal_get_now: bad arguments", 0);
     192           2 :                 RETURN_FALSE;
     193             :         }
     194             : 
     195           2 :         RETURN_DOUBLE((double)Calendar::getNow());
     196             : }
     197             : 
     198           4 : U_CFUNC PHP_FUNCTION(intlcal_get_available_locales)
     199             : {
     200           4 :         intl_error_reset(NULL);
     201             : 
     202           4 :         if (zend_parse_parameters_none() == FAILURE) {
     203             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     204           2 :                         "intlcal_get_available_locales: bad arguments", 0);
     205           2 :                 RETURN_FALSE;
     206             :         }
     207             : 
     208             :         int32_t count;
     209           2 :         const Locale *availLocales = Calendar::getAvailableLocales(count);
     210           2 :         array_init(return_value);
     211           2 :         for (int i = 0; i < count; i++) {
     212         584 :                 Locale locale = availLocales[i];
     213         584 :                 add_next_index_string(return_value, locale.getName());
     214             :         }
     215             : }
     216             : 
     217          47 : static void _php_intlcal_field_uec_ret_in32t_method(
     218             :                 int32_t (Calendar::*func)(UCalendarDateFields, UErrorCode&) const,
     219             :                 const char *method_name,
     220             :                 INTERNAL_FUNCTION_PARAMETERS)
     221             : {
     222             :         zend_long       field;
     223             :         char    *message;
     224          47 :         CALENDAR_METHOD_INIT_VARS;
     225             : 
     226          47 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     227             :                         "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
     228          15 :                 spprintf(&message, 0, "%s: bad arguments", method_name);
     229          15 :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
     230          15 :                 efree(message);
     231          15 :                 RETURN_FALSE;
     232             :         }
     233             : 
     234          32 :         if (field < 0 || field >= UCAL_FIELD_COUNT) {
     235           6 :                 spprintf(&message, 0, "%s: invalid field", method_name);
     236           6 :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
     237           6 :                 efree(message);
     238           6 :                 RETURN_FALSE;
     239             :         }
     240             : 
     241          26 :         CALENDAR_METHOD_FETCH_OBJECT;
     242             : 
     243             :         int32_t result = (co->ucal->*func)(
     244          26 :                 (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co));
     245          26 :         INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
     246             : 
     247          26 :         RETURN_LONG((zend_long)result);
     248             : }
     249             : 
     250          29 : U_CFUNC PHP_FUNCTION(intlcal_get)
     251             : {
     252             :         _php_intlcal_field_uec_ret_in32t_method(&Calendar::get,
     253          29 :                 "intlcal_get", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     254          29 : }
     255             : 
     256          17 : U_CFUNC PHP_FUNCTION(intlcal_get_time)
     257             : {
     258          17 :         CALENDAR_METHOD_INIT_VARS;
     259             : 
     260          17 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
     261             :                         &object, Calendar_ce_ptr) == FAILURE) {
     262             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     263           2 :                         "intlcal_get_time: bad arguments", 0);
     264           2 :                 RETURN_FALSE;
     265             :         }
     266             : 
     267          15 :         CALENDAR_METHOD_FETCH_OBJECT;
     268             : 
     269          15 :         UDate result = co->ucal->getTime(CALENDAR_ERROR_CODE(co));
     270          15 :         INTL_METHOD_CHECK_STATUS(co,
     271             :                 "intlcal_get_time: error calling ICU Calendar::getTime");
     272             : 
     273          15 :         RETURN_DOUBLE((double)result);
     274             : }
     275             : 
     276          15 : U_CFUNC PHP_FUNCTION(intlcal_set_time)
     277             : {
     278             :         double  time_arg;
     279          15 :         CALENDAR_METHOD_INIT_VARS;
     280             : 
     281          15 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Od",
     282             :                         &object, Calendar_ce_ptr, &time_arg) == FAILURE) {
     283             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     284           3 :                         "intlcal_set_time: bad arguments", 0);
     285           3 :                 RETURN_FALSE;
     286             :         }
     287             : 
     288          12 :         CALENDAR_METHOD_FETCH_OBJECT;
     289             : 
     290          12 :         co->ucal->setTime((UDate)time_arg, CALENDAR_ERROR_CODE(co));
     291          12 :         INTL_METHOD_CHECK_STATUS(co, "Call to underlying method failed");
     292             : 
     293          12 :         RETURN_TRUE;
     294             : }
     295             : 
     296           9 : U_CFUNC PHP_FUNCTION(intlcal_add)
     297             : {
     298             :         zend_long       field,
     299             :                         amount;
     300           9 :         CALENDAR_METHOD_INIT_VARS;
     301             : 
     302           9 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     303             :                         "Oll", &object, Calendar_ce_ptr, &field, &amount) == FAILURE) {
     304             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     305           3 :                         "intlcal_add: bad arguments", 0);
     306           3 :                 RETURN_FALSE;
     307             :         }
     308             : 
     309           6 :         if (field < 0 || field >= UCAL_FIELD_COUNT) {
     310             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     311           1 :                         "intlcal_add: invalid field", 0);
     312           1 :                 RETURN_FALSE;
     313             :         }
     314           5 :         if (amount < INT32_MIN || amount > INT32_MAX) {
     315             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     316           0 :                         "intlcal_add: amount out of bounds", 0);
     317           0 :                 RETURN_FALSE;
     318             :         }
     319             : 
     320           5 :         CALENDAR_METHOD_FETCH_OBJECT;
     321             : 
     322           5 :         co->ucal->add((UCalendarDateFields)field, (int32_t)amount, CALENDAR_ERROR_CODE(co));
     323           5 :         INTL_METHOD_CHECK_STATUS(co, "intlcal_add: Call to underlying method failed");
     324             : 
     325           5 :         RETURN_TRUE;
     326             : }
     327             : 
     328          10 : U_CFUNC PHP_FUNCTION(intlcal_set_time_zone)
     329             : {
     330             :         zval                    *zv_timezone;
     331             :         TimeZone                *timeZone;
     332          10 :         CALENDAR_METHOD_INIT_VARS;
     333             : 
     334          10 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     335             :                         "Oz!", &object, Calendar_ce_ptr, &zv_timezone) == FAILURE) {
     336             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     337           3 :                         "intlcal_set_time_zone: bad arguments", 0);
     338           3 :                 RETURN_FALSE;
     339             :         }
     340             : 
     341           7 :         CALENDAR_METHOD_FETCH_OBJECT;
     342             : 
     343           7 :         if (zv_timezone == NULL) {
     344           1 :                 RETURN_TRUE; /* the method does nothing if passed null */
     345             :         }
     346             : 
     347             :         timeZone = timezone_process_timezone_argument(zv_timezone,
     348           6 :                         CALENDAR_ERROR_P(co), "intlcal_set_time_zone");
     349           6 :         if (timeZone == NULL) {
     350           2 :                 RETURN_FALSE;
     351             :         }
     352             : 
     353           4 :         co->ucal->adoptTimeZone(timeZone);
     354             : 
     355           4 :         RETURN_TRUE;
     356             : }
     357             : 
     358             : 
     359          12 : static void _php_intlcal_before_after(
     360             :                 UBool (Calendar::*func)(const Calendar&, UErrorCode&) const,
     361             :                 INTERNAL_FUNCTION_PARAMETERS)
     362             : {
     363             :         zval                    *when_object;
     364             :         Calendar_object *when_co;
     365          12 :         CALENDAR_METHOD_INIT_VARS;
     366             : 
     367          12 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     368             :                         "OO", &object, Calendar_ce_ptr, &when_object, Calendar_ce_ptr)
     369             :                         == FAILURE) {
     370             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     371           6 :                         "intlcal_before/after: bad arguments", 0);
     372           6 :                 RETURN_FALSE;
     373             :         }
     374             : 
     375           6 :         CALENDAR_METHOD_FETCH_OBJECT;
     376             : 
     377           6 :         when_co = Z_INTL_CALENDAR_P(when_object);
     378           6 :         if (when_co->ucal == NULL) {
     379             :                 intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
     380           0 :                         "intlcal_before/after: Other IntlCalendar was unconstructed", 0);
     381           0 :                 RETURN_FALSE;
     382             :         }
     383             : 
     384           6 :         UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co));
     385           6 :         INTL_METHOD_CHECK_STATUS(co, "intlcal_before/after: Error calling ICU method");
     386             : 
     387           6 :         RETURN_BOOL((int)res);
     388             : }
     389             : 
     390           6 : U_CFUNC PHP_FUNCTION(intlcal_after)
     391             : {
     392           6 :         _php_intlcal_before_after(&Calendar::after, INTERNAL_FUNCTION_PARAM_PASSTHRU);
     393           6 : }
     394             : 
     395           6 : U_CFUNC PHP_FUNCTION(intlcal_before)
     396             : {
     397           6 :         _php_intlcal_before_after(&Calendar::before, INTERNAL_FUNCTION_PARAM_PASSTHRU);
     398           6 : }
     399             : 
     400          15 : U_CFUNC PHP_FUNCTION(intlcal_set)
     401             : {
     402             :         zend_long       arg1, arg2, arg3, arg4, arg5, arg6;
     403          15 :         zval    args_a[7] = {0},
     404          15 :                         *args = args_a;
     405             :         int             i;
     406             :         int             variant; /* number of args of the set() overload */
     407          15 :         CALENDAR_METHOD_INIT_VARS;
     408             : 
     409             :         /* must come before zpp because zpp would convert the args in the stack to 0 */
     410          15 :         if (ZEND_NUM_ARGS() > (getThis() ? 6 : 7) ||
     411             :                                 zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
     412             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     413           1 :                         "intlcal_set: too many arguments", 0);
     414           1 :                 RETURN_FALSE;
     415             :         }
     416          14 :         if (!getThis()) {
     417           2 :                 args++;
     418             :         }
     419          14 :         variant = ZEND_NUM_ARGS() - (getThis() ? 0 : 1);
     420          32 :         while (variant > 2 && Z_TYPE(args[variant - 1]) == IS_NULL) {
     421           0 :                 variant--;
     422             :         }
     423             : 
     424          14 :         if (variant == 4 ||
     425             :                         zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     426             :                         "Oll|llll",   &object, Calendar_ce_ptr, &arg1, &arg2, &arg3, &arg4,
     427             :                         &arg5, &arg6) == FAILURE) {
     428             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     429           2 :                         "intlcal_set: bad arguments", 0);
     430           2 :                 RETURN_FALSE;
     431             :         }
     432             : 
     433          44 :         for (i = 0; i < variant; i++) {
     434          32 :                 if (Z_LVAL(args[i]) < INT32_MIN || Z_LVAL(args[i]) > INT32_MAX) {
     435             :                         intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     436             :                                 "intlcal_set: at least one of the arguments has an absolute "
     437           0 :                                 "value that is too large", 0);
     438           0 :                         RETURN_FALSE;
     439             :                 }
     440             :         }
     441             : 
     442          12 :         if (variant == 2 && (arg1 < 0 || arg1 >= UCAL_FIELD_COUNT)) {
     443             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     444           2 :                         "intlcal_set: invalid field", 0);
     445           2 :                 RETURN_FALSE;
     446             :         }
     447             : 
     448          10 :         CALENDAR_METHOD_FETCH_OBJECT;
     449             : 
     450          10 :         if (variant == 2) {
     451           7 :                 co->ucal->set((UCalendarDateFields)arg1, (int32_t)arg2);
     452           3 :         } else if (variant == 3) {
     453           1 :                 co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3);
     454           2 :         } else if (variant == 5) {
     455           1 :                 co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5);
     456           1 :         } else if (variant == 6) {
     457           1 :                 co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5, (int32_t)arg6);
     458             :         }
     459             : 
     460          10 :         RETURN_TRUE;
     461             : }
     462             : 
     463           9 : U_CFUNC PHP_FUNCTION(intlcal_roll)
     464             : {
     465             :         zend_long               field,
     466             :                                 value;
     467           9 :         zval            args_a[3]                = {0},
     468           9 :                                 *args                    = args_a;
     469           9 :         zend_bool       bool_variant_val = (zend_bool)-1;
     470           9 :         CALENDAR_METHOD_INIT_VARS;
     471             : 
     472           9 :         if (ZEND_NUM_ARGS() > (getThis() ? 2 :3) ||
     473             :                         zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
     474             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     475           2 :                         "intlcal_set: too many arguments", 0);
     476           2 :                 RETURN_FALSE;
     477             :         }
     478           7 :         if (!getThis()) {
     479           2 :                 args++;
     480             :         }
     481          24 :         if (!Z_ISUNDEF(args[1]) && (Z_TYPE(args[1]) == IS_TRUE || Z_TYPE(args[1]) == IS_FALSE)) {
     482           3 :                 if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     483             :                                 "Olb", &object, Calendar_ce_ptr, &field, &bool_variant_val)
     484             :                                 == FAILURE) {
     485             :                         intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     486           0 :                                 "intlcal_roll: bad arguments", 0);
     487           0 :                         RETURN_FALSE;
     488             :                 }
     489           6 :                 bool_variant_val = Z_TYPE(args[1]) == IS_TRUE? 1 : 0;
     490           4 :         } else if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     491             :                         "Oll", &object, Calendar_ce_ptr, &field, &value) == FAILURE) {
     492             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     493           1 :                         "intlcal_roll: bad arguments", 0);
     494           1 :                 RETURN_FALSE;
     495             :         }
     496             : 
     497           6 :         if (field < 0 || field >= UCAL_FIELD_COUNT) {
     498             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     499           1 :                         "intlcal_roll: invalid field", 0);
     500           1 :                 RETURN_FALSE;
     501             :         }
     502           5 :         if (bool_variant_val == (zend_bool)-1 &&
     503             :                         (value < INT32_MIN || value > INT32_MAX)) {
     504             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     505           0 :                         "intlcal_roll: value out of bounds", 0);
     506           0 :                 RETURN_FALSE;
     507             :         }
     508             : 
     509           5 :         CALENDAR_METHOD_FETCH_OBJECT;
     510             : 
     511           5 :         if (bool_variant_val != (zend_bool)-1) {
     512             :                 co->ucal->roll((UCalendarDateFields)field, (UBool)bool_variant_val,
     513           3 :                         CALENDAR_ERROR_CODE(co));
     514             :         } else {
     515             :                 co->ucal->roll((UCalendarDateFields)field, (int32_t)value,
     516           2 :                         CALENDAR_ERROR_CODE(co));
     517             :         }
     518           5 :         INTL_METHOD_CHECK_STATUS(co, "intlcal_roll: Error calling ICU Calendar::roll");
     519             : 
     520           5 :         RETURN_TRUE;
     521             : }
     522             : 
     523           9 : U_CFUNC PHP_FUNCTION(intlcal_clear)
     524             : {
     525             :         zend_long field;
     526           9 :         zend_bool field_is_null = 1;
     527           9 :         CALENDAR_METHOD_INIT_VARS;
     528             : 
     529           9 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(),
     530             :                         getThis(), "O|l!", &object, Calendar_ce_ptr, &field, &field_is_null) == FAILURE) {
     531             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     532           1 :                         "intlcal_clear: bad arguments", 0);
     533           1 :                 RETURN_FALSE;
     534             :         }
     535             : 
     536           8 :         CALENDAR_METHOD_FETCH_OBJECT;
     537             : 
     538           8 :         if (field_is_null) {
     539           4 :                 co->ucal->clear();
     540             :         } else {
     541           4 :                 if (field < 0 || field >= UCAL_FIELD_COUNT) {
     542             :                         intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     543           2 :                                 "intlcal_clear: invalid field", 0);
     544           2 :                         RETURN_FALSE;
     545             :                 }
     546             : 
     547           2 :                 co->ucal->clear((UCalendarDateFields)field);
     548             :         }
     549             : 
     550           6 :         RETURN_TRUE;
     551             : }
     552             : 
     553           7 : U_CFUNC PHP_FUNCTION(intlcal_field_difference)
     554             : {
     555             :         zend_long       field;
     556             :         double  when;
     557           7 :         CALENDAR_METHOD_INIT_VARS;
     558             : 
     559           7 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     560             :                         "Odl", &object, Calendar_ce_ptr, &when, &field)   == FAILURE) {
     561             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     562           3 :                         "intlcal_field_difference: bad arguments", 0);
     563           3 :                 RETURN_FALSE;
     564             :         }
     565             : 
     566           4 :         if (field < 0 || field >= UCAL_FIELD_COUNT) {
     567             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     568           0 :                         "intlcal_field_difference: invalid field", 0);
     569           0 :                 RETURN_FALSE;
     570             :         }
     571             : 
     572           4 :         CALENDAR_METHOD_FETCH_OBJECT;
     573             : 
     574             :         int32_t result = co->ucal->fieldDifference((UDate)when,
     575           4 :                 (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co));
     576           4 :         INTL_METHOD_CHECK_STATUS(co,
     577             :                 "intlcal_field_difference: Call to ICU method has failed");
     578             : 
     579           2 :         RETURN_LONG((zend_long)result);
     580             : }
     581             : 
     582           9 : U_CFUNC PHP_FUNCTION(intlcal_get_actual_maximum)
     583             : {
     584             :         _php_intlcal_field_uec_ret_in32t_method(&Calendar::getActualMaximum,
     585           9 :                 "intlcal_get_actual_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     586           9 : }
     587             : 
     588           9 : U_CFUNC PHP_FUNCTION(intlcal_get_actual_minimum)
     589             : {
     590             :         _php_intlcal_field_uec_ret_in32t_method(&Calendar::getActualMinimum,
     591           9 :                 "intlcal_get_actual_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     592           9 : }
     593             : 
     594             : #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
     595             : U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type)
     596             : {
     597             :         zend_long       dow;
     598             :         CALENDAR_METHOD_INIT_VARS;
     599             : 
     600             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     601             :                         "Ol", &object, Calendar_ce_ptr, &dow) == FAILURE) {
     602             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     603             :                         "intlcal_get_day_of_week_type: bad arguments", 0);
     604             :                 RETURN_FALSE;
     605             :         }
     606             : 
     607             :         if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
     608             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     609             :                         "intlcal_get_day_of_week_type: invalid day of week", 0);
     610             :                 RETURN_FALSE;
     611             :         }
     612             : 
     613             :         CALENDAR_METHOD_FETCH_OBJECT;
     614             : 
     615             :         int32_t result = co->ucal->getDayOfWeekType(
     616             :                 (UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co));
     617             :         INTL_METHOD_CHECK_STATUS(co,
     618             :                 "intlcal_get_day_of_week_type: Call to ICU method has failed");
     619             : 
     620             :         RETURN_LONG((zend_long)result);
     621             : }
     622             : #endif
     623             : 
     624           6 : U_CFUNC PHP_FUNCTION(intlcal_get_first_day_of_week)
     625             : {
     626           6 :         CALENDAR_METHOD_INIT_VARS;
     627             : 
     628           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     629             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
     630             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     631           2 :                         "intlcal_get_first_day_of_week: bad arguments", 0);
     632           2 :                 RETURN_FALSE;
     633             :         }
     634             : 
     635           4 :         CALENDAR_METHOD_FETCH_OBJECT;
     636             : 
     637           4 :         int32_t result = co->ucal->getFirstDayOfWeek(CALENDAR_ERROR_CODE(co));
     638           4 :         INTL_METHOD_CHECK_STATUS(co,
     639             :                 "intlcal_get_first_day_of_week: Call to ICU method has failed");
     640             : 
     641           4 :         RETURN_LONG((zend_long)result);
     642             : }
     643             : 
     644          20 : static void _php_intlcal_field_ret_in32t_method(
     645             :                 int32_t (Calendar::*func)(UCalendarDateFields) const,
     646             :                 const char *method_name,
     647             :                 INTERNAL_FUNCTION_PARAMETERS)
     648             : {
     649             :         zend_long       field;
     650             :         char    *message;
     651          20 :         CALENDAR_METHOD_INIT_VARS;
     652             : 
     653          20 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     654             :                         "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
     655           4 :                 spprintf(&message, 0, "%s: bad arguments", method_name);
     656           4 :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
     657           4 :                 efree(message);
     658           4 :                 RETURN_FALSE;
     659             :         }
     660             : 
     661          16 :         if (field < 0 || field >= UCAL_FIELD_COUNT) {
     662           8 :                 spprintf(&message, 0, "%s: invalid field", method_name);
     663           8 :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
     664           8 :                 efree(message);
     665           8 :                 RETURN_FALSE;
     666             :         }
     667             : 
     668           8 :         CALENDAR_METHOD_FETCH_OBJECT;
     669             : 
     670           8 :         int32_t result = (co->ucal->*func)((UCalendarDateFields)field);
     671           8 :         INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
     672             : 
     673           8 :         RETURN_LONG((zend_long)result);
     674             : }
     675             : 
     676           5 : U_CFUNC PHP_FUNCTION(intlcal_get_greatest_minimum)
     677             : {
     678             :         _php_intlcal_field_ret_in32t_method(&Calendar::getGreatestMinimum,
     679           5 :                 "intlcal_get_greatest_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     680           5 : }
     681             : 
     682           5 : U_CFUNC PHP_FUNCTION(intlcal_get_least_maximum)
     683             : {
     684             :         _php_intlcal_field_ret_in32t_method(&Calendar::getLeastMaximum,
     685           5 :                 "intlcal_get_least_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     686           5 : }
     687             : 
     688           6 : U_CFUNC PHP_FUNCTION(intlcal_get_locale)
     689             : {
     690             :         zend_long       locale_type;
     691           6 :         CALENDAR_METHOD_INIT_VARS;
     692             : 
     693           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     694             :                         "Ol", &object, Calendar_ce_ptr, &locale_type) == FAILURE) {
     695             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     696           3 :                         "intlcal_get_locale: bad arguments", 0);
     697           3 :                 RETURN_FALSE;
     698             :         }
     699             : 
     700           3 :         if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) {
     701             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     702           1 :                         "intlcal_get_locale: invalid locale type", 0);
     703           1 :                 RETURN_FALSE;
     704             :         }
     705             : 
     706           2 :         CALENDAR_METHOD_FETCH_OBJECT;
     707             : 
     708             :         Locale locale = co->ucal->getLocale((ULocDataLocaleType)locale_type,
     709           2 :                 CALENDAR_ERROR_CODE(co));
     710           2 :         INTL_METHOD_CHECK_STATUS(co,
     711             :                 "intlcal_get_locale: Call to ICU method has failed");
     712             : 
     713           4 :         RETURN_STRING(locale.getName());
     714             : }
     715             : 
     716           5 : U_CFUNC PHP_FUNCTION(intlcal_get_maximum)
     717             : {
     718             :         _php_intlcal_field_ret_in32t_method(&Calendar::getMaximum,
     719           5 :                 "intlcal_get_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     720           5 : }
     721             : 
     722           4 : U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week)
     723             : {
     724           4 :         CALENDAR_METHOD_INIT_VARS;
     725             : 
     726           4 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     727             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
     728             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     729           2 :                         "intlcal_get_minimal_days_in_first_week: bad arguments", 0);
     730           2 :                 RETURN_FALSE;
     731             :         }
     732             : 
     733           2 :         CALENDAR_METHOD_FETCH_OBJECT;
     734             : 
     735           2 :         uint8_t result = co->ucal->getMinimalDaysInFirstWeek();
     736           2 :         INTL_METHOD_CHECK_STATUS(co,
     737             :                 "intlcal_get_first_day_of_week: Call to ICU method has failed");
     738             : 
     739           2 :         RETURN_LONG((zend_long)result);
     740             : }
     741             : 
     742           5 : U_CFUNC PHP_FUNCTION(intlcal_get_minimum)
     743             : {
     744             :         _php_intlcal_field_ret_in32t_method(&Calendar::getMinimum,
     745           5 :                 "intlcal_get_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
     746           5 : }
     747             : 
     748          17 : U_CFUNC PHP_FUNCTION(intlcal_get_time_zone)
     749             : {
     750          17 :         CALENDAR_METHOD_INIT_VARS;
     751             : 
     752          17 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     753             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
     754             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     755           2 :                         "intlcal_get_time_zone: bad arguments", 0);
     756           2 :                 RETURN_FALSE;
     757             :         }
     758             : 
     759          15 :         CALENDAR_METHOD_FETCH_OBJECT;
     760             : 
     761          15 :         TimeZone *tz = co->ucal->getTimeZone().clone();
     762          15 :         if (tz == NULL) {
     763             :                 intl_errors_set(CALENDAR_ERROR_P(co), U_MEMORY_ALLOCATION_ERROR,
     764           0 :                         "intlcal_get_time_zone: could not clone TimeZone", 0);
     765           0 :                 RETURN_FALSE;
     766             :         }
     767             : 
     768          15 :         timezone_object_construct(tz, return_value, 1);
     769             : }
     770             : 
     771           9 : U_CFUNC PHP_FUNCTION(intlcal_get_type)
     772             : {
     773           9 :         CALENDAR_METHOD_INIT_VARS;
     774             : 
     775           9 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     776             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
     777             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     778           2 :                         "intlcal_get_type: bad arguments", 0);
     779           2 :                 RETURN_FALSE;
     780             :         }
     781             : 
     782           7 :         CALENDAR_METHOD_FETCH_OBJECT;
     783             : 
     784          14 :         RETURN_STRING(co->ucal->getType());
     785             : }
     786             : 
     787             : #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
     788             : U_CFUNC PHP_FUNCTION(intlcal_get_weekend_transition)
     789             : {
     790             :         zend_long       dow;
     791             :         CALENDAR_METHOD_INIT_VARS;
     792             : 
     793             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     794             :                         "Ol", &object, Calendar_ce_ptr, &dow) == FAILURE) {
     795             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     796             :                         "intlcal_get_weekend_transition: bad arguments", 0);
     797             :                 RETURN_FALSE;
     798             :         }
     799             : 
     800             :         if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
     801             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     802             :                         "intlcal_get_weekend_transition: invalid day of week", 0);
     803             :                 RETURN_FALSE;
     804             :         }
     805             : 
     806             :         CALENDAR_METHOD_FETCH_OBJECT;
     807             : 
     808             :         int32_t res = co->ucal->getWeekendTransition((UCalendarDaysOfWeek)dow,
     809             :                 CALENDAR_ERROR_CODE(co));
     810             :         INTL_METHOD_CHECK_STATUS(co, "intlcal_get_weekend_transition: "
     811             :                 "Error calling ICU method");
     812             : 
     813             :         RETURN_LONG((zend_long)res);
     814             : }
     815             : #endif
     816             : 
     817           4 : U_CFUNC PHP_FUNCTION(intlcal_in_daylight_time)
     818             : {
     819           4 :         CALENDAR_METHOD_INIT_VARS;
     820             : 
     821           4 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     822             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
     823             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     824           2 :                         "intlcal_in_daylight_time: bad arguments", 0);
     825           2 :                 RETURN_FALSE;
     826             :         }
     827             : 
     828           2 :         CALENDAR_METHOD_FETCH_OBJECT;
     829             : 
     830           2 :         UBool ret = co->ucal->inDaylightTime(CALENDAR_ERROR_CODE(co));
     831           2 :         INTL_METHOD_CHECK_STATUS(co, "intlcal_in_daylight_time: "
     832             :                 "Error calling ICU method");
     833             : 
     834           2 :         RETURN_BOOL((int)ret);
     835             : }
     836             : 
     837           6 : U_CFUNC PHP_FUNCTION(intlcal_is_equivalent_to)
     838             : {
     839             :         zval                    *other_object;
     840             :         Calendar_object *other_co;
     841           6 :         CALENDAR_METHOD_INIT_VARS;
     842             : 
     843           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     844             :                         "OO", &object, Calendar_ce_ptr, &other_object, Calendar_ce_ptr)
     845             :                         == FAILURE) {
     846             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     847           2 :                         "intlcal_is_equivalent_to: bad arguments", 0);
     848           2 :                 RETURN_FALSE;
     849             :         }
     850             : 
     851           4 :         other_co = Z_INTL_CALENDAR_P(other_object);
     852           4 :         if (other_co->ucal == NULL) {
     853             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_is_equivalent_to:"
     854           0 :                         " Other IntlCalendar is unconstructed", 0);
     855           0 :                 RETURN_FALSE;
     856             :         }
     857             : 
     858           4 :         CALENDAR_METHOD_FETCH_OBJECT;
     859             : 
     860           4 :         RETURN_BOOL((int)co->ucal->isEquivalentTo(*other_co->ucal));
     861             : }
     862             : 
     863           6 : U_CFUNC PHP_FUNCTION(intlcal_is_lenient)
     864             : {
     865           6 :         CALENDAR_METHOD_INIT_VARS;
     866             : 
     867           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     868             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
     869             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     870           2 :                         "intlcal_is_lenient: bad arguments", 0);
     871           2 :                 RETURN_FALSE;
     872             :         }
     873             : 
     874           4 :         CALENDAR_METHOD_FETCH_OBJECT;
     875             : 
     876           4 :         RETURN_BOOL((int)co->ucal->isLenient());
     877             : }
     878             : 
     879           9 : U_CFUNC PHP_FUNCTION(intlcal_is_set)
     880             : {
     881             :         zend_long field;
     882           9 :         CALENDAR_METHOD_INIT_VARS;
     883             : 
     884           9 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     885             :                         "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
     886             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     887           3 :                         "intlcal_is_set: bad arguments", 0);
     888           3 :                 RETURN_FALSE;
     889             :         }
     890             : 
     891           6 :         if (field < 0 || field >= UCAL_FIELD_COUNT) {
     892             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     893           1 :                         "intlcal_is_set: invalid field", 0);
     894           1 :                 RETURN_FALSE;
     895             :         }
     896             : 
     897           5 :         CALENDAR_METHOD_FETCH_OBJECT;
     898             : 
     899           5 :         RETURN_BOOL((int)co->ucal->isSet((UCalendarDateFields)field));
     900             : }
     901             : 
     902             : #if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
     903             : U_CFUNC PHP_FUNCTION(intlcal_is_weekend)
     904             : {
     905             :         double date;
     906             :         zend_bool date_is_null = 1;
     907             :         CALENDAR_METHOD_INIT_VARS;
     908             : 
     909             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     910             :                                 "O|d!", &object, Calendar_ce_ptr, &date, &date_is_null) == FAILURE) {
     911             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     912             :                         "intlcal_is_weekend: bad arguments", 0);
     913             :                 RETURN_FALSE;
     914             :         }
     915             : 
     916             :         CALENDAR_METHOD_FETCH_OBJECT;
     917             : 
     918             :         if (date_is_null) {
     919             :                 RETURN_BOOL((int)co->ucal->isWeekend());
     920             :         } else {
     921             :                 UBool ret = co->ucal->isWeekend((UDate)date, CALENDAR_ERROR_CODE(co));
     922             :                 INTL_METHOD_CHECK_STATUS(co, "intlcal_is_weekend: "
     923             :                         "Error calling ICU method");
     924             :                 RETURN_BOOL((int)ret);
     925             :         }
     926             : }
     927             : #endif
     928             : 
     929             : 
     930           6 : U_CFUNC PHP_FUNCTION(intlcal_set_first_day_of_week)
     931             : {
     932             :         zend_long       dow;
     933           6 :         CALENDAR_METHOD_INIT_VARS;
     934             : 
     935           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     936             :                         "Ol", &object, Calendar_ce_ptr, &dow) == FAILURE) {
     937             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     938           2 :                         "intlcal_set_first_day_of_week: bad arguments", 0);
     939           2 :                 RETURN_FALSE;
     940             :         }
     941             : 
     942           4 :         if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
     943             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     944           2 :                         "intlcal_set_first_day_of_week: invalid day of week", 0);
     945           2 :                 RETURN_FALSE;
     946             :         }
     947             : 
     948           2 :         CALENDAR_METHOD_FETCH_OBJECT;
     949             : 
     950           2 :         co->ucal->setFirstDayOfWeek((UCalendarDaysOfWeek)dow);
     951             : 
     952           2 :         RETURN_TRUE;
     953             : }
     954             : 
     955           6 : U_CFUNC PHP_FUNCTION(intlcal_set_lenient)
     956             : {
     957             :         zend_bool is_lenient;
     958           6 :         CALENDAR_METHOD_INIT_VARS;
     959             : 
     960           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     961             :                         "Ob", &object, Calendar_ce_ptr, &is_lenient) == FAILURE) {
     962             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     963           4 :                         "intlcal_set_lenient: bad arguments", 0);
     964           4 :                 RETURN_FALSE;
     965             :         }
     966             : 
     967           2 :         CALENDAR_METHOD_FETCH_OBJECT;
     968             : 
     969           2 :         co->ucal->setLenient((UBool) is_lenient);
     970             : 
     971           2 :         RETURN_TRUE;
     972             : }
     973             : 
     974           6 : U_CFUNC PHP_FUNCTION(intlcal_set_minimal_days_in_first_week)
     975             : {
     976             :         zend_long       num_days;
     977           6 :         CALENDAR_METHOD_INIT_VARS;
     978             : 
     979           6 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
     980             :                         "Ol", &object, Calendar_ce_ptr, &num_days) == FAILURE) {
     981             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     982           2 :                         "intlcal_set_minimal_days_in_first_week: bad arguments", 0);
     983           2 :                 RETURN_FALSE;
     984             :         }
     985             : 
     986           4 :         if (num_days < 1 || num_days > 7) {
     987             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
     988             :                         "intlcal_set_minimal_days_in_first_week: invalid number of days; "
     989           2 :                         "must be between 1 and 7", 0);
     990           2 :                 RETURN_FALSE;
     991             :         }
     992             : 
     993           2 :         CALENDAR_METHOD_FETCH_OBJECT;
     994             : 
     995           2 :         co->ucal->setMinimalDaysInFirstWeek((uint8_t)num_days);
     996             : 
     997           2 :         RETURN_TRUE;
     998             : }
     999             : 
    1000           5 : U_CFUNC PHP_FUNCTION(intlcal_equals)
    1001             : {
    1002             :         zval                    *other_object;
    1003             :         Calendar_object *other_co;
    1004           5 :         CALENDAR_METHOD_INIT_VARS;
    1005             : 
    1006           5 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    1007             :                         "OO", &object, Calendar_ce_ptr, &other_object, Calendar_ce_ptr)
    1008             :                         == FAILURE) {
    1009             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1010           1 :                         "intlcal_equals: bad arguments", 0);
    1011           1 :                 RETURN_FALSE;
    1012             :         }
    1013             : 
    1014           4 :         CALENDAR_METHOD_FETCH_OBJECT;
    1015           4 :         other_co = Z_INTL_CALENDAR_P(other_object);
    1016           4 :         if (other_co->ucal == NULL) {
    1017             :                 intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
    1018           0 :                         "intlcal_equals: The second IntlCalendar is unconstructed", 0);
    1019           0 :                 RETURN_FALSE;
    1020             :         }
    1021             : 
    1022           4 :         UBool result = co->ucal->equals(*other_co->ucal, CALENDAR_ERROR_CODE(co));
    1023           4 :         INTL_METHOD_CHECK_STATUS(co, "intlcal_equals: error calling ICU Calendar::equals");
    1024             : 
    1025           4 :         RETURN_BOOL((int)result);
    1026             : }
    1027             : 
    1028             : #if U_ICU_VERSION_MAJOR_NUM >= 49
    1029             : 
    1030             : U_CFUNC PHP_FUNCTION(intlcal_get_repeated_wall_time_option)
    1031             : {
    1032             :         CALENDAR_METHOD_INIT_VARS;
    1033             : 
    1034             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    1035             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
    1036             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1037             :                         "intlcal_get_repeated_wall_time_option: bad arguments", 0);
    1038             :                 RETURN_FALSE;
    1039             :         }
    1040             : 
    1041             :         CALENDAR_METHOD_FETCH_OBJECT;
    1042             : 
    1043             :         RETURN_LONG(co->ucal->getRepeatedWallTimeOption());
    1044             : }
    1045             : 
    1046             : U_CFUNC PHP_FUNCTION(intlcal_get_skipped_wall_time_option)
    1047             : {
    1048             :         CALENDAR_METHOD_INIT_VARS;
    1049             : 
    1050             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    1051             :                         "O", &object, Calendar_ce_ptr) == FAILURE) {
    1052             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1053             :                         "intlcal_get_skipped_wall_time_option: bad arguments", 0);
    1054             :                 RETURN_FALSE;
    1055             :         }
    1056             : 
    1057             :         CALENDAR_METHOD_FETCH_OBJECT;
    1058             : 
    1059             :         RETURN_LONG(co->ucal->getSkippedWallTimeOption());
    1060             : }
    1061             : 
    1062             : U_CFUNC PHP_FUNCTION(intlcal_set_repeated_wall_time_option)
    1063             : {
    1064             :         zend_long       option;
    1065             :         CALENDAR_METHOD_INIT_VARS;
    1066             : 
    1067             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    1068             :                         "Ol", &object, Calendar_ce_ptr, &option) == FAILURE) {
    1069             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1070             :                         "intlcal_set_repeated_wall_time_option: bad arguments", 0);
    1071             :                 RETURN_FALSE;
    1072             :         }
    1073             : 
    1074             :         if (option != UCAL_WALLTIME_FIRST && option != UCAL_WALLTIME_LAST) {
    1075             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1076             :                         "intlcal_set_repeated_wall_time_option: invalid option", 0);
    1077             :                 RETURN_FALSE;
    1078             :         }
    1079             : 
    1080             :         CALENDAR_METHOD_FETCH_OBJECT;
    1081             : 
    1082             :         co->ucal->setRepeatedWallTimeOption((UCalendarWallTimeOption)option);
    1083             : 
    1084             :         RETURN_TRUE;
    1085             : }
    1086             : 
    1087             : U_CFUNC PHP_FUNCTION(intlcal_set_skipped_wall_time_option)
    1088             : {
    1089             :         zend_long       option;
    1090             :         CALENDAR_METHOD_INIT_VARS;
    1091             : 
    1092             :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
    1093             :                         "Ol", &object, Calendar_ce_ptr, &option) == FAILURE) {
    1094             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1095             :                         "intlcal_set_skipped_wall_time_option: bad arguments", 0);
    1096             :                 RETURN_FALSE;
    1097             :         }
    1098             : 
    1099             :         if (option != UCAL_WALLTIME_FIRST && option != UCAL_WALLTIME_LAST
    1100             :                         && option != UCAL_WALLTIME_NEXT_VALID) {
    1101             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1102             :                         "intlcal_set_skipped_wall_time_option: invalid option", 0);
    1103             :                 RETURN_FALSE;
    1104             :         }
    1105             : 
    1106             :         CALENDAR_METHOD_FETCH_OBJECT;
    1107             : 
    1108             :         co->ucal->setSkippedWallTimeOption((UCalendarWallTimeOption)option);
    1109             : 
    1110             :         RETURN_TRUE;
    1111             : }
    1112             : 
    1113             : #endif
    1114             : 
    1115          13 : U_CFUNC PHP_FUNCTION(intlcal_from_date_time)
    1116             : {
    1117             :         zval                    *zv_arg,
    1118             :                                         zv_tmp,
    1119          13 :                                         *zv_datetime            = NULL,
    1120             :                                         zv_timestamp;
    1121             :         php_date_obj    *datetime;
    1122          13 :         char                    *locale_str                     = NULL;
    1123             :         size_t                          locale_str_len;
    1124             :         TimeZone                *timeZone;
    1125          13 :         UErrorCode              status                          = U_ZERO_ERROR;
    1126             :         Calendar        *cal;
    1127          13 :         intl_error_reset(NULL);
    1128             : 
    1129          13 :         if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|s!",
    1130             :                         &zv_arg, &locale_str, &locale_str_len) == FAILURE) {
    1131             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1132           3 :                         "intlcal_from_date_time: bad arguments", 0);
    1133           3 :                 RETURN_NULL();
    1134             :         }
    1135             : 
    1136          20 :         if (!(Z_TYPE_P(zv_arg) == IS_OBJECT && instanceof_function(
    1137             :                         Z_OBJCE_P(zv_arg), php_date_get_date_ce()))) {
    1138           5 :                 object_init_ex(&zv_tmp, php_date_get_date_ce());
    1139           5 :                 zend_call_method_with_1_params(&zv_tmp, NULL, NULL, "__construct", NULL, zv_arg);
    1140           5 :                 zv_datetime = &zv_tmp;
    1141           5 :                 if (EG(exception)) {
    1142           2 :                         zend_object_store_ctor_failed(Z_OBJ(zv_tmp));
    1143           2 :                         goto error;
    1144             :                 }
    1145             :         } else {
    1146           5 :                 zv_datetime = zv_arg;
    1147             :         }
    1148             : 
    1149           8 :         datetime = Z_PHPDATE_P(zv_datetime);
    1150           8 :         if (!datetime->time) {
    1151             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1152             :                         "intlcal_from_date_time: DateTime object is unconstructed",
    1153           1 :                         0);
    1154           1 :                 goto error;
    1155             :         }
    1156             : 
    1157           7 :         zend_call_method_with_0_params(zv_datetime, php_date_get_date_ce(), NULL, "gettimestamp", &zv_timestamp);
    1158           7 :         if (Z_TYPE(zv_timestamp) != IS_LONG) {
    1159             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1160             :                         "intlcal_from_date_time: bad DateTime; call to "
    1161           0 :                         "DateTime::getTimestamp() failed", 0);
    1162           0 :                 zval_ptr_dtor(&zv_timestamp);
    1163           0 :                 goto error;
    1164             :         }
    1165             : 
    1166           7 :         if (!datetime->time->is_localtime) {
    1167           0 :                 timeZone = TimeZone::getGMT()->clone();
    1168             :         } else {
    1169             :                 timeZone = timezone_convert_datetimezone(datetime->time->zone_type,
    1170           7 :                         datetime, 1, NULL, "intlcal_from_date_time");
    1171           7 :                 if (timeZone == NULL) {
    1172           2 :                         goto error;
    1173             :                 }
    1174             :         }
    1175             : 
    1176           5 :         if (!locale_str) {
    1177           4 :                 locale_str = const_cast<char*>(intl_locale_get_default());
    1178             :         }
    1179             : 
    1180             :         cal = Calendar::createInstance(timeZone,
    1181           5 :                 Locale::createFromName(locale_str), status);
    1182           5 :         if (cal == NULL) {
    1183           0 :                 delete timeZone;
    1184             :                 intl_error_set(NULL, status, "intlcal_from_date_time: "
    1185           0 :                                 "error creating ICU Calendar object", 0);
    1186           0 :                 goto error;
    1187             :         }
    1188           5 :         cal->setTime(((UDate)Z_LVAL(zv_timestamp)) * 1000., status);
    1189           5 :     if (U_FAILURE(status)) {
    1190             :                 /* time zone was adopted by cal; should not be deleted here */
    1191           0 :                 delete cal;
    1192             :                 intl_error_set(NULL, status, "intlcal_from_date_time: "
    1193           0 :                                 "error creating ICU Calendar::setTime()", 0);
    1194           0 :         goto error;
    1195             :     }
    1196             : 
    1197           5 :         calendar_object_create(return_value, cal);
    1198             : 
    1199             : error:
    1200          10 :         if (zv_datetime && zv_datetime != zv_arg) {
    1201           5 :                 zval_ptr_dtor(zv_datetime);
    1202             :         }
    1203             : }
    1204             : 
    1205           4 : U_CFUNC PHP_FUNCTION(intlcal_to_date_time)
    1206             : {
    1207             :         zval retval;
    1208           4 :         CALENDAR_METHOD_INIT_VARS;
    1209             : 
    1210           4 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
    1211             :                         &object, Calendar_ce_ptr) == FAILURE) {
    1212             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1213           2 :                         "intlcal_to_date_time: bad arguments", 0);
    1214           2 :                 RETURN_FALSE;
    1215             :         }
    1216             : 
    1217           2 :         CALENDAR_METHOD_FETCH_OBJECT;
    1218             : 
    1219             :         /* There are no exported functions in ext/date to this
    1220             :          * in a more native fashion */
    1221           2 :         double  date = co->ucal->getTime(CALENDAR_ERROR_CODE(co)) / 1000.;
    1222             :         int64_t ts;
    1223             :         char    ts_str[sizeof("@-9223372036854775808")];
    1224             :         int             ts_str_len;
    1225             :         zval    ts_zval, tmp;
    1226             : 
    1227           2 :         INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
    1228             : 
    1229           2 :         if (date > (double)U_INT64_MAX || date < (double)U_INT64_MIN) {
    1230             :                 intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
    1231             :                         "intlcal_to_date_time: The calendar date is out of the "
    1232           0 :                         "range for a 64-bit integer", 0);
    1233           0 :                 RETURN_FALSE;
    1234             :         }
    1235             : 
    1236           2 :         ZVAL_UNDEF(&retval);
    1237           2 :         ts = (int64_t)date;
    1238             : 
    1239           2 :         ts_str_len = slprintf(ts_str, sizeof(ts_str), "@%I64d", ts);
    1240           4 :         ZVAL_STRINGL(&ts_zval, ts_str, ts_str_len);
    1241             : 
    1242             :         /* Now get the time zone */
    1243           2 :         const TimeZone& tz = co->ucal->getTimeZone();
    1244             :         zval *timezone_zval = timezone_convert_to_datetimezone(
    1245           2 :                 &tz, CALENDAR_ERROR_P(co), "intlcal_to_date_time", &tmp);
    1246           2 :         if (timezone_zval == NULL) {
    1247           1 :                 zval_ptr_dtor(&ts_zval);
    1248           1 :                 RETURN_FALSE;
    1249             :         }
    1250             : 
    1251             :         /* resources allocated from now on */
    1252             : 
    1253             :         /* Finally, instantiate object and call constructor */
    1254           1 :         object_init_ex(return_value, php_date_get_date_ce());
    1255           1 :         zend_call_method_with_2_params(return_value, NULL, NULL, "__construct", NULL, &ts_zval, timezone_zval);
    1256           1 :         if (EG(exception)) {
    1257             :                 intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
    1258             :                         "intlcal_to_date_time: DateTime constructor has thrown exception",
    1259           0 :                         1);
    1260           0 :                 zend_object_store_ctor_failed(Z_OBJ_P(return_value));
    1261           0 :                 zval_ptr_dtor(return_value);
    1262           0 :                 zval_ptr_dtor(&ts_zval);
    1263             : 
    1264           0 :                 RETVAL_FALSE;
    1265           0 :                 goto error;
    1266             :         }
    1267           1 :         zval_ptr_dtor(&ts_zval);
    1268             : 
    1269             :         /* due to bug #40743, we have to set the time zone again */
    1270             :         zend_call_method_with_1_params(return_value, NULL, NULL, "settimezone",
    1271           1 :                         &retval, timezone_zval);
    1272           2 :         if (Z_ISUNDEF(retval) || Z_TYPE(retval) == IS_FALSE) {
    1273             :                 intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
    1274             :                         "intlcal_to_date_time: call to DateTime::setTimeZone has failed",
    1275           0 :                         1);
    1276           0 :                 zval_ptr_dtor(return_value);
    1277           0 :                 RETVAL_FALSE;
    1278             :                 goto error;
    1279             :         }
    1280             : 
    1281             : error:
    1282           1 :         zval_ptr_dtor(timezone_zval);
    1283           1 :         zval_ptr_dtor(&retval);
    1284             : }
    1285             : 
    1286           5 : U_CFUNC PHP_FUNCTION(intlcal_get_error_code)
    1287             : {
    1288           5 :         CALENDAR_METHOD_INIT_VARS;
    1289             : 
    1290           5 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
    1291             :                         &object, Calendar_ce_ptr) == FAILURE) {
    1292             :                 intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1293           1 :                         "intlcal_get_error_code: bad arguments", 0);
    1294           1 :                 RETURN_FALSE;
    1295             :         }
    1296             : 
    1297             :         /* Fetch the object (without resetting its last error code ). */
    1298           4 :         co = Z_INTL_CALENDAR_P(object);
    1299           4 :         if (co == NULL)
    1300           0 :                 RETURN_FALSE;
    1301             : 
    1302           4 :         RETURN_LONG((zend_long)CALENDAR_ERROR_CODE(co));
    1303             : }
    1304             : 
    1305           5 : U_CFUNC PHP_FUNCTION(intlcal_get_error_message)
    1306             : {
    1307           5 :         zend_string* message = NULL;
    1308           5 :         CALENDAR_METHOD_INIT_VARS;
    1309             : 
    1310           5 :         if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O",
    1311             :                         &object, Calendar_ce_ptr) == FAILURE) {
    1312             :                 intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
    1313           1 :                         "intlcal_get_error_message: bad arguments", 0 );
    1314           1 :                 RETURN_FALSE;
    1315             :         }
    1316             : 
    1317             : 
    1318             :         /* Fetch the object (without resetting its last error code ). */
    1319           4 :         co = Z_INTL_CALENDAR_P(object);
    1320           4 :         if (co == NULL)
    1321           0 :                 RETURN_FALSE;
    1322             : 
    1323             :         /* Return last error message. */
    1324           4 :         message = intl_error_get_message(CALENDAR_ERROR_P(co));
    1325           4 :         RETURN_STR(message);
    1326             : }

Generated by: LCOV version 1.10

Generated at Sat, 25 Jun 2016 07:08:56 +0000 (17 hours ago)

Copyright © 2005-2016 The PHP Group
All rights reserved.