aboutsummaryrefslogtreecommitdiff
path: root/src/stdlib/bools.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdlib/bools.c')
-rw-r--r--src/stdlib/bools.c39
1 files changed, 26 insertions, 13 deletions
diff --git a/src/stdlib/bools.c b/src/stdlib/bools.c
index 66b7e209..85de0621 100644
--- a/src/stdlib/bools.c
+++ b/src/stdlib/bools.c
@@ -22,24 +22,37 @@ PUREFUNC public Text_t Bool$as_text(const void *b, bool colorize, const TypeInfo
return *(Bool_t*)b ? Text("yes") : Text("no");
}
-PUREFUNC public OptionalBool_t Bool$parse(Text_t text)
+static bool try_parse(Text_t text, Text_t target, bool target_value, Text_t *remainder, bool *result)
{
- Text_t lang = Text("C");
- if (Text$equal_ignoring_case(text, Text("yes"), lang)
- || Text$equal_ignoring_case(text, Text("on"), lang)
- || Text$equal_ignoring_case(text, Text("true"), lang)
- || Text$equal_ignoring_case(text, Text("1"), lang)) {
- return yes;
- } else if (Text$equal_ignoring_case(text, Text("no"), lang)
- || Text$equal_ignoring_case(text, Text("off"), lang)
- || Text$equal_ignoring_case(text, Text("false"), lang)
- || Text$equal_ignoring_case(text, Text("0"), lang)) {
- return no;
+ static const Text_t lang = Text("C");
+ if (text.length < target.length) return false;
+ Text_t prefix = Text$to(text, Int$from_int64(target.length));
+ if (Text$equal_ignoring_case(prefix, target, lang)) {
+ if (remainder) *remainder = Text$from(text, Int$from_int64(target.length + 1));
+ else if (text.length > target.length) return false;
+ *result = target_value;
+ return true;
} else {
- return NONE_BOOL;
+ return false;
}
}
+PUREFUNC public OptionalBool_t Bool$parse(Text_t text, Text_t *remainder)
+{
+ bool result;
+ if (try_parse(text, Text("yes"), true, remainder, &result)
+ || try_parse(text, Text("true"), true, remainder, &result)
+ || try_parse(text, Text("on"), true, remainder, &result)
+ || try_parse(text, Text("1"), true, remainder, &result)
+ || try_parse(text, Text("no"), false, remainder, &result)
+ || try_parse(text, Text("false"), false, remainder, &result)
+ || try_parse(text, Text("off"), false, remainder, &result)
+ || try_parse(text, Text("0"), false, remainder, &result))
+ return result;
+ else
+ return NONE_BOOL;
+}
+
static bool Bool$is_none(const void *b, const TypeInfo_t *info)
{
(void)info;