diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index c77dc871009..fa66ca7efb4 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2555,324 +2555,321 @@ bs: ulong my_strntoul_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; - - if (base < 0 || base == 1 || base > 36) + register ulong cutoff; + register ulong res; + register const char *s=nptr; + register const char *e=nptr+l; + const char *save; + + 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 (overflow) { my_errno=(ERANGE); return ((ulong)~0L); } - return (negative ? -((long) i) : (long) i); + return (negative ? -((long) res) : (long) res); -noconv: - my_errno=(EDOM); - if (endptr != NULL) - *endptr = (char *) nptr; - return 0L; } -longlong my_strntoll_ucs2(CHARSET_INFO *cs __attribute__((unused)), + +longlong my_strntoll_ucs2(CHARSET_INFO *cs, const char *nptr, uint l, char **endptr, int base) { - int negative; - register ulonglong cutoff; + int negative=0; + int overflow; + int cnv; + my_wc_t wc; + register ulonglong cutoff; register unsigned int cutlim; - register ulonglong i; - register const char *s, *e; - register unsigned char c; + register ulonglong res; + register const char *s=nptr; + register const char *e=nptr+l; const char *save; - int overflow; - - if (base < 0 || base == 1 || base > 36) - base = 10; - - s = nptr; - e = nptr+l; - - for(; smb_wc(cs,&wc,s,e))>0) { - if (my_toupper(cs,s[1]) == 'X') + switch (wc) { - s += 2; - base = 16; + case ' ' : break; + case '\t': break; + case '-' : negative= !negative; break; + case '+' : break; + default : goto bs; } - else - base = 8; - } - else - base = 10; - } - + } + 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; + + overflow = 0; + res = 0; 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; + 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 *= (ulonglong) base; + res += wc; + } + } + else if (cnv==MY_CS_ILSEQ) + { + if (endptr !=NULL ) + *endptr = (char*)s; + my_errno=EILSEQ; + return 0; + } else { - i *= (ulonglong) 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 > (ulonglong) LONGLONG_MIN) + if (res > (ulonglong) LONGLONG_MIN) overflow = 1; } - else if (i > (ulonglong) LONGLONG_MAX) + else if (res > (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; + + return (negative ? -((longlong)res) : (longlong)res); } -ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, + + +ulonglong my_strntoull_ucs2(CHARSET_INFO *cs, const char *nptr, uint l, char **endptr, int base) { - int negative; - register ulonglong cutoff; + int negative=0; + int overflow; + int cnv; + my_wc_t wc; + register ulonglong cutoff; register unsigned int cutlim; - register ulonglong i; - register const char *s, *e; - register unsigned char c; + register ulonglong res; + register const char *s=nptr; + register const char *e=nptr+l; const char *save; - int overflow; - - if (base < 0 || base == 1 || base > 36) - base = 10; - - s = nptr; - e = nptr+l; - - for(; smb_wc(cs,&wc,s,e))>0) { - if (my_toupper(cs,s[1]) == 'X') + switch (wc) { - s += 2; - base = 16; + case ' ' : break; + case '\t': break; + case '-' : negative= !negative; break; + case '+' : break; + default : goto bs; } - else - base = 8; - } - else - base = 10; - } - + } + 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; + + overflow = 0; + res = 0; 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; + 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 *= (ulonglong) base; + res += wc; + } + } + else if (cnv==MY_CS_ILSEQ) + { + if (endptr !=NULL ) + *endptr = (char*)s; + my_errno=EILSEQ; + return 0; + } else { - i *= (ulonglong) 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 (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; + return (negative ? -((longlong) res) : (longlong) res); } + double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)), const char *nptr, uint l, char **endptr) {