diff options
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | include/m_string.h | 6 | ||||
-rw-r--r-- | include/my_global.h | 14 | ||||
-rw-r--r-- | libmysql/Makefile.shared | 2 | ||||
-rw-r--r-- | mysys/mf_keycache.c | 4 | ||||
-rw-r--r-- | mysys/my_new.cc | 4 | ||||
-rw-r--r-- | mytest-old.c | 169 | ||||
-rw-r--r-- | sql/gstream.cc | 2 | ||||
-rw-r--r-- | sql/init.cc | 3 | ||||
-rw-r--r-- | sql/item.h | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_sum.h | 4 | ||||
-rw-r--r-- | sql/sql_analyse.cc | 2 | ||||
-rw-r--r-- | sql/sql_string.cc | 2 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 26 | ||||
-rw-r--r-- | strings/Makefile.am | 6 | ||||
-rw-r--r-- | strings/atof.c | 207 | ||||
-rw-r--r-- | strings/ctype-simple.c | 6 | ||||
-rw-r--r-- | strings/ctype-ucs2.c | 6 | ||||
-rw-r--r-- | strings/strtod.c | 140 |
20 files changed, 184 insertions, 425 deletions
diff --git a/configure.in b/configure.in index 9cdb9d209c2..67a751f7e17 100644 --- a/configure.in +++ b/configure.in @@ -1828,7 +1828,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 \ diff --git a/include/m_string.h b/include/m_string.h index d72342fb3c1..ac2aae37704 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -201,7 +201,7 @@ extern int strcmp(const char *, const char *); extern size_t strlen(const char *); #endif #endif -#ifndef HAVE_STRNLEN +#ifndef HAVE_STRNLEN extern uint strnlen(const char *s, uint n); #endif @@ -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); diff --git a/include/my_global.h b/include/my_global.h index c9660d4d649..41e3636116a 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -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. diff --git a/libmysql/Makefile.shared b/libmysql/Makefile.shared index 1cffae4dc56..678abc91859 100644 --- a/libmysql/Makefile.shared +++ b/libmysql/Makefile.shared @@ -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 \ diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 08737221fb2..52b7f153e0d 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -627,7 +627,7 @@ writes: %ld r_requests: %ld reads: %ld", a pointer to the last element. */ -static inline void link_into_queue(KEYCACHE_WQUEUE *wqueue, +static void link_into_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread) { struct st_my_thread_var *last; @@ -662,7 +662,7 @@ static inline void link_into_queue(KEYCACHE_WQUEUE *wqueue, See NOTES for link_into_queue */ -static inline void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, +static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, struct st_my_thread_var *thread) { KEYCACHE_DBUG_PRINT("unlink_from_queue", ("thread %ld", thread->id)); diff --git a/mysys/my_new.cc b/mysys/my_new.cc index ec27502d8aa..14423c3afd5 100644 --- a/mysys/my_new.cc +++ b/mysys/my_new.cc @@ -19,10 +19,10 @@ with gcc 3.0.x to avoid including libstdc++ */ -#ifdef USE_MYSYS_NEW - #include "mysys_priv.h" +#ifdef USE_MYSYS_NEW + void *operator new (size_t sz) { return (void *) malloc (sz ? sz : 1); diff --git a/mytest-old.c b/mytest-old.c deleted file mode 100644 index 8b4029f5e1e..00000000000 --- a/mytest-old.c +++ /dev/null @@ -1,169 +0,0 @@ -/*C4*/ -/****************************************************************/ -/* Author: Jethro Wright, III TS : 3/ 4/1998 9:15 */ -/* Date: 02/18/1998 */ -/* mytest.c : do some testing of the libmySQL.DLL.... */ -/* */ -/* History: */ -/* 02/18/1998 jw3 also sprach zarathustra.... */ -/****************************************************************/ - - -#include <windows.h> -#include <stdio.h> -#include <string.h> - -#include <mysql.h> - -#define DEFALT_SQL_STMT "SELECT * FROM db" -#ifndef offsetof -#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -#endif - - -/******************************************************** -** -** main :- -** -********************************************************/ - -int -main( int argc, char * argv[] ) -{ - - char szSQL[ 200 ], aszFlds[ 25 ][ 25 ], * pszT, szDB[ 50 ] ; - int i, j, k, l, x ; - MYSQL * myData ; - MYSQL_RES * res ; - MYSQL_FIELD * fd ; - MYSQL_ROW row ; - - //....just curious.... - printf( "sizeof( MYSQL ) == %d\n", sizeof( MYSQL ) ) ; - if ( argc == 2 ) - { - strcpy( szDB, argv[ 1 ] ) ; - strcpy( szSQL, DEFALT_SQL_STMT ) ; - if (!strcmp(szDB,"--debug")) - { - strcpy( szDB, "mysql" ) ; - printf("Some mysql struct information (size and offset):\n"); - printf("net:\t%3d %3d\n",sizeof(myData->net),offsetof(MYSQL,net)); - printf("host:\t%3d %3d\n",sizeof(myData->host),offsetof(MYSQL,host)); - printf("port:\t%3d %3d\n",sizeof(myData->port),offsetof(MYSQL,port)); - printf("protocol_version:\t%3d %3d\n",sizeof(myData->protocol_version), - offsetof(MYSQL,protocol_version)); - printf("thread_id:\t%3d %3d\n",sizeof(myData->thread_id), - offsetof(MYSQL,thread_id)); - printf("affected_rows:\t%3d %3d\n",sizeof(myData->affected_rows), - offsetof(MYSQL,affected_rows)); - printf("packet_length:\t%3d %3d\n",sizeof(myData->packet_length), - offsetof(MYSQL,packet_length)); - printf("status:\t%3d %3d\n",sizeof(myData->status), - offsetof(MYSQL,status)); - printf("fields:\t%3d %3d\n",sizeof(myData->fields), - offsetof(MYSQL,fields)); - printf("field_alloc:\t%3d %3d\n",sizeof(myData->field_alloc), - offsetof(MYSQL,field_alloc)); - printf("free_me:\t%3d %3d\n",sizeof(myData->free_me), - offsetof(MYSQL,free_me)); - printf("options:\t%3d %3d\n",sizeof(myData->options), - offsetof(MYSQL,options)); - puts(""); - } - } - else if ( argc > 2 ) { - strcpy( szDB, argv[ 1 ] ) ; - strcpy( szSQL, argv[ 2 ] ) ; - } - else { - strcpy( szDB, "mysql" ) ; - strcpy( szSQL, DEFALT_SQL_STMT ) ; - } - //.... - - if ( (myData = mysql_init((MYSQL*) 0)) && - mysql_real_connect( myData, NULL, NULL, NULL, NULL, MYSQL_PORT, - NULL, 0 ) ) - { - if ( mysql_select_db( myData, szDB ) < 0 ) { - printf( "Can't select the %s database !\n", szDB ) ; - mysql_close( myData ) ; - return 2 ; - } - } - else { - printf( "Can't connect to the mysql server on port %d !\n", - MYSQL_PORT ) ; - mysql_close( myData ) ; - return 1 ; - } - //.... - if ( ! mysql_query( myData, szSQL ) ) { - res = mysql_store_result( myData ) ; - i = (int) mysql_num_rows( res ) ; l = 1 ; - printf( "Query: %s\nNumber of records found: %ld\n", szSQL, i ) ; - //....we can get the field-specific characteristics here.... - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - //.... - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Record #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - mysql_free_result( res ) ; - } - else printf( "Couldn't execute %s on the server !\n", szSQL ) ; - //.... - puts( "==== Diagnostic info ====" ) ; - pszT = mysql_get_client_info() ; - printf( "Client info: %s\n", pszT ) ; - //.... - pszT = mysql_get_host_info( myData ) ; - printf( "Host info: %s\n", pszT ) ; - //.... - pszT = mysql_get_server_info( myData ) ; - printf( "Server info: %s\n", pszT ) ; - //.... - res = mysql_list_processes( myData ) ; l = 1 ; - if (res) - { - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Process #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - } - else - { - printf("Got error %s when retreiving processlist\n",mysql_error(myData)); - } - //.... - res = mysql_list_tables( myData, "%" ) ; l = 1 ; - for ( x = 0 ; fd = mysql_fetch_field( res ) ; x++ ) - strcpy( aszFlds[ x ], fd->name ) ; - while ( row = mysql_fetch_row( res ) ) { - j = mysql_num_fields( res ) ; - printf( "Table #%ld:-\n", l++ ) ; - for ( k = 0 ; k < j ; k++ ) - printf( " Fld #%d (%s): %s\n", k + 1, aszFlds[ k ], - (((row[k]==NULL)||(!strlen(row[k])))?"NULL":row[k])) ; - puts( "==============================\n" ) ; - } - //.... - pszT = mysql_stat( myData ) ; - puts( pszT ) ; - //.... - mysql_close( myData ) ; - return 0 ; - -} diff --git a/sql/gstream.cc b/sql/gstream.cc index a97ed9cae03..17b85af22bd 100644 --- a/sql/gstream.cc +++ b/sql/gstream.cc @@ -101,7 +101,7 @@ int GTextReadStream::get_next_number(double *d) char *endptr; - *d = strtod(cur, &endptr); + *d = my_strtod(cur, &endptr); if (endptr) { diff --git a/sql/init.cc b/sql/init.cc index 033dfd72843..084db57f8aa 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -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 diff --git a/sql/item.h b/sql/item.h index a5648c5889b..4d081905e0d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -442,7 +442,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); diff --git a/sql/item_func.cc b/sql/item_func.cc index 34a61ba0353..82ff9de4a56 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2254,7 +2254,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; diff --git a/sql/item_sum.h b/sql/item_sum.h index bb03f029997..41a77f2ac93 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -736,7 +736,7 @@ class Item_func_group_concat : public Item_sum enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} const char *func_name() const { return "group_concat"; } - enum Type type() const { return SUM_FUNC_ITEM; } + enum Type type() const { return SUM_FUNC_ITEM; } virtual Item_result result_type () const { return STRING_RESULT; } void clear(); bool add(); @@ -748,7 +748,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() { diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 9e73e06d9c6..3c9563165fe 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -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; } } diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 093b85b46b7..e76c7902210 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -453,7 +453,7 @@ bool String::append(const char *s,uint32 arg_length, CHARSET_INFO *cs) if (!arg_length) // Default argument if (!(arg_length= (uint32) strlen(s))) return FALSE; - if (str_charset->mbmaxlen > 1) + if (cs != str_charset && str_charset->mbmaxlen > 1) { uint32 add_length=arg_length * str_charset->mbmaxlen; if (realloc(str_length+ add_length)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bdeaf5a0b86..0e68fcc016d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2152,13 +2152,13 @@ select_init: SELECT_LEX * sel= lex->current_select; if (sel->set_braces(1)) { - send_error(lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } if (sel->linkage == UNION_TYPE && !sel->master_unit()->first_select()->braces) { - send_error(lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } /* select in braces, can't contain global parameters */ @@ -2174,13 +2174,13 @@ select_init2: SELECT_LEX * sel= lex->current_select; if (lex->current_select->set_braces(0)) { - send_error(lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } if (sel->linkage == UNION_TYPE && sel->master_unit()->first_select()->braces) { - send_error(lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } } @@ -2734,7 +2734,7 @@ simple_expr: { if ($1->type() != Item::ROW_ITEM) { - send_error(Lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } $$= new Item_func_interval((Item_row *)$1); @@ -3070,7 +3070,7 @@ in_sum_expr: LEX *lex= Lex; if (lex->current_select->inc_in_sum_expr()) { - send_error(lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } } @@ -3241,8 +3241,8 @@ select_derived: if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN && lex->sql_command <= (int)SQLCOM_HA_READ) || lex->sql_command == (int)SQLCOM_KILL) - { - send_error(lex->thd, ER_SYNTAX_ERROR); + { + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || @@ -3877,7 +3877,7 @@ opt_insert_update: for a moment */ if (Lex->sql_command != SQLCOM_INSERT) { - send_error(Lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } } @@ -4484,7 +4484,7 @@ param_marker: } else { - yyerror("You have an error in your SQL syntax"); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } } @@ -5527,7 +5527,7 @@ union_list: } if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { - send_error(lex->thd, ER_SYNTAX_ERROR); + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } if (mysql_new_select(lex, 0)) @@ -5627,8 +5627,8 @@ subselect_start: if (((int)lex->sql_command >= (int)SQLCOM_HA_OPEN && lex->sql_command <= (int)SQLCOM_HA_READ) || lex->sql_command == (int)SQLCOM_KILL) - { - send_error(lex->thd, ER_SYNTAX_ERROR); + { + yyerror(ER(ER_SYNTAX_ERROR)); YYABORT; } if (mysql_new_select(Lex, 1)) 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 233251e16a8..e4435d1222d 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 bb74e0cf56b..ec306d9af35 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)); +} + |