diff options
author | unknown <bar@bar.mysql.r18.ru> | 2002-11-27 18:08:31 +0400 |
---|---|---|
committer | unknown <bar@bar.mysql.r18.ru> | 2002-11-27 18:08:31 +0400 |
commit | 68e63a36e5421e4fcf17ad5ad9ce0b4edb23fae8 (patch) | |
tree | 6bf8deff485129d2acae45c230f19de1912c5034 /strings/ctype-utf8.c | |
parent | b94f9320c05cb8d793d819c91ad1b202d95232ce (diff) | |
download | mariadb-git-68e63a36e5421e4fcf17ad5ad9ce0b4edb23fae8.tar.gz |
new string-to-number functions
include/m_ctype.h:
Typo fix
sql/field.cc:
Use new string-to-number functions
strings/ctype-bin.c:
Use new string-to-number functions
strings/ctype-simple.c:
Use new string-to-number functions
strings/ctype-utf8.c:
Use new string-to-number functions
Diffstat (limited to 'strings/ctype-utf8.c')
-rw-r--r-- | strings/ctype-utf8.c | 457 |
1 files changed, 442 insertions, 15 deletions
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; } |