diff options
Diffstat (limited to 'strings')
66 files changed, 442 insertions, 2501 deletions
diff --git a/strings/CHARSET_INFO.txt b/strings/CHARSET_INFO.txt index bb8e40025c7..6f0a810be37 100644 --- a/strings/CHARSET_INFO.txt +++ b/strings/CHARSET_INFO.txt @@ -208,14 +208,11 @@ charpos() - calculates the offset of the given position in the string. Used in SQL functions LEFT(), RIGHT(), SUBSTRING(), INSERT() -well_formed_length() - - finds the length of correctly formed multi-byte beginning. - Used in INSERTs to cut a beginning of the given string - which is - a) "well formed" according to the given character set. +well_formed_len() + - returns length of a given multi-byte string in bytes + Used in INSERTs to shorten the given string so it + a) is "well formed" according to the given character set b) can fit into the given data type - Terminates the string in the good position, taking in account - multi-byte character boundaries. lengthsp() - returns the length of the given string without trailing spaces. diff --git a/strings/Makefile.am b/strings/Makefile.am deleted file mode 100644 index a8732720e10..00000000000 --- a/strings/Makefile.am +++ /dev/null @@ -1,80 +0,0 @@ -# Copyright (C) 2000-2006 MySQL AB, 2009 Sun Microsystems, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# This file is public domain and comes with NO WARRANTY of any kind - -# -# Note that the string library is built with #define THREAD, -# which by default cause all the thread related code (my_pthread.h) -# and therefore the associated instrumentation (mysql/psi/mysql_thread.h) -# to be used. -# Since the string code itself is not instrumented, we use -# #define DISABLE_MYSQL_THREAD_H here to avoid unneeded dependencies. -# - -INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -DDISABLE_MYSQL_THREAD_H -pkglib_LIBRARIES = libmystrings.a - -# Exact one of ASSEMBLER_X -if ASSEMBLER_x86 -ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s -CSRCS = bfill.c bmove.c bchange.c strxnmov.c int2str.c str2int.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c dtoa.c strmov.c strmov_overlapp.c -else -#no assembler -ASRCS = -# These file MUST all be on the same line!! Otherwise automake -# generats a very broken makefile -CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bchange.c strxnmov.c int2str.c str2int.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c dtoa.c strmov_overlapp.c -endif - -libmystrings_a_SOURCES = $(ASRCS) $(CSRCS) -noinst_PROGRAMS = conf_to_src -CLEANFILES = str_test uctypedump test_decimal -# Default charset definitions -EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \ - ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ - ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \ - xml.c decimal.c strto.c strings-x86.s \ - longlong2str.c longlong2str-x86.s longlong2str_asm.c \ - my_strtoll10.c my_strtoll10-x86.s \ - strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ - strfill.c strcend.c is_prefix.c strstr.c \ - strmake.c strnmov.c strmov.c strnlen.c \ - t_ctype.h my_strchr.c CMakeLists.txt \ - CHARSET_INFO.txt strmov_overlapp.c - -libmystrings_a_LIBADD= -conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c -conf_to_src_LDADD= -#force static linking of conf_to_src - essential when linking against -#custom installation of libc -conf_to_src_LDFLAGS= @NOINST_LDFLAGS@ - -# This is because the dependency tracking misses @FOO@ vars in sources. -#strtoull.o: @CHARSET_OBJS@ - - -FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@ - -str_test: str_test.c $(pkglib_LIBRARIES) - $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LIBRARIES) - -uctypedump: uctypedump.c - $(LINK) $(INCLUDES) $(srcdir)/uctypedump.c - -test_decimal$(EXEEXT): decimal.c $(pkglib_LIBRARIES) - $(CP) $(srcdir)/decimal.c ./test_decimal.c - $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LIBRARIES) - $(RM) -f ./test_decimal.c diff --git a/strings/bchange.c b/strings/bchange.c index 0b2c62019b5..45eabacb767 100644 --- a/strings/bchange.c +++ b/strings/bchange.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/bfill.c b/strings/bfill.c deleted file mode 100644 index ccc063f59e3..00000000000 --- a/strings/bfill.c +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) 2002 MySQL AB - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; version 2 - of the License. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA */ - -/* File : bfill.c - Author : Richard A. O'Keefe. - Michael Widenius; ifdef MC68000 - Updated: 23 April 1984 - Defines: bfill() - - bfill(dst, len, fill) moves "len" fill characters to "dst". - Thus to set a buffer to 80 spaces, do bfill(buff, 80, ' '). -*/ - -#include <my_global.h> -#include "m_string.h" - -#if !defined(bfill) && !defined(HAVE_BFILL) - -void bfill(dst, len, fill) -register byte *dst; -register uint len; -register pchar fill; -{ - while (len-- != 0) *dst++ = fill; -} - -#endif diff --git a/strings/bmove.c b/strings/bmove.c deleted file mode 100644 index 0aa825558ca..00000000000 --- a/strings/bmove.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2002 MySQL AB - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; version 2 - of the License. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA */ - -/* File : bmove.c - Author : Richard A. O'Keefe. - Michael Widenius; ifdef MC68000 - Updated: 23 April 1984 - Defines: bmove() - - bmove(dst, src, len) moves exactly "len" bytes from the source "src" - to the destination "dst". It does not check for NUL characters as - strncpy() and strnmov() do. Thus if your C compiler doesn't support - structure assignment, you can simulate it with - bmove(&to, &from, sizeof from); - The standard 4.2bsd routine for this purpose is bcopy. But as bcopy - has its first two arguments the other way around you may find this a - bit easier to get right. - No value is returned. -*/ - -#include <my_global.h> -#include "m_string.h" - -#if !defined(HAVE_BMOVE) && !defined(bmove) - -void bmove(dst, src, len) -register char *dst; -register const char *src; -register uint len; -{ - while (len-- != 0) *dst++ = *src++; -} - -#endif diff --git a/strings/bmove_upp.c b/strings/bmove_upp.c index 05e786837f4..d466b69face 100644 --- a/strings/bmove_upp.c +++ b/strings/bmove_upp.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c index d7321d3a691..3217d1a4aa6 100644 --- a/strings/conf_to_src.c +++ b/strings/conf_to_src.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -251,7 +251,7 @@ static void fprint_copyright(FILE *file) { fprintf(file, -"/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.\n" +"/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.\n" "\n" " This program is free software; you can redistribute it and/or modify\n" " it under the terms of the GNU General Public License as published by\n" diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 691513ec92c..b093aa6b080 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index b67da6f5794..9738d1068b8 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp. +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. & tommy@valley.ne.jp. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c index 7d6874b6ebd..c7b01450779 100644 --- a/strings/ctype-cp932.c +++ b/strings/ctype-cp932.c @@ -1,5 +1,4 @@ - -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c index 81a5322d706..f0078a38bf0 100644 --- a/strings/ctype-czech.c +++ b/strings/ctype-czech.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 1e3279a93ad..5a6c2cb07d5 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-eucjpms.c b/strings/ctype-eucjpms.c index 2d5743070cb..edf29dc327b 100644 --- a/strings/ctype-eucjpms.c +++ b/strings/ctype-eucjpms.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp. +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. & tommy@valley.ne.jp. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c index 3e30931f579..57f900888a2 100644 --- a/strings/ctype-extra.c +++ b/strings/ctype-extra.c @@ -6,7 +6,7 @@ ./conf_to_src ../sql/share/charsets/ > FILE */ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1040,7 +1040,7 @@ static const uint16 to_uni_cp1251_bulgarian_ci[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -1730,7 +1730,7 @@ static const uint16 to_uni_cp1251_ukrainian_ci[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -3762,7 +3762,7 @@ static const uint16 to_uni_cp1251_bin[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -3877,7 +3877,7 @@ static const uint16 to_uni_cp1251_general_ci[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, @@ -3992,7 +3992,7 @@ static const uint16 to_uni_cp1251_general_cs[] = { 0x0070,0x0071,0x0072,0x0073,0x0074,0x0075,0x0076,0x0077, 0x0078,0x0079,0x007A,0x007B,0x007C,0x007D,0x007E,0x007F, 0x0402,0x0403,0x201A,0x0453,0x201E,0x2026,0x2020,0x2021, -0x0000,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, +0x20AC,0x2030,0x0409,0x2039,0x040A,0x040C,0x040B,0x040F, 0x0452,0x2018,0x2019,0x201C,0x201D,0x2022,0x2013,0x2014, 0x0000,0x2122,0x0459,0x203A,0x045A,0x045C,0x045B,0x045F, 0x00A0,0x040E,0x045E,0x0408,0x00A4,0x0490,0x00A6,0x00A7, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index a327b5d0cf4..940284c535a 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 01241e99624..0c5f67e206b 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index ae2590cddd5..4eba876a08f 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index 76af3ef2cdf..8d864dfaad5 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -636,7 +636,7 @@ static void pad_max_char(CHARSET_INFO *cs, char *str, char *end) DBUG_ASSERT(buflen > 0); do { - if ((str + buflen) < end) + if ((str + buflen) <= end) { /* Enough space for the characer */ memcpy(str, buf, buflen); @@ -683,7 +683,6 @@ my_bool my_like_range_mb(CHARSET_INFO *cs, char *min_end= min_str + res_length; char *max_end= max_str + res_length; size_t maxcharlen= res_length / cs->mbmaxlen; - my_bool have_contractions= my_uca_have_contractions(cs); for (; ptr != end && min_str != min_end && maxcharlen ; maxcharlen--) { @@ -751,8 +750,8 @@ fill_max_and_min: 'ab\min\min\min\min' and 'ab\max\max\max\max'. */ - if (have_contractions && ptr + 1 < end && - my_uca_can_be_contraction_head(cs, (uchar) *ptr)) + if (contraction_flags && ptr + 1 < end && + contraction_flags[(uchar) *ptr]) { /* Ptr[0] is a contraction head. */ @@ -774,8 +773,8 @@ fill_max_and_min: is not a contraction, then we put only ptr[0], and continue with ptr[1] on the next loop. */ - if (my_uca_can_be_contraction_tail(cs, (uchar) ptr[1]) && - my_uca_contraction2_weight(cs, (uchar) ptr[0], (uchar) ptr[1])) + if (contraction_flags[(uchar) ptr[1]] && + cs->contractions[(*ptr-0x40)*0x40 + ptr[1] - 0x40]) { /* Contraction found */ if (maxcharlen == 1 || min_str + 1 >= min_end) @@ -801,6 +800,192 @@ fill_max_and_min: } +/** + Calculate min_str and max_str that ranges a LIKE string. + Generic function, currently used for ucs2, utf16, utf32, + but should be suitable for any other character sets with + cs->min_sort_char and cs->max_sort_char represented in + Unicode code points. + + @param cs Character set and collation pointer + @param ptr Pointer to LIKE pattern. + @param ptr_length Length of LIKE pattern. + @param escape Escape character pattern, typically '\'. + @param w_one 'One character' pattern, typically '_'. + @param w_many 'Many characters' pattern, typically '%'. + @param res_length Length of min_str and max_str. + + @param[out] min_str Smallest string that ranges LIKE. + @param[out] max_str Largest string that ranges LIKE. + @param[out] min_len Length of min_str + @param[out] max_len Length of max_str + + @return Optimization status. + @retval FALSE if LIKE pattern can be optimized + @rerval TRUE if LIKE can't be optimized. +*/ +my_bool +my_like_range_generic(CHARSET_INFO *cs, + const char *ptr, size_t ptr_length, + pbool escape, pbool w_one, pbool w_many, + size_t res_length, + char *min_str,char *max_str, + size_t *min_length,size_t *max_length) +{ + const char *end= ptr + ptr_length; + const char *min_org= min_str; + const char *max_org= max_str; + char *min_end= min_str + res_length; + char *max_end= max_str + res_length; + size_t charlen= res_length / cs->mbmaxlen; + size_t res_length_diff; + my_bool have_contractions= my_cs_have_contractions(cs); + + for ( ; charlen > 0; charlen--) + { + my_wc_t wc, wc2; + int res; + if ((res= cs->cset->mb_wc(cs, &wc, (uchar*) ptr, (uchar*) end)) <= 0) + { + if (res == MY_CS_ILSEQ) /* Bad sequence */ + return TRUE; /* min_length and max_length are not important */ + break; /* End of the string */ + } + ptr+= res; + + if (wc == (my_wc_t) escape) + { + if ((res= cs->cset->mb_wc(cs, &wc, (uchar*) ptr, (uchar*) end)) <= 0) + { + if (res == MY_CS_ILSEQ) + return TRUE; /* min_length and max_length are not important */ + /* + End of the string: Escape is the last character. + Put escape as a normal character. + We'll will leave the loop on the next iteration. + */ + } + else + ptr+= res; + + /* Put escape character to min_str and max_str */ + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; /* No space */ + min_str+= res; + + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; /* No space */ + max_str+= res; + continue; + } + else if (wc == (my_wc_t) w_one) + { + if ((res= cs->cset->wc_mb(cs, cs->min_sort_char, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; + min_str+= res; + + if ((res= cs->cset->wc_mb(cs, cs->max_sort_char, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; + max_str+= res; + continue; + } + else if (wc == (my_wc_t) w_many) + { + /* + Calculate length of keys: + a\min\min... is the smallest possible string + a\max\max... is the biggest possible string + */ + *min_length= ((cs->state & MY_CS_BINSORT) ? + (size_t) (min_str - min_org) : + res_length); + *max_length= res_length; + goto pad_min_max; + } + + if (have_contractions && + my_cs_can_be_contraction_head(cs, wc) && + (res= cs->cset->mb_wc(cs, &wc2, (uchar*) ptr, (uchar*) end)) > 0) + { + uint16 *weight; + if ((wc2 == (my_wc_t) w_one || wc2 == (my_wc_t) w_many)) + { + /* Contraction head followed by a wildcard */ + *min_length= *max_length= res_length; + goto pad_min_max; + } + + if (my_cs_can_be_contraction_tail(cs, wc2) && + (weight= my_cs_contraction2_weight(cs, wc, wc2)) && weight[0]) + { + /* Contraction found */ + if (charlen == 1) + { + /* contraction does not fit to result */ + *min_length= *max_length= res_length; + goto pad_min_max; + } + + ptr+= res; + charlen--; + + /* Put contraction head */ + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; + min_str+= res; + + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; + max_str+= res; + wc= wc2; /* Prepare to put contraction tail */ + } + } + + /* Normal character, or contraction tail */ + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) min_str, (uchar*) min_end)) <= 0) + goto pad_set_lengths; + min_str+= res; + if ((res= cs->cset->wc_mb(cs, wc, + (uchar*) max_str, (uchar*) max_end)) <= 0) + goto pad_set_lengths; + max_str+= res; + } + +pad_set_lengths: + *min_length= (size_t) (min_str - min_org); + *max_length= (size_t) (max_str - max_org); + +pad_min_max: + /* + Fill up max_str and min_str to res_length. + fill() cannot set incomplete characters and + requires that "length" argument is divisible to mbminlen. + Make sure to call fill() with proper "length" argument. + */ + res_length_diff= res_length % cs->mbminlen; + cs->cset->fill(cs, min_str, min_end - min_str - res_length_diff, + cs->min_sort_char); + cs->cset->fill(cs, max_str, max_end - max_str - res_length_diff, + cs->max_sort_char); + + /* In case of incomplete characters set the remainder to 0x00's */ + if (res_length_diff) + { + /* Example: odd res_length for ucs2 */ + memset(min_end - res_length_diff, 0, res_length_diff); + memset(max_end - res_length_diff, 0, res_length_diff); + } + return FALSE; +} + + int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *str,const char *str_end, diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c index 6c1dcb7481e..3507bd279eb 100644 --- a/strings/ctype-simple.c +++ b/strings/ctype-simple.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 2b51ae6416f..7e06fe828ff 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index 29ec013849c..f62c2619e1f 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index fcef2c68967..a8b12e13e39 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 MySQL AB +/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -36,11 +36,6 @@ #include "m_ctype.h" -#define MY_UCA_CNT_FLAG_SIZE 4096 -#define MY_UCA_CNT_FLAG_MASK 4095 -#define MY_UCA_CNT_HEAD 1 -#define MY_UCA_CNT_TAIL 2 - #ifdef HAVE_UCA_COLLATIONS #define MY_UCA_NPAGES 256 @@ -6770,7 +6765,7 @@ typedef struct my_uca_scanner_st const uchar *send; /* End of the input string */ const uchar *uca_length; const uint16 * const *uca_weight; - const MY_CONTRACTIONS *contractions; + uint16 *contractions; uint16 implicit[2]; int page; int code; @@ -6790,80 +6785,6 @@ typedef struct my_uca_scanner_handler_st static const uint16 nochar[]= {0,0}; -/********** Helper functions to handle contraction ************/ - - -/** - Mark a character as a contraction part - - @cs Pointer to CHARSET_INFO data - @wc Unicode code point - @flag flag: "is contraction head", "is contraction tail" -*/ - -static void -my_uca_add_contraction_flag(CHARSET_INFO *cs, my_wc_t wc, int flag) -{ - cs->contractions->flags[wc & MY_UCA_CNT_FLAG_MASK]|= flag; -} - - -/** - Add a new contraction into contraction list - - @cs Pointer to CHARSET_INFO data - @wc Unicode code points of the characters - @len Number of characters - - @return New contraction - @retval Pointer to a newly added contraction -*/ - -static MY_CONTRACTION * -my_uca_add_contraction(struct charset_info_st *cs, - my_wc_t *wc, int len __attribute__((unused))) -{ - MY_CONTRACTIONS *list= (MY_CONTRACTIONS*) cs->contractions; - MY_CONTRACTION *next= &list->item[list->nitems]; - DBUG_ASSERT(len == 2); /* We currently support only contraction2 */ - next->ch[0]= wc[0]; - next->ch[1]= wc[1]; - list->nitems++; - return next; -} - - -/** - Allocate and initialize memory for contraction list and flags - - @cs Pointer to CHARSET_INFO data - @alloc Memory allocation function (typically points to my_alloc_once) - @n Number of contractions - - @return Error code - @retval 0 - memory allocated successfully - @retval 1 - not enough memory -*/ - -static my_bool -my_uca_alloc_contractions(struct charset_info_st *cs, - void *(*alloc)(size_t), size_t n) -{ - uint size= n * sizeof(MY_CONTRACTION); - MY_CONTRACTIONS *contractions; - - if (!(cs->contractions= contractions= (*alloc)(sizeof(MY_CONTRACTIONS)))) - return 1; - bzero(contractions, sizeof(MY_CONTRACTIONS)); - if (!(contractions->item= (*alloc)(size)) || - !(contractions->flags= (char*) (*alloc)(MY_UCA_CNT_FLAG_SIZE))) - return 1; - bzero(contractions->item, size); - bzero(contractions->flags, MY_UCA_CNT_FLAG_SIZE); - return 0; -} - - #ifdef HAVE_CHARSET_ucs2 /* Initialize collation weight scanner @@ -6883,7 +6804,7 @@ my_uca_alloc_contractions(struct charset_info_st *cs, */ static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner, - CHARSET_INFO *cs, + CHARSET_INFO *cs __attribute__((unused)), const uchar *str, size_t length) { scanner->wbeg= nochar; @@ -6894,7 +6815,6 @@ static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner, scanner->uca_length= cs->sort_order; scanner->uca_weight= cs->sort_order_big; scanner->contractions= cs->contractions; - scanner->cs= cs; return; } @@ -6983,23 +6903,18 @@ static int my_uca_scanner_next_ucs2(my_uca_scanner *scanner) if (scanner->contractions && (scanner->sbeg <= scanner->send)) { - my_wc_t wc1= ((scanner->page << 8) | scanner->code); + int cweight; - if (my_uca_can_be_contraction_head(scanner->cs, wc1)) - { - const uint16 *cweight; - my_wc_t wc2= (((my_wc_t) scanner->sbeg[0]) << 8) | scanner->sbeg[1]; - if (my_uca_can_be_contraction_tail(scanner->cs, wc2) && - (cweight= my_uca_contraction2_weight(scanner->cs, - scanner->code, - scanner->sbeg[1]))) + if (!scanner->page && !scanner->sbeg[0] && + (scanner->sbeg[1] > 0x40) && (scanner->sbeg[1] < 0x80) && + (scanner->code > 0x40) && (scanner->code < 0x80) && + (cweight= scanner->contractions[(scanner->code-0x40)*0x40+scanner->sbeg[1]-0x40])) { scanner->implicit[0]= 0; scanner->wbeg= scanner->implicit; scanner->sbeg+=2; - return *cweight; + return cweight; } - } } if (!ucaw[scanner->page]) @@ -7091,22 +7006,23 @@ static int my_uca_scanner_next_any(my_uca_scanner *scanner) scanner->code= wc & 0xFF; } - if (my_uca_have_contractions(scanner->cs) && - my_uca_can_be_contraction_head(scanner->cs, wc)) + if (scanner->contractions && !scanner->page && + (scanner->code > 0x40) && (scanner->code < 0x80)) { - my_wc_t wc2; - const uint16 *cweight; + uint page1, code1, cweight; - if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc2, + if (((mb_len= scanner->cs->cset->mb_wc(scanner->cs, &wc, scanner->sbeg, scanner->send)) >=0) && - my_uca_can_be_contraction_tail(scanner->cs, wc2) && - (cweight= my_uca_contraction2_weight(scanner->cs, wc, wc2))) + (!(page1= (wc >> 8))) && + ((code1= (wc & 0xFF)) > 0x40) && + (code1 < 0x80) && + (cweight= scanner->contractions[(scanner->code-0x40)*0x40 + code1-0x40])) { scanner->implicit[0]= 0; scanner->wbeg= scanner->implicit; scanner->sbeg+= mb_len; - return *cweight; + return cweight; } } @@ -7145,31 +7061,6 @@ static my_uca_scanner_handler my_any_uca_scanner_handler= -/** - Helper function: - Find address of weights of the given character. - - @weights UCA weight array - @lengths UCA length array - @ch character Unicode code point - - @return Weight array - @retval pointer to weight array for the given character, - or NULL if this page does not have implicit weights. -*/ - -static inline const uint16 * -my_char_weight_addr(CHARSET_INFO *cs, uint wc) -{ - uint page= (wc >> 8); - uint ofst= wc & 0xFF; - return (cs->sort_order_big[page] ? - cs->sort_order_big[page] + ofst * cs->sort_order[page] : - 0); -} - - - /* Compares two strings according to the collation @@ -7846,8 +7737,8 @@ ex: typedef struct my_coll_rule_item_st { - my_wc_t base; /* Base character */ - my_wc_t curr[2]; /* Current character */ + uint base; /* Base character */ + uint curr[2]; /* Current character */ int diff[3]; /* Primary, Secondary and Tertiary difference */ } MY_COLL_RULE; @@ -8002,7 +7893,6 @@ static my_bool create_tailoring(struct charset_info_st *cs, void *(*alloc)(size_t)) { MY_COLL_RULE rule[MY_MAX_COLL_RULE]; - MY_COLL_RULE *r, *rfirst, *rlast; char errstr[128]; uchar *newlengths; uint16 **newweights; @@ -8027,9 +7917,6 @@ static my_bool create_tailoring(struct charset_info_st *cs, return 1; } - rfirst= rule; - rlast= rule + rc; - if (!cs->caseinfo) cs->caseinfo= my_unicase_default; @@ -8113,21 +8000,44 @@ static my_bool create_tailoring(struct charset_info_st *cs, /* Now process contractions */ if (ncontractions) { - if (my_uca_alloc_contractions(cs, alloc, ncontractions)) - return 1; - for (r= rfirst; r < rlast; r++) + /* + 8K for weights for basic latin letter pairs, + plus 256 bytes for "is contraction part" flags. + */ + uint size= 0x40*0x40*sizeof(uint16) + 256; + char *contraction_flags; + if (!(cs->contractions= (uint16*) (*alloc)(size))) + return 1; + bzero((void*)cs->contractions, size); + contraction_flags= ((char*) cs->contractions) + 0x40*0x40; + for (i=0; i < rc; i++) { - uint16 *to; - if (r->curr[1]) /* Contraction */ + if (rule[i].curr[1]) { - /* Mark both letters as "is contraction part" */ - my_uca_add_contraction_flag(cs, r->curr[0], MY_UCA_CNT_HEAD); - my_uca_add_contraction_flag(cs, r->curr[1], MY_UCA_CNT_TAIL); - to= my_uca_add_contraction(cs, r->curr, 2)->weight; - /* Copy weight from the reset character */ - to[0]= my_char_weight_addr(cs, r->base)[0]; - /* Apply primary difference */ - to[0]+= r->diff[0]; + uint pageb= (rule[i].base >> 8) & 0xFF; + uint chb= rule[i].base & 0xFF; + uint16 *offsb= defweights[pageb] + chb*deflengths[pageb]; + uint offsc; + + if (offsb[1] || + rule[i].curr[0] < 0x40 || rule[i].curr[0] > 0x7f || + rule[i].curr[1] < 0x40 || rule[i].curr[1] > 0x7f) + { + /* + TODO: add error reporting; + We support only basic latin letters contractions at this point. + Also, We don't support contractions with weight longer than one. + Otherwise, we'd need much more memory. + */ + return 1; + } + offsc= (rule[i].curr[0]-0x40)*0x40+(rule[i].curr[1]-0x40); + + /* Copy base weight applying primary difference */ + cs->contractions[offsc]= offsb[0] + rule[i].diff[0]; + /* Mark both letters as "is contraction part */ + contraction_flags[rule[i].curr[0]]= 1; + contraction_flags[rule[i].curr[1]]= 1; } } } @@ -8229,7 +8139,7 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler = my_strnncollsp_ucs2_uca, my_strnxfrm_ucs2_uca, my_strnxfrmlen_simple, - my_like_range_ucs2, + my_like_range_generic, my_wildcmp_uca, NULL, my_instr_mb, @@ -9593,7 +9503,7 @@ struct charset_info_st my_charset_utf8_sinhala_uca_ci= 8, /* strxfrm_multiply */ 1, /* caseup_multiply */ 1, /* casedn_multiply */ - 3, /* mbminlen */ + 1, /* mbminlen */ 3, /* mbmaxlen */ 9, /* min_sort_char */ 0xFFFF, /* max_sort_char */ @@ -10330,7 +10240,7 @@ MY_COLLATION_HANDLER my_collation_utf32_uca_handler = my_strnncollsp_any_uca, my_strnxfrm_any_uca, my_strnxfrmlen_simple, - my_like_range_utf32, + my_like_range_generic, my_wildcmp_uca, NULL, my_instr_mb, @@ -11028,7 +10938,7 @@ MY_COLLATION_HANDLER my_collation_utf16_uca_handler = my_strnncollsp_any_uca, my_strnxfrm_any_uca, my_strnxfrmlen_simple, - my_like_range_utf16, + my_like_range_generic, my_wildcmp_uca, NULL, my_instr_mb, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index e9c69c628da..64652bf6d36 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -903,7 +903,8 @@ static void my_fill_mb2(CHARSET_INFO *cs __attribute__((unused)), char *s, size_t l, int fill) { - for ( ; l >= 2; s[0]= 0, s[1]= fill, s+= 2, l-= 2); + DBUG_ASSERT(fill <= 0xFFFF); + for ( ; l >= 2; s[0]= (fill >> 8), s[1]= (fill & 0xFF), s+= 2, l-= 2); } @@ -1205,12 +1206,10 @@ my_strnncoll_utf16(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res, t_res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se= s + slen; const uchar *te= t + tlen; MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; - LINT_INIT(s_wc); - LINT_INIT(t_wc); while (s < se && t < te) { @@ -1271,11 +1270,9 @@ my_strnncollsp_utf16(CHARSET_INFO *cs, my_bool diff_if_only_endspace_difference) { int res; - my_wc_t s_wc, t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se= s + slen, *te= t + tlen; MY_UNICASE_INFO *const *uni_plane= cs->caseinfo; - LINT_INIT(s_wc); - LINT_INIT(t_wc); DBUG_ASSERT((slen % 2) == 0); DBUG_ASSERT((tlen % 2) == 0); @@ -1451,17 +1448,15 @@ my_strnncoll_utf16_bin(CHARSET_INFO *cs, my_bool t_is_prefix) { int s_res,t_res; - my_wc_t s_wc,t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se=s+slen; const uchar *te=t+tlen; - LINT_INIT(s_wc); - LINT_INIT(t_wc); while ( s < se && t < te ) { s_res= my_utf16_uni(cs,&s_wc, s, se); t_res= my_utf16_uni(cs,&t_wc, t, te); - + if (s_res <= 0 || t_res <= 0) { /* Incorrect string, compare by char value */ @@ -1469,9 +1464,9 @@ my_strnncoll_utf16_bin(CHARSET_INFO *cs, } if (s_wc != t_wc) { - return my_bincmp(s, s + s_res, t, t + t_res); + return s_wc > t_wc ? 1 : -1; } - + s+= s_res; t+= t_res; } @@ -1486,10 +1481,8 @@ my_strnncollsp_utf16_bin(CHARSET_INFO *cs, my_bool diff_if_only_endspace_difference) { int res; - my_wc_t s_wc, t_wc; + my_wc_t UNINIT_VAR(s_wc), UNINIT_VAR(t_wc); const uchar *se= s + slen, *te= t + tlen; - LINT_INIT(s_wc); - LINT_INIT(t_wc); DBUG_ASSERT((slen % 2) == 0); DBUG_ASSERT((tlen % 2) == 0); @@ -1511,7 +1504,7 @@ my_strnncollsp_utf16_bin(CHARSET_INFO *cs, if (s_wc != t_wc) { - return my_bincmp(s, s + s_res, t, t + t_res); + return s_wc > t_wc ? 1 : -1; } s+= s_res; @@ -1571,98 +1564,6 @@ my_hash_sort_utf16_bin(CHARSET_INFO *cs __attribute__((unused)), } -/** - Calculate min_str and max_str that ranges a LIKE string. - - @param ptr Pointer to LIKE pattern. - @param ptr_length Length of LIKE pattern. - @param escape Escape character in LIKE. (Normally '\'). - All escape characters should be removed - from min_str and max_str. - @param res_length Length of min_str and max_str. - @param min_str Smallest case sensitive string that ranges LIKE. - Should be space padded to res_length. - @param max_str Largest case sensitive string that ranges LIKE. - Normally padded with the biggest character sort value. - - @return Optimization status. - @retval FALSE if LIKE pattern can be optimized - @rerval TRUE if LIKE can't be optimized. -*/ - -my_bool -my_like_range_utf16(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str,char *max_str, - size_t *min_length,size_t *max_length) -{ - const char *end=ptr+ptr_length; - char *min_org=min_str; - char *min_end=min_str+res_length; - size_t charlen= res_length / cs->mbmaxlen; - - for ( ; ptr + 1 < end && min_str + 1 < min_end && charlen > 0 - ; ptr+=2, charlen--) - { - if (ptr[0] == '\0' && ptr[1] == escape && ptr + 1 < end) - { - ptr+=2; /* Skip escape */ - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_one) /* '_' in SQL */ - { - *min_str++= (char) (cs->min_sort_char >> 8); - *min_str++= (char) (cs->min_sort_char & 255); - *max_str++= (char) (cs->max_sort_char >> 8); - *max_str++= (char) (cs->max_sort_char & 255); - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_many) /* '%' in SQL */ - { - /* - Calculate length of keys: - 'a\0\0... is the smallest possible string when we have space expand - a\ff\ff... is the biggest possible string - */ - *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; - do { - *min_str++ = 0; - *min_str++ = 0; - *max_str++ = (char) (cs->max_sort_char >> 8); - *max_str++ = (char) (cs->max_sort_char & 255); - } while (min_str + 1 < min_end); - return FALSE; - } - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - } - - /* Temporary fix for handling w_one at end of string (key compression) */ - { - char *tmp; - for (tmp= min_str ; tmp-1 > min_org && tmp[-1] == '\0' && tmp[-2]=='\0';) - { - *--tmp=' '; - *--tmp='\0'; - } - } - - *min_length= *max_length = (size_t) (min_str - min_org); - while (min_str + 1 < min_end) - { - *min_str++ = *max_str++ = '\0'; - *min_str++ = *max_str++ = ' '; /* Because if key compression */ - } - return FALSE; -} - - static MY_COLLATION_HANDLER my_collation_utf16_general_ci_handler = { NULL, /* init */ @@ -1670,7 +1571,7 @@ static MY_COLLATION_HANDLER my_collation_utf16_general_ci_handler = my_strnncollsp_utf16, my_strnxfrm_unicode, my_strnxfrmlen_simple, - my_like_range_utf16, + my_like_range_generic, my_wildcmp_utf16_ci, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -1686,7 +1587,7 @@ static MY_COLLATION_HANDLER my_collation_utf16_bin_handler = my_strnncollsp_utf16_bin, my_strnxfrm_unicode_full_bin, my_strnxfrmlen_unicode_full_bin, - my_like_range_utf16, + my_like_range_generic, my_wildcmp_utf16_bin, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -2559,113 +2460,6 @@ my_strnncollsp_utf32_bin(CHARSET_INFO *cs __attribute__((unused)), } -/** - Calculate min_str and max_str that ranges a LIKE string. - - @param ptr Pointer to LIKE pattern. - @param ptr_length Length of LIKE pattern. - @param escape Escape character in LIKE. (Normally '\'). - All escape characters should be removed - from min_str and max_str. - @param res_length Length of min_str and max_str. - @param min_str Smallest case sensitive string that ranges LIKE. - Should be space padded to res_length. - @param max_str Largest case sensitive string that ranges LIKE. - Normally padded with the biggest character sort value. - - @return Optimization status. - @retval FALSE if LIKE pattern can be optimized - @rerval TRUE if LIKE can't be optimized. -*/ - -my_bool -my_like_range_utf32(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str,char *max_str, - size_t *min_length,size_t *max_length) -{ - const char *end= ptr + ptr_length; - char *min_org= min_str; - char *min_end= min_str + res_length; - char *max_end= max_str + res_length; - size_t charlen= res_length / cs->mbmaxlen; - - DBUG_ASSERT((res_length % 4) == 0); - - for ( ; charlen > 0; ptr+= 4, charlen--) - { - my_wc_t wc; - int res; - if ((res= my_utf32_uni(cs, &wc, (uchar*) ptr, (uchar*) end)) < 0) - { - my_fill_utf32(cs, min_str, min_end - min_str, cs->min_sort_char); - my_fill_utf32(cs, max_str, min_end - min_str, cs->max_sort_char); - /* min_length and max_legnth are not important */ - return TRUE; - } - - if (wc == (my_wc_t) escape) - { - ptr+= 4; /* Skip escape */ - if ((res= my_utf32_uni(cs, &wc, (uchar*) ptr, (uchar*) end)) < 0) - { - my_fill_utf32(cs, min_str, min_end - min_str, cs->min_sort_char); - my_fill_utf32(cs, max_str, max_end - min_str, cs->max_sort_char); - /* min_length and max_length are not important */ - return TRUE; - } - if (my_uni_utf32(cs, wc, (uchar*) min_str, (uchar*) min_end) != 4 || - my_uni_utf32(cs, wc, (uchar*) max_str, (uchar*) max_end) != 4) - goto pad_set_lengths; - *min_str++= 4; - *max_str++= 4; - continue; - } - - if (wc == (my_wc_t) w_one) - { - if (my_uni_utf32(cs, cs->min_sort_char, (uchar*) min_str, (uchar*) min_end) != 4 || - my_uni_utf32(cs, cs->max_sort_char, (uchar*) max_str, (uchar*) max_end) != 4) - goto pad_set_lengths; - min_str+= 4; - max_str+= 4; - continue; - } - - if (wc == (my_wc_t) w_many) - { - /* - Calculate length of keys: - 'a\0\0... is the smallest possible string when we have space expand - a\ff\ff... is the biggest possible string - */ - *min_length= ((cs->state & MY_CS_BINSORT) ? - (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; - goto pad_min_max; - } - - /* Normal character */ - if (my_uni_utf32(cs, wc, (uchar*) min_str, (uchar*) min_end) != 4 || - my_uni_utf32(cs, wc, (uchar*) max_str, (uchar*) max_end) != 4) - goto pad_set_lengths; - min_str+= 4; - max_str+= 4; - } - -pad_set_lengths: - *min_length= *max_length= (size_t) (min_str - min_org); - -pad_min_max: - my_fill_utf32(cs, min_str, min_end - min_str, cs->min_sort_char); - my_fill_utf32(cs, max_str, max_end - max_str, cs->max_sort_char); - return FALSE; -} - - static size_t my_scan_utf32(CHARSET_INFO *cs, const char *str, const char *end, int sequence_type) @@ -2697,7 +2491,7 @@ static MY_COLLATION_HANDLER my_collation_utf32_general_ci_handler = my_strnncollsp_utf32, my_strnxfrm_unicode, my_strnxfrmlen_utf32, - my_like_range_utf32, + my_like_range_generic, my_wildcmp_utf32_ci, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -2713,7 +2507,7 @@ static MY_COLLATION_HANDLER my_collation_utf32_bin_handler = my_strnncollsp_utf32_bin, my_strnxfrm_unicode_full_bin, my_strnxfrmlen_unicode_full_bin, - my_like_range_utf32, + my_like_range_generic, my_wildcmp_utf32_bin, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -2899,7 +2693,10 @@ static int my_uni_ucs2(CHARSET_INFO *cs __attribute__((unused)) , { if ( r+2 > e ) return MY_CS_TOOSMALL2; - + + if (wc > 0xFFFF) /* UCS2 does not support characters outside BMP */ + return MY_CS_ILUNI; + r[0]= (uchar) (wc >> 8); r[1]= (uchar) (wc & 0xFF); return 2; @@ -3261,129 +3058,6 @@ void my_hash_sort_ucs2_bin(CHARSET_INFO *cs __attribute__((unused)), } -static inline my_wc_t -ucs2_to_wc(const uchar *ptr) -{ - return (((uint) ptr[0]) << 8) + ptr[1]; -} - - -/* -** Calculate min_str and max_str that ranges a LIKE string. -** Arguments: -** ptr Pointer to LIKE string. -** ptr_length Length of LIKE string. -** escape Escape character in LIKE. (Normally '\'). -** All escape characters should be removed from min_str and max_str -** res_length Length of min_str and max_str. -** min_str Smallest case sensitive string that ranges LIKE. -** Should be space padded to res_length. -** max_str Largest case sensitive string that ranges LIKE. -** Normally padded with the biggest character sort value. -** -** The function should return 0 if ok and 1 if the LIKE string can't be -** optimized ! -*/ - -my_bool my_like_range_ucs2(CHARSET_INFO *cs, - const char *ptr, size_t ptr_length, - pbool escape, pbool w_one, pbool w_many, - size_t res_length, - char *min_str,char *max_str, - size_t *min_length,size_t *max_length) -{ - const char *end=ptr+ptr_length; - char *min_org=min_str; - char *min_end=min_str+res_length; - size_t charlen= res_length / cs->mbmaxlen; - my_bool have_contractions= my_uca_have_contractions(cs); - - for ( ; ptr + 1 < end && min_str + 1 < min_end && charlen > 0 - ; ptr+=2, charlen--) - { - my_wc_t wc; - if (ptr[0] == '\0' && ptr[1] == escape && ptr + 1 < end) - { - ptr+=2; /* Skip escape */ - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_one) /* '_' in SQL */ - { - *min_str++= (char) (cs->min_sort_char >> 8); - *min_str++= (char) (cs->min_sort_char & 255); - *max_str++= (char) (cs->max_sort_char >> 8); - *max_str++= (char) (cs->max_sort_char & 255); - continue; - } - if (ptr[0] == '\0' && ptr[1] == w_many) /* '%' in SQL */ - { -fill_max_and_min: - /* - Calculate length of keys: - 'a\0\0... is the smallest possible string when we have space expand - a\ff\ff... is the biggest possible string - */ - *min_length= ((cs->state & MY_CS_BINSORT) ? (size_t) (min_str - min_org) : - res_length); - *max_length= res_length; - do { - *min_str++ = 0; - *min_str++ = 0; - *max_str++ = (char) (cs->max_sort_char >> 8); - *max_str++ = (char) (cs->max_sort_char & 255); - } while (min_str + 1 < min_end); - return 0; - } - - if (have_contractions && ptr + 3 < end && - my_uca_can_be_contraction_head(cs, (wc= ucs2_to_wc((uchar*) ptr)))) - { - my_wc_t wc2; - /* Contraction head found */ - if (ptr[2] == '\0' && (ptr[3] == w_one || ptr[3] == w_many)) - { - /* Contraction head followed by a wildcard, quit */ - goto fill_max_and_min; - } - - /* - Check if the second letter can be contraction part, - and if two letters really produce a contraction. - */ - if (my_uca_can_be_contraction_tail(cs, (wc2= ucs2_to_wc((uchar*) ptr + 2))) && - my_uca_contraction2_weight(cs, wc , wc2)) - { - /* Contraction found */ - if (charlen == 1 || min_str + 2 >= min_end) - { - /* Full contraction doesn't fit, quit */ - goto fill_max_and_min; - } - - /* Put contraction head */ - *min_str++= *max_str++= *ptr++; - *min_str++= *max_str++= *ptr++; - charlen--; - } - } - /* Put contraction tail, or a single character */ - *min_str++= *max_str++ = ptr[0]; - *min_str++= *max_str++ = ptr[1]; - } - - *min_length= *max_length = (size_t) (min_str - min_org); - while (min_str + 1 < min_end) - { - *min_str++ = *max_str++ = '\0'; - *min_str++ = *max_str++ = ' '; /* Because if key compression */ - } - return 0; -} - - - static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = { NULL, /* init */ @@ -3391,7 +3065,7 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler = my_strnncollsp_ucs2, my_strnxfrm_unicode, my_strnxfrmlen_simple, - my_like_range_ucs2, + my_like_range_generic, my_wildcmp_ucs2_ci, my_strcasecmp_mb2_or_mb4, my_instr_mb, @@ -3407,7 +3081,7 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler = my_strnncollsp_ucs2_bin, my_strnxfrm_unicode, my_strnxfrmlen_simple, - my_like_range_ucs2, + my_like_range_generic, my_wildcmp_ucs2_bin, my_strcasecmp_mb2_or_mb4, my_instr_mb, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index 0f6cf990701..5ef752412d6 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB & tommy@valley.ne.jp. +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. & tommy@valley.ne.jp. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 4b0265693b6..729d9c41a54 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -1965,17 +1965,6 @@ my_strnxfrm_unicode_full_bin(CHARSET_INFO *cs, if ((res= cs->cset->mb_wc(cs, &wc, src, se)) <= 0) break; src+= res; - if (cs->mbminlen == 2) /* utf16_bin */ - { - /* - Reorder code points to weights as follows: - U+0000..U+D7FF -> [00][00][00]..[00][D7][FF] BMP part #1 - U+10000..U+10FFFF -> [01][00][00]..[10][FF][FF] Supplementary - U+E000..U+FFFF -> [20][E0][00]..[20][FF][FF] BMP part #2 - */ - if (wc >= 0xE000 && wc <= 0xFFFF) - wc+= 0x200000; - } *dst++= (uchar) (wc >> 16); *dst++= (uchar) ((wc >> 8) & 0xFF); *dst++= (uchar) (wc & 0xFF); diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c index ba61a3bbeea..9a6d21567ed 100644 --- a/strings/ctype-win1250ch.c +++ b/strings/ctype-win1250ch.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 MySQL AB +/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/ctype.c b/strings/ctype.c index 873255ad0d8..338ed75198a 100644 --- a/strings/ctype.c +++ b/strings/ctype.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/decimal.c b/strings/decimal.c index d606bebf152..6e0edf6a513 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,8 +13,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#line 18 "decimal.c" - /* ======================================================================= NOTE: this library implements SQL standard "exact numeric" type @@ -250,7 +248,7 @@ void max_decimal(int precision, int frac, decimal_t *to) } -static dec1 *remove_leading_zeroes(decimal_t *from, int *intg_result) +static dec1 *remove_leading_zeroes(const decimal_t *from, int *intg_result) { int intg= from->intg, i; dec1 *buf0= from->buf; @@ -314,8 +312,8 @@ int decimal_actual_fraction(decimal_t *from) from - value to convert to - points to buffer where string representation should be stored - *to_len - in: size of to buffer - out: length of the actually written string + *to_len - in: size of to buffer (incl. terminating '\0') + out: length of the actually written string (excl. '\0') fixed_precision - 0 if representation can be variable length and fixed_decimals will not be checked in this case. Put number as with fixed point position with this @@ -328,10 +326,11 @@ int decimal_actual_fraction(decimal_t *from) E_DEC_OK/E_DEC_TRUNCATED/E_DEC_OVERFLOW */ -int decimal2string(decimal_t *from, char *to, int *to_len, +int decimal2string(const decimal_t *from, char *to, int *to_len, int fixed_precision, int fixed_decimals, char filler) { + /* {intg_len, frac_len} output widths; {intg, frac} places in input */ int len, intg, frac= from->frac, i, intg_len, frac_len, fill; /* number digits before decimal point */ int fixed_intg= (fixed_precision ? @@ -944,7 +943,7 @@ fatal_error: E_DEC_OK/E_DEC_OVERFLOW/E_DEC_TRUNCATED */ -int decimal2double(decimal_t *from, double *to) +int decimal2double(const decimal_t *from, double *to) { char strbuf[FLOATING_POINT_BUFFER], *end; int len= sizeof(strbuf); @@ -1463,7 +1462,7 @@ int decimal_bin_size(int precision, int scale) */ int -decimal_round(decimal_t *from, decimal_t *to, int scale, +decimal_round(const decimal_t *from, decimal_t *to, int scale, decimal_round_mode mode) { int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1, @@ -1697,7 +1696,7 @@ int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param) return -1; /* shut up the warning */ } -static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to) +static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to) { int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac), @@ -1779,7 +1778,7 @@ static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to) /* to=from1-from2. if to==0, return -1/0/+1 - the result of the comparison */ -static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) +static int do_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to) { int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac); @@ -1849,7 +1848,7 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) /* ensure that always from1 > from2 (and intg1 >= intg2) */ if (carry) { - swap_variables(decimal_t *,from1,from1); + swap_variables(const decimal_t *, from1, from2); swap_variables(dec1 *,start1, start2); swap_variables(int,intg1,intg2); swap_variables(int,frac1,frac2); @@ -1915,35 +1914,35 @@ static int do_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) return error; } -int decimal_intg(decimal_t *from) +int decimal_intg(const decimal_t *from) { int res; remove_leading_zeroes(from, &res); return res; } -int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to) +int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to) { if (likely(from1->sign == from2->sign)) return do_add(from1, from2, to); return do_sub(from1, from2, to); } -int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to) +int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to) { if (likely(from1->sign == from2->sign)) return do_sub(from1, from2, to); return do_add(from1, from2, to); } -int decimal_cmp(decimal_t *from1, decimal_t *from2) +int decimal_cmp(const decimal_t *from1, const decimal_t *from2) { if (likely(from1->sign == from2->sign)) return do_sub(from1, from2, 0); return from1->sign > from2->sign ? -1 : 1; } -int decimal_is_zero(decimal_t *from) +int decimal_is_zero(const decimal_t *from) { dec1 *buf1=from->buf, *end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac); @@ -1974,7 +1973,7 @@ int decimal_is_zero(decimal_t *from) XXX if this library is to be used with huge numbers of thousands of digits, fast multiplication must be implemented. */ -int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) +int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to) { int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac), @@ -2098,8 +2097,8 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) changed to malloc (or at least fallback to malloc if alloca() fails) but then, decimal_mul() should be rewritten too :( */ -static int do_div_mod(decimal_t *from1, decimal_t *from2, - decimal_t *to, decimal_t *mod, int scale_incr) +static int do_div_mod(const decimal_t *from1, const decimal_t *from2, + decimal_t *to, decimal_t *mod, int scale_incr) { int frac1=ROUND_UP(from1->frac)*DIG_PER_DEC1, prec1=from1->intg+frac1, frac2=ROUND_UP(from2->frac)*DIG_PER_DEC1, prec2=from2->intg+frac2, @@ -2184,9 +2183,12 @@ static int do_div_mod(decimal_t *from1, decimal_t *from2, } buf0=to->buf; stop0=buf0+intg0+frac0; + DBUG_ASSERT(stop0 <= &to->buf[to->len]); if (likely(div_mod)) - while (dintg++ < 0) + while (dintg++ < 0 && buf0 < &to->buf[to->len]) + { *buf0++=0; + } len1=(i=ROUND_UP(prec1))+ROUND_UP(2*frac2+scale_incr+1) + 1; set_if_bigger(len1, 3); @@ -2358,7 +2360,8 @@ done: */ int -decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr) +decimal_div(const decimal_t *from1, const decimal_t *from2, decimal_t *to, + int scale_incr) { return do_div_mod(from1, from2, to, 0, scale_incr); } @@ -2390,7 +2393,7 @@ decimal_div(decimal_t *from1, decimal_t *from2, decimal_t *to, int scale_incr) thus, there's no requirement for M or N to be integers */ -int decimal_mod(decimal_t *from1, decimal_t *from2, decimal_t *to) +int decimal_mod(const decimal_t *from1, const decimal_t *from2, decimal_t *to) { return do_div_mod(from1, from2, 0, to, 0); } diff --git a/strings/do_ctype.c b/strings/do_ctype.c index f87d55b6251..9bdbd3d27eb 100644 --- a/strings/do_ctype.c +++ b/strings/do_ctype.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/dtoa.c b/strings/dtoa.c index d64c420b499..59aa056df9c 100644 --- a/strings/dtoa.c +++ b/strings/dtoa.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 MySQL AB +/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/dump_map.c b/strings/dump_map.c index e2b8b7db077..60bd91541c4 100644 --- a/strings/dump_map.c +++ b/strings/dump_map.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003-2004 MySQL AB +/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/int2str.c b/strings/int2str.c index 63cda79d23b..d292594e1d9 100644 --- a/strings/int2str.c +++ b/strings/int2str.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/is_prefix.c b/strings/is_prefix.c index 451cd468b7e..370927a24cd 100644 --- a/strings/is_prefix.c +++ b/strings/is_prefix.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/llstr.c b/strings/llstr.c index 678f8b05f39..1ad798397b7 100644 --- a/strings/llstr.c +++ b/strings/llstr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/longlong2str-x86.s b/strings/longlong2str-x86.s deleted file mode 100644 index 3de43a96e78..00000000000 --- a/strings/longlong2str-x86.s +++ /dev/null @@ -1,216 +0,0 @@ -# Copyright (C) 2000 MySQL AB -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# Optimized longlong2str function for Intel 80x86 (gcc/gas syntax) -# Some set sequences are optimized for pentuimpro II - - .file "longlong2str-x86.s" - .version "1.02" - -.text - .align 4 - -.globl longlong2str_with_dig_vector - .type longlong2str_with_dig_vector,@function - -longlong2str_with_dig_vector: - subl $80,%esp # Temporary buffer for up to 64 radix-2 digits - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - movl 100(%esp),%esi # esi = Lower part of val - movl 112(%esp),%ebx # ebx = Radix - movl 104(%esp),%ebp # ebp = Higher part of val - movl 108(%esp),%edi # edi = dst - - testl %ebx,%ebx - jge .L144 # Radix was positive - negl %ebx # Change radix to positive - testl %ebp,%ebp # Test if given value is negative - jge .L144 - movb $45,(%edi) # Add sign - incl %edi # Change sign of val - negl %esi - adcl $0,%ebp - negl %ebp - -.L144: # Test that radix is between 2 and 36 - movl %ebx, %eax - addl $-2,%eax # Test that radix is between 2 and 36 - cmpl $34,%eax - ja .Lerror # Radix was not in range - - leal 92(%esp),%ecx # End of buffer - movl %edi, 108(%esp) # Store possible modified dest - movl 116(%esp), %edi # dig_vec_upper - testl %ebp,%ebp # Test if value > 0xFFFFFFFF - jne .Llongdiv - cmpl %ebx, %esi # Test if <= radix, for easy loop - movl %esi, %eax # Value in eax (for Llow) - jae .Llow - - # Value is one digit (negative or positive) - movb (%eax,%edi),%bl - movl 108(%esp),%edi # get dst - movb %bl,(%edi) - incl %edi # End null here - jmp .L10_end - -.Llongdiv: - # Value in ebp:esi. div the high part by the radix, - # then div remainder + low part by the radix. - movl %ebp,%eax # edx=0,eax=high(from ebp) - xorl %edx,%edx - decl %ecx - divl %ebx - movl %eax,%ebp # edx=result of last, eax=low(from esi) - movl %esi,%eax - divl %ebx - movl %eax,%esi # ebp:esi = quotient - movb (%edx,%edi),%dl # Store result number in temporary buffer - testl %ebp,%ebp - movb %dl,(%ecx) # store value in buff - ja .Llongdiv # (Higher part of val still > 0) - - .align 4 -.Llow: # Do rest with integer precision - # Value in 0:eax. div 0 + low part by the radix. - xorl %edx,%edx - decl %ecx - divl %ebx - movb (%edx,%edi),%dl # bh is always zero as ebx=radix < 36 - testl %eax,%eax - movb %dl,(%ecx) - jne .Llow - -.L160: - movl 108(%esp),%edi # get dst - -.Lcopy_end: - leal 92(%esp),%esi # End of buffer -.Lmov: # mov temporary buffer to result (%ecx -> %edi) - movb (%ecx), %al - movb %al, (%edi) - incl %ecx - incl %edi - cmpl %ecx,%esi - jne .Lmov - -.L10_end: - movl %edi,%eax # Pointer to end null - movb $0,(%edi) # Store the end null - -.L165: - popl %ebx - popl %edi - popl %esi - popl %ebp - addl $80,%esp - ret - -.Lerror: - xorl %eax,%eax # Wrong radix - jmp .L165 - -.Lfe3: - .size longlong2str_with_dig_vector,.Lfe3-longlong2str_with_dig_vector - -# -# This is almost equal to the above, except that we can do the final -# loop much more efficient -# - - .align 4 - -.globl longlong10_to_str - .type longlong10_to_str,@function -longlong10_to_str: - subl $80,%esp - pushl %ebp - pushl %esi - pushl %edi - pushl %ebx - movl 100(%esp),%esi # Lower part of val - movl 104(%esp),%ebp # Higher part of val - movl 108(%esp),%edi # get dst - movl 112(%esp),%ebx # Radix (10 or -10) - testl %ebx,%ebx - jge .L10_10 # Positive radix - - negl %ebx # Change radix to positive (= 10) - - testl %ebp,%ebp # Test if negative value - jge .L10_10 - movb $45,(%edi) # Add sign - incl %edi - negl %esi # Change sign of val (ebp:esi) - adcl $0,%ebp - negl %ebp - -.L10_10: - leal 92(%esp),%ecx # End of buffer - testl %ebp,%ebp # Test if value > 0xFFFFFFFF - jne .L10_longdiv - cmpl $10, %esi # Test if <= radix, for easy loop - movl %esi, %ebx # Value in eax (for L10_low) - jae .L10_low - - # Value is one digit (negative or positive) - addb $48, %bl - movb %bl,(%edi) - incl %edi - jmp .L10_end - .align 4 - -.L10_longdiv: - # val is stored in in ebp:esi - movl %ebp,%eax # High part of value - xorl %edx,%edx - divl %ebx # Divide by 10 - movl %eax,%ebp - movl %esi,%eax - divl %ebx # Divide by 10 - decl %ecx - movl %eax,%esi # quotent in ebp:esi - addl $48,%edx # Convert to ascii - movb %dl,(%ecx) # store value in buff - -.L10_30: - testl %ebp,%ebp - ja .L10_longdiv - movl %esi,%ebx # Move val to %ebx - -.L10_low: - # The following code uses some tricks to change division by 10 to - # multiplication and shifts - movl $0xcccccccd,%esi - -.L10_40: # Divide %ebx with 10 - movl %ebx,%eax - mull %esi - decl %ecx - shrl $3,%edx - leal (%edx,%edx,4),%eax - addl %eax,%eax - subb %al,%bl # %bl now contains val % 10 - addb $48,%bl - movb %bl,(%ecx) - movl %edx,%ebx - testl %ebx,%ebx - jne .L10_40 - jmp .Lcopy_end # Shared end with longlong2str - -.L10end: - .size longlong10_to_str,.L10end-longlong10_to_str diff --git a/strings/longlong2str.c b/strings/longlong2str.c index 641ae0955d3..21027a0ee9a 100644 --- a/strings/longlong2str.c +++ b/strings/longlong2str.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/longlong2str_asm.c b/strings/longlong2str_asm.c deleted file mode 100644 index e5628043da6..00000000000 --- a/strings/longlong2str_asm.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - Wrapper for longlong2str.s - - We need this because the assembler code can't access the local variable - _dig_vector in a portable manner. -*/ - -#include <my_global.h> -#include "m_string.h" - -extern char *longlong2str_with_dig_vector(longlong val,char *dst,int radix, - const char *dig_vector); - -char *ll2str(longlong val,char *dst,int radix, int upcase) -{ - return longlong2str_with_dig_vector(val, dst, radix, - upcase ? _dig_vec_upper : _dig_vec_lower); -} diff --git a/strings/my_strchr.c b/strings/my_strchr.c index 6724bf39ff2..35f39d563c5 100644 --- a/strings/my_strchr.c +++ b/strings/my_strchr.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2005 MySQL AB +/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -13,6 +13,45 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <my_global.h> +#include "m_string.h" +#include "m_ctype.h" + +#define NEQ(A, B) ((A) != (B)) +#define EQU(A, B) ((A) == (B)) + +/** + Macro for the body of the string scanning. + + @param CS The character set of the string + @param STR Pointer to beginning of string + @param END Pointer to one-after-end of string + @param ACC Pointer to beginning of accept (or reject) string + @param LEN Length of accept (or reject) string + @param CMP is a function-like for doing the comparison of two characters. + */ + +#define SCAN_STRING(CS, STR, END, ACC, LEN, CMP) \ + do { \ + uint mbl; \ + const char *ptr_str, *ptr_acc; \ + const char *acc_end= (ACC) + (LEN); \ + for (ptr_str= (STR) ; ptr_str < (END) ; ptr_str+= mbl) \ + { \ + mbl= my_mbcharlen((CS), *(uchar*)ptr_str); \ + if (mbl < 2) \ + { \ + DBUG_ASSERT(mbl == 1); \ + for (ptr_acc= (ACC) ; ptr_acc < acc_end ; ++ptr_acc) \ + if (CMP(*ptr_acc, *ptr_str)) \ + goto end; \ + } \ + } \ +end: \ + return (size_t) (ptr_str - (STR)); \ + } while (0) + + /* my_strchr(cs, str, end, c) returns a pointer to the first place in str where c (1-byte character) occurs, or NULL if c does not occur @@ -21,11 +60,6 @@ frequently. */ -#include <my_global.h> -#include "m_string.h" -#include "m_ctype.h" - - char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end, pchar c) { @@ -45,3 +79,26 @@ char *my_strchr(CHARSET_INFO *cs, const char *str, const char *end, return(0); } +/** + Calculate the length of the initial segment of 'str' which consists + entirely of characters not in 'reject'. + + @note The reject string points to single-byte characters so it is + only possible to find the first occurrence of a single-byte + character. Multi-byte characters in 'str' are treated as not + matching any character in the reject string. + + @todo should be moved to CHARSET_INFO if it's going to be called + frequently. + + @internal The implementation builds on the assumption that 'str' is long, + while 'reject' is short. So it compares each character in string + with the characters in 'reject' in a tight loop over the characters + in 'reject'. +*/ + +size_t my_strcspn(CHARSET_INFO *cs, const char *str, const char *str_end, + const char *reject) +{ + SCAN_STRING(cs, str, str_end, reject, strlen(reject), EQU); +} diff --git a/strings/my_strtoll10-x86.s b/strings/my_strtoll10-x86.s deleted file mode 100644 index f73428de7de..00000000000 --- a/strings/my_strtoll10-x86.s +++ /dev/null @@ -1,418 +0,0 @@ -# Copyright (C) 2003 MySQL AB -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# Implemention of my_strtoll(): Converting a string to a 64 bit integer. -# For documentation, check my_strtoll.c - - .file "my_strtoll10-x86.s" - .version "01.02" - -.text - .align 4 - -.globl my_strtoll10 - .type my_strtoll10,@function - - - # Used stack variables - # ebp-4 dummy for storing endptr if endptr = 0 - # ebp-8 First 9 digits of return values - # ebp-12 Pointer to first digit of second part - # ebp-16 Store lowest 2 digits - # ebp-20 != 0 if value was negative - # ebp-24 High max value - # ebp-28 Middle max value - # ebp-32 Low max value - # ebp-36 Temp value - - # esi Pointer to input string - # ebx End of string - -my_strtoll10: - pushl %ebp - movl %esp,%ebp - subl $48,%esp - pushl %esi - pushl %edi - pushl %ebx - movl 8(%ebp),%esi # esi= nptr - movl 16(%ebp),%ecx # ecx= error (Will be overwritten later) - movl 12(%ebp),%eax # eax= endptr - cmpl $0,%eax # if (endptr) - je .L110 - -# Fixed length string - movl (%eax),%ebx # bx= end-of-string - .p2align 4,,7 -.L100: - cmpl %ebx,%esi - je .Lno_conv - movb (%esi), %al # al= next byte - incl %esi - cmpb $32,%al # Skip space - je .L100 - cmpb $9,%al # Skip tab - je .L100 - jmp .L130 - -# String that ends with \0 - -.L110: - leal -4(%ebp),%edi - movl %edi,12(%ebp) # endptr= &dummy, for easier end check - .p2align 4,,7 -.L120: - movb (%esi), %al # al= next byte - incl %esi - cmpb $32,%al - je .L120 - cmpb $9,%al - je .L120 - testb %al,%al # Test if we found end \0 - je .Lno_conv - leal 65535(%esi),%ebx # ebx = end-of-string - -.L130: - cmpb $45,%al # Test if '-' - jne .Lpositive - - # negative number - movl $-1,(%ecx) # error = -1 (mark that number is negative) - movl $1,-20(%ebp) # negative= 1 - movl $92233720,-24(%ebp) - movl $368547758,-28(%ebp) - movl $8,-32(%ebp) - jmp .L460 - - .p2align 4,,7 -.Lpositive: - movl $0,(%ecx) # error=0 - movl $0,-20(%ebp) # negative= 0 - movl $184467440,-24(%ebp) - movl $737095516,-28(%ebp) - movl $15,-32(%ebp) - cmpb $43,%al # Check if '+' - jne .L462 - -.L460: - cmpl %ebx,%esi # Check if overflow - je .Lno_conv - movb (%esi), %al # al= next byte after sign - incl %esi - - # Remove pre zero to be able to handle a lot of pre-zero -.L462: - cmpb $48,%al - jne .L475 # Number doesn't start with 0 - decl %esi - .p2align 4,,7 - - # Skip pre zeros -.L481: - incl %esi # Skip processed byte - cmpl %ebx,%esi - je .Lms_return_zero - cmpb (%esi),%al # Test if next byte is also zero - je .L481 - leal 9(%esi),%ecx # ecx = end-of-current-part - xorl %edi,%edi # Store first 9 digits in edi - jmp .L482 - .p2align 4,,7 - - # Check if first char is a valid number -.L475: - addb $-48,%al - cmpb $9,%al - ja .Lno_conv -.L477: - movzbl %al,%edi # edi = first digit - leal 8(%esi),%ecx # ecx = end-of-current-part - - # Handle first 8/9 digits and store them in edi -.L482: - cmpl %ebx,%ecx - jbe .L522 - movl %ebx,%ecx # ecx = min(end-of-current-part, end-of-string) - jmp .L522 - - .p2align 4,,7 -.L488: - movb (%esi), %al # al= next byte - incl %esi - addb $-48,%al - cmpb $9,%al - ja .Lend_i_dec_esi - - # Calculate edi= edi*10 + al - leal (%edi,%edi,4),%edx - movzbl %al,%eax - leal (%eax,%edx,2),%edi -.L522: - cmpl %ecx,%esi # If more digits at this level - jne .L488 - cmpl %ebx,%esi # If end of string - je .Lend_i - - movl %edi,-8(%ebp) # Store first 9 digits - movl %esi,-12(%ebp) # store pos to first digit of second part - - # Calculate next 9 digits and store them in edi - - xorl %edi,%edi - leal 9(%esi),%ecx # ecx= end-of-current-part - movl %ecx,-36(%ebp) # Store max length - cmpl %ebx,%ecx - jbe .L498 - movl %ebx,%ecx # ecx = min(end-of-current-part, end-of-string) - - .p2align 4,,7 -.L498: - movb (%esi), %al # al= next byte - incl %esi - addb $-48,%al - cmpb $9,%al - ja .Lend_i_and_j_decl_esi - - # Calculate edi= edi*10 + al - leal (%edi,%edi,4),%edx - movzbl %al,%eax - leal (%eax,%edx,2),%edi - - cmpl %ecx,%esi # If end of current part - jne .L498 - cmpl %ebx,%esi # If end of string - jne .L500 - cmpl -36(%ebp),%esi # Test if string is less than 18 digits - jne .Lend_i_and_j -.L499: - movl $1000000000,%eax - jmp .Lgot_factor # 18 digit string - - # Handle the possible next to last digit and store in ecx -.L500: - movb (%esi),%al - addb $-48,%al - cmpb $9,%al - ja .L499 # 18 digit string - - incl %esi - movzbl %al,%ecx - cmpl %ebx,%esi # If end of string - je .Lend4 - - movb (%esi),%al # Read last digit - addb $-48,%al - cmpb $9,%al - ja .Lend4 - - # ecx= ecx*10 + al - leal (%ecx,%ecx,4),%edx - movzbl %al,%eax - leal (%eax,%edx,2),%ecx - - movl 12(%ebp),%eax # eax = endptr - incl %esi - movl %esi,(%eax) # *endptr = end-of-string - cmpl %ebx,%esi - je .L505 # At end of string - - movb (%esi),%al # check if extra digits - addb $-48,%al - cmpb $9,%al - jbe .Loverflow - - # At this point we have: - # -8(%ebp) First 9 digits - # edi Next 9 digits - # ecx Last 2 digits - # *endpos end-of-string - -.L505: # Check that we are not going to get overflow for unsigned long long - movl -8(%ebp),%eax # First 9 digits - cmpl -24(%ebp),%eax - ja .Loverflow - jne .L507 - cmpl -28(%ebp),%edi - ja .Loverflow - jne .L507 - cmpl -32(%ebp),%ecx - ja .Loverflow - -.L507: - movl %edi,-4(%ebp) # Save middle bytes - movl %ecx,%esi # esi = 2 last digits - movl $1215752192,%ecx # %ecx= lower_32_bits(100000000000) - mull %ecx - imull $23,-8(%ebp),%ecx - movl $0,-36(%ebp) - movl %eax,%ebx - imull $1215752192,-36(%ebp),%eax - movl %edx,%edi - addl %ecx,%edi - addl %eax,%edi # Temp in edi:ebx - - movl $100,%eax # j= j*100 - mull -4(%ebp) - addl %ebx,%eax # edx:eax+= edi:ebx - adcl %edi,%edx - addl %esi,%eax - adcl $0,%edx - jmp .Lms_return - -.Loverflow: - # When we come here, *endptr is already updated - - movl 16(%ebp),%edx # edx= error - movl $34,(%edx) # *error = 34 - movl $-1,%eax - movl %eax,%edx - cmpl $0,-20(%ebp) # If negative - je .Lms_return - xor %eax,%eax # edx:eax = LONGLONG_LMIN - movl $-2147483648,%edx - jmp .Lms_return - - # Return value that is in %edi as long long - .p2align 4,,7 -.Lend_i_dec_esi: - decl %esi # Fix so that it points at last digit -.Lend_i: - xorl %edx,%edx - movl %edi,%eax - cmpl $0,-20(%ebp) - je .Lreturn_save_endptr # Positive number - negl %eax - cltd # Neg result in edx:eax - jmp .Lreturn_save_endptr - - # Return value (%ebp-8) * lfactor[(uint) (edx-start)] + edi - .p2align 4,,7 -.Lend_i_and_j_decl_esi: - decl %esi # Fix so that it points at last digit -.Lend_i_and_j: - movl %esi,%ecx - subl -12(%ebp),%ecx # ecx= number of digits in second part - - # Calculate %eax= 10 ** %cl, where %cl <= 8 - # With an array one could do this with: - # movl 10_factor_table(,%ecx,4),%eax - # We calculate the table here to avoid problems in - # position independent code (gcc -pic) - - cmpb $3,%cl - ja .L4_to_8 - movl $1000, %eax - je .Lgot_factor # %cl=3, eax= 1000 - movl $10, %eax - cmpb $1,%cl # %cl is here 0 - 2 - je .Lgot_factor # %cl=1, eax= 10 - movl $100, %eax - ja .Lgot_factor # %cl=2, eax=100 - movl $1, %eax - jmp .Lgot_factor # %cl=0, eax=1 - -.L4_to_8: # %cl is here 4-8 - cmpb $5,%cl - movl $100000, %eax - je .Lgot_factor # %cl=5, eax=100000 - movl $10000, %eax - jbe .Lgot_factor # %cl=4, eax=10000 - movl $10000000, %eax - cmpb $7,%cl - je .Lgot_factor # %cl=7, eax=10000000 - movl $100000000, %eax - ja .Lgot_factor # %cl=8, eax=100000000 - movl $1000000, %eax # %cl=6, eax=1000000 - - # Return -8(%ebp) * %eax + edi - .p2align 4,,7 -.Lgot_factor: - mull -8(%ebp) - addl %edi,%eax - adcl $0,%edx - cmpl $0,-20(%ebp) # if negative - je .Lreturn_save_endptr - negl %eax # Neg edx:%eax - adcl $0,%edx - negl %edx - jmp .Lreturn_save_endptr - - # Return -8(%ebp) * $10000000000 + edi*10 + ecx - .p2align 4,,7 -.Lend4: - movl %ecx,-16(%ebp) # store lowest digits - movl 12(%ebp),%ebx - movl %esi,(%ebx) # *endpos = end-of-string - movl -8(%ebp),%eax # First 9 digits - movl $1410065408,%ecx # ecx= lower_32_bits(10000000000) - mull %ecx - movl $0,-36(%ebp) - movl %eax,%ebx # Store lowest 32 byte from multiplication - imull $1410065408,-36(%ebp),%eax - movl -8(%ebp),%ecx # First 9 digits - movl %edx,%esi - addl %ecx,%ecx - addl %ecx,%esi - addl %eax,%esi # %esi:%ebx now has -8(%ebp) * $10000000000 - - movl $10,%eax # Calc edi*10 - mull %edi - addl %ebx,%eax # And add to result - adcl %esi,%edx - addl -16(%ebp),%eax # Add lowest digit - adcl $0,%edx - cmpl $0,-20(%ebp) # if negative - je .Lms_return - - cmpl $-2147483648,%edx # Test if too big signed integer - ja .Loverflow - jne .L516 - testl %eax,%eax - ja .Loverflow - -.L516: - negl %eax - adcl $0,%edx - negl %edx - jmp .Lms_return - - .p2align 4,,7 -.Lno_conv: # Not a legal number - movl 16(%ebp),%eax - movl $33,(%eax) # error= edom - -.Lms_return_zero: - xorl %eax,%eax # Return zero - xorl %edx,%edx - - .p2align 4,,7 -.Lreturn_save_endptr: - movl 12(%ebp),%ecx # endptr= end-of-string - movl %esi,(%ecx) # *endptr= end-of-string - -.Lms_return: - popl %ebx - popl %edi - popl %esi - movl %ebp,%esp - popl %ebp - ret - -.my_strtoll10_end: - .size my_strtoll10,.my_strtoll10_end-my_strtoll10 - .comm res,240,32 - .comm end_ptr,120,32 - .comm error,120,32 - .ident "Monty" diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c index b9fc4b4be8e..5263abb335c 100644 --- a/strings/my_strtoll10.c +++ b/strings/my_strtoll10.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 MySQL AB +/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 1284203f739..9f425a1db4d 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -513,7 +513,7 @@ start: arg_count= max(arg_count, arg_index); goto start; } - DBUG_ASSERT(0); + return 0; } diff --git a/strings/str2int.c b/strings/str2int.c index c4a4c07eeff..7cf49982d76 100644 --- a/strings/str2int.c +++ b/strings/str2int.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/str_alloc.c b/strings/str_alloc.c index 615ad1ba1e2..fdf32b8ee15 100644 --- a/strings/str_alloc.c +++ b/strings/str_alloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/str_test.c b/strings/str_test.c deleted file mode 100644 index ce23b2c3588..00000000000 --- a/strings/str_test.c +++ /dev/null @@ -1,275 +0,0 @@ -/* Copyright (C) 2000-2003 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* Test of all stringfunktions that is coded in assembler */ - -#include <my_global.h> -#include <stdarg.h> -#include "m_string.h" - -#define F_LEN 8 -#define F_CHAR 'A' -#define F_FILL 'B' -#define T_LEN 15 -#define T_CHAR 'D' -#define T_FILL 'E' -#define F_PREFILL '0' -#define T_PREFILL '1' - -static char from_buff[100],to_buff[100]; -static char * from, *to; -static int errors,tests; -static int test_strarg(const char *name,...); -static void init_strings (void); /* Init from and to */ -void test_arg (const char *message,long func_value,long value); -int compare_buff(const char *message,char * b1,char * b2,int length, - pchar fill, pchar prefill); - -static int my_test(int a) -{ - return a ? 1 : 0; -} - -int main(void) -{ - static char v1[]="Monty",v2[]="on",v3[]="Montys",v4[]="ty",v5[]="gr", - v6[]="hohohoo",v7[]="hohoo",v8[]="hohooo",v9[]="t", - cont[]="qwet"; - errors=tests=0; - init_strings(); - - test_arg("bcmp(from,to,5)",(long) my_test(bcmp(from,to,5)),1L); - test_arg("bcmp(from,from,5)",(long) bcmp(from,from,5),0L); - - test_arg("bcmp(from,to,0)",(long) bcmp(from,to,0),0L); - test_arg("strend(from)",(long) strend(from),(long) from+F_LEN); - test_arg("strchr(v1,'M')",(long) strchr(v1,'M'),(long) v1); - test_arg("strchr(v1,'y')",(long) strchr(v1,'y'),(long) v1+4); - test_arg("strchr(v1,'x')",(long) strchr(v1,'x'),0L); - test_arg("strcont(v1,cont)",(long) strcont(v1,cont),(long) v1+3); - test_arg("strcont(v1,v2)",(long) strcont(v1,v2),(long) v1+1); - test_arg("strcont(v1,v5)",(long) strcont(v1,v5),0L); - test_arg("is_prefix(v3,v1)",(long) is_prefix(v3,v1),1L); - test_arg("is_prefix(v1,v3)",(long) is_prefix(v1,v3),0L); - test_arg("is_prefix(v3,v4)",(long) is_prefix(v3,v4),0L); - test_arg("strstr(v1,v1)",(long) strstr(v1,v1),(long) v1); - test_arg("strstr(v1,v2)",(long) strstr(v1,v2),(long) v1+1); - test_arg("strstr(v1,v4)",(long) strstr(v1,v4),(long) v1+3); - test_arg("strstr(v6,v7)",(long) strstr(v6,v7),(long) v6+2); - test_arg("strstr(v1,v9)",(long) strstr(v1,v9),(long) v1+3); - test_arg("strstr(v1,v3)",(long) strstr(v1,v3),0L); - test_arg("strstr(v1,v5)",(long) strstr(v1,v5),0L); - test_arg("strstr(v6,v8)",(long) strstr(v6,v8),0L); - - test_arg("strlen(from)",(long) strlen(from),(long) F_LEN); - test_arg("strlen(\"\")",(long) strlen(""),0L); -#ifdef HAVE_STRNLEN - test_arg("strnlen(from,3)",(long) strnlen(from,3),3L); - test_arg("strnlen(from,0)",(long) strnlen(from,0),0L); - test_arg("strnlen(from,1000)",(long) strnlen(from,1000),(long) F_LEN); -#endif - - test_strarg("bfill(to,4,' ')",(bfill(to,4,' '),0L),INT_MAX32,4,' ',0,0); - test_strarg("bfill(from,0,' ')",(bfill(from,0,' '),0L),INT_MAX32,0,0); - test_strarg("bzero(to,3)",(bzero(to,3),0L),INT_MAX32,3,0,0,0); - test_strarg("bzero(to,0)",(bzero(to,0),0L),INT_MAX32,0,0); - test_strarg("bmove(to,from,4)",(bmove(to,from,4),0L),INT_MAX32,4,F_CHAR, - 0,0); - test_strarg("bmove(to,from,0)",(bmove(to,from,0),0L),INT_MAX32,0,0); - test_strarg("bmove_upp(to+6,from+6,3)",(bmove_upp(to+6,from+6,3),0L),INT_MAX32, - 3,T_CHAR,3,F_CHAR,0,0); - test_strarg("bmove_upp(to,from,0)",(bmove_upp(to,from,0),0L),INT_MAX32,0,0); - test_strarg("bmove_align(to,from,8)",(bmove_align(to,from,8),0L),INT_MAX32, - 8,F_CHAR,0,0); - test_strarg("strappend(to,3,' ')",(strappend(to,3,' '),0L),INT_MAX32, - 3,T_CHAR,1,0,T_LEN-4,T_CHAR,1,0,0,0); - test_strarg("strappend(to,T_LEN+5,' ')",(strappend(to,T_LEN+5,' '),0L),INT_MAX32, - T_LEN,T_CHAR,5,' ',1,0,0,0); - test_strarg("strcat(to,from)",strcat(to,from),to,T_LEN,T_CHAR, - F_LEN,F_CHAR,1,0,0,0); - test_strarg("strcat(to,\"\")",strcat(to,""),INT_MAX32,0,0); - test_strarg("strfill(to,4,' ')",strfill(to,4,' '),to+4,4,' ',1,0,0,0); - test_strarg("strfill(from,0,' ')",strfill(from,0,' '),from,0,1,0,0); - test_strarg("strmake(to,from,4)",strmake(to,from,4),to+4,4,F_CHAR, - 1,0,0,0); - test_strarg("strmake(to,from,0)",strmake(to,from,0),to+0,1,0,0,0); - test_strarg("strmov(to,from)",strmov(to,from),to+F_LEN,F_LEN,F_CHAR,0,0); - test_strarg("strmov(to,\"\")",strmov(to,""),to,1,0,0,0); - test_strarg("strnmov(to,from,2)",strnmov(to,from,2),to+2,2,F_CHAR,0,0); - test_strarg("strnmov(to,from,F_LEN+5)",strnmov(to,from,F_LEN+5),to+F_LEN, - F_LEN,F_CHAR,1,0,0,0); - test_strarg("strnmov(to,\"\",2)",strnmov(to,"",2),to,1,0,0,0); - test_strarg("strxmov(to,from,\"!!\",NullS)",strxmov(to,from,"!!",NullS),to+F_LEN+2,F_LEN,F_CHAR,2,'!',0,0,0); - test_strarg("strxmov(to,NullS)",strxmov(to,NullS),to,1,0,0,0); - test_strarg("strxmov(to,from,from,from,from,from,'!!',from,NullS)",strxmov(to,from,from,from,from,from,"!!",from,NullS),to+F_LEN*6+2,F_LEN,F_CHAR,F_LEN,F_CHAR,F_LEN,F_CHAR,F_LEN,F_CHAR,F_LEN,F_CHAR,2,'!',F_LEN,F_CHAR,1,0,0,0); - - test_strarg("strxnmov(to,100,from,\"!!\",NullS)",strxnmov(to,100,from,"!!",NullS),to+F_LEN+2,F_LEN,F_CHAR,2,'!',0,0,0); - test_strarg("strxnmov(to,2,NullS)",strxnmov(to,2,NullS),to,1,0,0,0); - test_strarg("strxnmov(to,100,from,from,from,from,from,'!!',from,NullS)",strxnmov(to,100,from,from,from,from,from,"!!",from,NullS),to+F_LEN*6+2,F_LEN,F_CHAR,F_LEN,F_CHAR,F_LEN,F_CHAR,F_LEN,F_CHAR,F_LEN,F_CHAR,2,'!',F_LEN,F_CHAR,1,0,0,0); - test_strarg("strxnmov(to,2,\"!!!\",NullS)",strxnmov(to,2,"!!!",NullS),to+2,2,'!',0,0,0); - test_strarg("strxnmov(to,2,\"!!\",NullS)",strxnmov(to,2,"!!","xx",NullS),to+2,2,'!',0,0,0); - test_strarg("strxnmov(to,2,\"!\",\"x\",\"y\",NullS)",strxnmov(to,2,"!","x","y",NullS),to+2,1,'!',1,'x',0,0,0); - - test_strarg("bchange(to,2,from,4,6)",(bchange(to,2,from,4,6),0L),INT_MAX32, - 4,F_CHAR,2,T_CHAR,0,0); - - printf("tests: %d errors: %d\n",tests,errors); - if (errors) - fputs("--- Some functions doesn't work!! Fix them\n",stderr); - return(errors > 0); -} /* main */ - - - /* Init strings */ - -void init_strings(void) -{ - reg1 int i; - reg2 char *pos; - - from=from_buff+3; to=to_buff+3; - - pos=from_buff; *pos++= F_FILL; *pos++=F_FILL; *pos++=F_PREFILL; - for (i=0 ; i < F_LEN ; i++) - *pos++=F_CHAR; - *pos++=0; - for (i=0; i<50 ; i++) - *pos++= F_FILL; - - pos=to_buff; *pos++= T_FILL; *pos++=T_FILL; *pos++=T_PREFILL; - for (i=0 ; i < T_LEN ; i++) - *pos++=T_CHAR; - *pos++=0; - for (i=0; i<50 ; i++) - *pos++= T_FILL; -} /* init_strings */ - - - /* Test that function return rigth value */ - -void test_arg(const char *message, long int func_value, long int value) -{ - tests++; - printf("testing '%s'\n",message); - if (func_value != value) - { - printf("func: '%s' = %ld Should be: %ld\n",message,func_value,value); - errors++; - } -} /* test_arg */ - - /* Test function return value and from and to arrays */ - -static int test_strarg(const char *message,...) -{ - long func_value,value; - int error,length; - char chr,cmp_buff[100],*pos,*pos2; - va_list pvar; - - tests++; - va_start(pvar,message); - func_value=va_arg(pvar,long); - value=va_arg(pvar,long); - - printf("testing '%s'\n",message); - if (func_value != value && value != INT_MAX32) - { - printf("func: '%s' = %ld Should be: %ld\n",message,func_value,value); - errors++; - } - pos= cmp_buff; - while ((length = va_arg(pvar, int)) != 0) - { - chr= (char) (va_arg(pvar, int)); - while (length--) - *pos++=chr; - } - pos2=to+ (int)(pos-cmp_buff); - while (pos <= cmp_buff+T_LEN) - *pos++= *pos2++; - if (compare_buff(message,to,cmp_buff,(int) (pos-cmp_buff),T_FILL,T_PREFILL)) - { - init_strings(); - va_end(pvar); - return 1; - } - - pos= cmp_buff; - while ((length = va_arg(pvar, int)) != 0) - { - chr= (char) (va_arg(pvar, int)); - while (length--) - *pos++=chr; - } - pos2=from+ (int)(pos-cmp_buff); - while (pos <= cmp_buff+F_LEN) - *pos++= *pos2++; - error=compare_buff(message,from,cmp_buff,(int) (pos-cmp_buff),F_FILL,F_PREFILL); - init_strings(); - va_end(pvar); - return (error != 0); -} /* test_strarg */ - - - /* test if function made right value */ - -int compare_buff(const char *message, char * b1, char * b2, int length, - pchar fill, pchar prefill) -{ - int i,error=0; - - if (bcmp(b1,b2,length)) - { - errors++; - printf("func: '%s' Buffers differ\nIs: ",message); - for (i=0 ; i<length ; i++) - printf("%3d ",b1[i]); - printf("\nShould be: "); - for (i=0 ; i<length ; i++) - printf("%3d ",b2[i]); - puts(""); - } - else if (b1[-1] != prefill || b1[-2] != fill || b1[-3] != fill) - { - printf("func: '%s' Chars before buffer is changed\n",message); - errors++; - error=1; - } - else if (b1[length] != fill || b1[length+1] != fill) - { - printf("func: '%s' Chars after buffer is changed\n",message); - errors++; - error=1; - } - return error; -} /* compare_buff */ - - /* These are here to be loaded and examined */ - -extern void dummy_functions(void); - -void dummy_functions(void) -{ - (void) memchr(from,'a',5); - (void) memcmp(from,to,5); - (void) memcpy(from,to,5); - (void) memset(from,' ',5); - (void) strcmp(from,to); - (void) strcpy(from,to); - (void) strstr(from,to); - (void) strrchr(from,'a'); - return; -} diff --git a/strings/strappend.c b/strings/strappend.c index bb926f74665..e81a4d4301e 100644 --- a/strings/strappend.c +++ b/strings/strappend.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strcend.c b/strings/strcend.c index e08ad2b1e75..c48f695cfd6 100644 --- a/strings/strcend.c +++ b/strings/strcend.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strcont.c b/strings/strcont.c index 5a518a3550f..ddf8f2c838f 100644 --- a/strings/strcont.c +++ b/strings/strcont.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strend.c b/strings/strend.c index d70a5d648d5..c38502bd55c 100644 --- a/strings/strend.c +++ b/strings/strend.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/strfill.c b/strings/strfill.c index 4b1fe67b206..12d227f5805 100644 --- a/strings/strfill.c +++ b/strings/strfill.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strings-x86.s b/strings/strings-x86.s deleted file mode 100644 index 4872c566685..00000000000 --- a/strings/strings-x86.s +++ /dev/null @@ -1,393 +0,0 @@ -# Copyright (C) 2000 MySQL AB -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; version 2 of the License. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -# Optimized string functions Intel 80x86 (gcc/gas syntax) - - .file "strings.s" - .version "1.00" - -.text - -# Move a alligned, not overlapped, by (long) divided memory area -# Args: to,from,length - -.globl bmove_align - .type bmove_align,@function -bmove_align: - movl %edi,%edx - push %esi - movl 4(%esp),%edi # to - movl 8(%esp),%esi # from - movl 12(%esp),%ecx # length - addw $3,%cx # fix if not divisible with long - shrw $2,%cx - jz .ba_20 - .p2align 4,,7 -.ba_10: - movl -4(%esi,%ecx),%eax - movl %eax,-4(%edi,%ecx) - decl %ecx - jnz .ba_10 -.ba_20: pop %esi - movl %edx,%edi - ret - -.bmove_align_end: - .size bmove_align,.bmove_align_end-bmove_align - - # Move a string from higher to lower - # Arg from_end+1,to_end+1,length - -.globl bmove_upp - .type bmove_upp,@function -bmove_upp: - movl %edi,%edx # Remember %edi - push %esi - movl 8(%esp),%edi # dst - movl 16(%esp),%ecx # length - movl 12(%esp),%esi # source - test %ecx,%ecx - jz .bu_20 - subl %ecx,%esi # To start of strings - subl %ecx,%edi - - .p2align 4,,7 -.bu_10: movb -1(%esi,%ecx),%al - movb %al,-1(%edi,%ecx) - decl %ecx - jnz .bu_10 -.bu_20: pop %esi - movl %edx,%edi - ret - -.bmove_upp_end: - .size bmove_upp,.bmove_upp_end-bmove_upp - - # Append fillchars to string - # Args: dest,len,fill - -.globl strappend - .type strappend,@function -strappend: - pushl %edi - movl 8(%esp),%edi # Memory pointer - movl 12(%esp),%ecx # Length - clrl %eax # Find end of string - repne - scasb - jnz sa_99 # String to long, shorten it - movzb 16(%esp),%eax # Fillchar - decl %edi # Point at end null - incl %ecx # rep made one dec for null-char - - movb %al,%ah # (2) Set up a 32 bit pattern. - movw %ax,%dx # (2) - shll $16,%eax # (3) - movw %dx,%ax # (2) %eax has the 32 bit pattern. - - movl %ecx,%edx # (2) Save the count of bytes. - shrl $2,%ecx # (2) Number of dwords. - rep - stosl # (5 + 5n) - movb $3,%cl # (2) - and %edx,%ecx # (2) Fill in the odd bytes - rep - stosb # Move last bytes if any - -sa_99: movb $0,(%edi) # End of string - popl %edi - ret -.strappend_end: - .size strappend,.strappend_end-strappend - - # Find if string contains any char in another string - # Arg: str,set - # Ret: Pointer to first found char in str - -.globl strcont - .type strcont,@function -strcont: - movl %edi,%edx - pushl %esi - movl 8(%esp),%esi # str - movl 12(%esp),%ecx # set - clrb %ah # For endtest - jmp sc_60 - -sc_10: scasb - jz sc_fo # Found char -sc_20: cmp (%edi),%ah # Test if null - jnz sc_10 # Not end of set yet - incl %esi # Next char in str -sc_60: movl %ecx,%edi # %edi = Set - movb (%esi),%al # Test if this char exist - andb %al,%al - jnz sc_20 # Not end of string - clrl %esi # Return Null -sc_fo: movl %esi,%eax # Char found here - movl %edx,%edi # Restore - popl %esi - ret -.strcont_end: - .size strcont,.strcont_end-strcont - - # Find end of string - # Arg: str - # ret: Pointer to end null - -.globl strend - .type strend,@function -strend: - movl %edi,%edx # Save - movl 4(%esp),%edi # str - clrl %eax # Find end of string - movl %eax,%ecx - decl %ecx # ECX = -1 - repne - scasb - movl %edi,%eax - decl %eax # End of string - movl %edx,%edi # Restore - ret -.strend_end: - .size strend,.strend_end-strend - - # Make a string with len fill-chars and endnull - # Args: dest,len,fill - # Ret: dest+len - -.globl strfill - .type strfill,@function -strfill: - pushl %edi - movl 8(%esp),%edi # Memory pointer - movl 12(%esp),%ecx # Length - movzb 16(%esp),%eax # Fill - - movb %al,%ah # (2) Set up a 32 bit pattern - movw %ax,%dx # (2) - shll $16,%eax # (3) - movw %dx,%ax # (2) %eax has the 32 bit pattern. - - movl %ecx,%edx # (2) Save the count of bytes. - shrl $2,%ecx # (2) Number of dwords. - rep - stosl # (5 + 5n) - movb $3,%cl # (2) - and %edx,%ecx # (2) Fill in the odd bytes - rep - stosb # Move last bytes if any - - movb %cl,(%edi) # End NULL - movl %edi,%eax # End i %eax - popl %edi - ret -.strfill_end: - .size strfill,.strfill_end-strfill - - - # Find a char in or end of a string - # Arg: str,char - # Ret: pointer to found char or NullS - -.globl strcend - .type strcend,@function -strcend: - movl %edi,%edx - movl 4(%esp),%edi # str - movb 8(%esp),%ah # search - clrb %al # for scasb to find end - -se_10: cmpb (%edi),%ah - jz se_20 # Found char - scasb - jnz se_10 # Not end - dec %edi # Not found, point at end of string -se_20: movl %edi,%eax - movl %edx,%edi # Restore - ret -.strcend_end: - .size strcend,.strcend_end-strcend - - # Test if string has a given suffix - -.globl is_prefix - .type is_prefix,@function -is_prefix: - movl %edi,%edx # Save %edi - pushl %esi # and %esi - movl 12(%esp),%esi # get suffix - movl 8(%esp),%edi # s1 - movl $1,%eax # Ok and zero-test -ip_10: cmpb (%esi),%ah - jz suf_ok # End of string/ found suffix - cmpsb # Compare strings - jz ip_10 # Same, possible prefix - xor %eax,%eax # Not suffix -suf_ok: popl %esi - movl %edx,%edi - ret -.is_prefix_end: - .size is_prefix,.is_prefix_end-is_prefix - - # Find a substring in string - # Arg: str,search - -.globl strstr - .type strstr,@function - -strstr: - pushl %edi - pushl %esi - movl 12(%esp),%esi # str - movl 16(%esp),%edi # search - movl %edi,%ecx - incl %ecx # %ecx = search+1 - movb (%edi),%ah # %ah = First char in search - jmp sf_10 - -sf_00: movl %edx,%esi # si = Current str-pos -sf_10: movb (%esi),%al # Test if this char exist - andb %al,%al - jz sf_90 # End of string, didn't find search - incl %esi - cmpb %al,%ah - jnz sf_10 # Didn't find first char, continue - movl %esi,%edx # Save str-pos in %edx - movl %ecx,%edi -sf_20: cmpb $0,(%edi) - jz sf_fo # Found substring - cmpsb - jz sf_20 # Char ok - jmp sf_00 # Next str-pos - -sf_90: movl $1,%edx # Return Null -sf_fo: movl %edx,%eax # Char found here - decl %eax # Pointed one after - popl %esi - popl %edi - ret -.strstr_end: - .size strstr,.strstr_end-strstr - - # Make a string of len length from another string - # Arg: dst,src,length - # ret: end of dst - -.globl strmake - .type strmake,@function - -strmake: - pushl %edi - pushl %esi - mov 12(%esp),%edi # dst - movl $0,%edx - movl 20(%esp),%ecx # length - movl 16(%esp),%esi # src - cmpl %edx,%ecx - jz sm_90 -sm_00: movb (%esi,%edx),%al - cmpb $0,%al - jz sm_90 - movb %al,(%edi,%edx) - incl %edx - cmpl %edx,%ecx - jnz sm_00 -sm_90: movb $0,(%edi,%edx) -sm_99: lea (%edi,%edx),%eax # Return pointer to end null - pop %esi - pop %edi - ret -.strmake_end: - .size strmake,.strmake_end-strmake - - # Move a string with max len chars - # arg: dst,src,len - # ret: pos to first null or dst+len - -.globl strnmov - .type strnmov,@function -strnmov: - pushl %edi - pushl %esi - movl 12(%esp),%edi # dst - movl 16(%esp),%esi # src - movl 20(%esp),%ecx # Length of memory-area - jecxz snm_99 # Nothing to do - clrb %al # For test of end-null - -snm_10: cmpb (%esi),%al # Next char to move - movsb # move arg - jz snm_20 # last char, fill with null - loop snm_10 # Continue moving - incl %edi # Point two after last -snm_20: decl %edi # Point at first null (or last+1) -snm_99: movl %edi,%eax # Pointer at last char - popl %esi - popl %edi - ret -.strnmov_end: - .size strnmov,.strnmov_end-strnmov - - -.globl strmov - .type strmov,@function -strmov: - movl %esi,%ecx # Save old %esi and %edi - movl %edi,%edx - movl 8(%esp),%esi # get source pointer (s2) - movl 4(%esp),%edi # %edi -> s1 -smo_10: movb (%esi),%al - movsb # move arg - andb %al,%al - jnz smo_10 # Not last - movl %edi,%eax - dec %eax - movl %ecx,%esi # Restore - movl %edx,%edi - ret -.strmov_end: - .size strmov,.strmov_end-strmov - -.globl strxmov - .type strxmov,@function -strxmov: - movl %ebx,%edx # Save %ebx, %esi and %edi - mov %esi,%ecx - push %edi - leal 8(%esp),%ebx # Get destination - movl (%ebx),%edi - xorb %al,%al - jmp next_str # Handle source ebx+4 - -start_str: - movsb - cmpb -1(%edi),%al - jne start_str - decl %edi # Don't copy last null - -next_str: - addl $4,%ebx - movl (%ebx),%esi - orl %esi,%esi - jne start_str - movb %al,0(%edi) # Force last to ASCII 0 - - movl %edi,%eax # Return ptr to ASCII 0 - pop %edi # Restore registers - movl %ecx,%esi - movl %edx,%ebx - ret -.strxmov_end: - .size strxmov,.strxmov_end-strxmov diff --git a/strings/strmake.c b/strings/strmake.c index 56bd3a8f084..500d739f8dd 100644 --- a/strings/strmake.c +++ b/strings/strmake.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strmov.c b/strings/strmov.c index 849c5812401..19f12efceb9 100644 --- a/strings/strmov.c +++ b/strings/strmov.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strnlen.c b/strings/strnlen.c index 826cd5ae5dd..7c8f3c4a54e 100644 --- a/strings/strnlen.c +++ b/strings/strnlen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strnmov.c b/strings/strnmov.c index 7e26877637b..a826233bb17 100644 --- a/strings/strnmov.c +++ b/strings/strnmov.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/strstr.c b/strings/strstr.c deleted file mode 100644 index a5b50d12043..00000000000 --- a/strings/strstr.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2002 MySQL AB - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; version 2 - of the License. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA */ - -/* File : strstr.c - Author : Monty - Updated: 1986.11.24 - Defines: strstr() - - strstr(src, pat) looks for an instance of pat in src. pat is not a - regex(3) pattern, it is a literal string which must be matched exactly. - The result is a pointer to the first character of the located instance, - or NullS if pat does not occur in src. - -*/ - -#include <my_global.h> -#include "m_string.h" - -#ifndef HAVE_STRSTR - -char *strstr(register const char *str,const char *search) -{ - register char *i,*j; - register char first= *search; - -skip: - while (*str != '\0') { - if (*str++ == first) { - i=(char*) str; j=(char*) search+1; - while (*j) - if (*i++ != *j++) goto skip; - return ((char*) str-1); - } - } - return ((char*) 0); -} /* strstr */ - -#endif diff --git a/strings/strto.c b/strings/strto.c deleted file mode 100644 index fcb0d800b81..00000000000 --- a/strings/strto.c +++ /dev/null @@ -1,209 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - strtol,strtoul,strtoll,strtoull - convert string to long, unsigned long, long long or unsigned long long. - strtoxx(char *src,char **ptr,int base) - converts the string pointed to by src to an long of appropriate long and - returnes it. It skips leading spaces and tabs (but not newlines, formfeeds, - backspaces), then it accepts an optional sign and a sequence of digits - in the specified radix. - If the value of ptr is not (char **)NULL, a pointer to the character - terminating the scan is returned in the location pointed to by ptr. - Trailing spaces will NOT be skipped. - - If an error is detected, the result will be LONG_MIN, 0 or LONG_MAX, - (or LONGLONG..) and errno will be set to - EDOM if there are no digits - ERANGE if the result would overflow. - the ptr will be set to src. - This file is based on the strtol from the the GNU C Library. - it can be compiled with the UNSIGNED and/or LONGLONG flag set -*/ - - -#if !defined(_global_h) || !defined(_m_string_h) -# error Calling file must include 'my_global.h' and 'm_string.h' - /* see 'strtoll.c' and 'strtoull.c' for the reasons */ -#endif - -#include "m_ctype.h" -#include "my_sys.h" /* defines errno */ -#include <errno.h> - -#undef strtoull -#undef strtoll -#undef strtoul -#undef strtol -#ifdef USE_LONGLONG -#define UTYPE_MAX (~(ulonglong) 0) -#define TYPE_MIN LONGLONG_MIN -#define TYPE_MAX LONGLONG_MAX -#define longtype longlong -#define ulongtype ulonglong -#ifdef USE_UNSIGNED -#define function ulongtype strtoull -#else -#define function longtype strtoll -#endif -#else -#define UTYPE_MAX (ulong) ~0L -#define TYPE_MIN LONG_MIN -#define TYPE_MAX LONG_MAX -#define longtype long -#define ulongtype unsigned long -#ifdef USE_UNSIGNED -#define function ulongtype strtoul -#else -#define function longtype strtol -#endif -#endif - - -/* Convert NPTR to an `unsigned long int' or `long int' in base BASE. - If BASE is 0 the base is determined by the presence of a leading - zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal. - If BASE is < 2 or > 36, it is reset to 10. - If ENDPTR is not NULL, a pointer to the character after the last - one converted is stored in *ENDPTR. */ - - -function (const char *nptr,char **endptr,int base) -{ - int negative; - register ulongtype cutoff; - register unsigned int cutlim; - register ulongtype i; - register const char *s; - register uchar c; - const char *save; - int overflow; - - if (base < 0 || base == 1 || base > 36) - base = 10; - - s = nptr; - - /* Skip white space. */ - while (my_isspace(&my_charset_latin1, *s)) - ++s; - if (*s == '\0') - { - goto noconv; - } - - /* Check for a sign. */ - negative= 0; - if (*s == '-') - { - negative = 1; - ++s; - } - else if (*s == '+') - { - ++s; - } - - - if (base == 16 && s[0] == '0' && my_toupper (&my_charset_latin1, s[1]) == 'X') - s += 2; - - /* If BASE is zero, figure it out ourselves. */ - if (base == 0) - { - if (*s == '0') - { - if (my_toupper (&my_charset_latin1, s[1]) == 'X') - { - s += 2; - base = 16; - } - else - base = 8; - } - else - base = 10; - } - - /* Save the pointer so we can check later if anything happened. */ - save = s; - - cutoff = UTYPE_MAX / (unsigned long int) base; - cutlim = (uint) (UTYPE_MAX % (unsigned long int) base); - - overflow = 0; - i = 0; - for (c = *s; c != '\0'; c = *++s) - { - if (my_isdigit (&my_charset_latin1, c)) - c -= '0'; - else if (my_isalpha (&my_charset_latin1, c)) - c = my_toupper (&my_charset_latin1, c) - 'A' + 10; - else - break; - if (c >= base) - break; - /* Check for overflow. */ - if (i > cutoff || (i == cutoff && c > cutlim)) - overflow = 1; - else - { - i *= (ulongtype) base; - i += c; - } - } - - /* Check if anything actually happened. */ - if (s == save) - goto noconv; - - /* Store in ENDPTR the address of one character - past the last character we converted. */ - if (endptr != NULL) - *endptr = (char *) s; - -#ifndef USE_UNSIGNED - /* Check for a value that is within the range of - `unsigned long int', but outside the range of `long int'. */ - if (negative) - { - if (i > (ulongtype) TYPE_MIN) - overflow = 1; - } - else if (i > (ulongtype) TYPE_MAX) - overflow = 1; -#endif - - if (overflow) - { - my_errno=ERANGE; -#ifdef USE_UNSIGNED - return UTYPE_MAX; -#else - return negative ? TYPE_MIN : TYPE_MAX; -#endif - } - - /* Return the result of the appropriate sign. */ - return (negative ? -((longtype) i) : (longtype) i); - -noconv: - /* There was no number to convert. */ - my_errno=EDOM; - if (endptr != NULL) - *endptr = (char *) nptr; - return 0L; -} diff --git a/strings/strtol.c b/strings/strtol.c deleted file mode 100644 index 2f0a5286ee9..00000000000 --- a/strings/strtol.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This implements strtol() if needed */ - -/* - These includes are mandatory because they check for type sizes and - functions, especially they handle tricks for Tru64 where 'long' is - 64 bit already and our 'longlong' is just a 'long'. - */ -#include <my_global.h> -#include <m_string.h> - -#if !defined(HAVE_STRTOL) && !defined(__WIN__) -#include "strto.c" -#endif diff --git a/strings/strtoll.c b/strings/strtoll.c deleted file mode 100644 index cfb6fbd75ee..00000000000 --- a/strings/strtoll.c +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This implements strtoll() if needed */ - - -/* - These includes are mandatory because they check for type sizes and - functions, especially they handle tricks for Tru64 where 'long' is - 64 bit already and our 'longlong' is just a 'long'. - This solves a problem on Tru64 where the C99 compiler has a prototype - for 'strtoll()' but no implementation, see "6.1 New C99 library functions" - in file '/usr/share/doclib/cc.dtk/release_notes.txt'. - */ -#include <my_global.h> -#include <m_string.h> - -#if !defined(HAVE_STRTOLL) && defined(HAVE_LONG_LONG) -#define USE_LONGLONG -#include "strto.c" -#endif diff --git a/strings/strtoul.c b/strings/strtoul.c deleted file mode 100644 index df5c46c220f..00000000000 --- a/strings/strtoul.c +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This implements strtol() if needed */ - -/* - These includes are mandatory because they check for type sizes and - functions, especially they handle tricks for Tru64 where 'long' is - 64 bit already and our 'longlong' is just a 'long'. - */ -#include <my_global.h> -#include <m_string.h> - -#if !defined(HAVE_STRTOUL) -#define USE_UNSIGNED -#include "strto.c" -#endif diff --git a/strings/strtoull.c b/strings/strtoull.c deleted file mode 100644 index 94bf6904f8d..00000000000 --- a/strings/strtoull.c +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* This implements strtoull() if needed */ - - -/* - These includes are mandatory because they check for type sizes and - functions, especially they handle tricks for Tru64 where 'long' is - 64 bit already and our 'longlong' is just a 'long'. - This solves a problem on Tru64 where the C99 compiler has a prototype - for 'strtoull()' but no implementation, see "6.1 New C99 library functions" - in file '/usr/share/doclib/cc.dtk/release_notes.txt'. - */ -#include <my_global.h> -#include <m_string.h> - -#if !defined(HAVE_STRTOULL) && defined(HAVE_LONG_LONG) -#define USE_UNSIGNED -#define USE_LONGLONG -#include "strto.c" -#endif diff --git a/strings/strxmov.c b/strings/strxmov.c index d5d81fd9274..815a4cbeaad 100644 --- a/strings/strxmov.c +++ b/strings/strxmov.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/strxnmov.c b/strings/strxnmov.c index 16469be6e45..dac6eab5d63 100644 --- a/strings/strxnmov.c +++ b/strings/strxnmov.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB +/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public diff --git a/strings/uca-dump.c b/strings/uca-dump.c index 774e940c7da..3ba78163c2f 100644 --- a/strings/uca-dump.c +++ b/strings/uca-dump.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 MySQL AB +/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/uctypedump.c b/strings/uctypedump.c index 2e484604fd3..5b902843ee1 100644 --- a/strings/uctypedump.c +++ b/strings/uctypedump.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 MySQL AB +/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/utr11-dump.c b/strings/utr11-dump.c index a15f63025f4..adbbdda1169 100644 --- a/strings/utr11-dump.c +++ b/strings/utr11-dump.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 MySQL AB +/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/strings/xml.c b/strings/xml.c index 14da69e088a..abe40810a97 100644 --- a/strings/xml.c +++ b/strings/xml.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -106,6 +106,13 @@ static void my_xml_norm_text(MY_XML_ATTR *a) } +static inline my_bool +my_xml_parser_prefix_cmp(MY_XML_PARSER *p, const char *s, size_t slen) +{ + return (p->cur + slen > p->end) || memcmp(p->cur, s, slen); +} + + static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a) { int lex; @@ -123,16 +130,20 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a) a->beg=p->cur; a->end=p->cur; - if ((p->end - p->cur > 3) && !bcmp((uchar*) p->cur, (uchar*) "<!--",4)) + if (!my_xml_parser_prefix_cmp(p, C_STRING_WITH_LEN("<!--"))) { - for (; (p->cur < p->end) && bcmp((uchar*) p->cur, (uchar*) "-->", 3); p->cur++) - {} - if (!bcmp((uchar*) p->cur, (uchar*) "-->", 3)) - p->cur+=3; + for (; p->cur < p->end; p->cur++) + { + if (!my_xml_parser_prefix_cmp(p, C_STRING_WITH_LEN("-->"))) + { + p->cur+= 3; + break; + } + } a->end=p->cur; lex=MY_XML_COMMENT; } - else if (!bcmp((uchar*) p->cur, (uchar*) "<![CDATA[",9)) + else if (!my_xml_parser_prefix_cmp(p, C_STRING_WITH_LEN("<![CDATA["))) { p->cur+= 9; for (; p->cur < p->end - 2 ; p->cur++) @@ -154,11 +165,16 @@ static int my_xml_scan(MY_XML_PARSER *p,MY_XML_ATTR *a) } else if ( (p->cur[0] == '"') || (p->cur[0] == '\'') ) { + /* + "string" or 'string' found. + Scan until the closing quote/doublequote, or until the END-OF-INPUT. + */ p->cur++; for (; ( p->cur < p->end ) && (p->cur[0] != a->beg[0]); p->cur++) {} a->end=p->cur; - if (a->beg[0] == p->cur[0])p->cur++; + if (p->cur < p->end) /* Closing quote or doublequote has been found */ + p->cur++; a->beg++; if (!(p->flags & MY_XML_FLAG_SKIP_TEXT_NORMALIZATION)) my_xml_norm_text(a); |