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