]> granicus.if.org Git - php/commitdiff
Added localeconv() function. Operates similarly to localeconv() defined in
authorSean Bright <elixer@php.net>
Sun, 14 Jan 2001 16:36:30 +0000 (16:36 +0000)
committerSean Bright <elixer@php.net>
Sun, 14 Jan 2001 16:36:30 +0000 (16:36 +0000)
locale.h.  Should work well under non-ZTS as well as ZTS.

configure.in
ext/standard/basic_functions.c
ext/standard/php_string.h
ext/standard/string.c
main/config.w32.h

index f16671bc16fa6dca9c39d420b5be0e0c122523c1..e60a53143c6d2eb3449bc4c9c60c69753c2d07f0 100644 (file)
@@ -379,6 +379,7 @@ rand_r \
 regcomp \
 setitimer \
 setlocale \
+localeconv \
 setsockopt \
 setvbuf \
 shutdown \
index 7221f83dc98cf766d7a9b55159375e4d557553bf..4c71abf18e0b8312c96744ffd1a248ba18b18a22 100644 (file)
@@ -182,6 +182,7 @@ function_entry basic_functions[] = {
        PHP_FE(explode,                                                                 NULL)
        PHP_FE(implode,                                                                 NULL)
        PHP_FE(setlocale,                                                               NULL)
+       PHP_FE(localeconv,                                                              NULL)
        PHP_FE(soundex,                                                                 NULL)
        PHP_FE(levenshtein,                                                             NULL)
        PHP_FE(chr,                                                                             NULL)
@@ -713,6 +714,9 @@ PHP_MINIT_FUNCTION(basic)
        PHP_MINIT(pack)(INIT_FUNC_ARGS_PASSTHRU);
        PHP_MINIT(browscap)(INIT_FUNC_ARGS_PASSTHRU);
        PHP_MINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU);
+#ifdef ZTS
+       PHP_MINIT(localeconv)(INIT_FUNC_ARGS_PASSTHRU);
+#endif
 
 #if HAVE_CRYPT
        PHP_MINIT(crypt)(INIT_FUNC_ARGS_PASSTHRU);
@@ -769,6 +773,9 @@ PHP_MSHUTDOWN_FUNCTION(basic)
        PHP_MSHUTDOWN(url_scanner_ex)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
 #endif
        PHP_MSHUTDOWN(file)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+#ifdef ZTS
+       PHP_MSHUTDOWN(localeconv)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+#endif
 
        return SUCCESS;
 }
index d4d89c8778030348358c7778fc0f32895ee28988..807ea2c5d62adeb136bd108367624caf94320744 100644 (file)
@@ -65,6 +65,7 @@ PHP_FUNCTION(chr);
 PHP_FUNCTION(ord);
 PHP_FUNCTION(nl2br);
 PHP_FUNCTION(setlocale);
+PHP_FUNCTION(localeconv);
 PHP_FUNCTION(stristr);
 PHP_FUNCTION(chunk_split);
 PHP_FUNCTION(parse_str);
index c354e4482c382aa0b4f0a446d4e14a0dbbd9509d..98e0c3a73bd93cc2e57ab783c54cde4b422f0659 100644 (file)
@@ -36,6 +36,9 @@
 #include "php_globals.h"
 #include "basic_functions.h"
 #include "php_smart_str.h"
+#ifdef ZTS
+#include "TSRM.h"
+#endif
 
 #define STR_PAD_LEFT                   0
 #define STR_PAD_RIGHT                  1
@@ -53,6 +56,17 @@ void register_string_constants(INIT_FUNC_ARGS)
        REGISTER_LONG_CONSTANT("PATHINFO_BASENAME", PHP_PATHINFO_BASENAME, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("PATHINFO_EXTENSION", PHP_PATHINFO_EXTENSION, CONST_CS | CONST_PERSISTENT);
 
+#ifdef HAVE_LOCALECONV
+       /* If last members of struct lconv equal CHAR_MAX, no grouping is done */       
+
+/* This is bad, but since we are going to be hardcoding in the POSIX stuff anyway... */
+# ifndef HAVE_LIMITS_H
+# define CHAR_MAX 127
+# endif
+
+       REGISTER_LONG_CONSTANT("CHAR_MAX", CHAR_MAX, CONST_CS | CONST_PERSISTENT);
+#endif
+
 #ifdef HAVE_LOCALE_H
        REGISTER_LONG_CONSTANT("LC_CTYPE", LC_CTYPE, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("LC_NUMERIC", LC_NUMERIC, CONST_CS | CONST_PERSISTENT);
@@ -72,6 +86,11 @@ int php_tag_find(char *tag, int len, char *set);
 /* this is read-only, so it's ok */
 static char hexconvtab[] = "0123456789abcdef";
 
+/* localeconv mutex */
+#ifdef ZTS
+static MUTEX_T locale_mutex = NULL;
+#endif
+
 static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *newlen)
 {
        unsigned char *result = NULL;
@@ -92,6 +111,47 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t *
        return result;
 }
 
+#ifdef HAVE_LOCALECONV
+/* glibc's localeconv is not reentrant, so lets make it so ... sorta */
+struct lconv *localeconv_r(struct lconv *out)
+{
+       struct lconv *res;
+
+# ifdef ZTS
+       tsrm_mutex_lock( locale_mutex );
+# endif
+
+       /* localeconv doesn't return an error condition */
+       res = localeconv();
+
+       *out = *res;
+
+# ifdef ZTS
+       tsrm_mutex_unlock( locale_mutex );
+# endif
+
+       return out;
+}
+
+# ifdef ZTS
+PHP_MINIT_FUNCTION(localeconv)
+{
+       locale_mutex = tsrm_mutex_alloc();
+
+       return SUCCESS;
+}
+
+PHP_MSHUTDOWN_FUNCTION(localeconv)
+{
+       tsrm_mutex_free( locale_mutex );
+
+       locale_mutex = NULL;
+
+       return SUCCESS;
+}
+# endif
+#endif
+
 /* {{{ proto string bin2hex(string data)
    Converts the binary representation of data to hex */
 PHP_FUNCTION(bin2hex)
@@ -2805,6 +2865,96 @@ PHP_FUNCTION(strnatcmp)
 }
 /* }}} */
 
+/* {{{ proto array localeconv( void )
+   Returns all the information stored in the lconv struct defined
+   in locale.h based on the currently selected locale */
+PHP_FUNCTION(localeconv)
+{
+       zval *grouping, *mon_grouping;
+       int len, i;
+
+       MAKE_STD_ZVAL(grouping);
+       MAKE_STD_ZVAL(mon_grouping);
+
+       /* We don't need no stinkin' parameters... */
+       if (ZEND_NUM_ARGS() > 0) {
+               WRONG_PARAM_COUNT;
+       }
+
+       if (array_init(return_value) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (array_init(grouping) == FAILURE || array_init(mon_grouping) == FAILURE) {
+               RETURN_FALSE;
+       }       
+
+#ifdef HAVE_LOCALECONV
+       {
+               struct lconv currlocdata;
+
+               localeconv_r( &currlocdata );
+   
+               /* Grab the grouping data out of the array */
+               len = strlen(currlocdata.grouping);
+
+               for (i=0;i<len;i++) {
+                       add_index_long(grouping, i, currlocdata.grouping[i]);
+               }
+
+               /* Grab the monetary grouping data out of the array */
+               len = strlen(currlocdata.mon_grouping);
+
+               for (i=0;i<len;i++) {
+                       add_index_long(mon_grouping, i, currlocdata.mon_grouping[i]);
+               }
+
+               add_assoc_string(return_value, "decimal_point",     currlocdata.decimal_point,     1);
+               add_assoc_string(return_value, "thousands_sep",     currlocdata.thousands_sep,     1);
+               add_assoc_string(return_value, "int_curr_symbol",   currlocdata.int_curr_symbol,   1);
+               add_assoc_string(return_value, "currency_symbol",   currlocdata.currency_symbol,   1);
+               add_assoc_string(return_value, "mon_decimal_point", currlocdata.mon_decimal_point, 1);
+               add_assoc_string(return_value, "mon_thousands_sep", currlocdata.mon_thousands_sep, 1);
+               add_assoc_string(return_value, "positive_sign",     currlocdata.positive_sign,     1);
+               add_assoc_string(return_value, "negative_sign",     currlocdata.negative_sign,     1);
+               add_assoc_long(  return_value, "int_frac_digits",   currlocdata.int_frac_digits     );
+               add_assoc_long(  return_value, "frac_digits",       currlocdata.frac_digits         );
+               add_assoc_long(  return_value, "p_cs_precedes",     currlocdata.p_cs_precedes       );
+               add_assoc_long(  return_value, "p_sep_by_space",    currlocdata.p_sep_by_space      );
+               add_assoc_long(  return_value, "n_cs_precedes",     currlocdata.n_cs_precedes       );
+               add_assoc_long(  return_value, "n_sep_by_space",    currlocdata.n_sep_by_space      );
+               add_assoc_long(  return_value, "p_sign_posn",       currlocdata.p_sign_posn         );
+               add_assoc_long(  return_value, "n_sign_posn",       currlocdata.n_sign_posn         );
+       }
+#else
+       /* Ok, it doesn't look like we have locale info floating around, so I guess it
+          wouldn't hurt to just go ahead and return the POSIX locale information?  */
+
+       add_index_long(grouping, 0, -1);
+       add_index_long(mon_grouping, 0, -1);
+
+       add_assoc_string(return_value, "decimal_point",     "\x2E", 1);
+       add_assoc_string(return_value, "thousands_sep",     "",     1);
+       add_assoc_string(return_value, "int_curr_symbol",   "",     1);
+       add_assoc_string(return_value, "currency_symbol",   "",     1);
+       add_assoc_string(return_value, "mon_decimal_point", "\x2E", 1);
+       add_assoc_string(return_value, "mon_thousands_sep", "",     1);
+       add_assoc_string(return_value, "positive_sign",     "",     1);
+       add_assoc_string(return_value, "negative_sign",     "",     1);
+       add_assoc_long(  return_value, "int_frac_digits",   CHAR_MAX );
+       add_assoc_long(  return_value, "frac_digits",       CHAR_MAX );
+       add_assoc_long(  return_value, "p_cs_precedes",     CHAR_MAX );
+       add_assoc_long(  return_value, "p_sep_by_space",    CHAR_MAX );
+       add_assoc_long(  return_value, "n_cs_precedes",     CHAR_MAX );
+       add_assoc_long(  return_value, "n_sep_by_space",    CHAR_MAX );
+       add_assoc_long(  return_value, "p_sign_posn",       CHAR_MAX );
+       add_assoc_long(  return_value, "n_sign_posn",       CHAR_MAX );
+#endif
+
+       zend_hash_update(return_value->value.ht, "grouping", 9, &grouping, sizeof(zval *), NULL);
+       zend_hash_update(return_value->value.ht, "mon_grouping", 13, &mon_grouping, sizeof(zval *), NULL);
+}
+
 
 /* {{{ proto int strnatcasecmp(string s1, string s2)
    Returns the result of case-insensitive string comparison using 'natural' algorithm */
index 8bac9868c8d7cbd7237b5aff92372a125affca3d..4e042ee68001210f36697c30d3ac82cac7e96b6f 100644 (file)
 /* Define if you have the setlocale function.  */
 #define HAVE_SETLOCALE 1
 
+#define HAVE_LOCALECONV 1
+
 #define HAVE_LOCALE_H 1
 
 /* Define if you have the setvbuf function.  */