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