1240116Smarcel/*
2240116Smarcel * Automated Testing Framework (atf)
3240116Smarcel *
4240116Smarcel * Copyright (c) 2009 The NetBSD Foundation, Inc.
5240116Smarcel * All rights reserved.
6240116Smarcel *
7240116Smarcel * Redistribution and use in source and binary forms, with or without
8240116Smarcel * modification, are permitted provided that the following conditions
9240116Smarcel * are met:
10240116Smarcel * 1. Redistributions of source code must retain the above copyright
11240116Smarcel *    notice, this list of conditions and the following disclaimer.
12240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
13240116Smarcel *    notice, this list of conditions and the following disclaimer in the
14240116Smarcel *    documentation and/or other materials provided with the distribution.
15240116Smarcel *
16240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27240116Smarcel * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28240116Smarcel */
29240116Smarcel
30240116Smarcel#include <stdio.h>
31240116Smarcel#include <stdlib.h>
32240116Smarcel#include <string.h>
33240116Smarcel
34240116Smarcel#include <atf-c.h>
35240116Smarcel
36240116Smarcel#include "atf-c/build.h"
37240116Smarcel#include "atf-c/config.h"
38240116Smarcel#include "atf-c/utils.h"
39240116Smarcel
40240116Smarcel#include "detail/env.h"
41240116Smarcel#include "detail/test_helpers.h"
42240116Smarcel#include "h_build.h"
43240116Smarcel
44240116Smarcel/* ---------------------------------------------------------------------
45240116Smarcel * Auxiliary functions.
46240116Smarcel * --------------------------------------------------------------------- */
47240116Smarcel
48240116Smarcelvoid __atf_config_reinit(void);
49240116Smarcel
50240116Smarcelstatic
51240116Smarcelbool
52240116Smarcelequal_arrays(const char *const *exp_array, char **actual_array)
53240116Smarcel{
54240116Smarcel    bool equal;
55240116Smarcel
56240116Smarcel    if (*exp_array == NULL && *actual_array == NULL)
57240116Smarcel        equal = true;
58240116Smarcel    else if (*exp_array == NULL || *actual_array == NULL)
59240116Smarcel        equal = false;
60240116Smarcel    else {
61240116Smarcel        equal = true;
62240116Smarcel        while (*actual_array != NULL) {
63240116Smarcel            if (*exp_array == NULL || strcmp(*exp_array, *actual_array) != 0) {
64240116Smarcel                equal = false;
65240116Smarcel                break;
66240116Smarcel            }
67240116Smarcel            exp_array++;
68240116Smarcel            actual_array++;
69240116Smarcel        }
70240116Smarcel    }
71240116Smarcel
72240116Smarcel    return equal;
73240116Smarcel}
74240116Smarcel
75240116Smarcelstatic
76240116Smarcelvoid
77240116Smarcelcheck_equal_array(const char *const *exp_array, char **actual_array)
78240116Smarcel{
79240116Smarcel    {
80240116Smarcel        const char *const *exp_ptr;
81240116Smarcel        printf("Expected arguments:");
82240116Smarcel        for (exp_ptr = exp_array; *exp_ptr != NULL; exp_ptr++)
83240116Smarcel            printf(" '%s'", *exp_ptr);
84240116Smarcel        printf("\n");
85240116Smarcel    }
86240116Smarcel
87240116Smarcel    {
88240116Smarcel        char **actual_ptr;
89240116Smarcel        printf("Returned arguments:");
90240116Smarcel        for (actual_ptr = actual_array; *actual_ptr != NULL; actual_ptr++)
91240116Smarcel            printf(" '%s'", *actual_ptr);
92240116Smarcel        printf("\n");
93240116Smarcel    }
94240116Smarcel
95240116Smarcel    if (!equal_arrays(exp_array, actual_array))
96240116Smarcel        atf_tc_fail_nonfatal("The constructed argv differs from the "
97240116Smarcel                             "expected values");
98240116Smarcel}
99240116Smarcel
100240116Smarcelstatic
101240116Smarcelvoid
102240116Smarcelverbose_set_env(const char *var, const char *val)
103240116Smarcel{
104240116Smarcel    printf("Setting %s to '%s'\n", var, val);
105240116Smarcel    RE(atf_env_set(var, val));
106240116Smarcel}
107240116Smarcel
108240116Smarcel/* ---------------------------------------------------------------------
109240116Smarcel * Internal test cases.
110240116Smarcel * --------------------------------------------------------------------- */
111240116Smarcel
112240116SmarcelATF_TC(equal_arrays);
113240116SmarcelATF_TC_HEAD(equal_arrays, tc)
114240116Smarcel{
115240116Smarcel    atf_tc_set_md_var(tc, "descr", "Tests the test case internal "
116240116Smarcel                      "equal_arrays function");
117240116Smarcel}
118240116SmarcelATF_TC_BODY(equal_arrays, tc)
119240116Smarcel{
120240116Smarcel    {
121240116Smarcel        const char *const exp[] = { NULL };
122240116Smarcel        char *actual[] = { NULL };
123240116Smarcel
124240116Smarcel        ATF_CHECK(equal_arrays(exp, actual));
125240116Smarcel    }
126240116Smarcel
127240116Smarcel    {
128240116Smarcel        const char *const exp[] = { NULL };
129240116Smarcel        char *actual[2] = { strdup("foo"), NULL };
130240116Smarcel
131240116Smarcel        ATF_CHECK(!equal_arrays(exp, actual));
132240116Smarcel        free(actual[0]);
133240116Smarcel    }
134240116Smarcel
135240116Smarcel    {
136240116Smarcel        const char *const exp[] = { "foo", NULL };
137240116Smarcel        char *actual[] = { NULL };
138240116Smarcel
139240116Smarcel        ATF_CHECK(!equal_arrays(exp, actual));
140240116Smarcel    }
141240116Smarcel
142240116Smarcel    {
143240116Smarcel        const char *const exp[] = { "foo", NULL };
144240116Smarcel        char *actual[2] = { strdup("foo"), NULL };
145240116Smarcel
146240116Smarcel        ATF_CHECK(equal_arrays(exp, actual));
147240116Smarcel        free(actual[0]);
148240116Smarcel    }
149240116Smarcel}
150240116Smarcel
151240116Smarcel/* ---------------------------------------------------------------------
152240116Smarcel * Test cases for the free functions.
153240116Smarcel * --------------------------------------------------------------------- */
154240116Smarcel
155240116SmarcelATF_TC(c_o);
156240116SmarcelATF_TC_HEAD(c_o, tc)
157240116Smarcel{
158240116Smarcel    atf_tc_set_md_var(tc, "descr", "Tests the atf_build_c_o function");
159240116Smarcel}
160240116SmarcelATF_TC_BODY(c_o, tc)
161240116Smarcel{
162240116Smarcel    struct c_o_test *test;
163240116Smarcel
164240116Smarcel    for (test = c_o_tests; test->expargv[0] != NULL; test++) {
165240116Smarcel        printf("> Test: %s\n", test->msg);
166240116Smarcel
167240116Smarcel        verbose_set_env("ATF_BUILD_CC", test->cc);
168240116Smarcel        verbose_set_env("ATF_BUILD_CFLAGS", test->cflags);
169240116Smarcel        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
170240116Smarcel        __atf_config_reinit();
171240116Smarcel
172240116Smarcel        {
173240116Smarcel            char **argv;
174240116Smarcel            if (test->hasoptargs)
175240116Smarcel                RE(atf_build_c_o(test->sfile, test->ofile, test->optargs,
176240116Smarcel                                 &argv));
177240116Smarcel            else
178240116Smarcel                RE(atf_build_c_o(test->sfile, test->ofile, NULL, &argv));
179240116Smarcel            check_equal_array(test->expargv, argv);
180240116Smarcel            atf_utils_free_charpp(argv);
181240116Smarcel        }
182240116Smarcel    }
183240116Smarcel}
184240116Smarcel
185240116SmarcelATF_TC(cpp);
186240116SmarcelATF_TC_HEAD(cpp, tc)
187240116Smarcel{
188240116Smarcel    atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cpp function");
189240116Smarcel}
190240116SmarcelATF_TC_BODY(cpp, tc)
191240116Smarcel{
192240116Smarcel    struct cpp_test *test;
193240116Smarcel
194240116Smarcel    for (test = cpp_tests; test->expargv[0] != NULL; test++) {
195240116Smarcel        printf("> Test: %s\n", test->msg);
196240116Smarcel
197240116Smarcel        verbose_set_env("ATF_BUILD_CPP", test->cpp);
198240116Smarcel        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
199240116Smarcel        __atf_config_reinit();
200240116Smarcel
201240116Smarcel        {
202240116Smarcel            char **argv;
203240116Smarcel            if (test->hasoptargs)
204240116Smarcel                RE(atf_build_cpp(test->sfile, test->ofile, test->optargs,
205240116Smarcel                                 &argv));
206240116Smarcel            else
207240116Smarcel                RE(atf_build_cpp(test->sfile, test->ofile, NULL, &argv));
208240116Smarcel            check_equal_array(test->expargv, argv);
209240116Smarcel            atf_utils_free_charpp(argv);
210240116Smarcel        }
211240116Smarcel    }
212240116Smarcel}
213240116Smarcel
214240116SmarcelATF_TC(cxx_o);
215240116SmarcelATF_TC_HEAD(cxx_o, tc)
216240116Smarcel{
217240116Smarcel    atf_tc_set_md_var(tc, "descr", "Tests the atf_build_cxx_o function");
218240116Smarcel}
219240116SmarcelATF_TC_BODY(cxx_o, tc)
220240116Smarcel{
221240116Smarcel    struct cxx_o_test *test;
222240116Smarcel
223240116Smarcel    for (test = cxx_o_tests; test->expargv[0] != NULL; test++) {
224240116Smarcel        printf("> Test: %s\n", test->msg);
225240116Smarcel
226240116Smarcel        verbose_set_env("ATF_BUILD_CXX", test->cxx);
227240116Smarcel        verbose_set_env("ATF_BUILD_CXXFLAGS", test->cxxflags);
228240116Smarcel        verbose_set_env("ATF_BUILD_CPPFLAGS", test->cppflags);
229240116Smarcel        __atf_config_reinit();
230240116Smarcel
231240116Smarcel        {
232240116Smarcel            char **argv;
233240116Smarcel            if (test->hasoptargs)
234240116Smarcel                RE(atf_build_cxx_o(test->sfile, test->ofile, test->optargs,
235240116Smarcel                                   &argv));
236240116Smarcel            else
237240116Smarcel                RE(atf_build_cxx_o(test->sfile, test->ofile, NULL, &argv));
238240116Smarcel            check_equal_array(test->expargv, argv);
239240116Smarcel            atf_utils_free_charpp(argv);
240240116Smarcel        }
241240116Smarcel    }
242240116Smarcel}
243240116Smarcel
244240116Smarcel/* ---------------------------------------------------------------------
245240116Smarcel * Tests cases for the header file.
246240116Smarcel * --------------------------------------------------------------------- */
247240116Smarcel
248240116SmarcelHEADER_TC(include, "atf-c/build.h");
249240116Smarcel
250240116Smarcel/* ---------------------------------------------------------------------
251240116Smarcel * Main.
252240116Smarcel * --------------------------------------------------------------------- */
253240116Smarcel
254240116SmarcelATF_TP_ADD_TCS(tp)
255240116Smarcel{
256240116Smarcel    /* Add the internal test cases. */
257240116Smarcel    ATF_TP_ADD_TC(tp, equal_arrays);
258240116Smarcel
259240116Smarcel    /* Add the test cases for the free functions. */
260240116Smarcel    ATF_TP_ADD_TC(tp, c_o);
261240116Smarcel    ATF_TP_ADD_TC(tp, cpp);
262240116Smarcel    ATF_TP_ADD_TC(tp, cxx_o);
263240116Smarcel
264240116Smarcel    /* Add the test cases for the header file. */
265240116Smarcel    ATF_TP_ADD_TC(tp, include);
266240116Smarcel
267240116Smarcel    return atf_no_error();
268240116Smarcel}
269