From 51cd7a140b6c8f65fbcec405580a9f4d16351484 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Fri, 25 Jul 2025 01:43:26 +0300 Subject: [PATCH 01/10] Intl: Add IntlNumberRangeFormatter --- ext/intl/config.m4 | 2 + ext/intl/config.w32 | 3 + ext/intl/php_intl.c | 4 + .../rangeformatter/rangeformatter.stub.php | 40 ++++ .../rangeformatter/rangeformatter_arginfo.h | 86 +++++++++ .../rangeformatter/rangeformatter_class.cpp | 180 ++++++++++++++++++ .../rangeformatter/rangeformatter_class.h | 54 ++++++ ext/intl/tests/rangeformatter/basic.phpt | 20 ++ 8 files changed, 389 insertions(+) create mode 100644 ext/intl/rangeformatter/rangeformatter.stub.php create mode 100644 ext/intl/rangeformatter/rangeformatter_arginfo.h create mode 100644 ext/intl/rangeformatter/rangeformatter_class.cpp create mode 100644 ext/intl/rangeformatter/rangeformatter_class.h create mode 100644 ext/intl/tests/rangeformatter/basic.phpt diff --git a/ext/intl/config.m4 b/ext/intl/config.m4 index c4c3c9b1d4cea..f54e563af4ee5 100644 --- a/ext/intl/config.m4 +++ b/ext/intl/config.m4 @@ -60,6 +60,7 @@ if test "$PHP_INTL" != "no"; then dateformat/datepatterngenerator_class.cpp \ dateformat/datepatterngenerator_methods.cpp \ msgformat/msgformat_helpers.cpp \ + rangeformatter/rangeformatter_class.cpp \ timezone/timezone_class.cpp \ timezone/timezone_methods.cpp \ calendar/calendar_class.cpp \ @@ -123,6 +124,7 @@ if test "$PHP_INTL" != "no"; then $ext_builddir/listformatter $ext_builddir/msgformat $ext_builddir/normalizer + $ext_builddir/rangeformatter $ext_builddir/resourcebundle $ext_builddir/spoofchecker $ext_builddir/timezone diff --git a/ext/intl/config.w32 b/ext/intl/config.w32 index fb3f0212729dd..9d68a7c2d3ef7 100644 --- a/ext/intl/config.w32 +++ b/ext/intl/config.w32 @@ -63,6 +63,9 @@ if (PHP_INTL != "no") { normalizer_class.cpp \ normalizer_normalize.cpp \ ", "intl"); + ADD_SOURCES(configure_module_dirname + "/rangeformatter", "\ + rangeformatter_class.cpp \ + ", "intl"); ADD_SOURCES(configure_module_dirname + "/dateformat", "\ dateformat.c \ dateformat_class.c \ diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index 28debad4133c4..241f126d672d2 100644 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -42,6 +42,7 @@ #include "locale/locale_class.h" #include "listformatter/listformatter_class.h" +#include "rangeformatter/rangeformatter_class.h" #include "dateformat/dateformat.h" #include "dateformat/dateformat_class.h" @@ -175,6 +176,9 @@ PHP_MINIT_FUNCTION( intl ) /* Register 'ListFormatter' PHP class */ listformatter_register_class( ); + /* Register 'NumberRangeFormatter' PHP class */ + rangeformatter_register_class( ); + /* Register 'Normalizer' PHP class */ normalizer_register_Normalizer_class( ); diff --git a/ext/intl/rangeformatter/rangeformatter.stub.php b/ext/intl/rangeformatter/rangeformatter.stub.php new file mode 100644 index 0000000000000..2cd947ecab07d --- /dev/null +++ b/ext/intl/rangeformatter/rangeformatter.stub.php @@ -0,0 +1,40 @@ + | + +----------------------------------------------------------------------+ +*/ + +#include +#include +#include +#include +#include "../intl_convertcpp.h" + +extern "C" { + #include "php.h" + #include "../php_intl.h" + #include "../intl_data.h" + #include "rangeformatter_arginfo.h" + #include "rangeformatter_class.h" +#include "intl_convert.h" +} + +using icu::number::NumberRangeFormatter; +using icu::number::NumberFormatter; +using icu::number::UnlocalizedNumberFormatter; +using icu::number::LocalizedNumberRangeFormatter; +using icu::UnicodeString; +using icu::MeasureUnit; + +static zend_object_handlers rangeformatter_handlers; +zend_class_entry *class_entry_IntlNumberRangeFormatter; + +zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) +{ + IntlNumberRangeFormatter_object* intern; + + intern = (IntlNumberRangeFormatter_object*)zend_object_alloc(sizeof(IntlNumberRangeFormatter_object), ce); + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); + + return &intern->zo; +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct) +{ + +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) +{ + char* skeleton; + char* locale; + size_t locale_len; + size_t skeleton_len; + zend_long collapse; + zend_long identityFallback; + + ZEND_PARSE_PARAMETERS_START(4,4) + Z_PARAM_STRING(skeleton, skeleton_len) + Z_PARAM_STRING(locale, locale_len) + Z_PARAM_LONG(collapse) + Z_PARAM_LONG(identityFallback) + ZEND_PARSE_PARAMETERS_END(); + + if (locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } + + if (skeleton_len == 0) { + zend_argument_value_error(1, "Skeleton string cannot be empty"); + RETURN_THROWS(); + } + + if (locale_len > INTL_MAX_LOCALE_LEN) { + zend_argument_value_error(2, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); + RETURN_THROWS(); + } + + if (strlen(uloc_getISO3Language(locale)) == 0) { + zend_argument_value_error(2, "\"%s\" is invalid", locale); + RETURN_THROWS(); + } + + if (collapse != UNUM_RANGE_COLLAPSE_AUTO && collapse != UNUM_RANGE_COLLAPSE_NONE && collapse != UNUM_RANGE_COLLAPSE_UNIT && collapse != UNUM_RANGE_COLLAPSE_ALL) { + zend_argument_value_error(3, "Invalid collapse value"); + RETURN_THROWS(); + } + + if (identityFallback != UNUM_IDENTITY_FALLBACK_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY && identityFallback != UNUM_IDENTITY_FALLBACK_RANGE) { + zend_argument_value_error(4, "Invalid identity fallback value"); + RETURN_THROWS(); + } + + UErrorCode error = U_ZERO_ERROR; + + UnicodeString skeleton_ustr(skeleton, skeleton_len); + + UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, error); + + LocalizedNumberRangeFormatter* nrf = new LocalizedNumberRangeFormatter( + NumberRangeFormatter::with() + .locale(locale) + .numberFormatterBoth(nf) + .collapse(static_cast(collapse)) + .identityFallback(static_cast(identityFallback)) + ); + + zend_object* obj = IntlNumberRangeFormatter_object_create(class_entry_IntlNumberRangeFormatter); + obj->handlers = &rangeformatter_handlers; + + RANGEFORMATTER_OBJECT(php_intl_numberrangeformatter_fetch_object(obj)) = nrf; + + RETURN_OBJ(obj); + +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) +{ + double start; + double end; + + IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_DOUBLE(start) + Z_PARAM_DOUBLE(end) + ZEND_PARSE_PARAMETERS_END(); + + UErrorCode error = U_ZERO_ERROR; + + UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start, end, error).toString(error); + + if (U_FAILURE(error)) { + intl_error_set(NULL, error, "Failed to format number range", 0); + + return; + } + + zend_string *ret = intl_charFromString(result, &error); + + if (!ret) { + intl_error_set(NULL, error, "Failed to convert result to UTF-8", 0); + // RETVAL_FALSE; + return; + } + + RETVAL_NEW_STR(ret); +} + +void IntlNumberRangeFormatter_object_free(zend_object *object) +{ + IntlNumberRangeFormatter_object* nfo = php_intl_numberrangeformatter_fetch_object(object); + + if (nfo->nrf_data.unumrf) { + delete nfo->nrf_data.unumrf; + nfo->nrf_data.unumrf = nullptr; + } + + intl_error_reset(&nfo->nrf_data.error); + + zend_object_std_dtor(&nfo->zo); +} + +void rangeformatter_register_class(void) +{ + class_entry_IntlNumberRangeFormatter = register_class_IntlNumberRangeFormatter(); + class_entry_IntlNumberRangeFormatter->create_object = IntlNumberRangeFormatter_object_create; + + memcpy(&rangeformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + rangeformatter_handlers.offset = XtOffsetOf(IntlNumberRangeFormatter_object, zo); + rangeformatter_handlers.free_obj = IntlNumberRangeFormatter_object_free; + rangeformatter_handlers.clone_obj = NULL; +} diff --git a/ext/intl/rangeformatter/rangeformatter_class.h b/ext/intl/rangeformatter/rangeformatter_class.h new file mode 100644 index 0000000000000..cf8a08aefb4eb --- /dev/null +++ b/ext/intl/rangeformatter/rangeformatter_class.h @@ -0,0 +1,54 @@ +/* + +----------------------------------------------------------------------+ + | 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: | + | https://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: Bogdan Ungureanu | + +----------------------------------------------------------------------+ +*/ + +#ifndef RANGEFORMATTER_CLASS_H +#define RANGEFORMATTER_CLASS_H + +#include + +#ifdef __cplusplus +using icu::number::LocalizedNumberRangeFormatter; +#else +typedef void LocalizedNumberRangeFormatter; +#endif + +typedef struct { + // error handling + intl_error error; + + // formatter handling + LocalizedNumberRangeFormatter* unumrf; +} rangeformatter_data; + +typedef struct { + rangeformatter_data nrf_data; + zend_object zo; +} IntlNumberRangeFormatter_object; + +static inline IntlNumberRangeFormatter_object *php_intl_numberrangeformatter_fetch_object(zend_object *obj) { + return (IntlNumberRangeFormatter_object *)((char*)(obj) - XtOffsetOf(IntlNumberRangeFormatter_object, zo)); +} + +#define Z_INTL_RANGEFORMATTER_P(zv) php_intl_numberrangeformatter_fetch_object(Z_OBJ_P(zv)) + +#define RANGEFORMATTER_ERROR(nfo) (nfo)->nrf_data.error +#define RANGEFORMATTER_ERROR_P(nfo) &(RANGEFORMATTER_ERROR(nfo)) + +#define RANGEFORMATTER_OBJECT(nfo) (nfo)->nrf_data.unumrf + + +void rangeformatter_register_class(void); + + +#endif \ No newline at end of file diff --git a/ext/intl/tests/rangeformatter/basic.phpt b/ext/intl/tests/rangeformatter/basic.phpt new file mode 100644 index 0000000000000..42f29ba12c708 --- /dev/null +++ b/ext/intl/tests/rangeformatter/basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +Basic test for IntlNumberRangeFormatter +--EXTENSIONS-- +intl +--FILE-- +format(1.1, 2.2)); +var_dump($nrf->format(100, 200)); +var_dump($nrf->format(-5, 5)); +?> +--EXPECT-- +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" From 5133aabe859b1d3df9ca5e8a8d93cb9bb8dac468 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Sun, 3 Aug 2025 01:12:48 +0300 Subject: [PATCH 02/10] Add error methods, update error messages and tests --- .../rangeformatter/rangeformatter.stub.php | 23 +- .../rangeformatter/rangeformatter_arginfo.h | 64 ++- .../rangeformatter/rangeformatter_class.cpp | 77 +++- ext/intl/tests/rangeformatter/basic.phpt | 383 +++++++++++++++++- .../rangeformatter/rangeformatter_clone.phpt | 26 ++ .../rangeformatter/rangeformatter_errors.phpt | 63 +++ .../rangeformatter_icu63_compatibility.phpt | 24 ++ 7 files changed, 636 insertions(+), 24 deletions(-) create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_clone.phpt create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_errors.phpt create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt diff --git a/ext/intl/rangeformatter/rangeformatter.stub.php b/ext/intl/rangeformatter/rangeformatter.stub.php index 2cd947ecab07d..eae40b5a56c23 100644 --- a/ext/intl/rangeformatter/rangeformatter.stub.php +++ b/ext/intl/rangeformatter/rangeformatter.stub.php @@ -7,7 +7,7 @@ * @strict-properties */ final class IntlNumberRangeFormatter { - +#if U_ICU_VERSION_MAJOR_NUM >= 63 /** @cvalue UNUM_RANGE_COLLAPSE_AUTO */ public const int COLLAPSE_AUTO = UNKNOWN; @@ -31,10 +31,31 @@ final class IntlNumberRangeFormatter { /** @cvalue UNUM_IDENTITY_FALLBACK_RANGE */ public const int IDENTITY_FALLBACK_RANGE = UNKNOWN; +#else + public const int COLLAPSE_AUTO = 0; + + public const int COLLAPSE_NONE = 1; + + public const int COLLAPSE_UNIT = 2; + + public const int COLLAPSE_ALL = 3; + + public const int IDENTITY_FALLBACK_SINGLE_VALUE = 0; + + public const int IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE = 1; + + public const int IDENTITY_FALLBACK_APPROXIMATELY = 2; + + public const int IDENTITY_FALLBACK_RANGE = 3; +#endif private function __construct() {} public static function createFromSkeleton(string $skeleton, string $locale, int $collapse, int $identityFallback): IntlNumberRangeFormatter {} public function format(float|int $start, float|int $end): string {} + + public function getErrorCode(): int {} + + public function getErrorMessage(): string {} } diff --git a/ext/intl/rangeformatter/rangeformatter_arginfo.h b/ext/intl/rangeformatter/rangeformatter_arginfo.h index 9b3234bd8d31c..00e923702be11 100644 --- a/ext/intl/rangeformatter/rangeformatter_arginfo.h +++ b/ext/intl/rangeformatter/rangeformatter_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: c70c84f9487bfa60f66e22bde4c2c6e9dcc02d64 */ + * Stub hash: 7029642524e32984e893e1e050a5e0bbf275c416 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IntlNumberRangeFormatter___construct, 0, 0, 0) ZEND_END_ARG_INFO() @@ -16,14 +16,24 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_IntlNumberRangeFormatter_f ZEND_ARG_TYPE_MASK(0, end, MAY_BE_DOUBLE|MAY_BE_LONG, NULL) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_IntlNumberRangeFormatter_getErrorCode, 0, 0, IS_LONG, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_IntlNumberRangeFormatter_getErrorMessage, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_METHOD(IntlNumberRangeFormatter, __construct); ZEND_METHOD(IntlNumberRangeFormatter, createFromSkeleton); ZEND_METHOD(IntlNumberRangeFormatter, format); +ZEND_METHOD(IntlNumberRangeFormatter, getErrorCode); +ZEND_METHOD(IntlNumberRangeFormatter, getErrorMessage); static const zend_function_entry class_IntlNumberRangeFormatter_methods[] = { ZEND_ME(IntlNumberRangeFormatter, __construct, arginfo_class_IntlNumberRangeFormatter___construct, ZEND_ACC_PRIVATE) ZEND_ME(IntlNumberRangeFormatter, createFromSkeleton, arginfo_class_IntlNumberRangeFormatter_createFromSkeleton, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(IntlNumberRangeFormatter, format, arginfo_class_IntlNumberRangeFormatter_format, ZEND_ACC_PUBLIC) + ZEND_ME(IntlNumberRangeFormatter, getErrorCode, arginfo_class_IntlNumberRangeFormatter_getErrorCode, ZEND_ACC_PUBLIC) + ZEND_ME(IntlNumberRangeFormatter, getErrorMessage, arginfo_class_IntlNumberRangeFormatter_getErrorMessage, ZEND_ACC_PUBLIC) ZEND_FE_END }; @@ -33,6 +43,7 @@ static zend_class_entry *register_class_IntlNumberRangeFormatter(void) INIT_CLASS_ENTRY(ce, "IntlNumberRangeFormatter", class_IntlNumberRangeFormatter_methods); class_entry = zend_register_internal_class_with_flags(&ce, NULL, ZEND_ACC_FINAL|ZEND_ACC_NO_DYNAMIC_PROPERTIES|ZEND_ACC_NOT_SERIALIZABLE); +#if U_ICU_VERSION_MAJOR_NUM >= 63 zval const_COLLAPSE_AUTO_value; ZVAL_LONG(&const_COLLAPSE_AUTO_value, UNUM_RANGE_COLLAPSE_AUTO); @@ -81,6 +92,57 @@ static zend_class_entry *register_class_IntlNumberRangeFormatter(void) zend_string *const_IDENTITY_FALLBACK_RANGE_name = zend_string_init_interned("IDENTITY_FALLBACK_RANGE", sizeof("IDENTITY_FALLBACK_RANGE") - 1, 1); zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_RANGE_name, &const_IDENTITY_FALLBACK_RANGE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); zend_string_release(const_IDENTITY_FALLBACK_RANGE_name); +#endif +#if !(U_ICU_VERSION_MAJOR_NUM >= 63) + + zval const_COLLAPSE_AUTO_value; + ZVAL_LONG(&const_COLLAPSE_AUTO_value, 0); + zend_string *const_COLLAPSE_AUTO_name = zend_string_init_interned("COLLAPSE_AUTO", sizeof("COLLAPSE_AUTO") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_AUTO_name, &const_COLLAPSE_AUTO_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_COLLAPSE_AUTO_name); + + zval const_COLLAPSE_NONE_value; + ZVAL_LONG(&const_COLLAPSE_NONE_value, 1); + zend_string *const_COLLAPSE_NONE_name = zend_string_init_interned("COLLAPSE_NONE", sizeof("COLLAPSE_NONE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_NONE_name, &const_COLLAPSE_NONE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_COLLAPSE_NONE_name); + + zval const_COLLAPSE_UNIT_value; + ZVAL_LONG(&const_COLLAPSE_UNIT_value, 2); + zend_string *const_COLLAPSE_UNIT_name = zend_string_init_interned("COLLAPSE_UNIT", sizeof("COLLAPSE_UNIT") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_UNIT_name, &const_COLLAPSE_UNIT_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_COLLAPSE_UNIT_name); + + zval const_COLLAPSE_ALL_value; + ZVAL_LONG(&const_COLLAPSE_ALL_value, 3); + zend_string *const_COLLAPSE_ALL_name = zend_string_init_interned("COLLAPSE_ALL", sizeof("COLLAPSE_ALL") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_COLLAPSE_ALL_name, &const_COLLAPSE_ALL_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_COLLAPSE_ALL_name); + + zval const_IDENTITY_FALLBACK_SINGLE_VALUE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_SINGLE_VALUE_value, 0); + zend_string *const_IDENTITY_FALLBACK_SINGLE_VALUE_name = zend_string_init_interned("IDENTITY_FALLBACK_SINGLE_VALUE", sizeof("IDENTITY_FALLBACK_SINGLE_VALUE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_SINGLE_VALUE_name, &const_IDENTITY_FALLBACK_SINGLE_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IDENTITY_FALLBACK_SINGLE_VALUE_name); + + zval const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value, 1); + zend_string *const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name = zend_string_init_interned("IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE", sizeof("IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name, &const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE_name); + + zval const_IDENTITY_FALLBACK_APPROXIMATELY_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_APPROXIMATELY_value, 2); + zend_string *const_IDENTITY_FALLBACK_APPROXIMATELY_name = zend_string_init_interned("IDENTITY_FALLBACK_APPROXIMATELY", sizeof("IDENTITY_FALLBACK_APPROXIMATELY") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_APPROXIMATELY_name, &const_IDENTITY_FALLBACK_APPROXIMATELY_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IDENTITY_FALLBACK_APPROXIMATELY_name); + + zval const_IDENTITY_FALLBACK_RANGE_value; + ZVAL_LONG(&const_IDENTITY_FALLBACK_RANGE_value, 3); + zend_string *const_IDENTITY_FALLBACK_RANGE_name = zend_string_init_interned("IDENTITY_FALLBACK_RANGE", sizeof("IDENTITY_FALLBACK_RANGE") - 1, 1); + zend_declare_typed_class_constant(class_entry, const_IDENTITY_FALLBACK_RANGE_name, &const_IDENTITY_FALLBACK_RANGE_value, ZEND_ACC_PUBLIC, NULL, (zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_LONG)); + zend_string_release(const_IDENTITY_FALLBACK_RANGE_name); +#endif return class_entry; } diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index 09368a51c0eac..eb44d1342aeb5 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -20,6 +20,9 @@ extern "C" { #include "php.h" + #include "zend_API.h" + #include "../intl_common.h" + #include "../intl_error.h" #include "../php_intl.h" #include "../intl_data.h" #include "rangeformatter_arginfo.h" @@ -45,16 +48,28 @@ zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) zend_object_std_init(&intern->zo, ce); object_properties_init(&intern->zo, ce); + // Initialize rangeformatter_data structure + intl_error_init(&intern->nrf_data.error); + intern->nrf_data.unumrf = nullptr; + + intern->zo.handlers = &rangeformatter_handlers; + return &intern->zo; } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct) { - + ZEND_PARSE_PARAMETERS_NONE(); + zend_throw_error(NULL, "Cannot directly construct %s, use createFromSkeleton method instead", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name)); } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) { + #if U_ICU_VERSION_MAJOR_NUM < 63 + zend_throw_error(NULL, "IntlNumberRangeFormatter is not available in ICU 62 and earlier"); + RETURN_THROWS(); + #endif + char* skeleton; char* locale; size_t locale_len; @@ -74,12 +89,12 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) } if (skeleton_len == 0) { - zend_argument_value_error(1, "Skeleton string cannot be empty"); + zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } if (locale_len > INTL_MAX_LOCALE_LEN) { - zend_argument_value_error(2, "Locale string too long, should be no longer than %d characters", INTL_MAX_LOCALE_LEN); + zend_argument_value_error(2, "must be no longer than %d characters", INTL_MAX_LOCALE_LEN); RETURN_THROWS(); } @@ -89,20 +104,26 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) } if (collapse != UNUM_RANGE_COLLAPSE_AUTO && collapse != UNUM_RANGE_COLLAPSE_NONE && collapse != UNUM_RANGE_COLLAPSE_UNIT && collapse != UNUM_RANGE_COLLAPSE_ALL) { - zend_argument_value_error(3, "Invalid collapse value"); + zend_argument_value_error(3, "must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL"); RETURN_THROWS(); } if (identityFallback != UNUM_IDENTITY_FALLBACK_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE && identityFallback != UNUM_IDENTITY_FALLBACK_APPROXIMATELY && identityFallback != UNUM_IDENTITY_FALLBACK_RANGE) { - zend_argument_value_error(4, "Invalid identity fallback value"); + zend_argument_value_error(4, "must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE"); RETURN_THROWS(); } - UErrorCode error = U_ZERO_ERROR; + UErrorCode status = U_ZERO_ERROR; UnicodeString skeleton_ustr(skeleton, skeleton_len); - UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, error); + UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, status); + + if (U_FAILURE(status)) { + intl_error_set(NULL, status, "Failed to create the number skeleton", 0); + zend_throw_exception(IntlException_ce_ptr, "Failed to create the number skeleton", 0); + RETURN_THROWS(); + } LocalizedNumberRangeFormatter* nrf = new LocalizedNumberRangeFormatter( NumberRangeFormatter::with() @@ -113,7 +134,6 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) ); zend_object* obj = IntlNumberRangeFormatter_object_create(class_entry_IntlNumberRangeFormatter); - obj->handlers = &rangeformatter_handlers; RANGEFORMATTER_OBJECT(php_intl_numberrangeformatter_fetch_object(obj)) = nrf; @@ -123,37 +143,58 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) { - double start; - double end; + zval *start; + zval *end; IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); ZEND_PARSE_PARAMETERS_START(2, 2) - Z_PARAM_DOUBLE(start) - Z_PARAM_DOUBLE(end) + Z_PARAM_NUMBER(start) + Z_PARAM_NUMBER(end) ZEND_PARSE_PARAMETERS_END(); UErrorCode error = U_ZERO_ERROR; - UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start, end, error).toString(error); + icu::Formattable start_formattable(Z_TYPE_P(start) == IS_DOUBLE ? Z_DVAL_P(start) : Z_LVAL_P(start)); + icu::Formattable end_formattable(Z_TYPE_P(end) == IS_DOUBLE ? Z_DVAL_P(end) : Z_LVAL_P(end)); + + UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start_formattable, end_formattable, error).toString(error); if (U_FAILURE(error)) { intl_error_set(NULL, error, "Failed to format number range", 0); - - return; + zend_throw_exception(IntlException_ce_ptr, "Failed to format number range", 0); + RETURN_THROWS(); } zend_string *ret = intl_charFromString(result, &error); - if (!ret) { + if (U_FAILURE(error)) { intl_error_set(NULL, error, "Failed to convert result to UTF-8", 0); - // RETVAL_FALSE; - return; + zend_throw_exception(IntlException_ce_ptr, "Failed to convert result to UTF-8", 0); + RETURN_THROWS(); } RETVAL_NEW_STR(ret); } +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorCode) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); + + RETURN_LONG(intl_error_get_code(&obj->nrf_data.error)); +} + +U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorMessage) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + IntlNumberRangeFormatter_object* obj = Z_INTL_RANGEFORMATTER_P(ZEND_THIS); + + RETURN_STR(intl_error_get_message(&obj->nrf_data.error)); +} + void IntlNumberRangeFormatter_object_free(zend_object *object) { IntlNumberRangeFormatter_object* nfo = php_intl_numberrangeformatter_fetch_object(object); diff --git a/ext/intl/tests/rangeformatter/basic.phpt b/ext/intl/tests/rangeformatter/basic.phpt index 42f29ba12c708..70aae282614bc 100644 --- a/ext/intl/tests/rangeformatter/basic.phpt +++ b/ext/intl/tests/rangeformatter/basic.phpt @@ -2,19 +2,394 @@ Basic test for IntlNumberRangeFormatter --EXTENSIONS-- intl +--SKIPIF-- + --FILE-- IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, + 'IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE' => IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, + 'IDENTITY_FALLBACK_APPROXIMATELY' => IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, + 'IDENTITY_FALLBACK_RANGE' => IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE +]; + +$collapses = [ + 'COLLAPSE_AUTO' => IntlNumberRangeFormatter::COLLAPSE_AUTO, + 'COLLAPSE_NONE' => IntlNumberRangeFormatter::COLLAPSE_NONE, + 'COLLAPSE_UNIT' => IntlNumberRangeFormatter::COLLAPSE_UNIT, + 'COLLAPSE_ALL' => IntlNumberRangeFormatter::COLLAPSE_ALL +]; + +foreach ($languages as $language) { + foreach ($identityFallbacks as $iName => $identityFallback) { + foreach ($collapses as $cName => $collapse) { + echo PHP_EOL . $language . ' - ' . $cName . ' - ' . $iName . PHP_EOL; + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'measure-unit/length-meter', + $language, + $collapse, + $identityFallback + ); + + var_dump($nrf->format(1.1, 2.2)); + var_dump($nrf->format(100, 200)); + var_dump($nrf->format(-5, 5)); + var_dump($nrf->format(5, 5)); + var_dump($nrf->format(5.0001, 5.0001)); + + } + } +} +echo 'en_GB - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE' . PHP_EOL; $nrf = IntlNumberRangeFormatter::createFromSkeleton( - 'measure-unit/length-meter', 'ro', + 'measure-unit/length-meter', + 'en_GB', IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE ); -var_dump($nrf->format(1.1, 2.2)); -var_dump($nrf->format(100, 200)); -var_dump($nrf->format(-5, 5)); ?> --EXPECT-- +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(4) "~5 m" +string(9) "~5.0001 m" + +en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(7) "5–5 m" +string(17) "5.0001–5.0001 m" + +en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE +string(15) "1.1 m – 2.2 m" +string(15) "100 m – 200 m" +string(12) "-5 m – 5 m" +string(11) "5 m – 5 m" +string(21) "5.0001 m – 5.0001 m" + +en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(7) "5–5 m" +string(17) "5.0001–5.0001 m" + +en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE +string(11) "1.1–2.2 m" +string(11) "100–200 m" +string(10) "-5 – 5 m" +string(7) "5–5 m" +string(17) "5.0001–5.0001 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(3) "5 m" +string(8) "5,0001 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(4) "~5 m" +string(9) "~5,0001 m" + +RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(7) "5 - 5 m" +string(17) "5,0001 - 5,0001 m" + +RO - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE +string(13) "1,1 m - 2,2 m" +string(13) "100 m - 200 m" +string(10) "-5 m - 5 m" +string(9) "5 m - 5 m" +string(19) "5,0001 m - 5,0001 m" + +RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE +string(11) "1,1 - 2,2 m" +string(11) "100 - 200 m" +string(8) "-5 - 5 m" +string(7) "5 - 5 m" +string(17) "5,0001 - 5,0001 m" + +RO - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE string(11) "1,1 - 2,2 m" string(11) "100 - 200 m" string(8) "-5 - 5 m" +string(7) "5 - 5 m" +string(17) "5,0001 - 5,0001 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(3) "5 m" +string(8) "5.0001 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(6) "約5 m" +string(11) "約5.0001 m" + +JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(7) "5~5 m" +string(17) "5.0001~5.0001 m" + +JA - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE +string(15) "1.1 m ~ 2.2 m" +string(15) "100 m ~ 200 m" +string(12) "-5 m ~ 5 m" +string(11) "5 m ~ 5 m" +string(21) "5.0001 m ~ 5.0001 m" + +JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(7) "5~5 m" +string(17) "5.0001~5.0001 m" + +JA - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE +string(11) "1.1~2.2 m" +string(11) "100~200 m" +string(10) "-5 ~ 5 m" +string(7) "5~5 m" +string(17) "5.0001~5.0001 m" +en_GB - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE diff --git a/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt b/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt new file mode 100644 index 0000000000000..f8a0dd30e9da0 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test IntlNumberRangeFormatter cannot be cloned +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Trying to clone an uncloneable object of class IntlNumberRangeFormatter \ No newline at end of file diff --git a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt new file mode 100644 index 0000000000000..e4bd3edbb18fd --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt @@ -0,0 +1,63 @@ +--TEST-- +errors for IntlNumberRangeFormatter +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +getMessage() . PHP_EOL; +} + +echo intl_get_error_code() . PHP_EOL; +echo intl_get_error_message() . PHP_EOL; + +try { + new IntlNumberRangeFormatter(); +} catch(Error $error) { + echo $error->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'ro', + 34, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'ro', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + 343 + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +?> +--EXPECT-- +Failed to create the number skeleton +65811 +Failed to create the number skeleton: U_NUMBER_SKELETON_SYNTAX_ERROR +Call to private IntlNumberRangeFormatter::__construct() from global scope +IntlNumberRangeFormatter::createFromSkeleton(): Argument #3 ($collapse) must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL +IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE \ No newline at end of file diff --git a/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt b/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt new file mode 100644 index 0000000000000..5152a25c1706c --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test IntlNumberRangeFormatter::createFromSkeleton throws error for ICU < 63 +--SKIPIF-- += 0) { + die('skip for ICU > 63.0'); +} +?> +--FILE-- +getMessage(); +} +?> +--EXPECT-- +IntlNumberRangeFormatter is not available in ICU 62 and earlier \ No newline at end of file From d7ba5ff6580c45293d274120ff294a51725863c8 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Sun, 3 Aug 2025 01:43:16 +0300 Subject: [PATCH 03/10] remove the 4th param in intl_error_set --- ext/intl/rangeformatter/rangeformatter_class.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index eb44d1342aeb5..c5e3487c7379f 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -120,7 +120,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) UnlocalizedNumberFormatter nf = NumberFormatter::forSkeleton(skeleton_ustr, status); if (U_FAILURE(status)) { - intl_error_set(NULL, status, "Failed to create the number skeleton", 0); + intl_error_set(NULL, status, "Failed to create the number skeleton"); zend_throw_exception(IntlException_ce_ptr, "Failed to create the number skeleton", 0); RETURN_THROWS(); } @@ -161,7 +161,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) UnicodeString result = RANGEFORMATTER_OBJECT(obj)->formatFormattableRange(start_formattable, end_formattable, error).toString(error); if (U_FAILURE(error)) { - intl_error_set(NULL, error, "Failed to format number range", 0); + intl_error_set(NULL, error, "Failed to format number range"); zend_throw_exception(IntlException_ce_ptr, "Failed to format number range", 0); RETURN_THROWS(); } @@ -169,7 +169,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) zend_string *ret = intl_charFromString(result, &error); if (U_FAILURE(error)) { - intl_error_set(NULL, error, "Failed to convert result to UTF-8", 0); + intl_error_set(NULL, error, "Failed to convert result to UTF-8"); zend_throw_exception(IntlException_ce_ptr, "Failed to convert result to UTF-8", 0); RETURN_THROWS(); } From aebecd3108e1d2a8edbc569f3dd9ab6b95299bf2 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Sun, 3 Aug 2025 02:05:36 +0300 Subject: [PATCH 04/10] fix failing test --- ext/intl/tests/rangeformatter/rangeformatter_errors.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt index e4bd3edbb18fd..8d2ab0b755785 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt @@ -57,7 +57,7 @@ try { --EXPECT-- Failed to create the number skeleton 65811 -Failed to create the number skeleton: U_NUMBER_SKELETON_SYNTAX_ERROR +IntlNumberRangeFormatter::createFromSkeleton(): Failed to create the number skeleton: U_NUMBER_SKELETON_SYNTAX_ERROR Call to private IntlNumberRangeFormatter::__construct() from global scope IntlNumberRangeFormatter::createFromSkeleton(): Argument #3 ($collapse) must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE \ No newline at end of file From c5464734b9bf3d092d38775c6f7c35fb106a8d88 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Mon, 4 Aug 2025 15:34:05 +0300 Subject: [PATCH 05/10] change validation order and use reinterpret_cast --- ext/intl/rangeformatter/rangeformatter_class.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index c5e3487c7379f..838f015d5c317 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -44,7 +44,7 @@ zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) { IntlNumberRangeFormatter_object* intern; - intern = (IntlNumberRangeFormatter_object*)zend_object_alloc(sizeof(IntlNumberRangeFormatter_object), ce); + intern = reinterpret_cast(zend_object_alloc(sizeof(IntlNumberRangeFormatter_object), ce)); zend_object_std_init(&intern->zo, ce); object_properties_init(&intern->zo, ce); @@ -84,14 +84,14 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) Z_PARAM_LONG(identityFallback) ZEND_PARSE_PARAMETERS_END(); - if (locale_len == 0) { - locale = (char *)intl_locale_get_default(); - } - if (skeleton_len == 0) { zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } + + if (locale_len == 0) { + locale = (char *)intl_locale_get_default(); + } if (locale_len > INTL_MAX_LOCALE_LEN) { zend_argument_value_error(2, "must be no longer than %d characters", INTL_MAX_LOCALE_LEN); From 27da6a175ddcbdf941d0c25c84236698c54599c7 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Mon, 4 Aug 2025 15:39:03 +0300 Subject: [PATCH 06/10] Add more tests --- .../rangeformatter/rangeformatter_errors.phpt | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt index 8d2ab0b755785..58a62c1e26b3e 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt @@ -53,6 +53,28 @@ try { echo $exception->getMessage() . PHP_EOL; } +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'invalid-language', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + +try { + $nrf = IntlNumberRangeFormatter::createFromSkeleton( + 'invalid skeleton here', + 'ro_thisiswaytooooooooooooooooooooooooooooooooooooooooooooolongtobevaliditneedstobeatleast157characterstofailthevalidationinthelistformattercodeimplementation', + IntlNumberRangeFormatter::COLLAPSE_AUTO, + IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE + ); +} catch (ValueError $exception) { + echo $exception->getMessage() . PHP_EOL; +} + ?> --EXPECT-- Failed to create the number skeleton @@ -60,4 +82,6 @@ Failed to create the number skeleton IntlNumberRangeFormatter::createFromSkeleton(): Failed to create the number skeleton: U_NUMBER_SKELETON_SYNTAX_ERROR Call to private IntlNumberRangeFormatter::__construct() from global scope IntlNumberRangeFormatter::createFromSkeleton(): Argument #3 ($collapse) must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL -IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE \ No newline at end of file +IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE +IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) "invalid-language" is invalid +IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) must be no longer than 156 characters \ No newline at end of file From 08aa56cc922519cf94470af00417298e6a32a407 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Tue, 5 Aug 2025 00:58:47 +0300 Subject: [PATCH 07/10] formatting fixes --- .../rangeformatter/rangeformatter_class.cpp | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index 838f015d5c317..21a8fa71fec3b 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -27,7 +27,7 @@ extern "C" { #include "../intl_data.h" #include "rangeformatter_arginfo.h" #include "rangeformatter_class.h" -#include "intl_convert.h" + #include "intl_convert.h" } using icu::number::NumberRangeFormatter; @@ -45,16 +45,16 @@ zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) IntlNumberRangeFormatter_object* intern; intern = reinterpret_cast(zend_object_alloc(sizeof(IntlNumberRangeFormatter_object), ce)); - zend_object_std_init(&intern->zo, ce); - object_properties_init(&intern->zo, ce); + zend_object_std_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); - // Initialize rangeformatter_data structure - intl_error_init(&intern->nrf_data.error); - intern->nrf_data.unumrf = nullptr; + // Initialize rangeformatter_data structure + intl_error_init(&intern->nrf_data.error); + intern->nrf_data.unumrf = nullptr; intern->zo.handlers = &rangeformatter_handlers; - return &intern->zo; + return &intern->zo; } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct) @@ -65,10 +65,10 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, __construct) U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) { - #if U_ICU_VERSION_MAJOR_NUM < 63 - zend_throw_error(NULL, "IntlNumberRangeFormatter is not available in ICU 62 and earlier"); - RETURN_THROWS(); - #endif +#if U_ICU_VERSION_MAJOR_NUM < 63 + zend_throw_error(NULL, "IntlNumberRangeFormatter is not available in ICU 62 and earlier"); + RETURN_THROWS(); +#endif char* skeleton; char* locale; @@ -88,7 +88,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) zend_argument_must_not_be_empty_error(1); RETURN_THROWS(); } - + if (locale_len == 0) { locale = (char *)intl_locale_get_default(); } @@ -138,7 +138,6 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) RANGEFORMATTER_OBJECT(php_intl_numberrangeformatter_fetch_object(obj)) = nrf; RETURN_OBJ(obj); - } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) @@ -166,15 +165,15 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) RETURN_THROWS(); } - zend_string *ret = intl_charFromString(result, &error); + zend_string *ret = intl_charFromString(result, &error); - if (U_FAILURE(error)) { + if (U_FAILURE(error)) { intl_error_set(NULL, error, "Failed to convert result to UTF-8"); zend_throw_exception(IntlException_ce_ptr, "Failed to convert result to UTF-8", 0); RETURN_THROWS(); - } + } - RETVAL_NEW_STR(ret); + RETVAL_NEW_STR(ret); } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorCode) @@ -197,7 +196,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorMessage) void IntlNumberRangeFormatter_object_free(zend_object *object) { - IntlNumberRangeFormatter_object* nfo = php_intl_numberrangeformatter_fetch_object(object); + IntlNumberRangeFormatter_object* nfo = php_intl_numberrangeformatter_fetch_object(object); if (nfo->nrf_data.unumrf) { delete nfo->nrf_data.unumrf; @@ -206,14 +205,14 @@ void IntlNumberRangeFormatter_object_free(zend_object *object) intl_error_reset(&nfo->nrf_data.error); - zend_object_std_dtor(&nfo->zo); + zend_object_std_dtor(&nfo->zo); } void rangeformatter_register_class(void) { class_entry_IntlNumberRangeFormatter = register_class_IntlNumberRangeFormatter(); class_entry_IntlNumberRangeFormatter->create_object = IntlNumberRangeFormatter_object_create; - + memcpy(&rangeformatter_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); rangeformatter_handlers.offset = XtOffsetOf(IntlNumberRangeFormatter_object, zo); rangeformatter_handlers.free_obj = IntlNumberRangeFormatter_object_free; From d0cc2a01aff0b92cfadbff40628b94402e81c23c Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Fri, 8 Aug 2025 01:24:31 +0300 Subject: [PATCH 08/10] Remove empty validation for skeleton, fix formatting and add more tests --- .../rangeformatter/rangeformatter_class.cpp | 7 +- ext/intl/tests/rangeformatter/basic.phpt | 107 ++++++++++++++++-- .../rangeformatter_fraction_skeleton.phpt | 39 +++++++ .../rangeformatter_with_empty_skeleton.phpt | 24 ++++ 4 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt create mode 100644 ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index 21a8fa71fec3b..3e6435982afcf 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -42,7 +42,7 @@ zend_class_entry *class_entry_IntlNumberRangeFormatter; zend_object *IntlNumberRangeFormatter_object_create(zend_class_entry *ce) { - IntlNumberRangeFormatter_object* intern; + IntlNumberRangeFormatter_object* intern; intern = reinterpret_cast(zend_object_alloc(sizeof(IntlNumberRangeFormatter_object), ce)); zend_object_std_init(&intern->zo, ce); @@ -84,11 +84,6 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) Z_PARAM_LONG(identityFallback) ZEND_PARSE_PARAMETERS_END(); - if (skeleton_len == 0) { - zend_argument_must_not_be_empty_error(1); - RETURN_THROWS(); - } - if (locale_len == 0) { locale = (char *)intl_locale_get_default(); } diff --git a/ext/intl/tests/rangeformatter/basic.phpt b/ext/intl/tests/rangeformatter/basic.phpt index 70aae282614bc..ebb164a4c508c 100644 --- a/ext/intl/tests/rangeformatter/basic.phpt +++ b/ext/intl/tests/rangeformatter/basic.phpt @@ -43,17 +43,11 @@ foreach ($languages as $language) { var_dump($nrf->format(-5, 5)); var_dump($nrf->format(5, 5)); var_dump($nrf->format(5.0001, 5.0001)); - + var_dump($nrf->format(5, 5.1)); + var_dump($nrf->format(5.1, 6)); } } } -echo 'en_GB - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE' . PHP_EOL; -$nrf = IntlNumberRangeFormatter::createFromSkeleton( - 'measure-unit/length-meter', - 'en_GB', - IntlNumberRangeFormatter::COLLAPSE_AUTO, - IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE -); ?> --EXPECT-- @@ -63,6 +57,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE string(15) "1.1 m – 2.2 m" @@ -70,6 +66,8 @@ string(15) "100 m – 200 m" string(12) "-5 m – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1.1–2.2 m" @@ -77,6 +75,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1.1–2.2 m" @@ -84,6 +84,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1.1–2.2 m" @@ -91,6 +93,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(15) "1.1 m – 2.2 m" @@ -98,6 +102,8 @@ string(15) "100 m – 200 m" string(12) "-5 m – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1.1–2.2 m" @@ -105,6 +111,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1.1–2.2 m" @@ -112,6 +120,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1.1–2.2 m" @@ -119,6 +129,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(4) "~5 m" string(9) "~5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY string(15) "1.1 m – 2.2 m" @@ -126,6 +138,8 @@ string(15) "100 m – 200 m" string(12) "-5 m – 5 m" string(4) "~5 m" string(9) "~5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1.1–2.2 m" @@ -133,6 +147,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(4) "~5 m" string(9) "~5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1.1–2.2 m" @@ -140,6 +156,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(4) "~5 m" string(9) "~5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE string(11) "1.1–2.2 m" @@ -147,6 +165,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(7) "5–5 m" string(17) "5.0001–5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE string(15) "1.1 m – 2.2 m" @@ -154,6 +174,8 @@ string(15) "100 m – 200 m" string(12) "-5 m – 5 m" string(11) "5 m – 5 m" string(21) "5.0001 m – 5.0001 m" +string(13) "5 m – 5.1 m" +string(13) "5.1 m – 6 m" en_US - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE string(11) "1.1–2.2 m" @@ -161,6 +183,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(7) "5–5 m" string(17) "5.0001–5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" en_US - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE string(11) "1.1–2.2 m" @@ -168,6 +192,8 @@ string(11) "100–200 m" string(10) "-5 – 5 m" string(7) "5–5 m" string(17) "5.0001–5.0001 m" +string(9) "5–5.1 m" +string(9) "5.1–6 m" RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1,1 - 2,2 m" @@ -175,6 +201,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE string(13) "1,1 m - 2,2 m" @@ -182,6 +210,8 @@ string(13) "100 m - 200 m" string(10) "-5 m - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1,1 - 2,2 m" @@ -189,6 +219,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1,1 - 2,2 m" @@ -196,6 +228,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1,1 - 2,2 m" @@ -203,6 +237,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(13) "1,1 m - 2,2 m" @@ -210,6 +246,8 @@ string(13) "100 m - 200 m" string(10) "-5 m - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1,1 - 2,2 m" @@ -217,6 +255,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1,1 - 2,2 m" @@ -224,6 +264,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(3) "5 m" string(8) "5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1,1 - 2,2 m" @@ -231,6 +273,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(4) "~5 m" string(9) "~5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY string(13) "1,1 m - 2,2 m" @@ -238,6 +282,8 @@ string(13) "100 m - 200 m" string(10) "-5 m - 5 m" string(4) "~5 m" string(9) "~5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1,1 - 2,2 m" @@ -245,6 +291,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(4) "~5 m" string(9) "~5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1,1 - 2,2 m" @@ -252,6 +300,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(4) "~5 m" string(9) "~5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE string(11) "1,1 - 2,2 m" @@ -259,6 +309,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(7) "5 - 5 m" string(17) "5,0001 - 5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE string(13) "1,1 m - 2,2 m" @@ -266,6 +318,8 @@ string(13) "100 m - 200 m" string(10) "-5 m - 5 m" string(9) "5 m - 5 m" string(19) "5,0001 m - 5,0001 m" +string(11) "5 m - 5,1 m" +string(11) "5,1 m - 6 m" RO - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE string(11) "1,1 - 2,2 m" @@ -273,6 +327,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(7) "5 - 5 m" string(17) "5,0001 - 5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" RO - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE string(11) "1,1 - 2,2 m" @@ -280,6 +336,8 @@ string(11) "100 - 200 m" string(8) "-5 - 5 m" string(7) "5 - 5 m" string(17) "5,0001 - 5,0001 m" +string(9) "5 - 5,1 m" +string(9) "5,1 - 6 m" JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1.1~2.2 m" @@ -287,6 +345,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_NONE - IDENTITY_FALLBACK_SINGLE_VALUE string(15) "1.1 m ~ 2.2 m" @@ -294,6 +354,8 @@ string(15) "100 m ~ 200 m" string(12) "-5 m ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1.1~2.2 m" @@ -301,6 +363,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_ALL - IDENTITY_FALLBACK_SINGLE_VALUE string(11) "1.1~2.2 m" @@ -308,6 +372,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1.1~2.2 m" @@ -315,6 +381,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(15) "1.1 m ~ 2.2 m" @@ -322,6 +390,8 @@ string(15) "100 m ~ 200 m" string(12) "-5 m ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1.1~2.2 m" @@ -329,6 +399,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE string(11) "1.1~2.2 m" @@ -336,6 +408,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(3) "5 m" string(8) "5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1.1~2.2 m" @@ -343,6 +417,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(6) "約5 m" string(11) "約5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_NONE - IDENTITY_FALLBACK_APPROXIMATELY string(15) "1.1 m ~ 2.2 m" @@ -350,6 +426,8 @@ string(15) "100 m ~ 200 m" string(12) "-5 m ~ 5 m" string(6) "約5 m" string(11) "約5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1.1~2.2 m" @@ -357,6 +435,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(6) "約5 m" string(11) "約5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_ALL - IDENTITY_FALLBACK_APPROXIMATELY string(11) "1.1~2.2 m" @@ -364,6 +444,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(6) "約5 m" string(11) "約5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_AUTO - IDENTITY_FALLBACK_RANGE string(11) "1.1~2.2 m" @@ -371,6 +453,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(7) "5~5 m" string(17) "5.0001~5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_NONE - IDENTITY_FALLBACK_RANGE string(15) "1.1 m ~ 2.2 m" @@ -378,6 +462,8 @@ string(15) "100 m ~ 200 m" string(12) "-5 m ~ 5 m" string(11) "5 m ~ 5 m" string(21) "5.0001 m ~ 5.0001 m" +string(13) "5 m ~ 5.1 m" +string(13) "5.1 m ~ 6 m" JA - COLLAPSE_UNIT - IDENTITY_FALLBACK_RANGE string(11) "1.1~2.2 m" @@ -385,6 +471,8 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(7) "5~5 m" string(17) "5.0001~5.0001 m" +string(9) "5~5.1 m" +string(9) "5.1~6 m" JA - COLLAPSE_ALL - IDENTITY_FALLBACK_RANGE string(11) "1.1~2.2 m" @@ -392,4 +480,5 @@ string(11) "100~200 m" string(10) "-5 ~ 5 m" string(7) "5~5 m" string(17) "5.0001~5.0001 m" -en_GB - COLLAPSE_AUTO - IDENTITY_FALLBACK_SINGLE_VALUE +string(9) "5~5.1 m" +string(9) "5.1~6 m" \ No newline at end of file diff --git a/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt b/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt new file mode 100644 index 0000000000000..3cb2ff92d4263 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test precision skeleton with IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format(5.1, 5.2)); + var_dump($nrf->format(5.01, 5.02)); + var_dump($nrf->format(5.001, 5.002)); +} + +?> +--EXPECT-- +Approximate with .## +string(9) "5.1–5.2" +string(11) "5.01–5.02" +string(2) "~5" +Approximate with .# +string(9) "5.1–5.2" +string(2) "~5" +string(2) "~5" \ No newline at end of file diff --git a/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt b/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt new file mode 100644 index 0000000000000..a7513a0f8e4c9 --- /dev/null +++ b/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test an empty skeleton with IntlNumberRangeFormatter +--EXTENSIONS-- +intl +--SKIPIF-- + +--FILE-- +format(5.1, 5.2)); + +?> +--EXPECT-- +string(9) "5.1–5.2" \ No newline at end of file From aee4911484732049944276a8d549cc45badeec6f Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Fri, 8 Aug 2025 01:29:02 +0300 Subject: [PATCH 09/10] Add empty end lines --- ext/intl/rangeformatter/rangeformatter_class.h | 3 +-- ext/intl/tests/rangeformatter/basic.phpt | 2 +- ext/intl/tests/rangeformatter/rangeformatter_clone.phpt | 2 +- ext/intl/tests/rangeformatter/rangeformatter_errors.phpt | 2 +- .../tests/rangeformatter/rangeformatter_fraction_skeleton.phpt | 2 +- .../rangeformatter/rangeformatter_icu63_compatibility.phpt | 2 +- .../rangeformatter/rangeformatter_with_empty_skeleton.phpt | 2 +- 7 files changed, 7 insertions(+), 8 deletions(-) diff --git a/ext/intl/rangeformatter/rangeformatter_class.h b/ext/intl/rangeformatter/rangeformatter_class.h index cf8a08aefb4eb..661641c2ce0f0 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.h +++ b/ext/intl/rangeformatter/rangeformatter_class.h @@ -50,5 +50,4 @@ static inline IntlNumberRangeFormatter_object *php_intl_numberrangeformatter_fet void rangeformatter_register_class(void); - -#endif \ No newline at end of file +#endif diff --git a/ext/intl/tests/rangeformatter/basic.phpt b/ext/intl/tests/rangeformatter/basic.phpt index ebb164a4c508c..0e76466bc09b7 100644 --- a/ext/intl/tests/rangeformatter/basic.phpt +++ b/ext/intl/tests/rangeformatter/basic.phpt @@ -481,4 +481,4 @@ string(10) "-5 ~ 5 m" string(7) "5~5 m" string(17) "5.0001~5.0001 m" string(9) "5~5.1 m" -string(9) "5.1~6 m" \ No newline at end of file +string(9) "5.1~6 m" diff --git a/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt b/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt index f8a0dd30e9da0..9963d7122b831 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_clone.phpt @@ -23,4 +23,4 @@ try { } ?> --EXPECT-- -Trying to clone an uncloneable object of class IntlNumberRangeFormatter \ No newline at end of file +Trying to clone an uncloneable object of class IntlNumberRangeFormatter diff --git a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt index 58a62c1e26b3e..3b0a137fbe89f 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_errors.phpt @@ -84,4 +84,4 @@ Call to private IntlNumberRangeFormatter::__construct() from global scope IntlNumberRangeFormatter::createFromSkeleton(): Argument #3 ($collapse) must be one of IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, or IntlNumberRangeFormatter::COLLAPSE_ALL IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) "invalid-language" is invalid -IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) must be no longer than 156 characters \ No newline at end of file +IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) must be no longer than 156 characters diff --git a/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt b/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt index 3cb2ff92d4263..f054aea94b5fa 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_fraction_skeleton.phpt @@ -36,4 +36,4 @@ string(2) "~5" Approximate with .# string(9) "5.1–5.2" string(2) "~5" -string(2) "~5" \ No newline at end of file +string(2) "~5" diff --git a/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt b/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt index 5152a25c1706c..9f741d77437fe 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_icu63_compatibility.phpt @@ -21,4 +21,4 @@ try { } ?> --EXPECT-- -IntlNumberRangeFormatter is not available in ICU 62 and earlier \ No newline at end of file +IntlNumberRangeFormatter is not available in ICU 62 and earlier diff --git a/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt b/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt index a7513a0f8e4c9..43afc85f2b5fa 100644 --- a/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt +++ b/ext/intl/tests/rangeformatter/rangeformatter_with_empty_skeleton.phpt @@ -21,4 +21,4 @@ var_dump($nrf->format(5.1, 5.2)); ?> --EXPECT-- -string(9) "5.1–5.2" \ No newline at end of file +string(9) "5.1–5.2" From 128a3b61267aae455dc96a87fa02d9ee05510213 Mon Sep 17 00:00:00 2001 From: Bogdan Ungureanu Date: Tue, 12 Aug 2025 01:10:27 +0300 Subject: [PATCH 10/10] Fix compile issues on icu62 and lower --- .../rangeformatter/rangeformatter_class.cpp | 22 ++++++++++++++----- .../rangeformatter/rangeformatter_class.h | 6 +++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/ext/intl/rangeformatter/rangeformatter_class.cpp b/ext/intl/rangeformatter/rangeformatter_class.cpp index 3e6435982afcf..edd447115370a 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.cpp +++ b/ext/intl/rangeformatter/rangeformatter_class.cpp @@ -12,16 +12,21 @@ +----------------------------------------------------------------------+ */ +extern "C" { + #include "php.h" + #include "zend_API.h" + #include "../intl_common.h" +} + +#if U_ICU_VERSION_MAJOR_NUM >= 63 #include #include #include #include #include "../intl_convertcpp.h" +#endif extern "C" { - #include "php.h" - #include "zend_API.h" - #include "../intl_common.h" #include "../intl_error.h" #include "../php_intl.h" #include "../intl_data.h" @@ -30,12 +35,14 @@ extern "C" { #include "intl_convert.h" } +#if U_ICU_VERSION_MAJOR_NUM >= 63 using icu::number::NumberRangeFormatter; using icu::number::NumberFormatter; using icu::number::UnlocalizedNumberFormatter; using icu::number::LocalizedNumberRangeFormatter; using icu::UnicodeString; using icu::MeasureUnit; +#endif static zend_object_handlers rangeformatter_handlers; zend_class_entry *class_entry_IntlNumberRangeFormatter; @@ -68,8 +75,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) #if U_ICU_VERSION_MAJOR_NUM < 63 zend_throw_error(NULL, "IntlNumberRangeFormatter is not available in ICU 62 and earlier"); RETURN_THROWS(); -#endif - +#else char* skeleton; char* locale; size_t locale_len; @@ -133,10 +139,15 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, createFromSkeleton) RANGEFORMATTER_OBJECT(php_intl_numberrangeformatter_fetch_object(obj)) = nrf; RETURN_OBJ(obj); +#endif } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) { +#if U_ICU_VERSION_MAJOR_NUM < 63 + zend_throw_error(NULL, "IntlNumberRangeFormatter is not available in ICU 62 and earlier"); + RETURN_THROWS(); +#else zval *start; zval *end; @@ -169,6 +180,7 @@ U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, format) } RETVAL_NEW_STR(ret); +#endif } U_CFUNC PHP_METHOD(IntlNumberRangeFormatter, getErrorCode) diff --git a/ext/intl/rangeformatter/rangeformatter_class.h b/ext/intl/rangeformatter/rangeformatter_class.h index 661641c2ce0f0..f5018cbaf71fa 100644 --- a/ext/intl/rangeformatter/rangeformatter_class.h +++ b/ext/intl/rangeformatter/rangeformatter_class.h @@ -15,6 +15,7 @@ #ifndef RANGEFORMATTER_CLASS_H #define RANGEFORMATTER_CLASS_H +#if U_ICU_VERSION_MAJOR_NUM >= 63 #include #ifdef __cplusplus @@ -22,13 +23,18 @@ using icu::number::LocalizedNumberRangeFormatter; #else typedef void LocalizedNumberRangeFormatter; #endif +#endif // U_ICU_VERSION_MAJOR_NUM >= 63 typedef struct { // error handling intl_error error; // formatter handling +#if U_ICU_VERSION_MAJOR_NUM >= 63 LocalizedNumberRangeFormatter* unumrf; +#else + void* unumrf; +#endif } rangeformatter_data; typedef struct {