1 /** tests for strXXX
2 */
3 #include <testfwk.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199409L
7 #include <wchar.h>
8 #endif
9 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
10 #include <uchar.h>
11 #endif
12 
13 /** tests for strcmp
14 */
15 static void
do_teststrcmp(void)16 do_teststrcmp (void)
17 {
18 #ifndef __SDCC_pdk14 // Lack of memory
19 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
20   int result = strcmp ("", "");
21   ASSERT (result == 0);
22 
23   result = strcmp ("", "a");
24   ASSERT (result < 0);
25 
26   result = strcmp ("a", "");
27   ASSERT (result > 0);
28 
29   result = strcmp ("ab", "ab");
30   ASSERT (result == 0);
31 
32   result = strcmp ("aa", "ab");
33   ASSERT (result < 0);
34 #endif
35 #endif
36 }
37 
38 /** tests for strcpy
39 */
40 static void
do_teststrcpy(void)41 do_teststrcpy (void)
42 {
43 #ifndef __SDCC_pdk14 // Lack of memory
44 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
45   static char empty[] = "";
46   static char string[] = "\1\2\0\3";
47   char buf[40] = "abcdefghijklmnopqrstuvwxyz";
48 
49   char * result = strcpy (buf, empty);
50   ASSERT (strlen (buf) == 0);
51   ASSERT (result == buf);
52 
53   result = strcpy (buf, string);
54   ASSERT (result == buf);
55   ASSERT (strlen (buf) == 2);
56   ASSERT (buf[0] == '\1');
57   ASSERT (buf[1] == '\2');
58   ASSERT (buf[3] == 'd');
59 #endif
60 #endif
61 }
62 
63 /** tests for strncmp
64 */
65 static void
do_teststrncmp(void)66 do_teststrncmp (void)
67 {
68 #ifndef __SDCC_pdk14 // Lack of memory
69 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
70   ASSERT (strncmp ("", "", 0) == 0);
71   ASSERT (strncmp ("ab", "ab", 0) == 0);
72   ASSERT (strncmp ("a", "a", 2) == 0);
73   ASSERT (strncmp ("aa", "ab", 1) == 0);
74   ASSERT (strncmp ("aa", "ab", 2) < 0);
75   ASSERT (strncmp ("abc", "abd", 2) == 0);
76   ASSERT (strncmp ("abc", "abc", 3) == 0);
77 #endif
78 #endif
79 }
80 
81 /** tests for strpbrk
82  * related to bug #2908537
83 */
84 static void
do_teststrpbrk(void)85 do_teststrpbrk (void)
86 {
87 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
88   const char *a = "test";
89 
90   ASSERT (strpbrk (a, "e")  == &a[1] );
91   ASSERT (strpbrk (a, "z")  == NULL );
92   ASSERT (strpbrk (a, "et") == &a[0] );
93   ASSERT (strpbrk (a, "ze") == &a[1] );
94   ASSERT (strpbrk (a, "")   == NULL );
95   ASSERT (strpbrk ("", "e") == NULL );
96   ASSERT (*strpbrk ("test2", "s") == 's' );
97 #endif
98 }
99 
100 /** tests for strrchr
101 */
102 static void
do_teststrrchr(void)103 do_teststrrchr (void)
104 {
105 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
106   const char *test = "test";
107 
108   ASSERT (strrchr (test, 0) == test + 4);
109   ASSERT (strrchr (test, 't') == test + 3);
110   ASSERT (strrchr (test, 'e') == test + 1);
111 #endif
112 }
113 
114 /** tests for strstr
115 */
116 static void
do_teststrstr(void)117 do_teststrstr (void)
118 {
119 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
120   const char *a = "aabbcd";
121   ASSERT (strstr (a, "\0\1") == a);
122   ASSERT (strstr (a, "") == a);
123   ASSERT (strstr (a, "ab") == &a[1]);
124   ASSERT (strstr (a, "abc") == NULL);
125   ASSERT (strstr (a, "abbc") == &a[1]);
126   ASSERT (strstr ("", "abbc") == NULL);
127 /* ASSERT (strstr ("", "") == a); should work, but it doesn't */
128   ASSERT (strstr (a, "cd") == &a[4]);
129 #endif
130 }
131 
132 /** tests for strspn
133 */
134 static void
do_teststrspn(void)135 do_teststrspn (void)
136 {
137 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
138   ASSERT (strspn("aabbcd", "ab") == 4);
139   ASSERT (strspn("abbacd", "") == 0);
140   ASSERT (strspn("abbacd", "ac") == 1);
141   ASSERT (strspn("abbacd", "x") == 0);
142   ASSERT (strspn("abbacd", "c") == 0);
143   ASSERT (strspn("abbacd", "cba") == 5);
144   ASSERT (strspn("abbacd", "cdba") == 6);
145 #endif
146 }
147 
148 /** tests for strtok
149 */
150 static void
do_teststrtok(void)151 do_teststrtok (void)
152 {
153 #if !defined(__SDCC_pdk14) && !defined(__SDCC_pdk15) // Lack of memory
154   static char str[] = "?a???b,,,#c";
155   char str2[] = "axaaba";
156   char *token = strtok (str, "?"); // 'token' points to the token "a"
157   ASSERT (token == &str[1] && 0 == strcmp (token,"a"));
158   token = strtok (NULL, ","); // 'token' points to the token "??b"
159   ASSERT (token == &str[3] && 0 == strcmp (token,"??b"));
160   token = strtok (NULL, "#,"); // 'token' points to the token "c"
161   ASSERT (token == &str[10] && 0 == strcmp (token,"c"));
162   token = strtok (NULL, "?"); // 'token' is a null pointer
163   ASSERT (token == NULL);
164 
165   token = strtok (str2, "ab");
166   ASSERT (token && 0 == strcmp (token, "x"));
167   token = strtok (NULL, "ab");
168   ASSERT (token == NULL);
169 #if !defined (__SUNPRO_C) && !defined (__sun__)
170   /* SunPro C compiler and GCC on Solaris have problem with strtok-ing after NULL */
171   token = strtok (NULL, "a");
172   ASSERT (token == NULL);
173 #endif
174 #endif
175 }
176 
177 #if !defined (__APPLE__) // uchar.h/char16_t/char32_t are not supported on MacOS/Clang
178 
179 // Test C11 UTF-8 behaviour.
180 static void
do_utf_8(void)181 do_utf_8 (void)
182 {
183 #ifndef __SDCC_pdk14 // Lack of memory
184 #if defined(__STDC_VERSION) && __STDC_VERSION >= 201112L
185   const char *str1 = u8"Ä ä";
186   const char *str2 = u8"\u00c4 ä";
187   const char *str3 = u8"Ä " "ä";
188   const char *str4 = u8"Ä " u8"ä";
189   const char *str5 = "Ä " u8"ä";
190 
191   ASSERT (str1[0] == 0xc3);
192   ASSERT (str2[1] == 0x84);
193   ASSERT (!strcmp (str1, str2));
194   ASSERT (!strcmp (str1, str3));
195   ASSERT (!strcmp (str1, str4));
196   ASSERT (!strcmp (str1, str5));
197 #endif
198 #endif
199 }
200 
201 // Test SDCC implementation-defined UTF-8 behaviour
202 // string literals are UTF-8 (as nearly all implementations out there)
203 static void
do_utf_8_sdcc(void)204 do_utf_8_sdcc (void)
205 {
206 #ifndef __SDCC_pdk14 // Lack of memory
207 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
208 #ifdef __SDCC
209   const char *str1 = "Ä ä";
210   const char *str2 = "\u00c4 ä";
211   const char *str3 = u8"Ä " "ä";
212   const char *str4 = "Ä " "ä";
213   const char *str5 = u8"Ä " u8"ä";
214 
215   ASSERT (str1[0] == 0xc3);
216   ASSERT (str2[1] == 0x84);
217   ASSERT (!strcmp (str1, str2));
218   ASSERT (!strcmp (str1, str3));
219   ASSERT (!strcmp (str1, str4));
220   ASSERT (!strcmp (str1, str5));
221 
222   ASSERT (!mblen(0, 0));
223   ASSERT (mblen(str1, 3) == 2);
224   ASSERT (mblen("test", 3) == 1);
225   ASSERT (mblen("", 3) == 0);
226 #endif
227 #endif
228 #endif
229 }
230 
231 // Test C11 UTF-16 behaviour
232 static void
do_utf_16(void)233 do_utf_16 (void)
234 {
235 #if defined(__STDC_UTF_16__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
236   const char16_t *str1 = u"Ä ä";
237   const char16_t *str2 = u"\u00c4 ä";
238   const char16_t *str3 = u"Ä " "ä";
239   const char16_t *str4 = "Ä " u"ä";
240   const char16_t *str5 = u"Ä " u"ä";
241 
242   ASSERT (str1[0] == 0xc4);
243   ASSERT (str2[2] == 0xe4);
244   ASSERT (!memcmp (str1, str2, 4 * sizeof(char16_t)));
245   ASSERT (!memcmp (str1, str3, 4 * sizeof(char16_t)));
246   ASSERT (!memcmp (str1, str4, 4 * sizeof(char16_t)));
247   ASSERT (!memcmp (str1, str5, 4 * sizeof(char16_t)));
248 #endif
249 }
250 
251 // Test C95 UTF-32 behaviour
252 static void
do_utf_32_c95(void)253 do_utf_32_c95 (void)
254 {
255 #ifndef __SDCC_pdk14 // Lack of memory
256 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
257 #ifdef __STDC_ISO_10646__
258   const wchar_t *str1 = L"Ä ä";
259   const wchar_t *str2 = L"\u00c4 ä";
260   const wchar_t *str3 = L"Ä " "ä";
261   const wchar_t *str4 = "Ä " L"ä";
262   const wchar_t *str5 = L"Ä " L"ä";
263 
264   ASSERT (str1[0] == 0xc4);
265   ASSERT (str2[2] == 0xe4);
266   ASSERT (wcslen (str1) == 3);
267   ASSERT (!memcmp (str1, str2, 4 * sizeof(wchar_t)));
268   ASSERT (!memcmp (str1, str3, 4 * sizeof(wchar_t)));
269   ASSERT (!memcmp (str1, str4, 4 * sizeof(wchar_t)));
270   ASSERT (!memcmp (str1, str5, 4 * sizeof(wchar_t)));
271 #endif
272 #endif
273 #endif
274 }
275 
276 // Test C11 UTF-32 behaviour
277 static void
do_utf_32_c11(void)278 do_utf_32_c11 (void)
279 {
280 #if defined(__STDC_UTF_32__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
281   const char32_t *str1 = U"Ä ä";
282   const char32_t *str2 = U"\u00c4 ä";
283   const char32_t *str3 = U"Ä " "ä";
284   const char32_t *str4 = "Ä " U"ä";
285   const char32_t *str5 = U"Ä " U"ä";
286 
287   ASSERT (str1[0] == 0xc4);
288   ASSERT (str2[2] == 0xe4);
289   ASSERT (!memcmp (str1, str2, 4 * sizeof(char32_t)));
290   ASSERT (!memcmp (str1, str3, 4 * sizeof(char32_t)));
291   ASSERT (!memcmp (str1, str4, 4 * sizeof(char32_t)));
292   ASSERT (!memcmp (str1, str5, 4 * sizeof(char32_t)));
293 #endif
294 }
295 
296 static void
do_chinese(void)297 do_chinese (void)
298 {
299 #if defined(__STDC_UTF_32__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
300   const char32_t *p0 = U"史斌";
301 #endif
302 #ifdef __STDC_ISO_10646__
303   const wchar_t *p1 = L"史庭芳";
304 #endif
305 #if defined(__STDC_UTF_16__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
306   const char16_t *p2 = u"天津";
307 #endif
308 #if defined(__STDC_UTF_32__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
309   ASSERT (p0[0] == 0x53f2);
310 #endif
311 #ifdef __STDC_ISO_10646__
312   ASSERT (p1[2] == 0x82b3);
313 #endif
314 #if defined(__STDC_UTF_16__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
315   ASSERT (p2[1] == 0x6d25);
316 #endif
317 }
318 
319 #endif // __APPLE__
320 
321 static void
teststr(void)322 teststr (void)
323 {
324   do_teststrcmp ();
325   do_teststrcpy ();
326   do_teststrncmp ();
327   do_teststrpbrk ();
328   do_teststrrchr ();
329   do_teststrstr ();
330   do_teststrspn ();
331   do_teststrtok ();
332 #if !defined (__APPLE__)
333   do_utf_8 ();
334   do_utf_8_sdcc ();
335   do_utf_16 ();
336   do_utf_32_c95 ();
337   do_utf_32_c11 ();
338   do_chinese ();
339 #endif // __APPLE__
340 }
341 
342