use errors; use fmt; use strings; // A parsed locale name. export type locale = struct { lang: str, country: str, encoding: str, modifier: str, }; // The default locale. Stands for computer, the C language, etc. export def c = locale { lang = "C", ... }; // Parses a [[locale]] name of the form: // // lang_COUNTRY.ENCODING@MODIFIER // // Where _COUNTRY, .ENCODING, and @MODIFIER may be omitted. The function // returns a [[locale]], or [[errors::invalid]] if the input cannot be parsed. // All memory is borrowed from the input, so [[locale_finish]] should not be // used to free it. export fn parse_locale(in: str) (locale | errors::invalid) = { let (in, modifier) = strings::rcut(in, "@"); if (strings::compare(in, "") == 0) return void: errors::invalid; let (in, encoding) = strings::rcut(in, "."); if (strings::compare(in, "") == 0) return void: errors::invalid; let (in, country) = strings::rcut(in, "_"); if (strings::compare(in, "") == 0) return void: errors::invalid; return locale { lang = in, country = country, encoding = encoding, modifier = modifier, }; }; // Formats a [[locale]]. The caller must free the return value. export fn format_locale(local: locale) str = { let output = strings::dup(local.lang); if (strings::compare(local.country, "") != 0) { let new_output = strings::join("_", output, local.country); free(output); output = new_output; }; if (strings::compare(local.encoding, "") != 0) { let new_output = strings::join(".", output, local.encoding); free(output); output = new_output; }; if (strings::compare(local.modifier, "") != 0) { let new_output = strings::join("@", output, local.modifier); free(output); output = new_output; }; return output; }; // Checks if two [[locale]]s are equal. export fn locale_equal(a: locale, b: locale) bool = a.lang == b.lang && a.country == b.country && a.encoding == b.encoding && a.modifier == b.modifier; // Duplicates a [[locale]] structure. Use [[locale_finish]] to get rid of it. export fn locale_dup(local: locale) locale = locale { lang = strings::dup(local.lang), country = strings::dup(local.country), encoding = strings::dup(local.encoding), modifier = strings::dup(local.modifier), }; // Frees memory associated with a [[locale]] structure. export fn locale_finish(local: locale) void = { free(local.lang); free(local.country); free(local.encoding); free(local.modifier); };