From 8da88a6f2b9c20f72abe3f232c32de7c257511f6 Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Fri, 7 Jan 2000 17:22:47 +0000 Subject: [PATCH] Sorry, that I send this letter/patch again, but previous sending is still without answer. I want continue with to_char(), but I need any answer for this patch. Please. Thank! (and sorry of my impatient :-) Karel --- src/backend/utils/adt/Makefile | 4 +- src/backend/utils/adt/pg_locale.c | 128 ++++++++++++++++++++++++++++++ src/include/utils/pg_locale.h | 46 +++++++++++ 3 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 src/backend/utils/adt/pg_locale.c create mode 100644 src/include/utils/pg_locale.h diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 9aba127264..dbf5d40ce9 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -4,7 +4,7 @@ # Makefile for utils/adt # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.30 1999/12/28 13:40:48 wieck Exp $ +# $Header: /cvsroot/pgsql/src/backend/utils/adt/Makefile,v 1.31 2000/01/07 17:22:47 momjian Exp $ # #------------------------------------------------------------------------- @@ -35,7 +35,7 @@ OBJS = acl.o arrayfuncs.o arrayutils.o bool.o cash.o char.o chunk.o \ regexp.o regproc.o ruleutils.o selfuncs.o sets.o \ tid.o timestamp.o varchar.o varlena.o version.o \ network.o mac.o inet_net_ntop.o inet_net_pton.o \ - ri_triggers.o pg_lzcompress.o + ri_triggers.o pg_lzcompress.o pg_locale.o all: SUBSYS.o diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c new file mode 100644 index 0000000000..7688a753db --- /dev/null +++ b/src/backend/utils/adt/pg_locale.c @@ -0,0 +1,128 @@ + +/*------ + * pg_locale.c + * + * The PostgreSQL locale utils. + * + * 2000 Karel Zak - Zakkr + * + *------ + */ + +#include + +#include "postgres.h" + +#ifdef USE_LOCALE + +#include +#include "utils/pg_locale.h" + +/* #define DEBUG_LOCALE_UTILS */ + + +/*------ + * Return in PG_LocaleCategories current locale setting + *------ + */ +PG_LocaleCategories * +PGLC_current( PG_LocaleCategories *lc ) +{ + lc->lang = getenv("LANG"); + +lc->lc_ctype = setlocale(LC_CTYPE, NULL); +lc->lc_numeric = setlocale(LC_NUMERIC, NULL); +lc->lc_time = setlocale(LC_TIME, NULL); +lc->lc_collate = setlocale(LC_COLLATE, NULL); +lc->lc_monetary = setlocale(LC_MONETARY, NULL); +lc->lc_messages = setlocale(LC_MESSAGES, NULL); + + return lc; +} + + +#ifdef DEBUG_LOCALE_UTILS + +/*------ + * Print a PG_LocaleCategories struct as DEBUG + *------ + */ +PG_LocaleCategories * +PGLC_debug_lc( PG_LocaleCategories *lc ) +{ + elog(DEBUG, "CURRENT LOCALE ENVIRONMENT:\n\nLANG: \t%s\nLC_CTYPE:\t%s\nLC_NUMERIC:\t%s\nLC_TIME:\t%s\nLC_COLLATE:\t%s\nLC_MONETARY:\t%s\nLC_MESSAGES:\t%s\n", + lc->lang, + lc->lc_ctype, + lc->lc_numeric, + lc->lc_time, + lc->lc_collate, + lc->lc_monetary, + lc->lc_messages + ); + + return lc; +} + +#endif + +/*------ + * Set locales via a PG_LocaleCategories struct + *------ + */ +PG_LocaleCategories * +PGLC_setlocale( PG_LocaleCategories *lc ) +{ + if (!setlocale(LC_CTYPE, lc->lc_ctype )) + elog(NOTICE, "pg_setlocale(): 'LC_CTYPE=%s' cannot be honored.", lc->lc_ctype); + + if (!setlocale(LC_NUMERIC, lc->lc_numeric )) + elog(NOTICE, "pg_setlocale(): 'LC_NUMERIC=%s' cannot be honored.", lc->lc_numeric); + + if (!setlocale(LC_TIME, lc->lc_time )) + elog(NOTICE, "pg_setlocale(): 'LC_TIME=%s' cannot be honored.", lc->lc_time); + + if (!setlocale(LC_COLLATE, lc->lc_collate )) + elog(NOTICE, "pg_setlocale(): 'LC_COLLATE=%s' cannot be honored.", lc->lc_collate); + + if (!setlocale(LC_MONETARY, lc->lc_monetary )) + elog(NOTICE, "pg_setlocale(): 'LC_MONETARY=%s' cannot be honored.", lc->lc_monetary); + + if (!setlocale(LC_MESSAGES, lc->lc_messages )) + elog(NOTICE, "pg_setlocale(): 'LC_MESSAGE=%s' cannot be honored.", lc->lc_messages); + + return lc; +} + +/*------ + * Return the POSIX lconv struct (contains number/money formatting information) + * with locale information for *all* categories. + * => Returned lconv is *independent* on current locale catogories setting - in + * contrast to standard localeconv(). + * + * ! libc prepare memory space for lconv itself and all returned strings in + * lconv are *static strings*. + *------ + */ +struct lconv * +PGLC_localeconv() +{ + PG_LocaleCategories lc; + struct lconv *lconv; + + /* Save current locale setting to lc */ + PGLC_current(&lc); + + /* Set all locale category for current lang */ + setlocale(LC_ALL, ""); + + /* Get numeric formatting information */ + lconv = localeconv(); + + /* Set previous original locale */ + PGLC_setlocale(&lc); + + return lconv; +} + + +#endif /* USE_LOCALE */ diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h new file mode 100644 index 0000000000..e5aee46c9b --- /dev/null +++ b/src/include/utils/pg_locale.h @@ -0,0 +1,46 @@ + +/*------ + * pg_locale.h + * + * The PostgreSQL locale utils + * + * 2000 Karel Zak - Zakkr + * + *------ + */ + + #ifndef _PG_LOCALE_ + #define _PG_LOCALE_ + + #ifdef USE_LOCALE + +/*------ + * POSIX locale categories and environment variable LANG + *------ + */ +typedef struct PG_LocaleCategories { + char *lang, + *lc_ctype, + *lc_numeric, + *lc_time, + *lc_collate, + *lc_monetary, + *lc_messages; +} PG_LocaleCategories; + + +extern PG_LocaleCategories *PGLC_current( PG_LocaleCategories *lc ); +extern PG_LocaleCategories *PGLC_setlocale( PG_LocaleCategories *lc ); + +/*------ + * Return the POSIX lconv struct (contains number/money formatting information) + * with locale information for *all* categories. Returned lconv is *independent* + * on current locale catogories setting - in contrast to standard localeconv(). + *------ + */ +extern struct lconv *PGLC_localeconv(); + + +#endif /* USE_LOCALE */ + +#endif /* _PG_LOCALE_ */