Re: [PATCH 02/12] libxcmd: add cvt{int, long} to convert strings to int and long

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 6/15/17 3:36 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> 
> Create some helper functions to convert strings to int or long
> in a standard way and work around problems in the C library
> atoi/strtol functions.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>
> ---
>  include/input.h |    8 +++
>  libxcmd/input.c |  134 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 142 insertions(+)
> 
> 
> diff --git a/include/input.h b/include/input.h
> index 82cd2f4..145114b 100644
> --- a/include/input.h
> +++ b/include/input.h
> @@ -28,6 +28,14 @@ extern char	**breakline(char *input, int *count);
>  extern void	doneline(char *input, char **vec);
>  extern char	*fetchline(void);
>  
> +extern int64_t	cvt_s64(char *s, int base);
> +extern int32_t	cvt_s32(char *s, int base);
> +extern int16_t	cvt_s16(char *s, int base);
> +
> +extern uint64_t	cvt_u64(char *s, int base);
> +extern uint32_t	cvt_u32(char *s, int base);
> +extern uint16_t	cvt_u16(char *s, int base);
> +
>  extern size_t numlen(uint64_t val, size_t base);
>  extern long long cvtnum(size_t blocksize, size_t sectorsize, char *s);
>  extern void	cvtstr(double value, char *str, size_t sz);
> diff --git a/libxcmd/input.c b/libxcmd/input.c
> index 9437be3..8dd232c 100644
> --- a/libxcmd/input.c
> +++ b/libxcmd/input.c
> @@ -149,6 +149,140 @@ numlen(
>  	return len == 0 ? 1 : len;
>  }
>  
> +/*
> + * Convert string to int64_t, set errno if the conversion fails or
> + * doesn't fit.  Does not allow unit specifiers.  Sets errno to zero
> + * prior to conversion.
> + */
> +int64_t
> +cvt_s64(
> +	char		*s,
> +	int		base)
> +{
> +	long long	i;
> +	char		*sp;
> +	int		c;

unused var c

> +
> +	errno = 0;
> +	i = strtoll(s, &sp, base);
> +	if (*sp == '\0' && sp != s)
> +		return i;
> +bad:

label bad: defined but not used

> +	errno = -ERANGE;
> +	return INT64_MIN;

Hm, doesn't strtoll return LLONG_MIN or LLONG_MAX for underflows
and overflows?  Do you really want to return MIN even if this /overflowed/?
(Maybe it doesn't matter, gut its a bit of a departure from strtoll semantics)

> +}
> +
> +/*
> + * Convert string to int32_t, set errno if the conversion fails or
> + * doesn't fit.  Does not allow unit specifiers.  Sets errno to zero
> + * prior to conversion.
> + */
> +int32_t
> +cvt_s32(
> +	char		*s,
> +	int		base)
> +{
> +	int64_t		i;
> +
> +	i = cvt_s64(s, base);
> +	if (errno)
> +		return i;
> +	if (i > INT32_MAX || i < INT32_MIN) {
> +		errno = -ERANGE;
> +		return INT32_MIN;

same sort of Q here, wouldn't you want MIN or MAX
for underflow/overflow?  Same below as well for all
signed type conversions.

> +	}
> +	return i;
> +}
> +
> +/*
> + * Convert string to int16_t, set errno if the conversion fails or
> + * doesn't fit.  Does not allow unit specifiers.  Sets errno to zero
> + * prior to conversion.
> + */
> +int16_t
> +cvt_s16(
> +	char		*s,
> +	int		base)
> +{
> +	int64_t		i;
> +
> +	i = cvt_s64(s, base);
> +	if (errno)
> +		return i;
> +	if (i > INT16_MAX || i < INT16_MIN) {
> +		errno = -ERANGE;
> +		return INT16_MIN;
> +	}
> +	return i;
> +}
> +
> +/*
> + * Convert string to uint64_t, set errno if the conversion fails or
> + * doesn't fit.  Does not allow unit specifiers.  Sets errno to zero
> + * prior to conversion.
> + */
> +uint64_t
> +cvt_u64(
> +	char		*s,
> +	int		base)
> +{
> +	long long	i;
> +	char		*sp;
> +	int		c;

unused var c:

> +
> +	errno = 0;
> +	i = strtoll(s, &sp, base);
> +	if (*sp == '\0' && sp != s)
> +		return i;
> +bad:

unused label bad:

> +	errno = -ERANGE;
> +	return UINT64_MAX;
> +}
> +
> +/*
> + * Convert string to uint32_t, set errno if the conversion fails or
> + * doesn't fit.  Does not allow unit specifiers.  Sets errno to zero
> + * prior to conversion.
> + */
> +uint32_t
> +cvt_u32(
> +	char		*s,
> +	int		base)
> +{
> +	uint64_t	i;
> +
> +	i = cvt_u64(s, base);
> +	if (errno)
> +		return i;
> +	if (i > UINT32_MAX) {
> +		errno = -ERANGE;
> +		return UINT32_MAX;
> +	}
> +	return i;
> +}
> +
> +/*
> + * Convert string to uint16_t, set errno if the conversion fails or
> + * doesn't fit.  Does not allow unit specifiers.  Sets errno to zero
> + * prior to conversion.
> + */
> +uint16_t
> +cvt_u16(
> +	char		*s,
> +	int		base)
> +{
> +	uint64_t	i;
> +
> +	i = cvt_u64(s, base);
> +	if (errno)
> +		return i;
> +	if (i > UINT16_MAX) {
> +		errno = -ERANGE;
> +		return UINT16_MAX;
> +	}
> +	return i;
> +}
> +
>  #define EXABYTES(x)	((long long)(x) << 60)
>  #define PETABYTES(x)	((long long)(x) << 50)
>  #define TERABYTES(x)	((long long)(x) << 40)
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux