|
|
Message-ID: <20260907024553.GA25922@brightrain.aerifal.cx> Date: Sun, 6 Sep 2026 22:45:53 -0400 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Idiom to replace LCTRANS/gettext approach in locale overhaul I'm working out some of the last details for actually being able to merge the locale overhaul. The big thing we set out to replace was the gettext-style string localization, which did not work for "May", and while inexpensive in the C-locale case, made substitution by a localized string rather slow. In addition, the C-locale message lookup for everything but strerror already was slow (linear search over a multi-string). The new approach performs O(1)-time lookup via the int-keyed multi-level table format, for both the baked-in C-locale strings and localized ones. This has been the plan since near the beginning, but the source-level idiom for the logic hasn't been spelled out til now. The approach I've settled on lets the relevant functions -- strerror, gai_strerror, hstrerror, reg_error, and nl_langinfo -- share all of their core logic in a function which takes the following arguments: - built-in table for the C locale - mmapped table for the requested locale - key for the string requested - fallback key if requested key is not found First, it checks whether the requested key is present in the C locale. This ensures that invalid keys are caught and that a locale file which has new keys for things added in a later libc version don't cause older libc versions to wrongly show those things as present. If the key is found in the C locale, a lookup is performed in the requested locale. If successful, it's used. If not, the value obtained from the C locale is used. If the key is not found in the C locale, the above process is repeated with the fallback key. This makes it so each of the above functions does not need its own independent logic for "unknown error code" or similar. It simply provides the key for the "Unknown error" string (for errno, /4/0/-1) as fallback, and the shared logic handles the rest, including getting the localized version of the fallback if available. In the case of nl_langinfo, where the fallback result should be "" and locales must not be able to override this, we can just pass a key that's not present in the C locale data. This will prevent a localized lookup, and nl_langinfo() can replace the null-pointer result with "" before returning. For strerror with untranslated messages, all of this comes out slightly "worse" than the current implementation in code size and performance, simply because it's generalized and using a portable data format rather than a native array. For the rest, though, it comes out far better than what we have now, and I don't think the difference for strerror is significant.
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.