summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2004-02-13 15:27:21 +0100
committerunknown <serg@serg.mylan>2004-02-13 15:27:21 +0100
commit98150adcec185a147426a2cea5d7ea582c609fd2 (patch)
treee72eb3285c6d77bd43ee040603595ce715626551 /strings
parent5beeb066ad74dbca5d663915bb1b83277a96f5d7 (diff)
downloadmariadb-git-98150adcec185a147426a2cea5d7ea582c609fd2.tar.gz
my_atof is deleted
strtod from mit-threads is restored and cleaned up BitKeeper/deleted/.del-atof.c~d3edf47a9884080: Delete: strings/atof.c configure.in: atod() is no longer used in MySQL isinf() now is include/m_string.h: my_strtod, my_atof include/my_global.h: my_atof is deleted define isinf() libmysql/Makefile.shared: use internal strtod sql/gstream.cc: use internal strtod sql/init.cc: my_atof is deleted sql/item.h: use internal strtod sql/item_func.cc: use internal strtod sql/item_sum.h: use internal strtod sql/sql_analyse.cc: use internal strtod strings/Makefile.am: use internal strtod strings/ctype-simple.c: use internal strtod strings/ctype-ucs2.c: use internal strtod strings/strtod.c: cleanup stricter input checks (e.g. ".E10" is no longer a number) don't return an "inf"
Diffstat (limited to 'strings')
-rw-r--r--strings/Makefile.am6
-rw-r--r--strings/atof.c207
-rw-r--r--strings/ctype-simple.c6
-rw-r--r--strings/ctype-ucs2.c6
-rw-r--r--strings/strtod.c140
5 files changed, 149 insertions, 216 deletions
diff --git a/strings/Makefile.am b/strings/Makefile.am
index 61219c8abb9..89f32ac6b40 100644
--- a/strings/Makefile.am
+++ b/strings/Makefile.am
@@ -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
diff --git a/strings/atof.c b/strings/atof.c
deleted file mode 100644
index 0e0aa598718..00000000000
--- a/strings/atof.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* 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
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 6f77d6f3e16..c55d12fcd3c 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -684,7 +684,7 @@ noconv:
double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)),
- char *str, uint length,
+ char *str, uint length,
char **end, int *err)
{
char end_char;
@@ -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;
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index a7a59fc50f7..94f0a1bb2a2 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -856,7 +856,7 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
if (length >= sizeof(buf))
length= sizeof(buf)-1;
end= s+length;
-
+
while ((cnv=cs->cset->mb_wc(cs,&wc,s,end)) > 0)
{
s+=cnv;
@@ -865,9 +865,9 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
*b++= (char) wc;
}
*b= 0;
-
+
errno= 0;
- res=strtod(buf, endptr);
+ res=my_strtod(buf, endptr);
*err= errno;
if (endptr)
*endptr=(char*) (*endptr-buf+nptr);
diff --git a/strings/strtod.c b/strings/strtod.c
new file mode 100644
index 00000000000..ea6acbac6c4
--- /dev/null
+++ b/strings/strtod.c
@@ -0,0 +1,140 @@
+/*
+ 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));
+}
+