1275988Sngie/* Copyright (c) 2008 The NetBSD Foundation, Inc. 2240116Smarcel * All rights reserved. 3240116Smarcel * 4240116Smarcel * Redistribution and use in source and binary forms, with or without 5240116Smarcel * modification, are permitted provided that the following conditions 6240116Smarcel * are met: 7240116Smarcel * 1. Redistributions of source code must retain the above copyright 8240116Smarcel * notice, this list of conditions and the following disclaimer. 9240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright 10240116Smarcel * notice, this list of conditions and the following disclaimer in the 11240116Smarcel * documentation and/or other materials provided with the distribution. 12240116Smarcel * 13240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24275988Sngie * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 25240116Smarcel 26275988Sngie#include "atf-c/detail/dynstr.h" 27275988Sngie 28240116Smarcel#include <stdarg.h> 29240116Smarcel#include <stdint.h> 30240116Smarcel#include <stdio.h> 31240116Smarcel#include <stdlib.h> 32240116Smarcel#include <string.h> 33240116Smarcel 34240116Smarcel#include <atf-c.h> 35240116Smarcel 36275988Sngie#include "atf-c/detail/test_helpers.h" 37240116Smarcel 38240116Smarcel/* --------------------------------------------------------------------- 39240116Smarcel * Tests for the "atf_dynstr" type. 40240116Smarcel * --------------------------------------------------------------------- */ 41240116Smarcel 42240116Smarcel/* 43240116Smarcel * Constructors and destructors. 44240116Smarcel */ 45240116Smarcel 46240116SmarcelATF_TC(init); 47240116SmarcelATF_TC_HEAD(init, tc) 48240116Smarcel{ 49240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the empty constructor"); 50240116Smarcel} 51240116SmarcelATF_TC_BODY(init, tc) 52240116Smarcel{ 53240116Smarcel atf_dynstr_t str; 54240116Smarcel 55240116Smarcel RE(atf_dynstr_init(&str)); 56240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); 57240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 58240116Smarcel atf_dynstr_fini(&str); 59240116Smarcel} 60240116Smarcel 61240116Smarcelstatic 62240116Smarcelvoid 63240116Smarcelinit_fmt(atf_dynstr_t *str, const char *fmt, ...) 64240116Smarcel{ 65240116Smarcel va_list ap; 66240116Smarcel 67240116Smarcel va_start(ap, fmt); 68240116Smarcel RE(atf_dynstr_init_ap(str, fmt, ap)); 69240116Smarcel va_end(ap); 70240116Smarcel} 71240116Smarcel 72240116SmarcelATF_TC(init_ap); 73240116SmarcelATF_TC_HEAD(init_ap, tc) 74240116Smarcel{ 75240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using " 76240116Smarcel "a va_list argument"); 77240116Smarcel} 78240116SmarcelATF_TC_BODY(init_ap, tc) 79240116Smarcel{ 80240116Smarcel atf_dynstr_t str; 81240116Smarcel 82240116Smarcel init_fmt(&str, "String 1"); 83240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); 84240116Smarcel atf_dynstr_fini(&str); 85240116Smarcel 86240116Smarcel init_fmt(&str, "String %d", 2); 87240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); 88240116Smarcel atf_dynstr_fini(&str); 89240116Smarcel 90240116Smarcel init_fmt(&str, "%s %d", "String", 3); 91240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0); 92240116Smarcel atf_dynstr_fini(&str); 93240116Smarcel 94240116Smarcel init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ", 95240116Smarcel "large ", "string ", "aaaabbbbccccdddd"); 96240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), 97240116Smarcel "This should be a large string " 98240116Smarcel "aaaabbbbccccdddd") == 0); 99240116Smarcel atf_dynstr_fini(&str); 100240116Smarcel} 101240116Smarcel 102240116SmarcelATF_TC(init_fmt); 103240116SmarcelATF_TC_HEAD(init_fmt, tc) 104240116Smarcel{ 105240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using " 106240116Smarcel "a variable list of parameters"); 107240116Smarcel} 108240116SmarcelATF_TC_BODY(init_fmt, tc) 109240116Smarcel{ 110240116Smarcel atf_dynstr_t str; 111240116Smarcel 112240116Smarcel RE(atf_dynstr_init_fmt(&str, "String 1")); 113240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); 114240116Smarcel atf_dynstr_fini(&str); 115240116Smarcel 116240116Smarcel RE(atf_dynstr_init_fmt(&str, "String %d", 2)); 117240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); 118240116Smarcel atf_dynstr_fini(&str); 119240116Smarcel 120240116Smarcel RE(atf_dynstr_init_fmt(&str, "%s %d", "String", 3)); 121240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0); 122240116Smarcel atf_dynstr_fini(&str); 123240116Smarcel 124240116Smarcel RE(atf_dynstr_init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", 125240116Smarcel "be ", "a ", "large ", "string ", 126240116Smarcel "aaaabbbbccccdddd")); 127240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), 128240116Smarcel "This should be a large string " 129240116Smarcel "aaaabbbbccccdddd") == 0); 130240116Smarcel atf_dynstr_fini(&str); 131240116Smarcel} 132240116Smarcel 133240116SmarcelATF_TC(init_raw); 134240116SmarcelATF_TC_HEAD(init_raw, tc) 135240116Smarcel{ 136240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the construction of a string " 137240116Smarcel "using a raw memory pointer"); 138240116Smarcel} 139240116SmarcelATF_TC_BODY(init_raw, tc) 140240116Smarcel{ 141240116Smarcel const char *src = "String 1, String 2"; 142240116Smarcel atf_dynstr_t str; 143240116Smarcel 144240116Smarcel RE(atf_dynstr_init_raw(&str, src, 0)); 145240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 146240116Smarcel atf_dynstr_fini(&str); 147240116Smarcel 148240116Smarcel RE(atf_dynstr_init_raw(&str, src, 8)); 149240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0); 150240116Smarcel atf_dynstr_fini(&str); 151240116Smarcel 152240116Smarcel RE(atf_dynstr_init_raw(&str, src + 10, 8)); 153240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0); 154240116Smarcel atf_dynstr_fini(&str); 155240116Smarcel 156240116Smarcel RE(atf_dynstr_init_raw(&str, "String\0Lost", 11)); 157240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0); 158240116Smarcel atf_dynstr_fini(&str); 159240116Smarcel 160240116Smarcel { 161240116Smarcel atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1); 162240116Smarcel ATF_REQUIRE(atf_is_error(err)); 163240116Smarcel ATF_REQUIRE(atf_error_is(err, "no_memory")); 164240116Smarcel atf_error_free(err); 165240116Smarcel } 166240116Smarcel} 167240116Smarcel 168240116SmarcelATF_TC(init_rep); 169240116SmarcelATF_TC_HEAD(init_rep, tc) 170240116Smarcel{ 171240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the construction of a string by " 172240116Smarcel "repeating characters"); 173240116Smarcel} 174240116SmarcelATF_TC_BODY(init_rep, tc) 175240116Smarcel{ 176240116Smarcel const size_t maxlen = 8192; 177240116Smarcel char buf[maxlen + 1]; 178240116Smarcel size_t i; 179240116Smarcel 180240116Smarcel buf[0] = '\0'; 181240116Smarcel 182240116Smarcel for (i = 0; i < maxlen; i++) { 183240116Smarcel atf_dynstr_t str; 184240116Smarcel 185240116Smarcel RE(atf_dynstr_init_rep(&str, i, 'a')); 186240116Smarcel 187240116Smarcel if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 188240116Smarcel fprintf(stderr, "Failed at iteration %zd\n", i); 189240116Smarcel atf_tc_fail("Failed to construct dynstr by repeating %zd " 190240116Smarcel "times the '%c' character", i, 'a'); 191240116Smarcel } 192240116Smarcel 193240116Smarcel atf_dynstr_fini(&str); 194240116Smarcel 195240116Smarcel strcat(buf, "a"); 196240116Smarcel } 197240116Smarcel 198240116Smarcel { 199240116Smarcel atf_dynstr_t str; 200240116Smarcel atf_error_t err; 201240116Smarcel 202240116Smarcel err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a'); 203240116Smarcel ATF_REQUIRE(atf_is_error(err)); 204240116Smarcel ATF_REQUIRE(atf_error_is(err, "no_memory")); 205240116Smarcel atf_error_free(err); 206240116Smarcel 207240116Smarcel err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a'); 208240116Smarcel ATF_REQUIRE(atf_is_error(err)); 209240116Smarcel ATF_REQUIRE(atf_error_is(err, "no_memory")); 210240116Smarcel atf_error_free(err); 211240116Smarcel } 212240116Smarcel} 213240116Smarcel 214240116SmarcelATF_TC(init_substr); 215240116SmarcelATF_TC_HEAD(init_substr, tc) 216240116Smarcel{ 217240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the construction of a string " 218240116Smarcel "using a substring of another one"); 219240116Smarcel} 220240116SmarcelATF_TC_BODY(init_substr, tc) 221240116Smarcel{ 222240116Smarcel atf_dynstr_t src; 223240116Smarcel atf_dynstr_t str; 224240116Smarcel 225240116Smarcel RE(atf_dynstr_init_fmt(&src, "Str 1, Str 2")); 226240116Smarcel 227240116Smarcel RE(atf_dynstr_init_substr(&str, &src, 0, 0)); 228240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 229240116Smarcel atf_dynstr_fini(&str); 230240116Smarcel 231240116Smarcel RE(atf_dynstr_init_substr(&str, &src, 0, atf_dynstr_npos)); 232240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0); 233240116Smarcel atf_dynstr_fini(&str); 234240116Smarcel 235240116Smarcel RE(atf_dynstr_init_substr(&str, &src, 0, 100)); 236240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0); 237240116Smarcel atf_dynstr_fini(&str); 238240116Smarcel 239240116Smarcel RE(atf_dynstr_init_substr(&str, &src, 0, 5)); 240240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1") == 0); 241240116Smarcel atf_dynstr_fini(&str); 242240116Smarcel 243240116Smarcel RE(atf_dynstr_init_substr(&str, &src, 100, atf_dynstr_npos)); 244240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 245240116Smarcel atf_dynstr_fini(&str); 246240116Smarcel 247240116Smarcel RE(atf_dynstr_init_substr(&str, &src, 7, atf_dynstr_npos)); 248240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 2") == 0); 249240116Smarcel atf_dynstr_fini(&str); 250240116Smarcel 251240116Smarcel atf_dynstr_fini(&src); 252240116Smarcel} 253240116Smarcel 254240116SmarcelATF_TC(copy); 255240116SmarcelATF_TC_HEAD(copy, tc) 256240116Smarcel{ 257240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor"); 258240116Smarcel} 259240116SmarcelATF_TC_BODY(copy, tc) 260240116Smarcel{ 261240116Smarcel atf_dynstr_t str, str2; 262240116Smarcel 263240116Smarcel RE(atf_dynstr_init_fmt(&str, "Test string")); 264240116Smarcel RE(atf_dynstr_copy(&str2, &str)); 265240116Smarcel 266240116Smarcel ATF_REQUIRE(atf_equal_dynstr_dynstr(&str, &str2)); 267240116Smarcel 268240116Smarcel RE(atf_dynstr_append_fmt(&str2, " non-shared text")); 269240116Smarcel 270240116Smarcel ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2)); 271240116Smarcel 272240116Smarcel atf_dynstr_fini(&str2); 273240116Smarcel atf_dynstr_fini(&str); 274240116Smarcel} 275240116Smarcel 276240116SmarcelATF_TC(fini_disown); 277240116SmarcelATF_TC_HEAD(fini_disown, tc) 278240116Smarcel{ 279240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks grabbing ownership of the " 280240116Smarcel "internal plain C string"); 281240116Smarcel} 282240116SmarcelATF_TC_BODY(fini_disown, tc) 283240116Smarcel{ 284240116Smarcel const char *cstr; 285240116Smarcel char *cstr2; 286240116Smarcel atf_dynstr_t str; 287240116Smarcel 288240116Smarcel RE(atf_dynstr_init_fmt(&str, "Test string 1")); 289240116Smarcel cstr = atf_dynstr_cstring(&str); 290240116Smarcel cstr2 = atf_dynstr_fini_disown(&str); 291240116Smarcel 292240116Smarcel ATF_REQUIRE_EQ(cstr, cstr2); 293240116Smarcel free(cstr2); 294240116Smarcel} 295240116Smarcel 296240116Smarcel/* 297240116Smarcel * Getters. 298240116Smarcel */ 299240116Smarcel 300240116SmarcelATF_TC(cstring); 301240116SmarcelATF_TC_HEAD(cstring, tc) 302240116Smarcel{ 303240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C " 304240116Smarcel "string"); 305240116Smarcel} 306240116SmarcelATF_TC_BODY(cstring, tc) 307240116Smarcel{ 308240116Smarcel const char *cstr; 309240116Smarcel atf_dynstr_t str; 310240116Smarcel 311240116Smarcel RE(atf_dynstr_init_fmt(&str, "Test string 1")); 312240116Smarcel cstr = atf_dynstr_cstring(&str); 313240116Smarcel ATF_REQUIRE(cstr != NULL); 314240116Smarcel ATF_REQUIRE(strcmp(cstr, "Test string 1") == 0); 315240116Smarcel atf_dynstr_fini(&str); 316240116Smarcel 317240116Smarcel RE(atf_dynstr_init_fmt(&str, "Test string 2")); 318240116Smarcel cstr = atf_dynstr_cstring(&str); 319240116Smarcel ATF_REQUIRE(cstr != NULL); 320240116Smarcel ATF_REQUIRE(strcmp(cstr, "Test string 2") == 0); 321240116Smarcel atf_dynstr_fini(&str); 322240116Smarcel} 323240116Smarcel 324240116SmarcelATF_TC(length); 325240116SmarcelATF_TC_HEAD(length, tc) 326240116Smarcel{ 327240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length"); 328240116Smarcel} 329240116SmarcelATF_TC_BODY(length, tc) 330240116Smarcel{ 331240116Smarcel size_t i; 332240116Smarcel 333240116Smarcel for (i = 0; i < 8192; i++) { 334240116Smarcel atf_dynstr_t str; 335240116Smarcel RE(atf_dynstr_init_rep(&str, i, 'a')); 336240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_length(&str), i); 337240116Smarcel atf_dynstr_fini(&str); 338240116Smarcel } 339240116Smarcel} 340240116Smarcel 341240116SmarcelATF_TC(rfind_ch); 342240116SmarcelATF_TC_HEAD(rfind_ch, tc) 343240116Smarcel{ 344240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the method to locate the first " 345240116Smarcel "occurrence of a character starting from the end"); 346240116Smarcel} 347240116SmarcelATF_TC_BODY(rfind_ch, tc) 348240116Smarcel{ 349240116Smarcel atf_dynstr_t str; 350240116Smarcel 351240116Smarcel RE(atf_dynstr_init_fmt(&str, "Foo1/Bar2/,.Baz")); 352240116Smarcel 353240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '\0'), atf_dynstr_npos); 354240116Smarcel 355240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '0'), atf_dynstr_npos); 356240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'b'), atf_dynstr_npos); 357240116Smarcel 358240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'F'), 0); 359240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '/'), 9); 360240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'a'), 13); 361240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'z'), 14); 362240116Smarcel 363240116Smarcel atf_dynstr_fini(&str); 364240116Smarcel} 365240116Smarcel 366240116Smarcel/* 367240116Smarcel * Modifiers. 368240116Smarcel */ 369240116Smarcel 370240116Smarcelstatic 371240116Smarcelvoid 372240116Smarcelcheck_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...)) 373240116Smarcel{ 374240116Smarcel const size_t maxlen = 8192; 375240116Smarcel char buf[maxlen + 1]; 376240116Smarcel size_t i; 377240116Smarcel atf_dynstr_t str; 378240116Smarcel 379240116Smarcel printf("Appending with plain string\n"); 380240116Smarcel buf[0] = '\0'; 381240116Smarcel RE(atf_dynstr_init(&str)); 382240116Smarcel for (i = 0; i < maxlen; i++) { 383240116Smarcel if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 384240116Smarcel fprintf(stderr, "Failed at iteration %zd\n", i); 385240116Smarcel atf_tc_fail("Failed to append character at iteration %zd", i); 386240116Smarcel } 387240116Smarcel 388240116Smarcel RE(append(&str, "a")); 389240116Smarcel strcat(buf, "a"); 390240116Smarcel } 391240116Smarcel atf_dynstr_fini(&str); 392240116Smarcel 393240116Smarcel printf("Appending with formatted string\n"); 394240116Smarcel buf[0] = '\0'; 395240116Smarcel RE(atf_dynstr_init(&str)); 396240116Smarcel for (i = 0; i < maxlen; i++) { 397240116Smarcel if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 398240116Smarcel fprintf(stderr, "Failed at iteration %zd\n", i); 399240116Smarcel atf_tc_fail("Failed to append character at iteration %zd", i); 400240116Smarcel } 401240116Smarcel 402240116Smarcel RE(append(&str, "%s", "a")); 403240116Smarcel strcat(buf, "a"); 404240116Smarcel } 405240116Smarcel atf_dynstr_fini(&str); 406240116Smarcel} 407240116Smarcel 408240116Smarcelstatic 409240116Smarcelatf_error_t 410240116Smarcelappend_ap_aux(atf_dynstr_t *str, const char *fmt, ...) 411240116Smarcel{ 412240116Smarcel va_list ap; 413240116Smarcel atf_error_t err; 414240116Smarcel 415240116Smarcel va_start(ap, fmt); 416240116Smarcel err = atf_dynstr_append_ap(str, fmt, ap); 417240116Smarcel va_end(ap); 418240116Smarcel 419240116Smarcel return err; 420240116Smarcel} 421240116Smarcel 422240116SmarcelATF_TC(append_ap); 423240116SmarcelATF_TC_HEAD(append_ap, tc) 424240116Smarcel{ 425240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks that appending a string to " 426240116Smarcel "another one works"); 427240116Smarcel} 428240116SmarcelATF_TC_BODY(append_ap, tc) 429240116Smarcel{ 430240116Smarcel check_append(append_ap_aux); 431240116Smarcel} 432240116Smarcel 433240116SmarcelATF_TC(append_fmt); 434240116SmarcelATF_TC_HEAD(append_fmt, tc) 435240116Smarcel{ 436240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks that appending a string to " 437240116Smarcel "another one works"); 438240116Smarcel} 439240116SmarcelATF_TC_BODY(append_fmt, tc) 440240116Smarcel{ 441240116Smarcel check_append(atf_dynstr_append_fmt); 442240116Smarcel} 443240116Smarcel 444240116SmarcelATF_TC(clear); 445240116SmarcelATF_TC_HEAD(clear, tc) 446240116Smarcel{ 447240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks clearing a string"); 448240116Smarcel} 449240116SmarcelATF_TC_BODY(clear, tc) 450240116Smarcel{ 451240116Smarcel atf_dynstr_t str; 452240116Smarcel 453240116Smarcel printf("Clear an empty string\n"); 454240116Smarcel RE(atf_dynstr_init(&str)); 455240116Smarcel atf_dynstr_clear(&str); 456240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); 457240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 458240116Smarcel atf_dynstr_fini(&str); 459240116Smarcel 460240116Smarcel printf("Clear a non-empty string\n"); 461240116Smarcel RE(atf_dynstr_init_fmt(&str, "Not empty")); 462240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_length(&str), strlen("Not empty")); 463240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Not empty") == 0); 464240116Smarcel atf_dynstr_clear(&str); 465240116Smarcel ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0); 466240116Smarcel ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0); 467240116Smarcel atf_dynstr_fini(&str); 468240116Smarcel} 469240116Smarcel 470240116Smarcelstatic 471240116Smarcelvoid 472240116Smarcelcheck_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...)) 473240116Smarcel{ 474240116Smarcel const size_t maxlen = 8192; 475240116Smarcel char buf[maxlen + 1]; 476240116Smarcel size_t i; 477240116Smarcel atf_dynstr_t str; 478240116Smarcel 479240116Smarcel printf("Prepending with plain string\n"); 480240116Smarcel buf[0] = '\0'; 481240116Smarcel RE(atf_dynstr_init(&str)); 482240116Smarcel for (i = 0; i < maxlen; i++) { 483240116Smarcel if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 484240116Smarcel fprintf(stderr, "Failed at iteration %zd\n", i); 485240116Smarcel atf_tc_fail("Failed to prepend character at iteration %zd", i); 486240116Smarcel } 487240116Smarcel 488240116Smarcel memmove(buf + 1, buf, i + 1); 489240116Smarcel if (i % 2 == 0) { 490240116Smarcel RE(prepend(&str, "%s", "a")); 491240116Smarcel buf[0] = 'a'; 492240116Smarcel } else { 493240116Smarcel RE(prepend(&str, "%s", "b")); 494240116Smarcel buf[0] = 'b'; 495240116Smarcel } 496240116Smarcel } 497240116Smarcel atf_dynstr_fini(&str); 498240116Smarcel 499240116Smarcel printf("Prepending with formatted string\n"); 500240116Smarcel buf[0] = '\0'; 501240116Smarcel RE(atf_dynstr_init(&str)); 502240116Smarcel for (i = 0; i < maxlen; i++) { 503240116Smarcel if (strcmp(atf_dynstr_cstring(&str), buf) != 0) { 504240116Smarcel fprintf(stderr, "Failed at iteration %zd\n", i); 505240116Smarcel atf_tc_fail("Failed to prepend character at iteration %zd", i); 506240116Smarcel } 507240116Smarcel 508240116Smarcel memmove(buf + 1, buf, i + 1); 509240116Smarcel if (i % 2 == 0) { 510240116Smarcel RE(prepend(&str, "%s", "a")); 511240116Smarcel buf[0] = 'a'; 512240116Smarcel } else { 513240116Smarcel RE(prepend(&str, "%s", "b")); 514240116Smarcel buf[0] = 'b'; 515240116Smarcel } 516240116Smarcel } 517240116Smarcel atf_dynstr_fini(&str); 518240116Smarcel} 519240116Smarcel 520240116Smarcelstatic 521240116Smarcelatf_error_t 522240116Smarcelprepend_ap_aux(atf_dynstr_t *str, const char *fmt, ...) 523240116Smarcel{ 524240116Smarcel va_list ap; 525240116Smarcel atf_error_t err; 526240116Smarcel 527240116Smarcel va_start(ap, fmt); 528240116Smarcel err = atf_dynstr_prepend_ap(str, fmt, ap); 529240116Smarcel va_end(ap); 530240116Smarcel 531240116Smarcel return err; 532240116Smarcel} 533240116Smarcel 534240116SmarcelATF_TC(prepend_ap); 535240116SmarcelATF_TC_HEAD(prepend_ap, tc) 536240116Smarcel{ 537240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to " 538240116Smarcel "another one works"); 539240116Smarcel} 540240116SmarcelATF_TC_BODY(prepend_ap, tc) 541240116Smarcel{ 542240116Smarcel check_prepend(prepend_ap_aux); 543240116Smarcel} 544240116Smarcel 545240116SmarcelATF_TC(prepend_fmt); 546240116SmarcelATF_TC_HEAD(prepend_fmt, tc) 547240116Smarcel{ 548240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to " 549240116Smarcel "another one works"); 550240116Smarcel} 551240116SmarcelATF_TC_BODY(prepend_fmt, tc) 552240116Smarcel{ 553240116Smarcel check_prepend(atf_dynstr_prepend_fmt); 554240116Smarcel} 555240116Smarcel 556240116Smarcel/* 557240116Smarcel * Operators. 558240116Smarcel */ 559240116Smarcel 560240116SmarcelATF_TC(equal_cstring); 561240116SmarcelATF_TC_HEAD(equal_cstring, tc) 562240116Smarcel{ 563240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring " 564240116Smarcel "function"); 565240116Smarcel} 566240116SmarcelATF_TC_BODY(equal_cstring, tc) 567240116Smarcel{ 568240116Smarcel atf_dynstr_t str; 569240116Smarcel 570240116Smarcel RE(atf_dynstr_init(&str)); 571240116Smarcel ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "")); 572240116Smarcel ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test")); 573240116Smarcel atf_dynstr_fini(&str); 574240116Smarcel 575240116Smarcel RE(atf_dynstr_init_fmt(&str, "Test")); 576240116Smarcel ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "Test")); 577240116Smarcel ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "")); 578240116Smarcel ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Tes")); 579240116Smarcel ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test ")); 580240116Smarcel atf_dynstr_fini(&str); 581240116Smarcel} 582240116Smarcel 583240116SmarcelATF_TC(equal_dynstr); 584240116SmarcelATF_TC_HEAD(equal_dynstr, tc) 585240116Smarcel{ 586240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr " 587240116Smarcel "function"); 588240116Smarcel} 589240116SmarcelATF_TC_BODY(equal_dynstr, tc) 590240116Smarcel{ 591240116Smarcel atf_dynstr_t str, str2; 592240116Smarcel 593240116Smarcel RE(atf_dynstr_init(&str)); 594240116Smarcel RE(atf_dynstr_init_fmt(&str2, "Test")); 595240116Smarcel ATF_REQUIRE( atf_equal_dynstr_dynstr(&str, &str)); 596240116Smarcel ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2)); 597240116Smarcel atf_dynstr_fini(&str2); 598240116Smarcel atf_dynstr_fini(&str); 599240116Smarcel} 600240116Smarcel 601240116Smarcel/* --------------------------------------------------------------------- 602240116Smarcel * Main. 603240116Smarcel * --------------------------------------------------------------------- */ 604240116Smarcel 605240116SmarcelATF_TP_ADD_TCS(tp) 606240116Smarcel{ 607240116Smarcel /* Constructors and destructors. */ 608240116Smarcel ATF_TP_ADD_TC(tp, init); 609240116Smarcel ATF_TP_ADD_TC(tp, init_ap); 610240116Smarcel ATF_TP_ADD_TC(tp, init_fmt); 611240116Smarcel ATF_TP_ADD_TC(tp, init_raw); 612240116Smarcel ATF_TP_ADD_TC(tp, init_rep); 613240116Smarcel ATF_TP_ADD_TC(tp, init_substr); 614240116Smarcel ATF_TP_ADD_TC(tp, copy); 615240116Smarcel ATF_TP_ADD_TC(tp, fini_disown); 616240116Smarcel 617240116Smarcel /* Getters. */ 618240116Smarcel ATF_TP_ADD_TC(tp, cstring); 619240116Smarcel ATF_TP_ADD_TC(tp, length); 620240116Smarcel ATF_TP_ADD_TC(tp, rfind_ch); 621240116Smarcel 622240116Smarcel /* Modifiers. */ 623240116Smarcel ATF_TP_ADD_TC(tp, append_ap); 624240116Smarcel ATF_TP_ADD_TC(tp, append_fmt); 625240116Smarcel ATF_TP_ADD_TC(tp, clear); 626240116Smarcel ATF_TP_ADD_TC(tp, prepend_ap); 627240116Smarcel ATF_TP_ADD_TC(tp, prepend_fmt); 628240116Smarcel 629240116Smarcel /* Operators. */ 630240116Smarcel ATF_TP_ADD_TC(tp, equal_cstring); 631240116Smarcel ATF_TP_ADD_TC(tp, equal_dynstr); 632240116Smarcel 633240116Smarcel return atf_no_error(); 634240116Smarcel} 635