diff --git a/lib/libc/locale/ldpart.c b/lib/libc/locale/ldpart.c new file mode 100644 index 000000000000..7675a0c50f18 --- /dev/null +++ b/lib/libc/locale/ldpart.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include "setlocale.h" +#include "ldpart.h" + +static int split_lines(char *, const char *); +static void set_from_buf(const char *, int, const char **); + +int +__part_load_locale(const char *name, + int* using_locale, + char *locale_buf, + const char *category_name, + int locale_buf_size, + const char **dst_localebuf) { + + static char locale_buf_C[] = "C"; + static int num_lines; + + int fd; + char * lbuf; + char * p; + const char * plim; + char filename[PATH_MAX]; + struct stat st; + size_t namesize; + size_t bufsize; + int save_using_locale; + + save_using_locale = *using_locale; + *using_locale = 0; + + if (name == NULL) + goto no_locale; + + if (!strcmp(name, "C") || !strcmp(name, "POSIX")) + return 0; + + /* + ** If the locale name is the same as our cache, use the cache. + */ + lbuf = locale_buf; + if (lbuf != NULL && strcmp(name, lbuf) == 0) { + set_from_buf(lbuf, num_lines, dst_localebuf); + *using_locale = 1; + return 0; + } + /* + ** Slurp the locale file into the cache. + */ + namesize = strlen(name) + 1; + + if (!_PathLocale) + goto no_locale; + /* Range checking not needed, 'name' size is limited */ + strcpy(filename, _PathLocale); + strcat(filename, "/"); + strcat(filename, name); + strcat(filename, "/"); + strcat(filename, category_name); + fd = _open(filename, O_RDONLY); + if (fd < 0) + goto no_locale; + if (fstat(fd, &st) != 0) + goto bad_locale; + if (st.st_size <= 0) + goto bad_locale; + bufsize = namesize + st.st_size; + locale_buf = NULL; + lbuf = (lbuf == NULL || lbuf == locale_buf_C) ? + malloc(bufsize) : reallocf(lbuf, bufsize); + if (lbuf == NULL) + goto bad_locale; + (void) strcpy(lbuf, name); + p = lbuf + namesize; + plim = p + st.st_size; + if (_read(fd, p, (size_t) st.st_size) != st.st_size) + goto bad_lbuf; + if (_close(fd) != 0) + goto bad_lbuf; + /* + ** Parse the locale file into localebuf. + */ + if (plim[-1] != '\n') + goto bad_lbuf; + num_lines = split_lines(p, plim); + if (num_lines >= locale_buf_size) + num_lines = locale_buf_size; + else + goto reset_locale; + set_from_buf(lbuf, num_lines, dst_localebuf); + /* + ** Record the successful parse in the cache. + */ + locale_buf = lbuf; + + *using_locale = 1; + return 0; + +reset_locale: + locale_buf = locale_buf_C; + save_using_locale = 0; +bad_lbuf: + free(lbuf); +bad_locale: + (void)_close(fd); +no_locale: + *using_locale = save_using_locale; + return -1; +} + +static int +split_lines(char *p, const char *plim) +{ + int i; + + for (i = 0; p < plim; i++) { + p = strchr(p, '\n'); + *p++ = '\0'; + } + return i; +} + +static void +set_from_buf(const char *p, int num_lines, const char **dst_localebuf) +{ + const char **ap; + int i; + + for (ap = dst_localebuf, i = 0; i < num_lines; ++ap, ++i) + *ap = p += strlen(p) + 1; +} + diff --git a/lib/libc/locale/ldpart.h b/lib/libc/locale/ldpart.h new file mode 100644 index 000000000000..6478d8953113 --- /dev/null +++ b/lib/libc/locale/ldpart.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LDPART_H +#define _LDPART_H + +extern int __part_load_locale(const char *, int*, char *, const char *, + int, const char **); + +#endif /* _LDPART_H */ diff --git a/lib/libc/locale/lmessages.c b/lib/libc/locale/lmessages.c new file mode 100644 index 000000000000..51ee10a90f05 --- /dev/null +++ b/lib/libc/locale/lmessages.c @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "lmessages.h" +#include "ldpart.h" + +#define LCMESSAGES_SIZE (sizeof(struct lc_messages_T) / sizeof(char *)) + +char empty[] = ""; + +static const struct lc_messages_T _C_messages_locale = { + "^[yY]" , /* yesexpr */ + "^[nN]" , /* noexpr */ + "yes" , /* yesstr */ + "no" /* nostr */ +}; + +static struct lc_messages_T _messages_locale; +static int _messages_using_locale; +static char * messages_locale_buf; + +int +__messages_load_locale(const char *name) { + + int ret; + ret = __part_load_locale(name, &_messages_using_locale, + messages_locale_buf, "LC_MESSAGES", LCMESSAGES_SIZE, + (const char **)&_messages_locale); + if (ret == -1) { + /* Assume that we have incomplete locale file (without + * "yesstr" and "nostr" declared. Try it also. + */ + ret = __part_load_locale(name, &_messages_using_locale, + messages_locale_buf, "LC_MESSAGES", LCMESSAGES_SIZE/2, + (const char **)&_messages_locale); + if (ret != -1) { + _messages_locale.yesstr = empty; + _messages_locale.nostr = empty; + } + } + return ret; +} + +struct lc_messages_T * +__get_current_messages_locale(void) { + + return (_messages_using_locale + ? &_messages_locale + : (struct lc_messages_T *)&_C_messages_locale); +} + +#ifdef LOCALE_DEBUG +void +msgdebug() { +printf( "yesexpr = %s\n" + "noexpr = %s\n" + "yesstr = %s\n" + "nostr = %s\n", + _messages_locale.yesexpr, + _messages_locale.noexpr, + _messages_locale.yesstr, + _messages_locale.nostr +); +} +#endif /* LOCALE_DEBUG */ diff --git a/lib/libc/locale/lmessages.h b/lib/libc/locale/lmessages.h new file mode 100644 index 000000000000..810264411895 --- /dev/null +++ b/lib/libc/locale/lmessages.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LMESSAGES_H +#define _LMESSAGES_H + +struct lc_messages_T { + const char * yesexpr; + const char * noexpr; + const char * yesstr; + const char * nostr; +}; + +extern struct lc_messages_T * __get_current_messages_locale(void); +extern int __messages_load_locale(const char *); + +#endif /* _LMESSAGES_H */ diff --git a/lib/libc/locale/lmonetary.c b/lib/libc/locale/lmonetary.c new file mode 100644 index 000000000000..0b8581a929fb --- /dev/null +++ b/lib/libc/locale/lmonetary.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "lmonetary.h" +#include "ldpart.h" + +extern int __mlocale_changed; + +#define LCMONETARY_SIZE (sizeof(struct lc_monetary_T) / sizeof(char *)) + +static char empty[] = ""; +static char numempty[] = "-1"; + +static const struct lc_monetary_T _C_monetary_locale = { + empty , /* int_curr_symbol */ + empty , /* currency_symbol */ + "." , /* mon_decimal_point */ + empty , /* mon_thousands_sep */ + numempty , /* mon_grouping */ + empty , /* positive_sign */ + empty , /* negative_sign */ + numempty , /* int_frac_digits */ + numempty , /* frac_digits */ + numempty , /* p_cs_precedes */ + numempty , /* p_sep_by_space */ + numempty , /* n_cs_precedes */ + numempty , /* n_sep_by_space */ + numempty , /* p_sign_posn */ + numempty /* n_sign_posn */ +}; + +static struct lc_monetary_T _monetary_locale; +static int _monetary_using_locale; +static char * monetary_locale_buf; + +int +__monetary_load_locale(const char *name) { + + int ret; + ret = __part_load_locale(name, &_monetary_using_locale, + monetary_locale_buf, "LC_MONETARY", LCMONETARY_SIZE, + (const char **)&_monetary_locale); + if (!ret) + __mlocale_changed = 1; + return ret; +} + +struct lc_monetary_T * +__get_current_monetary_locale(void) { + + return (_monetary_using_locale + ? &_monetary_locale + : (struct lc_monetary_T *)&_C_monetary_locale); +} + +#ifdef LOCALE_DEBUG +void +monetdebug() { +printf( "int_curr_symbol = %s\n" + "currency_symbol = %s\n" + "mon_decimal_point = %s\n" + "mon_thousands_sep = %s\n" + "mon_grouping = %s\n" + "positive_sign = %s\n" + "negative_sign = %s\n" + "int_frac_digits = %s\n" + "frac_digits = %s\n" + "p_cs_precedes = %s\n" + "p_sep_by_space = %s\n" + "n_cs_precedes = %s\n" + "n_sep_by_space = %s\n" + "p_sign_posn = %s\n" + "n_sign_posn = %s\n", + _monetary_locale.int_curr_symbol, + _monetary_locale.currency_symbol, + _monetary_locale.mon_decimal_point, + _monetary_locale.mon_thousands_sep, + _monetary_locale.mon_grouping, + _monetary_locale.positive_sign, + _monetary_locale.negative_sign, + _monetary_locale.int_frac_digits, + _monetary_locale.frac_digits, + _monetary_locale.p_cs_precedes, + _monetary_locale.p_sep_by_space, + _monetary_locale.n_cs_precedes, + _monetary_locale.n_sep_by_space, + _monetary_locale.p_sign_posn, + _monetary_locale.n_sign_posn +); +} +#endif /* LOCALE_DEBUG */ diff --git a/lib/libc/locale/lmonetary.h b/lib/libc/locale/lmonetary.h new file mode 100644 index 000000000000..a248fadcddfe --- /dev/null +++ b/lib/libc/locale/lmonetary.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LMONETARY_H +#define _LMONETARY_H + +struct lc_monetary_T { + const char * int_curr_symbol; + const char * currency_symbol; + const char * mon_decimal_point; + const char * mon_thousands_sep; + const char * mon_grouping; + const char * positive_sign; + const char * negative_sign; + const char * int_frac_digits; + const char * frac_digits; + const char * p_cs_precedes; + const char * p_sep_by_space; + const char * n_cs_precedes; + const char * n_sep_by_space; + const char * p_sign_posn; + const char * n_sign_posn; +}; + +extern struct lc_monetary_T * __get_current_monetary_locale(void); +extern int __monetary_load_locale(const char *); + +#endif /* _LMONETARY_H */ diff --git a/lib/libc/locale/lnumeric.c b/lib/libc/locale/lnumeric.c new file mode 100644 index 000000000000..765d604a7285 --- /dev/null +++ b/lib/libc/locale/lnumeric.c @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include "lnumeric.h" +#include "ldpart.h" + +extern int __nlocale_changed; + +#define LCNUMERIC_SIZE (sizeof(struct lc_numeric_T) / sizeof(char *)) + +static const struct lc_numeric_T _C_numeric_locale = { + ".", /* decimal_point */ + "", /* thousands_sep */ + "-1" /* grouping */ +}; + +static struct lc_numeric_T _numeric_locale; +static int _numeric_using_locale; +static char * numeric_locale_buf; + +int +__numeric_load_locale(const char *name) { + + int ret; + + ret = __part_load_locale(name, &_numeric_using_locale, + numeric_locale_buf, "LC_NUMERIC", LCNUMERIC_SIZE, + (const char **)&_numeric_locale); + if (!ret) + __nlocale_changed = 1; + return ret; +} + +struct lc_numeric_T * +__get_current_numeric_locale(void) { + + return (_numeric_using_locale + ? &_numeric_locale + : (struct lc_numeric_T *)&_C_numeric_locale); +} + +#ifdef LOCALE_DEBUG +void +numericdebug(void) { +printf( "decimal_point = %s\n" + "thousands_sep = %s\n" + "grouping = %s\n", + _numeric_locale.decimal_point, + _numeric_locale.thousands_sep, + _numeric_locale.grouping +); +} +#endif /* LOCALE_DEBUG */ diff --git a/lib/libc/locale/lnumeric.h b/lib/libc/locale/lnumeric.h new file mode 100644 index 000000000000..5dcfefd320ef --- /dev/null +++ b/lib/libc/locale/lnumeric.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000, 2001 Alexey Zelkin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LNUMERIC_H +#define _LNUMERIC_H + +struct lc_numeric_T { + const char * decimal_point; + const char * thousands_sep; + const char * grouping; +}; + +extern struct lc_numeric_T * __get_current_numeric_locale(void); +extern int __numeric_load_locale(const char *); + +#endif /* _LNUMERIC_H */ diff --git a/lib/libc/locale/setlocale.c b/lib/libc/locale/setlocale.c index cba6a531b482..ccae90607eac 100644 --- a/lib/libc/locale/setlocale.c +++ b/lib/libc/locale/setlocale.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 1996 - 2001 FreeBSD Project * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -54,6 +55,9 @@ static char sccsid[] = "@(#)setlocale.c 8.1 (Berkeley) 7/4/93"; #include #include #include "collate.h" +#include "lmonetary.h" /* for __monetary_load_locale() */ +#include "lnumeric.h" /* for __numeric_load_locale() */ +#include "lmessages.h" /* for __messages_load_locale() */ #include "setlocale.h" /* @@ -92,7 +96,6 @@ static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)]; static char *currentlocale __P((void)); static char *loadlocale __P((int)); -static int stub_load_locale __P((const char *)); extern int __time_load_locale __P((const char *)); /* strftime.c */ @@ -247,63 +250,23 @@ loadlocale(category) return (ret); } - if (category == LC_COLLATE) { - ret = (__collate_load_tables(new) < 0) ? NULL : new; - if (!ret) - (void)__collate_load_tables(old); - else - (void)strcpy(old, new); - return (ret); +#define LOAD_CATEGORY(CAT, FUNC) \ + if (category == CAT) { \ + ret = (FUNC(new) < 0) ? NULL : new; \ + if (!ret) \ + (void)FUNC(old); \ + else \ + (void)strcpy(old, new); \ + return (ret); \ } - if (category == LC_TIME) { - ret = (__time_load_locale(new) < 0) ? NULL : new; - if (!ret) - (void)__time_load_locale(old); - else - (void)strcpy(old, new); - return (ret); - } - - if (category == LC_MONETARY || - category == LC_MESSAGES || - category == LC_NUMERIC) { - ret = stub_load_locale(new) ? NULL : new; - if (!ret) - (void)stub_load_locale(old); - else - (void)strcpy(old, new); - return (ret); - } + LOAD_CATEGORY(LC_COLLATE, __collate_load_tables); + LOAD_CATEGORY(LC_TIME, __time_load_locale); + LOAD_CATEGORY(LC_NUMERIC, __numeric_load_locale); + LOAD_CATEGORY(LC_MONETARY, __monetary_load_locale); + LOAD_CATEGORY(LC_MESSAGES, __messages_load_locale); /* Just in case...*/ return (NULL); } -static int -stub_load_locale(encoding) -const char *encoding; -{ - char name[PATH_MAX]; - struct stat st; - - if (!encoding) - return(1); - /* - * The "C" and "POSIX" locale are always here. - */ - if (!strcmp(encoding, "C") || !strcmp(encoding, "POSIX")) - return(0); - if (!_PathLocale) - return(1); - /* Range checking not needed, encoding has fixed size */ - strcpy(name, _PathLocale); - strcat(name, "/"); - strcat(name, encoding); -#if 0 - /* - * Some day we will actually look at this file. - */ -#endif - return (stat(name, &st) != 0 || !S_ISDIR(st.st_mode)); -}