Commit 5914e570 authored by serg@serg.mylan's avatar serg@serg.mylan

my_atof is deleted

strtod from mit-threads is restored and cleaned up
parent 67fbc4d2
......@@ -1825,7 +1825,7 @@ AC_CHECK_FUNCS(alarm bmove \
strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \
gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror \
tell atod memcpy memmove \
tell isinf memcpy memmove \
setupterm strcasecmp sighold vidattr lrand48 localtime_r gmtime_r \
sigset sigthreadmask pthread_sigmask pthread_setprio pthread_setprio_np \
pthread_setschedparam pthread_attr_setprio pthread_attr_setschedparam \
......
......@@ -215,7 +215,9 @@ extern char *strstr(const char *, const char *);
#endif
extern int is_prefix(const char *, const char *);
/* Conversion rutins */
/* Conversion routines */
double my_strtod(const char *str, char **end);
double my_atof(const char *nptr);
#ifdef USE_MY_ITOA
extern char *my_itoa(int val,char *dst,int radix);
......
......@@ -522,7 +522,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_EXTCHAR '.'
#define FN_HOMELIB '~' /* ~/ is used as abbrev for home dir */
#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
#define FN_PARENTDIR ".." /* Parentdirectory; Must be a string */
#define FN_PARENTDIR ".." /* Parent directory; Must be a string */
#define FN_DEVCHAR ':'
#ifndef FN_LIBCHAR
......@@ -581,14 +581,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Some defines of functions for portability */
#ifndef HAVE_ATOD
#define atod atof
#endif
#ifdef USE_MY_ATOF
#define atof my_atof
extern void init_my_atof(void);
extern double my_atof(const char*);
#endif
#undef remove /* Crashes MySQL on SCO 5.0.0 */
#ifndef __WIN__
#ifdef OS2
......@@ -677,6 +669,10 @@ extern double my_atof(const char*);
#define FLT_MAX ((float)3.40282346638528860e+38)
#endif
#ifndef HAVE_ISINF
#define isinf(X) 0
#endif
/*
Max size that must be added to a so that we know Size to make
adressable obj.
......
......@@ -32,7 +32,7 @@ target_sources = libmysql.c password.c manager.c \
get_password.c errmsg.c
mystringsobjects = strmov.lo strxmov.lo strxnmov.lo strnmov.lo \
strmake.lo strend.lo \
strmake.lo strend.lo strtod.lo \
strnlen.lo strfill.lo is_prefix.lo \
int2str.lo str2int.lo strinstr.lo strcont.lo \
strcend.lo bcmp.lo ctype-latin1.lo \
......
......@@ -101,7 +101,7 @@ int GTextReadStream::get_next_number(double *d)
char *endptr;
*d = strtod(cur, &endptr);
*d = my_strtod(cur, &endptr);
if (endptr)
{
......
......@@ -34,9 +34,6 @@ void unireg_init(ulong options)
current_pid=(ulong) getpid(); /* Save for later ref */
init_time(); /* Init time-functions (read zone) */
#ifdef USE_MY_ATOF
init_my_atof(); /* use our atof */
#endif
#ifndef EMBEDDED_LIBRARY
my_abort_hook=unireg_abort; /* Abort with close of databases */
#endif
......
......@@ -441,7 +441,7 @@ class Item_real :public Item
public:
const double value;
// Item_real() :value(0) {}
Item_real(const char *str_arg,uint length) :value(atof(str_arg))
Item_real(const char *str_arg,uint length) :value(my_atof(str_arg))
{
name=(char*) str_arg;
decimals=(uint8) nr_of_decimals(str_arg);
......
......@@ -2255,7 +2255,7 @@ double user_var_entry::val(my_bool *null_value)
case INT_RESULT:
return (double) *(longlong*) value;
case STRING_RESULT:
return atof(value); // This is null terminated
return my_atof(value); // This is null terminated
case ROW_RESULT:
DBUG_ASSERT(1); // Impossible
break;
......
......@@ -747,7 +747,7 @@ class Item_func_group_concat : public Item_sum
double val()
{
String *res; res=val_str(&str_value);
return res ? atof(res->c_ptr()) : 0.0;
return res ? my_atof(res->c_ptr()) : 0.0;
}
longlong val_int()
{
......
......@@ -225,7 +225,7 @@ bool test_if_number(NUM_INFO *info, const char *str, uint str_len)
info->decimals++;
if (str == end)
{
info->dval = atod(begin);
info->dval = my_atof(begin);
return 1;
}
}
......
......@@ -22,19 +22,19 @@ pkglib_LIBRARIES = libmystrings.a
# Exact one of ASSEMBLER_X
if ASSEMBLER_x86
ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c
CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c
else
if ASSEMBLER_sparc32
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
else
#no assembler
ASRCS =
# These file MUST all be on the same line!! Otherwise automake
# generats a very broken makefile
CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c atof.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c my_strtoll10.c
endif
endif
......
/* Copyright (C) 2000 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; either version 2 of the License, or
(at your option) any later version.
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 */
/*
A quicker atof. About 2-10 times faster than standard atof on sparc.
This don't handle iee-options (NaN...) and the presission :s is a little
less for some high exponential numbers (+-1 at 14th place).
Returns 0.0 if overflow or wrong number.
Must be inited with init_my_atof to handle possibly overflows.
*/
#include <my_global.h>
#ifdef USE_MY_ATOF /* Skipp if we don't want it */
#include <m_ctype.h>
#include <floatingpoint.h>
#include <signal.h>
/* Read a double. If float is wrong return 0.
float ::= [space]* [sign] {digit}+ decimal-point {digit}+ [exponent] |
[sign] {digit}+ [decimal-point {digit}*] exponent |
[sign] {digit}+ decimal-point [{digit}*] exponent |
[sign] decimal-point {digit}* exponent |
exponent :: = exponent-marker [sign] {digit}+
exponent-marker ::= E e
*/
#define is_exponent_marker(ch) (ch == 'E' || ch == 'e')
static void my_atof_overflow _A((int sig,int code, struct sigcontext *scp,
char *addr));
static int parse_sign _A((char **str));
static void parse_float_number_part _A((char **str,double *number, int *length));
static void parse_decimal_number_part _A((char **str,double *number));
static int parse_int_number_part _A((char **str,uint *number));
static int volatile overflow,in_my_atof;
static sigfpe_handler_type old_overflow_handler;
void init_my_atof()
{
old_overflow_handler = (sigfpe_handler_type)
ieee_handler("get", "overflow", old_overflow_handler);
VOID(ieee_handler("set", "overflow", my_atof_overflow));
return;
}
static void my_atof_overflow(sig, code, scp, addr)
int sig;
int code;
struct sigcontext *scp;
char *addr;
{
if (!in_my_atof)
old_overflow_handler(sig,code,scp,addr);
else
overflow=1;
return;
}
double my_atof(src)
const char *src;
{
int sign, exp_sign; /* is number negative (+1) or positive (-1) */
int length_before_point;
double after_point; /* Number after decimal point and before exp */
uint exponent; /* Exponent value */
double exp_log,exp_val;
char *tmp_src;
double result_number;
tmp_src = (char*) src;
while (isspace(tmp_src[0]))
tmp_src++; /* Skipp pre-space */
sign = parse_sign(&tmp_src);
overflow=0;
in_my_atof=1;
parse_float_number_part(&tmp_src, &result_number, &length_before_point);
if (*tmp_src == '.')
{
tmp_src++;
parse_decimal_number_part(&tmp_src, &after_point);
result_number += after_point;
}
else if (length_before_point == 0)
{
in_my_atof=0;
return 0.0;
}
if (is_exponent_marker(*tmp_src))
{
tmp_src++;
exp_sign = parse_sign(&tmp_src);
overflow|=parse_int_number_part(&tmp_src, &exponent);
exp_log=10.0; exp_val=1.0;
for (;;)
{
if (exponent & 1)
{
exp_val*= exp_log;
exponent--;
}
if (!exponent)
break;
exp_log*=exp_log;
exponent>>=1;
}
if (exp_sign < 0)
result_number*=exp_val;
else
result_number/=exp_val;
}
if (sign > 0)
result_number= -result_number;
in_my_atof=0;
if (overflow)
return 0.0;
return result_number;
}
static int parse_sign(str)
char **str;
{
if (**str == '-')
{
(*str)++;
return 1;
}
if (**str == '+')
(*str)++;
return -1;
}
/* Get number with may be separated with ',' */
static void parse_float_number_part(str, number, length)
char **str;
double *number;
int *length;
{
*number = 0;
*length = 0;
for (;;)
{
while (isdigit(**str))
{
(*length)++;
*number = (*number * 10) + (**str - '0');
(*str)++;
}
if (**str != ',')
return; /* Skipp possibly ',' */
(*str)++;
}
}
static void parse_decimal_number_part(str, number)
char **str;
double *number;
{
double exp_log;
*number = 0;
exp_log=1/10.0;
while (isdigit(**str))
{
*number+= (**str - '0')*exp_log;
exp_log/=10;
(*str)++;
}
}
/* Parses int suitably for exponent */
static int parse_int_number_part(str, number)
char **str;
uint *number;
{
*number = 0;
while (isdigit(**str))
{
if (*number >= ((uint) ~0)/10)
return 1; /* Don't overflow */
*number = (*number * 10) + **str - '0';
(*str)++;
}
return 0;
}
#endif
......@@ -702,12 +702,12 @@ double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
#else
if (length == INT_MAX32 || str[length] == 0)
#endif
result= strtod(str, end);
result= my_strtod(str, end);
else
{
end_char= str[length];
str[length]= 0;
result= strtod(str, end);
result= my_strtod(str, end);
str[length]= end_char; /* Restore end char */
}
*err= errno;
......
......@@ -867,7 +867,7 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
*b= 0;
errno= 0;
res=strtod(buf, endptr);
res=my_strtod(buf, endptr);
*err= errno;
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
......
/*
An alternative implementation of "strtod()" that is both
simplier, and thread-safe.
From mit-threads as bundled with MySQL 3.22
SQL:2003 specifies a number as
<signed numeric literal> ::= [ <sign> ] <unsigned numeric literal>
<unsigned numeric literal> ::=
<exact numeric literal>
| <approximate numeric literal>
<exact numeric literal> ::=
<unsigned integer> [ <period> [ <unsigned integer> ] ]
| <period> <unsigned integer>
<approximate numeric literal> ::= <mantissa> E <exponent>
<mantissa> ::= <exact numeric literal>
<exponent> ::= <signed integer>
So do we.
*/
#include "my_base.h"
#include "m_ctype.h"
static double scaler10[] = {
1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
};
static double scaler1[] = {
1.0, 10.0, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9
};
// let's use a static array for not to accumulate the error
static double pastpoint[] = {
1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9,
1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17, 1e-18, 1e-19,
1e-20, 1e-21, 1e-22, 1e-23, 1e-24, 1e-25, 1e-26, 1e-27, 1e-28, 1e-29,
1e-30, 1e-31, 1e-32, 1e-33, 1e-34, 1e-35, 1e-36, 1e-37, 1e-38, 1e-39,
1e-40, 1e-41, 1e-42, 1e-43, 1e-44, 1e-45, 1e-46, 1e-47, 1e-48, 1e-49,
1e-50, 1e-51, 1e-52, 1e-53, 1e-54, 1e-55, 1e-56, 1e-57, 1e-58, 1e-59,
};
double my_strtod(const char *str, char **end)
{
double result= 0.0;
int negative, ndigits;
const char *old_str;
while (my_isspace(&my_charset_latin1, *str))
str++;
if ((negative= (*str == '-')) || *str=='+')
str++;
old_str= str;
while (my_isdigit (&my_charset_latin1, *str))
{
result= result*10.0 + (*str - '0');
str++;
}
ndigits= str-old_str;
if (*str == '.')
{
int n= 0;
str++;
old_str= str;
while (my_isdigit (&my_charset_latin1, *str))
{
if (n < sizeof(pastpoint)/sizeof(pastpoint[0]))
{
result+= pastpoint[n] * (*str - '0');
n++;
}
str++;
}
ndigits+= str-old_str;
if (!ndigits) str--;
}
if (ndigits && (*str=='e' || *str=='E'))
{
int exp= 0;
int neg= 0;
const char *old_str= str++;
if ((neg= (*str == '-')) || *str == '+')
str++;
if (!my_isdigit (&my_charset_latin1, *str))
str= old_str;
else
{
double scaler= 1.0;
while (my_isdigit (&my_charset_latin1, *str))
{
exp= exp*10 + *str - '0';
str++;
}
if (exp >= 1000)
{
if (neg)
result= 0.0;
else
result= DBL_MAX;
goto done;
}
while (exp >= 100)
{
scaler*= 1.0e100;
exp-= 100;
}
scaler*= scaler10[exp/10]*scaler1[exp%10];
if (neg)
result/= scaler;
else
result*= scaler;
}
}
done:
if (end)
*end = (char *)str;
if (isinf(result))
result=DBL_MAX;
return negative ? -result : result;
}
double my_atof(const char *nptr)
{
return (strtod(nptr, 0));
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment