mirror of
https://github.com/MariaDB/server.git
synced 2026-04-30 12:15:32 +02:00
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:
commit
2f246d2ff6
54 changed files with 617 additions and 281 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
170
strings/strtod.c
170
strings/strtod.c
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue