6 const char *it
= "<UNSET>"; /* Routine name for message routines. */
9 /* Complain if condition is not true. */
10 #define check(thing) checkit(thing, __LINE__)
22 printf("string.c:%d %s\n", l
, it
);
29 /* Complain if first two args don't strcmp as equal. */
30 #define equal(a, b) funcqual(a,b,__LINE__);
40 if (a
== NULL
&& b
== NULL
) return;
42 printf("string.c:%d (%s)\n", l
, it
);
54 /* Test strcmp first because we use it to test other things. */
56 check(strcmp("", "") == 0); /* Trivial case. */
57 check(strcmp("a", "a") == 0); /* Identity. */
58 check(strcmp("abc", "abc") == 0); /* Multicharacter. */
59 check(strcmp("abc", "abcd") < 0); /* Length mismatches. */
60 check(strcmp("abcd", "abc") > 0);
61 check(strcmp("abcd", "abce") < 0); /* Honest miscompares. */
62 check(strcmp("abce", "abcd") > 0);
63 check(strcmp("a\103", "a") > 0); /* Tricky if char signed. */
64 check(strcmp("a\103", "a\003") > 0);
66 /* Test strcpy next because we need it to set up other tests. */
68 check(strcpy(one
, "abcd") == one
); /* Returned value. */
69 equal(one
, "abcd"); /* Basic test. */
71 (void) strcpy(one
, "x");
72 equal(one
, "x"); /* Writeover. */
73 equal(one
+2, "cd"); /* Wrote too much? */
75 (void) strcpy(two
, "hi there");
76 (void) strcpy(one
, two
);
77 equal(one
, "hi there"); /* Basic test encore. */
78 equal(two
, "hi there"); /* Stomped on source? */
80 (void) strcpy(one
, "");
81 equal(one
, ""); /* Boundary condition. */
85 (void) strcpy(one
, "ijk");
86 check(strcat(one
, "lmn") == one
); /* Returned value. */
87 equal(one
, "ijklmn"); /* Basic test. */
89 (void) strcpy(one
, "x");
90 (void) strcat(one
, "yz");
91 equal(one
, "xyz"); /* Writeover. */
92 equal(one
+4, "mn"); /* Wrote too much? */
94 (void) strcpy(one
, "gh");
95 (void) strcpy(two
, "ef");
96 (void) strcat(one
, two
);
97 equal(one
, "ghef"); /* Basic test encore. */
98 equal(two
, "ef"); /* Stomped on source? */
100 (void) strcpy(one
, "");
101 (void) strcat(one
, "");
102 equal(one
, ""); /* Boundary conditions. */
103 (void) strcpy(one
, "ab");
104 (void) strcat(one
, "");
106 (void) strcpy(one
, "");
107 (void) strcat(one
, "cd");
110 /* strncat - first test it as strcat, with big counts,
111 then test the count mechanism. */
113 (void) strcpy(one
, "ijk");
114 check(strncat(one
, "lmn", 99) == one
); /* Returned value. */
115 equal(one
, "ijklmn"); /* Basic test. */
117 (void) strcpy(one
, "x");
118 (void) strncat(one
, "yz", 99);
119 equal(one
, "xyz"); /* Writeover. */
120 equal(one
+4, "mn"); /* Wrote too much? */
122 (void) strcpy(one
, "gh");
123 (void) strcpy(two
, "ef");
124 (void) strncat(one
, two
, 99);
125 equal(one
, "ghef"); /* Basic test encore. */
126 equal(two
, "ef"); /* Stomped on source? */
128 (void) strcpy(one
, "");
129 (void) strncat(one
, "", 99);
130 equal(one
, ""); /* Boundary conditions. */
131 (void) strcpy(one
, "ab");
132 (void) strncat(one
, "", 99);
134 (void) strcpy(one
, "");
135 (void) strncat(one
, "cd", 99);
138 (void) strcpy(one
, "ab");
139 (void) strncat(one
, "cdef", 2);
140 equal(one
, "abcd"); /* Count-limited. */
142 (void) strncat(one
, "gh", 0);
143 equal(one
, "abcd"); /* Zero count. */
145 (void) strncat(one
, "gh", 2);
146 equal(one
, "abcdgh"); /* Count, length equal. */
148 /* strncmp - first test as strcmp with big counts";*/
149 check(strncmp("", "", 99) == 0); /* Trivial case. */
150 check(strncmp("a", "a", 99) == 0); /* Identity. */
151 check(strncmp("abc", "abc", 99) == 0); /* Multicharacter. */
152 check(strncmp("abc", "abcd", 99) < 0); /* Length unequal. */
153 check(strncmp("abcd", "abc",99) > 0);
154 check(strncmp("abcd", "abce", 99) < 0); /* Honestly unequal. */
155 check(strncmp("abce", "abcd",99)>0);
156 check(strncmp("abce", "abcd", 3) == 0); /* Count limited. */
157 check(strncmp("abce", "abc", 3) == 0); /* Count == length. */
158 check(strncmp("abcd", "abce", 4) < 0); /* Nudging limit. */
159 check(strncmp("abc", "def", 0) == 0); /* Zero count. */
161 /* strncpy - testing is a bit different because of odd semantics. */
163 check(strncpy(one
, "abc", 4) == one
); /* Returned value. */
164 equal(one
, "abc"); /* Did the copy go right? */
166 (void) strcpy(one
, "abcdefgh");
167 (void) strncpy(one
, "xyz", 2);
168 equal(one
, "xycdefgh"); /* Copy cut by count. */
170 (void) strcpy(one
, "abcdefgh");
171 (void) strncpy(one
, "xyz", 3); /* Copy cut just before NUL. */
172 equal(one
, "xyzdefgh");
174 (void) strcpy(one
, "abcdefgh");
175 (void) strncpy(one
, "xyz", 4); /* Copy just includes NUL. */
177 equal(one
+4, "efgh"); /* Wrote too much? */
179 (void) strcpy(one
, "abcdefgh");
180 (void) strncpy(one
, "xyz", 5); /* Copy includes padding. */
185 (void) strcpy(one
, "abc");
186 (void) strncpy(one
, "xyz", 0); /* Zero-length copy. */
189 (void) strncpy(one
, "", 2); /* Zero-length source. */
194 (void) strcpy(one
, "hi there");
195 (void) strncpy(two
, one
, 9);
196 equal(two
, "hi there"); /* Just paranoia. */
197 equal(one
, "hi there"); /* Stomped on source? */
201 check(strlen("") == 0); /* Empty. */
202 check(strlen("a") == 1); /* Single char. */
203 check(strlen("abcd") == 4); /* Multiple chars. */
207 check(strchr("abcd", 'z') == NULL
); /* Not found. */
208 (void) strcpy(one
, "abcd");
209 check(strchr(one
, 'c') == one
+2); /* Basic test. */
210 check(strchr(one
, 'd') == one
+3); /* End of string. */
211 check(strchr(one
, 'a') == one
); /* Beginning. */
212 check(strchr(one
, '\0') == one
+4); /* Finding NUL. */
213 (void) strcpy(one
, "ababa");
214 check(strchr(one
, 'b') == one
+1); /* Finding first. */
215 (void) strcpy(one
, "");
216 check(strchr(one
, 'b') == NULL
); /* Empty string. */
217 check(strchr(one
, '\0') == one
); /* NUL in empty string. */
219 /* index - just like strchr. */
221 check(index("abcd", 'z') == NULL
); /* Not found. */
222 (void) strcpy(one
, "abcd");
223 check(index(one
, 'c') == one
+2); /* Basic test. */
224 check(index(one
, 'd') == one
+3); /* End of string. */
225 check(index(one
, 'a') == one
); /* Beginning. */
226 check(index(one
, '\0') == one
+4); /* Finding NUL. */
227 (void) strcpy(one
, "ababa");
228 check(index(one
, 'b') == one
+1); /* Finding first. */
229 (void) strcpy(one
, "");
230 check(index(one
, 'b') == NULL
); /* Empty string. */
231 check(index(one
, '\0') == one
); /* NUL in empty string. */
235 check(strrchr("abcd", 'z') == NULL
); /* Not found. */
236 (void) strcpy(one
, "abcd");
237 check(strrchr(one
, 'c') == one
+2); /* Basic test. */
238 check(strrchr(one
, 'd') == one
+3); /* End of string. */
239 check(strrchr(one
, 'a') == one
); /* Beginning. */
240 check(strrchr(one
, '\0') == one
+4); /* Finding NUL. */
241 (void) strcpy(one
, "ababa");
242 check(strrchr(one
, 'b') == one
+3); /* Finding last. */
243 (void) strcpy(one
, "");
244 check(strrchr(one
, 'b') == NULL
); /* Empty string. */
245 check(strrchr(one
, '\0') == one
); /* NUL in empty string. */
247 /* rindex - just like strrchr. */
249 check(rindex("abcd", 'z') == NULL
); /* Not found. */
250 (void) strcpy(one
, "abcd");
251 check(rindex(one
, 'c') == one
+2); /* Basic test. */
252 check(rindex(one
, 'd') == one
+3); /* End of string. */
253 check(rindex(one
, 'a') == one
); /* Beginning. */
254 check(rindex(one
, '\0') == one
+4); /* Finding NUL. */
255 (void) strcpy(one
, "ababa");
256 check(rindex(one
, 'b') == one
+3); /* Finding last. */
257 (void) strcpy(one
, "");
258 check(rindex(one
, 'b') == NULL
); /* Empty string. */
259 check(rindex(one
, '\0') == one
); /* NUL in empty string. */
261 /* strpbrk - somewhat like strchr. */
263 check(strpbrk("abcd", "z") == NULL
); /* Not found. */
264 (void) strcpy(one
, "abcd");
265 check(strpbrk(one
, "c") == one
+2); /* Basic test. */
266 check(strpbrk(one
, "d") == one
+3); /* End of string. */
267 check(strpbrk(one
, "a") == one
); /* Beginning. */
268 check(strpbrk(one
, "") == NULL
); /* Empty search list. */
269 check(strpbrk(one
, "cb") == one
+1); /* Multiple search. */
270 (void) strcpy(one
, "abcabdea");
271 check(strpbrk(one
, "b") == one
+1); /* Finding first. */
272 check(strpbrk(one
, "cb") == one
+1); /* With multiple search. */
273 check(strpbrk(one
, "db") == one
+1); /* Another variant. */
274 (void) strcpy(one
, "");
275 check(strpbrk(one
, "bc") == NULL
); /* Empty string. */
276 check(strpbrk(one
, "") == NULL
); /* Both strings empty. */
278 /* strstr - somewhat like strchr. */
280 check(strstr("z", "abcd") == NULL
); /* Not found. */
281 check(strstr("abx", "abcd") == NULL
); /* Dead end. */
282 (void) strcpy(one
, "abcd");
283 check(strstr(one
,"c") == one
+2); /* Basic test. */
284 check(strstr(one
, "bc") == one
+1); /* Multichar. */
285 check(strstr(one
,"d") == one
+3); /* End of string. */
286 check(strstr(one
,"cd") == one
+2); /* Tail of string. */
287 check(strstr(one
,"abc") == one
); /* Beginning. */
288 check(strstr(one
,"abcd") == one
); /* Exact match. */
289 check(strstr(one
,"de") == NULL
); /* Past end. */
290 check(strstr(one
,"") == one
); /* Finding empty. */
291 (void) strcpy(one
, "ababa");
292 check(strstr(one
,"ba") == one
+1); /* Finding first. */
293 (void) strcpy(one
, "");
294 check(strstr(one
, "b") == NULL
); /* Empty string. */
295 check(strstr(one
,"") == one
); /* Empty in empty string. */
296 (void) strcpy(one
, "bcbca");
297 check(strstr(one
,"bca") == one
+2); /* False start. */
298 (void) strcpy(one
, "bbbcabbca");
299 check(strstr(one
,"bbca") == one
+1); /* With overlap. */
303 check(strspn("abcba", "abc") == 5); /* Whole string. */
304 check(strspn("abcba", "ab") == 2); /* Partial. */
305 check(strspn("abc", "qx") == 0); /* None. */
306 check(strspn("", "ab") == 0); /* Null string. */
307 check(strspn("abc", "") == 0); /* Null search list. */
311 check(strcspn("abcba", "qx") == 5); /* Whole string. */
312 check(strcspn("abcba", "cx") == 2); /* Partial. */
313 check(strcspn("abc", "abc") == 0); /* None. */
314 check(strcspn("", "ab") == 0); /* Null string. */
315 check(strcspn("abc", "") == 3); /* Null search list. */
317 /* strtok - the hard one. */
319 (void) strcpy(one
, "first, second, third");
320 equal(strtok(one
, ", "), "first"); /* Basic test. */
322 equal(strtok((char *)NULL
, ", "), "second");
323 equal(strtok((char *)NULL
, ", "), "third");
324 check(strtok((char *)NULL
, ", ") == NULL
);
325 (void) strcpy(one
, ", first, ");
326 equal(strtok(one
, ", "), "first"); /* Extra delims, 1 tok. */
327 check(strtok((char *)NULL
, ", ") == NULL
);
328 (void) strcpy(one
, "1a, 1b; 2a, 2b");
329 equal(strtok(one
, ", "), "1a"); /* Changing delim lists. */
330 equal(strtok((char *)NULL
, "; "), "1b");
331 equal(strtok((char *)NULL
, ", "), "2a");
332 (void) strcpy(two
, "x-y");
333 equal(strtok(two
, "-"), "x"); /* New string before done. */
334 equal(strtok((char *)NULL
, "-"), "y");
335 check(strtok((char *)NULL
, "-") == NULL
);
336 (void) strcpy(one
, "a,b, c,, ,d");
337 equal(strtok(one
, ", "), "a"); /* Different separators. */
338 equal(strtok((char *)NULL
, ", "), "b");
339 equal(strtok((char *)NULL
, " ,"), "c"); /* Permute list too. */
340 equal(strtok((char *)NULL
, " ,"), "d");
341 check(strtok((char *)NULL
, ", ") == NULL
);
342 check(strtok((char *)NULL
, ", ") == NULL
); /* Persistence. */
343 (void) strcpy(one
, ", ");
344 check(strtok(one
, ", ") == NULL
); /* No tokens. */
345 (void) strcpy(one
, "");
346 check(strtok(one
, ", ") == NULL
); /* Empty string. */
347 (void) strcpy(one
, "abc");
348 equal(strtok(one
, ", "), "abc"); /* No delimiters. */
349 check(strtok((char *)NULL
, ", ") == NULL
);
350 (void) strcpy(one
, "abc");
351 equal(strtok(one
, ""), "abc"); /* Empty delimiter list. */
352 check(strtok((char *)NULL
, "") == NULL
);
353 (void) strcpy(one
, "abcdefgh");
354 (void) strcpy(one
, "a,b,c");
355 equal(strtok(one
, ","), "a"); /* Basics again... */
356 equal(strtok((char *)NULL
, ","), "b");
357 equal(strtok((char *)NULL
, ","), "c");
358 check(strtok((char *)NULL
, ",") == NULL
);
359 equal(one
+6, "gh"); /* Stomped past end? */
360 equal(one
, "a"); /* Stomped old tokens? */
366 check(memcmp("a", "a", 1) == 0); /* Identity. */
367 check(memcmp("abc", "abc", 3) == 0); /* Multicharacter. */
368 check(memcmp("abcd", "abce", 4) < 0); /* Honestly unequal. */
369 check(memcmp("abce", "abcd",4));
370 check(memcmp("alph", "beta", 4) < 0);
371 check(memcmp("abce", "abcd", 3) == 0); /* Count limited. */
372 check(memcmp("abc", "def", 0) == 0); /* Zero count. */
374 /* memcmp should test strings as unsigned */
377 check(memcmp(one
, two
,1) > 0);
382 check(memchr("abcd", 'z', 4) == NULL
); /* Not found. */
383 (void) strcpy(one
, "abcd");
384 check(memchr(one
, 'c', 4) == one
+2); /* Basic test. */
385 check(memchr(one
, 'd', 4) == one
+3); /* End of string. */
386 check(memchr(one
, 'a', 4) == one
); /* Beginning. */
387 check(memchr(one
, '\0', 5) == one
+4); /* Finding NUL. */
388 (void) strcpy(one
, "ababa");
389 check(memchr(one
, 'b', 5) == one
+1); /* Finding first. */
390 check(memchr(one
, 'b', 0) == NULL
); /* Zero count. */
391 check(memchr(one
, 'a', 1) == one
); /* Singleton case. */
392 (void) strcpy(one
, "a\203b");
393 check(memchr(one
, 0203, 3) == one
+1); /* Unsignedness. */
395 /* memcpy - need not work for overlap. */
397 check(memcpy(one
, "abc", 4) == one
); /* Returned value. */
398 equal(one
, "abc"); /* Did the copy go right? */
400 (void) strcpy(one
, "abcdefgh");
401 (void) memcpy(one
+1, "xyz", 2);
402 equal(one
, "axydefgh"); /* Basic test. */
404 (void) strcpy(one
, "abc");
405 (void) memcpy(one
, "xyz", 0);
406 equal(one
, "abc"); /* Zero-length copy. */
408 (void) strcpy(one
, "hi there");
409 (void) strcpy(two
, "foo");
410 (void) memcpy(two
, one
, 9);
411 equal(two
, "hi there"); /* Just paranoia. */
412 equal(one
, "hi there"); /* Stomped on source? */
414 /* memmove - must work on overlap. */
416 check(memmove(one
, "abc", 4) == one
); /* Returned value. */
417 equal(one
, "abc"); /* Did the copy go right? */
419 (void) strcpy(one
, "abcdefgh");
420 (void) memmove(one
+1, "xyz", 2);
421 equal(one
, "axydefgh"); /* Basic test. */
423 (void) strcpy(one
, "abc");
424 (void) memmove(one
, "xyz", 0);
425 equal(one
, "abc"); /* Zero-length copy. */
427 (void) strcpy(one
, "hi there");
428 (void) strcpy(two
, "foo");
429 (void) memmove(two
, one
, 9);
430 equal(two
, "hi there"); /* Just paranoia. */
431 equal(one
, "hi there"); /* Stomped on source? */
433 (void) strcpy(one
, "abcdefgh");
434 (void) memmove(one
+1, one
, 9);
435 equal(one
, "aabcdefgh"); /* Overlap, right-to-left. */
437 (void) strcpy(one
, "abcdefgh");
438 (void) memmove(one
+1, one
+2, 7);
439 equal(one
, "acdefgh"); /* Overlap, left-to-right. */
441 (void) strcpy(one
, "abcdefgh");
442 (void) memmove(one
, one
, 9);
443 equal(one
, "abcdefgh"); /* 100% overlap. */
446 /* memccpy - first test like memcpy, then the search part
447 The SVID, the only place where memccpy is mentioned, says
448 overlap might fail, so we don't try it. Besides, it's hard
449 to see the rationale for a non-left-to-right memccpy. */
451 check(memccpy(one
, "abc", 'q', 4) == NULL
); /* Returned value. */
452 equal(one
, "abc"); /* Did the copy go right? */
454 (void) strcpy(one
, "abcdefgh");
455 (void) memccpy(one
+1, "xyz", 'q', 2);
456 equal(one
, "axydefgh"); /* Basic test. */
458 (void) strcpy(one
, "abc");
459 (void) memccpy(one
, "xyz", 'q', 0);
460 equal(one
, "abc"); /* Zero-length copy. */
462 (void) strcpy(one
, "hi there");
463 (void) strcpy(two
, "foo");
464 (void) memccpy(two
, one
, 'q', 9);
465 equal(two
, "hi there"); /* Just paranoia. */
466 equal(one
, "hi there"); /* Stomped on source? */
468 (void) strcpy(one
, "abcdefgh");
469 (void) strcpy(two
, "horsefeathers");
470 check(memccpy(two
, one
, 'f', 9) == two
+6); /* Returned value. */
471 equal(one
, "abcdefgh"); /* Source intact? */
472 equal(two
, "abcdefeathers"); /* Copy correct? */
474 (void) strcpy(one
, "abcd");
475 (void) strcpy(two
, "bumblebee");
476 check(memccpy(two
, one
, 'a', 4) == two
+1); /* First char. */
477 equal(two
, "aumblebee");
478 check(memccpy(two
, one
, 'd', 4) == two
+4); /* Last char. */
479 equal(two
, "abcdlebee");
480 (void) strcpy(one
, "xyz");
481 check(memccpy(two
, one
, 'x', 1) == two
+1); /* Singleton. */
482 equal(two
, "xbcdlebee");
486 (void) strcpy(one
, "abcdefgh");
487 check(memset(one
+1, 'x', 3) == one
+1); /* Return value. */
488 equal(one
, "axxxefgh"); /* Basic test. */
490 (void) memset(one
+2, 'y', 0);
491 equal(one
, "axxxefgh"); /* Zero-length set. */
493 (void) memset(one
+5, 0, 1);
494 equal(one
, "axxxe"); /* Zero fill. */
495 equal(one
+6, "gh"); /*, the leftover. */
497 (void) memset(one
+2, 010045, 1);
498 equal(one
, "ax\045xe"); /* Unsigned char convert. */
500 /* bcopy - much like memcpy.
501 Berklix manual is silent about overlap, so don't test it. */
503 (void) bcopy("abc", one
, 4);
504 equal(one
, "abc"); /* Simple copy. */
506 (void) strcpy(one
, "abcdefgh");
507 (void) bcopy("xyz", one
+1, 2);
508 equal(one
, "axydefgh"); /* Basic test. */
510 (void) strcpy(one
, "abc");
511 (void) bcopy("xyz", one
, 0);
512 equal(one
, "abc"); /* Zero-length copy. */
514 (void) strcpy(one
, "hi there");
515 (void) strcpy(two
, "foo");
516 (void) bcopy(one
, two
, 9);
517 equal(two
, "hi there"); /* Just paranoia. */
518 equal(one
, "hi there"); /* Stomped on source? */
522 (void) strcpy(one
, "abcdef");
524 equal(one
, "ab"); /* Basic test. */
528 (void) strcpy(one
, "abcdef");
530 equal(one
, "abcdef"); /* Zero-length copy. */
532 /* bcmp - somewhat like memcmp. */
534 check(bcmp("a", "a", 1) == 0); /* Identity. */
535 check(bcmp("abc", "abc", 3) == 0); /* Multicharacter. */
536 check(bcmp("abcd", "abce", 4) != 0); /* Honestly unequal. */
537 check(bcmp("abce", "abcd",4));
538 check(bcmp("alph", "beta", 4) != 0);
539 check(bcmp("abce", "abcd", 3) == 0); /* Count limited. */
540 check(bcmp("abc", "def", 0) == 0); /* Zero count. */
542 #if 0 /* strerror - VERY system-dependent. */
544 extern CONST
unsigned int _sys_nerr
;
545 extern CONST
char *CONST _sys_errlist
[];
548 f
= open("/", O_WRONLY
); /* Should always fail. */
549 check(f
< 0 && errno
> 0 && errno
< _sys_nerr
);
550 equal(strerror(errno
), _sys_errlist
[errno
]);