[BACK]Return to setlocale.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / locale

Annotation of src/lib/libc/locale/setlocale.c, Revision 1.12

1.12    ! christos    1: /*     $NetBSD: setlocale.c,v 1.11 1997/06/02 09:52:50 kleink Exp $    */
1.10      kleink      2:
1.1       cgd         3: /*
1.5       jtc         4:  * Copyright (c) 1991, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Paul Borman at Krystal Technologies.
1.1       cgd         9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by the University of
                     21:  *     California, Berkeley and its contributors.
                     22:  * 4. Neither the name of the University nor the names of its contributors
                     23:  *    may be used to endorse or promote products derived from this software
                     24:  *    without specific prior written permission.
                     25:  *
                     26:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     27:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     28:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     29:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     30:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     31:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     32:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     33:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     34:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     35:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     36:  * SUCH DAMAGE.
                     37:  */
                     38:
1.12    ! christos   39: #include <sys/cdefs.h>
1.1       cgd        40: #if defined(LIBC_SCCS) && !defined(lint)
1.10      kleink     41: #if 0
1.5       jtc        42: static char sccsid[] = "@(#)setlocale.c        8.1 (Berkeley) 7/4/93";
1.10      kleink     43: #else
1.12    ! christos   44: __RCSID("$NetBSD$");
1.10      kleink     45: #endif
1.1       cgd        46: #endif /* LIBC_SCCS and not lint */
                     47:
1.11      kleink     48: #define _CTYPE_PRIVATE
                     49:
1.5       jtc        50: #include <sys/localedef.h>
1.11      kleink     51: #include <ctype.h>
                     52: #include <limits.h>
1.1       cgd        53: #include <locale.h>
1.11      kleink     54: #include <paths.h>
1.6       jtc        55: #include <stdio.h>
1.5       jtc        56: #include <stdlib.h>
1.1       cgd        57: #include <string.h>
1.11      kleink     58: #include "ctypeio.h"
1.1       cgd        59:
1.5       jtc        60: /*
                     61:  * Category names for getenv()
                     62:  */
                     63: static char *categories[_LC_LAST] = {
                     64:     "LC_ALL",
                     65:     "LC_COLLATE",
                     66:     "LC_CTYPE",
                     67:     "LC_MONETARY",
                     68:     "LC_NUMERIC",
                     69:     "LC_TIME",
                     70:     "LC_MESSAGES"
                     71: };
1.1       cgd        72:
                     73: /*
1.5       jtc        74:  * Current locales for each category
                     75:  */
                     76: static char current_categories[_LC_LAST][32] = {
                     77:     "C",
                     78:     "C",
                     79:     "C",
                     80:     "C",
                     81:     "C",
                     82:     "C",
                     83:     "C"
                     84: };
                     85:
                     86: /*
                     87:  * The locales we are going to try and load
1.1       cgd        88:  */
1.5       jtc        89: static char new_categories[_LC_LAST][32];
                     90:
                     91: static char current_locale_string[_LC_LAST * 33];
                     92: static char *PathLocale;
                     93:
                     94: static char    *currentlocale __P((void));
                     95: static char    *loadlocale __P((int));
                     96:
1.1       cgd        97: char *
                     98: setlocale(category, locale)
                     99:        int category;
                    100:        const char *locale;
                    101: {
1.9       kleink    102:        int i, len;
1.5       jtc       103:        char *env, *r;
                    104:
1.8       mrg       105:        /*
                    106:         * XXX potential security problem here with set-id programs
                    107:         * being able to read files the user can not normally read.
                    108:         */
1.5       jtc       109:        if (!PathLocale && !(PathLocale = getenv("PATH_LOCALE")))
                    110:                PathLocale = _PATH_LOCALE;
                    111:
                    112:        if (category < 0 || category >= _LC_LAST)
1.1       cgd       113:                return (NULL);
1.5       jtc       114:
                    115:        if (!locale)
                    116:                return (category ?
                    117:                    current_categories[category] : currentlocale());
                    118:
                    119:        /*
                    120:         * Default to the current locale for everything.
                    121:         */
                    122:        for (i = 1; i < _LC_LAST; ++i)
1.7       mrg       123:                (void)strncpy(new_categories[i], current_categories[i],
                    124:                    sizeof(new_categories[i]) - 1);
1.5       jtc       125:
                    126:        /*
                    127:         * Now go fill up new_categories from the locale argument
                    128:         */
                    129:        if (!*locale) {
                    130:                env = getenv(categories[category]);
                    131:
1.9       kleink    132:                if (!env || !*env)
1.5       jtc       133:                        env = getenv(categories[0]);
                    134:
1.9       kleink    135:                if (!env || !*env)
1.5       jtc       136:                        env = getenv("LANG");
                    137:
1.9       kleink    138:                if (!env || !*env)
1.5       jtc       139:                        env = "C";
                    140:
1.8       mrg       141:                (void)strncpy(new_categories[category], env, 31);
1.5       jtc       142:                new_categories[category][31] = 0;
                    143:                if (!category) {
                    144:                        for (i = 1; i < _LC_LAST; ++i) {
1.9       kleink    145:                                if (!(env = getenv(categories[i])) || !*env)
1.5       jtc       146:                                        env = new_categories[0];
                    147:                                (void)strncpy(new_categories[i], env, 31);
                    148:                                new_categories[i][31] = 0;
                    149:                        }
                    150:                }
1.8       mrg       151:        } else if (category) {
1.5       jtc       152:                (void)strncpy(new_categories[category], locale, 31);
                    153:                new_categories[category][31] = 0;
                    154:        } else {
                    155:                if ((r = strchr(locale, '/')) == 0) {
                    156:                        for (i = 1; i < _LC_LAST; ++i) {
                    157:                                (void)strncpy(new_categories[i], locale, 31);
                    158:                                new_categories[i][31] = 0;
                    159:                        }
                    160:                } else {
                    161:                        for (i = 1; r[1] == '/'; ++r);
                    162:                        if (!r[1])
                    163:                                return (NULL);  /* Hmm, just slashes... */
                    164:                        do {
                    165:                                len = r - locale > 31 ? 31 : r - locale;
                    166:                                (void)strncpy(new_categories[i++], locale, len);
                    167:                                new_categories[i++][len] = 0;
                    168:                                locale = r;
                    169:                                while (*locale == '/')
                    170:                                    ++locale;
                    171:                                while (*++r && *r != '/');
                    172:                        } while (*locale);
                    173:                        while (i < _LC_LAST)
1.7       mrg       174:                                (void)strncpy(new_categories[i],
                    175:                                    new_categories[i-1],
                    176:                                    sizeof(new_categories[i]) - 1);
1.5       jtc       177:                }
                    178:        }
                    179:
                    180:        if (category)
                    181:                return (loadlocale(category));
                    182:
                    183:        for (i = 1; i < _LC_LAST; ++i)
1.9       kleink    184:                if (loadlocale(i) == NULL)
                    185:                        return (NULL);
                    186:
                    187:        return (currentlocale());
1.5       jtc       188: }
                    189:
                    190: static char *
                    191: currentlocale()
                    192: {
                    193:        int i;
                    194:
1.7       mrg       195:        (void)strncpy(current_locale_string, current_categories[1],
                    196:            sizeof(current_locale_string) - 1);
1.5       jtc       197:
                    198:        for (i = 2; i < _LC_LAST; ++i)
                    199:                if (strcmp(current_categories[1], current_categories[i])) {
                    200:                        (void)snprintf(current_locale_string,
                    201:                            sizeof(current_locale_string), "%s/%s/%s/%s/%s",
                    202:                            current_categories[1], current_categories[2],
                    203:                            current_categories[3], current_categories[4],
                    204:                            current_categories[5]);
                    205:                        break;
                    206:                }
                    207:        return (current_locale_string);
                    208: }
                    209:
1.11      kleink    210: char *
1.5       jtc       211: loadlocale(category)
                    212:        int category;
                    213: {
                    214:        char name[PATH_MAX];
                    215:
1.11      kleink    216:        if (strcmp(new_categories[category], current_categories[category]) == 0)
1.5       jtc       217:                return (current_categories[category]);
                    218:
                    219:        if (!strcmp(new_categories[category], "C") ||
1.11      kleink    220:            !strcmp(new_categories[category], "POSIX")) {
                    221:
                    222:                switch (category) {
                    223:                case LC_CTYPE:
                    224:                        if (_ctype_ != _C_ctype_) {
                    225:                                free((void *)_ctype_);
                    226:                                _ctype_ = _C_ctype_;
                    227:                        }
                    228:                        if (_toupper_tab_ != _C_toupper_) {
                    229:                                free((void *)_toupper_tab_);
                    230:                                _toupper_tab_ = _C_toupper_;
                    231:                        }
                    232:                        if (_tolower_tab_ != _C_tolower_) {
                    233:                                free((void *)_tolower_tab_);
                    234:                                _tolower_tab_ = _C_tolower_;
                    235:                        }
                    236:                }
1.5       jtc       237:
1.7       mrg       238:                (void)strncpy(current_categories[category],
                    239:                    new_categories[category],
                    240:                    sizeof(current_categories[category]) - 1);
1.11      kleink    241:                return current_categories[category];
1.5       jtc       242:        }
                    243:
                    244:        /*
                    245:         * Some day we will actually look at this file.
                    246:         */
                    247:        (void)snprintf(name, sizeof(name), "%s/%s/%s",
                    248:            PathLocale, new_categories[category], categories[category]);
                    249:
                    250:        switch (category) {
1.11      kleink    251:        case LC_CTYPE:
                    252:                if (__loadctype(name)) {
                    253:                        (void)strncpy(current_categories[category],
                    254:                            new_categories[category],
                    255:                            sizeof(current_categories[category]) - 1);
                    256:                        return current_categories[category];
                    257:                }
                    258:                return NULL;
                    259:
                    260:        case LC_COLLATE:
                    261:        case LC_MESSAGES:
                    262:        case LC_MONETARY:
                    263:        case LC_NUMERIC:
                    264:        case LC_TIME:
                    265:                return NULL;
1.5       jtc       266:        }
1.11      kleink    267:
                    268:        return NULL;
1.1       cgd       269: }

CVSweb <webmaster@jp.NetBSD.org>