xref: /freebsd/contrib/atf/atf-c/build.c (revision d8a0fe102c0cfdfcd5b818f850eff09d8536c9bc)
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.h"
27 
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "atf-c/detail/env.h"
32 #include "atf-c/detail/sanity.h"
33 #include "atf-c/detail/text.h"
34 #include "atf-c/error.h"
35 
36 /* ---------------------------------------------------------------------
37  * Auxiliary functions.
38  * --------------------------------------------------------------------- */
39 
40 static
41 atf_error_t
42 append_config_var(const char *var, const char *default_value, atf_list_t *argv)
43 {
44     atf_error_t err;
45     atf_list_t words;
46 
47     err = atf_text_split(atf_env_get_with_default(var, default_value),
48                          " ", &words);
49     if (atf_is_error(err))
50         goto out;
51 
52     atf_list_append_list(argv, &words);
53 
54 out:
55     return err;
56 }
57 
58 static
59 atf_error_t
60 append_arg1(const char *arg, atf_list_t *argv)
61 {
62     return atf_list_append(argv, strdup(arg), true);
63 }
64 
65 static
66 atf_error_t
67 append_arg2(const char *flag, const char *arg, atf_list_t *argv)
68 {
69     atf_error_t err;
70 
71     err = append_arg1(flag, argv);
72     if (!atf_is_error(err))
73         err = append_arg1(arg, argv);
74 
75     return err;
76 }
77 
78 static
79 atf_error_t
80 append_optargs(const char *const optargs[], atf_list_t *argv)
81 {
82     atf_error_t err;
83 
84     err = atf_no_error();
85     while (*optargs != NULL && !atf_is_error(err)) {
86         err = append_arg1(strdup(*optargs), argv);
87         optargs++;
88     }
89 
90     return err;
91 }
92 
93 static
94 atf_error_t
95 append_src_out(const char *src, const char *obj, atf_list_t *argv)
96 {
97     atf_error_t err;
98 
99     err = append_arg2("-o", obj, argv);
100     if (atf_is_error(err))
101         goto out;
102 
103     err = append_arg1("-c", argv);
104     if (atf_is_error(err))
105         goto out;
106 
107     err = append_arg1(src, argv);
108 
109 out:
110     return err;
111 }
112 
113 static
114 atf_error_t
115 list_to_array(const atf_list_t *l, char ***ap)
116 {
117     atf_error_t err;
118     char **a;
119 
120     a = (char **)malloc((atf_list_size(l) + 1) * sizeof(char *));
121     if (a == NULL)
122         err = atf_no_memory_error();
123     else {
124         char **aiter;
125         atf_list_citer_t liter;
126 
127         aiter = a;
128         atf_list_for_each_c(liter, l) {
129             *aiter = strdup((const char *)atf_list_citer_data(liter));
130             aiter++;
131         }
132         *aiter = NULL;
133 
134         err = atf_no_error();
135     }
136     *ap = a; /* Shut up warnings in the caller about uninitialized *ap. */
137 
138     return err;
139 }
140 
141 /* ---------------------------------------------------------------------
142  * Free functions.
143  * --------------------------------------------------------------------- */
144 
145 atf_error_t
146 atf_build_c_o(const char *sfile,
147               const char *ofile,
148               const char *const optargs[],
149               char ***argv)
150 {
151     atf_error_t err;
152     atf_list_t argv_list;
153 
154     err = atf_list_init(&argv_list);
155     if (atf_is_error(err))
156         goto out;
157 
158     err = append_config_var("ATF_BUILD_CC", ATF_BUILD_CC, &argv_list);
159     if (atf_is_error(err))
160         goto out_list;
161 
162     err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
163                             &argv_list);
164     if (atf_is_error(err))
165         goto out_list;
166 
167     err = append_config_var("ATF_BUILD_CFLAGS", ATF_BUILD_CFLAGS, &argv_list);
168     if (atf_is_error(err))
169         goto out_list;
170 
171     if (optargs != NULL) {
172         err = append_optargs(optargs, &argv_list);
173         if (atf_is_error(err))
174             goto out_list;
175     }
176 
177     err = append_src_out(sfile, ofile, &argv_list);
178     if (atf_is_error(err))
179         goto out_list;
180 
181     err = list_to_array(&argv_list, argv);
182     if (atf_is_error(err))
183         goto out_list;
184 
185 out_list:
186     atf_list_fini(&argv_list);
187 out:
188     return err;
189 }
190 
191 atf_error_t
192 atf_build_cpp(const char *sfile,
193               const char *ofile,
194               const char *const optargs[],
195               char ***argv)
196 {
197     atf_error_t err;
198     atf_list_t argv_list;
199 
200     err = atf_list_init(&argv_list);
201     if (atf_is_error(err))
202         goto out;
203 
204     err = append_config_var("ATF_BUILD_CPP", ATF_BUILD_CPP, &argv_list);
205     if (atf_is_error(err))
206         goto out_list;
207 
208     err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
209                             &argv_list);
210     if (atf_is_error(err))
211         goto out_list;
212 
213     if (optargs != NULL) {
214         err = append_optargs(optargs, &argv_list);
215         if (atf_is_error(err))
216             goto out_list;
217     }
218 
219     err = append_arg2("-o", ofile, &argv_list);
220     if (atf_is_error(err))
221         goto out_list;
222 
223     err = append_arg1(sfile, &argv_list);
224     if (atf_is_error(err))
225         goto out_list;
226 
227     err = list_to_array(&argv_list, argv);
228     if (atf_is_error(err))
229         goto out_list;
230 
231 out_list:
232     atf_list_fini(&argv_list);
233 out:
234     return err;
235 }
236 
237 atf_error_t
238 atf_build_cxx_o(const char *sfile,
239                 const char *ofile,
240                 const char *const optargs[],
241                 char ***argv)
242 {
243     atf_error_t err;
244     atf_list_t argv_list;
245 
246     err = atf_list_init(&argv_list);
247     if (atf_is_error(err))
248         goto out;
249 
250     err = append_config_var("ATF_BUILD_CXX", ATF_BUILD_CXX, &argv_list);
251     if (atf_is_error(err))
252         goto out_list;
253 
254     err = append_config_var("ATF_BUILD_CPPFLAGS", ATF_BUILD_CPPFLAGS,
255                             &argv_list);
256     if (atf_is_error(err))
257         goto out_list;
258 
259     err = append_config_var("ATF_BUILD_CXXFLAGS", ATF_BUILD_CXXFLAGS,
260                             &argv_list);
261     if (atf_is_error(err))
262         goto out_list;
263 
264     if (optargs != NULL) {
265         err = append_optargs(optargs, &argv_list);
266         if (atf_is_error(err))
267             goto out_list;
268     }
269 
270     err = append_src_out(sfile, ofile, &argv_list);
271     if (atf_is_error(err))
272         goto out_list;
273 
274     err = list_to_array(&argv_list, argv);
275     if (atf_is_error(err))
276         goto out_list;
277 
278 out_list:
279     atf_list_fini(&argv_list);
280 out:
281     return err;
282 }
283