Home | History | Annotate | Line # | Download | only in atf-c
      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