⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 locale.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  Copyright (C) 2002     Manuel Novoa III * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public *  License along with this library; if not, write to the Free *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* Nov. 1, 2002 * Reworked setlocale() return values and locale arg processing to *   be more like glibc.  Applications expecting to be able to *   query locale settings should now work... at the cost of almost *   doubling the size of the setlocale object code. * Fixed a bug in the internal fixed-size-string locale specifier code. * * Dec 20, 2002 * Added in collation support and updated stub nl_langinfo. * * Aug 1, 2003 * Added glibc-like extended locale stuff (newlocale, duplocale, etc). * * Aug 18, 2003 * Bug in duplocale... collation data wasn't copied. * Bug in newlocale... translate 1<<LC_ALL to LC_ALL_MASK. * Bug in _wchar_utf8sntowcs... fix cut-n-paste error. * * Aug 31, 2003 * Hack around bg_BG bug; grouping specified but no thousands separator. * Also, disable the locale link_warnings for now, as they generate a * lot of noise when using libstd++. *//*  TODO: *  Implement the shared mmap code so non-mmu platforms can use this. *  Add some basic collate functionality similar to what the previous *    locale support had (8-bit codesets only). */#define _GNU_SOURCE#define __CTYPE_HAS_8_BIT_LOCALES 1#include <string.h>#include <stdlib.h>#include <stddef.h>#include <limits.h>#include <stdint.h>#include <assert.h>#include <errno.h>#include <ctype.h>#include <stdio.h>#ifdef __UCLIBC_MJN3_ONLY__#ifdef L_setlocale#warning TODO: Make the link_warning()s a config option?#endif#endif#undef link_warning#define link_warning(A,B)#undef __LOCALE_C_ONLY#ifndef __UCLIBC_HAS_LOCALE__#define __LOCALE_C_ONLY#endif /* __UCLIBC_HAS_LOCALE__ */#ifdef __LOCALE_C_ONLY#include <locale.h>#else  /* __LOCALE_C_ONLY */#ifdef __UCLIBC_MJN3_ONLY__#ifdef L_setlocale#warning TODO: Fix the __CTYPE_HAS_8_BIT_LOCALES define at the top of the file.#warning TODO: Fix __WCHAR_ENABLED.#endif#endif/* Need to include this before locale.h and xlocale.h! */#include <bits/uClibc_locale.h>#undef CODESET_LIST#define CODESET_LIST			(__locale_mmap->codeset_list)#ifdef __UCLIBC_HAS_XLOCALE__#include <xlocale.h>#include <locale.h>#else  /* __UCLIBC_HAS_XLOCALE__ *//* We need this internally... */#define __UCLIBC_HAS_XLOCALE__ 1#include <xlocale.h>#include <locale.h>#undef __UCLIBC_HAS_XLOCALE__#endif /* __UCLIBC_HAS_XLOCALE__ */#include <wchar.h>#define LOCALE_NAMES			(__locale_mmap->locale_names5)#define LOCALES					(__locale_mmap->locales)#define LOCALE_AT_MODIFIERS 	(__locale_mmap->locale_at_modifiers)#define CATEGORY_NAMES			(__locale_mmap->lc_names)#ifdef __UCLIBC_MJN3_ONLY__#warning REMINDER: redo the MAX_LOCALE_STR stuff...#endif#define MAX_LOCALE_STR            256 /* TODO: Only sufficient for current case. */#define MAX_LOCALE_CATEGORY_STR    32 /* TODO: Only sufficient for current case. *//* Note: Best if MAX_LOCALE_CATEGORY_STR is a power of 2. */extern int _locale_set_l(const unsigned char *p, __locale_t base);extern void _locale_init_l(__locale_t base);#endif /* __LOCALE_C_ONLY */#undef LOCALE_STRING_SIZE#define LOCALE_SELECTOR_SIZE (2 * __LC_ALL + 2)#ifdef __UCLIBC_MJN3_ONLY__#ifdef L_setlocale#warning TODO: Create a C locale selector string.#endif#endif#define C_LOCALE_SELECTOR "\x23\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80\x80"#include <langinfo.h>#include <nl_types.h>/**********************************************************************/#ifdef L_setlocale#ifdef __LOCALE_C_ONLYlink_warning(setlocale,"REMINDER: The 'setlocale' function supports only C|POSIX locales.")static const char C_string[] = "C";char *setlocale(int category, register const char *locale){	return ( (((unsigned int)(category)) <= LC_ALL)			 && ( (!locale)		/* Request for locale category string. */				  || (!*locale)	/* Implementation-defined default is C. */				  || ((*locale == 'C') && !locale[1])				  || (!strcmp(locale, "POSIX"))) )		? (char *) C_string		/* Always in C/POSIX locale. */		: NULL;}#else  /* ---------------------------------------------- __LOCALE_C_ONLY */#ifdef __UCLIBC_HAS_THREADS__link_warning(setlocale,"REMINDER: The 'setlocale' function is _not_ threadsafe except for simple queries.")#endif#if !defined(__LOCALE_DATA_NUM_LOCALES) || (__LOCALE_DATA_NUM_LOCALES <= 1)#error locales enabled, but not data other than for C locale!#endif#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Move posix and utf8 strings.#endifstatic const char posix[] = "POSIX";static const char utf8[] = "UTF-8";#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Fix dimensions of hr_locale.#endif/* Individual category strings start at hr_locale + category * MAX_LOCALE_CATEGORY.  * This holds for LC_ALL as well. */static char hr_locale[(MAX_LOCALE_CATEGORY_STR * LC_ALL) + MAX_LOCALE_STR];static void update_hr_locale(const unsigned char *spec){	const unsigned char *loc;	const unsigned char *s;	char *n;	int i, category, done;	done = category = 0;	do {		s = spec + 1;		n = hr_locale + category * MAX_LOCALE_CATEGORY_STR;		if (category == LC_ALL) {			done = 1;			for (i = 0 ; i < LC_ALL-1 ; i += 2) {				if ((s[i] != s[i+2]) || (s[i+1] != s[i+3])) {					goto SKIP;				}			}			/* All categories the same, so simplify string by using a single			 * category. */			category = LC_CTYPE;		}	SKIP:		i = (category == LC_ALL) ? 0 : category;		s += 2*i;		do {			if ((*s != 0xff) || (s[1] != 0xff)) {				loc = LOCALES					+ __LOCALE_DATA_WIDTH_LOCALES * ((((int)(*s & 0x7f)) << 7)													 + (s[1] & 0x7f));				if (category == LC_ALL) {					n = stpcpy(n, CATEGORY_NAMES + (int) CATEGORY_NAMES[i]);					*n++ = '=';				}				if (*loc == 0) {					*n++ = 'C';					*n = 0;				} else {					char at = 0;					memcpy(n, LOCALE_NAMES + 5*((*loc)-1), 5);					if (n[2] != '_') {						at = n[2];						n[2] = '_';					}					n += 5;					*n++ = '.';					if (loc[2] == 2) {						n = stpcpy(n, utf8);					} else if (loc[2] >= 3) {						n = stpcpy(n, CODESET_LIST + (int)(CODESET_LIST[loc[2] - 3]));					}					if (at) {						const char *q;						*n++ = '@';						q = LOCALE_AT_MODIFIERS;						do {							if (q[1] == at) {								n = stpcpy(n, q+2);								break;							}							q += 2 + *q;						} while (*q);					}				}				*n++ = ';';			}			s += 2;		} while (++i < category);		*--n = 0;		  /* Remove trailing ';' and nul-terminate. */		++category;	} while (!done);}char *setlocale(int category, const char *locale){	if (((unsigned int)(category)) > LC_ALL) {#if 0		__set_errno(EINVAL);	/* glibc sets errno -- SUSv3 doesn't say. */#endif		return NULL;			/* Illegal/unsupported category. */	}	if (locale != NULL) {		/* Not just a query... */		if (!__newlocale((1 << category), locale, __global_locale)) {			return NULL;		/* Failed! */		}		update_hr_locale(__global_locale->cur_locale);	}	/* Either a query or a successful set, so return current locale string. */	return hr_locale + (category * MAX_LOCALE_CATEGORY_STR);}#endif /* __LOCALE_C_ONLY */#endif/**********************************************************************/#ifdef L_localeconv/* Note: We assume here that the compiler does the sane thing regarding * placement of the fields in the struct.  If necessary, we could ensure * this usings an array of offsets but at some size cost. */#ifdef __LOCALE_C_ONLYlink_warning(localeconv,"REMINDER: The 'localeconv' function is hardwired for C/POSIX locale only.")static struct lconv the_lconv;static const char decpt[] = ".";struct lconv *localeconv(void){	register char *p = (char *)(&the_lconv);	*((char **)p) = (char *) decpt;	do {		p += sizeof(char **);		*((char **)p) = (char *) (decpt+1);	} while (p < (char *) &the_lconv.negative_sign);	p = (&the_lconv.int_frac_digits);	do {		*p = CHAR_MAX;		++p;	} while (p <= &the_lconv.int_n_sign_posn);	return &the_lconv;}#else  /* __LOCALE_C_ONLY */static struct lconv the_lconv;struct lconv *localeconv(void){	register char *p = (char *) &the_lconv;	register char **q = (char **) &(__UCLIBC_CURLOCALE_DATA).decimal_point;	do {		*((char **)p) = *q;		p += sizeof(char **);		++q;	} while (p < &the_lconv.int_frac_digits);	do {		*p = **q;		++p;		++q;	} while (p <= &the_lconv.int_n_sign_posn);	return &the_lconv;}#endif /* __LOCALE_C_ONLY */#endif/**********************************************************************/#if defined(L__locale_init) && !defined(__LOCALE_C_ONLY)__uclibc_locale_t __global_locale_data;__locale_t __global_locale = &__global_locale_data;#ifdef __UCLIBC_HAS_XLOCALE____locale_t __curlocale_var = &__global_locale_data;#endif/*----------------------------------------------------------------------*/#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Move utf8 and ascii strings.#endifstatic const char utf8[] = "UTF-8";static const char ascii[] = "ASCII";typedef struct {	uint16_t num_base;	uint16_t num_der;	uint16_t MAX_WEIGHTS;	uint16_t num_index2weight;#define num_index2ruleidx num_index2weight	uint16_t num_weightstr;	uint16_t num_multistart;	uint16_t num_override;	uint16_t num_ruletable;} coldata_header_t;typedef struct {	uint16_t num_weights;	uint16_t num_starters;	uint16_t ii_shift;	uint16_t ti_shift;	uint16_t ii_len;	uint16_t ti_len;	uint16_t max_weight;	uint16_t num_col_base;	uint16_t max_col_index;	uint16_t undefined_idx;	uint16_t range_low;	uint16_t range_count;	uint16_t range_base_weight;	uint16_t range_rule_offset;	uint16_t index2weight_offset;	uint16_t index2ruleidx_offset;	uint16_t multistart_offset;	uint16_t wcs2colidt_offset_low;	uint16_t wcs2colidt_offset_hi;} coldata_base_t;typedef struct {	uint16_t base_idx;	uint16_t undefined_idx;	uint16_t overrides_offset;	uint16_t multistart_offset;} coldata_der_t;static int init_cur_collate(int der_num, __collate_t *cur_collate){	const uint16_t *__locale_collate_tbl = __locale_mmap->collate_data;	coldata_header_t *cdh;	coldata_base_t *cdb;	coldata_der_t *cdd;	const uint16_t *p;	size_t n;	uint16_t i, w;#ifdef __UCLIBC_MJN3_ONLY__#warning kill of x86-specific asserts#endif#if 0	assert(sizeof(coldata_base_t) == 19*2);	assert(sizeof(coldata_der_t) == 4*2);	assert(sizeof(coldata_header_t) == 8*2);#endif	if (!der_num) { 			/* C locale... special */		cur_collate->num_weights = 0;		return 1;	}	--der_num;	cdh = (coldata_header_t *) __locale_collate_tbl;#ifdef __UCLIBC_MJN3_ONLY__#warning CONSIDER: Should we assert here?#endif#if 0	if (der_num >= cdh->num_der) {		return 0;	}#else	assert((der_num < cdh->num_der));#endif	cdd = (coldata_der_t *)(__locale_collate_tbl							+ (sizeof(coldata_header_t)							   + cdh->num_base * sizeof(coldata_base_t)							   + der_num * sizeof(coldata_der_t)							   )/2 );	cdb = (coldata_base_t *)(__locale_collate_tbl							 + (sizeof(coldata_header_t)								+ cdd->base_idx * sizeof(coldata_base_t)								)/2 );	memcpy(cur_collate, cdb, offsetof(coldata_base_t,index2weight_offset));	cur_collate->undefined_idx = cdd->undefined_idx;	cur_collate->ti_mask = (1 << cur_collate->ti_shift)-1;	cur_collate->ii_mask = (1 << cur_collate->ii_shift)-1;/* 	fflush(stdout); *//* 	fprintf(stderr,"base=%d  num_col_base: %d  %d\n", cdd->base_idx ,cur_collate->num_col_base, cdb->num_col_base); */	n = (sizeof(coldata_header_t) + cdh->num_base * sizeof(coldata_base_t)		 + cdh->num_der * sizeof(coldata_der_t))/2;/* 	fprintf(stderr,"n   = %d\n", n); */	cur_collate->index2weight_tbl = __locale_collate_tbl + n + cdb->index2weight_offset;/* 	fprintf(stderr,"i2w = %d\n", n + cdb->index2weight_offset); */	n += cdh->num_index2weight;	cur_collate->index2ruleidx_tbl = __locale_collate_tbl + n + cdb->index2ruleidx_offset;/* 	fprintf(stderr,"i2r = %d\n", n + cdb->index2ruleidx_offset); */	n += cdh->num_index2ruleidx;	cur_collate->multistart_tbl = __locale_collate_tbl + n + cdd->multistart_offset;/* 	fprintf(stderr,"mts = %d\n", n + cdb->multistart_offset); */	n += cdh->num_multistart;	cur_collate->overrides_tbl = __locale_collate_tbl + n + cdd->overrides_offset;/* 	fprintf(stderr,"ovr = %d\n", n + cdd->overrides_offset); */	n += cdh->num_override;	cur_collate->ruletable = __locale_collate_tbl + n;/* 	fprintf(stderr, "rtb = %d\n", n); */	n += cdh->num_ruletable;	cur_collate->weightstr = __locale_collate_tbl + n;/* 	fprintf(stderr,"wts = %d\n", n); */	n += cdh->num_weightstr;	cur_collate->wcs2colidt_tbl = __locale_collate_tbl + n

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -