Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Aug 2010 14:45:29 +0000
From:      mdf@FreeBSD.org
To:        Dag-Erling Smorgrav <des@freebsd.org>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r211304 - head/lib/libutil
Message-ID:  <AANLkTinzsSZnkHWJQoUj5t8os6Lz2uOtSNRb=vPGBpnn@mail.gmail.com>
In-Reply-To: <201008141434.o7EEYaSA030301@svn.freebsd.org>
References:  <201008141434.o7EEYaSA030301@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Aug 14, 2010 at 2:34 PM, Dag-Erling Smorgrav <des@freebsd.org> wrot=
e:
> Author: des
> Date: Sat Aug 14 14:34:36 2010
> New Revision: 211304
> URL: http://svn.freebsd.org/changeset/base/211304
>
> Log:
> =A0Simplify expand_number() by combining the (unrolled) loop with the
> =A0switch. =A0Since expand_number() does not accept negative numbers, swi=
tch
> =A0from int64_t to uint64_t; this makes it easier to check for overflow.
>
> =A0MFC after: =A0 =A03 weeks
>
> Modified:
> =A0head/lib/libutil/expand_number.c
> =A0head/lib/libutil/libutil.h
>
> Modified: head/lib/libutil/expand_number.c
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/lib/libutil/expand_number.c =A0 =A0Sat Aug 14 14:18:02 2010 =A0 =
=A0 =A0 =A0(r211303)
> +++ head/lib/libutil/expand_number.c =A0 =A0Sat Aug 14 14:34:36 2010 =A0 =
=A0 =A0 =A0(r211304)
> @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$");
>
> =A0/*
> =A0* Convert an expression of the following forms to a int64_t.
> - * =A0 =A0 1) A positive decimal number.
> + * =A0 =A0 1) A positive decimal number.
> =A0* =A0 =A0 2) A positive decimal number followed by a 'b' or 'B' (mult =
by 1).
> =A0* =A0 =A0 3) A positive decimal number followed by a 'k' or 'K' (mult =
by 1 << 10).
> =A0* =A0 =A0 4) A positive decimal number followed by a 'm' or 'M' (mult =
by 1 << 20).
> @@ -47,14 +47,12 @@ __FBSDID("$FreeBSD$");
> =A0* =A0 =A0 8) A positive decimal number followed by a 'e' or 'E' (mult =
by 1 << 60).
> =A0*/
> =A0int
> -expand_number(const char *buf, int64_t *num)
> +expand_number(const char *buf, uint64_t *num)
> =A0{
> - =A0 =A0 =A0 static const char unit[] =3D "bkmgtpe";
> - =A0 =A0 =A0 char *endptr, s;
> - =A0 =A0 =A0 int64_t number;
> - =A0 =A0 =A0 int i;
> + =A0 =A0 =A0 uint64_t number;
> + =A0 =A0 =A0 char *endptr;
>
> - =A0 =A0 =A0 number =3D strtoimax(buf, &endptr, 0);
> + =A0 =A0 =A0 number =3D strtoumax(buf, &endptr, 0);
>
> =A0 =A0 =A0 =A0if (endptr =3D=3D buf) {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* No valid digits. */
> @@ -68,15 +66,23 @@ expand_number(const char *buf, int64_t *
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (0);
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 s =3D tolower(*endptr);
> - =A0 =A0 =A0 switch (s) {
> - =A0 =A0 =A0 case 'b':
> - =A0 =A0 =A0 case 'k':
> - =A0 =A0 =A0 case 'm':
> - =A0 =A0 =A0 case 'g':
> - =A0 =A0 =A0 case 't':
> - =A0 =A0 =A0 case 'p':
> +#define SHIFT(n, b) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0\
> + =A0 =A0 =A0 do { if ((n << b) < n) goto overflow; n <<=3D b; } while (0=
)

I think it's possible for the number to overflow but also not shrink.
e.g. 0x12345678T.

Perhaps if (((n << b) >> b) !=3D n) would be better.

Thanks,
matthew

> +
> + =A0 =A0 =A0 switch (tolower((unsigned char)*endptr)) {
> =A0 =A0 =A0 =A0case 'e':
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SHIFT(number, 10);
> + =A0 =A0 =A0 case 'p':
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SHIFT(number, 10);
> + =A0 =A0 =A0 case 't':
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SHIFT(number, 10);
> + =A0 =A0 =A0 case 'g':
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SHIFT(number, 10);
> + =A0 =A0 =A0 case 'm':
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SHIFT(number, 10);
> + =A0 =A0 =A0 case 'k':
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 SHIFT(number, 10);
> + =A0 =A0 =A0 case 'b':
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0break;
> =A0 =A0 =A0 =A0default:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0/* Unrecognized unit. */
> @@ -84,17 +90,11 @@ expand_number(const char *buf, int64_t *
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0return (-1);
> =A0 =A0 =A0 =A0}
>
> - =A0 =A0 =A0 for (i =3D 0; unit[i] !=3D '\0'; i++) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (s =3D=3D unit[i])
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 break;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 if ((number < 0 && (number << 10) > number)=
 ||
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (number >=3D 0 && (number << 10) < =
number)) {
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 errno =3D ERANGE;
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return (-1);
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 }
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 number <<=3D 10;
> - =A0 =A0 =A0 }
> -
> =A0 =A0 =A0 =A0*num =3D number;
> =A0 =A0 =A0 =A0return (0);
> +
> +overflow:
> + =A0 =A0 =A0 /* Overflow */
> + =A0 =A0 =A0 errno =3D ERANGE;
> + =A0 =A0 =A0 return (-1);
> =A0}
>
> Modified: head/lib/libutil/libutil.h
> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D
> --- head/lib/libutil/libutil.h =A0Sat Aug 14 14:18:02 2010 =A0 =A0 =A0 =
=A0(r211303)
> +++ head/lib/libutil/libutil.h =A0Sat Aug 14 14:34:36 2010 =A0 =A0 =A0 =
=A0(r211304)
> @@ -109,7 +109,7 @@ int forkpty(int *_amaster, char *_name,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct termios *_termp, struct wi=
nsize *_winp);
> =A0int =A0 =A0humanize_number(char *_buf, size_t _len, int64_t _number,
> =A0 =A0 =A0 =A0 =A0 =A0const char *_suffix, int _scale, int _flags);
> -int =A0 =A0expand_number(const char *_buf, int64_t *_num);
> +int =A0 =A0expand_number(const char *_buf, uint64_t *_num);
> =A0const char *uu_lockerr(int _uu_lockresult);
> =A0int =A0 =A0uu_lock(const char *_ttyname);
> =A0int =A0 =A0uu_unlock(const char *_ttyname);
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?AANLkTinzsSZnkHWJQoUj5t8os6Lz2uOtSNRb=vPGBpnn>