summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorunknown <msvensson@neptunus.(none)>2006-10-03 14:24:43 +0200
committerunknown <msvensson@neptunus.(none)>2006-10-03 14:24:43 +0200
commit7d7487658531c3a191479188c102cb0821bfad9c (patch)
treece65490bd585d1b82550064472dd7946246fc32b /strings
parentb274c522ec84c84c76901ecafb6a59fb2a6716e7 (diff)
parentc317c2d224c8d7753cf7acd238968a9a8584dbc4 (diff)
downloadmariadb-git-7d7487658531c3a191479188c102cb0821bfad9c.tar.gz
Merge bk-internal:/home/bk/mysql-5.0-rpl
into neptunus.(none):/home/msvensson/mysql/mysql-5.0-maint client/mysql.cc: Auto merged include/m_ctype.h: Auto merged mysql-test/r/ctype_utf8.result: Auto merged mysql-test/r/strict.result: Auto merged mysql-test/r/warnings.result: Auto merged mysql-test/t/ctype_utf8.test: Auto merged sql/field.cc: Auto merged sql/item_func.cc: Auto merged
Diffstat (limited to 'strings')
-rw-r--r--strings/ctype-big5.c1
-rw-r--r--strings/ctype-bin.c1
-rw-r--r--strings/ctype-cp932.c1
-rw-r--r--strings/ctype-euc_kr.c1
-rw-r--r--strings/ctype-eucjpms.c1
-rw-r--r--strings/ctype-gb2312.c1
-rw-r--r--strings/ctype-gbk.c1
-rw-r--r--strings/ctype-latin1.c1
-rw-r--r--strings/ctype-simple.c337
-rw-r--r--strings/ctype-sjis.c1
-rw-r--r--strings/ctype-tis620.c1
-rw-r--r--strings/ctype-ucs2.c30
-rw-r--r--strings/ctype-ujis.c1
-rw-r--r--strings/ctype-utf8.c1
14 files changed, 379 insertions, 0 deletions
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 0ca1cf21129..479fb789816 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -6370,6 +6370,7 @@ static MY_CHARSET_HANDLER my_charset_big5_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index 54c35c82652..0bd5a1fda76 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -517,6 +517,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c
index 5f8a93b1c2b..b4e9ba16d92 100644
--- a/strings/ctype-cp932.c
+++ b/strings/ctype-cp932.c
@@ -5492,6 +5492,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index d6df46f7e05..40e0f4e3d2d 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -8711,6 +8711,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c
index 348eb2f6e87..65fef2dfc4c 100644
--- a/strings/ctype-eucjpms.c
+++ b/strings/ctype-eucjpms.c
@@ -8677,6 +8677,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index 29ecafc3527..c2fc1e2c190 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -5762,6 +5762,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index ef1b33fd82c..c4d06d67eb9 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -10015,6 +10015,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c
index a3f5aec9605..1298b66bb7e 100644
--- a/strings/ctype-latin1.c
+++ b/strings/ctype-latin1.c
@@ -411,6 +411,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index 12ef77c59b1..e40a1948dcf 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -17,6 +17,7 @@
#include <my_global.h>
#include "m_string.h"
#include "m_ctype.h"
+#include "my_sys.h" /* Needed for MY_ERRNO_ERANGE */
#include <errno.h>
#include "stdarg.h"
@@ -1354,6 +1355,341 @@ longlong my_strtoll10_8bit(CHARSET_INFO *cs __attribute__((unused)),
}
+#undef ULONGLONG_MAX
+/*
+ Needed under MetroWerks Compiler, since MetroWerks compiler does not
+ properly handle a constant expression containing a mod operator
+*/
+#if defined(__NETWARE__) && defined(__MWERKS__)
+static ulonglong ulonglong_max= ~(ulonglong) 0;
+#define ULONGLONG_MAX ulonglong_max
+#else
+#define ULONGLONG_MAX (~(ulonglong) 0)
+#endif /* __NETWARE__ && __MWERKS__ */
+
+
+#define CUTOFF (ULONGLONG_MAX / 10)
+#define CUTLIM (ULONGLONG_MAX % 10)
+#define DIGITS_IN_ULONGLONG 20
+
+static ulonglong d10[DIGITS_IN_ULONGLONG]=
+{
+ 1,
+ 10,
+ 100,
+ 1000,
+ 10000,
+ 100000,
+ 1000000,
+ 10000000,
+ 100000000,
+ 1000000000,
+ 10000000000ULL,
+ 100000000000ULL,
+ 1000000000000ULL,
+ 10000000000000ULL,
+ 100000000000000ULL,
+ 1000000000000000ULL,
+ 10000000000000000ULL,
+ 100000000000000000ULL,
+ 1000000000000000000ULL,
+ 10000000000000000000ULL
+};
+
+
+/*
+
+ Convert a string to unsigned long long integer value
+ with rounding.
+
+ SYNOPSYS
+ my_strntoull10_8bit()
+ cs in pointer to character set
+ str in pointer to the string to be converted
+ length in string length
+ unsigned_flag in whether the number is unsigned
+ endptr out pointer to the stop character
+ error out returned error code
+
+ DESCRIPTION
+ This function takes the decimal representation of integer number
+ from string str and converts it to an signed or unsigned
+ long long integer value.
+ Space characters and tab are ignored.
+ A sign character might precede the digit characters.
+ The number may have any number of pre-zero digits.
+ The number may have decimal point and exponent.
+ Rounding is always done in "away from zero" style:
+ 0.5 -> 1
+ -0.5 -> -1
+
+ The function stops reading the string str after "length" bytes
+ or at the first character that is not a part of correct number syntax:
+
+ <signed numeric literal> ::=
+ [ <sign> ] <exact numeric literal> [ E [ <sign> ] <unsigned integer> ]
+
+ <exact numeric literal> ::=
+ <unsigned integer> [ <period> [ <unsigned integer> ] ]
+ | <period> <unsigned integer>
+ <unsigned integer> ::= <digit>...
+
+ RETURN VALUES
+ Value of string as a signed/unsigned longlong integer
+
+ endptr cannot be NULL. The function will store the end pointer
+ to the stop character here.
+
+ The error parameter contains information how things went:
+ 0 ok
+ ERANGE If the the value of the converted number is out of range
+ In this case the return value is:
+ - ULONGLONG_MAX if unsigned_flag and the number was too big
+ - 0 if unsigned_flag and the number was negative
+ - LONGLONG_MAX if no unsigned_flag and the number is too big
+ - LONGLONG_MIN if no unsigned_flag and the number it too big negative
+
+ EDOM If the string didn't contain any digits.
+ In this case the return value is 0.
+*/
+
+ulonglong
+my_strntoull10rnd_8bit(CHARSET_INFO *cs __attribute__((unused)),
+ const char *str, uint length, int unsigned_flag,
+ char **endptr, int *error)
+{
+ const char *dot, *end9, *beg, *end= str + length;
+ ulonglong ull;
+ ulong ul;
+ unsigned char ch;
+ int shift= 0, digits= 0, negative, addon;
+
+ /* Skip leading spaces and tabs */
+ for ( ; str < end && (*str == ' ' || *str == '\t') ; str++);
+
+ if (str >= end)
+ goto ret_edom;
+
+ if ((negative= (*str == '-')) || *str=='+') /* optional sign */
+ {
+ if (++str == end)
+ goto ret_edom;
+ }
+
+ beg= str;
+ end9= (str + 9) > end ? end : (str + 9);
+ /* Accumulate small number into ulong, for performance purposes */
+ for (ul= 0 ; str < end9 && (ch= (unsigned char) (*str - '0')) < 10; str++)
+ {
+ ul= ul * 10 + ch;
+ }
+
+ if (str >= end) /* Small number without dots and expanents */
+ {
+ *endptr= (char*) str;
+ if (negative)
+ {
+ if (unsigned_flag)
+ {
+ *error= ul ? MY_ERRNO_ERANGE : 0;
+ return 0;
+ }
+ else
+ {
+ *error= 0;
+ return (ulonglong) (longlong) (long) -ul;
+ }
+ }
+ else
+ {
+ *error=0;
+ return (ulonglong) ul;
+ }
+ }
+
+ digits= str - beg;
+
+ /* Continue to accumulate into ulonglong */
+ for (dot= NULL, ull= ul; str < end; str++)
+ {
+ if ((ch= (unsigned char) (*str - '0')) < 10)
+ {
+ if (ull < CUTOFF || (ull == CUTOFF && ch <= CUTLIM))
+ {
+ ull= ull * 10 + ch;
+ digits++;
+ continue;
+ }
+ /*
+ Adding the next digit would overflow.
+ Remember the next digit in "addon", for rounding.
+ Scan all digits with an optional single dot.
+ */
+ if (ull == CUTOFF)
+ {
+ ull= ULONGLONG_MAX;
+ addon= 1;
+ str++;
+ }
+ else
+ addon= (*str >= '5');
+ for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++)
+ {
+ if (!dot)
+ shift++;
+ }
+ if (str < end && *str == '.' && !dot)
+ {
+ str++;
+ for ( ; str < end && (ch= (unsigned char) (*str - '0')) < 10; str++);
+ }
+ goto exp;
+ }
+
+ if (*str == '.')
+ {
+ if (dot)
+ {
+ /* The second dot character */
+ addon= 0;
+ goto exp;
+ }
+ else
+ {
+ dot= str + 1;
+ }
+ continue;
+ }
+
+ /* Unknown character, exit the loop */
+ break;
+ }
+ shift= dot ? dot - str : 0; /* Right shift */
+ addon= 0;
+
+exp: /* [ E [ <sign> ] <unsigned integer> ] */
+
+ if (!digits)
+ {
+ str= beg;
+ goto ret_edom;
+ }
+
+ if (str < end && (*str == 'e' || *str == 'E'))
+ {
+ str++;
+ if (str < end)
+ {
+ int negative_exp, exp;
+ if ((negative_exp= (*str == '-')) || *str=='+')
+ {
+ if (++str == end)
+ goto ret_sign;
+ }
+ for (exp= 0 ;
+ str < end && (ch= (unsigned char) (*str - '0')) < 10;
+ str++)
+ {
+ exp= exp * 10 + ch;
+ }
+ shift+= negative_exp ? -exp : exp;
+ }
+ }
+
+ if (shift == 0) /* No shift, check addon digit */
+ {
+ if (addon)
+ {
+ if (ull == ULONGLONG_MAX)
+ goto ret_too_big;
+ ull++;
+ }
+ goto ret_sign;
+ }
+
+ if (shift < 0) /* Right shift */
+ {
+ ulonglong d, r;
+
+ if (-shift >= DIGITS_IN_ULONGLONG)
+ goto ret_zero; /* Exponent is a big negative number, return 0 */
+
+ d= d10[-shift];
+ r= (ull % d) * 2;
+ ull /= d;
+ if (r >= d)
+ ull++;
+ goto ret_sign;
+ }
+
+ if (shift > DIGITS_IN_ULONGLONG) /* Huge left shift */
+ {
+ if (!ull)
+ goto ret_sign;
+ goto ret_too_big;
+ }
+
+ for ( ; shift > 0; shift--, ull*= 10) /* Left shift */
+ {
+ if (ull > CUTOFF)
+ goto ret_too_big; /* Overflow, number too big */
+ }
+
+ret_sign:
+ *endptr= (char*) str;
+
+ if (!unsigned_flag)
+ {
+ if (negative)
+ {
+ if (ull > (ulonglong) LONGLONG_MIN)
+ {
+ *error= MY_ERRNO_ERANGE;
+ return (ulonglong) LONGLONG_MIN;
+ }
+ *error= 0;
+ return (ulonglong) -ull;
+ }
+ else
+ {
+ if (ull > (ulonglong) LONGLONG_MAX)
+ {
+ *error= MY_ERRNO_ERANGE;
+ return (ulonglong) LONGLONG_MAX;
+ }
+ *error= 0;
+ return ull;
+ }
+ }
+
+ /* Unsigned number */
+ if (negative && ull)
+ {
+ *error= MY_ERRNO_ERANGE;
+ return 0;
+ }
+ *error= 0;
+ return ull;
+
+ret_zero:
+ *endptr= (char*) str;
+ *error= 0;
+ return 0;
+
+ret_edom:
+ *endptr= (char*) str;
+ *error= MY_ERRNO_EDOM;
+ return 0;
+
+ret_too_big:
+ *endptr= (char*) str;
+ *error= MY_ERRNO_ERANGE;
+ return unsigned_flag ?
+ ULONGLONG_MAX :
+ negative ? (ulonglong) LONGLONG_MIN : (ulonglong) LONGLONG_MAX;
+}
+
+
/*
Check if a constant can be propagated
@@ -1434,6 +1770,7 @@ MY_CHARSET_HANDLER my_charset_8bit_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 57d6d8bae2b..3854837e09a 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -4663,6 +4663,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index dc4f18b516b..85ebbe82731 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -891,6 +891,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index 97dca79e84b..4a60220f73e 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -974,6 +974,35 @@ double my_strntod_ucs2(CHARSET_INFO *cs __attribute__((unused)),
}
+ulonglong my_strntoull10rnd_ucs2(CHARSET_INFO *cs __attribute__((unused)),
+ const char *nptr, uint length, int unsign_fl,
+ char **endptr, int *err)
+{
+ char buf[256], *b= buf;
+ ulonglong res;
+ const uchar *end, *s= (const uchar*) nptr;
+ my_wc_t wc;
+ int cnv;
+
+ /* Cut too long strings */
+ if (length >= sizeof(buf))
+ length= sizeof(buf)-1;
+ end= s + length;
+
+ while ((cnv= cs->cset->mb_wc(cs,&wc,s,end)) > 0)
+ {
+ s+= cnv;
+ if (wc > (int) (uchar) 'e' || !wc)
+ break; /* Can't be a number part */
+ *b++= (char) wc;
+ }
+
+ res= my_strntoull10rnd_8bit(cs, buf, b - buf, unsign_fl, endptr, err);
+ *endptr= (char*) nptr + 2 * (uint) (*endptr- buf);
+ return res;
+}
+
+
/*
This is a fast version optimized for the case of radix 10 / -10
*/
@@ -1629,6 +1658,7 @@ MY_CHARSET_HANDLER my_charset_ucs2_handler=
my_strntoull_ucs2,
my_strntod_ucs2,
my_strtoll10_ucs2,
+ my_strntoull10rnd_ucs2,
my_scan_ucs2
};
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index ca27b4bef6b..675ac918e2c 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -8545,6 +8545,7 @@ static MY_CHARSET_HANDLER my_charset_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index 3594ab954c6..3a5c01a2861 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -2548,6 +2548,7 @@ MY_CHARSET_HANDLER my_charset_utf8_handler=
my_strntoull_8bit,
my_strntod_8bit,
my_strtoll10_8bit,
+ my_strntoull10rnd_8bit,
my_scan_8bit
};