summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bar@bar.mysql.r18.ru>2002-11-29 13:29:48 +0400
committerunknown <bar@bar.mysql.r18.ru>2002-11-29 13:29:48 +0400
commit4b0a6e6bcdda3d4b97c389cc5063a6afd520b0a0 (patch)
treeb528e1e854cc3b19043313a8756eaef4cc36c035
parent781a5bc81ad3fdd6111986a895e6025d6910773e (diff)
downloadmariadb-git-4b0a6e6bcdda3d4b97c389cc5063a6afd520b0a0.tar.gz
my_strntod_ucs2 and my_strntol_ucs2 fixes
-rw-r--r--strings/ctype-utf8.c210
1 files changed, 112 insertions, 98 deletions
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index 8adeed7144a..c77dc871009 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -22,7 +22,7 @@
#include "m_string.h"
#include "m_ctype.h"
#include "my_sys.h" /* defines errno */
-
+#include <errno.h>
#ifdef HAVE_CHARSET_utf8
#define HAVE_UNIDATA
@@ -2118,7 +2118,7 @@ static int my_ucs2_uni (CHARSET_INFO *cs __attribute__((unused)) ,
my_wc_t * pwc, const uchar *s, const uchar *e)
{
if (s+2 > e) /* Need 2 characters */
- return MY_CS_ILSEQ;
+ return MY_CS_TOOFEW(0);
*pwc= ((unsigned char)s[0]) * 256 + ((unsigned char)s[1]);
return 2;
@@ -2441,118 +2441,114 @@ static int my_snprintf_ucs2(CHARSET_INFO *cs __attribute__((unused))
return my_vsnprintf_ucs2(to, n, fmt, args);
}
-#define MY_ERRNO(x)
long my_strntol_ucs2(CHARSET_INFO *cs,
const char *nptr, uint l, char **endptr, int base)
{
- int negative;
- register ulong cutoff;
+ int negative=0;
+ int overflow;
+ int cnv;
+ my_wc_t wc;
register unsigned int cutlim;
- register ulong i;
- register const char *s;
- register unsigned char c;
- const char *save, *e;
- int overflow;
+ register ulong cutoff;
+ register ulong res;
+ register const char *s=nptr;
+ register const char *e=nptr+l;
+ const char *save;
- if (base < 0 || base == 1 || base > 36)
- base = 10;
+ do {
+ if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
+ {
+ switch (wc)
+ {
+ case ' ' : break;
+ case '\t': break;
+ case '-' : negative= !negative; break;
+ case '+' : break;
+ default : goto bs;
+ }
+ }
+ else /* No more characters or bad multibyte sequence */
+ {
+ if (endptr !=NULL )
+ *endptr = (char*)s;
+ my_errno = (cnv==MY_CS_ILSEQ) ? EILSEQ : EDOM;
+ return 0;
+ }
+ s+=cnv;
+ } while (1);
- s = nptr;
- e = nptr+l;
+bs:
- for ( ; s<e && my_isspace(cs, *s) ; s++);
+ if (base <= 0 || base == 1 || base > 36)
+ base = 10;
- if (s == e)
- {
- goto noconv;
- }
+ overflow = 0;
+ res = 0;
+ save = s;
+ cutoff = ((ulong)~0L) / (unsigned long int) base;
+ cutlim = (uint) (((ulong)~0L) % (unsigned long int) base);
- /* 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')
+ do {
+ if ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
{
- if (my_toupper(cs,s[1]) == 'X')
+ s+=cnv;
+ if ( wc>='0' && wc<='9')
+ wc -= '0';
+ else if ( wc>='A' && wc<='Z')
+ wc = wc - 'A' + 10;
+ else if ( wc>='a' && wc<='z')
+ wc = wc - 'a' + 10;
+ else
+ break;
+ if ((int)wc >= base)
+ break;
+ if (res > cutoff || (res == cutoff && wc > cutlim))
+ overflow = 1;
+ else
{
- s += 2;
- base = 16;
+ res *= (ulong) base;
+ res += wc;
}
- 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 if (cnv==MY_CS_ILSEQ)
+ {
+ if (endptr !=NULL )
+ *endptr = (char*)s;
+ my_errno=EILSEQ;
+ return 0;
+ }
else
{
- i *= (ulong) base;
- i += c;
+ /* No more characters */
+ break;
}
- }
-
- if (s == save)
- goto noconv;
+ } while(1);
if (endptr != NULL)
*endptr = (char *) s;
+ if (s == save)
+ {
+ my_errno=EDOM;
+ return 0L;
+ }
+
if (negative)
{
- if (i > (ulong) LONG_MIN)
+ if (res > (ulong) LONG_MIN)
overflow = 1;
}
- else if (i > (ulong) LONG_MAX)
+ else if (res > (ulong) LONG_MAX)
overflow = 1;
if (overflow)
{
- MY_ERRNO(ERANGE);
+ 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;
+ return (negative ? -((long) res) : (long) res);
}
@@ -2646,14 +2642,14 @@ ulong my_strntoul_ucs2(CHARSET_INFO *cs,
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return ((ulong)~0L);
}
return (negative ? -((long) i) : (long) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
@@ -2759,14 +2755,14 @@ longlong my_strntoll_ucs2(CHARSET_INFO *cs __attribute__((unused)),
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return negative ? LONGLONG_MIN : LONGLONG_MAX;
}
return (negative ? -((longlong) i) : (longlong) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
@@ -2864,35 +2860,53 @@ ulonglong my_strntoull_ucs2(CHARSET_INFO *cs,
if (overflow)
{
- MY_ERRNO(ERANGE);
+ my_errno=(ERANGE);
return (~(ulonglong) 0);
}
return (negative ? -((longlong) i) : (longlong) i);
noconv:
- MY_ERRNO(EDOM);
+ my_errno=(EDOM);
if (endptr != NULL)
*endptr = (char *) nptr;
return 0L;
}
double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
- const char *s, uint l, char **e)
+ const char *nptr, uint l, char **endptr)
{
- char buf[256];
- double res;
+ char buf[256];
+ double res;
+ register char *b=buf;
+ register const char *s=nptr;
+ register const char *e=nptr+l;
+ my_wc_t wc;
+ int cnv;
+
if((l+1)>sizeof(buf))
{
- if (e)
- memcpy(*e,s,sizeof(s));
+ if (endptr)
+ *endptr=(char*)nptr;
+ my_errno=ERANGE;
return 0;
}
- strncpy(buf,s,l);
- buf[l]='\0';
- res=strtod(buf,e);
- if (e)
- memcpy(*e,*e-buf+s,sizeof(s));
+
+ while ((cnv=cs->mb_wc(cs,&wc,s,e))>0)
+ {
+ s+=cnv;
+ if (wc < 128)
+ {
+ *b++=wc;
+ }
+ else
+ break;
+ }
+ *b='\0';
+
+ res=strtod(buf,endptr);
+ if (endptr)
+ *endptr=(char*) (*endptr-buf+nptr);
return res;
}