stas Thu Jul 2 00:43:26 2009 UTC
Modified files: (Branch: PHP_5_3)
/php-src/ext/intl/locale locale_methods.c
/php-src/ext/intl/tests locale_lookup.phpt
Log:
cleanup Locale::lookup
http://cvs.php.net/viewvc.cgi/php-src/ext/intl/locale/locale_methods.c?r1=1.1.2.9&r2=1.1.2.10&diff_format=u
Index: php-src/ext/intl/locale/locale_methods.c
diff -u php-src/ext/intl/locale/locale_methods.c:1.1.2.9
php-src/ext/intl/locale/locale_methods.c:1.1.2.10
--- php-src/ext/intl/locale/locale_methods.c:1.1.2.9 Wed Jul 1 20:31:26 2009
+++ php-src/ext/intl/locale/locale_methods.c Thu Jul 2 00:43:26 2009
@@ -14,7 +14,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: locale_methods.c,v 1.1.2.9 2009/07/01 20:31:26 stas Exp $ */
+/* $Id: locale_methods.c,v 1.1.2.10 2009/07/02 00:43:26 stas Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -145,16 +145,16 @@
static int getStrrtokenPos(char* str, int savedPos)
{
int result =-1;
- int i=0;
+ int i;
- for( i=savedPos; i>=0 ;i--){
- if( isIDSeparator(*(str+i)) ){
+ for(i=savedPos; i>=0; i--) {
+ if(isIDSeparator(*(str+i)) ){
/* delimiter found; check for singleton */
- if( isIDSeparator(*(str+i-2)) ){
+ if(i>=2 && isIDSeparator(*(str+i-2)) ){
/* a singleton; so send the position of token
before the singleton */
- result = i-3;
+ result = i-2;
} else {
- result = i-1;
+ result = i;
}
break;
}
@@ -512,25 +512,6 @@
RETURN_FALSE;
}
}
-
-/*
- int singletonPos = 0;
- //Handle singletons
- if( (strcmp(tag_name , LOC_LANG_TAG)==0) &&
isIDPrefix(loc_name) ){
- //return mod_loc_name;
- } else {
- singletonPos = getSingletonPos( loc_name );
- if( singletonPos == 0){
- //singleton at start of script, region
, variant etc.
- //or invalid singleton at start of
language
- RETURN_FALSE;
- }else if(singletonPos > 0){
- //singleton at some position except at start
- //strip off the singleton and rest of the
loc_name
- mod_loc_name = estrndup( loc_name ,
singletonPos-1);
- }
- }
-*/
} /* end of if != LOC_CANONICAL_TAG */
if( mod_loc_name==NULL ){
@@ -1187,7 +1168,7 @@
/* }}} */
/*{{{
-* Converts to lower case and also replaces all hyphuns with the underscore
+* Converts to lower case and also replaces all hyphens with the underscore
*/
static int strToMatch(char* str ,char *retstr)
{
@@ -1196,7 +1177,7 @@
int result = 0;
int len = 0;
- if( (!str) || strlen(str) ==0){
+ if( (!str) || str[0] == '\0'){
return result;
} else {
anchor = retstr;
@@ -1221,11 +1202,11 @@
}
/* }}} */
-/* {{{ proto static boolean Locale::filterMatches(string $langtag, string
$locale, bool $canonicalize)
+/* {{{ proto static boolean Locale::filterMatches(string $langtag, string
$locale[, bool $canonicalize])
* Checks if a $langtag filter matches with $locale according to RFC 4647's
basic filtering algorithm
*/
/* }}} */
-/* {{{ proto boolean locale_filter_matches(string $langtag, string $locale,
bool $canonicalize)
+/* {{{ proto boolean locale_filter_matches(string $langtag, string $locale[,
bool $canonicalize])
* Checks if a $langtag filter matches with $locale according to RFC 4647's
basic filtering algorithm
*/
PHP_FUNCTION(locale_filter_matches)
@@ -1250,7 +1231,7 @@
intl_error_reset( NULL TSRMLS_CC );
- if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ssb",
+ if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ss|b",
&lang_tag, &lang_tag_len , &loc_range , &loc_range_len ,
&boolCanonical) == FAILURE)
{
@@ -1396,38 +1377,36 @@
{
int i=0;
for( i=0; i< arr_size; i++ ){
- if( arr[i] ){
- efree( arr[i]);
+ if( arr[i*2] ){
+ efree( arr[i*2]);
}
}
-
+ efree(arr);
}
+#define LOOKUP_CLEAN_RETURN(value) array_cleanup(cur_arr, cur_arr_len);
return (value)
/* {{{
* returns the lookup result to lookup_loc_range_src_php
* internal function
*/
-static char* lookup_loc_range(char* loc_range, HashTable* hash_arr , int
isCanonical TSRMLS_DC)
+static char* lookup_loc_range(char* loc_range, HashTable* hash_arr, int
canonicalize TSRMLS_DC)
{
- int cur_arr_ind = 0;
- int i = 0;
- int cur_arr_len = 0;
- int result = 0;
-
- char* lang_tag = NULL;
- zval** ele_value = NULL;
- char* cur_arr[MAX_NO_LOOKUP_LANG_TAG] ;
-
- char* loc_range_to_cmp = NULL;
- char* cur_loc_range = NULL;
- char* can_loc_range = NULL;
- int saved_pos = 0;
-
- char* return_value = NULL;
- UErrorCode status = U_ZERO_ERROR;
- char* empty_result = "";
+ int i = 0;
+ int cur_arr_len = 0;
+ int result = 0;
+
+ char* lang_tag = NULL;
+ zval** ele_value = NULL;
+ char** cur_arr = NULL;
+
+ char* cur_loc_range = NULL;
+ char* can_loc_range = NULL;
+ int saved_pos = 0;
- /* convert the array to lowercase , also replace hyphuns with the
underscore and store it in cur_arr */
+ char* return_value = NULL;
+
+ cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *));
+ /* convert the array to lowercase , also replace hyphens with the
underscore and store it in cur_arr */
for(zend_hash_internal_pointer_reset(hash_arr);
zend_hash_has_more_elements(hash_arr) == SUCCESS;
zend_hash_move_forward(hash_arr)) {
@@ -1436,163 +1415,115 @@
/* Should never actually fail since the key is known to
exist.*/
continue;
}
- if( Z_TYPE_PP(ele_value)!= IS_STRING ){
+ if(Z_TYPE_PP(ele_value)!= IS_STRING) {
/* element value is not a string */
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "lookup_loc_range: array element is not a string ",
- 0 TSRMLS_CC );
- return NULL;
- } else {
- if( lang_tag ){
- efree( lang_tag );
- }
- lang_tag = estrdup(Z_STRVAL_PP(ele_value) );
-
- if( isCanonical ==0 ){
- /* +1 for the terminating '\0' */
- cur_arr[cur_arr_ind] = ecalloc(1,
strlen(lang_tag)+1 );
- result = strToMatch(lang_tag,
cur_arr[cur_arr_ind]) ;
- } else {
- cur_arr[cur_arr_ind] = estrdup(lang_tag);
- }
-
- if( cur_arr_ind < MAX_NO_LOOKUP_LANG_TAG ){
- cur_arr_ind++ ;
- } else {
- break;
- }
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"lookup_loc_range: locale array element is not a string", 0 TSRMLS_CC);
+ LOOKUP_CLEAN_RETURN(NULL);
+ }
+ cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_PP(ele_value),
Z_STRLEN_PP(ele_value));
+ result = strToMatch(Z_STRVAL_PP(ele_value),
cur_arr[cur_arr_len*2]);
+ if(result == 0) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"lookup_loc_range: unable to canonicalize lang_tag", 0 TSRMLS_CC);
+ LOOKUP_CLEAN_RETURN(NULL);
}
+ cur_arr[cur_arr_len*2+1] = Z_STRVAL_PP(ele_value);
+ cur_arr_len++ ;
} /* end of for */
- if( lang_tag ){
- efree( lang_tag );
- }
-
- cur_arr_len = cur_arr_ind;
-
/* Canonicalize array elements */
- if( isCanonical ==1 ){
- for( i=0; i< cur_arr_ind; i++ ){
- lang_tag =get_icu_value_internal( cur_arr[i] ,
LOC_CANONICALIZE_TAG , &result , 0);
- efree( cur_arr[i] );
- cur_arr[i] = ecalloc(1, strlen(lang_tag)+1 );
- result = strToMatch(lang_tag, cur_arr[i]) ;
- efree( lang_tag);
- if( result ==0) {
- intl_error_set( NULL, status,
- "locale_lookup : unable to canonicalize
lang_tag" , 0 TSRMLS_CC );
- if( lang_tag ){
- efree( lang_tag );
+ if(canonicalize) {
+ for(i=0; i<cur_arr_len; i++) {
+ lang_tag = get_icu_value_internal(cur_arr[i*2],
LOC_CANONICALIZE_TAG, &result, 0);
+ if(result != 1 || lang_tag == NULL || !lang_tag[0]) {
+ if(lang_tag) {
+ efree(lang_tag);
}
- array_cleanup( cur_arr , cur_arr_len );
- return NULL;
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"lookup_loc_range: unable to canonicalize lang_tag" , 0 TSRMLS_CC);
+ LOOKUP_CLEAN_RETURN(NULL);
+ }
+ cur_arr[i*2] = erealloc(cur_arr[i*2],
strlen(lang_tag)+1);
+ result = strToMatch(lang_tag, cur_arr[i*2]);
+ efree(lang_tag);
+ if(result == 0) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"lookup_loc_range: unable to canonicalize lang_tag" , 0 TSRMLS_CC);
+ LOOKUP_CLEAN_RETURN(NULL);
}
}
}
- if( isCanonical ==1 ){
+ if(canonicalize) {
/* Canonicalize the loc_range */
- can_loc_range =get_icu_value_internal( loc_range,
LOC_CANONICALIZE_TAG , &result , 0);
- if( result != 1 ){
+ can_loc_range = get_icu_value_internal(loc_range,
LOC_CANONICALIZE_TAG, &result , 0);
+ if( result != 1 || can_loc_range == NULL || !can_loc_range[0]) {
/* Error */
- intl_error_set( NULL, status,
- "locale_lookup : unable to canonicalize
loc_range" , 0 TSRMLS_CC );
- if( lang_tag ){
- efree( lang_tag );
- }
- if( can_loc_range ){
- efree( can_loc_range );
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"lookup_loc_range: unable to canonicalize loc_range" , 0 TSRMLS_CC );
+ if(can_loc_range) {
+ efree(can_loc_range);
}
- array_cleanup( cur_arr , cur_arr_len );
- return NULL;
+ LOOKUP_CLEAN_RETURN(NULL);
} else {
- /* convert to lower and replace hyphuns */
- cur_loc_range = ecalloc( 1, strlen(can_loc_range) +1);
- result = strToMatch(can_loc_range , cur_loc_range);
+ loc_range = can_loc_range;
}
- } else {
- cur_loc_range = ecalloc( 1, strlen(loc_range) +1);
- /* convert to lower and replace hyphuns */
- result = strToMatch(loc_range , cur_loc_range);
- }
+ }
+ cur_loc_range = ecalloc(1, strlen(loc_range)+1);
+ /* convert to lower and replace hyphens */
+ result = strToMatch(loc_range, cur_loc_range);
+ if(can_loc_range) {
+ efree(can_loc_range);
+ }
+ if(result == 0) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
"lookup_loc_range: unable to canonicalize lang_tag" , 0 TSRMLS_CC);
+ LOOKUP_CLEAN_RETURN(NULL);
+ }
/* Lookup for the lang_tag match */
saved_pos = strlen(cur_loc_range);
- while(saved_pos!=(-1) ){
- if( loc_range_to_cmp){
- efree(loc_range_to_cmp);
- }
- loc_range_to_cmp = estrndup(cur_loc_range,saved_pos+1);
- for( i=0; i< cur_arr_ind; i++ ){
- if( cur_arr[i] &&
(strcmp(loc_range_to_cmp,cur_arr[i])==0) ){
+ while(saved_pos > 0) {
+ for(i=0; i< cur_arr_len; i++){
+ if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) ==
saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) {
/* Match found */
- return_value = estrdup( cur_arr[i] );
- if ( cur_loc_range ){
- efree( cur_loc_range );
- }
- if( loc_range_to_cmp){
- efree(loc_range_to_cmp);
- }
- if( can_loc_range ){
- efree( can_loc_range );
- }
- array_cleanup( cur_arr , cur_arr_len );
- return return_value;
+ return_value =
estrdup(canonicalize?cur_arr[i*2]:cur_arr[i*2+1]);
+ efree(cur_loc_range);
+ LOOKUP_CLEAN_RETURN(return_value);
}
}
- saved_pos = getStrrtokenPos( cur_loc_range , saved_pos );
+ saved_pos = getStrrtokenPos(cur_loc_range, saved_pos);
}
- if( loc_range_to_cmp){
- efree(loc_range_to_cmp);
- }
- if ( cur_loc_range ){
- efree( cur_loc_range );
- }
- if( can_loc_range ){
- efree( can_loc_range );
- }
- array_cleanup( cur_arr , cur_arr_len );
-
/* Match not found */
- return empty_result;
-
+ efree(cur_loc_range);
+ LOOKUP_CLEAN_RETURN(NULL);
}
/* }}} */
-/* {{{ proto string Locale::lookup(array $langtag, $locale[, $default = null])
+/* {{{ proto string Locale::lookup(array $langtag, string $locale[, bool
$canonicalize[, string $default = null]])
* Searchs the items in $langtag for the best match to the language
* range
*/
/* }}} */
-/* {{{ proto string locale_lookup(array $langtag, $locale[, $default = null])
+/* {{{ proto string locale_lookup(array $langtag, string $locale[, bool
$canonicalize[, string $default = null]])
* Searchs the items in $langtag for the best match to the language
* range
*/
PHP_FUNCTION(locale_lookup)
{
- char* fallback_loc = NULL;
- int fallback_loc_len = 0;
- char* loc_range = NULL;
- int loc_range_len = 0;
+ char* fallback_loc = NULL;
+ int fallback_loc_len = 0;
+ char* loc_range = NULL;
+ int loc_range_len = 0;
- zval* arr = NULL;
+ zval* arr = NULL;
HashTable* hash_arr = NULL;
- zend_bool boolCanonical = 0;
-
+ zend_bool boolCanonical = 0;
char* result =NULL;
intl_error_reset( NULL TSRMLS_CC );
- if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "asb|s",
- &arr,&loc_range,&loc_range_len,&boolCanonical,
- &fallback_loc,&fallback_loc_len) == FAILURE)
- {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "locale_lookup: unable to parse input params", 0 TSRMLS_CC );
-
+ if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "as|bs", &arr,
&loc_range, &loc_range_len,
+ &boolCanonical, &fallback_loc, &fallback_loc_len) == FAILURE) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_lookup:
unable to parse input params", 0 TSRMLS_CC );
RETURN_NULL();
}
@@ -1600,25 +1531,22 @@
loc_range = INTL_G(default_locale);
}
- /* MAKE_STD_ZVAL(hash_arr); */
- hash_arr = HASH_OF( arr );
+ hash_arr = HASH_OF(arr);
- if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ){
+ if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) {
RETURN_EMPTY_STRING();
- }
- else{
- result = lookup_loc_range( loc_range ,hash_arr
,(boolCanonical?1:0) TSRMLS_CC);
-
+ }
+
+ result = lookup_loc_range(loc_range, hash_arr, boolCanonical TSRMLS_CC);
if(result == NULL || result[0] == '\0') {
if( fallback_loc ) {
- result = estrndup( fallback_loc , fallback_loc_len);
+ result = estrndup(fallback_loc, fallback_loc_len);
} else {
RETURN_EMPTY_STRING();
}
}
-}
- RETVAL_STRINGL( result, strlen(result), 0);
+ RETVAL_STRINGL(result, strlen(result), 0);
}
/* }}} */
http://cvs.php.net/viewvc.cgi/php-src/ext/intl/tests/locale_lookup.phpt?r1=1.1.2.1&r2=1.1.2.2&diff_format=u
Index: php-src/ext/intl/tests/locale_lookup.phpt
diff -u php-src/ext/intl/tests/locale_lookup.phpt:1.1.2.1
php-src/ext/intl/tests/locale_lookup.phpt:1.1.2.2
--- php-src/ext/intl/tests/locale_lookup.phpt:1.1.2.1 Mon Jul 7 22:51:04 2008
+++ php-src/ext/intl/tests/locale_lookup.phpt Thu Jul 2 00:43:26 2009
@@ -71,19 +71,19 @@
loc_range:de-de
lang_tags:
de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2
-lookup result:de_de
+lookup result:de-DE
Canonical lookup result:de_de
--------------
loc_range:sl_IT
lang_tags:
de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2
-lookup result:sl_it
+lookup result:sl_IT
Canonical lookup result:sl_it
--------------
loc_range:sl_IT_Nedis
lang_tags:
de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2
-lookup result:sl_it
+lookup result:sl_IT
Canonical lookup result:sl_it
--------------
loc_range:jbo
@@ -95,5 +95,5 @@
loc_range:art-lojban
lang_tags:
de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2
-lookup result:art_lojban
-Canonical lookup result:jbo
\ No newline at end of file
+lookup result:art-lojban
+Canonical lookup result:jbo
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php