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