1/* Test of searching in a string. 2 Copyright (C) 2007 Free Software Foundation, Inc. 3 4 This program is free software: you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17/* Written by Bruno Haible <bruno@clisp.org>, 2007. */ 18 19#include <config.h> 20 21#include <string.h> 22 23#include <locale.h> 24#include <stdio.h> 25#include <stdlib.h> 26 27#define ASSERT(expr) \ 28 do \ 29 { \ 30 if (!(expr)) \ 31 { \ 32 fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ 33 abort (); \ 34 } \ 35 } \ 36 while (0) 37 38int 39main () 40{ 41 /* configure should already have checked that the locale is supported. */ 42 if (setlocale (LC_ALL, "") == NULL) 43 return 1; 44 45 { 46 const char input[] = "f\303\266\303\266"; 47 const char *result = mbsstr (input, ""); 48 ASSERT (result == input); 49 } 50 51 { 52 const char input[] = "f\303\266\303\266"; 53 const char *result = mbsstr (input, "\303\266"); 54 ASSERT (result == input + 1); 55 } 56 57 { 58 const char input[] = "f\303\266\303\266"; 59 const char *result = mbsstr (input, "\266\303"); 60 ASSERT (result == NULL); 61 } 62 63 { 64 const char input[] = "\303\204BC \303\204BCD\303\204B \303\204BCD\303\204BCD\303\204BDE"; /* "��BC ��BCD��B ��BCD��BCD��BDE" */ 65 const char *result = mbsstr (input, "\303\204BCD\303\204BD"); /* "��BCD��BD" */ 66 ASSERT (result == input + 19); 67 } 68 69 { 70 const char input[] = "\303\204BC \303\204BCD\303\204B \303\204BCD\303\204BCD\303\204BDE"; /* "��BC ��BCD��B ��BCD��BCD��BDE" */ 71 const char *result = mbsstr (input, "\303\204BCD\303\204BE"); /* "��BCD��BE" */ 72 ASSERT (result == NULL); 73 } 74 75 /* Check that a very long haystack is handled quickly if the needle is 76 short and occurs near the beginning. */ 77 { 78 size_t repeat = 10000; 79 size_t m = 1000000; 80 char *needle = 81 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 82 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 83 char *haystack = (char *) malloc (m + 1); 84 if (haystack != NULL) 85 { 86 memset (haystack, 'A', m); 87 haystack[0] = '\303'; haystack[1] = '\204'; 88 haystack[m] = '\0'; 89 90 for (; repeat > 0; repeat--) 91 { 92 ASSERT (mbsstr (haystack, needle) == haystack + 2); 93 } 94 95 free (haystack); 96 } 97 } 98 99 /* Check that a very long needle is discarded quickly if the haystack is 100 short. */ 101 { 102 size_t repeat = 10000; 103 size_t m = 1000000; 104 char *haystack = 105 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 106 "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207" 107 "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207" 108 "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207" 109 "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207" 110 "A\303\207A\303\207A\303\207A\303\207A\303\207A\303\207"; 111 char *needle = (char *) malloc (m + 1); 112 if (needle != NULL) 113 { 114 memset (needle, 'A', m); 115 needle[m] = '\0'; 116 117 for (; repeat > 0; repeat--) 118 { 119 ASSERT (mbsstr (haystack, needle) == NULL); 120 } 121 122 free (needle); 123 } 124 } 125 126 /* Check that the asymptotic worst-case complexity is not quadratic. */ 127 { 128 size_t m = 1000000; 129 char *haystack = (char *) malloc (2 * m + 3); 130 char *needle = (char *) malloc (m + 3); 131 if (haystack != NULL && needle != NULL) 132 { 133 const char *result; 134 135 memset (haystack, 'A', 2 * m); 136 haystack[2 * m] = '\303'; haystack[2 * m + 1] = '\207'; 137 haystack[2 * m + 2] = '\0'; 138 139 memset (needle, 'A', m); 140 needle[m] = '\303'; needle[m + 1] = '\207'; 141 needle[m + 2] = '\0'; 142 143 result = mbsstr (haystack, needle); 144 ASSERT (result == haystack + m); 145 } 146 if (needle != NULL) 147 free (needle); 148 if (haystack != NULL) 149 free (haystack); 150 } 151 152 return 0; 153} 154