da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 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 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 * 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 */
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 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;
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 },
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called by stropt() to set options
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*
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknersingle(int category, Lc_t* lc, unsigned int flags)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((flags & LC_setenv) && lc_all && locales[category])
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!lc && (!(lc_categories[category].flags & LC_setlocale) || !(lc = lc_categories[category].prev)) && !(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);
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'))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (lc_categories[category].flags ^ flags)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner lc_categories[category].flags &= ~(LC_setenv|LC_setlocale);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sfprintf(sfstderr, "locale set %17s %16s %16s %16s %s%s\n", lc_categories[category].name, lc->name, sys, lc_categories[category].prev ? lc_categories[category].prev->name : NiL, (lc_categories[category].flags & LC_setlocale) ? "[setlocale]" : "", (lc_categories[category].flags & LC_setenv) ? "[setenv]" : "");
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;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (!lc_categories[cat[i]].prev && !(ast.locale.set & AST_LC_internal))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (s[0] == '/' && s[1] && n < (AST_LC_COUNT - 1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (w = ++s; *s && *s != '/'; s++);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!single(n, p, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (i = 1; i < n; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if (!lc_categories[n].prev && !(ast.locale.set & AST_LC_internal))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * setlocale() intercept
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * "" initialize from environment (if LC_ALL)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * "" AST_LC_setenv: value unset (defer to LANG)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * "*" AST_LC_setenv: value set (defer to LC_ALL)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * * set (override LC_ALL)
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);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if ((ast.locale.set & (AST_LC_debug|AST_LC_setlocale)) && !(ast.locale.set & AST_LC_internal))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sfprintf(sfstderr, "locale user %17s %16s %s%s\n", category == AST_LC_LANG ? "LANG" : lc_categories[category].name, locale && !*locale ? "''" : locale, initialized ? "" : "[initial]", (ast.locale.set & AST_LC_setenv) ? "[setenv]" : "");
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * initialize from the environment
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * precedence determined by X/Open
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (lc_categories[i].flags & LC_setlocale)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner /* explicitly set by setlocale() */;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if ((s = getenv(lc_categories[i].name)) && *s)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!single(i, lc_all && !(lc_categories[i].flags & LC_setlocale) ? lc_all : lc_categories[i].prev, 0))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sfprintf(sfstderr, "locale env %17s %16s %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))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (p && !(ast.locale.set & AST_LC_internal))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (lc_all != p)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if (!single(i, lc_all && !(lc_categories[i].flags & LC_setlocale) ? lc_all : lc_categories[i].prev, 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (i--)