1273929Sjmmv/* 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 24273929Sjmmv * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 25240116Smarcel 26273929Sjmmv#include "atf-c/detail/text.h" 27273929Sjmmv 28240116Smarcel#include <stdio.h> 29240116Smarcel#include <stdlib.h> 30240116Smarcel#include <string.h> 31240116Smarcel 32240116Smarcel#include <atf-c.h> 33240116Smarcel 34273929Sjmmv#include "atf-c/detail/sanity.h" 35273929Sjmmv#include "atf-c/detail/test_helpers.h" 36240116Smarcel 37240116Smarcel/* --------------------------------------------------------------------- 38240116Smarcel * Auxiliary functions. 39240116Smarcel * --------------------------------------------------------------------- */ 40240116Smarcel 41240116Smarcel#define REQUIRE_ERROR(exp) \ 42240116Smarcel do { \ 43240116Smarcel atf_error_t err = exp; \ 44240116Smarcel ATF_REQUIRE(atf_is_error(err)); \ 45240116Smarcel atf_error_free(err); \ 46240116Smarcel } while (0) 47240116Smarcel 48240116Smarcelstatic 49240116Smarcelsize_t 50240116Smarcelarray_size(const char *words[]) 51240116Smarcel{ 52240116Smarcel size_t count; 53240116Smarcel const char **word; 54240116Smarcel 55240116Smarcel count = 0; 56240116Smarcel for (word = words; *word != NULL; word++) 57240116Smarcel count++; 58240116Smarcel 59240116Smarcel return count; 60240116Smarcel} 61240116Smarcel 62240116Smarcelstatic 63240116Smarcelvoid 64240116Smarcelcheck_split(const char *str, const char *delim, const char *words[]) 65240116Smarcel{ 66240116Smarcel atf_list_t list; 67240116Smarcel const char **word; 68240116Smarcel size_t i; 69240116Smarcel 70240116Smarcel printf("Splitting '%s' with delimiter '%s'\n", str, delim); 71240116Smarcel CE(atf_text_split(str, delim, &list)); 72240116Smarcel 73240116Smarcel printf("Expecting %zd words\n", array_size(words)); 74240116Smarcel ATF_CHECK_EQ(atf_list_size(&list), array_size(words)); 75240116Smarcel 76240116Smarcel for (word = words, i = 0; *word != NULL; word++, i++) { 77240116Smarcel printf("Word at position %zd should be '%s'\n", i, words[i]); 78240116Smarcel ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]); 79240116Smarcel } 80240116Smarcel 81240116Smarcel atf_list_fini(&list); 82240116Smarcel} 83240116Smarcel 84240116Smarcelstatic 85240116Smarcelatf_error_t 86240116Smarcelword_acum(const char *word, void *data) 87240116Smarcel{ 88240116Smarcel char *acum = data; 89240116Smarcel 90240116Smarcel strcat(acum, word); 91240116Smarcel 92240116Smarcel return atf_no_error(); 93240116Smarcel} 94240116Smarcel 95240116Smarcelstatic 96240116Smarcelatf_error_t 97240116Smarcelword_count(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 98240116Smarcel{ 99240116Smarcel size_t *counter = data; 100240116Smarcel 101240116Smarcel (*counter)++; 102240116Smarcel 103240116Smarcel return atf_no_error(); 104240116Smarcel} 105240116Smarcel 106240116Smarcelstruct fail_at { 107240116Smarcel int failpos; 108240116Smarcel int curpos; 109240116Smarcel}; 110240116Smarcel 111240116Smarcelstatic 112240116Smarcelatf_error_t 113240116Smarcelword_fail_at(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 114240116Smarcel{ 115240116Smarcel struct fail_at *fa = data; 116240116Smarcel atf_error_t err; 117240116Smarcel 118240116Smarcel if (fa->failpos == fa->curpos) 119240116Smarcel err = atf_no_memory_error(); /* Just a random error. */ 120240116Smarcel else { 121240116Smarcel fa->curpos++; 122240116Smarcel err = atf_no_error(); 123240116Smarcel } 124240116Smarcel 125240116Smarcel return err; 126240116Smarcel} 127240116Smarcel 128240116Smarcel/* --------------------------------------------------------------------- 129240116Smarcel * Test cases for the free functions. 130240116Smarcel * --------------------------------------------------------------------- */ 131240116Smarcel 132240116SmarcelATF_TC(for_each_word); 133240116SmarcelATF_TC_HEAD(for_each_word, tc) 134240116Smarcel{ 135240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word" 136240116Smarcel "function"); 137240116Smarcel} 138240116SmarcelATF_TC_BODY(for_each_word, tc) 139240116Smarcel{ 140240116Smarcel size_t cnt; 141240116Smarcel char acum[1024]; 142240116Smarcel 143240116Smarcel cnt = 0; 144240116Smarcel strcpy(acum, ""); 145240116Smarcel RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt)); 146240116Smarcel RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum)); 147240116Smarcel ATF_REQUIRE(cnt == 3); 148240116Smarcel ATF_REQUIRE(strcmp(acum, "123") == 0); 149240116Smarcel 150240116Smarcel cnt = 0; 151240116Smarcel strcpy(acum, ""); 152240116Smarcel RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt)); 153240116Smarcel RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum)); 154240116Smarcel ATF_REQUIRE(cnt == 1); 155240116Smarcel ATF_REQUIRE(strcmp(acum, "1 2 3") == 0); 156240116Smarcel 157240116Smarcel cnt = 0; 158240116Smarcel strcpy(acum, ""); 159240116Smarcel RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt)); 160240116Smarcel RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum)); 161240116Smarcel ATF_REQUIRE(cnt == 5); 162240116Smarcel ATF_REQUIRE(strcmp(acum, "12345") == 0); 163240116Smarcel 164240116Smarcel cnt = 0; 165240116Smarcel strcpy(acum, ""); 166240116Smarcel RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt)); 167240116Smarcel RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum)); 168240116Smarcel ATF_REQUIRE(cnt == 5); 169240116Smarcel ATF_REQUIRE(strcmp(acum, "12345") == 0); 170240116Smarcel 171240116Smarcel { 172240116Smarcel struct fail_at fa; 173240116Smarcel fa.failpos = 3; 174240116Smarcel fa.curpos = 0; 175240116Smarcel atf_error_t err = atf_text_for_each_word("a b c d e", " ", 176240116Smarcel word_fail_at, &fa); 177240116Smarcel ATF_REQUIRE(atf_is_error(err)); 178240116Smarcel ATF_REQUIRE(atf_error_is(err, "no_memory")); 179240116Smarcel ATF_REQUIRE(fa.curpos == 3); 180240116Smarcel atf_error_free(err); 181240116Smarcel } 182240116Smarcel} 183240116Smarcel 184240116SmarcelATF_TC(format); 185240116SmarcelATF_TC_HEAD(format, tc) 186240116Smarcel{ 187240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 188240116Smarcel "strings using a variable parameters list"); 189240116Smarcel} 190240116SmarcelATF_TC_BODY(format, tc) 191240116Smarcel{ 192240116Smarcel char *str; 193240116Smarcel atf_error_t err; 194240116Smarcel 195240116Smarcel err = atf_text_format(&str, "%s %s %d", "Test", "string", 1); 196240116Smarcel ATF_REQUIRE(!atf_is_error(err)); 197240116Smarcel ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 198240116Smarcel free(str); 199240116Smarcel} 200240116Smarcel 201240116Smarcelstatic 202240116Smarcelvoid 203240116Smarcelformat_ap(char **dest, const char *fmt, ...) 204240116Smarcel{ 205240116Smarcel va_list ap; 206240116Smarcel atf_error_t err; 207240116Smarcel 208240116Smarcel va_start(ap, fmt); 209240116Smarcel err = atf_text_format_ap(dest, fmt, ap); 210240116Smarcel va_end(ap); 211240116Smarcel 212240116Smarcel ATF_REQUIRE(!atf_is_error(err)); 213240116Smarcel} 214240116Smarcel 215240116SmarcelATF_TC(format_ap); 216240116SmarcelATF_TC_HEAD(format_ap, tc) 217240116Smarcel{ 218240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 219240116Smarcel "strings using a va_list argument"); 220240116Smarcel} 221240116SmarcelATF_TC_BODY(format_ap, tc) 222240116Smarcel{ 223240116Smarcel char *str; 224240116Smarcel 225240116Smarcel format_ap(&str, "%s %s %d", "Test", "string", 1); 226240116Smarcel ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 227240116Smarcel free(str); 228240116Smarcel} 229240116Smarcel 230240116SmarcelATF_TC(split); 231240116SmarcelATF_TC_HEAD(split, tc) 232240116Smarcel{ 233240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the split function"); 234240116Smarcel} 235240116SmarcelATF_TC_BODY(split, tc) 236240116Smarcel{ 237240116Smarcel { 238240116Smarcel const char *words[] = { NULL }; 239240116Smarcel check_split("", " ", words); 240240116Smarcel } 241240116Smarcel 242240116Smarcel { 243240116Smarcel const char *words[] = { NULL }; 244240116Smarcel check_split(" ", " ", words); 245240116Smarcel } 246240116Smarcel 247240116Smarcel { 248240116Smarcel const char *words[] = { NULL }; 249240116Smarcel check_split(" ", " ", words); 250240116Smarcel } 251240116Smarcel 252240116Smarcel { 253240116Smarcel const char *words[] = { "a", "b", NULL }; 254240116Smarcel check_split("a b", " ", words); 255240116Smarcel } 256240116Smarcel 257240116Smarcel { 258240116Smarcel const char *words[] = { "a", "b", "c", "d", NULL }; 259240116Smarcel check_split("a b c d", " ", words); 260240116Smarcel } 261240116Smarcel 262240116Smarcel { 263240116Smarcel const char *words[] = { "foo", "bar", NULL }; 264240116Smarcel check_split("foo bar", " ", words); 265240116Smarcel } 266240116Smarcel 267240116Smarcel { 268240116Smarcel const char *words[] = { "foo", "bar", "baz", "foobar", NULL }; 269240116Smarcel check_split("foo bar baz foobar", " ", words); 270240116Smarcel } 271240116Smarcel 272240116Smarcel { 273240116Smarcel const char *words[] = { "foo", "bar", NULL }; 274240116Smarcel check_split(" foo bar", " ", words); 275240116Smarcel } 276240116Smarcel 277240116Smarcel { 278240116Smarcel const char *words[] = { "foo", "bar", NULL }; 279240116Smarcel check_split("foo bar", " ", words); 280240116Smarcel } 281240116Smarcel 282240116Smarcel { 283240116Smarcel const char *words[] = { "foo", "bar", NULL }; 284240116Smarcel check_split("foo bar ", " ", words); 285240116Smarcel } 286240116Smarcel 287240116Smarcel { 288240116Smarcel const char *words[] = { "foo", "bar", NULL }; 289240116Smarcel check_split(" foo bar ", " ", words); 290240116Smarcel } 291240116Smarcel} 292240116Smarcel 293240116SmarcelATF_TC(split_delims); 294240116SmarcelATF_TC_HEAD(split_delims, tc) 295240116Smarcel{ 296240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the split function using " 297240116Smarcel "different delimiters"); 298240116Smarcel} 299240116SmarcelATF_TC_BODY(split_delims, tc) 300240116Smarcel{ 301240116Smarcel 302240116Smarcel { 303240116Smarcel const char *words[] = { NULL }; 304240116Smarcel check_split("", "/", words); 305240116Smarcel } 306240116Smarcel 307240116Smarcel { 308240116Smarcel const char *words[] = { " ", NULL }; 309240116Smarcel check_split(" ", "/", words); 310240116Smarcel } 311240116Smarcel 312240116Smarcel { 313240116Smarcel const char *words[] = { " ", NULL }; 314240116Smarcel check_split(" ", "/", words); 315240116Smarcel } 316240116Smarcel 317240116Smarcel { 318240116Smarcel const char *words[] = { "a", "b", NULL }; 319240116Smarcel check_split("a/b", "/", words); 320240116Smarcel } 321240116Smarcel 322240116Smarcel { 323240116Smarcel const char *words[] = { "a", "bcd", "ef", NULL }; 324240116Smarcel check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words); 325240116Smarcel } 326240116Smarcel} 327240116Smarcel 328240116SmarcelATF_TC(to_bool); 329240116SmarcelATF_TC_HEAD(to_bool, tc) 330240116Smarcel{ 331240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function"); 332240116Smarcel} 333240116SmarcelATF_TC_BODY(to_bool, tc) 334240116Smarcel{ 335240116Smarcel bool b; 336240116Smarcel 337240116Smarcel RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b); 338240116Smarcel RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b); 339240116Smarcel RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b); 340240116Smarcel RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b); 341240116Smarcel 342240116Smarcel RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b); 343240116Smarcel RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b); 344240116Smarcel RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b); 345240116Smarcel RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b); 346240116Smarcel 347240116Smarcel b = false; 348240116Smarcel REQUIRE_ERROR(atf_text_to_bool("", &b)); 349240116Smarcel ATF_REQUIRE(!b); 350240116Smarcel b = true; 351240116Smarcel REQUIRE_ERROR(atf_text_to_bool("", &b)); 352240116Smarcel ATF_REQUIRE(b); 353240116Smarcel 354240116Smarcel b = false; 355240116Smarcel REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 356240116Smarcel ATF_REQUIRE(!b); 357240116Smarcel b = true; 358240116Smarcel REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 359240116Smarcel ATF_REQUIRE(b); 360240116Smarcel 361240116Smarcel b = false; 362240116Smarcel REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 363240116Smarcel ATF_REQUIRE(!b); 364240116Smarcel b = true; 365240116Smarcel REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 366240116Smarcel ATF_REQUIRE(b); 367240116Smarcel 368240116Smarcel b = false; 369240116Smarcel REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 370240116Smarcel ATF_REQUIRE(!b); 371240116Smarcel b = true; 372240116Smarcel REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 373240116Smarcel ATF_REQUIRE(b); 374240116Smarcel 375240116Smarcel b = false; 376240116Smarcel REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 377240116Smarcel ATF_REQUIRE(!b); 378240116Smarcel b = true; 379240116Smarcel REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 380240116Smarcel ATF_REQUIRE(b); 381240116Smarcel} 382240116Smarcel 383240116SmarcelATF_TC(to_long); 384240116SmarcelATF_TC_HEAD(to_long, tc) 385240116Smarcel{ 386240116Smarcel atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function"); 387240116Smarcel} 388240116SmarcelATF_TC_BODY(to_long, tc) 389240116Smarcel{ 390240116Smarcel long l; 391240116Smarcel 392240116Smarcel RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0); 393240116Smarcel RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5); 394240116Smarcel RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5); 395240116Smarcel RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789); 396240116Smarcel 397240116Smarcel l = 1212; 398240116Smarcel REQUIRE_ERROR(atf_text_to_long("", &l)); 399240116Smarcel ATF_REQUIRE_EQ(l, 1212); 400240116Smarcel REQUIRE_ERROR(atf_text_to_long("foo", &l)); 401240116Smarcel ATF_REQUIRE_EQ(l, 1212); 402240116Smarcel REQUIRE_ERROR(atf_text_to_long("1234x", &l)); 403240116Smarcel ATF_REQUIRE_EQ(l, 1212); 404240116Smarcel} 405240116Smarcel 406240116Smarcel/* --------------------------------------------------------------------- 407240116Smarcel * Main. 408240116Smarcel * --------------------------------------------------------------------- */ 409240116Smarcel 410240116SmarcelATF_TP_ADD_TCS(tp) 411240116Smarcel{ 412240116Smarcel ATF_TP_ADD_TC(tp, for_each_word); 413240116Smarcel ATF_TP_ADD_TC(tp, format); 414240116Smarcel ATF_TP_ADD_TC(tp, format_ap); 415240116Smarcel ATF_TP_ADD_TC(tp, split); 416240116Smarcel ATF_TP_ADD_TC(tp, split_delims); 417240116Smarcel ATF_TP_ADD_TC(tp, to_bool); 418240116Smarcel ATF_TP_ADD_TC(tp, to_long); 419240116Smarcel 420240116Smarcel return atf_no_error(); 421240116Smarcel} 422