1 /* Copyright (c) 2008 The NetBSD Foundation, Inc. 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 25 26 #include "atf-c/detail/dynstr.h" 27 28 #include <stdarg.h> 29 #include <stdint.h> 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 34 #include <atf-c.h> 35 36 #include "atf-c/detail/test_helpers.h" 37 38 /* --------------------------------------------------------------------- 39 * Tests for the "atf_dynstr" type. 40 * --------------------------------------------------------------------- */ 41 42 /* 43 * Constructors and destructors. 44 */ 45 46 ATF_TC(init); 47 ATF_TC_HEAD(init, tc) 48 { 49 atf_tc_set_md_var(tc, "descr", "Checks the empty constructor"); 50 } 51 ATF_TC_BODY(init, tc) 52 { 53 atf_dynstr_t str; 54 55 RE(atf_dynstr_init(&str)); 56 ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); 57 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 58 atf_dynstr_fini(&str); 59 } 60 61 static 62 void 63 init_fmt(atf_dynstr_t *str, const char *fmt, ...) 64 { 65 va_list ap; 66 67 va_start(ap, fmt); 68 RE(atf_dynstr_init_ap(str, fmt, ap)); 69 va_end(ap); 70 } 71 72 ATF_TC(init_ap); 73 ATF_TC_HEAD(init_ap, tc) 74 { 75 atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using " 76 "a va_list argument"); 77 } 78 ATF_TC_BODY(init_ap, tc) 79 { 80 atf_dynstr_t str; 81 82 init_fmt(&str, "String 1"); 83 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); 84 atf_dynstr_fini(&str); 85 86 init_fmt(&str, "String %d", 2); 87 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); 88 atf_dynstr_fini(&str); 89 90 init_fmt(&str, "%s %d", "String", 3); 91 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0); 92 atf_dynstr_fini(&str); 93 94 init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ", 95 "large ", "string ", "aaaabbbbccccdddd"); 96 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), 97 "This should be a large string " 98 "aaaabbbbccccdddd") == 0); 99 atf_dynstr_fini(&str); 100 } 101 102 ATF_TC(init_fmt); 103 ATF_TC_HEAD(init_fmt, tc) 104 { 105 atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using " 106 "a variable list of parameters"); 107 } 108 ATF_TC_BODY(init_fmt, tc) 109 { 110 atf_dynstr_t str; 111 112 RE(atf_dynstr_init_fmt(&str, "String 1")); 113 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); 114 atf_dynstr_fini(&str); 115 116 RE(atf_dynstr_init_fmt(&str, "String %d", 2)); 117 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); 118 atf_dynstr_fini(&str); 119 120 RE(atf_dynstr_init_fmt(&str, "%s %d", "String", 3)); 121 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0); 122 atf_dynstr_fini(&str); 123 124 RE(atf_dynstr_init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", 125 "be ", "a ", "large ", "string ", 126 "aaaabbbbccccdddd")); 127 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), 128 "This should be a large string " 129 "aaaabbbbccccdddd") == 0); 130 atf_dynstr_fini(&str); 131 } 132 133 ATF_TC(init_raw); 134 ATF_TC_HEAD(init_raw, tc) 135 { 136 atf_tc_set_md_var(tc, "descr", "Checks the construction of a string " 137 "using a raw memory pointer"); 138 } 139 ATF_TC_BODY(init_raw, tc) 140 { 141 const char *src = "String 1, String 2"; 142 atf_dynstr_t str; 143 144 RE(atf_dynstr_init_raw(&str, src, 0)); 145 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 146 atf_dynstr_fini(&str); 147 148 RE(atf_dynstr_init_raw(&str, src, 8)); 149 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); 150 atf_dynstr_fini(&str); 151 152 RE(atf_dynstr_init_raw(&str, src + 10, 8)); 153 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); 154 atf_dynstr_fini(&str); 155 156 RE(atf_dynstr_init_raw(&str, "String\0Lost", 11)); 157 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0); 158 atf_dynstr_fini(&str); 159 160 { 161 atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1); 162 ATF_REQUIRE(atf_is_error(err)); 163 ATF_REQUIRE(atf_error_is(err, "no_memory")); 164 atf_error_free(err); 165 } 166 } 167 168 ATF_TC(init_rep); 169 ATF_TC_HEAD(init_rep, tc) 170 { 171 atf_tc_set_md_var(tc, "descr", "Checks the construction of a string by " 172 "repeating characters"); 173 } 174 ATF_TC_BODY(init_rep, tc) 175 { 176 const size_t maxlen = 8192; 177 char buf[maxlen + 1]; 178 size_t i; 179 180 buf[0] = '\0'; 181 182 for (i = 0; i < maxlen; i++) { 183 atf_dynstr_t str; 184 185 RE(atf_dynstr_init_rep(&str, i, 'a')); 186 187 if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 188 fprintf(stderr, "Failed at iteration %zd\n", i); 189 atf_tc_fail("Failed to construct dynstr by repeating %zd " 190 "times the '%c' character", i, 'a'); 191 } 192 193 atf_dynstr_fini(&str); 194 195 strcat(buf, "a"); 196 } 197 198 { 199 atf_dynstr_t str; 200 atf_error_t err; 201 202 err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a'); 203 ATF_REQUIRE(atf_is_error(err)); 204 ATF_REQUIRE(atf_error_is(err, "no_memory")); 205 atf_error_free(err); 206 207 err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a'); 208 ATF_REQUIRE(atf_is_error(err)); 209 ATF_REQUIRE(atf_error_is(err, "no_memory")); 210 atf_error_free(err); 211 } 212 } 213 214 ATF_TC(init_substr); 215 ATF_TC_HEAD(init_substr, tc) 216 { 217 atf_tc_set_md_var(tc, "descr", "Checks the construction of a string " 218 "using a substring of another one"); 219 } 220 ATF_TC_BODY(init_substr, tc) 221 { 222 atf_dynstr_t src; 223 atf_dynstr_t str; 224 225 RE(atf_dynstr_init_fmt(&src, "Str 1, Str 2")); 226 227 RE(atf_dynstr_init_substr(&str, &src, 0, 0)); 228 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 229 atf_dynstr_fini(&str); 230 231 RE(atf_dynstr_init_substr(&str, &src, 0, atf_dynstr_npos)); 232 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0); 233 atf_dynstr_fini(&str); 234 235 RE(atf_dynstr_init_substr(&str, &src, 0, 100)); 236 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0); 237 atf_dynstr_fini(&str); 238 239 RE(atf_dynstr_init_substr(&str, &src, 0, 5)); 240 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1") == 0); 241 atf_dynstr_fini(&str); 242 243 RE(atf_dynstr_init_substr(&str, &src, 100, atf_dynstr_npos)); 244 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 245 atf_dynstr_fini(&str); 246 247 RE(atf_dynstr_init_substr(&str, &src, 7, atf_dynstr_npos)); 248 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 2") == 0); 249 atf_dynstr_fini(&str); 250 251 atf_dynstr_fini(&src); 252 } 253 254 ATF_TC(copy); 255 ATF_TC_HEAD(copy, tc) 256 { 257 atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor"); 258 } 259 ATF_TC_BODY(copy, tc) 260 { 261 atf_dynstr_t str, str2; 262 263 RE(atf_dynstr_init_fmt(&str, "Test string")); 264 RE(atf_dynstr_copy(&str2, &str)); 265 266 ATF_REQUIRE(atf_equal_dynstr_dynstr(&str, &str2)); 267 268 RE(atf_dynstr_append_fmt(&str2, " non-shared text")); 269 270 ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2)); 271 272 atf_dynstr_fini(&str2); 273 atf_dynstr_fini(&str); 274 } 275 276 ATF_TC(fini_disown); 277 ATF_TC_HEAD(fini_disown, tc) 278 { 279 atf_tc_set_md_var(tc, "descr", "Checks grabbing ownership of the " 280 "internal plain C string"); 281 } 282 ATF_TC_BODY(fini_disown, tc) 283 { 284 const char *cstr; 285 char *cstr2; 286 atf_dynstr_t str; 287 288 RE(atf_dynstr_init_fmt(&str, "Test string 1")); 289 cstr = atf_dynstr_cstring(&str); 290 cstr2 = atf_dynstr_fini_disown(&str); 291 292 ATF_REQUIRE_EQ(cstr, cstr2); 293 free(cstr2); 294 } 295 296 /* 297 * Getters. 298 */ 299 300 ATF_TC(cstring); 301 ATF_TC_HEAD(cstring, tc) 302 { 303 atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C " 304 "string"); 305 } 306 ATF_TC_BODY(cstring, tc) 307 { 308 const char *cstr; 309 atf_dynstr_t str; 310 311 RE(atf_dynstr_init_fmt(&str, "Test string 1")); 312 cstr = atf_dynstr_cstring(&str); 313 ATF_REQUIRE(cstr != NULL); 314 ATF_REQUIRE(strcmp(cstr, "Test string 1") == 0); 315 atf_dynstr_fini(&str); 316 317 RE(atf_dynstr_init_fmt(&str, "Test string 2")); 318 cstr = atf_dynstr_cstring(&str); 319 ATF_REQUIRE(cstr != NULL); 320 ATF_REQUIRE(strcmp(cstr, "Test string 2") == 0); 321 atf_dynstr_fini(&str); 322 } 323 324 ATF_TC(length); 325 ATF_TC_HEAD(length, tc) 326 { 327 atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length"); 328 } 329 ATF_TC_BODY(length, tc) 330 { 331 size_t i; 332 333 for (i = 0; i < 8192; i++) { 334 atf_dynstr_t str; 335 RE(atf_dynstr_init_rep(&str, i, 'a')); 336 ATF_REQUIRE_EQ(atf_dynstr_length(&str), i); 337 atf_dynstr_fini(&str); 338 } 339 } 340 341 ATF_TC(rfind_ch); 342 ATF_TC_HEAD(rfind_ch, tc) 343 { 344 atf_tc_set_md_var(tc, "descr", "Checks the method to locate the first " 345 "occurrence of a character starting from the end"); 346 } 347 ATF_TC_BODY(rfind_ch, tc) 348 { 349 atf_dynstr_t str; 350 351 RE(atf_dynstr_init_fmt(&str, "Foo1/Bar2/,.Baz")); 352 353 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '\0'), atf_dynstr_npos); 354 355 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '0'), atf_dynstr_npos); 356 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'b'), atf_dynstr_npos); 357 358 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'F'), 0); 359 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '/'), 9); 360 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'a'), 13); 361 ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'z'), 14); 362 363 atf_dynstr_fini(&str); 364 } 365 366 /* 367 * Modifiers. 368 */ 369 370 static 371 void 372 check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...)) 373 { 374 const size_t maxlen = 8192; 375 char buf[maxlen + 1]; 376 size_t i; 377 atf_dynstr_t str; 378 379 printf("Appending with plain string\n"); 380 buf[0] = '\0'; 381 RE(atf_dynstr_init(&str)); 382 for (i = 0; i < maxlen; i++) { 383 if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 384 fprintf(stderr, "Failed at iteration %zd\n", i); 385 atf_tc_fail("Failed to append character at iteration %zd", i); 386 } 387 388 RE(append(&str, "a")); 389 strcat(buf, "a"); 390 } 391 atf_dynstr_fini(&str); 392 393 printf("Appending with formatted string\n"); 394 buf[0] = '\0'; 395 RE(atf_dynstr_init(&str)); 396 for (i = 0; i < maxlen; i++) { 397 if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 398 fprintf(stderr, "Failed at iteration %zd\n", i); 399 atf_tc_fail("Failed to append character at iteration %zd", i); 400 } 401 402 RE(append(&str, "%s", "a")); 403 strcat(buf, "a"); 404 } 405 atf_dynstr_fini(&str); 406 } 407 408 static 409 atf_error_t 410 append_ap_aux(atf_dynstr_t *str, const char *fmt, ...) 411 { 412 va_list ap; 413 atf_error_t err; 414 415 va_start(ap, fmt); 416 err = atf_dynstr_append_ap(str, fmt, ap); 417 va_end(ap); 418 419 return err; 420 } 421 422 ATF_TC(append_ap); 423 ATF_TC_HEAD(append_ap, tc) 424 { 425 atf_tc_set_md_var(tc, "descr", "Checks that appending a string to " 426 "another one works"); 427 } 428 ATF_TC_BODY(append_ap, tc) 429 { 430 check_append(append_ap_aux); 431 } 432 433 ATF_TC(append_fmt); 434 ATF_TC_HEAD(append_fmt, tc) 435 { 436 atf_tc_set_md_var(tc, "descr", "Checks that appending a string to " 437 "another one works"); 438 } 439 ATF_TC_BODY(append_fmt, tc) 440 { 441 check_append(atf_dynstr_append_fmt); 442 } 443 444 ATF_TC(clear); 445 ATF_TC_HEAD(clear, tc) 446 { 447 atf_tc_set_md_var(tc, "descr", "Checks clearing a string"); 448 } 449 ATF_TC_BODY(clear, tc) 450 { 451 atf_dynstr_t str; 452 453 printf("Clear an empty string\n"); 454 RE(atf_dynstr_init(&str)); 455 atf_dynstr_clear(&str); 456 ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); 457 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 458 atf_dynstr_fini(&str); 459 460 printf("Clear a non-empty string\n"); 461 RE(atf_dynstr_init_fmt(&str, "Not empty")); 462 ATF_REQUIRE_EQ(atf_dynstr_length(&str), strlen("Not empty")); 463 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Not empty") == 0); 464 atf_dynstr_clear(&str); 465 ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); 466 ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 467 atf_dynstr_fini(&str); 468 } 469 470 static 471 void 472 check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...)) 473 { 474 const size_t maxlen = 8192; 475 char buf[maxlen + 1]; 476 size_t i; 477 atf_dynstr_t str; 478 479 printf("Prepending with plain string\n"); 480 buf[0] = '\0'; 481 RE(atf_dynstr_init(&str)); 482 for (i = 0; i < maxlen; i++) { 483 if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 484 fprintf(stderr, "Failed at iteration %zd\n", i); 485 atf_tc_fail("Failed to prepend character at iteration %zd", i); 486 } 487 488 memmove(buf + 1, buf, i + 1); 489 if (i % 2 == 0) { 490 RE(prepend(&str, "%s", "a")); 491 buf[0] = 'a'; 492 } else { 493 RE(prepend(&str, "%s", "b")); 494 buf[0] = 'b'; 495 } 496 } 497 atf_dynstr_fini(&str); 498 499 printf("Prepending with formatted string\n"); 500 buf[0] = '\0'; 501 RE(atf_dynstr_init(&str)); 502 for (i = 0; i < maxlen; i++) { 503 if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 504 fprintf(stderr, "Failed at iteration %zd\n", i); 505 atf_tc_fail("Failed to prepend character at iteration %zd", i); 506 } 507 508 memmove(buf + 1, buf, i + 1); 509 if (i % 2 == 0) { 510 RE(prepend(&str, "%s", "a")); 511 buf[0] = 'a'; 512 } else { 513 RE(prepend(&str, "%s", "b")); 514 buf[0] = 'b'; 515 } 516 } 517 atf_dynstr_fini(&str); 518 } 519 520 static 521 atf_error_t 522 prepend_ap_aux(atf_dynstr_t *str, const char *fmt, ...) 523 { 524 va_list ap; 525 atf_error_t err; 526 527 va_start(ap, fmt); 528 err = atf_dynstr_prepend_ap(str, fmt, ap); 529 va_end(ap); 530 531 return err; 532 } 533 534 ATF_TC(prepend_ap); 535 ATF_TC_HEAD(prepend_ap, tc) 536 { 537 atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to " 538 "another one works"); 539 } 540 ATF_TC_BODY(prepend_ap, tc) 541 { 542 check_prepend(prepend_ap_aux); 543 } 544 545 ATF_TC(prepend_fmt); 546 ATF_TC_HEAD(prepend_fmt, tc) 547 { 548 atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to " 549 "another one works"); 550 } 551 ATF_TC_BODY(prepend_fmt, tc) 552 { 553 check_prepend(atf_dynstr_prepend_fmt); 554 } 555 556 /* 557 * Operators. 558 */ 559 560 ATF_TC(equal_cstring); 561 ATF_TC_HEAD(equal_cstring, tc) 562 { 563 atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring " 564 "function"); 565 } 566 ATF_TC_BODY(equal_cstring, tc) 567 { 568 atf_dynstr_t str; 569 570 RE(atf_dynstr_init(&str)); 571 ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "")); 572 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test")); 573 atf_dynstr_fini(&str); 574 575 RE(atf_dynstr_init_fmt(&str, "Test")); 576 ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "Test")); 577 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "")); 578 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Tes")); 579 ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test ")); 580 atf_dynstr_fini(&str); 581 } 582 583 ATF_TC(equal_dynstr); 584 ATF_TC_HEAD(equal_dynstr, tc) 585 { 586 atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr " 587 "function"); 588 } 589 ATF_TC_BODY(equal_dynstr, tc) 590 { 591 atf_dynstr_t str, str2; 592 593 RE(atf_dynstr_init(&str)); 594 RE(atf_dynstr_init_fmt(&str2, "Test")); 595 ATF_REQUIRE( atf_equal_dynstr_dynstr(&str, &str)); 596 ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2)); 597 atf_dynstr_fini(&str2); 598 atf_dynstr_fini(&str); 599 } 600 601 /* --------------------------------------------------------------------- 602 * Main. 603 * --------------------------------------------------------------------- */ 604 605 ATF_TP_ADD_TCS(tp) 606 { 607 /* Constructors and destructors. */ 608 ATF_TP_ADD_TC(tp, init); 609 ATF_TP_ADD_TC(tp, init_ap); 610 ATF_TP_ADD_TC(tp, init_fmt); 611 ATF_TP_ADD_TC(tp, init_raw); 612 ATF_TP_ADD_TC(tp, init_rep); 613 ATF_TP_ADD_TC(tp, init_substr); 614 ATF_TP_ADD_TC(tp, copy); 615 ATF_TP_ADD_TC(tp, fini_disown); 616 617 /* Getters. */ 618 ATF_TP_ADD_TC(tp, cstring); 619 ATF_TP_ADD_TC(tp, length); 620 ATF_TP_ADD_TC(tp, rfind_ch); 621 622 /* Modifiers. */ 623 ATF_TP_ADD_TC(tp, append_ap); 624 ATF_TP_ADD_TC(tp, append_fmt); 625 ATF_TP_ADD_TC(tp, clear); 626 ATF_TP_ADD_TC(tp, prepend_ap); 627 ATF_TP_ADD_TC(tp, prepend_fmt); 628 629 /* Operators. */ 630 ATF_TP_ADD_TC(tp, equal_cstring); 631 ATF_TP_ADD_TC(tp, equal_dynstr); 632 633 return atf_no_error(); 634 } 635