Merge with global tree

BitKeeper/etc/ignore:
  auto-union
Build-tools/Do-compile:
  Auto merged
configure.in:
  Auto merged
innobase/include/row0mysql.h:
  Auto merged
innobase/os/os0file.c:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/r/ctype_latin1_de.result:
  Auto merged
mysql-test/r/ctype_tis620.result:
  Auto merged
mysql-test/r/ctype_ucs.result:
  Auto merged
mysql-test/r/ctype_ujis.result:
  Auto merged
mysql-test/r/ctype_utf8.result:
  Auto merged
mysql-test/r/ps_1general.result:
  Auto merged
mysql-test/r/show_check.result:
  Auto merged
mysql-test/r/type_float.result.es:
  Auto merged
mysql-test/r/type_float.result:
  Auto merged
mysql-test/t/ctype_ucs.test:
  Auto merged
mysql-test/t/ps_1general.test:
  Auto merged
mysql-test/t/show_check.test:
  Auto merged
ndb/src/kernel/vm/Configuration.cpp:
  Auto merged
scripts/mysql_install_db.sh:
  Auto merged
sql/field.cc:
  Auto merged
sql/filesort.cc:
  Auto merged
sql/ha_berkeley.cc:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
strings/ctype-big5.c:
  Auto merged
strings/ctype-bin.c:
  Auto merged
strings/ctype-czech.c:
  Auto merged
strings/ctype-gbk.c:
  Auto merged
strings/ctype-latin1.c:
  Auto merged
strings/ctype-mb.c:
  Auto merged
strings/ctype-simple.c:
  Auto merged
strings/ctype-sjis.c:
  Auto merged
strings/ctype-tis620.c:
  Auto merged
strings/ctype-uca.c:
  Auto merged
strings/ctype-ucs2.c:
  Auto merged
strings/ctype-utf8.c:
  Auto merged
strings/ctype-win1250ch.c:
  Auto merged
sql/sql_show.cc:
  No changes
strings/ctype-cp932.c:
  No changes
support-files/mysql.spec.sh:
  No changes
This commit is contained in:
unknown 2005-01-15 14:39:16 +02:00
commit 2f246d2ff6
54 changed files with 617 additions and 281 deletions

View file

@ -243,9 +243,10 @@ static int my_strnncoll_cp932(CHARSET_INFO *cs __attribute__((unused)),
static int my_strnncollsp_cp932(CHARSET_INFO *cs __attribute__((unused)),
const uchar *a, uint a_length,
const uchar *b, uint b_length,
my_bool diff_end_space __attribute__((unused)))
const uchar *a, uint a_length,
const uchar *b, uint b_length,
my_bool diff_if_only_endspace_difference
__attribute__((unused)))
{
const uchar *a_end= a + a_length;
const uchar *b_end= b + b_length;

View file

@ -791,31 +791,10 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
char *str, uint length,
char **end, int *err)
{
char end_char;
double result;
errno= 0; /* Safety */
/*
The following define is to avoid warnings from valgrind as str[length]
may not be defined (which is not fatal in real life)
*/
#ifdef HAVE_purify
if (length == INT_MAX32)
#else
if (length == INT_MAX32 || str[length] == 0)
#endif
result= my_strtod(str, end);
else
{
end_char= str[length];
str[length]= 0;
result= my_strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
return result;
length= 65535; /* Should be big enough */
*end= str + length;
return my_strtod(str, end, err);
}

View file

@ -926,15 +926,16 @@ bs:
return (negative ? -((longlong) res) : (longlong) res);
}
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length,
char **endptr, int *err)
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
char *nptr, uint length,
char **endptr, int *err)
{
char buf[256];
double res;
register char *b=buf;
register const uchar *s= (const uchar*) nptr;
register const uchar *end;
const uchar *end;
my_wc_t wc;
int cnv;
@ -951,13 +952,10 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
break; /* Can't be part of double */
*b++= (char) wc;
}
*b= 0;
errno= 0;
res=my_strtod(buf, endptr);
*err= errno;
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
*endptr= b;
res= my_strtod(buf, endptr, err);
*endptr= nptr + (uint) (*endptr- buf);
return res;
}

View file

@ -2,7 +2,7 @@
An alternative implementation of "strtod()" that is both
simplier, and thread-safe.
From mit-threads as bundled with MySQL 3.23
Original code from mit-threads as bundled with MySQL 3.23
SQL:2003 specifies a number as
@ -29,6 +29,8 @@
#include "my_base.h" /* Includes errno.h */
#include "m_ctype.h"
#define MAX_DBL_EXP 308
#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
static double scaler10[] = {
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
};
@ -37,89 +39,154 @@ static double scaler1[] = {
};
double my_strtod(const char *str, char **end)
/*
Convert string to double (string doesn't have to be null terminated)
SYNOPSIS
my_strtod()
str String to convert
end_ptr Pointer to pointer that points to end of string
Will be updated to point to end of double.
error Will contain error number in case of error (else 0)
RETURN
value of str as double
*/
double my_strtod(const char *str, char **end_ptr, int *error)
{
double result= 0.0;
int negative, ndigits;
const char *old_str;
uint negative= 0, ndigits, dec_digits= 0, pre_zero, neg_exp= 0;
int exp= 0;
const char *old_str, *end= *end_ptr, *start_of_number;
char next_char;
my_bool overflow=0;
while (my_isspace(&my_charset_latin1, *str))
str++;
*error= 0;
if (str >= end)
goto done;
while (my_isspace(&my_charset_latin1, *str))
{
if (++str == end)
goto done;
}
start_of_number= str;
if ((negative= (*str == '-')) || *str=='+')
str++;
{
if (++str == end)
goto done; /* Could be changed to error */
}
/* Skip pre-zero for easier calculation of overflows */
while (*str == '0')
{
if (++str == end)
goto done;
start_of_number= 0; /* Found digit */
}
old_str= str;
while (my_isdigit (&my_charset_latin1, *str))
while ((next_char= *str) >= '0' && next_char <= '9')
{
result= result*10.0 + (*str - '0');
str++;
}
ndigits= str-old_str;
if (*str == '.')
{
double p10=10;
str++;
old_str= str;
while (my_isdigit (&my_charset_latin1, *str))
result= result*10.0 + (next_char - '0');
if (++str == end)
{
result+= (*str++ - '0')/p10;
p10*=10;
next_char= 0; /* Found end of string */
break;
}
ndigits+= str-old_str;
if (!ndigits) str--;
start_of_number= 0; /* Found digit */
}
if (ndigits && (*str=='e' || *str=='E'))
ndigits= (uint) (str-old_str);
pre_zero= 0;
if (next_char == '.' && str < end-1)
{
double p10= 10;
old_str= ++str;
while (my_isdigit(&my_charset_latin1, (next_char= *str)))
{
result+= (next_char - '0')/p10;
if (!result)
pre_zero++;
else
p10*= 10;
if (++str == end)
{
next_char= 0;
break;
}
}
/* If we found just '+.' or '.' then point at first character */
if (!(dec_digits= (uint) (str-old_str)) && start_of_number)
str= start_of_number; /* Point at '+' or '.' */
}
if ((next_char == 'e' || next_char == 'E') &&
dec_digits + ndigits != 0 && str < end-1)
{
int exp= 0;
int neg= 0;
const char *old_str= str++;
if ((neg= (*str == '-')) || *str == '+')
if ((neg_exp= (*str == '-')) || *str == '+')
str++;
if (!my_isdigit (&my_charset_latin1, *str))
if (str == end || !my_isdigit(&my_charset_latin1, *str))
str= old_str;
else
{
double scaler= 1.0;
while (my_isdigit (&my_charset_latin1, *str))
do
{
if (exp < 9999) /* protection against exp overflow */
if (exp < 9999) /* protec against exp overfl. */
exp= exp*10 + *str - '0';
str++;
}
if (exp >= 1000)
} while (str < end && my_isdigit(&my_charset_latin1, *str));
}
}
if ((exp= neg_exp ? exp + pre_zero : exp - pre_zero))
{
double scaler;
if (exp < 0)
{
exp= -exp;
neg_exp= 1; /* neg_exp was 0 before */
}
if (exp + ndigits >= MAX_DBL_EXP + 1 && result)
{
/*
This is not 100 % as we actually will give an owerflow for
17E307 but not for 1.7E308 but lets cut some corners to make life
simpler
*/
if (exp + ndigits > MAX_DBL_EXP + 1 ||
result >= MAX_RESULT_FOR_MAX_EXP)
{
if (neg)
result= 0.0;
else
if (neg_exp)
result= 0.0;
else
overflow= 1;
goto done;
}
while (exp >= 100)
{
scaler*= 1.0e100;
exp-= 100;
}
scaler*= scaler10[exp/10]*scaler1[exp%10];
if (neg)
result/= scaler;
else
result*= scaler;
}
scaler= 1.0;
while (exp >= 100)
{
scaler*= 1.0e100;
exp-= 100;
}
scaler*= scaler10[exp/10]*scaler1[exp%10];
if (neg_exp)
result/= scaler;
else
result*= scaler;
}
done:
if (end)
*end = (char *)str;
*end_ptr= (char*) str; /* end of number */
if (overflow || isinf(result))
{
result= DBL_MAX;
errno= EOVERFLOW;
*error= EOVERFLOW;
}
return negative ? -result : result;
@ -127,6 +194,7 @@ done:
double my_atof(const char *nptr)
{
return (my_strtod(nptr, 0));
int error;
const char *end= nptr+65535; /* Should be enough */
return (my_strtod(nptr, (char**) &end, &error));
}