string_test.cpp revision 13476deec46d7ba101c1f76b8ddcaab9d0b96b84
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <gtest/gtest.h> 18 19#include <errno.h> 20#include <math.h> 21#include <string.h> 22 23#define KB 1024 24#define SMALL 1*KB 25#define LARGE 64*KB 26 27static int signum(int i) { 28 if (i < 0) { 29 return -1; 30 } else if (i > 0) { 31 return 1; 32 } 33 return 0; 34} 35 36TEST(string, strerror) { 37 // Valid. 38 ASSERT_STREQ("Success", strerror(0)); 39 ASSERT_STREQ("Operation not permitted", strerror(1)); 40 41 // Invalid. 42 ASSERT_STREQ("Unknown error -1", strerror(-1)); 43 ASSERT_STREQ("Unknown error 1234", strerror(1234)); 44} 45 46#if __BIONIC__ // glibc's strerror isn't thread safe, only its strsignal. 47 48static void* ConcurrentStrErrorFn(void*) { 49 bool equal = (strcmp("Unknown error 2002", strerror(2002)) == 0); 50 return reinterpret_cast<void*>(equal); 51} 52 53TEST(string, strerror_concurrent) { 54 const char* strerror1001 = strerror(1001); 55 ASSERT_STREQ("Unknown error 1001", strerror1001); 56 57 pthread_t t; 58 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrErrorFn, NULL)); 59 void* result; 60 ASSERT_EQ(0, pthread_join(t, &result)); 61 ASSERT_TRUE(static_cast<bool>(result)); 62 63 ASSERT_STREQ("Unknown error 1001", strerror1001); 64} 65 66#endif 67 68#if __BIONIC__ // glibc's strerror_r doesn't even have the same signature as the POSIX one. 69TEST(string, strerror_r) { 70 char buf[256]; 71 72 // Valid. 73 ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf))); 74 ASSERT_STREQ("Success", buf); 75 ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf))); 76 ASSERT_STREQ("Operation not permitted", buf); 77 78 // Invalid. 79 ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf))); 80 ASSERT_STREQ("Unknown error -1", buf); 81 ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf))); 82 ASSERT_STREQ("Unknown error 1234", buf); 83 84 // Buffer too small. 85 ASSERT_EQ(-1, strerror_r(0, buf, 2)); 86 ASSERT_EQ(ERANGE, errno); 87} 88#endif 89 90TEST(string, strsignal) { 91 // A regular signal. 92 ASSERT_STREQ("Hangup", strsignal(1)); 93 94 // A real-time signal. 95#ifdef __GLIBC__ // glibc reserves real-time signals for internal use, and doesn't count those. 96 ASSERT_STREQ("Real-time signal 14", strsignal(48)); 97#else 98 ASSERT_STREQ("Real-time signal 16", strsignal(48)); 99#endif 100 101 // Errors. 102 ASSERT_STREQ("Unknown signal -1", strsignal(-1)); // Too small. 103 ASSERT_STREQ("Unknown signal 0", strsignal(0)); // Still too small. 104 ASSERT_STREQ("Unknown signal 1234", strsignal(1234)); // Too large. 105} 106 107static void* ConcurrentStrSignalFn(void*) { 108 bool equal = (strcmp("Unknown signal 2002", strsignal(2002)) == 0); 109 return reinterpret_cast<void*>(equal); 110} 111 112TEST(string, strsignal_concurrent) { 113 const char* strsignal1001 = strsignal(1001); 114 ASSERT_STREQ("Unknown signal 1001", strsignal1001); 115 116 pthread_t t; 117 ASSERT_EQ(0, pthread_create(&t, NULL, ConcurrentStrSignalFn, NULL)); 118 void* result; 119 ASSERT_EQ(0, pthread_join(t, &result)); 120 ASSERT_TRUE(static_cast<bool>(result)); 121 122 ASSERT_STREQ("Unknown signal 1001", strsignal1001); 123} 124 125// TODO: where did these numbers come from? 126#define POS_ITER 10 127#define ITER 500 128 129// For every length we want to test, vary and change alignment 130// of allocated memory, fill it with some values, calculate 131// expected result and then run function and compare what we got. 132// These tests contributed by Intel Corporation. 133// TODO: make these tests more intention-revealing and less random. 134struct StringTestState { 135 StringTestState(size_t MAX_LEN) : MAX_LEN(MAX_LEN) { 136 int max_alignment = 64; 137 138 // TODO: fix the tests to not sometimes use twice their specified "MAX_LEN". 139 glob_ptr = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment)); 140 glob_ptr1 = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment)); 141 glob_ptr2 = reinterpret_cast<char*>(valloc(2 * MAX_LEN + max_alignment)); 142 143 InitLenArray(); 144 145 srandom(1234); 146 } 147 148 ~StringTestState() { 149 free(glob_ptr); 150 free(glob_ptr1); 151 free(glob_ptr2); 152 } 153 154 void NewIteration() { 155 int alignments[] = { 24, 32, 16, 48, 1, 2, 3, 0, 5, 11 }; 156 int usable_alignments = 10; 157 int align1 = alignments[random() % (usable_alignments - 1)]; 158 int align2 = alignments[random() % (usable_alignments - 1)]; 159 160 ptr = glob_ptr + align1; 161 ptr1 = glob_ptr1 + align1; 162 ptr2 = glob_ptr2 + align2; 163 } 164 165 const size_t MAX_LEN; 166 char *ptr, *ptr1, *ptr2; 167 size_t n; 168 int len[ITER + 1]; 169 170 private: 171 char *glob_ptr, *glob_ptr1, *glob_ptr2; 172 173 // Calculate input lengths and fill state.len with them. 174 // Test small lengths with more density than big ones. Manually push 175 // smallest (0) and biggest (MAX_LEN) lengths. Avoid repeats. 176 // Return number of lengths to test. 177 void InitLenArray() { 178 n = 0; 179 len[n++] = 0; 180 for (size_t i = 1; i < ITER; ++i) { 181 int l = (int) exp(log((double) MAX_LEN) * i / ITER); 182 if (l != len[n - 1]) { 183 len[n++] = l; 184 } 185 } 186 len[n++] = MAX_LEN; 187 } 188}; 189 190TEST(string, strcat) { 191 StringTestState state(SMALL); 192 for (size_t i = 1; i < state.n; i++) { 193 for (size_t j = 0; j < POS_ITER; j++) { 194 state.NewIteration(); 195 196 memset(state.ptr2, '\2', state.MAX_LEN); 197 state.ptr2[state.MAX_LEN - 1] = '\0'; 198 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 199 200 memset(state.ptr1, random() & 255, state.len[i]); 201 state.ptr1[random() % state.len[i]] = '\0'; 202 state.ptr1[state.len[i] - 1] = '\0'; 203 204 strcpy(state.ptr + state.MAX_LEN - 1, state.ptr1); 205 206 EXPECT_TRUE(strcat(state.ptr2, state.ptr1) == state.ptr2); 207 EXPECT_TRUE(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN) == 0); 208 } 209 } 210} 211 212// one byte target with "\0" source 213TEST(string, strcpy2) { 214 char buf[1]; 215 char* orig = strdup(""); 216 strcpy(buf, orig); 217 ASSERT_EQ('\0', buf[0]); 218 free(orig); 219} 220 221// multibyte target where we under fill target 222TEST(string, strcpy3) { 223 char buf[10]; 224 char* orig = strdup("12345"); 225 memset(buf, 'A', sizeof(buf)); 226 strcpy(buf, orig); 227 ASSERT_EQ('1', buf[0]); 228 ASSERT_EQ('2', buf[1]); 229 ASSERT_EQ('3', buf[2]); 230 ASSERT_EQ('4', buf[3]); 231 ASSERT_EQ('5', buf[4]); 232 ASSERT_EQ('\0', buf[5]); 233 ASSERT_EQ('A', buf[6]); 234 ASSERT_EQ('A', buf[7]); 235 ASSERT_EQ('A', buf[8]); 236 ASSERT_EQ('A', buf[9]); 237 free(orig); 238} 239 240// multibyte target where we fill target exactly 241TEST(string, strcpy4) { 242 char buf[10]; 243 char* orig = strdup("123456789"); 244 memset(buf, 'A', sizeof(buf)); 245 strcpy(buf, orig); 246 ASSERT_EQ('1', buf[0]); 247 ASSERT_EQ('2', buf[1]); 248 ASSERT_EQ('3', buf[2]); 249 ASSERT_EQ('4', buf[3]); 250 ASSERT_EQ('5', buf[4]); 251 ASSERT_EQ('6', buf[5]); 252 ASSERT_EQ('7', buf[6]); 253 ASSERT_EQ('8', buf[7]); 254 ASSERT_EQ('9', buf[8]); 255 ASSERT_EQ('\0', buf[9]); 256 free(orig); 257} 258 259TEST(string, strcat2) { 260 char buf[10]; 261 memset(buf, 'A', sizeof(buf)); 262 buf[0] = 'a'; 263 buf[1] = '\0'; 264 char* res = strcat(buf, "01234"); 265 ASSERT_EQ(buf, res); 266 ASSERT_EQ('a', buf[0]); 267 ASSERT_EQ('0', buf[1]); 268 ASSERT_EQ('1', buf[2]); 269 ASSERT_EQ('2', buf[3]); 270 ASSERT_EQ('3', buf[4]); 271 ASSERT_EQ('4', buf[5]); 272 ASSERT_EQ('\0', buf[6]); 273 ASSERT_EQ('A', buf[7]); 274 ASSERT_EQ('A', buf[8]); 275 ASSERT_EQ('A', buf[9]); 276} 277 278TEST(string, strcat3) { 279 char buf[10]; 280 memset(buf, 'A', sizeof(buf)); 281 buf[0] = 'a'; 282 buf[1] = '\0'; 283 char* res = strcat(buf, "01234567"); 284 ASSERT_EQ(buf, res); 285 ASSERT_EQ('a', buf[0]); 286 ASSERT_EQ('0', buf[1]); 287 ASSERT_EQ('1', buf[2]); 288 ASSERT_EQ('2', buf[3]); 289 ASSERT_EQ('3', buf[4]); 290 ASSERT_EQ('4', buf[5]); 291 ASSERT_EQ('5', buf[6]); 292 ASSERT_EQ('6', buf[7]); 293 ASSERT_EQ('7', buf[8]); 294 ASSERT_EQ('\0', buf[9]); 295} 296 297TEST(string, strncat2) { 298 char buf[10]; 299 memset(buf, 'A', sizeof(buf)); 300 buf[0] = 'a'; 301 buf[1] = '\0'; 302 char* res = strncat(buf, "01234", sizeof(buf) - strlen(buf) - 1); 303 ASSERT_EQ(buf, res); 304 ASSERT_EQ('a', buf[0]); 305 ASSERT_EQ('0', buf[1]); 306 ASSERT_EQ('1', buf[2]); 307 ASSERT_EQ('2', buf[3]); 308 ASSERT_EQ('3', buf[4]); 309 ASSERT_EQ('4', buf[5]); 310 ASSERT_EQ('\0', buf[6]); 311 ASSERT_EQ('A', buf[7]); 312 ASSERT_EQ('A', buf[8]); 313 ASSERT_EQ('A', buf[9]); 314} 315 316TEST(string, strncat3) { 317 char buf[10]; 318 memset(buf, 'A', sizeof(buf)); 319 buf[0] = 'a'; 320 buf[1] = '\0'; 321 char* res = strncat(buf, "0123456789", 5); 322 ASSERT_EQ(buf, res); 323 ASSERT_EQ('a', buf[0]); 324 ASSERT_EQ('0', buf[1]); 325 ASSERT_EQ('1', buf[2]); 326 ASSERT_EQ('2', buf[3]); 327 ASSERT_EQ('3', buf[4]); 328 ASSERT_EQ('4', buf[5]); 329 ASSERT_EQ('\0', buf[6]); 330 ASSERT_EQ('A', buf[7]); 331 ASSERT_EQ('A', buf[8]); 332 ASSERT_EQ('A', buf[9]); 333} 334 335TEST(string, strncat4) { 336 char buf[10]; 337 memset(buf, 'A', sizeof(buf)); 338 buf[0] = 'a'; 339 buf[1] = '\0'; 340 char* res = strncat(buf, "01234567", 8); 341 ASSERT_EQ(buf, res); 342 ASSERT_EQ('a', buf[0]); 343 ASSERT_EQ('0', buf[1]); 344 ASSERT_EQ('1', buf[2]); 345 ASSERT_EQ('2', buf[3]); 346 ASSERT_EQ('3', buf[4]); 347 ASSERT_EQ('4', buf[5]); 348 ASSERT_EQ('5', buf[6]); 349 ASSERT_EQ('6', buf[7]); 350 ASSERT_EQ('7', buf[8]); 351 ASSERT_EQ('\0', buf[9]); 352} 353 354TEST(string, strncat5) { 355 char buf[10]; 356 memset(buf, 'A', sizeof(buf)); 357 buf[0] = 'a'; 358 buf[1] = '\0'; 359 char* res = strncat(buf, "01234567", 9); 360 ASSERT_EQ(buf, res); 361 ASSERT_EQ('a', buf[0]); 362 ASSERT_EQ('0', buf[1]); 363 ASSERT_EQ('1', buf[2]); 364 ASSERT_EQ('2', buf[3]); 365 ASSERT_EQ('3', buf[4]); 366 ASSERT_EQ('4', buf[5]); 367 ASSERT_EQ('5', buf[6]); 368 ASSERT_EQ('6', buf[7]); 369 ASSERT_EQ('7', buf[8]); 370 ASSERT_EQ('\0', buf[9]); 371} 372 373TEST(string, strchr_with_0) { 374 char buf[10]; 375 const char* s = "01234"; 376 memcpy(buf, s, strlen(s) + 1); 377 EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s))); 378} 379 380TEST(string, strchr) { 381 int seek_char = random() & 255; 382 383 StringTestState state(SMALL); 384 for (size_t i = 1; i < state.n; i++) { 385 for (size_t j = 0; j < POS_ITER; j++) { 386 state.NewIteration(); 387 388 if (~seek_char > 0) { 389 memset(state.ptr1, ~seek_char, state.len[i]); 390 } else { 391 memset(state.ptr1, '\1', state.len[i]); 392 } 393 state.ptr1[state.len[i] - 1] = '\0'; 394 395 int pos = random() % state.MAX_LEN; 396 char* expected; 397 if (pos >= state.len[i] - 1) { 398 if (seek_char == 0) { 399 expected = state.ptr1 + state.len[i] - 1; 400 } else { 401 expected = NULL; 402 } 403 } else { 404 state.ptr1[pos] = seek_char; 405 expected = state.ptr1 + pos; 406 } 407 408 ASSERT_TRUE(strchr(state.ptr1, seek_char) == expected); 409 } 410 } 411} 412 413TEST(string, strcmp) { 414 StringTestState state(SMALL); 415 for (size_t i = 1; i < state.n; i++) { 416 for (size_t j = 0; j < POS_ITER; j++) { 417 state.NewIteration(); 418 419 memset(state.ptr1, 'v', state.MAX_LEN); 420 memset(state.ptr2, 'n', state.MAX_LEN); 421 state.ptr1[state.len[i] - 1] = '\0'; 422 state.ptr2[state.len[i] - 1] = '\0'; 423 424 int pos = 1 + (random() % (state.MAX_LEN - 1)); 425 int actual; 426 int expected; 427 if (pos >= state.len[i] - 1) { 428 memcpy(state.ptr1, state.ptr2, state.len[i]); 429 expected = 0; 430 actual = strcmp(state.ptr1, state.ptr2); 431 } else { 432 memcpy(state.ptr1, state.ptr2, pos); 433 if (state.ptr1[pos] > state.ptr2[pos]) { 434 expected = 1; 435 } else if (state.ptr1[pos] == state.ptr2[pos]) { 436 state.ptr1[pos + 1] = '\0'; 437 state.ptr2[pos + 1] = '\0'; 438 expected = 0; 439 } else { 440 expected = -1; 441 } 442 actual = strcmp(state.ptr1, state.ptr2); 443 } 444 445 ASSERT_EQ(expected, signum(actual)); 446 } 447 } 448} 449 450TEST(string, strcpy) { 451 StringTestState state(SMALL); 452 for (size_t j = 0; j < POS_ITER; j++) { 453 state.NewIteration(); 454 455 size_t pos = random() % state.MAX_LEN; 456 457 memset(state.ptr1, '\2', pos); 458 state.ptr1[pos] = '\0'; 459 state.ptr1[state.MAX_LEN - 1] = '\0'; 460 461 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 462 463 memset(state.ptr2, '\1', state.MAX_LEN); 464 state.ptr2[state.MAX_LEN - 1] = '\0'; 465 466 memset(state.ptr + state.MAX_LEN, '\1', state.MAX_LEN); 467 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 468 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 469 470 ASSERT_TRUE(strcpy(state.ptr2, state.ptr1) == state.ptr2); 471 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN)) != 0 || 472 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 473 } 474} 475 476 477#if __BIONIC__ 478TEST(string, strlcat) { 479 StringTestState state(SMALL); 480 for (size_t i = 0; i < state.n; i++) { 481 for (size_t j = 0; j < POS_ITER; j++) { 482 state.NewIteration(); 483 484 memset(state.ptr2, '\2', state.MAX_LEN + state.len[i]); 485 state.ptr2[state.MAX_LEN - 1] = '\0'; 486 memcpy(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]); 487 488 int pos = random() % state.MAX_LEN; 489 memset(state.ptr1, '\3', pos); 490 state.ptr1[pos] = '\0'; 491 if (pos < state.len[i]) { 492 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, pos + 1); 493 } else { 494 memcpy(state.ptr + state.MAX_LEN - 1, state.ptr1, state.len[i]); 495 state.ptr[state.MAX_LEN + state.len[i] - 1] = '\0'; 496 } 497 498 strlcat(state.ptr2, state.ptr1, state.MAX_LEN + state.len[i]); 499 500 ASSERT_TRUE(memcmp(state.ptr, state.ptr2, state.MAX_LEN + state.len[i]) == 0); 501 } 502 } 503} 504#endif 505 506#if __BIONIC__ 507TEST(string, strlcpy) { 508 StringTestState state(SMALL); 509 for (size_t j = 0; j < POS_ITER; j++) { 510 state.NewIteration(); 511 512 int rand = random() & 255; 513 if (rand < 1) { 514 rand = 1; 515 } 516 memset(state.ptr1, rand, state.MAX_LEN); 517 518 size_t pos = random() % state.MAX_LEN; 519 if (pos < state.MAX_LEN) { 520 state.ptr1[pos] = '\0'; 521 } 522 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 523 524 memset(state.ptr2, random() & 255, state.MAX_LEN); 525 memcpy(state.ptr + state.MAX_LEN, state.ptr2, state.MAX_LEN); 526 527 if (pos > state.MAX_LEN - 1) { 528 memcpy(state.ptr + state.MAX_LEN, state.ptr1, state.MAX_LEN); 529 state.ptr[2 * state.MAX_LEN - 1] = '\0'; 530 } else { 531 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 532 } 533 534 ASSERT_EQ(strlcpy(state.ptr2, state.ptr1, state.MAX_LEN), strlen(state.ptr1)); 535 ASSERT_FALSE((memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0) || 536 (memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0)); 537 } 538} 539#endif 540 541TEST(string, strncat) { 542 StringTestState state(SMALL); 543 for (size_t i = 1; i < state.n; i++) { 544 for (size_t j = 0; j < POS_ITER; j++) { 545 state.NewIteration(); 546 547 memset(state.ptr2, '\2', state.MAX_LEN); 548 state.ptr2[state.MAX_LEN - 1] = '\0'; 549 memcpy(state.ptr, state.ptr2, 2 * state.MAX_LEN); 550 551 memset(state.ptr1, random() & 255, state.len[i]); 552 state.ptr1[random() % state.len[i]] = '\0'; 553 state.ptr1[state.len[i] - 1] = '\0'; 554 555 size_t pos = strlen(state.ptr1); 556 557 size_t actual = random() % state.len[i]; 558 strncpy(state.ptr + state.MAX_LEN - 1, state.ptr1, std::min(actual, pos)); 559 state.ptr[state.MAX_LEN + std::min(actual, pos) - 1] = '\0'; 560 561 ASSERT_TRUE(strncat(state.ptr2, state.ptr1, actual) == state.ptr2); 562 ASSERT_EQ(memcmp(state.ptr, state.ptr2, 2 * state.MAX_LEN), 0); 563 } 564 } 565} 566 567TEST(string, strncmp) { 568 StringTestState state(SMALL); 569 for (size_t i = 1; i < state.n; i++) { 570 for (size_t j = 0; j < POS_ITER; j++) { 571 state.NewIteration(); 572 573 memset(state.ptr1, 'v', state.MAX_LEN); 574 memset(state.ptr2, 'n', state.MAX_LEN); 575 state.ptr1[state.len[i] - 1] = '\0'; 576 state.ptr2[state.len[i] - 1] = '\0'; 577 578 int pos = 1 + (random() % (state.MAX_LEN - 1)); 579 int actual; 580 int expected; 581 if (pos >= state.len[i] - 1) { 582 memcpy(state.ptr1, state.ptr2, state.len[i]); 583 expected = 0; 584 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 585 } else { 586 memcpy(state.ptr1, state.ptr2, pos); 587 if (state.ptr1[pos] > state.ptr2[pos]) { 588 expected = 1; 589 } else if (state.ptr1[pos] == state.ptr2[pos]) { 590 state.ptr1[pos + 1] = '\0'; 591 state.ptr2[pos + 1] = '\0'; 592 expected = 0; 593 } else { 594 expected = -1; 595 } 596 actual = strncmp(state.ptr1, state.ptr2, state.len[i]); 597 } 598 599 ASSERT_EQ(expected, signum(actual)); 600 } 601 } 602} 603 604TEST(string, strncpy) { 605 StringTestState state(SMALL); 606 for (size_t j = 0; j < ITER; j++) { 607 state.NewIteration(); 608 609 memset(state.ptr1, random() & 255, state.MAX_LEN); 610 state.ptr1[random () % state.MAX_LEN] = '\0'; 611 memcpy(state.ptr, state.ptr1, state.MAX_LEN); 612 613 memset(state.ptr2, '\1', state.MAX_LEN); 614 615 size_t pos; 616 if (memchr(state.ptr1, 0, state.MAX_LEN)) { 617 pos = strlen(state.ptr1); 618 } else { 619 pos = state.MAX_LEN - 1; 620 } 621 622 memset(state.ptr + state.MAX_LEN, '\0', state.MAX_LEN); 623 memcpy(state.ptr + state.MAX_LEN, state.ptr1, pos + 1); 624 625 ASSERT_TRUE(strncpy(state.ptr2, state.ptr1, state.MAX_LEN) == state.ptr2); 626 ASSERT_FALSE(memcmp(state.ptr1, state.ptr, state.MAX_LEN) != 0 || 627 memcmp(state.ptr2, state.ptr + state.MAX_LEN, state.MAX_LEN) != 0); 628 } 629} 630 631TEST(string, strrchr) { 632 int seek_char = random() & 255; 633 StringTestState state(SMALL); 634 for (size_t i = 1; i < state.n; i++) { 635 for (size_t j = 0; j < POS_ITER; j++) { 636 state.NewIteration(); 637 638 if (~seek_char > 0) { 639 memset(state.ptr1, ~seek_char, state.len[i]); 640 } else { 641 memset(state.ptr1, '\1', state.len[i]); 642 } 643 state.ptr1[state.len[i] - 1] = '\0'; 644 645 int pos = random() % state.MAX_LEN; 646 char* expected; 647 if (pos >= state.len[i] - 1) { 648 if (seek_char == 0) { 649 expected = state.ptr1 + state.len[i] - 1; 650 } else { 651 expected = NULL; 652 } 653 } else { 654 state.ptr1[pos] = seek_char; 655 expected = state.ptr1 + pos; 656 } 657 658 ASSERT_TRUE(strrchr(state.ptr1, seek_char) == expected); 659 } 660 } 661} 662 663TEST(string, memchr) { 664 int seek_char = random() & 255; 665 StringTestState state(SMALL); 666 for (size_t i = 0; i < state.n; i++) { 667 for (size_t j = 0; j < POS_ITER; j++) { 668 state.NewIteration(); 669 670 memset(state.ptr1, ~seek_char, state.len[i]); 671 672 int pos = random() % state.MAX_LEN; 673 char* expected; 674 if (pos >= state.len[i]) { 675 expected = NULL; 676 } else { 677 state.ptr1[pos] = seek_char; 678 expected = state.ptr1 + pos; 679 } 680 681 ASSERT_TRUE(memchr(state.ptr1, seek_char, state.len[i]) == expected); 682 } 683 } 684} 685 686TEST(string, memrchr) { 687 int seek_char = random() & 255; 688 StringTestState state(SMALL); 689 for (size_t i = 0; i < state.n; i++) { 690 for (size_t j = 0; j < POS_ITER; j++) { 691 state.NewIteration(); 692 693 memset(state.ptr1, ~seek_char, state.len[i]); 694 695 int pos = random() % state.MAX_LEN; 696 char* expected; 697 if (pos >= state.len[i]) { 698 expected = NULL; 699 } else { 700 state.ptr1[pos] = seek_char; 701 expected = state.ptr1 + pos; 702 } 703 704 ASSERT_TRUE(memrchr(state.ptr1, seek_char, state.len[i]) == expected); 705 } 706 } 707} 708 709TEST(string, memcmp) { 710 StringTestState state(SMALL); 711 for (size_t i = 0; i < state.n; i++) { 712 for (size_t j = 0; j < POS_ITER; j++) { 713 state.NewIteration(); 714 715 int c1 = random() & 0xff; 716 int c2 = random() & 0xff; 717 memset(state.ptr1, c1, state.MAX_LEN); 718 memset(state.ptr2, c1, state.MAX_LEN); 719 720 int pos = (state.len[i] == 0) ? 0 : (random() % state.len[i]); 721 state.ptr2[pos] = c2; 722 723 int expected = (static_cast<int>(c1) - static_cast<int>(c2)); 724 int actual = memcmp(state.ptr1, state.ptr2, state.MAX_LEN); 725 726 ASSERT_EQ(signum(expected), signum(actual)); 727 } 728 } 729} 730 731TEST(string, memcpy) { 732 StringTestState state(LARGE); 733 int rand = random() & 255; 734 for (size_t i = 0; i < state.n - 1; i++) { 735 for (size_t j = 0; j < POS_ITER; j++) { 736 state.NewIteration(); 737 738 size_t pos = random() % (state.MAX_LEN - state.len[i]); 739 740 memset(state.ptr1, rand, state.len[i]); 741 memset(state.ptr1 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 742 743 memset(state.ptr2, rand, state.len[i]); 744 memset(state.ptr2 + state.len[i], ~rand, state.MAX_LEN - state.len[i]); 745 memset(state.ptr2 + pos, '\0', state.len[i]); 746 747 ASSERT_FALSE(memcpy(state.ptr2 + pos, state.ptr1 + pos, state.len[i]) != state.ptr2 + pos); 748 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 749 } 750 } 751} 752 753TEST(string, memset) { 754 StringTestState state(LARGE); 755 char ch = random () & 255; 756 for (size_t i = 0; i < state.n - 1; i++) { 757 for (size_t j = 0; j < POS_ITER; j++) { 758 state.NewIteration(); 759 760 memset(state.ptr1, ~ch, state.MAX_LEN); 761 memcpy(state.ptr2, state.ptr1, state.MAX_LEN); 762 763 size_t pos = random () % (state.MAX_LEN - state.len[i]); 764 for (size_t k = pos; k < pos + state.len[i]; k++) { 765 state.ptr1[k] = ch; 766 } 767 768 ASSERT_TRUE(memset(state.ptr2 + pos, ch, state.len[i]) == state.ptr2 + pos); 769 770 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 771 } 772 } 773} 774 775TEST(string, memmove) { 776 StringTestState state(LARGE); 777 for (size_t i = 0; i < state.n - 1; i++) { 778 for (size_t j = 0; j < POS_ITER; j++) { 779 state.NewIteration(); 780 781 memset(state.ptr1, random() & 255, 2 * state.MAX_LEN); 782 783 size_t pos = random() % (state.MAX_LEN - state.len[i]); 784 785 memset(state.ptr1, random() & 255, state.len[i]); 786 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 787 memcpy(state.ptr, state.ptr1, state.len[i]); 788 memcpy(state.ptr1 + pos, state.ptr, state.len[i]); 789 790 ASSERT_TRUE(memmove(state.ptr2 + pos, state.ptr2, state.len[i]) == state.ptr2 + pos); 791 ASSERT_EQ(0, memcmp(state.ptr2, state.ptr1, 2 * state.MAX_LEN)); 792 } 793 } 794} 795 796TEST(string, bcopy) { 797 StringTestState state(LARGE); 798 for (size_t i = 0; i < state.n; i++) { 799 for (size_t j = 0; j < POS_ITER; j++) { 800 state.NewIteration(); 801 802 memset(state.ptr1, random() & 255, state.MAX_LEN); 803 memset(state.ptr1 + state.MAX_LEN, random() & 255, state.MAX_LEN); 804 memcpy(state.ptr2, state.ptr1, 2 * state.MAX_LEN); 805 806 size_t start = random() % (2 * state.MAX_LEN - state.len[i]); 807 memcpy(state.ptr2 + start, state.ptr1, state.len[i]); 808 809 bcopy(state.ptr1, state.ptr1 + start, state.len[i]); 810 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, 2 * state.MAX_LEN)); 811 } 812 } 813} 814 815TEST(string, bzero) { 816 StringTestState state(LARGE); 817 for (size_t j = 0; j < ITER; j++) { 818 state.NewIteration(); 819 820 memset(state.ptr1, random() & 255, state.MAX_LEN); 821 822 size_t start = random() % state.MAX_LEN; 823 size_t end = start + random() % (state.MAX_LEN - start); 824 825 memcpy(state.ptr2, state.ptr1, start); 826 memset(state.ptr2 + start, '\0', end - start); 827 memcpy(state.ptr2 + end, state.ptr1 + end, state.MAX_LEN - end); 828 829 bzero(state.ptr1 + start, end - start); 830 831 ASSERT_EQ(0, memcmp(state.ptr1, state.ptr2, state.MAX_LEN)); 832 } 833} 834