diff options
author | rcombs <rcombs@rcombs.me> | 2020-11-16 15:41:23 -0600 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2020-11-16 15:41:23 -0600 |
commit | 11a020c38463b7617f9da2f180a7b30ffca86847 (patch) | |
tree | 19ef771d715338d50449feb8d62c283324f28723 | |
parent | f6138a72338559c3c2d3535b8a969f9d4124c021 (diff) | |
download | gcompat-11a020c38463b7617f9da2f180a7b30ffca86847.tar.gz gcompat-11a020c38463b7617f9da2f180a7b30ffca86847.tar.bz2 gcompat-11a020c38463b7617f9da2f180a7b30ffca86847.tar.xz gcompat-11a020c38463b7617f9da2f180a7b30ffca86847.zip |
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.
-rw-r--r-- | libgcompat/locale.c | 36 |
1 files changed, 15 insertions, 21 deletions
diff --git a/libgcompat/locale.c b/libgcompat/locale.c index 538ece7..46dadf7 100644 --- a/libgcompat/locale.c +++ b/libgcompat/locale.c @@ -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; } |