aboutsummaryrefslogtreecommitdiffstats
path: root/src/pdclib/functions/locale/setlocale.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pdclib/functions/locale/setlocale.c')
-rw-r--r--src/pdclib/functions/locale/setlocale.c257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/pdclib/functions/locale/setlocale.c b/src/pdclib/functions/locale/setlocale.c
new file mode 100644
index 0000000..585504a
--- /dev/null
+++ b/src/pdclib/functions/locale/setlocale.c
@@ -0,0 +1,257 @@
+/* setlocale( int, const char * )
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+*/
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef REGTEST
+
+static const char * _PDCLIB_LC_category_name[ _PDCLIB_LC_COUNT ] = { NULL, "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_MESSAGES" };
+
+static const char * _PDCLIB_default_locale( int category )
+{
+ const char * s;
+
+ if ( ( s = getenv( "LC_ALL" ) ) == NULL )
+ {
+ if ( category == LC_ALL || ( s = getenv( _PDCLIB_LC_category_name[ category ] ) ) == NULL )
+ {
+ if ( ( s = getenv( "LANG" ) ) == NULL )
+ {
+ s = "C";
+ }
+ }
+ }
+
+ return s;
+}
+
+char * setlocale( int category, const char * locale )
+{
+ /* All below is very much work-in-progress, so we do a dumb-dummy
+ return here.
+ */
+ if ( locale == NULL || ! strcmp( locale, "C" ) )
+ {
+ return (char *)"C";
+ }
+ else
+ {
+ return NULL;
+ }
+
+#if 0
+ /* Path to locale data files - _PDCLIB_LOCALE_PATH unless overruled
+ by the environment variable whose name is defined by preprocessor
+ symbol _PDCLIB_LOCALE_PATH_ENV (defaulting to PDCLIB_I18N).
+ Both of these definitions are set in _PDCLIB_config.h.
+ */
+ const char * path = _PDCLIB_LOCALE_PATH;
+
+ struct _PDCLIB_lc_lconv_numeric_t * numeric = NULL;
+ struct _PDCLIB_lc_lconv_monetary_t * monetary = NULL;
+ struct _PDCLIB_lc_collate_t * collate = NULL;
+ struct _PDCLIB_lc_ctype_t * ctype = NULL;
+ struct _PDCLIB_lc_messages_t * messages = NULL;
+ struct _PDCLIB_lc_time_t * time = NULL;
+
+ char * rc = (char *)locale;
+
+ if ( category < 0 || category >= _PDCLIB_LC_COUNT )
+ {
+ /* Bad category */
+ return NULL;
+ }
+
+ if ( locale == NULL )
+ {
+ /* NULL - Return current locale settings */
+ /* TODO */
+ }
+
+ if ( strlen( locale ) == 0 )
+ {
+ /* "" - Use default locale */
+ locale = _PDCLIB_default_locale( category );
+ }
+
+ if ( getenv( _PDCLIB_symbol2string( _PDCLIB_LOCALE_PATH_ENV ) ) != NULL )
+ {
+ path = getenv( _PDCLIB_symbol2string( _PDCLIB_LOCALE_PATH_ENV ) );
+ }
+
+ /* We have to do this in two runs. As we might be facing LC_ALL, we
+ need to be certain all the loads are successful before we start
+ to overwrite the current locale settings, because there is no way
+ this function could report a _partial_ success.
+ */
+
+ /* Run One -- get all the data for the new locale setting */
+ if ( category == LC_COLLATE || category == LC_ALL )
+ {
+ if ( ! ( collate = _PDCLIB_load_lc_collate( path, locale ) ) )
+ {
+ rc = NULL;
+ }
+ }
+
+ if ( category == LC_CTYPE || category == LC_ALL )
+ {
+ if ( ! ( ctype = _PDCLIB_load_lc_ctype( path, locale ) ) )
+ {
+ rc = NULL;
+ }
+ }
+
+ if ( category == LC_MONETARY || category == LC_ALL )
+ {
+ if ( ! ( monetary = _PDCLIB_load_lc_monetary( path, locale ) ) )
+ {
+ rc = NULL;
+ }
+ }
+
+ if ( category == LC_NUMERIC || category == LC_ALL )
+ {
+ if ( ! ( numeric = _PDCLIB_load_lc_numeric( path, locale ) ) )
+ {
+ rc = NULL;
+ }
+ }
+
+ if ( category == LC_TIME || category == LC_ALL )
+ {
+ if ( ! ( time = _PDCLIB_load_lc_time( path, locale ) ) )
+ {
+ rc = NULL;
+ }
+ }
+
+ if ( category == LC_MESSAGES || category == LC_ALL )
+ {
+ if ( ! ( messages = _PDCLIB_load_lc_messages( path, locale ) ) )
+ {
+ rc = NULL;
+ }
+ }
+
+ /* Run Two -- continue or release resources */
+ if ( rc != NULL )
+ {
+ if ( category == LC_COLLATE || category == LC_ALL )
+ {
+ if ( _PDCLIB_lc_collate.alloced )
+ {
+ /* free resources */
+ }
+
+ _PDCLIB_lc_collate = *collate;
+ free( collate );
+ }
+
+ if ( category == LC_CTYPE || category == LC_ALL )
+ {
+ if ( _PDCLIB_lc_ctype.alloced )
+ {
+ free( _PDCLIB_lc_ctype.entry - 1 );
+ }
+
+ _PDCLIB_lc_ctype = *ctype;
+ free( ctype );
+ }
+
+ if ( category == LC_MONETARY || category == LC_ALL )
+ {
+ if ( _PDCLIB_lc_numeric_monetary.monetary_alloced )
+ {
+ free( _PDCLIB_lc_numeric_monetary.lconv->mon_decimal_point );
+ }
+
+ _PDCLIB_lc_numeric_monetary.lconv->mon_decimal_point = monetary->mon_decimal_point;
+ _PDCLIB_lc_numeric_monetary.lconv->mon_thousands_sep = monetary->mon_thousands_sep;
+ _PDCLIB_lc_numeric_monetary.lconv->mon_grouping = monetary->mon_grouping;
+ _PDCLIB_lc_numeric_monetary.lconv->positive_sign = monetary->positive_sign;
+ _PDCLIB_lc_numeric_monetary.lconv->negative_sign = monetary->negative_sign;
+ _PDCLIB_lc_numeric_monetary.lconv->currency_symbol = monetary->currency_symbol;
+ _PDCLIB_lc_numeric_monetary.lconv->int_curr_symbol = monetary->int_curr_symbol;
+ _PDCLIB_lc_numeric_monetary.lconv->frac_digits = monetary->frac_digits;
+ _PDCLIB_lc_numeric_monetary.lconv->p_cs_precedes = monetary->p_cs_precedes;
+ _PDCLIB_lc_numeric_monetary.lconv->n_cs_precedes = monetary->n_cs_precedes;
+ _PDCLIB_lc_numeric_monetary.lconv->p_sep_by_space = monetary->p_sep_by_space;
+ _PDCLIB_lc_numeric_monetary.lconv->n_sep_by_space = monetary->n_sep_by_space;
+ _PDCLIB_lc_numeric_monetary.lconv->p_sign_posn = monetary->p_sign_posn;
+ _PDCLIB_lc_numeric_monetary.lconv->n_sign_posn = monetary->n_sign_posn;
+ _PDCLIB_lc_numeric_monetary.lconv->int_frac_digits = monetary->int_frac_digits;
+ _PDCLIB_lc_numeric_monetary.lconv->int_p_cs_precedes = monetary->int_p_cs_precedes;
+ _PDCLIB_lc_numeric_monetary.lconv->int_n_cs_precedes = monetary->int_n_cs_precedes;
+ _PDCLIB_lc_numeric_monetary.lconv->int_p_sep_by_space = monetary->int_p_sep_by_space;
+ _PDCLIB_lc_numeric_monetary.lconv->int_n_sep_by_space = monetary->int_n_sep_by_space;
+ _PDCLIB_lc_numeric_monetary.lconv->int_p_sign_posn = monetary->int_p_sign_posn;
+ _PDCLIB_lc_numeric_monetary.lconv->int_n_sign_posn = monetary->int_n_sign_posn;
+
+ _PDCLIB_lc_numeric_monetary.monetary_alloced = 1;
+
+ free( monetary );
+ }
+
+ if ( category == LC_NUMERIC || category == LC_ALL )
+ {
+ if ( _PDCLIB_lc_numeric_monetary.numeric_alloced )
+ {
+ free( _PDCLIB_lc_numeric_monetary.lconv->decimal_point );
+ }
+
+ _PDCLIB_lc_numeric_monetary.lconv->decimal_point = numeric->decimal_point;
+ _PDCLIB_lc_numeric_monetary.lconv->thousands_sep = numeric->thousands_sep;
+ _PDCLIB_lc_numeric_monetary.lconv->grouping = numeric->grouping;
+
+ _PDCLIB_lc_numeric_monetary.numeric_alloced = 1;
+
+ free( numeric );
+ }
+
+ if ( category == LC_TIME || category == LC_ALL )
+ {
+ if ( _PDCLIB_lc_time.alloced )
+ {
+ free( _PDCLIB_lc_time.month_name_abbr[ 0 ] );
+ }
+
+ _PDCLIB_lc_time = *time;
+ free( time );
+ }
+
+ if ( category == LC_MESSAGES || category == LC_ALL )
+ {
+ if ( _PDCLIB_lc_messages.alloced )
+ {
+ free( _PDCLIB_lc_messages.errno_texts[ 0 ] );
+ }
+
+ _PDCLIB_lc_messages = *messages;
+ free( messages );
+ }
+ }
+
+ return NULL;
+#endif
+}
+
+#endif
+
+#ifdef TEST
+
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+ setlocale(0,"");
+ TESTCASE( NO_TESTDRIVER );
+ return TEST_RESULTS;
+}
+
+#endif