1/* Test of case-insensitive 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 "c-strcasestr.h" 22 23#include <stdio.h> 24#include <stdlib.h> 25#include <string.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 { 42 const char input[] = "foo"; 43 const char *result = c_strcasestr (input, ""); 44 ASSERT (result == input); 45 } 46 47 { 48 const char input[] = "foo"; 49 const char *result = c_strcasestr (input, "O"); 50 ASSERT (result == input + 1); 51 } 52 53 { 54 const char input[] = "ABC ABCDAB ABCDABCDABDE"; 55 const char *result = c_strcasestr (input, "ABCDaBD"); 56 ASSERT (result == input + 15); 57 } 58 59 { 60 const char input[] = "ABC ABCDAB ABCDABCDABDE"; 61 const char *result = c_strcasestr (input, "ABCDaBE"); 62 ASSERT (result == NULL); 63 } 64 65 /* Check that a very long haystack is handled quickly if the needle is 66 short and occurs near the beginning. */ 67 { 68 size_t repeat = 10000; 69 size_t m = 1000000; 70 char *needle = 71 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 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 (c_strcasestr (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 (c_strcasestr (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 = c_strcasestr (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