Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/locale/setrunelocale.c
Show First 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
/* | /* | ||||
* A cached version of the runes for this thread. Used by ctype.h | * A cached version of the runes for this thread. Used by ctype.h | ||||
*/ | */ | ||||
_Thread_local const _RuneLocale *_ThreadRuneLocale; | _Thread_local const _RuneLocale *_ThreadRuneLocale; | ||||
#endif | #endif | ||||
extern int __mb_sb_limit; | extern int __mb_sb_limit; | ||||
extern _RuneLocale *_Read_RuneMagi(FILE *); | extern _RuneLocale *_Read_RuneMagi(const char *); | ||||
static int __setrunelocale(struct xlocale_ctype *l, const char *); | static int __setrunelocale(struct xlocale_ctype *l, const char *); | ||||
#define __collate_substitute_nontrivial (table->__collate_substitute_nontrivial) | |||||
#define __collate_substitute_table_ptr (table->__collate_substitute_table_ptr) | |||||
#define __collate_char_pri_table_ptr (table->__collate_char_pri_table_ptr) | |||||
#define __collate_chain_pri_table (table->__collate_chain_pri_table) | |||||
static void | static void | ||||
destruct_ctype(void *v) | destruct_ctype(void *v) | ||||
{ | { | ||||
struct xlocale_ctype *l = v; | struct xlocale_ctype *l = v; | ||||
if (strcmp(l->runes->__encoding, "EUC") == 0) | |||||
free(l->runes->__variable); | |||||
if (&_DefaultRuneLocale != l->runes) | if (&_DefaultRuneLocale != l->runes) | ||||
free(l->runes); | free(l->runes); | ||||
free(l); | free(l); | ||||
} | } | ||||
const _RuneLocale * | const _RuneLocale * | ||||
__getCurrentRuneLocale(void) | __getCurrentRuneLocale(void) | ||||
{ | { | ||||
return XLOCALE_CTYPE(__get_locale())->runes; | return XLOCALE_CTYPE(__get_locale())->runes; | ||||
} | } | ||||
static void | static void | ||||
free_runes(_RuneLocale *rl) | free_runes(_RuneLocale *rl) | ||||
{ | { | ||||
/* FIXME: The "EUC" check here is a hideous abstraction violation. */ | |||||
if ((rl != &_DefaultRuneLocale) && (rl)) { | if ((rl != &_DefaultRuneLocale) && (rl)) { | ||||
if (strcmp(rl->__encoding, "EUC") == 0) { | |||||
free(rl->__variable); | |||||
} | |||||
free(rl); | free(rl); | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
__setrunelocale(struct xlocale_ctype *l, const char *encoding) | __setrunelocale(struct xlocale_ctype *l, const char *encoding) | ||||
{ | { | ||||
FILE *fp; | |||||
char name[PATH_MAX]; | |||||
_RuneLocale *rl; | _RuneLocale *rl; | ||||
int saverr, ret; | int ret; | ||||
char *path; | |||||
struct xlocale_ctype saved = *l; | struct xlocale_ctype saved = *l; | ||||
/* | /* | ||||
* The "C" and "POSIX" locale are always here. | * The "C" and "POSIX" locale are always here. | ||||
*/ | */ | ||||
if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { | if (strcmp(encoding, "C") == 0 || strcmp(encoding, "POSIX") == 0) { | ||||
free_runes(saved.runes); | free_runes(saved.runes); | ||||
(void) _none_init(l, (_RuneLocale*)&_DefaultRuneLocale); | (void) _none_init(l, (_RuneLocale*)&_DefaultRuneLocale); | ||||
return (0); | return (0); | ||||
} | } | ||||
/* Range checking not needed, encoding length already checked before */ | /* Range checking not needed, encoding length already checked before */ | ||||
(void) strcpy(name, _PathLocale); | asprintf(&path, "%s/%s/LC_CTYPE", _PathLocale, encoding); | ||||
(void) strcat(name, "/"); | if (path == NULL) | ||||
(void) strcat(name, encoding); | return (0); | ||||
(void) strcat(name, "/LC_CTYPE"); | |||||
if ((fp = fopen(name, "re")) == NULL) | if ((rl = _Read_RuneMagi(path)) == NULL) { | ||||
return (errno == 0 ? ENOENT : errno); | free(path); | ||||
errno = EINVAL; | |||||
if ((rl = _Read_RuneMagi(fp)) == NULL) { | return (errno); | ||||
theraven: Same comment here re asprintf() / free(). | |||||
Done Inline ActionsI have addressed both with your suggestion even if I prefer the snprintf version :) bapt: I have addressed both with your suggestion even if I prefer the snprintf version :) | |||||
saverr = (errno == 0 ? EFTYPE : errno); | |||||
(void)fclose(fp); | |||||
return (saverr); | |||||
} | } | ||||
(void)fclose(fp); | free(path); | ||||
l->__mbrtowc = NULL; | l->__mbrtowc = NULL; | ||||
l->__mbsinit = NULL; | l->__mbsinit = NULL; | ||||
l->__mbsnrtowcs = __mbsnrtowcs_std; | l->__mbsnrtowcs = NULL; | ||||
l->__wcrtomb = NULL; | l->__wcrtomb = NULL; | ||||
l->__wcsnrtombs = __wcsnrtombs_std; | l->__wcsnrtombs = NULL; | ||||
rl->__sputrune = NULL; | rl->__sputrune = NULL; | ||||
rl->__sgetrune = NULL; | rl->__sgetrune = NULL; | ||||
if (strcmp(rl->__encoding, "NONE") == 0) | if (strcmp(rl->__encoding, "NONE") == 0) | ||||
ret = _none_init(l, rl); | ret = _none_init(l, rl); | ||||
else if (strcmp(rl->__encoding, "ASCII") == 0) | |||||
ret = _ascii_init(l, rl); | |||||
else if (strcmp(rl->__encoding, "UTF-8") == 0) | else if (strcmp(rl->__encoding, "UTF-8") == 0) | ||||
ret = _UTF8_init(l, rl); | ret = _UTF8_init(l, rl); | ||||
else if (strcmp(rl->__encoding, "EUC") == 0) | else if (strcmp(rl->__encoding, "EUC-CN") == 0) | ||||
ret = _EUC_init(l, rl); | ret = _EUC_CN_init(l, rl); | ||||
else if (strcmp(rl->__encoding, "EUC-JP") == 0) | |||||
ret = _EUC_JP_init(l, rl); | |||||
else if (strcmp(rl->__encoding, "EUC-KR") == 0) | |||||
ret = _EUC_KR_init(l, rl); | |||||
else if (strcmp(rl->__encoding, "EUC-TW") == 0) | |||||
ret = _EUC_TW_init(l, rl); | |||||
else if (strcmp(rl->__encoding, "GB18030") == 0) | else if (strcmp(rl->__encoding, "GB18030") == 0) | ||||
ret = _GB18030_init(l, rl); | ret = _GB18030_init(l, rl); | ||||
else if (strcmp(rl->__encoding, "GB2312") == 0) | else if (strcmp(rl->__encoding, "GB2312") == 0) | ||||
ret = _GB2312_init(l, rl); | ret = _GB2312_init(l, rl); | ||||
else if (strcmp(rl->__encoding, "GBK") == 0) | else if (strcmp(rl->__encoding, "GBK") == 0) | ||||
ret = _GBK_init(l, rl); | ret = _GBK_init(l, rl); | ||||
else if (strcmp(rl->__encoding, "BIG5") == 0) | else if (strcmp(rl->__encoding, "BIG5") == 0) | ||||
ret = _BIG5_init(l, rl); | ret = _BIG5_init(l, rl); | ||||
Show All 40 Lines | if (loc == NULL) { | ||||
_ThreadRuneLocale = 0; | _ThreadRuneLocale = 0; | ||||
} else { | } else { | ||||
_ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes; | _ThreadRuneLocale = XLOCALE_CTYPE(loc)->runes; | ||||
} | } | ||||
} | } | ||||
#endif | #endif | ||||
void * | void * | ||||
__ctype_load(const char *locale, locale_t unused) | __ctype_load(const char *locale, locale_t unused __unused) | ||||
{ | { | ||||
struct xlocale_ctype *l = calloc(sizeof(struct xlocale_ctype), 1); | struct xlocale_ctype *l = calloc(sizeof(struct xlocale_ctype), 1); | ||||
l->header.header.destructor = destruct_ctype; | l->header.header.destructor = destruct_ctype; | ||||
if (__setrunelocale(l, locale)) | if (__setrunelocale(l, locale)) | ||||
{ | { | ||||
free(l); | free(l); | ||||
return NULL; | return NULL; | ||||
} | } | ||||
return l; | return l; | ||||
} | } |
Same comment here re asprintf() / free().