1 // Copyright (c) 2009 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++/build.hpp" 27 28 #include <cstring> 29 #include <iostream> 30 31 #include <atf-c++.hpp> 32 33 extern "C" { 34 #include "atf-c/h_build.h" 35 } 36 37 #include "atf-c++/detail/env.hpp" 38 #include "atf-c++/detail/process.hpp" 39 40 // ------------------------------------------------------------------------ 41 // Auxiliary functions. 42 // ------------------------------------------------------------------------ 43 44 template< class C > 45 void 46 print_col(const char* prefix, const C& c) 47 { 48 std::cout << prefix << ":"; 49 for (typename C::const_iterator iter = c.begin(); iter != c.end(); 50 iter++) 51 std::cout << " '" << *iter << "'"; 52 std::cout << "\n"; 53 } 54 55 static 56 void 57 print_array(const char* prefix, const char* const* a) 58 { 59 std::cout << prefix << ":"; 60 for (; *a != NULL; a++) 61 std::cout << " '" << *a << "'"; 62 std::cout << "\n"; 63 } 64 65 static 66 void 67 verbose_set_env(const char *var, const char *val) 68 { 69 std::cout << "Setting " << var << " to '" << val << "'\n"; 70 atf::env::set(var, val); 71 } 72 73 static 74 bool 75 equal_argvs(const atf::process::argv_array& aa, const char* const* array) 76 { 77 bool equal = true; 78 79 atf::process::argv_array::size_type i = 0; 80 while (equal && (i < aa.size() && array[i] != NULL)) { 81 if (std::strcmp(aa[i], array[i]) != 0) 82 equal = false; 83 else 84 i++; 85 } 86 87 if (equal && (i < aa.size() || array[i] != NULL)) 88 equal = false; 89 90 return equal; 91 } 92 93 static 94 void 95 check_equal_argvs(const atf::process::argv_array& aa, const char* const* array) 96 { 97 print_array("Expected arguments", array); 98 print_col("Arguments returned", aa); 99 100 if (!equal_argvs(aa, array)) 101 ATF_FAIL("The constructed argv differs from the expected values"); 102 } 103 104 // ------------------------------------------------------------------------ 105 // Internal test cases. 106 // ------------------------------------------------------------------------ 107 108 ATF_TEST_CASE(equal_argvs); 109 ATF_TEST_CASE_HEAD(equal_argvs) 110 { 111 set_md_var("descr", "Tests the test case internal equal_argvs function"); 112 } 113 ATF_TEST_CASE_BODY(equal_argvs) 114 { 115 { 116 const char* const array[] = { NULL }; 117 const char* const argv[] = { NULL }; 118 119 ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array)); 120 } 121 122 { 123 const char* const array[] = { NULL }; 124 const char* const argv[] = { "foo", NULL }; 125 126 ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array)); 127 } 128 129 { 130 const char* const array[] = { "foo", NULL }; 131 const char* const argv[] = { NULL }; 132 133 ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array)); 134 } 135 136 { 137 const char* const array[] = { "foo", NULL }; 138 const char* const argv[] = { "foo", NULL }; 139 140 ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array)); 141 } 142 } 143 144 // ------------------------------------------------------------------------ 145 // Test cases for the free functions. 146 // ------------------------------------------------------------------------ 147 148 ATF_TEST_CASE(c_o); 149 ATF_TEST_CASE_HEAD(c_o) 150 { 151 set_md_var("descr", "Tests the c_o function"); 152 } 153 ATF_TEST_CASE_BODY(c_o) 154 { 155 for (struct c_o_test* test = c_o_tests; test->expargv[0] != NULL; 156 test++) { 157 std::cout << "> Test: " << test->msg << "\n"; 158 159 verbose_set_env("ATF_BUILD_CC", test->cc); 160 verbose_set_env("ATF_BUILD_CFLAGS", test->cflags); 161 verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags); 162 163 atf::process::argv_array argv = 164 atf::build::c_o(test->sfile, test->ofile, 165 atf::process::argv_array(test->optargs)); 166 check_equal_argvs(argv, test->expargv); 167 } 168 } 169 170 ATF_TEST_CASE(cpp); 171 ATF_TEST_CASE_HEAD(cpp) 172 { 173 set_md_var("descr", "Tests the cpp function"); 174 } 175 ATF_TEST_CASE_BODY(cpp) 176 { 177 for (struct cpp_test* test = cpp_tests; test->expargv[0] != NULL; 178 test++) { 179 std::cout << "> Test: " << test->msg << "\n"; 180 181 verbose_set_env("ATF_BUILD_CPP", test->cpp); 182 verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags); 183 184 atf::process::argv_array argv = 185 atf::build::cpp(test->sfile, test->ofile, 186 atf::process::argv_array(test->optargs)); 187 check_equal_argvs(argv, test->expargv); 188 } 189 } 190 191 ATF_TEST_CASE(cxx_o); 192 ATF_TEST_CASE_HEAD(cxx_o) 193 { 194 set_md_var("descr", "Tests the cxx_o function"); 195 } 196 ATF_TEST_CASE_BODY(cxx_o) 197 { 198 for (struct cxx_o_test* test = cxx_o_tests; test->expargv[0] != NULL; 199 test++) { 200 std::cout << "> Test: " << test->msg << "\n"; 201 202 verbose_set_env("ATF_BUILD_CXX", test->cxx); 203 verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags); 204 verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags); 205 206 atf::process::argv_array argv = 207 atf::build::cxx_o(test->sfile, test->ofile, 208 atf::process::argv_array(test->optargs)); 209 check_equal_argvs(argv, test->expargv); 210 } 211 } 212 213 // ------------------------------------------------------------------------ 214 // Main. 215 // ------------------------------------------------------------------------ 216 217 ATF_INIT_TEST_CASES(tcs) 218 { 219 // Add the internal test cases. 220 ATF_ADD_TEST_CASE(tcs, equal_argvs); 221 222 // Add the test cases for the free functions. 223 ATF_ADD_TEST_CASE(tcs, c_o); 224 ATF_ADD_TEST_CASE(tcs, cpp); 225 ATF_ADD_TEST_CASE(tcs, cxx_o); 226 } 227