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

Reply via email to