1 /* $NetBSD: build.c,v 1.1.1.3 2014/12/10 03:34:48 christos Exp $ */ 2 3 /* 4 * Automated Testing Framework (atf) 5 * 6 * Copyright (c) 2009 The NetBSD Foundation, Inc. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 19 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <stdlib.h> 33 #include <string.h> 34 35 #include "atf-c/build.h" 36 #include "atf-c/config.h" 37 #include "atf-c/error.h" 38 39 #include "detail/sanity.h" 40 #include "detail/text.h" 41 42 /* --------------------------------------------------------------------- 43 * Auxiliary functions. 44 * --------------------------------------------------------------------- */ 45 46 static 47 atf_error_t 48 append_config_var(const char *var, atf_list_t *argv) 49 { 50 atf_error_t err; 51 atf_list_t words; 52 53 err = atf_text_split(atf_config_get(var), " ", &words); 54 if (atf_is_error(err)) 55 goto out; 56 57 atf_list_append_list(argv, &words); 58 59 out: 60 return err; 61 } 62 63 static 64 atf_error_t 65 append_arg1(const char *arg, atf_list_t *argv) 66 { 67 return atf_list_append(argv, strdup(arg), true); 68 } 69 70 static 71 atf_error_t 72 append_arg2(const char *flag, const char *arg, atf_list_t *argv) 73 { 74 atf_error_t err; 75 76 err = append_arg1(flag, argv); 77 if (!atf_is_error(err)) 78 err = append_arg1(arg, argv); 79 80 return err; 81 } 82 83 static 84 atf_error_t 85 append_optargs(const char *const optargs[], atf_list_t *argv) 86 { 87 atf_error_t err; 88 89 err = atf_no_error(); 90 while (*optargs != NULL && !atf_is_error(err)) { 91 err = append_arg1(strdup(*optargs), argv); 92 optargs++; 93 } 94 95 return err; 96 } 97 98 static 99 atf_error_t 100 append_src_out(const char *src, const char *obj, atf_list_t *argv) 101 { 102 atf_error_t err; 103 104 err = append_arg2("-o", obj, argv); 105 if (atf_is_error(err)) 106 goto out; 107 108 err = append_arg1("-c", argv); 109 if (atf_is_error(err)) 110 goto out; 111 112 err = append_arg1(src, argv); 113 114 out: 115 return err; 116 } 117 118 static 119 atf_error_t 120 list_to_array(const atf_list_t *l, char ***ap) 121 { 122 atf_error_t err; 123 char **a; 124 125 a = (char **)malloc((atf_list_size(l) + 1) * sizeof(char *)); 126 if (a == NULL) 127 err = atf_no_memory_error(); 128 else { 129 char **aiter; 130 atf_list_citer_t liter; 131 132 aiter = a; 133 atf_list_for_each_c(liter, l) { 134 *aiter = strdup((const char *)atf_list_citer_data(liter)); 135 aiter++; 136 } 137 *aiter = NULL; 138 139 err = atf_no_error(); 140 } 141 *ap = a; /* Shut up warnings in the caller about uninitialized *ap. */ 142 143 return err; 144 } 145 146 /* --------------------------------------------------------------------- 147 * Free functions. 148 * --------------------------------------------------------------------- */ 149 150 atf_error_t 151 atf_build_c_o(const char *sfile, 152 const char *ofile, 153 const char *const optargs[], 154 char ***argv) 155 { 156 atf_error_t err; 157 atf_list_t argv_list; 158 159 err = atf_list_init(&argv_list); 160 if (atf_is_error(err)) 161 goto out; 162 163 err = append_config_var("atf_build_cc", &argv_list); 164 if (atf_is_error(err)) 165 goto out_list; 166 167 err = append_config_var("atf_build_cppflags", &argv_list); 168 if (atf_is_error(err)) 169 goto out_list; 170 171 err = append_config_var("atf_build_cflags", &argv_list); 172 if (atf_is_error(err)) 173 goto out_list; 174 175 if (optargs != NULL) { 176 err = append_optargs(optargs, &argv_list); 177 if (atf_is_error(err)) 178 goto out_list; 179 } 180 181 err = append_src_out(sfile, ofile, &argv_list); 182 if (atf_is_error(err)) 183 goto out_list; 184 185 err = list_to_array(&argv_list, argv); 186 if (atf_is_error(err)) 187 goto out_list; 188 189 out_list: 190 atf_list_fini(&argv_list); 191 out: 192 return err; 193 } 194 195 atf_error_t 196 atf_build_cpp(const char *sfile, 197 const char *ofile, 198 const char *const optargs[], 199 char ***argv) 200 { 201 atf_error_t err; 202 atf_list_t argv_list; 203 204 err = atf_list_init(&argv_list); 205 if (atf_is_error(err)) 206 goto out; 207 208 err = append_config_var("atf_build_cpp", &argv_list); 209 if (atf_is_error(err)) 210 goto out_list; 211 212 err = append_config_var("atf_build_cppflags", &argv_list); 213 if (atf_is_error(err)) 214 goto out_list; 215 216 if (optargs != NULL) { 217 err = append_optargs(optargs, &argv_list); 218 if (atf_is_error(err)) 219 goto out_list; 220 } 221 222 err = append_arg2("-o", ofile, &argv_list); 223 if (atf_is_error(err)) 224 goto out_list; 225 226 err = append_arg1(sfile, &argv_list); 227 if (atf_is_error(err)) 228 goto out_list; 229 230 err = list_to_array(&argv_list, argv); 231 if (atf_is_error(err)) 232 goto out_list; 233 234 out_list: 235 atf_list_fini(&argv_list); 236 out: 237 return err; 238 } 239 240 atf_error_t 241 atf_build_cxx_o(const char *sfile, 242 const char *ofile, 243 const char *const optargs[], 244 char ***argv) 245 { 246 atf_error_t err; 247 atf_list_t argv_list; 248 249 err = atf_list_init(&argv_list); 250 if (atf_is_error(err)) 251 goto out; 252 253 err = append_config_var("atf_build_cxx", &argv_list); 254 if (atf_is_error(err)) 255 goto out_list; 256 257 err = append_config_var("atf_build_cppflags", &argv_list); 258 if (atf_is_error(err)) 259 goto out_list; 260 261 err = append_config_var("atf_build_cxxflags", &argv_list); 262 if (atf_is_error(err)) 263 goto out_list; 264 265 if (optargs != NULL) { 266 err = append_optargs(optargs, &argv_list); 267 if (atf_is_error(err)) 268 goto out_list; 269 } 270 271 err = append_src_out(sfile, ofile, &argv_list); 272 if (atf_is_error(err)) 273 goto out_list; 274 275 err = list_to_array(&argv_list, argv); 276 if (atf_is_error(err)) 277 goto out_list; 278 279 out_list: 280 atf_list_fini(&argv_list); 281 out: 282 return err; 283 } 284