setlocale.c revision 7c2fbfb345896881c631598ee3852ce9ce33fb07
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/***********************************************************************
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* This software is part of the ast package *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* Copyright (c) 1985-2008 AT&T Intellectual Property *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* and is licensed under the *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* Common Public License, Version 1.0 *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* by AT&T Intellectual Property *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* A copy of the License is available at *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* http://www.opensource.org/licenses/cpl1.0.txt *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* Information and Software Systems Research *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* AT&T Research *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* Florham Park NJ *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* Glenn Fowler <gsf@research.att.com> *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* David Korn <dgk@research.att.com> *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* Phong Vo <kpv@research.att.com> *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk* *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk***********************************************************************/
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk#pragma prototyped
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk * setlocale() intercept
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * maintains a bitmask of non-default categories
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * and a permanent locale namespace for pointer comparison
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * and persistent private data for locale related functions
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <ast_standards.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include "lclib.h"
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <ast_wchar.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <ctype.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <mc.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <namval.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if ( _lib_wcwidth || _lib_wctomb ) && _hdr_wctype
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <wctype.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if _lib_wcwidth
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef wcwidth
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define wcwidth 0
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if _lib_wctomb
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef wctomb
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define wctomb 0
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#ifdef mblen
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef mblen
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkextern int mblen(const char*, size_t);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef mbtowc
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef setlocale
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef strcmp
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef strcoll
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef strxfrm
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef valid
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#ifndef AST_LC_CANONICAL
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define AST_LC_CANONICAL LC_abbreviated
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if _UWIN
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#include <ast_windows.h>
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef _lib_setlocale
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define _lib_setlocale 1
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define setlocale(c,l) native_setlocale(c,l)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkextern char* uwin_setlocale(int, const char*);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * convert locale to native locale name in buf
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic char*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenknative_locale(const char* locale, char* buf, size_t siz)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk Lc_t* lc;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk const Lc_attribute_list_t* ap;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int i;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk unsigned long lcid;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk unsigned long lang;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk unsigned long ctry;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char lbuf[128];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char cbuf[128];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (locale && *locale)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!(lc = lcmake(locale)))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lang = lc->language->index;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ctry = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (ap = lc->attributes; ap; ap = ap->next)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (ctry = ap->attribute->index)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!ctry)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (i = 0; i < elementsof(lc->territory->languages); i++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (lc->territory->languages[i] == lc->language)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ctry = lc->territory->indices[i];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!ctry)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ctry = SUBLANG_DEFAULT;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lcid = MAKELCID(MAKELANGID(lang, ctry), SORT_DEFAULT);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lcid = GetUserDefaultLCID();
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, lbuf, sizeof(lbuf)) <= 0 ||
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk GetLocaleInfo(lcid, LOCALE_SENGCOUNTRY, cbuf, sizeof(cbuf)) <= 0)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (lc->charset->ms)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sfsprintf(buf, siz, "%s_%s.%s", lbuf, cbuf, lc->charset->ms);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sfsprintf(buf, siz, "%s_%s", lbuf, cbuf);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return buf;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * locale!=0 here
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic char*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenknative_setlocale(int category, const char* locale)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char* usr;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char* sys;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char buf[256];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk /*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * win32 doesn't have LC_MESSAGES
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (category == LC_MESSAGES)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return (char*)locale;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!(usr = native_locale(locale, buf, sizeof(buf))))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sys = uwin_setlocale(category, usr);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (ast.locale.set & AST_LC_debug)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sfprintf(sfstderr, "locale uwin %17s %-24s %-24s\n", lc_categories[lcindex(category, 0)].name, usr, sys);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return sys;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define native_locale(a,b,c) ((char*)0)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * LC_COLLATE and LC_CTYPE native support
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if !_lib_mbtowc || MB_LEN_MAX <= 1
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define mblen 0
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define mbtowc 0
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if !_lib_strcoll
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define strcoll 0
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if !_lib_strxfrm
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define strxfrm 0
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * LC_COLLATE and LC_CTYPE debug support
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * mutibyte debug encoding
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * DL0 [ '0' .. '4' ] c1 ... c4 DR0
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * DL1 [ '0' .. '4' ] c1 ... c4 DR1
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * with these ligatures
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * ch CH sst SST
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * and private collation order
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * wide character display width is the low order 3 bits
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * wctomb() uses DL1...DR1
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DEBUG_MB_CUR_MAX 7
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if DEBUG_MB_CUR_MAX < MB_LEN_MAX
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#undef DEBUG_MB_CUR_MAX
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DEBUG_MB_CUR_MAX MB_LEN_MAX
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DL0 '<'
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DL1 0xab /* 8-bit mini << on xterm */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DR0 '>'
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DR1 0xbb /* 8-bit mini >> on xterm */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DB ((int)sizeof(wchar_t)*8-1)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DC 7 /* wchar_t embedded char bits */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DX (DB/DC) /* wchar_t max embedded chars */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DZ (DB-DX*DC+1) /* wchar_t embedded size bits */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define DD 3 /* # mb delimiter chars <n...> */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic unsigned char debug_order[] =
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 0, 1, 2, 3, 4, 5, 6, 7,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 8, 9, 10, 11, 12, 13, 14, 15,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 16, 17, 18, 19, 20, 21, 22, 23,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 24, 25, 26, 27, 28, 29, 30, 31,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 99, 100, 101, 102, 98, 103, 104, 105,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 106, 107, 108, 43, 109, 44, 42, 110,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 32, 33, 34, 35, 36, 37, 38, 39,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 40, 41, 111, 112, 113, 114, 115, 116,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 117, 71, 72, 73, 74, 75, 76, 77,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 78, 79, 80, 81, 82, 83, 84, 85,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 86, 87, 88, 89, 90, 91, 92, 93,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 94, 95, 96, 118, 119, 120, 121, 97,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 122, 45, 46, 47, 48, 49, 50, 51,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 52, 53, 54, 55, 56, 57, 58, 59,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 60, 61, 62, 63, 64, 65, 66, 67,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 68, 69, 70, 123, 124, 125, 126, 127,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 128, 129, 130, 131, 132, 133, 134, 135,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 136, 137, 138, 139, 140, 141, 142, 143,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 144, 145, 146, 147, 148, 149, 150, 151,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 152, 153, 154, 155, 156, 157, 158, 159,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 160, 161, 162, 163, 164, 165, 166, 167,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 168, 169, 170, 171, 172, 173, 174, 175,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 176, 177, 178, 179, 180, 181, 182, 183,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 184, 185, 186, 187, 188, 189, 190, 191,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 192, 193, 194, 195, 196, 197, 198, 199,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 200, 201, 202, 203, 204, 205, 206, 207,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 208, 209, 210, 211, 212, 213, 214, 215,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 216, 217, 218, 219, 220, 221, 222, 223,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 224, 225, 226, 227, 228, 229, 230, 231,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 232, 233, 234, 235, 236, 237, 238, 239,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 240, 241, 242, 243, 244, 245, 246, 247,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 248, 249, 250, 251, 252, 253, 254, 255,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk};
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdebug_mbtowc(register wchar_t* p, register const char* s, size_t n)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register const char* q;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register const char* r;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int dr;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk wchar_t c;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (n < 1)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!s || !*s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk switch (((unsigned char*)s)[0])
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk case DL0:
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk dr = DR0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk case DL1:
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk dr = DR1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk default:
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (p)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *p = ((unsigned char*)s)[0] & ((1<<DC)-1);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (n < 2)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((w = ((unsigned char*)s)[1]) == ((unsigned char*)s)[0])
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (p)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *p = w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 2;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (w < '0' || w > ('0' + DX))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((w -= '0' - DD) > n)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk r = s + w - 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk q = s += 2;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (q < r && *q)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk q++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (q != r || *((unsigned char*)q) != dr)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (p)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (--q >= s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c <<= DC;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c |= *((unsigned char*)q);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c <<= DZ;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c |= w - DD;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *p = c;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdebug_wctomb(char* s, wchar_t c)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int i;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int k;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (c >= 0 && c <= UCHAR_MAX)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *s = c;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if ((i = c & ((1<<DZ)-1)) > DX)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *s++ = DL1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c >>= DZ;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *s++ = i + '0';
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk while (i--)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (s)
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk *s++ = (k = c & ((1<<DC)-1)) ? k : '?';
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk c >>= DC;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *s++ = DR1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdebug_mblen(const char* s, size_t n)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return debug_mbtowc(NiL, s, n);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdebug_wcwidth(wchar_t c)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (c >= 0 && c <= UCHAR_MAX)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((c &= ((1<<DZ)-1)) > DX)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return c + DD;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic size_t
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdebug_strxfrm(register char* t, register const char* s, size_t n)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register const char* q;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register const char* r;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register char* e;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char* o;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register size_t z;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk o = t;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk z = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (e = t)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk e += n;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (s[0])
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((((unsigned char*)s)[0] == DL0 || ((unsigned char*)s)[0] == DL1) && (w = s[1]) >= '0' && w <= ('0' + DC))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w -= '0';
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk q = s + 2;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk r = q + w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (q < r && *q)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk q++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (*((unsigned char*)q) == DR0 || *((unsigned char*)q) == DR1)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (q = s + 2; q < r; q++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[*q];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (w++ < DX)
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk s = r + 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk z += DX;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk continue;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((s[0] == 'c' || s[0] == 'C') && (s[1] == 'h' || s[1] == 'H'))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[s[0]];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[s[1]];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk s += 2;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk z += DX;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk continue;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((s[0] == 's' || s[0] == 'S') && (s[1] == 's' || s[1] == 'S') && (s[2] == 't' || s[2] == 'T'))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[s[0]];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[s[1]];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[s[2]];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk s += 3;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk z += DX;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk continue;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = debug_order[s[0]];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t++ = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk s++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk z += DX;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!t)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return z;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (t < e)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *t = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return t - o;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdebug_strcoll(const char* a, const char* b)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char ab[1024];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char bb[1024];
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk debug_strxfrm(ab, a, sizeof(ab) - 1);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ab[sizeof(ab)-1] = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk debug_strxfrm(bb, b, sizeof(bb) - 1);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk bb[sizeof(bb)-1] = 0;
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk return strcmp(ab, bb);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * default locale
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdefault_wcwidth(wchar_t w)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return w >= 0 && w <= 255 && !iscntrl(w) ? 1 : -1;
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * called when LC_COLLATE initialized or changes
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkset_collate(Lc_category_t* cp)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (locales[cp->internal]->flags & LC_debug)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.collate = debug_strcoll;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_xfrm = debug_strxfrm;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if (locales[cp->internal]->flags & LC_default)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.collate = strcmp;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_xfrm = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.collate = strcoll;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_xfrm = strxfrm;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * workaround the interesting sjis that translates unshifted 7 bit ascii!
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if _hdr_wchar && _typ_mbstate_t && _lib_mbrtowc
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define mb_state_zero ((mbstate_t*)&ast.pad[sizeof(ast.pad)-2*sizeof(mbstate_t)])
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define mb_state ((mbstate_t*)&ast.pad[sizeof(ast.pad)-sizeof(mbstate_t)])
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenksjis_mbtowc(register wchar_t* p, register const char* s, size_t n)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk if (n && p && s && (*s == '\\' || *s == '~') && !memcmp(mb_state, mb_state_zero, sizeof(mbstate_t)))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *p = *s;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return mbrtowc(p, s, n, mb_state);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * called when LC_CTYPE initialized or changes
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkset_ctype(Lc_category_t* cp)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (locales[cp->internal]->flags & LC_debug)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_cur_max = DEBUG_MB_CUR_MAX;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_len = debug_mblen;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_towc = debug_mbtowc;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_width = debug_wcwidth;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_conv = debug_wctomb;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if ((locales[cp->internal]->flags & LC_default) || (ast.mb_cur_max = MB_CUR_MAX) <= 1 || !(ast.mb_len = mblen) || !(ast.mb_towc = mbtowc))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_cur_max = 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_len = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_towc = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_width = default_wcwidth;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_conv = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!(ast.mb_width = wcwidth))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_width = default_wcwidth;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_conv = wctomb;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#ifdef mb_state
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk /*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * check for sjis that translates unshifted 7 bit ascii!
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char* s;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char buf[2];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk mbinit();
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk buf[1] = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk *(s = buf) = '\\';
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (mbchar(s) != buf[0])
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk memcpy(mb_state, mb_state_zero, sizeof(mbstate_t));
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.mb_towc = sjis_mbtowc;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * called when LC_NUMERIC initialized or changes
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkset_numeric(Lc_category_t* cp)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int category = cp->internal;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk struct lconv* lp;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk Lc_numeric_t* dp;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk static Lc_numeric_t default_numeric = { '.', -1 };
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!LCINFO(category)->data)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((lp = localeconv()) && (dp = newof(0, Lc_numeric_t, 1, 0)))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk dp->decimal = lp->decimal_point && *lp->decimal_point ? *(unsigned char*)lp->decimal_point : '.';
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk dp->thousand = lp->thousands_sep && *lp->thousands_sep ? *(unsigned char*)lp->thousands_sep : -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk dp = &default_numeric;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk LCINFO(category)->data = (void*)dp;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (ast.locale.set & (AST_LC_debug|AST_LC_setlocale))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sfprintf(sfstderr, "locale info %17s decimal '%c' thousands '%c'\n", lc_categories[category].name, dp->decimal, dp->thousand >= 0 ? dp->thousand : 'X');
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * this table is indexed by AST_LC_[A-Z]*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkLc_category_t lc_categories[] =
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_ALL", LC_ALL, AST_LC_ALL, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_COLLATE", LC_COLLATE, AST_LC_COLLATE, set_collate },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_CTYPE", LC_CTYPE, AST_LC_CTYPE, set_ctype },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_MESSAGES", LC_MESSAGES, AST_LC_MESSAGES, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_MONETARY", LC_MONETARY, AST_LC_MONETARY, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_NUMERIC", LC_NUMERIC, AST_LC_NUMERIC, set_numeric },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_TIME", LC_TIME, AST_LC_TIME, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_IDENTIFICATION",LC_IDENTIFICATION,AST_LC_IDENTIFICATION,0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_ADDRESS", LC_ADDRESS, AST_LC_ADDRESS, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_NAME", LC_NAME, AST_LC_NAME, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_TELEPHONE", LC_TELEPHONE, AST_LC_TELEPHONE, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_XLITERATE", LC_XLITERATE, AST_LC_XLITERATE, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_MEASUREMENT", LC_MEASUREMENT, AST_LC_MEASUREMENT, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{ "LC_PAPER", LC_PAPER, AST_LC_PAPER, 0 },
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk};
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic const Namval_t options[] =
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk "debug", AST_LC_debug,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk "find", AST_LC_find,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk "setlocale", AST_LC_setlocale,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk "translate", AST_LC_translate,
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk 0, 0
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk};
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * called by stropt() to set options
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenksetopt(void* a, const void* p, int n, const char* v)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (p)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (n)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.locale.set |= ((Namval_t*)p)->value;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.locale.set &= ~((Namval_t*)p)->value;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#if !_lib_setlocale
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#define setlocale(c,l) default_setlocale(c,l)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic char*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkdefault_setlocale(int category, const char* locale)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk Lc_t* lc;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (locale)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!(lc = lcmake(locale)) || !(lc->flags & LC_default))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk locales[0]->flags &= ~lc->flags;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk locales[1]->flags &= ~lc->flags;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return lc->name;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return (locales[1]->flags & (1<<category)) ? locales[1]->name : locales[0]->name;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk#endif
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * set a single AST_LC_* locale category
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * the caller must validate category
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * lc==0 restores the previous state
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic char*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenksingle(int category, Lc_t* lc)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk const char* sys;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int i;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!lc && !(lc = lc_categories[category].prev))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lc = lcmake(NiL);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (locales[category] != lc)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (lc_categories[category].external == -lc_categories[category].internal)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sys = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (i = 1; i < AST_LC_COUNT; i++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (locales[i] == lc)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sys = (char*)lc->name;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if (lc->flags & (LC_debug|LC_local))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sys = setlocale(lc_categories[category].external, lcmake(NiL)->name);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if (!(sys = setlocale(lc_categories[category].external, lc->name)) &&
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk (streq(lc->name, lc->code) || !(sys = setlocale(lc_categories[category].external, lc->code))) &&
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk !streq(lc->code, lc->language->code))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk sys = setlocale(lc_categories[category].external, lc->language->code);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (ast.locale.set & (AST_LC_debug|AST_LC_setlocale))
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk sfprintf(sfstderr, "locale set %17s %-24s %-24s\n", lc_categories[category].name, lc->name, sys);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!sys)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk /*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * check for local override
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * currently this means an LC_MESSAGES dir exists
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!(lc->flags & LC_checked))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char path[PATH_MAX];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (mcfind(path, lc->code, NiL, LC_MESSAGES, 0))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lc->flags |= LC_local;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lc->flags |= LC_checked;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!(lc->flags & LC_local))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (lc_categories[category].external != -lc_categories[category].internal)
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk setlocale(lc_categories[category].external, lcmake(NiL)->name);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk locales[category] = lc;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (lc_categories[category].setf && (*lc_categories[category].setf)(&lc_categories[category]))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk locales[category] = lc_categories[category].prev;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (lc->flags & LC_default)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.locale.set &= ~(1<<category);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk ast.locale.set |= (1<<category);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return (char*)lc->name;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk}
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk/*
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * set composite AST_LC_ALL locale categories
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk * return <0:composite-error 0:not-composite >0:composite-ok
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk */
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkstatic int
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenkcomposite(register const char* s, int initialize)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk{
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register const char* t;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int i;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int j;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk register int k;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int n;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk const char* w;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk Lc_t* p;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int cat[AST_LC_COUNT];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk int stk[AST_LC_COUNT];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk char buf[PATH_MAX / 2];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk k = n = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (s[0] == 'L' && s[1] == 'C' && s[2] == '_')
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk n++;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk j = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w = s;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (i = 1; i < AST_LC_COUNT; i++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk s = w;
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk t = lc_categories[i].name;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (*t && *s++ == *t++);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!*t && *s++ == '=')
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk cat[j++] = i;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (s[0] != 'L' || s[1] != 'C' || s[2] != '_')
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w = s;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk i = -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (s = w; *s && *s != '='; s++);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!*s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (i = 0; i < k; i++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk single(stk[i], NiL);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk w = ++s;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (;;)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!*s)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk p = lcmake(w);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if (*s++ == ';')
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if ((n = s - w - 1) >= sizeof(buf))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk n = sizeof(buf) - 1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk memcpy(buf, w, n);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk buf[n] = 0;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk p = lcmake(buf);
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk break;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk for (i = 0; i < j; i++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!initialize)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk if (!single(cat[i], p))
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk {
dff2cc5646d4437ab9e0cb1dcb59da65462a5938jeff.schenk for (i = 0; i < k; i++)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk single(stk[i], NiL);
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk return -1;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk stk[k++] = cat[i];
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk else if (!lc_categories[cat[i]].prev)
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk lc_categories[cat[i]].prev = p;
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk }
5b64d5d44892834ba97f003080f3467299b7c5c5jeff.schenk while (s[0] == '/' && s[1] && n < AST_LC_COUNT)
{
n++;
for (w = ++s; *s && *s != '/'; s++);
if (!*s)
p = lcmake(w);
else
{
if ((j = s - w - 1) >= sizeof(buf))
j = sizeof(buf) - 1;
memcpy(buf, w, j);
buf[j] = 0;
p = lcmake(buf);
}
if (!initialize)
{
if (!single(n, p))
{
for (i = 1; i < n; i++)
single(i, NiL);
return -1;
}
}
else if (!lc_categories[n].prev)
lc_categories[n].prev = p;
}
return n;
}
/*
* setlocale() intercept
*/
char*
_ast_setlocale(int category, const char* locale)
{
register char* s;
register int i;
register int j;
int k;
char* a;
Lc_t* p;
int cat[AST_LC_COUNT];
static Sfio_t* sp;
static int initialized;
static char local[] = "local";
if ((category = lcindex(category, 0)) < 0)
return 0;
if (!locale)
{
/*
* return the current state
*/
compose:
if (category != AST_LC_ALL)
return (char*)locales[category]->name;
if (!sp && !(sp = sfstropen()))
return 0;
for (i = 1; i < AST_LC_COUNT; i++)
cat[i] = -1;
for (i = 1, k = 0; i < AST_LC_COUNT; i++)
if (cat[i] < 0)
{
k++;
cat[i] = i;
for (j = i + 1; j < AST_LC_COUNT; j++)
if (locales[j] == locales[i])
cat[j] = i;
}
if (k == 1)
return (char*)locales[1]->name;
for (i = 1; i < AST_LC_COUNT; i++)
if (cat[i] >= 0 && !(locales[i]->flags & LC_default))
{
if (sfstrtell(sp))
sfprintf(sp, ";");
for (j = i, k = cat[i]; j < AST_LC_COUNT; j++)
if (cat[j] == k)
{
cat[j] = -1;
sfprintf(sp, "%s=", lc_categories[j].name);
}
sfprintf(sp, "%s", locales[i]->name);
}
if (!sfstrtell(sp))
return (char*)locales[0]->name;
return sfstruse(sp);
}
if (!ast.locale.serial++)
stropt(getenv("LC_OPTIONS"), options, sizeof(*options), setopt, NiL);
if (*locale)
p = lcmake(locale);
else if (!initialized)
{
char* u;
char tmp[256];
/*
* initialize from the environment
* precedence determined by X/Open
*/
u = 0;
if (!(a = getenv("LC_ALL")) || !*a)
{
for (i = 1; i < AST_LC_COUNT; i++)
if ((s = getenv(lc_categories[i].name)) && *s)
{
if (streq(s, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
s = u;
lc_categories[i].prev = lcmake(s);
}
a = getenv("LANG");
}
if (a)
{
if (streq(a, local) && (u || (u = native_locale(locale, tmp, sizeof(tmp)))))
a = u;
if (composite(a, 1))
a = 0;
}
p = 0;
for (i = 1; i < AST_LC_COUNT; i++)
{
if (!lc_categories[i].prev)
{
if (!p && !(p = lcmake(a)))
break;
lc_categories[i].prev = p;
}
if (!single(i, lc_categories[i].prev))
{
while (i--)
single(i, NiL);
return 0;
}
}
if (ast.locale.set & AST_LC_debug)
for (i = 1; i < AST_LC_COUNT; i++)
sfprintf(sfstderr, "locale env %17s %s\n", lc_categories[i].name, locales[i]->name);
initialized = 1;
goto compose;
}
else if (!(p = lc_categories[category].prev))
p = lcmake("C");
if (category != AST_LC_ALL)
return single(category, p);
else if (!(i = composite(locale, 0)))
{
if (!p)
return 0;
for (i = 1; i < AST_LC_COUNT; i++)
if (!single(i, p))
{
while (i--)
single(i, NiL);
return 0;
}
}
else if (i < 0)
return 0;
goto compose;
}