Re: [PATCH RFC 3/3] iio: core: use kstrtodec64() to parse fixed-point values

From: Rodrigo Alencar

Date: Fri Oct 02 2026 - 05:29:01 EST


On 01/10/26 22:29, Andy Shevchenko wrote:
> On Thu, Oct 01, 2026 at 12:34:58PM -0300, Rodrigo Alencar via B4 Relay wrote:
>
> > Replace the open-coded __iio_str_to_fixpoint() parser with
> > kstrtodec64(), so sysfs writes of fixed-point values also accept E
> > notation. The scale passed to kstrtodec64() comes from fract_mult, which
> > is a power of ten, 10^n, so ffs(10^n) = n + 1. The fractional part only
> > keeps the sign when the integer part is zero, as before.
> >
> > The dB suffix for scale attributes is now handled by a separate
> > iio_str_to_fixpoint_units() helper. It strips an optional trailing
> > newline and the "dB" or " dB" suffix before parsing.
> >
> > When there is no fractional part (fract_mult == 0, or dec_scale == 0 for
> > 64-bit values), try base-autodetecting kstrtoll() first so hexadecimal
> > and octal input keeps its meaning ("010" is still 8). Fall back to
> > kstrtodec64() on -EINVAL to accept E notation.
> >
> > As a side effect, inputs that used to be rejected for integer-only
> > attributes are now accepted. An invalid octal number such as "08" is
> > parsed as decimal 8, and a fractional value such as "1.5" is truncated
> > to 1, matching how kstrtodec64() drops digits beyond the requested
> > scale.

...

> > +static int iio_str_to_fixpoint_units(const char *str, const char *units,
> > + int fract_mult, int *integer, int *fract)
> > +{
> > + size_t units_len = strlen(units);
> > + size_t num_len = strlen(str);
> > + const char *dec_str = str;
> > + char buf[64];
> > +
> > + if (num_len && str[num_len - 1] == '\n')
> > + num_len--;
> > +
> > + if (num_len > units_len &&
> > + !strncmp(str + num_len - units_len, units, units_len)) {
> > + num_len -= units_len;
> > + if (str[num_len - 1] == ' ')
> > + num_len--;
> > + if (num_len >= sizeof(buf))
> > + return -EINVAL;
> > + memcpy(buf, str, num_len);
> > + buf[num_len] = '\0';
> > + dec_str = buf;
> > + }
> > +
> > + return iio_str_to_fixpoint(dec_str, fract_mult, integer, fract);
> > +}
>
> This won't support cases when we have too many leading 0:s.
> All these functions should also strip leading and unneeded 0:s.

sorry, I messed up when replying to this (doing a proper group reply now).

It does support leading zeros just as kstrtodec64() (there are test cases
for that) does so, but when handling those units in the end the buffer is
being limited to 64, which I think it is enough (19 digits can hold real
decimal value, the rest could be the decimal point, signs, termination char
and leading zeros). In a practical use case, how many leading 0:s you would
expect to be supported?

--
Kind regards,

Rodrigo Alencar