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>