From 95930f129ec7463ff0f1ec22513414976d83e6e8 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Wed, 27 Nov 2002 18:08:31 +0400 Subject: new string-to-number functions --- include/m_ctype.h | 10 +- sql/field.cc | 12 +- strings/ctype-bin.c | 22 ++- strings/ctype-simple.c | 463 +++++++++++++++++++++++++++++++++++++++++++++++-- strings/ctype-utf8.c | 457 ++++++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 921 insertions(+), 43 deletions(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index deba69700a2..4af23bb3ab5 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -257,11 +257,11 @@ int my_wildcmp_mb(CHARSET_INFO *, #define my_strcasecmp(s, a, b) ((s)->strcasecmp((s), (a), (b))) #define my_strncasecmp(s, a, b, l) ((s)->strncasecmp((s), (a), (b), (l))) -#define my_strtol(s, a, b, c, d) ((s)->strtol((s),(a),(b),(c),(d))) -#define my_strtoul(s, a, b, c, d) ((s)->strtoul((s),(a),(b),(c),(d))) -#define my_strtoll(s, a, b, c, d) ((s)->strtoll((s),(a),(b),(c),(d))) -#define my_strtoull(s, a, b, c,d) ((s)->strtoull((s),(a),(b),(c),(d))) -#define my_strtod(s, a, b, c ) ((s)->strtod((s),(a),(b),(c))) +#define my_strntol(s, a, b, c, d) ((s)->strntol((s),(a),(b),(c),(d))) +#define my_strntoul(s, a, b, c, d) ((s)->strntoul((s),(a),(b),(c),(d))) +#define my_strntoll(s, a, b, c, d) ((s)->strntoll((s),(a),(b),(c),(d))) +#define my_strntoull(s, a, b, c,d) ((s)->strntoull((s),(a),(b),(c),(d))) +#define my_strntod(s, a, b, c ) ((s)->strntod((s),(a),(b),(c))) /* XXX: still need to take care of this one */ diff --git a/sql/field.cc b/sql/field.cc index f2324a0a331..e0910caeea2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -921,8 +921,7 @@ void Field_decimal::sql_type(String &res) const int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long tmp= strtol(tmp_str.c_ptr(),NULL,10); + long tmp= my_strntol(cs,from,len,(char **)NULL,10); int error= 0; if (unsigned_flag) @@ -1116,8 +1115,7 @@ void Field_tiny::sql_type(String &res) const int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long tmp= strtol(tmp_str.c_ptr(),NULL,10); + long tmp= my_strntol(cs,from,len,NULL,10); int error= 0; if (unsigned_flag) { @@ -1380,8 +1378,7 @@ void Field_short::sql_type(String &res) const int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long tmp= strtol(tmp_str.c_ptr(),NULL,10); + long tmp= my_strntol(cs,from,len,NULL,10); int error= 0; if (unsigned_flag) @@ -3097,8 +3094,7 @@ void Field_time::sql_type(String &res) const int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { - String tmp_str(from,len,default_charset_info); - long nr= strtol(tmp_str.c_ptr(),NULL,10); + long nr= my_strntol(cs,from,len,NULL,10); if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155) { diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index 29784acab16..7431ce82df5 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -22,6 +22,26 @@ #include "m_string.h" #include "m_ctype.h" +static uchar ctype_bin[] = { + 0, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 40, 40, 40, 40, 40, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 132,132,132,132,132,132,132,132,132,132, 16, 16, 16, 16, 16, 16, + 16,129,129,129,129,129,129, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, + 16,130,130,130,130,130,130, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 16, 16, 16, 32, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 72, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 16, 2, 2, 2, 2, 2, 2, 2, 2 +}; + static int my_strnncoll_binary(CHARSET_INFO * cs __attribute__((unused)), const uchar *s, uint slen, @@ -242,7 +262,7 @@ static CHARSET_INFO my_charset_bin_st = MY_CS_COMPILED|MY_CS_BINSORT,/* state */ "binary", /* name */ "", /* comment */ - NULL, /* ctype */ + ctype_bin, /* ctype */ NULL, /* to_lower */ NULL, /* to_upper */ NULL, /* sort_order */ diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 6ae305bbf7d..be4fdc9cb8d 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -15,12 +15,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include -#include "my_sys.h" -#include "m_ctype.h" #include "m_string.h" +#include "m_ctype.h" +#include "my_sys.h" /* defines errno */ #include "stdarg.h" #include "assert.h" + int my_strnxfrm_simple(CHARSET_INFO * cs, uchar *dest, uint len, const uchar *src, uint srclen) @@ -244,34 +245,468 @@ void my_hash_sort_simple(CHARSET_INFO *cs, } } -long my_strntol_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + +#define MY_ERRNO(y) + +long my_strntol_8bit(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for ( ; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='f') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulong) LONG_MIN) + overflow = 1; + } + else if (i > (ulong) LONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONG_MIN : LONG_MAX; + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -ulong my_strntoul_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + +ulong my_strntoul_8bit(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for( ; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='a') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return ((ulong)~0L); + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } + longlong my_strntoll_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='f') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulonglong) LONGLONG_MIN) + overflow = 1; + } + else if (i > (ulonglong) LONGLONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONGLONG_MIN : LONGLONG_MAX; + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -ulonglong my_strntoull_8bit(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + +ulonglong my_strntoull_8bit(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s='0' && c<='9') + c -= '0'; + else if (c>='A' && c<='F') + c = c - 'A' + 10; + else if (c>='a' && c<='f') + c = c - 'a' + 10; + else + break; + if (c >= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return (~(ulonglong) 0); + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } double my_strntod_8bit(CHARSET_INFO *cs __attribute__((unused)), const char *s, uint l, char **e) { - return 0; + char buf[256]; + double res; + if((l+1)>sizeof(buf)) + { + if (e) + memcpy(*e,s,sizeof(s)); + return 0; + } + strncpy(buf,s,l); + buf[l]='\0'; + res=strtod(buf,e); + if (e) + memcpy(*e,*e-buf+s,sizeof(s)); + return res; } diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index e55a6a717e5..8adeed7144a 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -19,7 +19,10 @@ /* Written by Alexander Barkov */ #include -#include +#include "m_string.h" +#include "m_ctype.h" +#include "my_sys.h" /* defines errno */ + #ifdef HAVE_CHARSET_utf8 #define HAVE_UNIDATA @@ -2438,35 +2441,459 @@ static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused)) return my_vsnprintf_ucs2(to, n, fmt, args); } +#define MY_ERRNO(x) -static long my_strntol_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) +long my_strntol_ucs2(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for ( ; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulong) LONG_MIN) + overflow = 1; + } + else if (i > (ulong) LONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONG_MIN : LONG_MAX; + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -static ulong my_strntoul_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + +ulong my_strntoul_ucs2(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulong cutoff; + register unsigned int cutlim; + register ulong i; + register const char *s; + register unsigned char c; + const char *save, *e; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for( ; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return ((ulong)~0L); + } + + return (negative ? -((long) i) : (long) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -static longlong my_strntoll_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + +longlong my_strntoll_ucs2(CHARSET_INFO *cs __attribute__((unused)), + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (negative) + { + if (i > (ulonglong) LONGLONG_MIN) + overflow = 1; + } + else if (i > (ulonglong) LONGLONG_MAX) + overflow = 1; + + if (overflow) + { + MY_ERRNO(ERANGE); + return negative ? LONGLONG_MIN : LONGLONG_MAX; + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -static ulonglong my_strntoull_ucs2(CHARSET_INFO *cs __attribute__((unused)), - const char *s, uint l, char **e, int base) + +ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, + const char *nptr, uint l, char **endptr, int base) { - return 0; + int negative; + register ulonglong cutoff; + register unsigned int cutlim; + register ulonglong i; + register const char *s, *e; + register unsigned char c; + const char *save; + int overflow; + + if (base < 0 || base == 1 || base > 36) + base = 10; + + s = nptr; + e = nptr+l; + + for(; s= base) + break; + if (i > cutoff || (i == cutoff && c > cutlim)) + overflow = 1; + else + { + i *= (ulonglong) base; + i += c; + } + } + + if (s == save) + goto noconv; + + if (endptr != NULL) + *endptr = (char *) s; + + if (overflow) + { + MY_ERRNO(ERANGE); + return (~(ulonglong) 0); + } + + return (negative ? -((longlong) i) : (longlong) i); + +noconv: + MY_ERRNO(EDOM); + if (endptr != NULL) + *endptr = (char *) nptr; + return 0L; } -double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), +double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), const char *s, uint l, char **e) { - return 0; + char buf[256]; + double res; + if((l+1)>sizeof(buf)) + { + if (e) + memcpy(*e,s,sizeof(s)); + return 0; + } + strncpy(buf,s,l); + buf[l]='\0'; + res=strtod(buf,e); + if (e) + memcpy(*e,*e-buf+s,sizeof(s)); + return res; } -- cgit v1.2.1