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