2024-10-04 21:12:58 -06:00
|
|
|
use bufio;
|
|
|
|
use errors;
|
2024-10-04 21:54:08 -06:00
|
|
|
use fmt;
|
2024-10-04 21:12:58 -06:00
|
|
|
use io;
|
|
|
|
use os;
|
|
|
|
use strings;
|
|
|
|
|
|
|
|
def locale_conf_path = "/etc/locale.conf";
|
|
|
|
|
|
|
|
// Returns the locale to use for character classification and case conversion.
|
|
|
|
// The memory is statically allocated and must not be free'd. It may be
|
2024-10-04 21:17:45 -06:00
|
|
|
// overwritten later, so use [[dup]] to extend its lifetime.
|
2024-10-04 21:12:58 -06:00
|
|
|
export fn get_ctype() locale = get_locale("LC_CTYPE");
|
|
|
|
|
|
|
|
// Returns the locale to use for collation order.
|
|
|
|
// The memory is statically allocated and must not be free'd. It may be
|
2024-10-04 21:17:45 -06:00
|
|
|
// overwritten later, so use [[dup]] to extend its lifetime.
|
2024-10-04 21:12:58 -06:00
|
|
|
export fn get_collate() locale = get_locale("LC_COLLATE");
|
|
|
|
|
|
|
|
// Returns the locale to use for monetary formatting.
|
|
|
|
// The memory is statically allocated and must not be free'd. It may be
|
2024-10-04 21:17:45 -06:00
|
|
|
// overwritten later, so use [[dup]] to extend its lifetime.
|
2024-10-04 21:12:58 -06:00
|
|
|
export fn get_monetary() locale = get_locale("LC_MONETARY");
|
|
|
|
|
|
|
|
// Returns the locale to use for numeric, non-monetary formatting.
|
|
|
|
// The memory is statically allocated and must not be free'd. It may be
|
2024-10-04 21:17:45 -06:00
|
|
|
// overwritten later, so use [[dup]] to extend its lifetime.
|
2024-10-04 21:12:58 -06:00
|
|
|
export fn get_numeric() locale = get_locale("LC_NUMERIC");
|
|
|
|
|
|
|
|
// Returns the locale to use for date and time formats.
|
|
|
|
// The memory is statically allocated and must not be free'd. It may be
|
2024-10-04 21:17:45 -06:00
|
|
|
// overwritten later, so use [[dup]] to extend its lifetime.
|
2024-10-04 21:12:58 -06:00
|
|
|
export fn get_time() locale = get_locale("LC_TIME");
|
|
|
|
|
|
|
|
// Returns the locale to use for formats of informative and diagnostic messages
|
|
|
|
// and interactive responses.
|
|
|
|
// The memory is statically allocated and must not be free'd. It may be
|
2024-10-04 21:17:45 -06:00
|
|
|
// overwritten later, so use [[dup]] to extend its lifetime.
|
2024-10-04 21:12:58 -06:00
|
|
|
export fn get_messages() locale = get_locale("LC_MESSAGES");
|
|
|
|
|
|
|
|
fn get_locale(var: str) locale =
|
2024-10-04 21:57:12 -06:00
|
|
|
match (get_locale_no_fallback("LC_ALL")) {
|
2024-10-04 21:12:58 -06:00
|
|
|
case let local: locale => yield local;
|
|
|
|
case =>
|
2024-10-04 21:57:12 -06:00
|
|
|
yield match (get_locale_no_fallback(var)) {
|
2024-10-04 21:12:58 -06:00
|
|
|
case let local: locale => yield local;
|
2024-10-04 21:57:12 -06:00
|
|
|
case =>
|
|
|
|
yield match (get_locale_no_fallback("LANG")) {
|
|
|
|
case let local: locale => yield local;
|
|
|
|
case => yield c;
|
|
|
|
};
|
2024-10-04 21:12:58 -06:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-10-04 21:25:18 -06:00
|
|
|
fn get_locale_no_fallback(var: str) (locale | errors::invalid) =
|
|
|
|
match (get_env_locale(var)) {
|
|
|
|
case let local: locale => yield local;
|
|
|
|
case => yield (get_locale_conf_entry(var));
|
|
|
|
};
|
|
|
|
|
2024-10-04 21:12:58 -06:00
|
|
|
fn get_env_locale(var: str) (locale | errors::invalid) =
|
|
|
|
match (os::getenv(var)) {
|
2024-10-04 21:17:45 -06:00
|
|
|
case let env: str => return parse(env);
|
2024-10-04 21:12:58 -06:00
|
|
|
case => return errors::invalid;
|
|
|
|
};
|
|
|
|
|
|
|
|
let locale_conf: []str = [];
|
|
|
|
|
|
|
|
@fini fn locale_conf() void = strings::freeall(locale_conf);
|
|
|
|
|
|
|
|
fn get_locale_conf_entry(var: str) (locale | errors::invalid) = {
|
|
|
|
get_locale_conf();
|
|
|
|
for (let entry .. locale_conf) {
|
|
|
|
let (key, value) = strings::cut(entry, "=");
|
2024-10-04 21:17:45 -06:00
|
|
|
if (key == var) return parse(value);
|
2024-10-04 21:12:58 -06:00
|
|
|
};
|
|
|
|
return errors::invalid;
|
|
|
|
};
|
|
|
|
|
|
|
|
fn get_locale_conf() []str = {
|
|
|
|
if (len(locale_conf) != 0) return locale_conf;
|
|
|
|
|
|
|
|
let file = match (os::open(locale_conf_path)) {
|
|
|
|
case let file: io::file => yield file;
|
|
|
|
case => return locale_conf;
|
|
|
|
};
|
2024-10-04 21:54:51 -06:00
|
|
|
defer io::close(file)!;
|
2024-10-04 21:12:58 -06:00
|
|
|
|
|
|
|
let scanner = bufio::newscanner(file);
|
|
|
|
defer bufio::finish(&scanner);
|
|
|
|
|
|
|
|
for (true) {
|
|
|
|
match (bufio::scan_line(&scanner)) {
|
2024-10-04 21:54:08 -06:00
|
|
|
case let line: const str =>
|
|
|
|
append(locale_conf, strings::dup(line));
|
|
|
|
case =>
|
|
|
|
return locale_conf;
|
2024-10-04 21:12:58 -06:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|