From 6af621213af253dc0d6531056226245387c2136b Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Mon, 21 Oct 2024 19:21:58 -0400 Subject: [PATCH] locale: Add localized string, untested resolution function --- locale/string.ha | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 locale/string.ha diff --git a/locale/string.ha b/locale/string.ha new file mode 100644 index 0000000..587ffbe --- /dev/null +++ b/locale/string.ha @@ -0,0 +1,59 @@ +// A string localized into multiple locales. +export type string = [](locale, str); + +// Selects the most appropriate localized version of a [[string]] given a +// [[locale]]. The matching algorithm used is the one specified by the +// XDG Desktop Entry Specification, ยง5. Memory is borrowed from the input. +export fn string_resolve(strin: string, local: locale) (str | void) = { + // The matching is done as follows. If LC_MESSAGES is of the form + // lang_COUNTRY.ENCODING@MODIFIER, then it will match a key of the form + // lang_COUNTRY@MODIFIER. If such a key does not exist, it will attempt + // to match lang_COUNTRY followed by lang@MODIFIER. Then, a match + // against lang by itself will be attempted. Finally, if no matching key + // is found the required key without a locale specified is used. The + // encoding from the LC_MESSAGES value is ignored when matching. + // + // If LC_MESSAGES does not have a MODIFIER field, then no key with a + // modifier will be matched. Similarly, if LC_MESSAGES does not have a + // COUNTRY field, then no key with a country specified will be matched. + // If LC_MESSAGES just has a lang field, then it will do a straight + // match to a key with a similar value. + + let lang_country_modifier = local; + lang_country_modifier.encoding = ""; + match (string_resolve_exact(strin, lang_country_modifier)) { + case let index: size => return index; + case => void; + }; + + let lang_country = local; + lang_country.modifier = ""; + match (string_resolve_exact(strin, lang_country)) { + case let index: size => return index; + case => void; + }; + + let lang_modifier = lang_country_modifier; + lang_modifier.country = ""; + match (string_resolve_exact(strin, lang_modifier)) { + case let index: size => return index; + case => void; + }; + + let lang = lang_modifier; + lang.modifier = ""; + match (string_resolve_exact(strin, lang)) { + case let index: size => return index; + case => void; + }; + + return void; +}; + +fn string_resolve_exact(strin: string, local: locale) (size | void) = { + let index = 0z; + for (let pair .. strn) { + if(equal(pair.1, local)) return index; + index += 1; + }; +};