1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2009 The NetBSD Foundation, Inc.
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 // 1. Redistributions of source code must retain the above copyright
11 // notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29
30 #include <cstring>
31 #include <iostream>
32
33 #include "../atf-c/h_build.h"
34
35 #include "build.hpp"
36 #include "config.hpp"
37 #include "macros.hpp"
38
39 #include "detail/env.hpp"
40 #include "detail/process.hpp"
41 #include "detail/test_helpers.hpp"
42
43 // ------------------------------------------------------------------------
44 // Auxiliary functions.
45 // ------------------------------------------------------------------------
46
47 namespace atf {
48 namespace config {
49 void __reinit(void);
50 }
51 }
52
53 template< class C >
54 void
print_col(const char * prefix,const C & c)55 print_col(const char* prefix, const C& c)
56 {
57 std::cout << prefix << ":";
58 for (typename C::const_iterator iter = c.begin(); iter != c.end();
59 iter++)
60 std::cout << " '" << *iter << "'";
61 std::cout << "\n";
62 }
63
64 static
65 void
print_array(const char * prefix,const char * const * a)66 print_array(const char* prefix, const char* const* a)
67 {
68 std::cout << prefix << ":";
69 for (; *a != NULL; a++)
70 std::cout << " '" << *a << "'";
71 std::cout << "\n";
72 }
73
74 static
75 void
verbose_set_env(const char * var,const char * val)76 verbose_set_env(const char *var, const char *val)
77 {
78 std::cout << "Setting " << var << " to '" << val << "'\n";
79 atf::env::set(var, val);
80 }
81
82 static
83 bool
equal_argvs(const atf::process::argv_array & aa,const char * const * array)84 equal_argvs(const atf::process::argv_array& aa, const char* const* array)
85 {
86 bool equal = true;
87
88 atf::process::argv_array::size_type i = 0;
89 while (equal && (i < aa.size() && array[i] != NULL)) {
90 if (std::strcmp(aa[i], array[i]) != 0)
91 equal = false;
92 else
93 i++;
94 }
95
96 if (equal && (i < aa.size() || array[i] != NULL))
97 equal = false;
98
99 return equal;
100 }
101
102 static
103 void
check_equal_argvs(const atf::process::argv_array & aa,const char * const * array)104 check_equal_argvs(const atf::process::argv_array& aa, const char* const* array)
105 {
106 print_array("Expected arguments", array);
107 print_col("Arguments returned", aa);
108
109 if (!equal_argvs(aa, array))
110 ATF_FAIL("The constructed argv differs from the expected values");
111 }
112
113 // ------------------------------------------------------------------------
114 // Internal test cases.
115 // ------------------------------------------------------------------------
116
117 ATF_TEST_CASE(equal_argvs);
ATF_TEST_CASE_HEAD(equal_argvs)118 ATF_TEST_CASE_HEAD(equal_argvs)
119 {
120 set_md_var("descr", "Tests the test case internal equal_argvs function");
121 }
ATF_TEST_CASE_BODY(equal_argvs)122 ATF_TEST_CASE_BODY(equal_argvs)
123 {
124 {
125 const char* const array[] = { NULL };
126 const char* const argv[] = { NULL };
127
128 ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array));
129 }
130
131 {
132 const char* const array[] = { NULL };
133 const char* const argv[] = { "foo", NULL };
134
135 ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array));
136 }
137
138 {
139 const char* const array[] = { "foo", NULL };
140 const char* const argv[] = { NULL };
141
142 ATF_REQUIRE(!equal_argvs(atf::process::argv_array(argv), array));
143 }
144
145 {
146 const char* const array[] = { "foo", NULL };
147 const char* const argv[] = { "foo", NULL };
148
149 ATF_REQUIRE(equal_argvs(atf::process::argv_array(argv), array));
150 }
151 }
152
153 // ------------------------------------------------------------------------
154 // Test cases for the free functions.
155 // ------------------------------------------------------------------------
156
157 ATF_TEST_CASE(c_o);
ATF_TEST_CASE_HEAD(c_o)158 ATF_TEST_CASE_HEAD(c_o)
159 {
160 set_md_var("descr", "Tests the c_o function");
161 }
ATF_TEST_CASE_BODY(c_o)162 ATF_TEST_CASE_BODY(c_o)
163 {
164 for (struct c_o_test* test = c_o_tests; test->expargv[0] != NULL;
165 test++) {
166 std::cout << "> Test: " << test->msg << "\n";
167
168 verbose_set_env("ATF_BUILD_CC", test->cc);
169 verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
170 verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
171 atf::config::__reinit();
172
173 atf::process::argv_array argv =
174 atf::build::c_o(test->sfile, test->ofile,
175 atf::process::argv_array(test->optargs));
176 check_equal_argvs(argv, test->expargv);
177 }
178 }
179
180 ATF_TEST_CASE(cpp);
ATF_TEST_CASE_HEAD(cpp)181 ATF_TEST_CASE_HEAD(cpp)
182 {
183 set_md_var("descr", "Tests the cpp function");
184 }
ATF_TEST_CASE_BODY(cpp)185 ATF_TEST_CASE_BODY(cpp)
186 {
187 for (struct cpp_test* test = cpp_tests; test->expargv[0] != NULL;
188 test++) {
189 std::cout << "> Test: " << test->msg << "\n";
190
191 verbose_set_env("ATF_BUILD_CPP", test->cpp);
192 verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
193 atf::config::__reinit();
194
195 atf::process::argv_array argv =
196 atf::build::cpp(test->sfile, test->ofile,
197 atf::process::argv_array(test->optargs));
198 check_equal_argvs(argv, test->expargv);
199 }
200 }
201
202 ATF_TEST_CASE(cxx_o);
ATF_TEST_CASE_HEAD(cxx_o)203 ATF_TEST_CASE_HEAD(cxx_o)
204 {
205 set_md_var("descr", "Tests the cxx_o function");
206 }
ATF_TEST_CASE_BODY(cxx_o)207 ATF_TEST_CASE_BODY(cxx_o)
208 {
209 for (struct cxx_o_test* test = cxx_o_tests; test->expargv[0] != NULL;
210 test++) {
211 std::cout << "> Test: " << test->msg << "\n";
212
213 verbose_set_env("ATF_BUILD_CXX", test->cxx);
214 verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
215 verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
216 atf::config::__reinit();
217
218 atf::process::argv_array argv =
219 atf::build::cxx_o(test->sfile, test->ofile,
220 atf::process::argv_array(test->optargs));
221 check_equal_argvs(argv, test->expargv);
222 }
223 }
224
225 // ------------------------------------------------------------------------
226 // Tests cases for the header file.
227 // ------------------------------------------------------------------------
228
229 HEADER_TC(include, "atf-c++/build.hpp");
230
231 // ------------------------------------------------------------------------
232 // Main.
233 // ------------------------------------------------------------------------
234
ATF_INIT_TEST_CASES(tcs)235 ATF_INIT_TEST_CASES(tcs)
236 {
237 // Add the internal test cases.
238 ATF_ADD_TEST_CASE(tcs, equal_argvs);
239
240 // Add the test cases for the free functions.
241 ATF_ADD_TEST_CASE(tcs, c_o);
242 ATF_ADD_TEST_CASE(tcs, cpp);
243 ATF_ADD_TEST_CASE(tcs, cxx_o);
244
245 // Add the test cases for the header file.
246 ATF_ADD_TEST_CASE(tcs, include);
247 }
248