📄 c_locale_glibc.c
字号:
/*
* Copyright (c) 1999
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef _POSIX_MAPPED_FILES
# include <sys/mman.h>
#endif
#include <stl/c_locale.h>
#include <limits.h>
#include <wctype.h>
/* #include <libc-lock.h> */
#include <locale.h>
#include <argz.h>
#include "gcc_localeinfo.h"
wint_t btowc(int c);
int wctob (wint_t c);
size_t mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps);
size_t wcrtomb (char *s, wchar_t wc, mbstate_t *ps);
size_t mbrlen (const char* s, size_t n, mbstate_t *ps);
#include <nl_types.h>
void _Locale_init()
{}
void _Locale_final()
{}
typedef struct _Locale_ctype {
const struct locale_data* gcc_data;
const int* __tolower;
const int* __toupper;
_Locale_mask_t* __class;
} L_ctype_t;
typedef struct _Locale_numeric {
const struct locale_data* gcc_data;
} L_numeric_t;
typedef struct _Locale_time {
const struct locale_data* gcc_data;
} L_time_t;
typedef struct _Locale_collate {
const struct locale_data* gcc_data;
} L_collate_t;
typedef struct _Locale_monetary {
const struct locale_data* gcc_data;
} L_monetary_t;
typedef struct _Locale_messages {
const struct locale_data* gcc_data;
} L_messages_t;
struct _Locale_name_hint* _Locale_get_ctype_hint(struct _Locale_ctype* ctype)
{ return 0; }
struct _Locale_name_hint* _Locale_get_numeric_hint(struct _Locale_numeric* numeric)
{ return 0; }
struct _Locale_name_hint* _Locale_get_time_hint(struct _Locale_time* time)
{ return 0; }
struct _Locale_name_hint* _Locale_get_collate_hint(struct _Locale_collate* collate)
{ return 0; }
struct _Locale_name_hint* _Locale_get_monetary_hint(struct _Locale_monetary* monetary)
{ return 0; }
struct _Locale_name_hint* _Locale_get_messages_hint(struct _Locale_messages* messages)
{ return 0; }
static char const*
_Locale_extract_name ( const char *cname, char *into, int category )
{
int i = 0;
const char * end;
if ( cname[0] != '/' )
return strcpy(into, cname); /* simple locale name */
for ( i = 0; i <= category; i ++ ) {
while ( *cname != '\0' && *cname != '/' )
cname++;
if ( *cname == '\0' )
return into;
cname++;
}
if ( *cname == '\0' )
return into;
end = cname;
while ( *end != '\0' && *end != '/' )
end++;
strncpy ( into, cname, end - cname );
into [ end - cname ] = '\0';
return into;
}
char const* _Locale_name(const struct locale_data* gcc_data,
char* buf)
{
if (!(gcc_data && gcc_data->name)) return 0;
strncpy(buf, gcc_data->name, _Locale_MAX_SIMPLE_NAME);
buf [ _Locale_MAX_SIMPLE_NAME - 1 ] = '\0';
return buf;
}
/* calls _nl_find_locale which is a function internal to the glibc
locale implementation that loads locale data in from the data
files. The locale_data struct has information for all categories.
In the following implementation we use a locale_data struct for
each category for simplicity, though there is an obvious waste in
doing that. */
const struct locale_data *
_Find_locale (char *locale_path, size_t locale_path_len,
int category, char **name)
{
return __nl_find_locale(locale_path, locale_path_len, category, name);
}
static void
_Remove_locale (int locale, struct locale_data *data)
{
/* this should eventually call _nl_remove_locale() in glibc 2.1 */
/* _nl_remove_locale( locale, data ); */
}
/* couldn't find where LOCALE_PATH was defined in glibc,
but this is the directory it is defined to -JGS */
#define __LOCALE_PATH "/usr/share/locale"
const struct locale_data*
_Category_create(const char * name, int category)
{
/* JGS, where should this path come from? */
char* locpath_var;
char* locale_path = NULL;
size_t locale_path_len = 0;
locpath_var = __secure_getenv("LOCPATH");
if (locpath_var != NULL && locpath_var[0] != '\0')
if (argz_create_sep (locpath_var, ':',
&locale_path, &locale_path_len) != 0)
return NULL;
if (argz_add_sep (&locale_path, &locale_path_len, __LOCALE_PATH, ':') != 0)
return NULL;
return _Find_locale(locale_path, locale_path_len,
category, (char**)&name);
}
static const char* get_default_locale(char* buf) {
char* lang = getenv("LANG");
if (lang == NULL || lang[0] == '\0') {
buf[0] = '\0';
return NULL;
}
else {
strcpy(buf, lang);
return buf;
}
}
const char* _Locale_ctype_default(char* buf) {
char fullname[_Locale_MAX_COMPOSITE_NAME];
if (get_default_locale(fullname) == NULL)
return NULL;
else
return _Locale_extract_ctype_name(fullname, buf, 0);
}
const char* _Locale_numeric_default(char* buf) {
char fullname[_Locale_MAX_COMPOSITE_NAME];
if (get_default_locale(fullname) == NULL)
return NULL;
else
return _Locale_extract_numeric_name(fullname, buf, 0);
}
const char* _Locale_time_default(char* buf) {
char fullname[_Locale_MAX_COMPOSITE_NAME];
if (get_default_locale(fullname) == NULL)
return NULL;
else
return _Locale_extract_time_name(fullname, buf, 0);
}
const char* _Locale_collate_default(char* buf) {
char fullname[_Locale_MAX_COMPOSITE_NAME];
if (get_default_locale(fullname) == NULL)
return NULL;
else
return _Locale_extract_collate_name(fullname, buf, 0);
}
const char* _Locale_monetary_default(char* buf) {
char fullname[_Locale_MAX_COMPOSITE_NAME];
if (get_default_locale(fullname) == NULL)
return NULL;
else
return _Locale_extract_monetary_name(fullname, buf, 0);
}
const char* _Locale_messages_default(char* buf) {
char fullname[_Locale_MAX_COMPOSITE_NAME];
if (get_default_locale(fullname) == NULL)
return NULL;
else
return _Locale_extract_messages_name(fullname, buf, 0);
}
/****** Numeric Category ******/
void*
_Locale_numeric_create(const char * name, struct _Locale_name_hint* hint) {
L_numeric_t* lnum = (L_numeric_t*)malloc(sizeof(L_numeric_t));
lnum->gcc_data = _Category_create(name, LC_NUMERIC);
return (void*)lnum;
}
char const* _Locale_numeric_name(const void* lnum,
char* buf) {
return _Locale_name(((struct _Locale_ctype*)lnum)->gcc_data, buf);
}
void _Locale_numeric_destroy(void* lnum)
{
_Remove_locale(LC_NUMERIC, (struct locale_data *)((struct _Locale_ctype*)lnum)->gcc_data);
free(lnum);
}
char const* _Locale_extract_numeric_name(const char* cname, char* buf, struct _Locale_name_hint* hint)
{
return _Locale_extract_name(cname, buf, LC_NUMERIC);
}
char _Locale_decimal_point(struct _Locale_numeric* lnum)
{
return lnum->gcc_data->values[_NL_ITEM_INDEX(DECIMAL_POINT)].string[0];
}
char _Locale_thousands_sep(struct _Locale_numeric* lnum)
{
return lnum->gcc_data->values[_NL_ITEM_INDEX(THOUSANDS_SEP)].string[0];
}
const char* _Locale_grouping(struct _Locale_numeric * lnum)
{
return lnum->gcc_data->values[_NL_ITEM_INDEX(GROUPING)].string;
}
/* JGS: gcc/linux does not provide true/false names in their
* locale data files
*/
static const char* __true_name = "true";
static const char* __false_name = "false";
const char * _Locale_true(struct _Locale_numeric *l)
{ return __true_name; }
const char * _Locale_false(struct _Locale_numeric *l)
{ return __false_name; }
/****** Monetary Category ******/
void* _Locale_monetary_create(const char* name, struct _Locale_name_hint* hint) {
L_monetary_t* lmon = (L_monetary_t*)malloc(sizeof(L_monetary_t));
lmon->gcc_data = _Category_create(name, LC_MONETARY);
return lmon;
}
char const* _Locale_monetary_name(const void* lmon,
char* buf) {
return _Locale_name(((struct _Locale_monetary*)lmon)->gcc_data, buf);
}
void _Locale_monetary_destroy(void*lmon) {
_Remove_locale(LC_MONETARY, (struct locale_data *)((struct _Locale_monetary*)lmon)->gcc_data);
free(lmon);
}
char const* _Locale_extract_monetary_name(const char* cname, char* buf, struct _Locale_name_hint* hint) {
return _Locale_extract_name(cname, buf, LC_MONETARY);
}
const char* _Locale_int_curr_symbol(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(INT_CURR_SYMBOL)].string;
}
const char* _Locale_currency_symbol(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(CURRENCY_SYMBOL)].string;
}
char _Locale_mon_decimal_point(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(MON_DECIMAL_POINT)].string[0];
}
char _Locale_mon_thousands_sep(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(MON_THOUSANDS_SEP)].string[0];
}
const char* _Locale_mon_grouping(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(MON_GROUPING)].string;
}
const char* _Locale_positive_sign(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(POSITIVE_SIGN)].string;
}
const char* _Locale_negative_sign(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(NEGATIVE_SIGN)].string;
}
char _Locale_int_frac_digits(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(INT_FRAC_DIGITS)].string[0];
}
char _Locale_frac_digits(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(FRAC_DIGITS)].string[0];
}
int _Locale_p_cs_precedes(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(P_CS_PRECEDES)].word;
}
int _Locale_p_sep_by_space(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(P_SEP_BY_SPACE)].word;
}
int _Locale_p_sign_posn(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(P_SIGN_POSN)].word;
}
int _Locale_n_cs_precedes(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(N_CS_PRECEDES)].word;
}
int _Locale_n_sep_by_space(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(N_SEP_BY_SPACE)].word;
}
int _Locale_n_sign_posn(struct _Locale_monetary* lmon) {
return lmon->gcc_data->values[_NL_ITEM_INDEX(N_SIGN_POSN)].word;
}
/****** Time Category ******/
void* _Locale_time_create(const char * name, struct _Locale_name_hint* hint) {
L_time_t* ltime = (L_time_t*)malloc(sizeof(L_time_t));
ltime->gcc_data = _Category_create(name, LC_TIME);
return ltime;
}
char const* _Locale_time_name(const void* ltime,
char* buf) {
return _Locale_name(((struct _Locale_time*)ltime)->gcc_data, buf);
}
char const* _Locale_extract_time_name(const char* cname, char* buf, struct _Locale_name_hint* hint) {
return _Locale_extract_name(cname, buf, LC_TIME);
}
void _Locale_time_destroy(void* ltime) {
_Remove_locale(LC_TIME, (struct locale_data *)((struct _Locale_time*)ltime)->gcc_data);
free(ltime);
}
const char * _Locale_full_monthname(struct _Locale_time *ltime, int month) {
const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(MON_1)]);
return names[month];
}
const char * _Locale_abbrev_monthname(struct _Locale_time *ltime, int month) {
const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(ABMON_1)]);
return names[month];
}
const char * _Locale_full_dayofweek(struct _Locale_time *ltime, int day) {
const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(DAY_1)]);
return names[day];
}
const char * _Locale_abbrev_dayofweek(struct _Locale_time *ltime, int day) {
const char **names = (const char **)&(ltime->gcc_data->values[_NL_ITEM_INDEX(ABDAY_1)]);
return names[day];
}
const char* _Locale_d_t_fmt(struct _Locale_time* ltime) {
return ltime->gcc_data->values[_NL_ITEM_INDEX(D_T_FMT)].string;
}
const char* _Locale_long_d_t_fmt(struct _Locale_time* ltime) {
return ltime->gcc_data->values[_NL_ITEM_INDEX(D_T_FMT)].string;
}
const char* _Locale_d_fmt(struct _Locale_time* ltime)
{
return ltime->gcc_data->values[_NL_ITEM_INDEX(D_FMT)].string;
}
const char* _Locale_long_d_fmt(struct _Locale_time* ltime)
{
return ltime->gcc_data->values[_NL_ITEM_INDEX(D_FMT)].string;
}
const char* _Locale_t_fmt(struct _Locale_time* ltime) {
return ltime->gcc_data->values[_NL_ITEM_INDEX(T_FMT)].string;
}
const char* _Locale_am_str(struct _Locale_time* ltime) {
return ltime->gcc_data->values[_NL_ITEM_INDEX(AM_STR)].string;
}
const char* _Locale_pm_str(struct _Locale_time* ltime) {
return ltime->gcc_data->values[_NL_ITEM_INDEX(PM_STR)].string;
}
const char* _Locale_t_fmt_ampm(struct _Locale_time* ltime)
{
return ltime->gcc_data->values[_NL_ITEM_INDEX(T_FMT_AMPM)].string;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -