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 46ATF_TC(init); 47ATF_TC_HEAD(init, tc) 48{ 49 atf_tc_set_md_var(tc, "descr", "Checks the empty constructor"); 50} 51ATF_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 61static 62void 63init_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 72ATF_TC(init_ap); 73ATF_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} 78ATF_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 102ATF_TC(init_fmt); 103ATF_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} 108ATF_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 133ATF_TC(init_raw); 134ATF_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} 139ATF_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 168ATF_TC(init_rep); 169ATF_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} 174ATF_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 214ATF_TC(init_substr); 215ATF_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} 220ATF_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 254ATF_TC(copy); 255ATF_TC_HEAD(copy, tc) 256{ 257 atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor"); 258} 259ATF_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 276ATF_TC(fini_disown); 277ATF_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} 282ATF_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 300ATF_TC(cstring); 301ATF_TC_HEAD(cstring, tc) 302{ 303 atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C " 304 "string"); 305} 306ATF_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 324ATF_TC(length); 325ATF_TC_HEAD(length, tc) 326{ 327 atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length"); 328} 329ATF_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 341ATF_TC(rfind_ch); 342ATF_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} 347ATF_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 370static 371void 372check_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 408static 409atf_error_t 410append_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 422ATF_TC(append_ap); 423ATF_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} 428ATF_TC_BODY(append_ap, tc) 429{ 430 check_append(append_ap_aux); 431} 432 433ATF_TC(append_fmt); 434ATF_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} 439ATF_TC_BODY(append_fmt, tc) 440{ 441 check_append(atf_dynstr_append_fmt); 442} 443 444ATF_TC(clear); 445ATF_TC_HEAD(clear, tc) 446{ 447 atf_tc_set_md_var(tc, "descr", "Checks clearing a string"); 448} 449ATF_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 470static 471void 472check_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 520static 521atf_error_t 522prepend_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 534ATF_TC(prepend_ap); 535ATF_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} 540ATF_TC_BODY(prepend_ap, tc) 541{ 542 check_prepend(prepend_ap_aux); 543} 544 545ATF_TC(prepend_fmt); 546ATF_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} 551ATF_TC_BODY(prepend_fmt, tc) 552{ 553 check_prepend(atf_dynstr_prepend_fmt); 554} 555 556/* 557 * Operators. 558 */ 559 560ATF_TC(equal_cstring); 561ATF_TC_HEAD(equal_cstring, tc) 562{ 563 atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring " 564 "function"); 565} 566ATF_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 583ATF_TC(equal_dynstr); 584ATF_TC_HEAD(equal_dynstr, tc) 585{ 586 atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr " 587 "function"); 588} 589ATF_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 605ATF_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