summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbar@bar.mysql.r18.ru <>2002-11-27 18:24:02 +0400
committerbar@bar.mysql.r18.ru <>2002-11-27 18:24:02 +0400
commite198ebc7bfe72bbaaaf4eb22cc53989eaf6667e4 (patch)
tree13f596c229e020f69deb18cd25121f677921925a
parentfa3c2489e9678aad81c55c8fb23d573ba9e71325 (diff)
parent95930f129ec7463ff0f1ec22513414976d83e6e8 (diff)
downloadmariadb-git-e198ebc7bfe72bbaaaf4eb22cc53989eaf6667e4.tar.gz
Merge abarkov@work.mysql.com:/home/bk/mysql-4.1
into bar.mysql.r18.ru:/usr/home/bar/mysql-4.1.wrk
-rw-r--r--include/m_ctype.h10
-rw-r--r--sql/field.cc12
-rw-r--r--strings/ctype-bin.c22
-rw-r--r--strings/ctype-simple.c463
-rw-r--r--strings/ctype-utf8.c457
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 <my_global.h>
-#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<e && my_isspace(cs, *s) ; s++);
+
+ if (s == e)
+ {
+ goto noconv;
+ }
+
+ /* Check for a sign. */
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (s[1]=='X' || s[1]=='x')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+ cutoff = ((ulong)~0L) / (unsigned long int) base;
+ cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; s != e; c = *++s)
+ {
+ if (c>='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<e && my_isspace(cs, *s); s++);
+
+ if (s==e)
+ {
+ goto noconv;
+ }
+
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (s[1]=='X' || s[1]=='x')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+ cutoff = ((ulong)~0L) / (unsigned long int) base;
+ cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
+ overflow = 0;
+ i = 0;
+
+ for (c = *s; s != e; c = *++s)
+ {
+ if (c>='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<e && my_isspace(cs,*s); s++);
+
+ if (s == e)
+ {
+ goto noconv;
+ }
+
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && (s[1]=='X'|| s[1]=='x'))
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (s[1]=='X' || s[1]=='x')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+
+ cutoff = (~(ulonglong) 0) / (unsigned long int) base;
+ cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; s != e; c = *++s)
+ {
+ if (c>='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<e && my_isspace(cs,*s); s++);
+
+ if (s == e)
+ {
+ goto noconv;
+ }
+
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && (s[1]=='X' || s[1]=='x'))
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (s[1]=='X' || s[1]=='x')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+
+ cutoff = (~(ulonglong) 0) / (unsigned long int) base;
+ cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; s != e; c = *++s)
+ {
+ if (c>='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 <bar@udm.net> */
#include <my_global.h>
-#include <m_ctype.h>
+#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<e && my_isspace(cs, *s) ; s++);
+
+ if (s == e)
+ {
+ goto noconv;
+ }
+
+ /* Check for a sign. */
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && my_toupper(cs,s[1]) == 'X')
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (my_toupper(cs,s[1]) == 'X')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+ cutoff = ((ulong)~0L) / (unsigned long int) base;
+ cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; s != e; c = *++s)
+ {
+ if (my_isdigit(cs,c))
+ c -= '0';
+ else if (my_isalpha(cs,c))
+ c = my_toupper(cs,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;
}
-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<e && my_isspace(cs, *s); s++);
+
+ if (s==e)
+ {
+ goto noconv;
+ }
+
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && my_toupper(cs,s[1]) == 'X')
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (my_toupper(cs,s[1]) == 'X')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+ cutoff = ((ulong)~0L) / (unsigned long int) base;
+ cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
+ overflow = 0;
+ i = 0;
+
+ for (c = *s; s != e; c = *++s)
+ {
+ if (my_isdigit(cs,c))
+ c -= '0';
+ else if (my_isalpha(cs,c))
+ c = my_toupper(cs,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;
}
-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<e && my_isspace(cs,*s); s++);
+
+ if (s == e)
+ {
+ goto noconv;
+ }
+
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && my_toupper(cs,s[1]) == 'X')
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (my_toupper(cs,s[1]) == 'X')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+
+ cutoff = (~(ulonglong) 0) / (unsigned long int) base;
+ cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; s != e; c = *++s)
+ {
+ if (my_isdigit(cs,c))
+ c -= '0';
+ else if (my_isalpha(cs,c))
+ c = my_toupper(cs,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;
}
-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<e && my_isspace(cs,*s); s++);
+
+ if (s == e)
+ {
+ goto noconv;
+ }
+
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && my_toupper(cs,s[1]) == 'X')
+ s += 2;
+
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (my_toupper(cs,s[1]) == 'X')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ save = s;
+
+ cutoff = (~(ulonglong) 0) / (unsigned long int) base;
+ cutlim = (uint) ((~(ulonglong) 0) % (unsigned long int) base);
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; s != e; c = *++s)
+ {
+ if (my_isdigit(cs,c))
+ c -= '0';
+ else if (my_isalpha(cs,c))
+ c = my_toupper(cs,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_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;
}