diff options
Diffstat (limited to 'ext/intl')
28 files changed, 768 insertions, 358 deletions
diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index 130c6b59f3..beb65f718f 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -18,6 +18,8 @@ #include "config.h" #endif +#include "../intl_cppshims.h" + #include <unicode/calendar.h> #include <unicode/gregocal.h> @@ -55,6 +57,14 @@ U_CFUNC void calendar_object_create(zval *object, calendar_object_construct(object, calendar TSRMLS_CC); } +U_CFUNC Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC) +{ + Calendar_object *co = (Calendar_object*) + zend_object_store_get_object(object TSRMLS_CC); + + return co->ucal; +} + U_CFUNC void calendar_object_construct(zval *object, Calendar *calendar TSRMLS_DC) { diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h index abf9555292..140389b639 100644 --- a/ext/intl/calendar/calendar_class.h +++ b/ext/intl/calendar/calendar_class.h @@ -56,6 +56,8 @@ typedef struct { void calendar_object_create(zval *object, Calendar *calendar TSRMLS_DC); +Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC); + void calendar_object_construct(zval *object, Calendar *calendar TSRMLS_DC); void calendar_register_IntlCalendar_class(TSRMLS_D); diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 1e8c9e7fef..8562a2d69e 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -18,6 +18,8 @@ #include "config.h" #endif +#include "../intl_cppshims.h" + #include <unicode/locid.h> #include <unicode/calendar.h> #include <unicode/ustring.h> @@ -31,7 +33,6 @@ extern "C" { #include "../locale/locale.h" #include <zend_exceptions.h> #include <zend_interfaces.h> -#define _MSC_STDINT_H_ /* avoid redefinitions */ #include <ext/date/php_date.h> } #include "../common/common_enum.h" diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index 4f26cc5945..47e84633a2 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -18,6 +18,8 @@ #include "config.h" #endif +#include "../intl_cppshims.h" + #include <unicode/locid.h> #include <unicode/calendar.h> #include <unicode/gregocal.h> @@ -27,8 +29,6 @@ extern "C" { #define USE_CALENDAR_POINTER 1 #include "calendar_class.h" #include "../locale/locale.h" -/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ -#define _MSC_STDINT_H_ 1 #include <ext/date/php_date.h> } diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp index 14265d4597..a0e346061a 100644 --- a/ext/intl/common/common_enum.cpp +++ b/ext/intl/common/common_enum.cpp @@ -18,6 +18,8 @@ #include "config.h" #endif +#include "../intl_cppshims.h" + // Fix build on Windows/old versions of ICU #include <stdio.h> diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index b1845d8feb..431deeb7d2 100755 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -52,6 +52,9 @@ if test "$PHP_INTL" != "no"; then dateformat/dateformat_data.c \ dateformat/dateformat_format.c \ dateformat/dateformat_parse.c \ + dateformat/dateformat_create.cpp \ + dateformat/dateformat_attrcpp.cpp \ + dateformat/dateformat_helpers.cpp \ msgformat/msgformat.c \ msgformat/msgformat_attr.c \ msgformat/msgformat_class.c \ @@ -67,11 +70,11 @@ if test "$PHP_INTL" != "no"; then transliterator/transliterator.c \ transliterator/transliterator_class.c \ transliterator/transliterator_methods.c \ - timezone/timezone_class.cpp \ - timezone/timezone_methods.cpp \ - calendar/calendar_class.cpp \ - calendar/calendar_methods.cpp \ - calendar/gregoriancalendar_methods.cpp \ + timezone/timezone_class.cpp \ + timezone/timezone_methods.cpp \ + calendar/calendar_class.cpp \ + calendar/calendar_methods.cpp \ + calendar/gregoriancalendar_methods.cpp \ idn/idn.c \ $icu_spoof_src, $ext_shared,,$ICU_INCS -Wno-write-strings) PHP_ADD_BUILD_DIR($ext_builddir/collator) diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index ce12d9d342..735749ab43 100755 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -63,6 +63,9 @@ if (PHP_INTL != "no") { dateformat_format.c \ dateformat_parse.c \ dateformat_data.c \ + dateformat_attrcpp.cpp \ + dateformat_helpers.cpp \ + dateformat_create.cpp \ ", "intl"); ADD_SOURCES(configure_module_dirname + "/idn", "\ idn.c", diff --git a/ext/intl/dateformat/dateformat.c b/ext/intl/dateformat/dateformat.c index b399a39fcb..fb83eeef05 100755 --- a/ext/intl/dateformat/dateformat.c +++ b/ext/intl/dateformat/dateformat.c @@ -17,12 +17,9 @@ #include "config.h" #endif -#include <unicode/ustring.h> #include <unicode/udat.h> -#include <unicode/ucal.h> #include "php_intl.h" -#include "intl_convert.h" #include "dateformat_class.h" #include "dateformat.h" @@ -67,157 +64,6 @@ void dateformat_register_constants( INIT_FUNC_ARGS ) } /* }}} */ -/* {{{ */ -static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) -{ - char* locale; - int locale_len = 0; - zval* object; - long date_type = 0; - long time_type = 0; - long calendar = UCAL_GREGORIAN; - char* timezone_str = NULL; - int timezone_str_len = 0; - char* pattern_str = NULL; - int pattern_str_len = 0; - UChar* svalue = NULL; /* UTF-16 pattern_str */ - int slength = 0; - UChar* timezone_utf16 = NULL; /* UTF-16 timezone_str */ - int timezone_utf16_len = 0; - UCalendar ucal_obj = NULL; - IntlDateFormatter_object* dfo; - - intl_error_reset( NULL TSRMLS_CC ); - object = return_value; - /* Parse parameters. */ - if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sll|sls", - &locale, &locale_len, &date_type, &time_type, &timezone_str, &timezone_str_len, &calendar,&pattern_str, &pattern_str_len ) == FAILURE ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: unable to parse input parameters", 0 TSRMLS_CC ); - zval_dtor(return_value); - RETURN_NULL(); - } - - INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); - - if (calendar != UCAL_TRADITIONAL && calendar != UCAL_GREGORIAN) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: " - "invalid value for calendar type; it must be one of " - "IntlDateFormatter::TRADITIONAL (locale's default calendar) " - "or IntlDateFormatter::GREGORIAN", 0 TSRMLS_CC); - goto error; - } - - DATE_FORMAT_METHOD_FETCH_OBJECT; - - if (DATE_FORMAT_OBJECT(dfo) != NULL) { - intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC); - return; - } - - /* Convert pattern (if specified) to UTF-16. */ - if( pattern_str && pattern_str_len>0 ){ - intl_convert_utf8_to_utf16(&svalue, &slength, - pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); - if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - /* object construction -> only set global error */ - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " - "error converting pattern to UTF-16", 0 TSRMLS_CC); - goto error; - } - } - - /* resources allocated from now on */ - - /* Convert pattern (if specified) to UTF-16. */ - if( timezone_str && timezone_str_len >0 ){ - intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len, - timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo)); - if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " - "error converting timezone_str to UTF-16", 0 TSRMLS_CC); - goto error; - } - } - - if(locale_len == 0) { - locale = INTL_G(default_locale); - } - - if( pattern_str && pattern_str_len>0 ){ - DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); - } else { - DATE_FORMAT_OBJECT(dfo) = udat_open(time_type, date_type, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); - } - - if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - if (calendar != UCAL_TRADITIONAL) { - ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale, - calendar, &INTL_DATA_ERROR_CODE(dfo)); - if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - udat_setCalendar(DATE_FORMAT_OBJECT(dfo), ucal_obj); - ucal_close(ucal_obj); - } else { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create" - ": error opening calendar", 0 TSRMLS_CC); - goto error; - } - } - } else { - intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " - "formatter creation failed", 0 TSRMLS_CC); - goto error; - } - - /* Set the class variables */ - dfo->date_type = date_type; - dfo->time_type = time_type; - dfo->calendar = calendar; - if( timezone_str && timezone_str_len > 0){ - dfo->timezone_id = estrndup( timezone_str, timezone_str_len); - } - -error: - if (svalue) { - efree(svalue); - } - if (timezone_utf16) { - efree(timezone_utf16); - } - if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) { - /* free_object handles partially constructed instances fine */ - zval_dtor(return_value); - RETVAL_NULL(); - } -} -/* }}} */ - -/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] ) - * Create formatter. }}} */ -/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] ) - - * Create formatter. - */ -PHP_FUNCTION( datefmt_create ) -{ - object_init_ex( return_value, IntlDateFormatter_ce_ptr ); - datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - -/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern]) - * IntlDateFormatter object constructor. - */ -PHP_METHOD( IntlDateFormatter, __construct ) -{ - /* return_value param is being changed, therefore we will always return - * NULL here */ - return_value = getThis(); - datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); -} -/* }}} */ - /* {{{ proto int IntlDateFormatter::getErrorCode() * Get formatter's last error code. }}} */ /* {{{ proto int datefmt_get_error_code( IntlDateFormatter $nf ) diff --git a/ext/intl/dateformat/dateformat_attr.c b/ext/intl/dateformat/dateformat_attr.c index 6131cedc95..a32a4860c9 100755 --- a/ext/intl/dateformat/dateformat_attr.c +++ b/ext/intl/dateformat/dateformat_attr.c @@ -24,39 +24,6 @@ #include <unicode/ustring.h> #include <unicode/udat.h> -#include <unicode/ucal.h> - -static void internal_set_calendar(IntlDateFormatter_object *dfo, char* timezone_id, int timezone_id_len, int calendar, zval* return_value TSRMLS_DC){ - int timezone_utf16_len = 0; - UChar* timezone_utf16 = NULL; /* timezone_id in UTF-16 */ - char* locale = NULL; - - UCalendar* ucal_obj = NULL; - - /* check for the validity of value of calendar passed */ - intl_error_reset( NULL TSRMLS_CC ); - if( calendar > 1){ - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_set_calendar: calendar value specified is out of valid range", 0 TSRMLS_CC); - RETURN_FALSE; - } - - /* Convert timezone to UTF-16. */ - intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len, timezone_id, timezone_id_len, &INTL_DATA_ERROR_CODE(dfo)); - INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" ); - - /* Get the locale for the dateformatter */ - locale = (char *)udat_getLocaleByType(DATE_FORMAT_OBJECT(dfo), ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(dfo)); - - /* Set the calendar if passed */ - ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale, calendar, &INTL_DATA_ERROR_CODE(dfo) ); - udat_setCalendar( DATE_FORMAT_OBJECT(dfo), ucal_obj ); - INTL_METHOD_CHECK_STATUS(dfo, "Error setting the calendar."); - - if( timezone_utf16){ - efree(timezone_utf16); - } -} /* {{{ proto unicode IntlDateFormatter::getDateType( ) * Get formatter datetype. }}} */ @@ -110,97 +77,6 @@ PHP_FUNCTION( datefmt_get_timetype ) } /* }}} */ - -/* {{{ proto unicode IntlDateFormatter::getCalendar( ) - * Get formatter calendar. }}} */ -/* {{{ proto string datefmt_get_calendar( IntlDateFormatter $mf ) - * Get formatter calendar. - */ -PHP_FUNCTION( datefmt_get_calendar ) -{ - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_get_calendar: unable to parse input params", 0 TSRMLS_CC ); - RETURN_FALSE; - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter calendar." ); - - RETURN_LONG(dfo->calendar); -} -/* }}} */ - -/* {{{ proto unicode IntlDateFormatter::getTimeZoneId( ) - * Get formatter timezone_id. }}} */ -/* {{{ proto string datefmt_get_timezone_id( IntlDateFormatter $mf ) - * Get formatter timezone_id. - */ -PHP_FUNCTION( datefmt_get_timezone_id ) -{ - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_get_timezone_id: unable to parse input params", 0 TSRMLS_CC ); - RETURN_FALSE; - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter timezone_id." ); - - if( dfo->timezone_id ){ - RETURN_STRING((char*)dfo->timezone_id, TRUE ); - }else{ - RETURN_NULL(); - } -} - -/* {{{ proto boolean IntlDateFormatter::setTimeZoneId( $timezone_id) - * Set formatter timezone_id. }}} */ -/* {{{ proto boolean datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id) - * Set formatter timezone_id. - */ -PHP_FUNCTION( datefmt_set_timezone_id ) -{ - char* timezone_id = NULL; - int timezone_id_len = 0; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, IntlDateFormatter_ce_ptr,&timezone_id, &timezone_id_len) == FAILURE ) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_set_timezone_id: unable to parse input params", 0 TSRMLS_CC ); - RETURN_FALSE; - } - - /* Fetch the object. */ - DATE_FORMAT_METHOD_FETCH_OBJECT; - - /* set the timezone for the calendar */ - internal_set_calendar( dfo, timezone_id, timezone_id_len, dfo->calendar, return_value TSRMLS_CC ); - - /* Set the IntlDateFormatter variable */ - if( dfo->timezone_id ){ - efree(dfo->timezone_id); - } - dfo->timezone_id = estrndup(timezone_id, timezone_id_len); - - RETURN_TRUE; -} - /* {{{ proto string IntlDateFormatter::getPattern( ) * Get formatter pattern. }}} */ /* {{{ proto string datefmt_get_pattern( IntlDateFormatter $mf ) @@ -369,43 +245,3 @@ PHP_FUNCTION( datefmt_set_lenient ) udat_setLenient(DATE_FORMAT_OBJECT(dfo), (UBool)isLenient ); } /* }}} */ - -/* {{{ proto bool IntlDateFormatter::setPattern( int $calendar ) - * Set formatter calendar. }}} */ -/* {{{ proto bool datefmt_set_calendar( IntlDateFormatter $mf, int $calendar ) - * Set formatter calendar. - */ -PHP_FUNCTION( datefmt_set_calendar ) -{ - long calendar = 0; - - DATE_FORMAT_METHOD_INIT_VARS; - - /* Parse parameters. */ - if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", - &object, IntlDateFormatter_ce_ptr, &calendar ) == FAILURE ) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC); - RETURN_FALSE; - } - - /* check for the validity of value of calendar passed */ - intl_error_reset( NULL TSRMLS_CC ); - if (calendar > 1) { - intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, - "datefmt_set_calendar: calendar value specified is out of valid range", 0 TSRMLS_CC); - RETURN_FALSE; - } - - DATE_FORMAT_METHOD_FETCH_OBJECT; - - internal_set_calendar( dfo, dfo->timezone_id, strlen(dfo->timezone_id), calendar, return_value TSRMLS_CC ); - - /* Set the calendar value in the IntlDateFormatter object */ - dfo->calendar = calendar; - - RETURN_TRUE; -} -/* }}} */ - - diff --git a/ext/intl/dateformat/dateformat_attr.h b/ext/intl/dateformat/dateformat_attr.h index bf28824d63..6fe82a6e00 100755 --- a/ext/intl/dateformat/dateformat_attr.h +++ b/ext/intl/dateformat/dateformat_attr.h @@ -21,11 +21,7 @@ //PHP_FUNCTION( datefmt_get_timezone ); PHP_FUNCTION( datefmt_get_datetype ); PHP_FUNCTION( datefmt_get_timetype ); -PHP_FUNCTION( datefmt_get_calendar ); -PHP_FUNCTION( datefmt_set_calendar ); PHP_FUNCTION( datefmt_get_locale ); -PHP_FUNCTION( datefmt_get_timezone_id ); -PHP_FUNCTION( datefmt_set_timezone_id ); PHP_FUNCTION( datefmt_get_pattern ); PHP_FUNCTION( datefmt_set_pattern ); PHP_FUNCTION( datefmt_is_lenient ); diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp new file mode 100644 index 0000000000..b68abec659 --- /dev/null +++ b/ext/intl/dateformat/dateformat_attrcpp.cpp @@ -0,0 +1,261 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ + +#include "../intl_cppshims.h" + +#include <unicode/timezone.h> +#include <unicode/calendar.h> +#include <unicode/datefmt.h> + +extern "C" { +#include "../php_intl.h" +#include "dateformat_class.h" +#include "dateformat_attrcpp.h" +#define USE_TIMEZONE_POINTER 1 +#include "../timezone/timezone_class.h" +#define USE_CALENDAR_POINTER 1 +#include "../calendar/calendar_class.h" +} + +#include "../intl_convertcpp.h" +#include "dateformat_helpers.h" + +static inline DateFormat *fetch_datefmt(IntlDateFormatter_object *dfo) { + return (DateFormat *)dfo->datef_data.udatf; +} + +/* {{{ proto string IntlDateFormatter::getTimeZoneId() + * Get formatter timezone_id. }}} */ +/* {{{ proto string datefmt_get_timezone_id(IntlDateFormatter $mf) + * Get formatter timezone_id. + */ +U_CFUNC PHP_FUNCTION(datefmt_get_timezone_id) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_get_timezone_" + "id: unable to parse input params", 0 TSRMLS_CC); + RETURN_FALSE; + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + UnicodeString res = UnicodeString(); + fetch_datefmt(dfo)->getTimeZone().getID(res); + intl_charFromString(res, &Z_STRVAL_P(return_value), + &Z_STRLEN_P(return_value), &INTL_DATA_ERROR_CODE(dfo)); + INTL_METHOD_CHECK_STATUS(dfo, "Could not convert time zone id to UTF-8"); + + Z_TYPE_P(return_value) = IS_STRING; +} + +/* {{{ proto IntlTimeZone IntlDateFormatter::getTimeZone() + * Get formatter timezone. }}} */ +/* {{{ proto IntlTimeZone datefmt_get_timezone(IntlDateFormatter $mf) + * Get formatter timezone. + */ +U_CFUNC PHP_FUNCTION(datefmt_get_timezone) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, + "datefmt_get_timezone: unable to parse input params", 0 TSRMLS_CC ); + RETURN_FALSE; + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + const TimeZone& tz = fetch_datefmt(dfo)->getTimeZone(); + TimeZone *tz_clone = tz.clone(); + if (tz_clone == NULL) { + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, + "datefmt_get_timezone: Out of memory when cloning time zone", + 0 TSRMLS_CC); + RETURN_FALSE; + } + + object_init_ex(return_value, TimeZone_ce_ptr); + timezone_object_construct(tz_clone, return_value, 1 TSRMLS_CC); +} + +U_CFUNC PHP_FUNCTION(datefmt_set_timezone_id) +{ + php_error_docref0(NULL TSRMLS_CC, E_DEPRECATED, + "Use datefmt_set_timezone() instead, which also accepts a plain " + "time zone identifier and for which this function is now an " + "alias"); + PHP_FN(datefmt_set_timezone)(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} + +/* {{{ proto boolean IntlDateFormatter::setTimeZone(mixed $timezone) + * Set formatter's timezone. }}} */ +/* {{{ proto boolean datefmt_set_timezone_id(IntlDateFormatter $mf, $timezone_id) + * Set formatter timezone_id. + */ +U_CFUNC PHP_FUNCTION(datefmt_set_timezone) +{ + zval **timezone_zv; + TimeZone *timezone; + + DATE_FORMAT_METHOD_INIT_VARS; + + if ( zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), + "OZ", &object, IntlDateFormatter_ce_ptr, &timezone_zv) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_set_timezone: " + "unable to parse input params", 0 TSRMLS_CC); + RETURN_FALSE; + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + timezone = timezone_process_timezone_argument(timezone_zv, + INTL_DATA_ERROR_P(dfo), "datefmt_set_timezone" TSRMLS_CC); + if (timezone == NULL) { + RETURN_FALSE; + } + + fetch_datefmt(dfo)->adoptTimeZone(timezone); +} + +/* {{{ proto int IntlDateFormatter::getCalendar( ) + * Get formatter calendar type. }}} */ +/* {{{ proto int datefmt_get_calendar(IntlDateFormatter $mf) + * Get formatter calendar type. + */ +U_CFUNC PHP_FUNCTION(datefmt_get_calendar) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "datefmt_get_calendar: unable to parse input params", 0 TSRMLS_CC); + RETURN_FALSE; + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + if (dfo->calendar == -1) { + /* an IntlCalendar was provided to the constructor */ + RETURN_FALSE; + } + + RETURN_LONG(dfo->calendar); +} +/* }}} */ + +/* {{{ proto IntlCalendar IntlDateFormatter::getCalendarObject() + * Get formatter calendar. }}} */ +/* {{{ proto IntlCalendar datefmt_get_calendar_object(IntlDateFormatter $mf) + * Get formatter calendar. + */ +U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object) +{ + DATE_FORMAT_METHOD_INIT_VARS; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", + &object, IntlDateFormatter_ce_ptr ) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "datefmt_get_calendar_object: unable to parse input params", + 0 TSRMLS_CC); + RETURN_FALSE; + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + const Calendar *cal = fetch_datefmt(dfo)->getCalendar(); + if (cal == NULL) { + RETURN_NULL(); + } + + Calendar *cal_clone = cal->clone(); + if (cal_clone == NULL) { + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, + "datefmt_get_calendar_object: Out of memory when cloning " + "calendar", 0 TSRMLS_CC); + RETURN_FALSE; + } + + calendar_object_create(return_value, cal_clone TSRMLS_CC); +} +/* }}} */ + +/* {{{ proto bool IntlDateFormatter::setCalendar(mixed $calendar) + * Set formatter's calendar. }}} */ +/* {{{ proto bool datefmt_set_calendar(IntlDateFormatter $mf, mixed $calendar) + * Set formatter's calendar. + */ +U_CFUNC PHP_FUNCTION(datefmt_set_calendar) +{ + zval *calendar_zv; + DATE_FORMAT_METHOD_INIT_VARS; + + if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", + &object, IntlDateFormatter_ce_ptr, &calendar_zv) == FAILURE) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, + "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC); + RETURN_FALSE; + } + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + Calendar *cal; + long cal_type; + bool cal_owned; + Locale locale = Locale::createFromName(dfo->requested_locale); + // getting the actual locale from the DateFormat is not enough + // because we would have lost modifiers such as @calendar. We + // must store the requested locale on object creation + + if (datefmt_process_calendar_arg(calendar_zv, locale, + "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type, + cal_owned TSRMLS_CC) == FAILURE) { + RETURN_FALSE; + } + + if (cal_owned) { + /* a non IntlCalendar was specified, we want to keep the timezone */ + TimeZone *old_timezone = fetch_datefmt(dfo)->getTimeZone().clone(); + if (old_timezone == NULL) { + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, + "datefmt_set_calendar: Out of memory when cloning calendar", + 0 TSRMLS_CC); + delete cal; + RETURN_FALSE; + } + cal->adoptTimeZone(old_timezone); + } else { + cal = cal->clone(); + if (cal == NULL) { + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR, + "datefmt_set_calendar: Out of memory when cloning calendar", + 0 TSRMLS_CC); + RETURN_FALSE; + } + } + + fetch_datefmt(dfo)->adoptCalendar(cal); + + dfo->calendar = cal_type; + + RETURN_TRUE; +} +/* }}} */ + diff --git a/ext/intl/dateformat/dateformat_attrcpp.h b/ext/intl/dateformat/dateformat_attrcpp.h new file mode 100644 index 0000000000..408232f940 --- /dev/null +++ b/ext/intl/dateformat/dateformat_attrcpp.h @@ -0,0 +1,35 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef DATEFORMAT_ATTRCPP_H +#define DATEFORMAT_ATTRCPP_H + +PHP_FUNCTION(datefmt_get_timezone_id); + +PHP_FUNCTION(datefmt_set_timezone_id); + +PHP_FUNCTION(datefmt_get_timezone); + +PHP_FUNCTION(datefmt_set_timezone); + +PHP_FUNCTION(datefmt_get_calendar); + +PHP_FUNCTION(datefmt_set_calendar); + +PHP_FUNCTION(datefmt_get_calendar_object); + +#endif /* DATEFORMAT_ATTRCPP_H */ + diff --git a/ext/intl/dateformat/dateformat_class.c b/ext/intl/dateformat/dateformat_class.c index c66610f23b..fda67f1b70 100755 --- a/ext/intl/dateformat/dateformat_class.c +++ b/ext/intl/dateformat/dateformat_class.c @@ -22,6 +22,7 @@ #include "dateformat_parse.h" #include "dateformat.h" #include "dateformat_attr.h" +#include "dateformat_attrcpp.h" zend_class_entry *IntlDateFormatter_ce_ptr = NULL; static zend_object_handlers IntlDateFormatter_handlers; @@ -44,12 +45,12 @@ void IntlDateFormatter_object_free( zend_object *object TSRMLS_DC ) zend_object_std_dtor( &dfo->zo TSRMLS_CC ); - dateformat_data_free( &dfo->datef_data TSRMLS_CC ); - - if( dfo->timezone_id ){ - efree(dfo->timezone_id); + if (dfo->requested_locale) { + efree( dfo->requested_locale ); } + dateformat_data_free( &dfo->datef_data TSRMLS_CC ); + efree( dfo ); } /* }}} */ @@ -63,10 +64,10 @@ zend_object_value IntlDateFormatter_object_create(zend_class_entry *ce TSRMLS_DC intern = ecalloc( 1, sizeof(IntlDateFormatter_object) ); dateformat_data_init( &intern->datef_data TSRMLS_CC ); zend_object_std_init( &intern->zo, ce TSRMLS_CC ); - intern->date_type = 0; - intern->time_type = 0; - intern->calendar = 1; /* Gregorian calendar */ - intern->timezone_id = NULL; + intern->date_type = 0; + intern->time_type = 0; + intern->calendar = -1; + intern->requested_locale = NULL; retval.handle = zend_objects_store_put( intern, @@ -157,9 +158,12 @@ static zend_function_entry IntlDateFormatter_class_functions[] = { PHP_NAMED_FE( getDateType, ZEND_FN( datefmt_get_datetype ), arginfo_intldateformatter_getdatetype ) PHP_NAMED_FE( getTimeType, ZEND_FN( datefmt_get_timetype ), arginfo_intldateformatter_getdatetype ) PHP_NAMED_FE( getCalendar, ZEND_FN( datefmt_get_calendar ), arginfo_intldateformatter_getdatetype ) + PHP_NAMED_FE( getCalendarObject, ZEND_FN( datefmt_get_calendar_object ), arginfo_intldateformatter_getdatetype ) PHP_NAMED_FE( setCalendar, ZEND_FN( datefmt_set_calendar ), arginfo_intldateformatter_setcalendar ) PHP_NAMED_FE( getTimeZoneId, ZEND_FN( datefmt_get_timezone_id ), arginfo_intldateformatter_getdatetype ) PHP_NAMED_FE( setTimeZoneId, ZEND_FN( datefmt_set_timezone_id ), arginfo_intldateformatter_settimezoneid ) + PHP_NAMED_FE( getTimeZone, ZEND_FN( datefmt_get_timezone ), arginfo_intldateformatter_getdatetype ) + PHP_NAMED_FE( setTimeZone, ZEND_FN( datefmt_set_timezone ), arginfo_intldateformatter_settimezoneid ) PHP_NAMED_FE( setPattern, ZEND_FN( datefmt_set_pattern ), arginfo_intldateformatter_setpattern ) PHP_NAMED_FE( getPattern, ZEND_FN( datefmt_get_pattern ), arginfo_intldateformatter_getdatetype ) PHP_NAMED_FE( getLocale, ZEND_FN( datefmt_get_locale ), arginfo_intldateformatter_getdatetype ) diff --git a/ext/intl/dateformat/dateformat_class.h b/ext/intl/dateformat/dateformat_class.h index 9ad83ee3d6..de5cf4a181 100755 --- a/ext/intl/dateformat/dateformat_class.h +++ b/ext/intl/dateformat/dateformat_class.h @@ -24,12 +24,12 @@ #include "dateformat_data.h" typedef struct { - zend_object zo; - dateformat_data datef_data; - int date_type ; - int time_type ; - int calendar ; - char* timezone_id; + zend_object zo; + dateformat_data datef_data; + int date_type; + int time_type; + int calendar; + char *requested_locale; } IntlDateFormatter_object; void dateformat_register_IntlDateFormatter_class( TSRMLS_D ); diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp new file mode 100644 index 0000000000..fef93e93d9 --- /dev/null +++ b/ext/intl/dateformat/dateformat_create.cpp @@ -0,0 +1,193 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Kirti Velankar <kirtig@yahoo-inc.com> | + | Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ + +#include "../intl_cppshims.h" + +#include <unicode/timezone.h> +#include <unicode/calendar.h> +#include <unicode/datefmt.h> + +extern "C" { +#include <unicode/ustring.h> +#include <unicode/udat.h> + +#include "php_intl.h" +#include "dateformat_create.h" +#include "dateformat_class.h" +#define USE_TIMEZONE_POINTER 1 +#include "../timezone/timezone_class.h" +#include "../intl_convert.h" +} + +#include "dateformat_helpers.h" + +/* {{{ */ +static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *object; + + char *locale_str; + int locale_len = 0; + Locale locale; + long date_type = 0; + long time_type = 0; + zval *calendar_zv = NULL; + Calendar *calendar = NULL; + long calendar_type; + bool calendar_owned; + zval **timezone_zv = NULL; + TimeZone *timezone = NULL; + bool explicit_tz; + char* pattern_str = NULL; + int pattern_str_len = 0; + UChar* svalue = NULL; /* UTF-16 pattern_str */ + int slength = 0; + IntlDateFormatter_object* dfo; + + intl_error_reset(NULL TSRMLS_CC); + object = return_value; + /* Parse parameters. */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|Zzs", + &locale_str, &locale_len, &date_type, &time_type, &timezone_zv, + &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: " + "unable to parse input parameters", 0 TSRMLS_CC); + zval_dtor(return_value); + RETURN_NULL(); + } + + INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); + if (locale_len == 0) { + locale_str = INTL_G(default_locale); + } + locale = Locale::createFromName(locale_str); + + DATE_FORMAT_METHOD_FETCH_OBJECT; + + if (DATE_FORMAT_OBJECT(dfo) != NULL) { + intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, + "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC); + return; + } + + /* process calendar */ + if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create", + INTL_DATA_ERROR_P(dfo), calendar, calendar_type, + calendar_owned TSRMLS_CC) + == FAILURE) { + goto error; + } + + /* process timezone */ + explicit_tz = timezone_zv != NULL && Z_TYPE_PP(timezone_zv) != IS_NULL; + + if (explicit_tz || calendar_owned ) { + //we have an explicit time zone or a non-object calendar + timezone = timezone_process_timezone_argument(timezone_zv, + INTL_DATA_ERROR_P(dfo), "datefmt_create" TSRMLS_CC); + if (timezone == NULL) { + goto error; + } + } + + /* Convert pattern (if specified) to UTF-16. */ + if (pattern_str && pattern_str_len > 0) { + intl_convert_utf8_to_utf16(&svalue, &slength, + pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo)); + if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { + /* object construction -> only set global error */ + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: " + "error converting pattern to UTF-16", 0 TSRMLS_CC); + goto error; + } + } + + if (pattern_str && pattern_str_len > 0) { + DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, + locale_str, NULL, 0, svalue, slength, + &INTL_DATA_ERROR_CODE(dfo)); + } else { + DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type, + (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue, + slength, &INTL_DATA_ERROR_CODE(dfo)); + } + + if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { + DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo); + if (calendar_owned) { + df->adoptCalendar(calendar); + calendar_owned = false; + } else { + df->setCalendar(*calendar); + } + + if (timezone != NULL) { + df->adoptTimeZone(timezone); + } + } else { + intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date " + "formatter creation failed", 0 TSRMLS_CC); + goto error; + } + + /* Set the class variables */ + dfo->date_type = date_type; + dfo->time_type = time_type; + dfo->calendar = calendar_type; + dfo->requested_locale = estrdup(locale_str); + +error: + if (svalue) { + efree(svalue); + } + if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) { + delete timezone; + } + if (calendar != NULL && calendar_owned) { + delete calendar; + } + if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) { + /* free_object handles partially constructed instances fine */ + zval_dtor(return_value); + RETVAL_NULL(); + } +} +/* }}} */ + +/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] ) + * Create formatter. }}} */ +/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern) + * Create formatter. + */ +U_CFUNC PHP_FUNCTION( datefmt_create ) +{ + object_init_ex( return_value, IntlDateFormatter_ce_ptr ); + datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern]) + * IntlDateFormatter object constructor. + */ +U_CFUNC PHP_METHOD( IntlDateFormatter, __construct ) +{ + /* return_value param is being changed, therefore we will always return + * NULL here */ + return_value = getThis(); + datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ diff --git a/ext/intl/dateformat/dateformat_create.h b/ext/intl/dateformat/dateformat_create.h new file mode 100644 index 0000000000..47e67c2f45 --- /dev/null +++ b/ext/intl/dateformat/dateformat_create.h @@ -0,0 +1,25 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ +#ifndef DATE_FORMATTER_H +#define DATE_FORMATTER_H + +#include <php.h> + +PHP_FUNCTION( datefmt_create ); +PHP_METHOD( IntlDateFormatter, __construct ); +void dateformat_register_constants( INIT_FUNC_ARGS ); + +#endif // DATE_FORMATTER_H diff --git a/ext/intl/dateformat/dateformat_format.c b/ext/intl/dateformat/dateformat_format.c index 4d03d924c8..82f825f140 100755 --- a/ext/intl/dateformat/dateformat_format.c +++ b/ext/intl/dateformat/dateformat_format.c @@ -27,6 +27,8 @@ #include "dateformat_class.h" #include "dateformat_format.h" #include "dateformat_data.h" +/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ +#define _MSC_STDINT_H_ 1 #include "ext/date/php_date.h" /* {{{ @@ -91,7 +93,7 @@ static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* ha long yday =0; long mday =0; UBool isInDST = FALSE; - UCalendar *pcal; + const UCalendar *pcal; /* Fetch values from the incoming array */ year = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YEAR TSRMLS_CC) + 1900; /* tm_year is years since 1900 */ diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp new file mode 100644 index 0000000000..74758bbec9 --- /dev/null +++ b/ext/intl/dateformat/dateformat_helpers.cpp @@ -0,0 +1,106 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ + +#include "../intl_cppshims.h" + +#include <unicode/calendar.h> +#include <unicode/gregocal.h> + +#include "dateformat_helpers.h" + +extern "C" { +#include "../php_intl.h" +#include <Zend/zend_operators.h> +#define USE_CALENDAR_POINTER 1 +#include "../calendar/calendar_class.h" +} + +int datefmt_process_calendar_arg(zval* calendar_zv, + Locale const& locale, + const char *func_name, + intl_error *err, + Calendar*& cal, + long& cal_int_type, + bool& calendar_owned TSRMLS_DC) +{ + char *msg; + UErrorCode status = UErrorCode(); + + if (calendar_zv == NULL || Z_TYPE_P(calendar_zv) == IS_NULL) { + + // default requested + cal = new GregorianCalendar(locale, status); + calendar_owned = true; + + cal_int_type = UCAL_GREGORIAN; + + } else if (Z_TYPE_P(calendar_zv) == IS_LONG) { + + long v = Z_LVAL_P(calendar_zv); + if (v != (long)UCAL_TRADITIONAL && v != (long)UCAL_GREGORIAN) { + spprintf(&msg, 0, "%s: invalid value for calendar type; it must be " + "one of IntlDateFormatter::TRADITIONAL (locale's default " + "calendar) or IntlDateFormatter::GREGORIAN. " + "Alternatively, it can be an IntlCalendar object", + func_name); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC); + efree(msg); + return FAILURE; + } else if (v == (long)UCAL_TRADITIONAL) { + cal = Calendar::createInstance(locale, status); + } else { //UCAL_GREGORIAN + cal = new GregorianCalendar(locale, status); + } + calendar_owned = true; + + cal_int_type = Z_LVAL_P(calendar_zv); + + } else if (Z_TYPE_P(calendar_zv) == IS_OBJECT && + instanceof_function_ex(Z_OBJCE_P(calendar_zv), + Calendar_ce_ptr, 0 TSRMLS_CC)) { + + cal = calendar_fetch_native_calendar(calendar_zv TSRMLS_CC); + if (cal == NULL) { + spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object", + func_name); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC); + efree(msg); + return FAILURE; + } + calendar_owned = false; + + cal_int_type = -1; + + } else { + spprintf(&msg, 0, "%s: Invalid calendar argument; should be an integer " + "or an IntlCalendar instance", func_name); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC); + efree(msg); + return FAILURE; + } + + if (cal == NULL && !U_FAILURE(status)) { + status = U_MEMORY_ALLOCATION_ERROR; + } + if (U_FAILURE(status)) { + spprintf(&msg, 0, "%s: Failure instantiating calendar", func_name); + intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC); + efree(msg); + return FAILURE; + } + + return SUCCESS; +} diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h new file mode 100644 index 0000000000..bded0b7d78 --- /dev/null +++ b/ext/intl/dateformat/dateformat_helpers.h @@ -0,0 +1,39 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef DATEFORMAT_HELPERS_H +#define DATEFORMAT_HELPERS_H + +#ifndef __cplusplus +#error For C++ only +#endif + +#include <unicode/calendar.h> + +extern "C" { +#include "../php_intl.h" +} + +int datefmt_process_calendar_arg(zval* calendar_zv, + Locale const& locale, + const char *func_name, + intl_error *err, + Calendar*& cal, + long& cal_int_type, + bool& calendar_owned TSRMLS_DC); + +#endif /* DATEFORMAT_HELPERS_H */ + diff --git a/ext/intl/grapheme/grapheme.h b/ext/intl/grapheme/grapheme.h index c0e697ac1e..756ce9173e 100755 --- a/ext/intl/grapheme/grapheme.h +++ b/ext/intl/grapheme/grapheme.h @@ -19,7 +19,6 @@ #include <php.h> #include <unicode/utypes.h> -#include <unicode/ubrk.h> PHP_FUNCTION(grapheme_strlen); PHP_FUNCTION(grapheme_strpos); diff --git a/ext/intl/intl_convertcpp.cpp b/ext/intl/intl_convertcpp.cpp index 503402871c..f699a3c61c 100644 --- a/ext/intl/intl_convertcpp.cpp +++ b/ext/intl/intl_convertcpp.cpp @@ -16,8 +16,7 @@ /* $Id$ */ -//Fixes the build on old versions of ICU with Windows -#include <stdio.h> +#include "intl_cppshims.h" #include "intl_convertcpp.h" #include <unicode/ustring.h> diff --git a/ext/intl/intl_cppshims.h b/ext/intl/intl_cppshims.h new file mode 100644 index 0000000000..2fb70edfd0 --- /dev/null +++ b/ext/intl/intl_cppshims.h @@ -0,0 +1,34 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Gustavo Lopes <cataphract@php.net> | + +----------------------------------------------------------------------+ +*/ + +#ifndef INTL_CPPSHIMS_H +#define INTL_CPPSHIMS_H + +#ifndef __cplusplus +#error For inclusion form C++ files only +#endif + +#ifdef _MSC_VER +//This is only required for old versions of ICU only +#include <stdio.h> + +#include <math.h> + +/* avoid redefinition of int8_t, also defined in unicode/pwin32.h */ +#define _MSC_STDINT_H_ 1 +#endif + +#endif
\ No newline at end of file diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp index 6f4615e169..fd8df1a39c 100755 --- a/ext/intl/msgformat/msgformat_helpers.cpp +++ b/ext/intl/msgformat/msgformat_helpers.cpp @@ -18,10 +18,8 @@ #include "config.h" #endif -// Fix build on Windows / old versions of ICU -#include <stdio.h> +#include "../intl_cppshims.h" -#include <math.h> #include <limits.h> #include <unicode/msgfmt.h> #include <unicode/chariter.h> diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index db8e00392c..59272db712 100755 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -41,6 +41,8 @@ #include "formatter/formatter_main.h" #include "formatter/formatter_parse.h" +#include "grapheme/grapheme.h" + #include "msgformat/msgformat.h" #include "msgformat/msgformat_class.h" #include "msgformat/msgformat_attr.h" @@ -58,6 +60,7 @@ #include "dateformat/dateformat.h" #include "dateformat/dateformat_class.h" #include "dateformat/dateformat_attr.h" +#include "dateformat/dateformat_attrcpp.h" #include "dateformat/dateformat_format.h" #include "dateformat/dateformat_parse.h" #include "dateformat/dateformat_data.h" @@ -321,6 +324,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_pattern, 0, 0, 2) ZEND_ARG_INFO(0, pattern) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_timezone, 0, 0, 2) + ZEND_ARG_INFO(0, mf) + ZEND_ARG_INFO(0, timezone) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_calendar, 0, 0, 2) ZEND_ARG_INFO(0, mf) ZEND_ARG_INFO(0, calendar) @@ -675,10 +683,13 @@ zend_function_entry intl_functions[] = { PHP_FE( datefmt_get_datetype, arginfo_msgfmt_get_locale ) PHP_FE( datefmt_get_timetype, arginfo_msgfmt_get_locale ) PHP_FE( datefmt_get_calendar, arginfo_msgfmt_get_locale ) + PHP_FE( datefmt_get_calendar_object, arginfo_msgfmt_get_locale ) PHP_FE( datefmt_set_calendar, arginfo_datefmt_set_calendar ) PHP_FE( datefmt_get_locale, arginfo_msgfmt_get_locale ) PHP_FE( datefmt_get_timezone_id, arginfo_msgfmt_get_locale ) - PHP_FE( datefmt_set_timezone_id, arginfo_msgfmt_get_locale ) + PHP_FE( datefmt_set_timezone_id, arginfo_datefmt_set_timezone ) + PHP_FE( datefmt_get_timezone, arginfo_msgfmt_get_locale ) + PHP_FE( datefmt_set_timezone, arginfo_datefmt_set_timezone ) PHP_FE( datefmt_get_pattern, arginfo_msgfmt_get_locale ) PHP_FE( datefmt_set_pattern, arginfo_datefmt_set_pattern ) PHP_FE( datefmt_is_lenient, arginfo_msgfmt_get_locale ) diff --git a/ext/intl/php_intl.h b/ext/intl/php_intl.h index 38f61ad8ac..c3d5c60f07 100755 --- a/ext/intl/php_intl.h +++ b/ext/intl/php_intl.h @@ -22,8 +22,13 @@ #include <php.h> +/* Even if we're included from C++, don't introduce C++ definitions + * because we were included with extern "C". The effect would be that + * when the headers defined any method, they would do so with C linkage */ +#undef U_SHOW_CPLUSPLUS_API +#define U_SHOW_CPLUSPLUS_API 0 #include "collator/collator_sort.h" -#include "grapheme/grapheme.h" +#include <unicode/ubrk.h> #include "intl_error.h" extern zend_module_entry intl_module_entry; diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp index c976eb143a..6e62c34f6d 100644 --- a/ext/intl/timezone/timezone_class.cpp +++ b/ext/intl/timezone/timezone_class.cpp @@ -19,6 +19,8 @@ #include "config.h" #endif +#include "../intl_cppshims.h" + #include <unicode/timezone.h> #include <unicode/calendar.h> #include "../intl_convertcpp.h" @@ -30,8 +32,6 @@ extern "C" { #include "timezone_methods.h" #include <zend_exceptions.h> #include <zend_interfaces.h> -/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ -#define _MSC_STDINT_H_ 1 #include <ext/date/php_date.h> } diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp index b7f31c3f3b..1435679fe7 100644 --- a/ext/intl/timezone/timezone_methods.cpp +++ b/ext/intl/timezone/timezone_methods.cpp @@ -18,6 +18,8 @@ #include "config.h" #endif +#include "../intl_cppshims.h" + #include <unicode/locid.h> #include <unicode/timezone.h> #include <unicode/ustring.h> @@ -28,8 +30,6 @@ extern "C" { #include "intl_convert.h" #include "../locale/locale.h" #include <zend_exceptions.h> -/* avoid redefinition of int8_t, already defined in unicode/pwin32.h */ -#define _MSC_STDINT_H_ 1 #include <ext/date/php_date.h> } #include "common/common_enum.h" diff --git a/ext/intl/timezone/timezone_methods.h b/ext/intl/timezone/timezone_methods.h index e153418ea7..28c39f4fd7 100644 --- a/ext/intl/timezone/timezone_methods.h +++ b/ext/intl/timezone/timezone_methods.h @@ -19,7 +19,7 @@ #include <php.h> -PHP_METHOD(IntlTimeZone, __construct) +PHP_METHOD(IntlTimeZone, __construct); PHP_FUNCTION(intltz_create_time_zone); |