Messages in this thread Patch in this message | | | Date | Fri, 26 Jun 2020 12:44:42 +0200 | From | Peter Zijlstra <> | Subject | [PATCH] lib: Extend kstrtobool() to accept "true"/"false" |
| |
On Fri, Jun 26, 2020 at 12:22:55PM +0200, Peter Zijlstra wrote:
> > This is too lax - it will be enabled for any !0 value. Please accept > > only 0 and 1. > > kstrtobool() ftw
And looking at that, I find it really strange it does not in fact accept "true" / "false", so how about this?
--- Subject: lib: Extend kstrtobool() to accept "true"/"false"
Extend the strings recognised by kstrtobool() to cover:
- 1/0 - y/n - yes/no (new) - t/f (new) - true/false (new) - on/off
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> --- lib/kstrtox.c | 60 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 15 deletions(-)
diff --git a/lib/kstrtox.c b/lib/kstrtox.c index 1006bf70bf74..b8b950325097 100644 --- a/lib/kstrtox.c +++ b/lib/kstrtox.c @@ -325,9 +325,17 @@ EXPORT_SYMBOL(kstrtos8); * @s: input string * @res: result * - * This routine returns 0 iff the first character is one of 'Yy1Nn0', or - * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value - * pointed to by res is updated upon finding a match. + * This return return 0 on success, otherwise it will return -EINVAL. + * It will accept (case invariant): + * + * - 1/0 + * - y/n + * - yes/no + * - t/f + * - true/false + * - on/off + * + * and set @*res to either true/false respectively. */ int kstrtobool(const char *s, bool *res) { @@ -335,30 +343,52 @@ int kstrtobool(const char *s, bool *res) return -EINVAL; switch (s[0]) { + case 't': + case 'T': + if (!s[1] || !strcasecmp(s, "true")) + goto have_true; + + break; + case 'y': case 'Y': + if (!s[1] || !strcasecmp(s, "yes")) + goto have_true; + + break; + case '1': +have_true: *res = true; return 0; + + case 'f': + case 'F': + if (!s[1] || !strcasecmp(s, "false")) + goto have_false; + + break; case 'n': case 'N': + if (!s[1] || !strcasecmp(s, "no")) + goto have_false; + + break; case '0': +have_false: *res = false; return 0; + case 'o': case 'O': - switch (s[1]) { - case 'n': - case 'N': - *res = true; - return 0; - case 'f': - case 'F': - *res = false; - return 0; - default: - break; - } + if (!strcasecmp(s, "on")) + goto have_true; + + if (!strcasecmp(s, "off")) + goto have_false; + + break; + default: break; }
| |