Verified Commit 11a020c3 authored by rcombs's avatar rcombs Committed by A. Wilcox
Browse files

locale: restructure how newlocale works

Now newlocale calls __newlocale with the returned glibc_locale structure
directly, making it work slightly better with non-"C" locales.
parent f6138a72
......@@ -5,7 +5,7 @@
#include "internal.h"
void *__newlocale(int, const char *, void *);
void __freelocale(void *);
void *__duplocale(void *);
struct glibc_locale {
/* hopefully nobody pokes at this */
......@@ -22,36 +22,30 @@ const unsigned short **__ctype_b_loc(void);
const int32_t **__ctype_tolower_loc(void);
const int32_t **__ctype_toupper_loc(void);
const char *__gcompat_valid_locales[] = {"C", "POSIX"};
#define valid_locale_count sizeof __gcompat_valid_locales / sizeof *__gcompat_valid_locales
bool _is_valid_locale(const char *candidate) {
for(size_t i = 0; i < valid_locale_count; i++) {
if(strcmp(candidate, __gcompat_valid_locales[i]) == 0) return true;
struct glibc_locale *newlocale(int mask, const char *name, locale_t base) {
struct glibc_locale *ret = (void*)base;
if(ret == NULL) {
ret = calloc(1, sizeof(struct glibc_locale));
if(ret == NULL) return NULL;
mask = 0x7fffffff;
}
return false;
}
struct glibc_locale *newlocale(int mask, const char *name, locale_t base) {
GCOMPAT__assert_with_reason(_is_valid_locale(name),
"locale %s not supported\n", name);
struct glibc_locale *ret = malloc(sizeof(struct glibc_locale));
if(ret == NULL) return NULL;
/* relies on sizeof(*locale_t) <= sizeof(ret.__locales) */
__newlocale(mask, name, ret);
ret->__locales[0] = __newlocale(mask, name, base);
for(int l = 1; l < 13; l++) ret->__locales[l] = ret->__locales[0];
ret->__ctype_b = *__ctype_b_loc();
ret->__ctype_tolower = *__ctype_tolower_loc();
ret->__ctype_toupper = *__ctype_toupper_loc();
ret->__names[0] = strdup("C");
ret->__names[0] = "C";
for(int i = 1; i < 13; i++) ret->__names[i] = ret->__names[0];
return ret;
}
void freelocale(struct glibc_locale *loc) {
free(loc->__names[0]);
__freelocale(loc->__locales[0]);
free(loc);
void *duplocale(struct glibc_locale *loc) {
struct glibc_locale *ret = malloc(sizeof *ret);
if(!ret) return NULL;
*ret = *loc;
return ret;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment