[9] | 1 | /* Test program for string(3) routines.
|
---|
| 2 | *
|
---|
| 3 | * Slightly modified from Henry Spencer's original routine.
|
---|
| 4 | * - incorporates semantic changes per the ANSI standard (original tests
|
---|
| 5 | * can be recovered by defining the symbol NOT_ANSI while compiling,
|
---|
| 6 | * except for the change of memcpy() to memmove()).
|
---|
| 7 | * - makes additional tests of functions on unaligned buffers and strings.
|
---|
| 8 | */
|
---|
| 9 |
|
---|
| 10 | #include <sys/types.h>
|
---|
| 11 | #include <fcntl.h>
|
---|
| 12 | #include <string.h>
|
---|
| 13 | #include <stdlib.h>
|
---|
| 14 | #include <stdio.h>
|
---|
| 15 |
|
---|
| 16 | _PROTOTYPE( int chdir, (char *_path)); /* from <unistd.h> */
|
---|
| 17 |
|
---|
| 18 | #define STREQ(a, b) (strcmp((a), (b)) == 0)
|
---|
| 19 |
|
---|
| 20 | char *it = "<UNSET>"; /* Routine name for message routines. */
|
---|
| 21 | int errct; /* count errors */
|
---|
| 22 | int waserror = 0; /* For exit status. */
|
---|
| 23 |
|
---|
| 24 | char uctest[] = "\004\203"; /* For testing signedness of chars. */
|
---|
| 25 | int charsigned; /* Result. */
|
---|
| 26 |
|
---|
| 27 | _PROTOTYPE(void check, (int thing, int number));
|
---|
| 28 | _PROTOTYPE(void equal, (char *a, char *b, int number));
|
---|
| 29 | _PROTOTYPE(int main, (int argc, char *argv []));
|
---|
| 30 | _PROTOTYPE(void first, (void));
|
---|
| 31 | _PROTOTYPE(void second, (void));
|
---|
| 32 | _PROTOTYPE(void quit, (void));
|
---|
| 33 |
|
---|
| 34 | /*
|
---|
| 35 | - check - complain if condition is not true
|
---|
| 36 | */
|
---|
| 37 | void check(thing, number)
|
---|
| 38 | int thing;
|
---|
| 39 | int number; /* Test number for error message. */
|
---|
| 40 | {
|
---|
| 41 | if (!thing) {
|
---|
| 42 | printf("%s flunked test %d\n", it, number);
|
---|
| 43 | waserror = 1;
|
---|
| 44 | errct++;
|
---|
| 45 | }
|
---|
| 46 | }
|
---|
| 47 |
|
---|
| 48 | /*
|
---|
| 49 | - equal - complain if first two args don't strcmp as equal
|
---|
| 50 | */
|
---|
| 51 | void equal(a, b, number)
|
---|
| 52 | char *a;
|
---|
| 53 | char *b;
|
---|
| 54 | int number; /* Test number for error message. */
|
---|
| 55 | {
|
---|
| 56 | check(a != NULL && b != NULL && STREQ(a, b), number);
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | char one[50];
|
---|
| 60 | char two[50];
|
---|
| 61 |
|
---|
| 62 | #ifdef UNIXERR
|
---|
| 63 | #define ERR 1
|
---|
| 64 | #endif
|
---|
| 65 | #ifdef BERKERR
|
---|
| 66 | #define ERR 1
|
---|
| 67 | #endif
|
---|
| 68 | #ifdef ERR
|
---|
| 69 | int f;
|
---|
| 70 | extern char *sys_errlist[];
|
---|
| 71 | extern int sys_nerr;
|
---|
| 72 | #endif
|
---|
| 73 |
|
---|
| 74 | /* ARGSUSED */
|
---|
| 75 | int main(argc, argv)
|
---|
| 76 | int argc;
|
---|
| 77 | char *argv[];
|
---|
| 78 | {
|
---|
| 79 | printf("Test 15 ");
|
---|
| 80 | fflush(stdout);
|
---|
| 81 |
|
---|
| 82 | system("rm -rf DIR_15; mkdir DIR_15");
|
---|
| 83 | chdir("DIR_15");
|
---|
| 84 | /* First, establish whether chars are signed. */
|
---|
| 85 | if (uctest[0] < uctest[1])
|
---|
| 86 | charsigned = 0;
|
---|
| 87 | else
|
---|
| 88 | charsigned = 1;
|
---|
| 89 |
|
---|
| 90 | /* Then, do the rest of the work. Split into two functions because
|
---|
| 91 | * some compilers get unhappy about a single immense function. */
|
---|
| 92 | first();
|
---|
| 93 | second();
|
---|
| 94 |
|
---|
| 95 | errct = waserror;
|
---|
| 96 | quit();
|
---|
| 97 | return(-1); /* impossible */
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | void first()
|
---|
| 101 | {
|
---|
| 102 | /* Test strcmp first because we use it to test other things. */
|
---|
| 103 | it = "strcmp";
|
---|
| 104 | check(strcmp("", "") == 0, 1);/* Trivial case. */
|
---|
| 105 | check(strcmp("a", "a") == 0, 2); /* Identity. */
|
---|
| 106 | check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */
|
---|
| 107 | check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */
|
---|
| 108 | check(strcmp("abcd", "abc") > 0, 5);
|
---|
| 109 | check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */
|
---|
| 110 | check(strcmp("abce", "abcd") > 0, 7);
|
---|
| 111 | check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */
|
---|
| 112 |
|
---|
| 113 | #ifdef NOT_ANSI
|
---|
| 114 | if (charsigned)
|
---|
| 115 | check(strcmp("a\203", "a\003") < 0, 9);
|
---|
| 116 | else
|
---|
| 117 | check(strcmp("a\203", "a\003") > 0, 9);
|
---|
| 118 | #else
|
---|
| 119 | check(strcmp("a\203", "a\003") > 0, 9);
|
---|
| 120 | #endif
|
---|
| 121 |
|
---|
| 122 | check(strcmp("abcd" + 1, "abcd" + 1) == 0, 10); /* Unaligned tests. */
|
---|
| 123 | check(strcmp("abcd" + 1, "abce" + 1) < 0, 11);
|
---|
| 124 | check(strcmp("abcd" + 1, "bcd") == 0, 12);
|
---|
| 125 | check(strcmp("abce" + 1, "bcd") > 0, 13);
|
---|
| 126 | check(strcmp("abcd" + 2, "bcd" + 1) == 0, 14);
|
---|
| 127 | check(strcmp("abcd" + 2, "bce" + 1) < 0, 15);
|
---|
| 128 |
|
---|
| 129 | /* Test strcpy next because we need it to set up other tests. */
|
---|
| 130 | it = "strcpy";
|
---|
| 131 | check(strcpy(one, "abcd") == one, 1); /* Returned value. */
|
---|
| 132 | equal(one, "abcd", 2); /* Basic test. */
|
---|
| 133 |
|
---|
| 134 | (void) strcpy(one, "x");
|
---|
| 135 | equal(one, "x", 3); /* Writeover. */
|
---|
| 136 | equal(one + 2, "cd", 4); /* Wrote too much? */
|
---|
| 137 |
|
---|
| 138 | (void) strcpy(two, "hi there");
|
---|
| 139 | (void) strcpy(one, two);
|
---|
| 140 | equal(one, "hi there", 5); /* Basic test encore. */
|
---|
| 141 | equal(two, "hi there", 6); /* Stomped on source? */
|
---|
| 142 |
|
---|
| 143 | (void) strcpy(one, "");
|
---|
| 144 | equal(one, "", 7); /* Boundary condition. */
|
---|
| 145 |
|
---|
| 146 | (void) strcpy(one, "abcdef" + 1); /* Unaligned tests. */
|
---|
| 147 | equal(one, "bcdef", 8);
|
---|
| 148 | (void) strcpy(one + 1, "*xy" + 1);
|
---|
| 149 | equal(one, "bxy", 9);
|
---|
| 150 | equal(one + 4, "f", 10);
|
---|
| 151 |
|
---|
| 152 | /* Strcat */
|
---|
| 153 | it = "strcat";
|
---|
| 154 | (void) strcpy(one, "ijk");
|
---|
| 155 | check(strcat(one, "lmn") == one, 1); /* Returned value. */
|
---|
| 156 | equal(one, "ijklmn", 2); /* Basic test. */
|
---|
| 157 |
|
---|
| 158 | (void) strcpy(one, "x");
|
---|
| 159 | (void) strcat(one, "yz");
|
---|
| 160 | equal(one, "xyz", 3); /* Writeover. */
|
---|
| 161 | equal(one + 4, "mn", 4); /* Wrote too much? */
|
---|
| 162 |
|
---|
| 163 | (void) strcpy(one, "gh");
|
---|
| 164 | (void) strcpy(two, "ef");
|
---|
| 165 | (void) strcat(one, two);
|
---|
| 166 | equal(one, "ghef", 5); /* Basic test encore. */
|
---|
| 167 | equal(two, "ef", 6); /* Stomped on source? */
|
---|
| 168 |
|
---|
| 169 | (void) strcpy(one, "");
|
---|
| 170 | (void) strcat(one, "");
|
---|
| 171 | equal(one, "", 7); /* Boundary conditions. */
|
---|
| 172 | (void) strcpy(one, "ab");
|
---|
| 173 | (void) strcat(one, "");
|
---|
| 174 | equal(one, "ab", 8);
|
---|
| 175 | (void) strcpy(one, "");
|
---|
| 176 | (void) strcat(one, "cd");
|
---|
| 177 | equal(one, "cd", 9);
|
---|
| 178 |
|
---|
| 179 | /* Strncat - first test it as strcat, with big counts, then test the
|
---|
| 180 | * count mechanism. */
|
---|
| 181 | it = "strncat";
|
---|
| 182 | (void) strcpy(one, "ijk");
|
---|
| 183 | check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
|
---|
| 184 | equal(one, "ijklmn", 2); /* Basic test. */
|
---|
| 185 |
|
---|
| 186 | (void) strcpy(one, "x");
|
---|
| 187 | (void) strncat(one, "yz", 99);
|
---|
| 188 | equal(one, "xyz", 3); /* Writeover. */
|
---|
| 189 | equal(one + 4, "mn", 4); /* Wrote too much? */
|
---|
| 190 |
|
---|
| 191 | (void) strcpy(one, "gh");
|
---|
| 192 | (void) strcpy(two, "ef");
|
---|
| 193 | (void) strncat(one, two, 99);
|
---|
| 194 | equal(one, "ghef", 5); /* Basic test encore. */
|
---|
| 195 | equal(two, "ef", 6); /* Stomped on source? */
|
---|
| 196 |
|
---|
| 197 | (void) strcpy(one, "");
|
---|
| 198 | (void) strncat(one, "", 99);
|
---|
| 199 | equal(one, "", 7); /* Boundary conditions. */
|
---|
| 200 | (void) strcpy(one, "ab");
|
---|
| 201 | (void) strncat(one, "", 99);
|
---|
| 202 | equal(one, "ab", 8);
|
---|
| 203 | (void) strcpy(one, "");
|
---|
| 204 | (void) strncat(one, "cd", 99);
|
---|
| 205 | equal(one, "cd", 9);
|
---|
| 206 |
|
---|
| 207 | (void) strcpy(one, "ab");
|
---|
| 208 | (void) strncat(one, "cdef", 2);
|
---|
| 209 | equal(one, "abcd", 10); /* Count-limited. */
|
---|
| 210 |
|
---|
| 211 | (void) strncat(one, "gh", 0);
|
---|
| 212 | equal(one, "abcd", 11); /* Zero count. */
|
---|
| 213 |
|
---|
| 214 | (void) strncat(one, "gh", 2);
|
---|
| 215 | equal(one, "abcdgh", 12); /* Count and length equal. */
|
---|
| 216 |
|
---|
| 217 | (void) strcpy(one, "abcdefghij"); /* Unaligned tests. */
|
---|
| 218 | (void) strcpy(one, "abcd");
|
---|
| 219 | (void) strcpy(one, "abc");
|
---|
| 220 | (void) strncat(one, "de" + 1, 1);
|
---|
| 221 | equal(one, "abce", 13);
|
---|
| 222 | equal(one + 4, "", 14);
|
---|
| 223 | equal(one + 5, "fghij", 15);
|
---|
| 224 |
|
---|
| 225 | /* Strncmp - first test as strcmp with big counts, then test count code. */
|
---|
| 226 | it = "strncmp";
|
---|
| 227 | check(strncmp("", "", 99) == 0, 1); /* Trivial case. */
|
---|
| 228 | check(strncmp("a", "a", 99) == 0, 2); /* Identity. */
|
---|
| 229 | check(strncmp("abc", "abc", 99) == 0, 3); /* Multicharacter. */
|
---|
| 230 | check(strncmp("abc", "abcd", 99) < 0, 4); /* Length unequal. */
|
---|
| 231 | check(strncmp("abcd", "abc", 99) > 0, 5);
|
---|
| 232 | check(strncmp("abcd", "abce", 99) < 0, 6); /* Honestly unequal. */
|
---|
| 233 | check(strncmp("abce", "abcd", 99) > 0, 7);
|
---|
| 234 | check(strncmp("a\203", "a", 2) > 0, 8); /* Tricky if '\203' < 0 */
|
---|
| 235 |
|
---|
| 236 | #ifdef NOT_ANSI
|
---|
| 237 | if (charsigned)
|
---|
| 238 | check(strncmp("a\203", "a\003", 2) < 0, 9);
|
---|
| 239 | else
|
---|
| 240 | check(strncmp("a\203", "a\003", 2) > 0, 9);
|
---|
| 241 | #else
|
---|
| 242 | check(strncmp("a\203", "a\003", 2) > 0, 9);
|
---|
| 243 | #endif
|
---|
| 244 |
|
---|
| 245 | check(strncmp("abce", "abcd", 3) == 0, 10); /* Count limited. */
|
---|
| 246 | check(strncmp("abce", "abc", 3) == 0, 11); /* Count == length. */
|
---|
| 247 | check(strncmp("abcd", "abce", 4) < 0, 12); /* Nudging limit. */
|
---|
| 248 | check(strncmp("abc", "def", 0) == 0, 13); /* Zero count. */
|
---|
| 249 |
|
---|
| 250 | /* Strncpy - testing is a bit different because of odd semantics */
|
---|
| 251 | it = "strncpy";
|
---|
| 252 | check(strncpy(one, "abc", 4) == one, 1); /* Returned value. */
|
---|
| 253 | equal(one, "abc", 2); /* Did the copy go right? */
|
---|
| 254 |
|
---|
| 255 | (void) strcpy(one, "abcdefgh");
|
---|
| 256 | (void) strncpy(one, "xyz", 2);
|
---|
| 257 | equal(one, "xycdefgh", 3); /* Copy cut by count. */
|
---|
| 258 |
|
---|
| 259 | (void) strcpy(one, "abcdefgh");
|
---|
| 260 | (void) strncpy(one, "xyz", 3);/* Copy cut just before NUL. */
|
---|
| 261 | equal(one, "xyzdefgh", 4);
|
---|
| 262 |
|
---|
| 263 | (void) strcpy(one, "abcdefgh");
|
---|
| 264 | (void) strncpy(one, "xyz", 4);/* Copy just includes NUL. */
|
---|
| 265 | equal(one, "xyz", 5);
|
---|
| 266 | equal(one + 4, "efgh", 6); /* Wrote too much? */
|
---|
| 267 |
|
---|
| 268 | (void) strcpy(one, "abcdefgh");
|
---|
| 269 | (void) strncpy(one, "xyz", 5);/* Copy includes padding. */
|
---|
| 270 | equal(one, "xyz", 7);
|
---|
| 271 | equal(one + 4, "", 8);
|
---|
| 272 | equal(one + 5, "fgh", 9);
|
---|
| 273 |
|
---|
| 274 | (void) strcpy(one, "abc");
|
---|
| 275 | (void) strncpy(one, "xyz", 0);/* Zero-length copy. */
|
---|
| 276 | equal(one, "abc", 10);
|
---|
| 277 |
|
---|
| 278 | (void) strncpy(one, "", 2); /* Zero-length source. */
|
---|
| 279 | equal(one, "", 11);
|
---|
| 280 | equal(one + 1, "", 12);
|
---|
| 281 | equal(one + 2, "c", 13);
|
---|
| 282 |
|
---|
| 283 | (void) strcpy(one, "hi there");
|
---|
| 284 | (void) strncpy(two, one, 9);
|
---|
| 285 | equal(two, "hi there", 14); /* Just paranoia. */
|
---|
| 286 | equal(one, "hi there", 15); /* Stomped on source? */
|
---|
| 287 |
|
---|
| 288 | /* Strlen */
|
---|
| 289 | it = "strlen";
|
---|
| 290 | check(strlen("") == 0, 1); /* Empty. */
|
---|
| 291 | check(strlen("a") == 1, 2); /* Single char. */
|
---|
| 292 | check(strlen("abcd") == 4, 3);/* Multiple chars. */
|
---|
| 293 | check(strlen("abcd" + 1) == 3, 4); /* Unaligned test. */
|
---|
| 294 |
|
---|
| 295 | /* Strchr */
|
---|
| 296 | it = "strchr";
|
---|
| 297 | check(strchr("abcd", 'z') == NULL, 1); /* Not found. */
|
---|
| 298 | (void) strcpy(one, "abcd");
|
---|
| 299 | check(strchr(one, 'c') == one + 2, 2); /* Basic test. */
|
---|
| 300 | check(strchr(one, 'd') == one + 3, 3); /* End of string. */
|
---|
| 301 | check(strchr(one, 'a') == one, 4); /* Beginning. */
|
---|
| 302 | check(strchr(one, '\0') == one + 4, 5); /* Finding NUL. */
|
---|
| 303 | (void) strcpy(one, "ababa");
|
---|
| 304 | check(strchr(one, 'b') == one + 1, 6); /* Finding first. */
|
---|
| 305 | (void) strcpy(one, "");
|
---|
| 306 | check(strchr(one, 'b') == NULL, 7); /* Empty string. */
|
---|
| 307 | check(strchr(one, '\0') == one, 8); /* NUL in empty string. */
|
---|
| 308 |
|
---|
| 309 | /* Index - just like strchr */
|
---|
| 310 | it = "index";
|
---|
| 311 | check(index("abcd", 'z') == NULL, 1); /* Not found. */
|
---|
| 312 | (void) strcpy(one, "abcd");
|
---|
| 313 | check(index(one, 'c') == one + 2, 2); /* Basic test. */
|
---|
| 314 | check(index(one, 'd') == one + 3, 3); /* End of string. */
|
---|
| 315 | check(index(one, 'a') == one, 4); /* Beginning. */
|
---|
| 316 | check(index(one, '\0') == one + 4, 5); /* Finding NUL. */
|
---|
| 317 | (void) strcpy(one, "ababa");
|
---|
| 318 | check(index(one, 'b') == one + 1, 6); /* Finding first. */
|
---|
| 319 | (void) strcpy(one, "");
|
---|
| 320 | check(index(one, 'b') == NULL, 7); /* Empty string. */
|
---|
| 321 | check(index(one, '\0') == one, 8); /* NUL in empty string. */
|
---|
| 322 |
|
---|
| 323 | /* Strrchr */
|
---|
| 324 | it = "strrchr";
|
---|
| 325 | check(strrchr("abcd", 'z') == NULL, 1); /* Not found. */
|
---|
| 326 | (void) strcpy(one, "abcd");
|
---|
| 327 | check(strrchr(one, 'c') == one + 2, 2); /* Basic test. */
|
---|
| 328 | check(strrchr(one, 'd') == one + 3, 3); /* End of string. */
|
---|
| 329 | check(strrchr(one, 'a') == one, 4); /* Beginning. */
|
---|
| 330 | check(strrchr(one, '\0') == one + 4, 5); /* Finding NUL. */
|
---|
| 331 | (void) strcpy(one, "ababa");
|
---|
| 332 | check(strrchr(one, 'b') == one + 3, 6); /* Finding last. */
|
---|
| 333 | (void) strcpy(one, "");
|
---|
| 334 | check(strrchr(one, 'b') == NULL, 7); /* Empty string. */
|
---|
| 335 | check(strrchr(one, '\0') == one, 8); /* NUL in empty string. */
|
---|
| 336 |
|
---|
| 337 | /* Rindex - just like strrchr */
|
---|
| 338 | it = "rindex";
|
---|
| 339 | check(rindex("abcd", 'z') == NULL, 1); /* Not found. */
|
---|
| 340 | (void) strcpy(one, "abcd");
|
---|
| 341 | check(rindex(one, 'c') == one + 2, 2); /* Basic test. */
|
---|
| 342 | check(rindex(one, 'd') == one + 3, 3); /* End of string. */
|
---|
| 343 | check(rindex(one, 'a') == one, 4); /* Beginning. */
|
---|
| 344 | check(rindex(one, '\0') == one + 4, 5); /* Finding NUL. */
|
---|
| 345 | (void) strcpy(one, "ababa");
|
---|
| 346 | check(rindex(one, 'b') == one + 3, 6); /* Finding last. */
|
---|
| 347 | (void) strcpy(one, "");
|
---|
| 348 | check(rindex(one, 'b') == NULL, 7); /* Empty string. */
|
---|
| 349 | check(rindex(one, '\0') == one, 8); /* NUL in empty string. */
|
---|
| 350 | }
|
---|
| 351 |
|
---|
| 352 | void second()
|
---|
| 353 | {
|
---|
| 354 | /* Strpbrk - somewhat like strchr */
|
---|
| 355 | it = "strpbrk";
|
---|
| 356 | check(strpbrk("abcd", "z") == NULL, 1); /* Not found. */
|
---|
| 357 | (void) strcpy(one, "abcd");
|
---|
| 358 | check(strpbrk(one, "c") == one + 2, 2); /* Basic test. */
|
---|
| 359 | check(strpbrk(one, "d") == one + 3, 3); /* End of string. */
|
---|
| 360 | check(strpbrk(one, "a") == one, 4); /* Beginning. */
|
---|
| 361 | check(strpbrk(one, "") == NULL, 5); /* Empty search list. */
|
---|
| 362 | check(strpbrk(one, "cb") == one + 1, 6); /* Multiple search. */
|
---|
| 363 | (void) strcpy(one, "abcabdea");
|
---|
| 364 | check(strpbrk(one, "b") == one + 1, 7); /* Finding first. */
|
---|
| 365 | check(strpbrk(one, "cb") == one + 1, 8); /* With multiple search. */
|
---|
| 366 | check(strpbrk(one, "db") == one + 1, 9); /* Another variant. */
|
---|
| 367 | (void) strcpy(one, "");
|
---|
| 368 | check(strpbrk(one, "bc") == NULL, 10); /* Empty string. */
|
---|
| 369 | check(strpbrk(one, "") == NULL, 11); /* Both strings empty. */
|
---|
| 370 |
|
---|
| 371 | /* Strstr - somewhat like strchr */
|
---|
| 372 | it = "strstr";
|
---|
| 373 | check(strstr("abcd", "z") == NULL, 1); /* Not found. */
|
---|
| 374 | check(strstr("abcd", "abx") == NULL, 2); /* Dead end. */
|
---|
| 375 | (void) strcpy(one, "abcd");
|
---|
| 376 | check(strstr(one, "c") == one + 2, 3); /* Basic test. */
|
---|
| 377 | check(strstr(one, "bc") == one + 1, 4); /* Multichar. */
|
---|
| 378 | check(strstr(one, "d") == one + 3, 5); /* End of string. */
|
---|
| 379 | check(strstr(one, "cd") == one + 2, 6); /* Tail of string. */
|
---|
| 380 | check(strstr(one, "abc") == one, 7); /* Beginning. */
|
---|
| 381 | check(strstr(one, "abcd") == one, 8); /* Exact match. */
|
---|
| 382 | check(strstr(one, "abcde") == NULL, 9); /* Too long. */
|
---|
| 383 | check(strstr(one, "de") == NULL, 10); /* Past end. */
|
---|
| 384 | #ifdef NOT_ANSI
|
---|
| 385 | check(strstr(one, "") == one + 4, 11); /* Finding empty. */
|
---|
| 386 | #else
|
---|
| 387 | check(strstr(one, "") == one, 11); /* Finding empty. */
|
---|
| 388 | #endif
|
---|
| 389 | (void) strcpy(one, "ababa");
|
---|
| 390 | check(strstr(one, "ba") == one + 1, 12); /* Finding first. */
|
---|
| 391 | (void) strcpy(one, "");
|
---|
| 392 | check(strstr(one, "b") == NULL, 13); /* Empty string. */
|
---|
| 393 | check(strstr(one, "") == one, 14); /* Empty in empty string. */
|
---|
| 394 | (void) strcpy(one, "bcbca");
|
---|
| 395 | check(strstr(one, "bca") == one + 2, 15); /* False start. */
|
---|
| 396 | (void) strcpy(one, "bbbcabbca");
|
---|
| 397 | check(strstr(one, "bbca") == one + 1, 16); /* With overlap. */
|
---|
| 398 |
|
---|
| 399 | /* Strspn */
|
---|
| 400 | it = "strspn";
|
---|
| 401 | check(strspn("abcba", "abc") == 5, 1); /* Whole string. */
|
---|
| 402 | check(strspn("abcba", "ab") == 2, 2); /* Partial. */
|
---|
| 403 | check(strspn("abc", "qx") == 0, 3); /* None. */
|
---|
| 404 | check(strspn("", "ab") == 0, 4); /* Null string. */
|
---|
| 405 | check(strspn("abc", "") == 0, 5); /* Null search list. */
|
---|
| 406 |
|
---|
| 407 | /* Strcspn */
|
---|
| 408 | it = "strcspn";
|
---|
| 409 | check(strcspn("abcba", "qx") == 5, 1); /* Whole string. */
|
---|
| 410 | check(strcspn("abcba", "cx") == 2, 2); /* Partial. */
|
---|
| 411 | check(strcspn("abc", "abc") == 0, 3); /* None. */
|
---|
| 412 | check(strcspn("", "ab") == 0, 4); /* Null string. */
|
---|
| 413 | check(strcspn("abc", "") == 3, 5); /* Null search list. */
|
---|
| 414 |
|
---|
| 415 | /* Strtok - the hard one */
|
---|
| 416 | it = "strtok";
|
---|
| 417 | (void) strcpy(one, "first, second, third");
|
---|
| 418 | equal(strtok(one, ", "), "first", 1); /* Basic test. */
|
---|
| 419 | equal(one, "first", 2);
|
---|
| 420 | equal(strtok((char *) NULL, ", "), "second", 3);
|
---|
| 421 | equal(strtok((char *) NULL, ", "), "third", 4);
|
---|
| 422 | check(strtok((char *) NULL, ", ") == NULL, 5);
|
---|
| 423 | (void) strcpy(one, ", first, ");
|
---|
| 424 | equal(strtok(one, ", "), "first", 6); /* Extra delims, 1 tok. */
|
---|
| 425 | check(strtok((char *) NULL, ", ") == NULL, 7);
|
---|
| 426 | (void) strcpy(one, "1a, 1b; 2a, 2b");
|
---|
| 427 | equal(strtok(one, ", "), "1a", 8); /* Changing delim lists. */
|
---|
| 428 | equal(strtok((char *) NULL, "; "), "1b", 9);
|
---|
| 429 | equal(strtok((char *) NULL, ", "), "2a", 10);
|
---|
| 430 | (void) strcpy(two, "x-y");
|
---|
| 431 | equal(strtok(two, "-"), "x", 11); /* New string before done. */
|
---|
| 432 | equal(strtok((char *) NULL, "-"), "y", 12);
|
---|
| 433 | check(strtok((char *) NULL, "-") == NULL, 13);
|
---|
| 434 | (void) strcpy(one, "a,b, c,, ,d");
|
---|
| 435 | equal(strtok(one, ", "), "a", 14); /* Different separators. */
|
---|
| 436 | equal(strtok((char *) NULL, ", "), "b", 15);
|
---|
| 437 | equal(strtok((char *) NULL, " ,"), "c", 16); /* Permute list too. */
|
---|
| 438 | equal(strtok((char *) NULL, " ,"), "d", 17);
|
---|
| 439 | check(strtok((char *) NULL, ", ") == NULL, 18);
|
---|
| 440 | check(strtok((char *) NULL, ", ") == NULL, 19); /* Persistence. */
|
---|
| 441 | (void) strcpy(one, ", ");
|
---|
| 442 | check(strtok(one, ", ") == NULL, 20); /* No tokens. */
|
---|
| 443 | (void) strcpy(one, "");
|
---|
| 444 | check(strtok(one, ", ") == NULL, 21); /* Empty string. */
|
---|
| 445 | (void) strcpy(one, "abc");
|
---|
| 446 | equal(strtok(one, ", "), "abc", 22); /* No delimiters. */
|
---|
| 447 | check(strtok((char *) NULL, ", ") == NULL, 23);
|
---|
| 448 | (void) strcpy(one, "abc");
|
---|
| 449 | equal(strtok(one, ""), "abc", 24); /* Empty delimiter list. */
|
---|
| 450 | check(strtok((char *) NULL, "") == NULL, 25);
|
---|
| 451 | (void) strcpy(one, "abcdefgh");
|
---|
| 452 | (void) strcpy(one, "a,b,c");
|
---|
| 453 | equal(strtok(one, ","), "a", 26); /* Basics again... */
|
---|
| 454 | equal(strtok((char *) NULL, ","), "b", 27);
|
---|
| 455 | equal(strtok((char *) NULL, ","), "c", 28);
|
---|
| 456 | check(strtok((char *) NULL, ",") == NULL, 29);
|
---|
| 457 | equal(one + 6, "gh", 30); /* Stomped past end? */
|
---|
| 458 | equal(one, "a", 31); /* Stomped old tokens? */
|
---|
| 459 | equal(one + 2, "b", 32);
|
---|
| 460 | equal(one + 4, "c", 33);
|
---|
| 461 |
|
---|
| 462 | /* Memcmp */
|
---|
| 463 | it = "memcmp";
|
---|
| 464 | check(memcmp("a", "a", 1) == 0, 1); /* Identity. */
|
---|
| 465 | check(memcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
|
---|
| 466 | check(memcmp("abcd", "abce", 4) < 0, 3); /* Honestly unequal. */
|
---|
| 467 | check(memcmp("abce", "abcd", 4) > 0, 4);
|
---|
| 468 | check(memcmp("alph", "beta", 4) < 0, 5);
|
---|
| 469 |
|
---|
| 470 | #ifdef NOT_ANSI
|
---|
| 471 | if (charsigned)
|
---|
| 472 | check(memcmp("a\203", "a\003", 2) < 0, 6);
|
---|
| 473 | else
|
---|
| 474 | check(memcmp("a\203", "a\003", 2) > 0, 6);
|
---|
| 475 | #else
|
---|
| 476 | check(memcmp("a\203", "a\003", 2) > 0, 6);
|
---|
| 477 | #endif
|
---|
| 478 |
|
---|
| 479 | check(memcmp("abce", "abcd", 3) == 0, 7); /* Count limited. */
|
---|
| 480 | check(memcmp("abc", "def", 0) == 0, 8); /* Zero count. */
|
---|
| 481 |
|
---|
| 482 | check(memcmp("a" + 1, "a" + 1, 1) == 0, 9); /* Unaligned tests. */
|
---|
| 483 | check(memcmp("abc" + 1, "bc", 2) == 0, 10);
|
---|
| 484 | check(memcmp("bc", "abc" + 1, 2) == 0, 11);
|
---|
| 485 | check(memcmp("abcd" + 1, "abce" + 1, 3) < 0, 12);
|
---|
| 486 | check(memcmp("abce" + 1, "abcd" + 1, 3) > 0, 13);
|
---|
| 487 | /*
|
---|
| 488 | check(memcmp("a\203" + 1, "a\003" + 1, 1) > 0, 14);
|
---|
| 489 | */
|
---|
| 490 | check(memcmp("abcde" + 1, "abcdf" + 1, 3) == 0, 15);
|
---|
| 491 |
|
---|
| 492 | /* Memchr */
|
---|
| 493 | it = "memchr";
|
---|
| 494 | check(memchr("abcd", 'z', 4) == NULL, 1); /* Not found. */
|
---|
| 495 | (void) strcpy(one, "abcd");
|
---|
| 496 | check( (char *)memchr(one, 'c', 4) == one + 2, 2); /* Basic test. */
|
---|
| 497 | check( (char *)memchr(one, 'd', 4) == one + 3, 3); /* End of string. */
|
---|
| 498 | check( (char *)memchr(one, 'a', 4) == one, 4); /* Beginning. */
|
---|
| 499 | check( (char *)memchr(one, '\0', 5) == one + 4, 5); /* Finding NUL. */
|
---|
| 500 | (void) strcpy(one, "ababa");
|
---|
| 501 | check( (char *)memchr(one, 'b', 5) == one + 1, 6); /* Finding first. */
|
---|
| 502 | check( (char *)memchr(one, 'b', 0) == NULL, 7); /* Zero count. */
|
---|
| 503 | check( (char *)memchr(one, 'a', 1) == one, 8); /* Singleton case. */
|
---|
| 504 | (void) strcpy(one, "a\203b");
|
---|
| 505 | check( (char *)memchr(one, 0203, 3) == one + 1, 9); /* Unsignedness. */
|
---|
| 506 |
|
---|
| 507 | /* Memcpy
|
---|
| 508 | * Note that X3J11 says memcpy may fail on overlap. */
|
---|
| 509 | it = "memcpy";
|
---|
| 510 | check( (char *)memcpy(one, "abc", 4) == one, 1); /* Returned value. */
|
---|
| 511 | equal(one, "abc", 2); /* Did the copy go right? */
|
---|
| 512 |
|
---|
| 513 | (void) strcpy(one, "abcdefgh");
|
---|
| 514 | (void) memcpy(one + 1, "xyz", 2);
|
---|
| 515 | equal(one, "axydefgh", 3); /* Basic test. */
|
---|
| 516 |
|
---|
| 517 | (void) strcpy(one, "abc");
|
---|
| 518 | (void) memcpy(one, "xyz", 0);
|
---|
| 519 | equal(one, "abc", 4); /* Zero-length copy. */
|
---|
| 520 |
|
---|
| 521 | (void) strcpy(one, "hi there");
|
---|
| 522 | (void) strcpy(two, "foo");
|
---|
| 523 | (void) memcpy(two, one, 9);
|
---|
| 524 | equal(two, "hi there", 5); /* Just paranoia. */
|
---|
| 525 | equal(one, "hi there", 6); /* Stomped on source? */
|
---|
| 526 |
|
---|
| 527 | (void) strcpy(one, "abcde"); /* Unaligned tests. */
|
---|
| 528 | (void) memcpy(one + 1, "\0\0\0\0\0", 1);
|
---|
| 529 | equal(one, "a", 7);
|
---|
| 530 | equal(one + 2, "cde", 8);
|
---|
| 531 | (void) memcpy(one + 1, "xyz" + 1, 2);
|
---|
| 532 | equal(one, "ayzde", 9);
|
---|
| 533 | (void) memcpy(one + 1, "xyz" + 1, 3);
|
---|
| 534 | equal(one, "ayz", 10);
|
---|
| 535 |
|
---|
| 536 | /* Memmove
|
---|
| 537 | * Note that X3J11 says memmove must work regardless of overlap. */
|
---|
| 538 | it = "memmove";
|
---|
| 539 | check( (char *)memmove(one, "abc", 4) == one, 1); /* Returned value. */
|
---|
| 540 | equal(one, "abc", 2); /* Did the copy go right? */
|
---|
| 541 |
|
---|
| 542 | (void) strcpy(one, "abcdefgh");
|
---|
| 543 | (void) memmove(one + 1, "xyz", 2);
|
---|
| 544 | equal(one, "axydefgh", 3); /* Basic test. */
|
---|
| 545 |
|
---|
| 546 | (void) strcpy(one, "abc");
|
---|
| 547 | (void) memmove(one, "xyz", 0);
|
---|
| 548 | equal(one, "abc", 4); /* Zero-length copy. */
|
---|
| 549 |
|
---|
| 550 | (void) strcpy(one, "hi there");
|
---|
| 551 | (void) strcpy(two, "foo");
|
---|
| 552 | (void) memmove(two, one, 9);
|
---|
| 553 | equal(two, "hi there", 5); /* Just paranoia. */
|
---|
| 554 | equal(one, "hi there", 6); /* Stomped on source? */
|
---|
| 555 |
|
---|
| 556 | (void) strcpy(one, "abcdefgh");
|
---|
| 557 | (void) memmove(one + 1, one, 9);
|
---|
| 558 | equal(one, "aabcdefgh", 7); /* Overlap, right-to-left. */
|
---|
| 559 |
|
---|
| 560 | (void) strcpy(one, "abcdefgh");
|
---|
| 561 | (void) memmove(one + 1, one + 2, 7);
|
---|
| 562 | equal(one, "acdefgh", 8); /* Overlap, left-to-right. */
|
---|
| 563 |
|
---|
| 564 | (void) strcpy(one, "abcdefgh");
|
---|
| 565 | (void) memmove(one, one, 9);
|
---|
| 566 | equal(one, "abcdefgh", 9); /* 100% overlap. */
|
---|
| 567 |
|
---|
| 568 | (void) strcpy(one, "abcde"); /* Unaligned tests. */
|
---|
| 569 | (void) memmove(one + 1, "\0\0\0\0\0", 1);
|
---|
| 570 | equal(one, "a", 10);
|
---|
| 571 | equal(one + 2, "cde", 11);
|
---|
| 572 | (void) memmove(one + 1, "xyz" + 1, 2);
|
---|
| 573 | equal(one, "ayzde", 12);
|
---|
| 574 | (void) memmove(one + 1, "xyz" + 1, 3);
|
---|
| 575 | equal(one, "ayz", 13);
|
---|
| 576 | (void) strcpy(one, "abcdefgh");
|
---|
| 577 | (void) memmove(one + 2, one + 1, 8);
|
---|
| 578 | equal(one, "abbcdefgh", 14);
|
---|
| 579 |
|
---|
| 580 | /* Memccpy - first test like memcpy, then the search part
|
---|
| 581 | * The SVID, the only place where memccpy is mentioned, says overlap
|
---|
| 582 | * might fail, so we don't try it. Besides, it's hard to see the
|
---|
| 583 | * rationale for a non-left-to-right memccpy. */
|
---|
| 584 | it = "memccpy";
|
---|
| 585 | check(memccpy(one, "abc", 'q', 4) == NULL, 1); /* Returned value. */
|
---|
| 586 | equal(one, "abc", 2); /* Did the copy go right? */
|
---|
| 587 |
|
---|
| 588 | (void) strcpy(one, "abcdefgh");
|
---|
| 589 | (void) memccpy(one + 1, "xyz", 'q', 2);
|
---|
| 590 | equal(one, "axydefgh", 3); /* Basic test. */
|
---|
| 591 |
|
---|
| 592 | (void) strcpy(one, "abc");
|
---|
| 593 | (void) memccpy(one, "xyz", 'q', 0);
|
---|
| 594 | equal(one, "abc", 4); /* Zero-length copy. */
|
---|
| 595 |
|
---|
| 596 | (void) strcpy(one, "hi there");
|
---|
| 597 | (void) strcpy(two, "foo");
|
---|
| 598 | (void) memccpy(two, one, 'q', 9);
|
---|
| 599 | equal(two, "hi there", 5); /* Just paranoia. */
|
---|
| 600 | equal(one, "hi there", 6); /* Stomped on source? */
|
---|
| 601 |
|
---|
| 602 | (void) strcpy(one, "abcdefgh");
|
---|
| 603 | (void) strcpy(two, "horsefeathers");
|
---|
| 604 | check( (char *)memccpy(two, one, 'f', 9) == two + 6, 7);/* Returned value. */
|
---|
| 605 | equal(one, "abcdefgh", 8); /* Source intact? */
|
---|
| 606 | equal(two, "abcdefeathers", 9); /* Copy correct? */
|
---|
| 607 |
|
---|
| 608 | (void) strcpy(one, "abcd");
|
---|
| 609 | (void) strcpy(two, "bumblebee");
|
---|
| 610 | check((char *)memccpy(two, one, 'a', 4) == two + 1, 10); /* First char. */
|
---|
| 611 | equal(two, "aumblebee", 11);
|
---|
| 612 | check((char *)memccpy(two, one, 'd', 4) == two + 4, 12); /* Last char. */
|
---|
| 613 | equal(two, "abcdlebee", 13);
|
---|
| 614 | (void) strcpy(one, "xyz");
|
---|
| 615 | check((char *)memccpy(two, one, 'x', 1) == two + 1, 14); /* Singleton. */
|
---|
| 616 | equal(two, "xbcdlebee", 15);
|
---|
| 617 |
|
---|
| 618 | /* Memset */
|
---|
| 619 | it = "memset";
|
---|
| 620 | (void) strcpy(one, "abcdefgh");
|
---|
| 621 | check( (char *) memset(one + 1, 'x', 3) == one + 1, 1); /* Return value. */
|
---|
| 622 | equal(one, "axxxefgh", 2); /* Basic test. */
|
---|
| 623 |
|
---|
| 624 | (void) memset(one + 2, 'y', 0);
|
---|
| 625 | equal(one, "axxxefgh", 3); /* Zero-length set. */
|
---|
| 626 |
|
---|
| 627 | (void) memset(one + 5, 0, 1);
|
---|
| 628 | equal(one, "axxxe", 4); /* Zero fill. */
|
---|
| 629 | equal(one + 6, "gh", 5); /* And the leftover. */
|
---|
| 630 |
|
---|
| 631 | (void) memset(one + 2, 010045, 1);
|
---|
| 632 | equal(one, "ax\045xe", 6); /* Unsigned char convert. */
|
---|
| 633 |
|
---|
| 634 | /* Bcopy - much like memcpy
|
---|
| 635 | * Berklix manual is silent about overlap, so don't test it. */
|
---|
| 636 | it = "bcopy";
|
---|
| 637 | (void) bcopy("abc", one, 4);
|
---|
| 638 | equal(one, "abc", 1); /* Simple copy. */
|
---|
| 639 |
|
---|
| 640 | (void) strcpy(one, "abcdefgh");
|
---|
| 641 | (void) bcopy("xyz", one + 1, 2);
|
---|
| 642 | equal(one, "axydefgh", 2); /* Basic test. */
|
---|
| 643 |
|
---|
| 644 | (void) strcpy(one, "abc");
|
---|
| 645 | (void) bcopy("xyz", one, 0);
|
---|
| 646 | equal(one, "abc", 3); /* Zero-length copy. */
|
---|
| 647 |
|
---|
| 648 | (void) strcpy(one, "hi there");
|
---|
| 649 | (void) strcpy(two, "foo");
|
---|
| 650 | (void) bcopy(one, two, 9);
|
---|
| 651 | equal(two, "hi there", 4); /* Just paranoia. */
|
---|
| 652 | equal(one, "hi there", 5); /* Stomped on source? */
|
---|
| 653 |
|
---|
| 654 | /* Bzero */
|
---|
| 655 | it = "bzero";
|
---|
| 656 | (void) strcpy(one, "abcdef");
|
---|
| 657 | bzero(one + 2, 2);
|
---|
| 658 | equal(one, "ab", 1); /* Basic test. */
|
---|
| 659 | equal(one + 3, "", 2);
|
---|
| 660 | equal(one + 4, "ef", 3);
|
---|
| 661 |
|
---|
| 662 | (void) strcpy(one, "abcdef");
|
---|
| 663 | bzero(one + 2, 0);
|
---|
| 664 | equal(one, "abcdef", 4); /* Zero-length copy. */
|
---|
| 665 |
|
---|
| 666 | /* Bcmp - somewhat like memcmp */
|
---|
| 667 | it = "bcmp";
|
---|
| 668 | check(bcmp("a", "a", 1) == 0, 1); /* Identity. */
|
---|
| 669 | check(bcmp("abc", "abc", 3) == 0, 2); /* Multicharacter. */
|
---|
| 670 | check(bcmp("abcd", "abce", 4) != 0, 3); /* Honestly unequal. */
|
---|
| 671 | check(bcmp("abce", "abcd", 4) != 0, 4);
|
---|
| 672 | check(bcmp("alph", "beta", 4) != 0, 5);
|
---|
| 673 | check(bcmp("abce", "abcd", 3) == 0, 6); /* Count limited. */
|
---|
| 674 | check(bcmp("abc", "def", 0) == 0, 8); /* Zero count. */
|
---|
| 675 |
|
---|
| 676 | #ifdef ERR
|
---|
| 677 | /* Strerror - VERY system-dependent */
|
---|
| 678 | it = "strerror";
|
---|
| 679 | f = open("/", O_WRONLY); /* Should always fail. */
|
---|
| 680 | check(f < 0 && errno > 0 && errno < sys_nerr, 1);
|
---|
| 681 | equal(strerror(errno), sys_errlist[errno], 2);
|
---|
| 682 | #ifdef UNIXERR
|
---|
| 683 | equal(strerror(errno), "Is a directory", 3);
|
---|
| 684 | #endif
|
---|
| 685 | #ifdef BERKERR
|
---|
| 686 | equal(strerror(errno), "Permission denied", 3);
|
---|
| 687 | #endif
|
---|
| 688 | #endif
|
---|
| 689 | }
|
---|
| 690 |
|
---|
| 691 | void quit()
|
---|
| 692 | {
|
---|
| 693 |
|
---|
| 694 | chdir("..");
|
---|
| 695 | system("rm -rf DIR*");
|
---|
| 696 |
|
---|
| 697 | if (errct == 0) {
|
---|
| 698 | printf("ok\n");
|
---|
| 699 | exit(0);
|
---|
| 700 | } else {
|
---|
| 701 | printf("%d errors\n", errct);
|
---|
| 702 | exit(1);
|
---|
| 703 | }
|
---|
| 704 | }
|
---|