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 <stdio.h> 24#include <stdlib.h> 25 26#define ASSERT(expr) \ 27 do \ 28 { \ 29 if (!(expr)) \ 30 { \ 31 fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ 32 abort (); \ 33 } \ 34 } \ 35 while (0) 36 37int 38main () 39{ 40 /* This test is executed in the C locale. */ 41 42 { 43 const char input[] = "foo"; 44 const char *result = mbsstr (input, ""); 45 ASSERT (result == input); 46 } 47 48 { 49 const char input[] = "foo"; 50 const char *result = mbsstr (input, "o"); 51 ASSERT (result == input + 1); 52 } 53 54 { 55 const char input[] = "ABC ABCDAB ABCDABCDABDE"; 56 const char *result = mbsstr (input, "ABCDABD"); 57 ASSERT (result == input + 15); 58 } 59 60 { 61 const char input[] = "ABC ABCDAB ABCDABCDABDE"; 62 const char *result = mbsstr (input, "ABCDABE"); 63 ASSERT (result == NULL); 64 } 65 66 /* Check that a very long haystack is handled quickly if the needle is 67 short and occurs near the beginning. */ 68 { 69 size_t repeat = 10000; 70 size_t m = 1000000; 71 char *needle = 72 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 73 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; 74 char *haystack = (char *) malloc (m + 1); 75 if (haystack != NULL) 76 { 77 memset (haystack, 'A', m); 78 haystack[0] = 'B'; 79 haystack[m] = '\0'; 80 81 for (; repeat > 0; repeat--) 82 { 83 ASSERT (mbsstr (haystack, needle) == haystack + 1); 84 } 85 86 free (haystack); 87 } 88 } 89 90 /* Check that a very long needle is discarded quickly if the haystack is 91 short. */ 92 { 93 size_t repeat = 10000; 94 size_t m = 1000000; 95 char *haystack = 96 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 97 "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB"; 98 char *needle = (char *) malloc (m + 1); 99 if (needle != NULL) 100 { 101 memset (needle, 'A', m); 102 needle[m] = '\0'; 103 104 for (; repeat > 0; repeat--) 105 { 106 ASSERT (mbsstr (haystack, needle) == NULL); 107 } 108 109 free (needle); 110 } 111 } 112 113 /* Check that the asymptotic worst-case complexity is not quadratic. */ 114 { 115 size_t m = 1000000; 116 char *haystack = (char *) malloc (2 * m + 2); 117 char *needle = (char *) malloc (m + 2); 118 if (haystack != NULL && needle != NULL) 119 { 120 const char *result; 121 122 memset (haystack, 'A', 2 * m); 123 haystack[2 * m] = 'B'; 124 haystack[2 * m + 1] = '\0'; 125 126 memset (needle, 'A', m); 127 needle[m] = 'B'; 128 needle[m + 1] = '\0'; 129 130 result = mbsstr (haystack, needle); 131 ASSERT (result == haystack + m); 132 } 133 if (needle != NULL) 134 free (needle); 135 if (haystack != NULL) 136 free (haystack); 137 } 138 139 return 0; 140} 141