summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrcombs <rcombs@rcombs.me>2020-11-16 15:41:23 -0600
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2020-11-16 15:41:23 -0600
commit11a020c38463b7617f9da2f180a7b30ffca86847 (patch)
tree19ef771d715338d50449feb8d62c283324f28723
parentf6138a72338559c3c2d3535b8a969f9d4124c021 (diff)
downloadgcompat-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.c36
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;
}