// 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. If no suitable version is found, an // exact match with the C locale will be attempted. If there are none, void will // be returned. 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. // lang_COUNTRY@MODIFIER let lang_country_modifier = local; lang_country_modifier.encoding = ""; match (string_resolve_exact(strin, lang_country_modifier)) { case let result: str => return result; case => void; }; // lang_COUNTRY let lang_country = local; lang_country.modifier = ""; match (string_resolve_exact(strin, lang_country)) { case let result: str => return result; case => void; }; // lang@MODIFIER let lang_modifier = lang_country_modifier; lang_modifier.country = ""; match (string_resolve_exact(strin, lang_modifier)) { case let result: str => return result; case => void; }; // lang let lang = lang_modifier; lang.modifier = ""; match (string_resolve_exact(strin, lang)) { case let result: str => return result; case => void; }; // fallback to c locale match (string_resolve_exact(strin, c)) { case let result: str => return result; case => void; }; return void; }; fn string_resolve_exact(strin: string, local: locale) (str | void) = { for (let pair .. strin) if(equal(pair.0, local)) return pair.1; };