Remove useless "if" tests before free. Deprecate "free" module.
[gnulib.git] / tests / test-strcasestr.c
1 /* Test of case-insensitive searching in a string.
2    Copyright (C) 2007, 2008 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 #include <unistd.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
38 int
39 main ()
40 {
41 #if HAVE_DECL_ALARM
42   /* Declare failure if test takes too long, by using default abort
43      caused by SIGALRM.  All known platforms that lack alarm also lack
44      memmem, and the replacement memmem is known to not take too
45      long.  */
46   alarm (50);
47 #endif
48
49   {
50     const char input[] = "foo";
51     const char *result = strcasestr (input, "");
52     ASSERT (result == input);
53   }
54
55   {
56     const char input[] = "foo";
57     const char *result = strcasestr (input, "O");
58     ASSERT (result == input + 1);
59   }
60
61   {
62     const char input[] = "ABC ABCDAB ABCDABCDABDE";
63     const char *result = strcasestr (input, "ABCDaBD");
64     ASSERT (result == input + 15);
65   }
66
67   {
68     const char input[] = "ABC ABCDAB ABCDABCDABDE";
69     const char *result = strcasestr (input, "ABCDaBE");
70     ASSERT (result == NULL);
71   }
72
73   {
74     const char input[] = "ABC ABCDAB ABCDABCDABDE";
75     const char *result = strcasestr (input, "ABCDaBCD");
76     ASSERT (result == input + 11);
77   }
78
79   /* Check that a very long haystack is handled quickly if the needle is
80      short and occurs near the beginning.  */
81   {
82     size_t repeat = 10000;
83     size_t m = 1000000;
84     char *needle =
85       "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
86       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaAaaaaaaAAAAaaaaaaa"
87       "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
88     char *haystack = (char *) malloc (m + 1);
89     if (haystack != NULL)
90       {
91         memset (haystack, 'A', m);
92         haystack[0] = 'B';
93         haystack[m] = '\0';
94
95         for (; repeat > 0; repeat--)
96           {
97             ASSERT (strcasestr (haystack, needle) == haystack + 1);
98           }
99
100         free (haystack);
101       }
102   }
103
104   /* Check that a very long needle is discarded quickly if the haystack is
105      short.  */
106   {
107     size_t repeat = 10000;
108     size_t m = 1000000;
109     char *haystack =
110       "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
111       "ABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABABAB";
112     char *needle = (char *) malloc (m + 1);
113     if (needle != NULL)
114       {
115         memset (needle, 'A', m);
116         needle[m] = '\0';
117
118         for (; repeat > 0; repeat--)
119           {
120             ASSERT (strcasestr (haystack, needle) == NULL);
121           }
122
123         free (needle);
124       }
125   }
126
127   /* Check that the asymptotic worst-case complexity is not quadratic.  */
128   {
129     size_t m = 1000000;
130     char *haystack = (char *) malloc (2 * m + 2);
131     char *needle = (char *) malloc (m + 2);
132     if (haystack != NULL && needle != NULL)
133       {
134         const char *result;
135
136         memset (haystack, 'A', 2 * m);
137         haystack[2 * m] = 'B';
138         haystack[2 * m + 1] = '\0';
139
140         memset (needle, 'a', m);
141         needle[m] = 'B';
142         needle[m + 1] = '\0';
143
144         result = strcasestr (haystack, needle);
145         ASSERT (result == haystack + m);
146       }
147     free (needle);
148     free (haystack);
149   }
150
151   return 0;
152 }