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 #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) + 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); + +bs: + + 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; + + do { + if ((cnv=cs->mb_wc(cs,&wc,s,e))>0) + { + 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 + { + res *= (ulong) base; + res += wc; + } + } + 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; }