From b604cd380c1a974a736525b6993e9c8a5a6cf95f Mon Sep 17 00:00:00 2001 From: Jakob Kaivo Date: Mon, 3 Jun 2024 14:12:36 -0400 Subject: mark return value as read-only, put all strings in a single page with the struct lconv itself --- src/locale/localeconv.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/locale/localeconv.c b/src/locale/localeconv.c index 9dc79302..146bd484 100644 --- a/src/locale/localeconv.c +++ b/src/locale/localeconv.c @@ -1,18 +1,48 @@ #include +#include #include "_locale.h" #include "_safety.h" +#include "_readonly.h" /** return locale-specific information **/ +#define ROCOPY(__dst, __src, __field, __offset) do { \ + (__dst)->__field = (char*)(__dst) + __offset; \ + strcpy((__dst)->__field, (__src)->__field); \ + __offset += strlen((__dst)->__field) + 1; \ + } while (0) + struct lconv * localeconv(void) { SIGNAL_SAFE(0); + static struct lconv *lc = NULL; + struct lconv *current = &(__get_locale()->lconv); + + if (lc == NULL) { + lc = __readonly(RO_ALLOC, "localeconv"); + } /* RETURN_SUCCESS(a pointer to a filled-in STRUCTDEF(lconv) for the current locale); */ - /* TODO: mark return value read-only */ - return &(__get_locale()->lconv); + + __readonly(RO_UNLOCK, lc); + /* TODO: This assumes all strings fit in a single page */ + (*lc) = (*current); + size_t offset = sizeof(*lc); + ROCOPY(lc, current, decimal_point, offset); + ROCOPY(lc, current, thousands_sep, offset); + ROCOPY(lc, current, grouping, offset); + ROCOPY(lc, current, int_curr_symbol, offset); + ROCOPY(lc, current, currency_symbol, offset); + ROCOPY(lc, current, mon_decimal_point, offset); + ROCOPY(lc, current, mon_thousands_sep, offset); + ROCOPY(lc, current, mon_grouping, offset); + ROCOPY(lc, current, positive_sign, offset); + ROCOPY(lc, current, negative_sign, offset); + __readonly(RO_LOCK, lc); + + return lc; } CHECK_0(struct lconv *, NULL, localeconv) -- cgit v1.2.1