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 49ATF_TC(init); 50ATF_TC_HEAD(init, tc) 51{ 52 atf_tc_set_md_var(tc, "descr", "Checks the empty constructor"); 53} 54ATF_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 64static 65void 66init_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 75ATF_TC(init_ap); 76ATF_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} 81ATF_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 105ATF_TC(init_fmt); 106ATF_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} 111ATF_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 136ATF_TC(init_raw); 137ATF_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} 142ATF_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 171ATF_TC(init_rep); 172ATF_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} 177ATF_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 217ATF_TC(init_substr); 218ATF_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} 223ATF_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 257ATF_TC(copy); 258ATF_TC_HEAD(copy, tc) 259{ 260 atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor"); 261} 262ATF_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 279ATF_TC(fini_disown); 280ATF_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} 285ATF_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 303ATF_TC(cstring); 304ATF_TC_HEAD(cstring, tc) 305{ 306 atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C " 307 "string"); 308} 309ATF_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 327ATF_TC(length); 328ATF_TC_HEAD(length, tc) 329{ 330 atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length"); 331} 332ATF_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 344ATF_TC(rfind_ch); 345ATF_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} 350ATF_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 373static 374void 375check_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 411static 412atf_error_t 413append_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 425ATF_TC(append_ap); 426ATF_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} 431ATF_TC_BODY(append_ap, tc) 432{ 433 check_append(append_ap_aux); 434} 435 436ATF_TC(append_fmt); 437ATF_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} 442ATF_TC_BODY(append_fmt, tc) 443{ 444 check_append(atf_dynstr_append_fmt); 445} 446 447ATF_TC(clear); 448ATF_TC_HEAD(clear, tc) 449{ 450 atf_tc_set_md_var(tc, "descr", "Checks clearing a string"); 451} 452ATF_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 473static 474void 475check_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 523static 524atf_error_t 525prepend_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 537ATF_TC(prepend_ap); 538ATF_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} 543ATF_TC_BODY(prepend_ap, tc) 544{ 545 check_prepend(prepend_ap_aux); 546} 547 548ATF_TC(prepend_fmt); 549ATF_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} 554ATF_TC_BODY(prepend_fmt, tc) 555{ 556 check_prepend(atf_dynstr_prepend_fmt); 557} 558 559/* 560 * Operators. 561 */ 562 563ATF_TC(equal_cstring); 564ATF_TC_HEAD(equal_cstring, tc) 565{ 566 atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring " 567 "function"); 568} 569ATF_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 586ATF_TC(equal_dynstr); 587ATF_TC_HEAD(equal_dynstr, tc) 588{ 589 atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr " 590 "function"); 591} 592ATF_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 608ATF_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