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/text.h" 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include <atf-c.h> 33 34 #include "atf-c/detail/sanity.h" 35 #include "atf-c/detail/test_helpers.h" 36 37 /* --------------------------------------------------------------------- 38 * Auxiliary functions. 39 * --------------------------------------------------------------------- */ 40 41 #define REQUIRE_ERROR(exp) \ 42 do { \ 43 atf_error_t err = exp; \ 44 ATF_REQUIRE(atf_is_error(err)); \ 45 atf_error_free(err); \ 46 } while (0) 47 48 static 49 size_t 50 array_size(const char *words[]) 51 { 52 size_t count; 53 const char **word; 54 55 count = 0; 56 for (word = words; *word != NULL; word++) 57 count++; 58 59 return count; 60 } 61 62 static 63 void 64 check_split(const char *str, const char *delim, const char *words[]) 65 { 66 atf_list_t list; 67 const char **word; 68 size_t i; 69 70 printf("Splitting '%s' with delimiter '%s'\n", str, delim); 71 CE(atf_text_split(str, delim, &list)); 72 73 printf("Expecting %zd words\n", array_size(words)); 74 ATF_CHECK_EQ(atf_list_size(&list), array_size(words)); 75 76 for (word = words, i = 0; *word != NULL; word++, i++) { 77 printf("Word at position %zd should be '%s'\n", i, words[i]); 78 ATF_CHECK_STREQ((const char *)atf_list_index_c(&list, i), words[i]); 79 } 80 81 atf_list_fini(&list); 82 } 83 84 static 85 atf_error_t 86 word_acum(const char *word, void *data) 87 { 88 char *acum = data; 89 90 strcat(acum, word); 91 92 return atf_no_error(); 93 } 94 95 static 96 atf_error_t 97 word_count(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 98 { 99 size_t *counter = data; 100 101 (*counter)++; 102 103 return atf_no_error(); 104 } 105 106 struct fail_at { 107 int failpos; 108 int curpos; 109 }; 110 111 static 112 atf_error_t 113 word_fail_at(const char *word ATF_DEFS_ATTRIBUTE_UNUSED, void *data) 114 { 115 struct fail_at *fa = data; 116 atf_error_t err; 117 118 if (fa->failpos == fa->curpos) 119 err = atf_no_memory_error(); /* Just a random error. */ 120 else { 121 fa->curpos++; 122 err = atf_no_error(); 123 } 124 125 return err; 126 } 127 128 /* --------------------------------------------------------------------- 129 * Test cases for the free functions. 130 * --------------------------------------------------------------------- */ 131 132 ATF_TC(for_each_word); 133 ATF_TC_HEAD(for_each_word, tc) 134 { 135 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_for_each_word" 136 "function"); 137 } 138 ATF_TC_BODY(for_each_word, tc) 139 { 140 size_t cnt; 141 char acum[1024]; 142 143 cnt = 0; 144 strcpy(acum, ""); 145 RE(atf_text_for_each_word("1 2 3", " ", word_count, &cnt)); 146 RE(atf_text_for_each_word("1 2 3", " ", word_acum, acum)); 147 ATF_REQUIRE(cnt == 3); 148 ATF_REQUIRE(strcmp(acum, "123") == 0); 149 150 cnt = 0; 151 strcpy(acum, ""); 152 RE(atf_text_for_each_word("1 2 3", ".", word_count, &cnt)); 153 RE(atf_text_for_each_word("1 2 3", ".", word_acum, acum)); 154 ATF_REQUIRE(cnt == 1); 155 ATF_REQUIRE(strcmp(acum, "1 2 3") == 0); 156 157 cnt = 0; 158 strcpy(acum, ""); 159 RE(atf_text_for_each_word("1 2 3 4 5", " ", word_count, &cnt)); 160 RE(atf_text_for_each_word("1 2 3 4 5", " ", word_acum, acum)); 161 ATF_REQUIRE(cnt == 5); 162 ATF_REQUIRE(strcmp(acum, "12345") == 0); 163 164 cnt = 0; 165 strcpy(acum, ""); 166 RE(atf_text_for_each_word("1 2.3.4 5", " .", word_count, &cnt)); 167 RE(atf_text_for_each_word("1 2.3.4 5", " .", word_acum, acum)); 168 ATF_REQUIRE(cnt == 5); 169 ATF_REQUIRE(strcmp(acum, "12345") == 0); 170 171 { 172 struct fail_at fa; 173 fa.failpos = 3; 174 fa.curpos = 0; 175 atf_error_t err = atf_text_for_each_word("a b c d e", " ", 176 word_fail_at, &fa); 177 ATF_REQUIRE(atf_is_error(err)); 178 ATF_REQUIRE(atf_error_is(err, "no_memory")); 179 ATF_REQUIRE(fa.curpos == 3); 180 atf_error_free(err); 181 } 182 } 183 184 ATF_TC(format); 185 ATF_TC_HEAD(format, tc) 186 { 187 atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 188 "strings using a variable parameters list"); 189 } 190 ATF_TC_BODY(format, tc) 191 { 192 char *str; 193 atf_error_t err; 194 195 err = atf_text_format(&str, "%s %s %d", "Test", "string", 1); 196 ATF_REQUIRE(!atf_is_error(err)); 197 ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 198 free(str); 199 } 200 201 static 202 void 203 format_ap(char **dest, const char *fmt, ...) 204 { 205 va_list ap; 206 atf_error_t err; 207 208 va_start(ap, fmt); 209 err = atf_text_format_ap(dest, fmt, ap); 210 va_end(ap); 211 212 ATF_REQUIRE(!atf_is_error(err)); 213 } 214 215 ATF_TC(format_ap); 216 ATF_TC_HEAD(format_ap, tc) 217 { 218 atf_tc_set_md_var(tc, "descr", "Checks the construction of free-form " 219 "strings using a va_list argument"); 220 } 221 ATF_TC_BODY(format_ap, tc) 222 { 223 char *str; 224 225 format_ap(&str, "%s %s %d", "Test", "string", 1); 226 ATF_REQUIRE(strcmp(str, "Test string 1") == 0); 227 free(str); 228 } 229 230 ATF_TC(split); 231 ATF_TC_HEAD(split, tc) 232 { 233 atf_tc_set_md_var(tc, "descr", "Checks the split function"); 234 } 235 ATF_TC_BODY(split, tc) 236 { 237 { 238 const char *words[] = { NULL }; 239 check_split("", " ", words); 240 } 241 242 { 243 const char *words[] = { NULL }; 244 check_split(" ", " ", words); 245 } 246 247 { 248 const char *words[] = { NULL }; 249 check_split(" ", " ", words); 250 } 251 252 { 253 const char *words[] = { "a", "b", NULL }; 254 check_split("a b", " ", words); 255 } 256 257 { 258 const char *words[] = { "a", "b", "c", "d", NULL }; 259 check_split("a b c d", " ", words); 260 } 261 262 { 263 const char *words[] = { "foo", "bar", NULL }; 264 check_split("foo bar", " ", words); 265 } 266 267 { 268 const char *words[] = { "foo", "bar", "baz", "foobar", NULL }; 269 check_split("foo bar baz foobar", " ", words); 270 } 271 272 { 273 const char *words[] = { "foo", "bar", NULL }; 274 check_split(" foo bar", " ", words); 275 } 276 277 { 278 const char *words[] = { "foo", "bar", NULL }; 279 check_split("foo bar", " ", words); 280 } 281 282 { 283 const char *words[] = { "foo", "bar", NULL }; 284 check_split("foo bar ", " ", words); 285 } 286 287 { 288 const char *words[] = { "foo", "bar", NULL }; 289 check_split(" foo bar ", " ", words); 290 } 291 } 292 293 ATF_TC(split_delims); 294 ATF_TC_HEAD(split_delims, tc) 295 { 296 atf_tc_set_md_var(tc, "descr", "Checks the split function using " 297 "different delimiters"); 298 } 299 ATF_TC_BODY(split_delims, tc) 300 { 301 302 { 303 const char *words[] = { NULL }; 304 check_split("", "/", words); 305 } 306 307 { 308 const char *words[] = { " ", NULL }; 309 check_split(" ", "/", words); 310 } 311 312 { 313 const char *words[] = { " ", NULL }; 314 check_split(" ", "/", words); 315 } 316 317 { 318 const char *words[] = { "a", "b", NULL }; 319 check_split("a/b", "/", words); 320 } 321 322 { 323 const char *words[] = { "a", "bcd", "ef", NULL }; 324 check_split("aLONGDELIMbcdLONGDELIMef", "LONGDELIM", words); 325 } 326 } 327 328 ATF_TC(to_bool); 329 ATF_TC_HEAD(to_bool, tc) 330 { 331 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_bool function"); 332 } 333 ATF_TC_BODY(to_bool, tc) 334 { 335 bool b; 336 337 RE(atf_text_to_bool("true", &b)); ATF_REQUIRE(b); 338 RE(atf_text_to_bool("TRUE", &b)); ATF_REQUIRE(b); 339 RE(atf_text_to_bool("yes", &b)); ATF_REQUIRE(b); 340 RE(atf_text_to_bool("YES", &b)); ATF_REQUIRE(b); 341 342 RE(atf_text_to_bool("false", &b)); ATF_REQUIRE(!b); 343 RE(atf_text_to_bool("FALSE", &b)); ATF_REQUIRE(!b); 344 RE(atf_text_to_bool("no", &b)); ATF_REQUIRE(!b); 345 RE(atf_text_to_bool("NO", &b)); ATF_REQUIRE(!b); 346 347 b = false; 348 REQUIRE_ERROR(atf_text_to_bool("", &b)); 349 ATF_REQUIRE(!b); 350 b = true; 351 REQUIRE_ERROR(atf_text_to_bool("", &b)); 352 ATF_REQUIRE(b); 353 354 b = false; 355 REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 356 ATF_REQUIRE(!b); 357 b = true; 358 REQUIRE_ERROR(atf_text_to_bool("tru", &b)); 359 ATF_REQUIRE(b); 360 361 b = false; 362 REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 363 ATF_REQUIRE(!b); 364 b = true; 365 REQUIRE_ERROR(atf_text_to_bool("true2", &b)); 366 ATF_REQUIRE(b); 367 368 b = false; 369 REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 370 ATF_REQUIRE(!b); 371 b = true; 372 REQUIRE_ERROR(atf_text_to_bool("fals", &b)); 373 ATF_REQUIRE(b); 374 375 b = false; 376 REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 377 ATF_REQUIRE(!b); 378 b = true; 379 REQUIRE_ERROR(atf_text_to_bool("false2", &b)); 380 ATF_REQUIRE(b); 381 } 382 383 ATF_TC(to_long); 384 ATF_TC_HEAD(to_long, tc) 385 { 386 atf_tc_set_md_var(tc, "descr", "Checks the atf_text_to_long function"); 387 } 388 ATF_TC_BODY(to_long, tc) 389 { 390 long l; 391 392 RE(atf_text_to_long("0", &l)); ATF_REQUIRE_EQ(l, 0); 393 RE(atf_text_to_long("-5", &l)); ATF_REQUIRE_EQ(l, -5); 394 RE(atf_text_to_long("5", &l)); ATF_REQUIRE_EQ(l, 5); 395 RE(atf_text_to_long("123456789", &l)); ATF_REQUIRE_EQ(l, 123456789); 396 397 l = 1212; 398 REQUIRE_ERROR(atf_text_to_long("", &l)); 399 ATF_REQUIRE_EQ(l, 1212); 400 REQUIRE_ERROR(atf_text_to_long("foo", &l)); 401 ATF_REQUIRE_EQ(l, 1212); 402 REQUIRE_ERROR(atf_text_to_long("1234x", &l)); 403 ATF_REQUIRE_EQ(l, 1212); 404 } 405 406 /* --------------------------------------------------------------------- 407 * Main. 408 * --------------------------------------------------------------------- */ 409 410 ATF_TP_ADD_TCS(tp) 411 { 412 ATF_TP_ADD_TC(tp, for_each_word); 413 ATF_TP_ADD_TC(tp, format); 414 ATF_TP_ADD_TC(tp, format_ap); 415 ATF_TP_ADD_TC(tp, split); 416 ATF_TP_ADD_TC(tp, split_delims); 417 ATF_TP_ADD_TC(tp, to_bool); 418 ATF_TP_ADD_TC(tp, to_long); 419 420 return atf_no_error(); 421 } 422