1275988Sngie/* Copyright (c) 2009 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
24275988Sngie * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
25240116Smarcel
26275988Sngie#include "atf-c/build.h"
27275988Sngie
28240116Smarcel#include <stdlib.h>
29240116Smarcel#include <string.h>
30240116Smarcel
31275988Sngie#include "atf-c/detail/env.h"
32275988Sngie#include "atf-c/detail/sanity.h"
33275988Sngie#include "atf-c/detail/text.h"
34240116Smarcel#include "atf-c/error.h"
35240116Smarcel
36240116Smarcel/* ---------------------------------------------------------------------
37240116Smarcel * Auxiliary functions.
38240116Smarcel * --------------------------------------------------------------------- */
39240116Smarcel
40240116Smarcelstatic
41240116Smarcelatf_error_t
42275988Sngieappend_config_var(const char *var, const char *default_value, atf_list_t *argv)
43240116Smarcel{
44240116Smarcel    atf_error_t err;
45240116Smarcel    atf_list_t words;
46240116Smarcel
47275988Sngie    err = atf_text_split(atf_env_get_with_default(var, default_value),
48275988Sngie                         " ", &words);
49240116Smarcel    if (atf_is_error(err))
50240116Smarcel        goto out;
51240116Smarcel
52240116Smarcel    atf_list_append_list(argv, &words);
53240116Smarcel
54240116Smarcelout:
55240116Smarcel    return err;
56240116Smarcel}
57240116Smarcel
58240116Smarcelstatic
59240116Smarcelatf_error_t
60240116Smarcelappend_arg1(const char *arg, atf_list_t *argv)
61240116Smarcel{
62240116Smarcel    return atf_list_append(argv, strdup(arg), true);
63240116Smarcel}
64240116Smarcel
65240116Smarcelstatic
66240116Smarcelatf_error_t
67240116Smarcelappend_arg2(const char *flag, const char *arg, atf_list_t *argv)
68240116Smarcel{
69240116Smarcel    atf_error_t err;
70240116Smarcel
71240116Smarcel    err = append_arg1(flag, argv);
72240116Smarcel    if (!atf_is_error(err))
73240116Smarcel        err = append_arg1(arg, argv);
74240116Smarcel
75240116Smarcel    return err;
76240116Smarcel}
77240116Smarcel
78240116Smarcelstatic
79240116Smarcelatf_error_t
80240116Smarcelappend_optargs(const char *const optargs[], atf_list_t *argv)
81240116Smarcel{
82240116Smarcel    atf_error_t err;
83240116Smarcel
84240116Smarcel    err = atf_no_error();
85240116Smarcel    while (*optargs != NULL && !atf_is_error(err)) {
86240116Smarcel        err = append_arg1(strdup(*optargs), argv);
87240116Smarcel        optargs++;
88240116Smarcel    }
89240116Smarcel
90240116Smarcel    return err;
91240116Smarcel}
92240116Smarcel
93240116Smarcelstatic
94240116Smarcelatf_error_t
95240116Smarcelappend_src_out(const char *src, const char *obj, atf_list_t *argv)
96240116Smarcel{
97240116Smarcel    atf_error_t err;
98240116Smarcel
99240116Smarcel    err = append_arg2("-o", obj, argv);
100240116Smarcel    if (atf_is_error(err))
101240116Smarcel        goto out;
102240116Smarcel
103240116Smarcel    err = append_arg1("-c", argv);
104240116Smarcel    if (atf_is_error(err))
105240116Smarcel        goto out;
106240116Smarcel
107240116Smarcel    err = append_arg1(src, argv);
108240116Smarcel
109240116Smarcelout:
110240116Smarcel    return err;
111240116Smarcel}
112240116Smarcel
113240116Smarcelstatic
114240116Smarcelatf_error_t
115240116Smarcellist_to_array(const atf_list_t *l, char ***ap)
116240116Smarcel{
117240116Smarcel    atf_error_t err;
118240116Smarcel    char **a;
119240116Smarcel
120240116Smarcel    a = (char **)malloc((atf_list_size(l) + 1) * sizeof(char *));
121240116Smarcel    if (a == NULL)
122240116Smarcel        err = atf_no_memory_error();
123240116Smarcel    else {
124240116Smarcel        char **aiter;
125240116Smarcel        atf_list_citer_t liter;
126240116Smarcel
127240116Smarcel        aiter = a;
128240116Smarcel        atf_list_for_each_c(liter, l) {
129240116Smarcel            *aiter = strdup((const char *)atf_list_citer_data(liter));
130240116Smarcel            aiter++;
131240116Smarcel        }
132240116Smarcel        *aiter = NULL;
133240116Smarcel
134240116Smarcel        err = atf_no_error();
135240116Smarcel    }
136240116Smarcel    *ap = a; /* Shut up warnings in the caller about uninitialized *ap. */
137240116Smarcel
138240116Smarcel    return err;
139240116Smarcel}
140240116Smarcel
141240116Smarcel/* ---------------------------------------------------------------------
142240116Smarcel * Free functions.
143240116Smarcel * --------------------------------------------------------------------- */
144240116Smarcel
145240116Smarcelatf_error_t
146240116Smarcelatf_build_c_o(const char *sfile,
147240116Smarcel              const char *ofile,
148240116Smarcel              const char *const optargs[],
149240116Smarcel              char ***argv)
150240116Smarcel{
151240116Smarcel    atf_error_t err;
152240116Smarcel    atf_list_t argv_list;
153240116Smarcel
154240116Smarcel    err = atf_list_init(&argv_list);
155240116Smarcel    if (atf_is_error(err))
156240116Smarcel        goto out;
157240116Smarcel
158275988Sngie    err = append_config_var("ATF_BUILD_CC", ATF_BUILD_CC, &argv_list);
159240116Smarcel    if (atf_is_error(err))
160240116Smarcel        goto out_list;
161240116Smarcel
162275988Sngie    err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
163275988Sngie                            &argv_list);
164240116Smarcel    if (atf_is_error(err))
165240116Smarcel        goto out_list;
166240116Smarcel
167275988Sngie    err = append_config_var("ATF_BUILD_CFLAGS", ATF_BUILD_CFLAGS, &argv_list);
168240116Smarcel    if (atf_is_error(err))
169240116Smarcel        goto out_list;
170240116Smarcel
171240116Smarcel    if (optargs != NULL) {
172240116Smarcel        err = append_optargs(optargs, &argv_list);
173240116Smarcel        if (atf_is_error(err))
174240116Smarcel            goto out_list;
175240116Smarcel    }
176240116Smarcel
177240116Smarcel    err = append_src_out(sfile, ofile, &argv_list);
178240116Smarcel    if (atf_is_error(err))
179240116Smarcel        goto out_list;
180240116Smarcel
181240116Smarcel    err = list_to_array(&argv_list, argv);
182240116Smarcel    if (atf_is_error(err))
183240116Smarcel        goto out_list;
184240116Smarcel
185240116Smarcelout_list:
186240116Smarcel    atf_list_fini(&argv_list);
187240116Smarcelout:
188240116Smarcel    return err;
189240116Smarcel}
190240116Smarcel
191240116Smarcelatf_error_t
192240116Smarcelatf_build_cpp(const char *sfile,
193240116Smarcel              const char *ofile,
194240116Smarcel              const char *const optargs[],
195240116Smarcel              char ***argv)
196240116Smarcel{
197240116Smarcel    atf_error_t err;
198240116Smarcel    atf_list_t argv_list;
199240116Smarcel
200240116Smarcel    err = atf_list_init(&argv_list);
201240116Smarcel    if (atf_is_error(err))
202240116Smarcel        goto out;
203240116Smarcel
204275988Sngie    err = append_config_var("ATF_BUILD_CPP", ATF_BUILD_CPP, &argv_list);
205240116Smarcel    if (atf_is_error(err))
206240116Smarcel        goto out_list;
207240116Smarcel
208275988Sngie    err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
209275988Sngie                            &argv_list);
210240116Smarcel    if (atf_is_error(err))
211240116Smarcel        goto out_list;
212240116Smarcel
213240116Smarcel    if (optargs != NULL) {
214240116Smarcel        err = append_optargs(optargs, &argv_list);
215240116Smarcel        if (atf_is_error(err))
216240116Smarcel            goto out_list;
217240116Smarcel    }
218240116Smarcel
219240116Smarcel    err = append_arg2("-o", ofile, &argv_list);
220240116Smarcel    if (atf_is_error(err))
221240116Smarcel        goto out_list;
222240116Smarcel
223240116Smarcel    err = append_arg1(sfile, &argv_list);
224240116Smarcel    if (atf_is_error(err))
225240116Smarcel        goto out_list;
226240116Smarcel
227240116Smarcel    err = list_to_array(&argv_list, argv);
228240116Smarcel    if (atf_is_error(err))
229240116Smarcel        goto out_list;
230240116Smarcel
231240116Smarcelout_list:
232240116Smarcel    atf_list_fini(&argv_list);
233240116Smarcelout:
234240116Smarcel    return err;
235240116Smarcel}
236240116Smarcel
237240116Smarcelatf_error_t
238240116Smarcelatf_build_cxx_o(const char *sfile,
239240116Smarcel                const char *ofile,
240240116Smarcel                const char *const optargs[],
241240116Smarcel                char ***argv)
242240116Smarcel{
243240116Smarcel    atf_error_t err;
244240116Smarcel    atf_list_t argv_list;
245240116Smarcel
246240116Smarcel    err = atf_list_init(&argv_list);
247240116Smarcel    if (atf_is_error(err))
248240116Smarcel        goto out;
249240116Smarcel
250275988Sngie    err = append_config_var("ATF_BUILD_CXX", ATF_BUILD_CXX, &argv_list);
251240116Smarcel    if (atf_is_error(err))
252240116Smarcel        goto out_list;
253240116Smarcel
254275988Sngie    err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
255275988Sngie                            &argv_list);
256240116Smarcel    if (atf_is_error(err))
257240116Smarcel        goto out_list;
258240116Smarcel
259275988Sngie    err = append_config_var("ATF_BUILD_CXXFLAGS", ATF_BUILD_CXXFLAGS,
260275988Sngie                            &argv_list);
261240116Smarcel    if (atf_is_error(err))
262240116Smarcel        goto out_list;
263240116Smarcel
264240116Smarcel    if (optargs != NULL) {
265240116Smarcel        err = append_optargs(optargs, &argv_list);
266240116Smarcel        if (atf_is_error(err))
267240116Smarcel            goto out_list;
268240116Smarcel    }
269240116Smarcel
270240116Smarcel    err = append_src_out(sfile, ofile, &argv_list);
271240116Smarcel    if (atf_is_error(err))
272240116Smarcel        goto out_list;
273240116Smarcel
274240116Smarcel    err = list_to_array(&argv_list, argv);
275240116Smarcel    if (atf_is_error(err))
276240116Smarcel        goto out_list;
277240116Smarcel
278240116Smarcelout_list:
279240116Smarcel    atf_list_fini(&argv_list);
280240116Smarcelout:
281240116Smarcel    return err;
282240116Smarcel}
283