Locale defines its own invalid error

This commit is contained in:
Sasha Koshka 2024-10-12 23:51:52 -04:00
parent 19e6aa5259
commit 8521320a7c
7 changed files with 23 additions and 19 deletions

View File

@ -1,4 +1,4 @@
// Any error which may be returned from a function in this module.
// All errors defined in this module.
export type error = !(
invalid_group_header |
invalid_entry |

View File

@ -109,7 +109,7 @@ fn parse_entry(line: str) ((str, str, (locale::locale | void)) | error) = {
local = match(locale::parse(local_string)) {
case let local: locale::locale => yield local;
case errors::invalid => return invalid_entry;
case locale::invalid => return invalid_entry;
};
};

View File

@ -52,29 +52,29 @@ fn get_locale(var: str) locale =
};
};
fn get_locale_no_fallback(var: str) (locale | errors::invalid) =
fn get_locale_no_fallback(var: str) (locale | invalid) =
match (get_env_locale(var)) {
case let local: locale => yield local;
case => yield (get_locale_conf_entry(var));
};
fn get_env_locale(var: str) (locale | errors::invalid) =
fn get_env_locale(var: str) (locale | invalid) =
match (os::getenv(var)) {
case let env: str => return parse(env);
case => return errors::invalid;
case => return invalid;
};
let locale_conf: []str = [];
@fini fn locale_conf() void = strings::freeall(locale_conf);
fn get_locale_conf_entry(var: str) (locale | errors::invalid) = {
fn get_locale_conf_entry(var: str) (locale | invalid) = {
get_locale_conf();
for (let entry .. locale_conf) {
let (key, value) = strings::cut(entry, "=");
if (key == var) return parse(value);
};
return errors::invalid;
return invalid;
};
fn get_locale_conf() []str = {

View File

@ -1,5 +1,3 @@
use errors;
// 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
// overwritten later, so use [[dup]] to extend its lifetime.

7
locale/error.ha Normal file
View File

@ -0,0 +1,7 @@
// All errors defined in this module.
export type error = !invalid;
// Returned when a malformed locale is encountered.
export type invalid = !void;
export fn strerror(err: error) str = "invalid locale";

View File

@ -21,16 +21,16 @@ export def c = locale {
// 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 [[finish]] should not be used to
// free it.
export fn parse(in: str) (locale | errors::invalid) = {
// returns a [[locale]], or [[invalid]] if the input cannot be parsed. All
// memory is borrowed from the input, so [[finish]] should not be used to free
// it.
export fn parse(in: str) (locale | invalid) = {
let (in, modifier) = strings::rcut(in, "@");
if (strings::compare(in, "") == 0) return void: errors::invalid;
if (strings::compare(in, "") == 0) return void: invalid;
let (in, encoding) = strings::rcut(in, ".");
if (strings::compare(in, "") == 0) return void: errors::invalid;
if (strings::compare(in, "") == 0) return void: invalid;
let (in, country) = strings::rcut(in, "_");
if (strings::compare(in, "") == 0) return void: errors::invalid;
if (strings::compare(in, "") == 0) return void: invalid;
return locale {
lang = in,
country = country,

View File

@ -1,5 +1,4 @@
use fmt;
use errors;
use strings;
@test fn parse_full() void = {
@ -64,8 +63,8 @@ use strings;
@test fn parse_error() void = {
let local = match(parse("_COUNTRY.ENCODING@MODIFIER")) {
case errors::invalid => void;
case => abort("error");
case invalid => void;
case => abort("no error");
};
};