Path: blob/main/contrib/atf/atf-c/detail/dynstr_test.c
39507 views
/* Copyright (c) 2008 The NetBSD Foundation, Inc.1* All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6* 1. Redistributions of source code must retain the above copyright7* notice, this list of conditions and the following disclaimer.8* 2. Redistributions in binary form must reproduce the above copyright9* notice, this list of conditions and the following disclaimer in the10* documentation and/or other materials provided with the distribution.11*12* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND13* CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,14* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF15* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16* IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY17* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE19* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS20* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER21* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR22* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN23* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */2425#include "atf-c/detail/dynstr.h"2627#include <stdarg.h>28#include <stdint.h>29#include <stdio.h>30#include <stdlib.h>31#include <string.h>3233#include <atf-c.h>3435#include "atf-c/detail/test_helpers.h"3637/* ---------------------------------------------------------------------38* Tests for the "atf_dynstr" type.39* --------------------------------------------------------------------- */4041/*42* Constructors and destructors.43*/4445ATF_TC(init);46ATF_TC_HEAD(init, tc)47{48atf_tc_set_md_var(tc, "descr", "Checks the empty constructor");49}50ATF_TC_BODY(init, tc)51{52atf_dynstr_t str;5354RE(atf_dynstr_init(&str));55ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);56ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);57atf_dynstr_fini(&str);58}5960static61void62init_fmt(atf_dynstr_t *str, const char *fmt, ...)63{64va_list ap;6566va_start(ap, fmt);67RE(atf_dynstr_init_ap(str, fmt, ap));68va_end(ap);69}7071ATF_TC(init_ap);72ATF_TC_HEAD(init_ap, tc)73{74atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using "75"a va_list argument");76}77ATF_TC_BODY(init_ap, tc)78{79atf_dynstr_t str;8081init_fmt(&str, "String 1");82ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);83atf_dynstr_fini(&str);8485init_fmt(&str, "String %d", 2);86ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);87atf_dynstr_fini(&str);8889init_fmt(&str, "%s %d", "String", 3);90ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0);91atf_dynstr_fini(&str);9293init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ", "be ", "a ",94"large ", "string ", "aaaabbbbccccdddd");95ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str),96"This should be a large string "97"aaaabbbbccccdddd") == 0);98atf_dynstr_fini(&str);99}100101ATF_TC(init_fmt);102ATF_TC_HEAD(init_fmt, tc)103{104atf_tc_set_md_var(tc, "descr", "Checks the formatted constructor using "105"a variable list of parameters");106}107ATF_TC_BODY(init_fmt, tc)108{109atf_dynstr_t str;110111RE(atf_dynstr_init_fmt(&str, "String 1"));112ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);113atf_dynstr_fini(&str);114115RE(atf_dynstr_init_fmt(&str, "String %d", 2));116ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);117atf_dynstr_fini(&str);118119RE(atf_dynstr_init_fmt(&str, "%s %d", "String", 3));120ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 3") == 0);121atf_dynstr_fini(&str);122123RE(atf_dynstr_init_fmt(&str, "%s%s%s%s%s%s%s", "This ", "should ",124"be ", "a ", "large ", "string ",125"aaaabbbbccccdddd"));126ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str),127"This should be a large string "128"aaaabbbbccccdddd") == 0);129atf_dynstr_fini(&str);130}131132ATF_TC(init_raw);133ATF_TC_HEAD(init_raw, tc)134{135atf_tc_set_md_var(tc, "descr", "Checks the construction of a string "136"using a raw memory pointer");137}138ATF_TC_BODY(init_raw, tc)139{140const char *src = "String 1, String 2";141atf_dynstr_t str;142143RE(atf_dynstr_init_raw(&str, src, 0));144ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);145atf_dynstr_fini(&str);146147RE(atf_dynstr_init_raw(&str, src, 8));148ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 1") == 0);149atf_dynstr_fini(&str);150151RE(atf_dynstr_init_raw(&str, src + 10, 8));152ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String 2") == 0);153atf_dynstr_fini(&str);154155RE(atf_dynstr_init_raw(&str, "String\0Lost", 11));156ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "String") == 0);157atf_dynstr_fini(&str);158159{160atf_error_t err = atf_dynstr_init_raw(&str, "NULL", SIZE_MAX - 1);161ATF_REQUIRE(atf_is_error(err));162ATF_REQUIRE(atf_error_is(err, "no_memory"));163atf_error_free(err);164}165}166167ATF_TC(init_rep);168ATF_TC_HEAD(init_rep, tc)169{170atf_tc_set_md_var(tc, "descr", "Checks the construction of a string by "171"repeating characters");172}173ATF_TC_BODY(init_rep, tc)174{175const size_t maxlen = 8192;176char buf[maxlen + 1];177size_t i;178179buf[0] = '\0';180181for (i = 0; i < maxlen; i++) {182atf_dynstr_t str;183184RE(atf_dynstr_init_rep(&str, i, 'a'));185186if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {187fprintf(stderr, "Failed at iteration %zd\n", i);188atf_tc_fail("Failed to construct dynstr by repeating %zd "189"times the '%c' character", i, 'a');190}191192atf_dynstr_fini(&str);193194strcat(buf, "a");195}196197{198atf_dynstr_t str;199atf_error_t err;200201err = atf_dynstr_init_rep(&str, SIZE_MAX, 'a');202ATF_REQUIRE(atf_is_error(err));203ATF_REQUIRE(atf_error_is(err, "no_memory"));204atf_error_free(err);205206err = atf_dynstr_init_rep(&str, SIZE_MAX - 1, 'a');207ATF_REQUIRE(atf_is_error(err));208ATF_REQUIRE(atf_error_is(err, "no_memory"));209atf_error_free(err);210}211}212213ATF_TC(init_substr);214ATF_TC_HEAD(init_substr, tc)215{216atf_tc_set_md_var(tc, "descr", "Checks the construction of a string "217"using a substring of another one");218}219ATF_TC_BODY(init_substr, tc)220{221atf_dynstr_t src;222atf_dynstr_t str;223224RE(atf_dynstr_init_fmt(&src, "Str 1, Str 2"));225226RE(atf_dynstr_init_substr(&str, &src, 0, 0));227ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);228atf_dynstr_fini(&str);229230RE(atf_dynstr_init_substr(&str, &src, 0, atf_dynstr_npos));231ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0);232atf_dynstr_fini(&str);233234RE(atf_dynstr_init_substr(&str, &src, 0, 100));235ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1, Str 2") == 0);236atf_dynstr_fini(&str);237238RE(atf_dynstr_init_substr(&str, &src, 0, 5));239ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 1") == 0);240atf_dynstr_fini(&str);241242RE(atf_dynstr_init_substr(&str, &src, 100, atf_dynstr_npos));243ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);244atf_dynstr_fini(&str);245246RE(atf_dynstr_init_substr(&str, &src, 7, atf_dynstr_npos));247ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Str 2") == 0);248atf_dynstr_fini(&str);249250atf_dynstr_fini(&src);251}252253ATF_TC(copy);254ATF_TC_HEAD(copy, tc)255{256atf_tc_set_md_var(tc, "descr", "Checks the atf_dynstr_copy constructor");257}258ATF_TC_BODY(copy, tc)259{260atf_dynstr_t str, str2;261262RE(atf_dynstr_init_fmt(&str, "Test string"));263RE(atf_dynstr_copy(&str2, &str));264265ATF_REQUIRE(atf_equal_dynstr_dynstr(&str, &str2));266267RE(atf_dynstr_append_fmt(&str2, " non-shared text"));268269ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2));270271atf_dynstr_fini(&str2);272atf_dynstr_fini(&str);273}274275ATF_TC(fini_disown);276ATF_TC_HEAD(fini_disown, tc)277{278atf_tc_set_md_var(tc, "descr", "Checks grabbing ownership of the "279"internal plain C string");280}281ATF_TC_BODY(fini_disown, tc)282{283const char *cstr;284char *cstr2;285atf_dynstr_t str;286287RE(atf_dynstr_init_fmt(&str, "Test string 1"));288cstr = atf_dynstr_cstring(&str);289cstr2 = atf_dynstr_fini_disown(&str);290291ATF_REQUIRE_EQ(cstr, cstr2);292free(cstr2);293}294295/*296* Getters.297*/298299ATF_TC(cstring);300ATF_TC_HEAD(cstring, tc)301{302atf_tc_set_md_var(tc, "descr", "Checks the method to obtain a plain C "303"string");304}305ATF_TC_BODY(cstring, tc)306{307const char *cstr;308atf_dynstr_t str;309310RE(atf_dynstr_init_fmt(&str, "Test string 1"));311cstr = atf_dynstr_cstring(&str);312ATF_REQUIRE(cstr != NULL);313ATF_REQUIRE(strcmp(cstr, "Test string 1") == 0);314atf_dynstr_fini(&str);315316RE(atf_dynstr_init_fmt(&str, "Test string 2"));317cstr = atf_dynstr_cstring(&str);318ATF_REQUIRE(cstr != NULL);319ATF_REQUIRE(strcmp(cstr, "Test string 2") == 0);320atf_dynstr_fini(&str);321}322323ATF_TC(length);324ATF_TC_HEAD(length, tc)325{326atf_tc_set_md_var(tc, "descr", "Checks the method to obtain the length");327}328ATF_TC_BODY(length, tc)329{330size_t i;331332for (i = 0; i < 8192; i++) {333atf_dynstr_t str;334RE(atf_dynstr_init_rep(&str, i, 'a'));335ATF_REQUIRE_EQ(atf_dynstr_length(&str), i);336atf_dynstr_fini(&str);337}338}339340ATF_TC(rfind_ch);341ATF_TC_HEAD(rfind_ch, tc)342{343atf_tc_set_md_var(tc, "descr", "Checks the method to locate the first "344"occurrence of a character starting from the end");345}346ATF_TC_BODY(rfind_ch, tc)347{348atf_dynstr_t str;349350RE(atf_dynstr_init_fmt(&str, "Foo1/Bar2/,.Baz"));351352ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '\0'), atf_dynstr_npos);353354ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '0'), atf_dynstr_npos);355ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'b'), atf_dynstr_npos);356357ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'F'), 0);358ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, '/'), 9);359ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'a'), 13);360ATF_REQUIRE_EQ(atf_dynstr_rfind_ch(&str, 'z'), 14);361362atf_dynstr_fini(&str);363}364365/*366* Modifiers.367*/368369static370void371check_append(atf_error_t (*append)(atf_dynstr_t *, const char *, ...))372{373const size_t maxlen = 8192;374char buf[maxlen + 1];375size_t i;376atf_dynstr_t str;377378printf("Appending with plain string\n");379buf[0] = '\0';380RE(atf_dynstr_init(&str));381for (i = 0; i < maxlen; i++) {382if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {383fprintf(stderr, "Failed at iteration %zd\n", i);384atf_tc_fail("Failed to append character at iteration %zd", i);385}386387RE(append(&str, "a"));388strcat(buf, "a");389}390atf_dynstr_fini(&str);391392printf("Appending with formatted string\n");393buf[0] = '\0';394RE(atf_dynstr_init(&str));395for (i = 0; i < maxlen; i++) {396if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {397fprintf(stderr, "Failed at iteration %zd\n", i);398atf_tc_fail("Failed to append character at iteration %zd", i);399}400401RE(append(&str, "%s", "a"));402strcat(buf, "a");403}404atf_dynstr_fini(&str);405}406407static408atf_error_t409append_ap_aux(atf_dynstr_t *str, const char *fmt, ...)410{411va_list ap;412atf_error_t err;413414va_start(ap, fmt);415err = atf_dynstr_append_ap(str, fmt, ap);416va_end(ap);417418return err;419}420421ATF_TC(append_ap);422ATF_TC_HEAD(append_ap, tc)423{424atf_tc_set_md_var(tc, "descr", "Checks that appending a string to "425"another one works");426}427ATF_TC_BODY(append_ap, tc)428{429check_append(append_ap_aux);430}431432ATF_TC(append_fmt);433ATF_TC_HEAD(append_fmt, tc)434{435atf_tc_set_md_var(tc, "descr", "Checks that appending a string to "436"another one works");437}438ATF_TC_BODY(append_fmt, tc)439{440check_append(atf_dynstr_append_fmt);441}442443ATF_TC(clear);444ATF_TC_HEAD(clear, tc)445{446atf_tc_set_md_var(tc, "descr", "Checks clearing a string");447}448ATF_TC_BODY(clear, tc)449{450atf_dynstr_t str;451452printf("Clear an empty string\n");453RE(atf_dynstr_init(&str));454atf_dynstr_clear(&str);455ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);456ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);457atf_dynstr_fini(&str);458459printf("Clear a non-empty string\n");460RE(atf_dynstr_init_fmt(&str, "Not empty"));461ATF_REQUIRE_EQ(atf_dynstr_length(&str), strlen("Not empty"));462ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "Not empty") == 0);463atf_dynstr_clear(&str);464ATF_REQUIRE_EQ(atf_dynstr_length(&str), 0);465ATF_REQUIRE(strcmp(atf_dynstr_cstring(&str), "") == 0);466atf_dynstr_fini(&str);467}468469static470void471check_prepend(atf_error_t (*prepend)(atf_dynstr_t *, const char *, ...))472{473const size_t maxlen = 8192;474char buf[maxlen + 1];475size_t i;476atf_dynstr_t str;477478printf("Prepending with plain string\n");479buf[0] = '\0';480RE(atf_dynstr_init(&str));481for (i = 0; i < maxlen; i++) {482if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {483fprintf(stderr, "Failed at iteration %zd\n", i);484atf_tc_fail("Failed to prepend character at iteration %zd", i);485}486487memmove(buf + 1, buf, i + 1);488if (i % 2 == 0) {489RE(prepend(&str, "%s", "a"));490buf[0] = 'a';491} else {492RE(prepend(&str, "%s", "b"));493buf[0] = 'b';494}495}496atf_dynstr_fini(&str);497498printf("Prepending with formatted string\n");499buf[0] = '\0';500RE(atf_dynstr_init(&str));501for (i = 0; i < maxlen; i++) {502if (strcmp(atf_dynstr_cstring(&str), buf) != 0) {503fprintf(stderr, "Failed at iteration %zd\n", i);504atf_tc_fail("Failed to prepend character at iteration %zd", i);505}506507memmove(buf + 1, buf, i + 1);508if (i % 2 == 0) {509RE(prepend(&str, "%s", "a"));510buf[0] = 'a';511} else {512RE(prepend(&str, "%s", "b"));513buf[0] = 'b';514}515}516atf_dynstr_fini(&str);517}518519static520atf_error_t521prepend_ap_aux(atf_dynstr_t *str, const char *fmt, ...)522{523va_list ap;524atf_error_t err;525526va_start(ap, fmt);527err = atf_dynstr_prepend_ap(str, fmt, ap);528va_end(ap);529530return err;531}532533ATF_TC(prepend_ap);534ATF_TC_HEAD(prepend_ap, tc)535{536atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to "537"another one works");538}539ATF_TC_BODY(prepend_ap, tc)540{541check_prepend(prepend_ap_aux);542}543544ATF_TC(prepend_fmt);545ATF_TC_HEAD(prepend_fmt, tc)546{547atf_tc_set_md_var(tc, "descr", "Checks that prepending a string to "548"another one works");549}550ATF_TC_BODY(prepend_fmt, tc)551{552check_prepend(atf_dynstr_prepend_fmt);553}554555/*556* Operators.557*/558559ATF_TC(equal_cstring);560ATF_TC_HEAD(equal_cstring, tc)561{562atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_cstring "563"function");564}565ATF_TC_BODY(equal_cstring, tc)566{567atf_dynstr_t str;568569RE(atf_dynstr_init(&str));570ATF_REQUIRE( atf_equal_dynstr_cstring(&str, ""));571ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test"));572atf_dynstr_fini(&str);573574RE(atf_dynstr_init_fmt(&str, "Test"));575ATF_REQUIRE( atf_equal_dynstr_cstring(&str, "Test"));576ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, ""));577ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Tes"));578ATF_REQUIRE(!atf_equal_dynstr_cstring(&str, "Test "));579atf_dynstr_fini(&str);580}581582ATF_TC(equal_dynstr);583ATF_TC_HEAD(equal_dynstr, tc)584{585atf_tc_set_md_var(tc, "descr", "Checks the atf_equal_dynstr_dynstr "586"function");587}588ATF_TC_BODY(equal_dynstr, tc)589{590atf_dynstr_t str, str2;591592RE(atf_dynstr_init(&str));593RE(atf_dynstr_init_fmt(&str2, "Test"));594ATF_REQUIRE( atf_equal_dynstr_dynstr(&str, &str));595ATF_REQUIRE(!atf_equal_dynstr_dynstr(&str, &str2));596atf_dynstr_fini(&str2);597atf_dynstr_fini(&str);598}599600/* ---------------------------------------------------------------------601* Main.602* --------------------------------------------------------------------- */603604ATF_TP_ADD_TCS(tp)605{606/* Constructors and destructors. */607ATF_TP_ADD_TC(tp, init);608ATF_TP_ADD_TC(tp, init_ap);609ATF_TP_ADD_TC(tp, init_fmt);610ATF_TP_ADD_TC(tp, init_raw);611ATF_TP_ADD_TC(tp, init_rep);612ATF_TP_ADD_TC(tp, init_substr);613ATF_TP_ADD_TC(tp, copy);614ATF_TP_ADD_TC(tp, fini_disown);615616/* Getters. */617ATF_TP_ADD_TC(tp, cstring);618ATF_TP_ADD_TC(tp, length);619ATF_TP_ADD_TC(tp, rfind_ch);620621/* Modifiers. */622ATF_TP_ADD_TC(tp, append_ap);623ATF_TP_ADD_TC(tp, append_fmt);624ATF_TP_ADD_TC(tp, clear);625ATF_TP_ADD_TC(tp, prepend_ap);626ATF_TP_ADD_TC(tp, prepend_fmt);627628/* Operators. */629ATF_TP_ADD_TC(tp, equal_cstring);630ATF_TP_ADD_TC(tp, equal_dynstr);631632return atf_no_error();633}634635636