setlocale.c revision 34f9b3eef6fdadbda0a846aa4d68691ac40eace5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 1985-2009 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * setlocale() intercept
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * maintains a bitmask of non-default categories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and a permanent locale namespace for pointer comparison
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and persistent private data for locale related functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern char* uwin_setlocale(int, const char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert locale to native locale name in buf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnative_locale(const char* locale, char* buf, size_t siz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long lcid;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long lang;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long ctry;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < elementsof(lc->territory->languages); i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, lbuf, sizeof(lbuf)) <= 0 ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, cbuf, sizeof(cbuf)) <= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(buf, siz, "%s_%s.%s", lbuf, cbuf, lc->charset->ms);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * locale!=0 here
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(usr = native_locale(locale, buf, sizeof(buf))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * win32 doesn't have LC_MESSAGES
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (char*)locale;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sfstderr, "locale uwin %17s %-24s %-24s\n", lc_categories[lcindex(category, 0)].name, usr, sys);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define native_locale(a,b,c) ((char*)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * LC_COLLATE and LC_CTYPE native support
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * LC_COLLATE and LC_CTYPE debug support
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mutibyte debug encoding
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * DL0 [ '0' .. '4' ] c1 ... c4 DR0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * DL1 [ '0' .. '4' ] c1 ... c4 DR1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * with these ligatures
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ch CH sst SST
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and private collation order
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * wide character display width is the low order 3 bits
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * wctomb() uses DL1...DR1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define DZ (DB-DX*DC+1) /* wchar_t embedded size bits */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic unsigned char debug_order[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindebug_mbtowc(register wchar_t* p, register const char* s, size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int dr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!s || !*s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (((unsigned char*)s)[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n < 2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((w = ((unsigned char*)s)[1]) == ((unsigned char*)s)[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = s + w - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = s += 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (q < r && *q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (q != r || *((unsigned char*)q) != dr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (--q >= s)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c |= *((unsigned char*)q);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= 0 && c <= UCHAR_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *s++ = i + '0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (i--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c >= 0 && c <= UCHAR_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return c + DD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindebug_strxfrm(register char* t, register const char* s, size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register size_t z;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (e = t)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (s[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((((unsigned char*)s)[0] == DL0 || ((unsigned char*)s)[0] == DL1) && (w = s[1]) >= '0' && w <= ('0' + DC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = s + 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = q + w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (q < r && *q)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*((unsigned char*)q) == DR0 || *((unsigned char*)q) == DR1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (q = s + 2; q < r; q++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (w++ < DX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = r + 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((s[0] == 'c' || s[0] == 'C') && (s[1] == 'h' || s[1] == 'H'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = debug_order[s[0]];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((s[0] == 's' || s[0] == 'S') && (s[1] == 's' || s[1] == 'S') && (s[2] == 't' || s[2] == 'T'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = debug_order[s[0]];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = debug_order[s[0]];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t < e)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return t - o;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindebug_strcoll(const char* a, const char* b)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * default locale
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called when LC_COLLATE initialized or changes
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * workaround the interesting sjis that translates unshifted 7 bit ascii!
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define mb_state_zero ((mbstate_t*)&ast.pad[sizeof(ast.pad)-2*sizeof(mbstate_t)])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define mb_state ((mbstate_t*)&ast.pad[sizeof(ast.pad)-sizeof(mbstate_t)])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinsjis_mbtowc(register wchar_t* p, register const char* s, size_t n)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (n && p && s && (*s == '\\' || *s == '~') && !memcmp(mb_state, mb_state_zero, sizeof(mbstate_t)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,-1,-1,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzutf8_mbtowc(wchar_t* wp, const char* str, size_t n)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register unsigned char* sp = (unsigned char*)str;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int m;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int i;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int c;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register wchar_t w = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (i = m - 1; i > 0; i--)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(utf8mask[m] & w) || w >= 0xd800 && (w <= 0xdfff || w >= 0xfffe && w <= 0xffff))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called when LC_CTYPE initialized or changes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((locales[cp->internal]->flags & LC_default) || (ast.mb_cur_max = MB_CUR_MAX) <= 1 || !(ast.mb_len = mblen) || !(ast.mb_towc = mbtowc))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if ((locales[cp->internal]->flags & LC_utf8) && !(ast.locale.set & AST_LC_test))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * check for sjis that translates unshifted 7 bit ascii!
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(mb_state, mb_state_zero, sizeof(mbstate_t));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (ast.locale.set & (AST_LC_debug|AST_LC_setlocale))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstderr, "locale info %17s MB_CUR_MAX=%d%s%s%s%s\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz , ast.mb_len == debug_mblen ? " debug_mblen" : ast.mb_len == mblen ? " mblen" : ""
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz , ast.mb_towc == debug_mbtowc ? " debug_mbtowc" : ast.mb_towc == mbtowc ? " mbtowc"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz , ast.mb_width == debug_wcwidth ? " debug_wcwidth" : ast.mb_width == wcwidth ? " wcwidth" : ast.mb_width == default_wcwidth ? " default_wcwidth" : ""
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz , ast.mb_conv == debug_wctomb ? " debug_wctomb" : ast.mb_conv == wctomb ? " wctomb" : ""
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called when LC_NUMERIC initialized or changes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((lp = localeconv()) && (dp = newof(0, Lc_numeric_t, 1, 0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->decimal = lp->decimal_point && *lp->decimal_point ? *(unsigned char*)lp->decimal_point : '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->thousand = lp->thousands_sep && *lp->thousands_sep ? *(unsigned char*)lp->thousands_sep : -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sfstderr, "locale info %17s decimal '%c' thousands '%c'\n", lc_categories[category].name, dp->decimal, dp->thousand >= 0 ? dp->thousand : 'X');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * this table is indexed by AST_LC_[A-Z]*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{ "LC_COLLATE", LC_COLLATE, AST_LC_COLLATE, set_collate },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{ "LC_NUMERIC", LC_NUMERIC, AST_LC_NUMERIC, set_numeric },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{ "LC_IDENTIFICATION",LC_IDENTIFICATION,AST_LC_IDENTIFICATION,0 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{ "LC_MEASUREMENT", LC_MEASUREMENT, AST_LC_MEASUREMENT, 0 },
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned int value;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called by stropt() to set options
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetopt(void* a, const void* p, int n, const char* v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(lc = lcmake(locale)) || !(lc->flags & LC_default))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return (locales[1]->flags & (1<<category)) ? locales[1]->name : locales[0]->name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set a single AST_LC_* locale category
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the caller must validate category
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * lc==0 restores the previous state
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* sys;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!lc && !(lc = lc_all) && !(lc = lc_categories[category].prev) && !(lc = lang))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (lc_categories[category].external == -lc_categories[category].internal)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sys = setlocale(lc_categories[category].external, lcmake(NiL)->name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if (!(sys = setlocale(lc_categories[category].external, lc->name)) &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (streq(lc->name, lc->code) || !(sys = setlocale(lc_categories[category].external, lc->code))) &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sys = setlocale(lc_categories[category].external, lc->language->code);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sfstderr, "locale set %17s %-24s %-24s\n", lc_categories[category].name, lc->name, sys);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for local override
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * currently this means an LC_MESSAGES dir exists
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (lc_categories[category].external != -lc_categories[category].internal)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin setlocale(lc_categories[category].external, lcmake(NiL)->name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (lc_categories[category].setf && (*lc_categories[category].setf)(&lc_categories[category]))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin locales[category] = lc_categories[category].prev;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((lc->flags & LC_default) || category == AST_LC_MESSAGES && lc->name[0] == 'e' && lc->name[1] == 'n' && (lc->name[2] == 0 || lc->name[2] == '_' && lc->name[3] == 'U'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * set composite AST_LC_ALL locale categories
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return <0:composite-error 0:not-composite >0:composite-ok
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int k;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* w;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin k = n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*t && *s++ == *t++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!*t && *s++ == '=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (s = w; *s && *s != '='; s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < k; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (*s++ == ';')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < j; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 0; i < k; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (s[0] == '/' && s[1] && n < (AST_LC_COUNT - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (w = ++s; *s && *s != '/'; s++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!single(n, p))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 1; i < n; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * setlocale() intercept
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * "" initialize from environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the current state
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (category != AST_LC_ALL && category != AST_LC_LANG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cat[i] < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (k == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (cat[j] == k)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stropt(getenv("LC_OPTIONS"), options, sizeof(*options), setopt, NiL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz p = streq(locale, "-") ? (Lc_t*)0 : lcmake(locale);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * initialize from the environment
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * precedence determined by X/Open
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!single(i, lc_all ? lc_all : lc_categories[i].prev))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstderr, "locale env %17s %16s %16s\n", lc_categories[i].name, locales[i]->name, lc_categories[i].prev ? lc_categories[i].prev->name : (char*)0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (category == AST_LC_LANG || !(p = lc_categories[category].prev))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (lc_all != p)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!single(i, lc_all ? lc_all : lc_categories[i].prev))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (i--)