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)
Thread
review of patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Chad MILLER20 Mar
  • Re: review of patch for Bug#25615,"Status command doesn't report anymore the Queries per second avg"joce20 Mar
    • Re: review of patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Chad MILLER20 Mar
      • Re: review of patch for Bug#25615, "Status command doesn't reportanymore the Queries per second avg"Jocelyn Fournier25 Mar
        • Re: debugger suggestionsChad MILLER26 Mar
          • Re: debugger suggestionsjoce26 Mar
      • [PATCH] Patch for Bug#25615, "Status command doesn't report anymorethe Queries per second avg"Jocelyn Fournier26 Mar
        • Review of second patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Chad MILLER2 Apr
          • Re: Review of second patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"Baron Schwartz2 Apr
            • Re: Review of second patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Chad MILLER2 Apr
          • Re: Review of second patch for Bug#25615,joce2 Apr
          • Re: Review of second patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Sergei Golubchik2 Apr
            • Re: Review of second patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"joce@presence-pc.com8 Apr
              • Re: Review of second patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Sergei Golubchik9 Apr
          • Re: Review of second patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"joce@presence-pc.com9 Apr
            • Re: Review of second patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"joce@presence-pc.com9 Apr
              • Re: Review of second patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Sergei Golubchik9 Apr
              • Re: Review of second patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"joce@presence-pc.com9 Apr
                • Re: Review of second patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"joce@presence-pc.com9 Apr
                  • Review of fourth patch for Bug#25615, "Status command doesn't report anymore the Queries per second avg"Chad MILLER10 Apr
                    • Re: Review of fourth patch for Bug#25615, "Status command doesn'treport anymore the Queries per second avg"Jocelyn Fournier10 Apr