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