| List: | Internals | « Previous MessageNext Message » | |
| From: | joce@presence-pc.com | Date: | April 9 2007 4:25pm |
| Subject: | Re: Review of second patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg" | ||
| View as plain text | |||
Hi, New patch with DBUG_ASSERT uncommented. Jocelyn joce@stripped a écrit : > Hi, > > New patch with fixed indentation. > > Jocelyn > > joce@stripped a écrit : >> Damned I didn't noticed my editor wasn't properly configured and was >> inserting tabs instead of spaces. >> I'll fix it ASAP. >> >> Jocelyn >> >> joce@stripped a écrit : >>> Hi Chad, >>> >>> Here is a new patch which includes some fixes after testing + new >>> test files. >>> It also includes the removal of DBUG functions from decimal.c >>> It passes the mysql-test, and no memory errors are reported by >>> valgrind on the unittest. >>> >>> Makefile.am and decimal-t.c have to be put in a new >>> unittest/strings/ directory. >>> >>> Jocelyn >>> >>> Chad MILLER a écrit : >>>> Hi Jocelyn. >>>> >>>> Great work! It's very close to passing my review. A few concerns: >>>> >>>> >>>> On 26 Mar 2007, at 02:25, Jocelyn Fournier wrote: >>>>> --- mysql-5.2-ref/strings/my_vsnprintf.c 2007-03-02 >>>>> 19:24:42.000000000 +0100 >>>>> +++ mysql-5.2/strings/my_vsnprintf.c 2007-03-26 >>>>> 08:01:55.000000000 +0200 >>>>> @@ -17,6 +17,7 @@ >>>>> #include <m_string.h> >>>>> #include <stdarg.h> >>>>> #include <m_ctype.h> >>>>> +#include <decimal.h> >>>>> >>>>> /* >>>>> Limited snprintf() implementations >>>>> @@ -152,6 +153,34 @@ >>>>> to+= res_length; >>>>> continue; >>>>> } >>>>> + else if (*fmt == 'f') /* Float parameter */ >>>>> + { >>>>> + register double larg; >>>>> + uint res_length, to_length; >>>>> + to_length= (uint) (end-to); >>>>> + decimal_t decimal; fixed patch >>>>> >>>>> + /* decimal buf and len fields must be set before calling >>>>> double2decimal */ >>>>> + /* allocating a buffer of the size of the remaining space >>>>> in "to" buffer */ >>>>> + char* buf1= malloc(sizeof(char)*to_length); >>>> >>>> Use my_malloc() and my_free(), always. >>>> >>>>> + decimal.buf= (void*) buf1; >>>>> + decimal.len= (int) sizeof(buf1)/sizeof(decimal_digit_t); >>>> >>>> Hmm, that division makes me uncomfortable. I need tests before I >>>> trust that. Intuitively, I suspect an off-by-one error. >>>> >>>>> + larg= va_arg(ap, double); >>>>> + /* converting the double format into decimal format */ >>>>> + double2decimal(larg, &decimal); >>>>> + res_length= to_length; >>>>> + /* then converting the decimal into string */ >>>>> + decimal2string(&decimal, to, >>>>> + &res_length, /* max buffer size */ >>>>> + /* will contain the size of the >>>>> result */ >>>>> + length ? length : (width ? (decimal.intg + >>>>> width) : 0), /* precision */ >>>>> + width, /* digits after the mantis */ >>>>> + 0); >>>> >>>> Add a note justifying the two steps -- just a few lines to the >>>> effect of "we want to gain the benefits of WL#2934 when it's >>>> completed." >>>> >>>>> + free(buf1); >>>>> + if (res_length > to_length) >>>>> + break; >>>>> + to+= res_length; >>>>> + continue; >>>>> + } >>>>> else if (*fmt == 'c') /* Character >>>>> parameter */ >>>>> { >>>>> register int larg; >>>>> --- mysql-5.2-ref/unittest/mysys/Makefile.am 2007-03-02 >>>>> 19:24:43.000000000 +0100 >>>>> +++ mysql-5.2/unittest/mysys/Makefile.am 2007-03-23 >>>>> 01:03:41.000000000 +0100 >>>>> @@ -17,9 +17,11 @@ >>>>> AM_CPPFLAGS += -I$(top_srcdir)/include >>>>> -I$(top_srcdir)/unittest/mytap >>>>> >>>>> LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ >>>>> + $(top_builddir)/mysys/libmysys.a \ >>>>> + $(top_builddir)/strings/libmystrings.a \ >>>>> + $(top_builddir)/dbug/libdbug.a \ >>>>> $(top_builddir)/mysys/libmysys.a \ >>>>> - $(top_builddir)/dbug/libdbug.a \ >>>>> - $(top_builddir)/strings/libmystrings.a >>>>> + $(top_builddir)/strings/libmystrings.a >>>>> >>>>> noinst_PROGRAMS = bitmap-t base64-t my_atomic-t >>>> >>>> Yes! You updated files in the unittest directory, but I don't see >>>> a test of the my_snprintf() . Perhaps you added it, but the 'diff' >>>> program omitted it? >>>> >>>> In particular, I'm interested in the results of: >>>> >>>> char foo[20]; >>>> my_snprintf(foo, 10, ">%0f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%.0f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%09.4f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%.1f<", 0.987654321098765432); >>>> my_snprintf(foo, 3, ">%.1f<", 0.987654321098765432); >>>> my_snprintf(foo, 4, ">%.1f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%.3f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%.4f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%+.4f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%+.5f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%.6f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%.7f<", 0.987654321098765432); >>>> my_snprintf(foo, 10, ">%80f<", 0.987654321098765432); >>>> >>>> >>>> Of course the test should fail if any results are not what we >>>> should expect. >>>> >>>> Our test suite runs the programs in the "unittest" directory, but >>>> since I spend most of my time in the 5.0 tree, I don't offhand know >>>> how. You may need to add a reference to it somewhere. I suggest >>>> adding a bogus test and making sure that the normal suite fails and >>>> then adding the real tests and making sure that it passes. >>>> >>>> >>>>> --- mysql-5.2-ref/libmysql/Makefile.shared 2007-03-02 >>>>> 19:24:28.000000000 +0100 >>>>> +++ mysql-5.2/libmysql/Makefile.shared 2007-03-22 >>>>> 23:57:59.000000000 +0100 >>>>> @@ -46,7 +46,7 @@ >>>>> ctype-win1250ch.lo ctype-utf8.lo ctype-extra.lo \ >>>>> ctype-ucs2.lo ctype-gb2312.lo ctype-gbk.lo \ >>>>> ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo \ >>>>> - ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo >>>>> + ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo >>>>> decimal.lo >>>>> >>>>> mystringsextra= strto.c >>>>> dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo >>>>> --- mysql-5.2-ref/libmysql/CMakeLists.txt 2007-03-02 >>>>> 19:24:43.000000000 +0100 >>>>> +++ mysql-5.2/libmysql/CMakeLists.txt 2007-03-22 >>>>> 23:58:47.000000000 +0100 >>>>> @@ -61,7 +61,7 @@ >>>>> ../strings/strmov.c ../strings/strnlen.c >>>>> ../strings/strnmov.c ../strings/strtod.c >>>>> ../strings/strtoll.c ../strings/strtoull.c >>>>> ../strings/strxmov.c ../strings/strxnmov.c >>>>> ../mysys/thr_mutex.c ../mysys/typelib.c >>>>> ../vio/vio.c ../vio/viosocket.c >>>>> - ../vio/viossl.c ../vio/viosslfactories.c >>>>> ../strings/xml.c) >>>>> + ../vio/viossl.c ../vio/viosslfactories.c >>>>> ../strings/xml.c ../strings/decimal.c) >>>>> ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib >>>>> yassl taocrypt) >>>>> TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32) >>>>> >>>>> --- mysql-5.2-ref/regex/Makefile.am 2007-03-02 >>>>> 19:24:43.000000000 +0100 >>>>> +++ mysql-5.2/regex/Makefile.am 2007-03-23 00:47:50.000000000 >>>>> +0100 >>>>> @@ -17,7 +17,7 @@ >>>>> >>>>> INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include >>>>> noinst_LIBRARIES = libregex.a >>>>> -LDADD= libregex.a $(top_builddir)/strings/libmystrings.a >>>>> +LDADD= libregex.a $(top_builddir)/strings/libmystrings.a >>>> >>>> Not a big deal, but avoid changing whitespace at the end, if you can. >>>> >>>>> $(top_builddir)/dbug/libdbug.a $(top_builddir)/mysys/libmysys.a >>>>> $(top_builddir)/strings/libmystrings.a >>>>> noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c >>>>> my_regex.h >>>>> libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c >>>>> reginit.c >>>>> noinst_PROGRAMS = re >>>> >>>> I guess the "status" command is too complex to include in the test >>>> suite. :( If it were in there, we never would have created this >>>> bug! I wonder if the relatively recent "replace-regex" commands >>>> could permit it now. >>>> >>>> - chad >>>> >>>> -- >>>> Chad Miller, Software Developer chad@stripped >>>> MySQL Inc., www.mysql.com >>>> Orlando, Florida, USA 13-20z, UTC-0400 >>>> Office: +1 408 213 6740 sip:6740@stripped >>>> >>>> >> >> > > ------------------------------------------------------------------------ > > --- mysql-5.1-ref/strings/my_vsnprintf.c 2007-01-22 13:10:43.000000000 +0100 > +++ mysql-5.1/strings/my_vsnprintf.c 2007-04-09 18:07:59.000000000 +0200 > @@ -14,9 +14,11 @@ > Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ > > #include <my_global.h> > +#include <my_sys.h> > #include <m_string.h> > #include <stdarg.h> > #include <m_ctype.h> > +#include <decimal.h> > > /* > Limited snprintf() implementations > @@ -33,9 +35,12 @@ > %#[l]d > %#[l]u > %#[l]x > + %#f > %#.#b Local format; note first # is ignored and second is REQUIRED > %#.#s Note first # is ignored > - > + %[+][#][#][.#]f > + > + > RETURN > length of result string > */ > @@ -43,32 +48,38 @@ > int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) > { > char *start=to, *end=to+n-1; > - uint length, width, pre_zero, have_long; > - > + uint width, precision, pre_zero, have_long, expected_size, add_sign= 0; > for (; *fmt ; fmt++) > { > if (*fmt != '%') > { > if (to == end) /* End of buffer */ > - break; > + break; > *to++= *fmt; /* Copy ordinary char */ > continue; > } > fmt++; /* skip '%' */ > - /* Read max fill size (only used with %d and %u) */ > + /* Skip - char, not supported */ > if (*fmt == '-') > fmt++; > - length= width= pre_zero= have_long= 0; > + if (*fmt == '+') > + { > + add_sign= 1; > + fmt++; > + } > + > + precision= width= pre_zero= have_long= 0; > + /* Read max fill size (only used with %d and %u) */ > if (*fmt == '*') > { > fmt++; > - length= va_arg(ap, int); > + width= va_arg(ap, int); > } > else > for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) > { > - length= length * 10 + (uint)(*fmt - '0'); > - if (!length) > + width= width * 10 + (uint)(*fmt - '0'); > + if (!width) > pre_zero= 1; /* first digit was 0 */ > } > if (*fmt == '.') > @@ -77,14 +88,14 @@ > if (*fmt == '*') > { > fmt++; > - width= va_arg(ap, int); > + precision= va_arg(ap, int); > } > else > for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) > - width= width * 10 + (uint)(*fmt - '0'); > + precision= precision * 10 + (uint)(*fmt - '0'); > } > else > - width= ~0; > + precision= ~0; > if (*fmt == 'l') > { > fmt++; > @@ -96,9 +107,9 @@ > uint plen,left_len = (uint)(end-to)+1; > if (!par) par = (char*)"(null)"; > plen = (uint) strlen(par); > - set_if_smaller(plen,width); > + set_if_smaller(plen,precision); > if (left_len <= plen) > - plen = left_len - 1; > + plen = left_len - 1; > to=strnmov(to,par,plen); > continue; > } > @@ -106,10 +117,10 @@ > { > char *par = va_arg(ap, char *); > DBUG_ASSERT(to <= end); > - if (to + abs(width) + 1 > end) > - width= end - to - 1; /* sign doesn't matter */ > - memmove(to, par, abs(width)); > - to+= width; > + if (to + abs(precision) + 1 > end) > + precision= end - to - 1; /* sign doesn't matter */ > + memmove(to, par, abs(precision)); > + to+= precision; > continue; > } > else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */ > @@ -119,8 +130,8 @@ > char *store_start= to, *store_end; > char buff[32]; > > - if ((to_length= (uint) (end-to)) < 16 || length) > - store_start= buff; > + if ((to_length= (uint) (end-to)) < 16 || width) > + store_start= buff; > if (have_long) > larg = va_arg(ap, long); > else > @@ -129,29 +140,100 @@ > else > larg= (long) (uint) va_arg(ap, int); > if (*fmt == 'd') > - store_end= int10_to_str(larg, store_start, -10); > + store_end= int10_to_str(larg, store_start, -10); > else > if (*fmt== 'u') > store_end= int10_to_str(larg, store_start, 10); > else > store_end= int2str(larg, store_start, 16, 0); > if ((res_length= (uint) (store_end - store_start)) > to_length) > - break; /* num doesn't fit in output */ > + break; /* num doesn't fit in output */ > /* If %#d syntax was used, we have to pre-zero/pre-space the string */ > if (store_start == buff) > { > - length= min(length, to_length); > - if (res_length < length) > - { > - uint diff= (length- res_length); > - bfill(to, diff, pre_zero ? '0' : ' '); > - to+= diff; > - } > - bmove(to, store_start, res_length); > + width= min(width, to_length); > + if (res_length < width) > + { > + uint diff= (width- res_length); > + bfill(to, diff, pre_zero ? '0' : ' '); > + to+= diff; > + } > + bmove(to, store_start, res_length); > } > to+= res_length; > continue; > } > + else if (*fmt == 'f') /* Float parameter */ > + { > + register double larg; > + uint res_length, to_length; > + larg= va_arg(ap, double); > + if (add_sign == 1) > + { > + if (larg >= 0.0) > + *to++= '+'; > + } > + to_length= (uint) (end-to); > + /* handle the .0f case */ > + if (precision == 0) > + { > + larg= (double) ceil(larg); > + } > + decimal_t decimal; > + /* decimal buf and len fields must be set before calling double2decimal */ > + /* allocating a buffer of the size of the remaining space in "to" buffer */ > + char* buf1= my_alloca(ceil(sizeof(char)*to_length/sizeof(decimal_digit_t)) > + *sizeof(decimal_digit_t)); > + decimal.buf= (void*) buf1; > + decimal.len= sizeof(buf1)/sizeof(decimal_digit_t); > + /* we are currently implementing %f using combination of > + double2decimal and decimal2double. We could gain the benefits of > + WL#2934 once it's completed */ > + /* converting the double format into decimal format */ > + double2decimal(larg, &decimal); > + res_length= to_length+1; /* res_length include the trailing \0 */ > + /* if no precision is specified, > + set the precision to the number of digit after the mantis */ > + if (precision == (uint) ~0) > + { > + precision= decimal.frac; > + } > + /* width include sign and decimal point */ > + if (precision) > + { > + expected_size= (decimal.intg + test(decimal.frac) > + + decimal.sign + precision); > + } > + else > + { > + expected_size= 0; > + } > + width= width ? width : (precision ? expected_size : 0); > + /* if the width is shorter than the number of characters to be printed, > + no truncation */ > + if (width != 0 && (width < expected_size)) > + { > + width= expected_size; > + } > + /* width value passed to decimal2string should not include sign and > + decimal point */ > + if (width != 0) > + { > + width= width - decimal.sign - test(decimal.frac); > + } > + /* converting the decimal into string */ > + decimal2string(&decimal, to, > + &res_length, /* max buffer size */ > + /* will contain the size of the result */ > + width, /* minimum number of characters to be printed */ > + precision, /* number of digits after the mantis */ > + pre_zero?'0':' ' /* pad with zero if required */); > + my_afree(buf1); > + if (res_length > to_length) > + res_length= to_length; > + to+= res_length; > + continue; > + } > else if (*fmt == 'c') /* Character parameter */ > { > register int larg; > --- mysql-5.1-ref/libmysql/Makefile.shared 2007-04-02 10:37:24.000000000 +0200 > +++ mysql-5.1/libmysql/Makefile.shared 2007-04-08 01:16:41.000000000 +0200 > @@ -46,7 +46,7 @@ > ctype-win1250ch.lo ctype-utf8.lo ctype-extra.lo \ > ctype-ucs2.lo ctype-gb2312.lo ctype-gbk.lo \ > ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo \ > - ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo > + ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo decimal.lo > > mystringsextra= strto.c > dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo > --- mysql-5.1-ref/libmysql/CMakeLists.txt 2007-04-02 10:37:32.000000000 +0200 > +++ mysql-5.1/libmysql/CMakeLists.txt 2007-04-08 01:17:52.000000000 +0200 > @@ -61,7 +61,7 @@ > ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c > ../strings/strtod.c > ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c > ../strings/strxnmov.c > ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c > ../vio/viosocket.c > - ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c) > + ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c > ../strings/decimal.c) > ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt) > TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32) > > --- mysql-5.1-ref/strings/decimal.c 2007-02-23 12:23:43.000000000 +0100 > +++ mysql-5.1/strings/decimal.c 2007-04-09 18:06:48.000000000 +0200 > @@ -145,10 +145,10 @@ > }; > > #ifdef HAVE_purify > -#define sanity(d) DBUG_ASSERT((d)->len > 0) > +#define sanity(d) /* DBUG_ASSERT((d)->len > 0) */ > #else > -#define sanity(d) DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \ > - (d)->buf[(d)->len-1] | 1)) > +#define sanity(d) /* DBUG_ASSERT((d)->len >0 && ((d)->buf[0] | \ > + (d)->buf[(d)->len-1] | 1)) */ > #endif > > #define FIX_INTG_FRAC_ERROR(len, intg1, frac1, error) \ > @@ -233,7 +233,7 @@ > { > int intpart; > dec1 *buf= to->buf; > - DBUG_ASSERT(precision && precision >= frac); > + /* DBUG_ASSERT(precision && precision >= frac); */ > > to->sign= 0; > if ((intpart= to->intg= (precision - frac))) > @@ -270,7 +270,7 @@ > if (intg > 0) > { > for (i= (intg - 1) % DIG_PER_DEC1; *buf0 < powers10[i--]; intg--) ; > - DBUG_ASSERT(intg > 0); > + /* DBUG_ASSERT(intg > 0); */ > } > else > intg=0; > @@ -346,7 +346,7 @@ > char *s=to; > dec1 *buf, *buf0=from->buf, tmp; > > - DBUG_ASSERT(*to_len >= 2+from->sign); > + /* DBUG_ASSERT(*to_len >= 2+from->sign); */ > > /* removing leading zeroes */ > buf0= remove_leading_zeroes(from, &intg); > @@ -374,18 +374,28 @@ > intg= fixed_intg; > } > } > - else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */ > + /* len and *to_len both takes into account \0 */ > + if (unlikely(len > *to_len)) > { > int j= len-*to_len; > error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW; > if (frac && j >= frac + 1) j--; > if (j > frac) > { > - intg-= j-frac; > - frac= 0; > + if (intg > (j-frac)) > + { > + intg-= j-frac; > + frac= 0; > + } > + else > + { > + intg= 0; > + intg_len= *to_len - from->sign + 1; > + frac= 0; > + } > } > else > - frac-=j; > + frac-= j; > len= from->sign + intg_len + test(frac) + frac_len; > } > *to_len=len; > @@ -524,8 +534,8 @@ > dec1 *from= dec->buf + ROUND_UP(beg + 1) - 1; > dec1 *end= dec->buf + ROUND_UP(last) - 1; > int c_shift= DIG_PER_DEC1 - shift; > - DBUG_ASSERT(from >= dec->buf); > - DBUG_ASSERT(end < dec->buf + dec->len); > + /* DBUG_ASSERT(from >= dec->buf); */ > + /* DBUG_ASSERT(end < dec->buf + dec->len); */ > if (beg % DIG_PER_DEC1 < shift) > *(from - 1)= (*from) / powers10[c_shift]; > for(; from < end; from++) > @@ -554,8 +564,8 @@ > dec1 *from= dec->buf + ROUND_UP(last) - 1; > dec1 *end= dec->buf + ROUND_UP(beg + 1) - 1; > int c_shift= DIG_PER_DEC1 - shift; > - DBUG_ASSERT(from < dec->buf + dec->len); > - DBUG_ASSERT(end >= dec->buf); > + /* DBUG_ASSERT(from < dec->buf + dec->len); */ > + /* DBUG_ASSERT(end >= dec->buf); */ > if (DIG_PER_DEC1 - ((last - 1) % DIG_PER_DEC1 + 1) < shift) > *(from + 1)= (*from % powers10[shift]) * powers10[c_shift]; > for(; from > end; from--) > @@ -663,7 +673,7 @@ > result > */ > do_left= l_mini_shift <= beg; > - DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= > r_mini_shift); > + /* DBUG_ASSERT(do_left || (dec->len * DIG_PER_DEC1 - end) >= > r_mini_shift); */ > } > else > { > @@ -671,7 +681,7 @@ > l_mini_shift= DIG_PER_DEC1 - r_mini_shift; > /* see comment above */ > do_left= !((dec->len * DIG_PER_DEC1 - end) >= r_mini_shift); > - DBUG_ASSERT(!do_left || l_mini_shift <= beg); > + /* DBUG_ASSERT(!do_left || l_mini_shift <= beg); */ > } > if (do_left) > { > @@ -711,8 +721,8 @@ > d_shift= new_front / DIG_PER_DEC1; > to= dec->buf + (ROUND_UP(beg + 1) - 1 - d_shift); > barier= dec->buf + (ROUND_UP(end) - 1 - d_shift); > - DBUG_ASSERT(to >= dec->buf); > - DBUG_ASSERT(barier + d_shift < dec->buf + dec->len); > + /* DBUG_ASSERT(to >= dec->buf); > + DBUG_ASSERT(barier + d_shift < dec->buf + dec->len); */ > for(; to <= barier; to++) > *to= *(to + d_shift); > for(barier+= d_shift; to <= barier; to++) > @@ -725,8 +735,8 @@ > d_shift= (1 - new_front) / DIG_PER_DEC1; > to= dec->buf + ROUND_UP(end) - 1 + d_shift; > barier= dec->buf + ROUND_UP(beg + 1) - 1 + d_shift; > - DBUG_ASSERT(to < dec->buf + dec->len); > - DBUG_ASSERT(barier - d_shift >= dec->buf); > + /* DBUG_ASSERT(to < dec->buf + dec->len); > + DBUG_ASSERT(barier - d_shift >= dec->buf); */ > for(; to >= barier; to--) > *to= *(to - d_shift); > for(barier-= d_shift; to >= barier; to--) > @@ -745,7 +755,7 @@ > */ > beg= ROUND_UP(beg + 1) - 1; > end= ROUND_UP(end) - 1; > - DBUG_ASSERT(new_point >= 0); > + /* DBUG_ASSERT(new_point >= 0); */ > > /* We don't want negative new_point below */ > if (new_point != 0) > @@ -964,14 +974,14 @@ > exp+= DIG_PER_DEC1; > } > > - DBUG_PRINT("info", ("interm.: %f %d %f", result, exp, > - scaler10[exp / 10] * scaler1[exp % 10])); > + /* DBUG_PRINT("info", ("interm.: %f %d %f", result, exp, > + scaler10[exp / 10] * scaler1[exp % 10])); */ > > result/= scaler10[exp / 10] * scaler1[exp % 10]; > > *to= from->sign ? -result : result; > > - DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to)); > + /* DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to)); */ > > return E_DEC_OK; > } > @@ -993,13 +1003,14 @@ > /* TODO: fix it, when we'll have dtoa */ > char buff[400], *end; > int length, res; > - DBUG_ENTER("double2decimal"); > + /* DBUG_ENTER("double2decimal"); */ > length= my_sprintf(buff, (buff, "%.16G", from)); > - DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff)); > + /* DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff)); */ > end= buff+length; > res= string2decimal(buff, to, &end); > - DBUG_PRINT("exit", ("res: %d", res)); > - DBUG_RETURN(res); > + /* DBUG_PRINT("exit", ("res: %d", res)); > + DBUG_RETURN(res); */ > + return res; > } > > > @@ -1258,7 +1269,7 @@ > case 2: mi_int2store(to, x); break; > case 3: mi_int3store(to, x); break; > case 4: mi_int4store(to, x); break; > - default: DBUG_ASSERT(0); > + default: /* DBUG_ASSERT(0) */; > } > to+=i; > } > @@ -1267,7 +1278,7 @@ > for (stop1=buf1+intg1+frac1; buf1 < stop1; to+=sizeof(dec1)) > { > dec1 x=*buf1++ ^ mask; > - DBUG_ASSERT(sizeof(dec1) == 4); > + /* DBUG_ASSERT(sizeof(dec1) == 4); */ > mi_int4store(to, x); > } > > @@ -1286,7 +1297,7 @@ > case 2: mi_int2store(to, x); break; > case 3: mi_int3store(to, x); break; > case 4: mi_int4store(to, x); break; > - default: DBUG_ASSERT(0); > + default: /* DBUG_ASSERT(0) */; > } > to+=i; > } > @@ -1300,7 +1311,7 @@ > orig_to[0]^= 0x80; > > /* Check that we have written the whole decimal and nothing more */ > - DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0); > + /* DBUG_ASSERT(to == orig_to + orig_fsize0 + orig_isize0); */ > return error; > } > > @@ -1369,7 +1380,7 @@ > case 2: x=mi_sint2korr(from); break; > case 3: x=mi_sint3korr(from); break; > case 4: x=mi_sint4korr(from); break; > - default: DBUG_ASSERT(0); > + default: /* DBUG_ASSERT(0) */; > } > from+=i; > *buf=x ^ mask; > @@ -1382,7 +1393,7 @@ > } > for (stop=from+intg0*sizeof(dec1); from < stop; from+=sizeof(dec1)) > { > - DBUG_ASSERT(sizeof(dec1) == 4); > + /* DBUG_ASSERT(sizeof(dec1) == 4); */ > *buf=mi_sint4korr(from) ^ mask; > if (((uint32)*buf) > DIG_MAX) > goto err; > @@ -1391,10 +1402,10 @@ > else > to->intg-=DIG_PER_DEC1; > } > - DBUG_ASSERT(to->intg >=0); > + /* DBUG_ASSERT(to->intg >=0); */ > for (stop=from+frac0*sizeof(dec1); from < stop; from+=sizeof(dec1)) > { > - DBUG_ASSERT(sizeof(dec1) == 4); > + /* DBUG_ASSERT(sizeof(dec1) == 4); */ > *buf=mi_sint4korr(from) ^ mask; > if (((uint32)*buf) > DIG_MAX) > goto err; > @@ -1411,7 +1422,7 @@ > case 2: x=mi_sint2korr(from); break; > case 3: x=mi_sint3korr(from); break; > case 4: x=mi_sint4korr(from); break; > - default: DBUG_ASSERT(0); > + default: /* DBUG_ASSERT(0) */; > } > *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x]; > if (((uint32)*buf) > DIG_MAX) > @@ -1437,7 +1448,7 @@ > > int decimal_size(int precision, int scale) > { > - DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= > precision); > + /* DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= > precision); */ > return ROUND_UP(precision-scale)+ROUND_UP(scale); > } > > @@ -1454,7 +1465,7 @@ > intg0=intg/DIG_PER_DEC1, frac0=scale/DIG_PER_DEC1, > intg0x=intg-intg0*DIG_PER_DEC1, frac0x=scale-frac0*DIG_PER_DEC1; > > - DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= > precision); > + /* DBUG_ASSERT(scale >= 0 && precision > 0 && scale <= > precision); */ > return intg0*sizeof(dec1)+dig2bytes[intg0x]+ > frac0*sizeof(dec1)+dig2bytes[frac0x]; > } > @@ -1498,7 +1509,7 @@ > case CEILING: round_digit= from->sign ? 10 : 0; break; > case FLOOR: round_digit= from->sign ? 0 : 10; break; > case TRUNCATE: round_digit=10; break; > - default: DBUG_ASSERT(0); > + default: /* DBUG_ASSERT(0) */; > } > > if (unlikely(frac0+intg0 > len)) > @@ -1546,7 +1557,7 @@ > if (scale == frac0*DIG_PER_DEC1) > { > int do_inc= FALSE; > - DBUG_ASSERT(frac0+intg0 >= 0); > + /* DBUG_ASSERT(frac0+intg0 >= 0); */ > switch (round_digit) { > case 0: > { > @@ -1588,7 +1599,7 @@ > { > /* TODO - fix this code as it won't work for CEILING mode */ > int pos=frac0*DIG_PER_DEC1-scale-1; > - DBUG_ASSERT(frac0+intg0 > 0); > + /* DBUG_ASSERT(frac0+intg0 > 0); */ > x=*buf1 / powers10[pos]; > y=x % 10; > if (y > round_digit || > @@ -1695,7 +1706,7 @@ > ROUND_UP(from1->frac)+ROUND_UP(from2->frac); > case '/': > return > ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param); > - default: DBUG_ASSERT(0); > + default: /* DBUG_ASSERT(0) */; > } > return -1; /* shut up the warning */ > } > @@ -1775,7 +1786,7 @@ > > if (unlikely(carry)) > *--buf0=1; > - DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1); > + /* DBUG_ASSERT(buf0 == to->buf || buf0 == to->buf+1); */ > > return error; > } > @@ -2053,7 +2064,7 @@ > { > dec1 *buf= to->buf; > dec1 *end= to->buf + intg0 + frac0; > - DBUG_ASSERT(buf != end); > + /* DBUG_ASSERT(buf != end); */ > for (;;) > { > if (*buf) > @@ -2121,7 +2132,7 @@ > if (prec2 <= 0) /* short-circuit everything: from2 == 0 */ > return E_DEC_DIV_ZERO; > for (i= (prec2 - 1) % DIG_PER_DEC1; *buf2 < powers10[i--]; prec2--) ; > - DBUG_ASSERT(prec2 > 0); > + /* DBUG_ASSERT(prec2 > 0); */ > > i=((prec1-1) % DIG_PER_DEC1)+1; > while (prec1 > 0 && *buf1 == 0) > @@ -2136,7 +2147,7 @@ > return E_DEC_OK; > } > for (i=(prec1-1) % DIG_PER_DEC1; *buf1 < powers10[i--]; prec1--) ; > - DBUG_ASSERT(prec1 > 0); > + /* DBUG_ASSERT(prec1 > 0); */ > > /* let's fix scale_incr, taking into account frac1,frac2 increase */ > if ((scale_incr-= frac1 - from1->frac + frac2 - from2->frac) < 0) > @@ -2241,13 +2252,13 @@ > guess--; > if (unlikely(start2[1]*guess > (x-guess*start2[0])*DIG_BASE+y)) > guess--; > - DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y); > + /* DBUG_ASSERT(start2[1]*guess <= (x-guess*start2[0])*DIG_BASE+y); */ > } > > /* D4: multiply and subtract */ > buf2=stop2; > buf1=start1+len2; > - DBUG_ASSERT(buf1 < stop1); > + /* DBUG_ASSERT(buf1 < stop1); */ > for (carry=0; buf2 > start2; buf1--) > { > dec1 hi, lo; > @@ -2318,7 +2329,7 @@ > error=E_DEC_OVERFLOW; > goto done; > } > - DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg)); > + /* DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg)); */ > stop1=start1+frac0+intg0; > to->intg=min(intg0*DIG_PER_DEC1, from2->intg); > } > --- mysql-5.1-ref/configure.in 2007-03-28 23:03:31.000000000 +0200 > +++ mysql-5.1/configure.in 2007-04-09 04:00:04.000000000 +0200 > @@ -2547,6 +2547,7 @@ > AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl > unittest/Makefile unittest/mytap/Makefile unittest/mytap/t/Makefile dnl > unittest/mysys/Makefile unittest/examples/Makefile dnl > + unittest/strings/Makefile dnl > strings/Makefile regex/Makefile storage/Makefile dnl > man/Makefile BUILD/Makefile vio/Makefile dnl > libmysql/Makefile client/Makefile dnl > --- mysql-5.1-ref/unittest/Makefile.am 2007-04-02 10:37:21.000000000 +0200 > +++ mysql-5.1/unittest/Makefile.am 2007-04-09 03:57:19.000000000 +0200 > @@ -13,12 +13,12 @@ > # along with this program; if not, write to the Free Software > # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > > -SUBDIRS = mytap . mysys examples > +SUBDIRS = mytap . mysys strings examples > > EXTRA_DIST = unit.pl > CLEANFILES = unit > > -unittests = mytap mysys @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ > +unittests = mytap mysys strings @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ > > test: > perl unit.pl run $(unittests) > > ------------------------------------------------------------------------ > > /* Copyright (C) 2007 MySQL AB > > This program is free software; you can redistribute it and/or > modify it under the terms of the GNU General Public License as > published by the Free Software Foundation; version 2 of the License. > > This program is distributed in the hope that it will be useful, but > WITHOUT ANY WARRANTY; without even the implied warranty of > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > General Public License for more details. > > You should have received a copy of the GNU General Public License > along with this program; if not, write to the Free Software > Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ > > #include <my_global.h> > #include <tap.h> > #include <m_string.h> > > int > main(void) > { > char foo[20]; > my_snprintf(foo, 10, ">%0f<", 0.987654321098765432); > ok(!strcmp(foo,">0.987654"), "foo value is %s, should be >0.987654", foo); > my_snprintf(foo, 10, ">%.0f<", 0.987654321098765432); > ok(!strcmp(foo,">1<"), "foo value is %s, should be >1<", foo); > my_snprintf(foo, 10, ">%09.4f<", 0.987654321098765432); > ok(!strcmp(foo,">0000.987"), "foo value is %s, should be >0000.987", foo); > my_snprintf(foo, 10, ">%9.4f<", 0.987654321098765432); > ok(!strcmp(foo,"> 0.987"), "foo value is %s, should be > 0.987", foo); > my_snprintf(foo, 10, ">%.1f<", 0.987654321098765432); > ok(!strcmp(foo,">0.9<"), "foo value is %s, should be >0.9<", foo); > my_snprintf(foo, 5, ">%.1f<", 0.987654321098765432); > ok(!strcmp(foo,">0.9"), "foo value is %s, should be >0.9", foo); > my_snprintf(foo, 4, ">%.1f<", 0.987654321098765432); > ok(!strcmp(foo,">0."), "foo value is %s, should be >0.", foo); > my_snprintf(foo, 10, ">%.3f<", 0.987654321098765432); > ok(!strcmp(foo,">0.987<"), "foo value is %s, should be >0.987<", foo); > my_snprintf(foo, 10, ">%.4f<", 0.987654321098765432); > ok(!strcmp(foo,">0.9876<"), "foo value is %s, should be >0.9876<", > foo); > my_snprintf(foo, 10, ">%+.4f<", 0.987654321098765432); > ok(!strcmp(foo,">+0.9876<"), "foo value is %s, should be >+0.9876<", > foo); > my_snprintf(foo, 10, ">%+.4f<", -0.987654321098765432); > ok(!strcmp(foo,">-0.9876<"), "foo value is %s, should be >-0.9876<", > foo); > my_snprintf(foo, 10, ">%+.5f<", 0.987654321098765432); > ok(!strcmp(foo,">+0.98765"), "foo value is %s, should be >+0.98765", foo); > my_snprintf(foo, 10, ">%.6f<", 0.987654321098765432); > ok(!strcmp(foo,">0.987654"), "foo value is %s, should be >0.987654", foo); > my_snprintf(foo, 10, ">%.7f<", 0.987654321098765432); > ok(!strcmp(foo,">0.987654"), "foo value is %s, should be >0.987654", foo); > my_snprintf(foo, 10, ">%80f<", 0.987654321098765432); > ok(!strcmp(foo,"> "), "foo value is %s, should be > ", foo); > my_snprintf(foo, 10, ">%.3f<", 10.65464); > ok(!strcmp(foo,">10.654<"), "foo value is %s, should be >10.654", foo); > return exit_status(); > } > > ------------------------------------------------------------------------ > > # Copyright (C) 2006 MySQL AB > # > # This program is free software; you can redistribute it and/or modify > # it under the terms of the GNU General Public License as published by > # the Free Software Foundation; version 2 of the License. > # > # This program is distributed in the hope that it will be useful, > # but WITHOUT ANY WARRANTY; without even the implied warranty of > # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > # GNU General Public License for more details. > # > # You should have received a copy of the GNU General Public License > # along with this program; if not, write to the Free Software > # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > > AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include > AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap > > LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ > $(top_builddir)/mysys/libmysys.a \ > $(top_builddir)/dbug/libdbug.a \ > $(top_builddir)/strings/libmystrings.a > > noinst_PROGRAMS = decimal-t > > > > ------------------------------------------------------------------------ > > > Attachment: [text/x-csrc] decimal-t.c
# Copyright (C) 2006 MySQL AB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/strings/libmystrings.a noinst_PROGRAMS = decimal-t --- mysql-5.1-ref/strings/my_vsnprintf.c 2007-01-22 13:10:43.000000000 +0100 +++ mysql-5.1/strings/my_vsnprintf.c 2007-04-09 18:07:59.000000000 +0200 @@ -14,9 +14,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <my_global.h> +#include <my_sys.h> #include <m_string.h> #include <stdarg.h> #include <m_ctype.h> +#include <decimal.h> /* Limited snprintf() implementations @@ -33,9 +35,12 @@ %#[l]d %#[l]u %#[l]x + %#f %#.#b Local format; note first # is ignored and second is REQUIRED %#.#s Note first # is ignored - + %[+][#][#][.#]f + + RETURN length of result string */ @@ -43,32 +48,38 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) { char *start=to, *end=to+n-1; - uint length, width, pre_zero, have_long; - + uint width, precision, pre_zero, have_long, expected_size, add_sign= 0; for (; *fmt ; fmt++) { if (*fmt != '%') { if (to == end) /* End of buffer */ - break; + break; *to++= *fmt; /* Copy ordinary char */ continue; } fmt++; /* skip '%' */ - /* Read max fill size (only used with %d and %u) */ + /* Skip - char, not supported */ if (*fmt == '-') fmt++; - length= width= pre_zero= have_long= 0; + if (*fmt == '+') + { + add_sign= 1; + fmt++; + } + + precision= width= pre_zero= have_long= 0; + /* Read max fill size (only used with %d and %u) */ if (*fmt == '*') { fmt++; - length= va_arg(ap, int); + width= va_arg(ap, int); } else for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) { - length= length * 10 + (uint)(*fmt - '0'); - if (!length) + width= width * 10 + (uint)(*fmt - '0'); + if (!width) pre_zero= 1; /* first digit was 0 */ } if (*fmt == '.') @@ -77,14 +88,14 @@ if (*fmt == '*') { fmt++; - width= va_arg(ap, int); + precision= va_arg(ap, int); } else for (; my_isdigit(&my_charset_latin1, *fmt); fmt++) - width= width * 10 + (uint)(*fmt - '0'); + precision= precision * 10 + (uint)(*fmt - '0'); } else - width= ~0; + precision= ~0; if (*fmt == 'l') { fmt++; @@ -96,9 +107,9 @@ uint plen,left_len = (uint)(end-to)+1; if (!par) par = (char*)"(null)"; plen = (uint) strlen(par); - set_if_smaller(plen,width); + set_if_smaller(plen,precision); if (left_len <= plen) - plen = left_len - 1; + plen = left_len - 1; to=strnmov(to,par,plen); continue; } @@ -106,10 +117,10 @@ { char *par = va_arg(ap, char *); DBUG_ASSERT(to <= end); - if (to + abs(width) + 1 > end) - width= end - to - 1; /* sign doesn't matter */ - memmove(to, par, abs(width)); - to+= width; + if (to + abs(precision) + 1 > end) + precision= end - to - 1; /* sign doesn't matter */ + memmove(to, par, abs(precision)); + to+= precision; continue; } else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */ @@ -119,8 +130,8 @@ char *store_start= to, *store_end; char buff[32]; - if ((to_length= (uint) (end-to)) < 16 || length) - store_start= buff; + if ((to_length= (uint) (end-to)) < 16 || width) + store_start= buff; if (have_long) larg = va_arg(ap, long); else @@ -129,29 +140,100 @@ else larg= (long) (uint) va_arg(ap, int); if (*fmt == 'd') - store_end= int10_to_str(larg, store_start, -10); + store_end= int10_to_str(larg, store_start, -10); else if (*fmt== 'u') store_end= int10_to_str(larg, store_start, 10); else store_end= int2str(larg, store_start, 16, 0); if ((res_length= (uint) (store_end - store_start)) > to_length) - break; /* num doesn't fit in output */ + break; /* num doesn't fit in output */ /* If %#d syntax was used, we have to pre-zero/pre-space the string */ if (store_start == buff) { - length= min(length, to_length); - if (res_length < length) - { - uint diff= (length- res_length); - bfill(to, diff, pre_zero ? '0' : ' '); - to+= diff; - } - bmove(to, store_start, res_length); + width= min(width, to_length); + if (res_length < width) + { + uint diff= (width- res_length); + bfill(to, diff, pre_zero ? '0' : ' '); + to+= diff; + } + bmove(to, store_start, res_length); } to+= res_length; continue; } + else if (*fmt == 'f') /* Float parameter */ + { + register double larg; + uint res_length, to_length; + larg= va_arg(ap, double); + if (add_sign == 1) + { + if (larg >= 0.0) + *to++= '+'; + } + to_length= (uint) (end-to); + /* handle the .0f case */ + if (precision == 0) + { + larg= (double) ceil(larg); + } + decimal_t decimal; + /* decimal buf and len fields must be set before calling double2decimal */ + /* allocating a buffer of the size of the remaining space in "to" buffer */ + char* buf1= my_alloca(ceil(sizeof(char)*to_length/sizeof(decimal_digit_t)) + *sizeof(decimal_digit_t)); + decimal.buf= (void*) buf1; + decimal.len= sizeof(buf1)/sizeof(decimal_digit_t); + /* we are currently implementing %f using combination of + double2decimal and decimal2double. We could gain the benefits of + WL#2934 once it's completed */ + /* converting the double format into decimal format */ + double2decimal(larg, &decimal); + res_length= to_length+1; /* res_length include the trailing \0 */ + /* if no precision is specified, + set the precision to the number of digit after the mantis */ + if (precision == (uint) ~0) + { + precision= decimal.frac; + } + /* width include sign and decimal point */ + if (precision) + { + expected_size= (decimal.intg + test(decimal.frac) + + decimal.sign + precision); + } + else + { + expected_size= 0; + } + width= width ? width : (precision ? expected_size : 0); + /* if the width is shorter than the number of characters to be printed, + no truncation */ + if (width != 0 && (width < expected_size)) + { + width= expected_size; + } + /* width value passed to decimal2string should not include sign and + decimal point */ + if (width != 0) + { + width= width - decimal.sign - test(decimal.frac); + } + /* converting the decimal into string */ + decimal2string(&decimal, to, + &res_length, /* max buffer size */ + /* will contain the size of the result */ + width, /* minimum number of characters to be printed */ + precision, /* number of digits after the mantis */ + pre_zero?'0':' ' /* pad with zero if required */); + my_afree(buf1); + if (res_length > to_length) + res_length= to_length; + to+= res_length; + continue; + } else if (*fmt == 'c') /* Character parameter */ { register int larg; --- mysql-5.1-ref/libmysql/Makefile.shared 2007-04-02 10:37:24.000000000 +0200 +++ mysql-5.1/libmysql/Makefile.shared 2007-04-08 01:16:41.000000000 +0200 @@ -46,7 +46,7 @@ ctype-win1250ch.lo ctype-utf8.lo ctype-extra.lo \ ctype-ucs2.lo ctype-gb2312.lo ctype-gbk.lo \ ctype-sjis.lo ctype-tis620.lo ctype-ujis.lo \ - ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo + ctype-uca.lo xml.lo my_strtoll10.lo str_alloc.lo decimal.lo mystringsextra= strto.c dbugobjects = dbug.lo # IT IS IN SAFEMALLOC.C sanity.lo --- mysql-5.1-ref/libmysql/CMakeLists.txt 2007-04-02 10:37:32.000000000 +0200 +++ mysql-5.1/libmysql/CMakeLists.txt 2007-04-08 01:17:52.000000000 +0200 @@ -61,7 +61,7 @@ ../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c ../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c ../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c - ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c) + ../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../strings/decimal.c) ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt) TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32) --- mysql-5.1-ref/strings/decimal.c 2007-02-23 12:23:43.000000000 +0100 +++ mysql-5.1/strings/decimal.c 2007-04-09 18:21:21.000000000 +0200 @@ -374,18 +374,28 @@ intg= fixed_intg; } } - else if (unlikely(len > --*to_len)) /* reserve one byte for \0 */ + /* len and *to_len both takes into account \0 */ + if (unlikely(len > *to_len)) { int j= len-*to_len; error= (frac && j <= frac + 1) ? E_DEC_TRUNCATED : E_DEC_OVERFLOW; if (frac && j >= frac + 1) j--; if (j > frac) { - intg-= j-frac; - frac= 0; + if (intg > (j-frac)) + { + intg-= j-frac; + frac= 0; + } + else + { + intg= 0; + intg_len= *to_len - from->sign + 1; + frac= 0; + } } else - frac-=j; + frac-= j; len= from->sign + intg_len + test(frac) + frac_len; } *to_len=len; @@ -964,14 +974,14 @@ exp+= DIG_PER_DEC1; } - DBUG_PRINT("info", ("interm.: %f %d %f", result, exp, - scaler10[exp / 10] * scaler1[exp % 10])); + /* DBUG_PRINT("info", ("interm.: %f %d %f", result, exp, + scaler10[exp / 10] * scaler1[exp % 10])); */ result/= scaler10[exp / 10] * scaler1[exp % 10]; *to= from->sign ? -result : result; - DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to)); + /* DBUG_PRINT("info", ("result: %f (%lx)", *to, *(ulong *)to)); */ return E_DEC_OK; } @@ -993,13 +1003,14 @@ /* TODO: fix it, when we'll have dtoa */ char buff[400], *end; int length, res; - DBUG_ENTER("double2decimal"); + /* DBUG_ENTER("double2decimal"); */ length= my_sprintf(buff, (buff, "%.16G", from)); - DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff)); + /* DBUG_PRINT("info",("from: %g from_as_str: %s", from, buff)); */ end= buff+length; res= string2decimal(buff, to, &end); - DBUG_PRINT("exit", ("res: %d", res)); - DBUG_RETURN(res); + /* DBUG_PRINT("exit", ("res: %d", res)); + DBUG_RETURN(res); */ + return res; } --- mysql-5.1-ref/configure.in 2007-03-28 23:03:31.000000000 +0200 +++ mysql-5.1/configure.in 2007-04-09 04:00:04.000000000 +0200 @@ -2547,6 +2547,7 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl unittest/Makefile unittest/mytap/Makefile unittest/mytap/t/Makefile dnl unittest/mysys/Makefile unittest/examples/Makefile dnl + unittest/strings/Makefile dnl strings/Makefile regex/Makefile storage/Makefile dnl man/Makefile BUILD/Makefile vio/Makefile dnl libmysql/Makefile client/Makefile dnl --- mysql-5.1-ref/unittest/Makefile.am 2007-04-02 10:37:21.000000000 +0200 +++ mysql-5.1/unittest/Makefile.am 2007-04-09 03:57:19.000000000 +0200 @@ -13,12 +13,12 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SUBDIRS = mytap . mysys examples +SUBDIRS = mytap . mysys strings examples EXTRA_DIST = unit.pl CLEANFILES = unit -unittests = mytap mysys @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ +unittests = mytap mysys strings @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ test: perl unit.pl run $(unittests)
