From: Jonathan Cameron <jic23@kernel.org>
To: Rodrigo Alencar via B4 Relay
<devnull+rodrigo.alencar.analog.com@kernel.org>
Cc: rodrigo.alencar@analog.com, linux-kernel@vger.kernel.org,
linux-iio@vger.kernel.org, devicetree@vger.kernel.org,
linux-doc@vger.kernel.org, David Lechner <dlechner@baylibre.com>,
Andy Shevchenko <andy@kernel.org>,
Lars-Peter Clausen <lars@metafoo.de>,
Michael Hennerich <Michael.Hennerich@analog.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Kozlowski <krzk+dt@kernel.org>,
Conor Dooley <conor+dt@kernel.org>,
Jonathan Corbet <corbet@lwn.net>,
Andrew Morton <akpm@linux-foundation.org>,
Petr Mladek <pmladek@suse.com>,
Steven Rostedt <rostedt@goodmis.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Rasmus Villemoes <linux@rasmusvillemoes.dk>,
Sergey Senozhatsky <senozhatsky@chromium.org>,
Shuah Khan <skhan@linuxfoundation.org>,
David Laight <david.laight.linux@gmail.com>
Subject: Re: [PATCH v12 02/11] lib: kstrtox: add kstrtoudec64() and kstrtodec64()
Date: Tue, 12 May 2026 12:39:53 +0100 [thread overview]
Message-ID: <20260512123953.40d80bc9@jic23-huawei> (raw)
In-Reply-To: <20260510-adf41513-iio-driver-v12-2-34af2ed2779f@analog.com>
On Sun, 10 May 2026 13:42:20 +0100
Rodrigo Alencar via B4 Relay <devnull+rodrigo.alencar.analog.com@kernel.org> wrote:
> From: Rodrigo Alencar <rodrigo.alencar@analog.com>
>
> Add helpers that parses decimal numbers into 64-bit number, i.e., decimal
> point numbers with pre-defined scale are parsed into a 64-bit value (fixed
> precision). After the decimal point, digits beyond the specified scale
> are ignored.
>
> Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
Whilst Rodrigo has already replied to say there will be another version
I'd like to request final feedback from those who were involved in the parser
discussions.
They got very involved and I'm far from an expert in the right way to do
this stuff.
I don't think David Laight was +CC so I've added that.
David, Andy - I think you two were most involved in that discussion:
Any objections to the end result?
Thanks,
Jonathan
> ---
> include/linux/kstrtox.h | 3 ++
> lib/kstrtox.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 110 insertions(+)
>
> diff --git a/include/linux/kstrtox.h b/include/linux/kstrtox.h
> index 6ea897222af1..bec2fc17bde0 100644
> --- a/include/linux/kstrtox.h
> +++ b/include/linux/kstrtox.h
> @@ -97,6 +97,9 @@ int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
> int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
> int __must_check kstrtobool(const char *s, bool *res);
>
> +int __must_check kstrtoudec64(const char *s, unsigned int scale, u64 *res);
> +int __must_check kstrtodec64(const char *s, unsigned int scale, s64 *res);
> +
> int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res);
> int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res);
> int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res);
> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
> index 97be2a39f537..da7b5f83a3c5 100644
> --- a/lib/kstrtox.c
> +++ b/lib/kstrtox.c
> @@ -17,6 +17,7 @@
> #include <linux/export.h>
> #include <linux/kstrtox.h>
> #include <linux/math64.h>
> +#include <linux/overflow.h>
> #include <linux/types.h>
> #include <linux/uaccess.h>
>
> @@ -392,6 +393,112 @@ int kstrtobool(const char *s, bool *res)
> }
> EXPORT_SYMBOL(kstrtobool);
>
> +static int _kstrtoudec64(const char *s, unsigned int scale, u64 *res)
> +{
> + u64 _res = 0, _frac = 0;
> + unsigned int rv;
> +
> + if (scale > 19) /* log10(2^64) = 19.26 */
> + return -EINVAL;
> +
> + if (*s != '.') {
> + rv = _parse_integer(s, 10, &_res);
> + if (rv & KSTRTOX_OVERFLOW)
> + return -ERANGE;
> + if (rv == 0)
> + return -EINVAL;
> + s += rv;
> + }
> +
> + if (*s == '.' && scale) {
> + s++; /* skip decimal point */
> + rv = _parse_integer_limit(s, 10, &_frac, scale);
> + if (rv & KSTRTOX_OVERFLOW)
> + return -ERANGE;
> + if (rv == 0)
> + return -EINVAL;
> + s += rv;
> + if (rv < scale)
> + _frac *= int_pow(10, scale - rv);
> + while (isdigit(*s)) /* truncate */
> + s++;
> + }
> +
> + if (*s == '\n')
> + s++;
> + if (*s)
> + return -EINVAL;
> +
> + if (check_mul_overflow(_res, int_pow(10, scale), &_res) ||
> + check_add_overflow(_res, _frac, &_res))
> + return -ERANGE;
> +
> + *res = _res;
> + return 0;
> +}
> +
> +/**
> + * kstrtoudec64() - Convert a string to an unsigned 64-bit value that represents
> + * a scaled decimal number.
> + * @s: The start of the string. The string must be null-terminated, and may also
> + * include a single newline before its terminating null. The first character
> + * may also be a plus sign, but not a minus sign. Digits beyond the specified
> + * scale are ignored.
> + * @scale: The number of digits to the right of the decimal point. For example,
> + * a scale of 2 would mean the number is represented with two decimal places,
> + * so "123.45" would be represented as 12345.
> + * @res: Where to write the result of the conversion on success.
> + *
> + * Return: 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
> + */
> +noinline
> +int kstrtoudec64(const char *s, unsigned int scale, u64 *res)
> +{
> + if (s[0] == '+')
> + s++;
> + return _kstrtoudec64(s, scale, res);
> +}
> +EXPORT_SYMBOL(kstrtoudec64);
> +
> +/**
> + * kstrtodec64() - Convert a string to a signed 64-bit value that represents a
> + * scaled decimal number.
> + * @s: The start of the string. The string must be null-terminated, and may also
> + * include a single newline before its terminating null. The first character
> + * may also be a plus sign or a minus sign. Digits beyond the specified
> + * scale are ignored.
> + * @scale: The number of digits to the right of the decimal point. For example,
> + * a scale of 5 would mean the number is represented with five decimal places,
> + * so "-3.141592" would be represented as -314159.
> + * @res: Where to write the result of the conversion on success.
> + *
> + * Return: 0 on success, -ERANGE on overflow and -EINVAL on parsing error.
> + */
> +noinline
> +int kstrtodec64(const char *s, unsigned int scale, s64 *res)
> +{
> + u64 tmp;
> + int rv;
> +
> + if (s[0] == '-') {
> + rv = _kstrtoudec64(s + 1, scale, &tmp);
> + if (rv < 0)
> + return rv;
> + if ((s64)-tmp > 0)
> + return -ERANGE;
> + *res = -tmp;
> + } else {
> + rv = kstrtoudec64(s, scale, &tmp);
> + if (rv < 0)
> + return rv;
> + if ((s64)tmp < 0)
> + return -ERANGE;
> + *res = tmp;
> + }
> + return 0;
> +}
> +EXPORT_SYMBOL(kstrtodec64);
> +
> /*
> * Since "base" would be a nonsense argument, this open-codes the
> * _from_user helper instead of using the helper macro below.
>
next prev parent reply other threads:[~2026-05-12 11:40 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-10 12:42 [PATCH v12 00/11] ADF41513/ADF41510 PLL frequency synthesizers Rodrigo Alencar via B4 Relay
2026-05-10 12:42 ` [PATCH v12 01/11] dt-bindings: iio: frequency: add adf41513 Rodrigo Alencar via B4 Relay
2026-05-10 12:42 ` [PATCH v12 02/11] lib: kstrtox: add kstrtoudec64() and kstrtodec64() Rodrigo Alencar via B4 Relay
2026-05-12 11:39 ` Jonathan Cameron [this message]
2026-05-12 11:52 ` Rodrigo Alencar
2026-05-12 13:12 ` Andy Shevchenko
2026-05-12 13:21 ` Rodrigo Alencar
2026-05-12 13:48 ` Andy Shevchenko
2026-05-12 14:12 ` Rodrigo Alencar
2026-05-12 14:43 ` Andy Shevchenko
2026-05-12 15:11 ` Rodrigo Alencar
2026-05-12 15:21 ` Andy Shevchenko
2026-05-12 16:18 ` David Laight
2026-05-12 17:08 ` Andy Shevchenko
2026-05-12 16:35 ` Rodrigo Alencar
2026-05-12 17:13 ` Andy Shevchenko
2026-05-12 17:26 ` Rodrigo Alencar
2026-05-12 17:46 ` Andy Shevchenko
2026-05-12 18:15 ` Rodrigo Alencar
2026-05-12 19:08 ` Andy Shevchenko
2026-05-10 12:42 ` [PATCH v12 03/11] lib: test-kstrtox: tests for kstrtodec64() and kstrtoudec64() Rodrigo Alencar via B4 Relay
2026-05-12 13:51 ` Andy Shevchenko
2026-05-10 12:42 ` [PATCH v12 04/11] lib: math: div64: add div64_s64_rem() Rodrigo Alencar via B4 Relay
2026-05-12 13:50 ` Andy Shevchenko
2026-05-10 12:42 ` [PATCH v12 05/11] iio: core: add decimal value formatting into 64-bit value Rodrigo Alencar via B4 Relay
2026-05-12 14:35 ` Andy Shevchenko
2026-05-12 16:09 ` Rodrigo Alencar
2026-05-12 17:49 ` Andy Shevchenko
2026-05-12 19:01 ` Rodrigo Alencar
2026-05-10 12:42 ` [PATCH v12 06/11] iio: test: iio-test-format: add test case for decimal format Rodrigo Alencar via B4 Relay
2026-05-12 14:36 ` Andy Shevchenko
2026-05-12 17:02 ` Rodrigo Alencar
2026-05-12 17:51 ` Andy Shevchenko
2026-05-10 12:42 ` [PATCH v12 07/11] iio: frequency: adf41513: driver implementation Rodrigo Alencar via B4 Relay
2026-05-10 12:42 ` [PATCH v12 08/11] iio: frequency: adf41513: handle LE synchronization feature Rodrigo Alencar via B4 Relay
2026-05-10 12:42 ` [PATCH v12 09/11] iio: frequency: adf41513: features on frequency change Rodrigo Alencar via B4 Relay
2026-05-10 12:42 ` [PATCH v12 10/11] docs: iio: add documentation for adf41513 driver Rodrigo Alencar via B4 Relay
2026-05-10 12:42 ` [PATCH v12 11/11] Documentation: ABI: testing: add common ABI file for iio/frequency Rodrigo Alencar via B4 Relay
2026-05-12 11:36 ` Jonathan Cameron
2026-05-12 11:48 ` [PATCH v12 00/11] ADF41513/ADF41510 PLL frequency synthesizers Jonathan Cameron
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260512123953.40d80bc9@jic23-huawei \
--to=jic23@kernel.org \
--cc=Michael.Hennerich@analog.com \
--cc=akpm@linux-foundation.org \
--cc=andriy.shevchenko@linux.intel.com \
--cc=andy@kernel.org \
--cc=conor+dt@kernel.org \
--cc=corbet@lwn.net \
--cc=david.laight.linux@gmail.com \
--cc=devicetree@vger.kernel.org \
--cc=devnull+rodrigo.alencar.analog.com@kernel.org \
--cc=dlechner@baylibre.com \
--cc=krzk+dt@kernel.org \
--cc=lars@metafoo.de \
--cc=linux-doc@vger.kernel.org \
--cc=linux-iio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=pmladek@suse.com \
--cc=robh@kernel.org \
--cc=rodrigo.alencar@analog.com \
--cc=rostedt@goodmis.org \
--cc=senozhatsky@chromium.org \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox