diff options
Diffstat (limited to 'contrib/atf/atf-c/build.c')
-rw-r--r-- | contrib/atf/atf-c/build.c | 281 |
1 files changed, 281 insertions, 0 deletions
diff --git a/contrib/atf/atf-c/build.c b/contrib/atf/atf-c/build.c new file mode 100644 index 0000000..2483303 --- /dev/null +++ b/contrib/atf/atf-c/build.c @@ -0,0 +1,281 @@ +/* + * Automated Testing Framework (atf) + * + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdlib.h> +#include <string.h> + +#include "atf-c/build.h" +#include "atf-c/config.h" +#include "atf-c/error.h" + +#include "detail/sanity.h" +#include "detail/text.h" + +/* --------------------------------------------------------------------- + * Auxiliary functions. + * --------------------------------------------------------------------- */ + +static +atf_error_t +append_config_var(const char *var, atf_list_t *argv) +{ + atf_error_t err; + atf_list_t words; + + err = atf_text_split(atf_config_get(var), " ", &words); + if (atf_is_error(err)) + goto out; + + atf_list_append_list(argv, &words); + +out: + return err; +} + +static +atf_error_t +append_arg1(const char *arg, atf_list_t *argv) +{ + return atf_list_append(argv, strdup(arg), true); +} + +static +atf_error_t +append_arg2(const char *flag, const char *arg, atf_list_t *argv) +{ + atf_error_t err; + + err = append_arg1(flag, argv); + if (!atf_is_error(err)) + err = append_arg1(arg, argv); + + return err; +} + +static +atf_error_t +append_optargs(const char *const optargs[], atf_list_t *argv) +{ + atf_error_t err; + + err = atf_no_error(); + while (*optargs != NULL && !atf_is_error(err)) { + err = append_arg1(strdup(*optargs), argv); + optargs++; + } + + return err; +} + +static +atf_error_t +append_src_out(const char *src, const char *obj, atf_list_t *argv) +{ + atf_error_t err; + + err = append_arg2("-o", obj, argv); + if (atf_is_error(err)) + goto out; + + err = append_arg1("-c", argv); + if (atf_is_error(err)) + goto out; + + err = append_arg1(src, argv); + +out: + return err; +} + +static +atf_error_t +list_to_array(const atf_list_t *l, char ***ap) +{ + atf_error_t err; + char **a; + + a = (char **)malloc((atf_list_size(l) + 1) * sizeof(char *)); + if (a == NULL) + err = atf_no_memory_error(); + else { + char **aiter; + atf_list_citer_t liter; + + aiter = a; + atf_list_for_each_c(liter, l) { + *aiter = strdup((const char *)atf_list_citer_data(liter)); + aiter++; + } + *aiter = NULL; + + err = atf_no_error(); + } + *ap = a; /* Shut up warnings in the caller about uninitialized *ap. */ + + return err; +} + +/* --------------------------------------------------------------------- + * Free functions. + * --------------------------------------------------------------------- */ + +atf_error_t +atf_build_c_o(const char *sfile, + const char *ofile, + const char *const optargs[], + char ***argv) +{ + atf_error_t err; + atf_list_t argv_list; + + err = atf_list_init(&argv_list); + if (atf_is_error(err)) + goto out; + + err = append_config_var("atf_build_cc", &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = append_config_var("atf_build_cppflags", &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = append_config_var("atf_build_cflags", &argv_list); + if (atf_is_error(err)) + goto out_list; + + if (optargs != NULL) { + err = append_optargs(optargs, &argv_list); + if (atf_is_error(err)) + goto out_list; + } + + err = append_src_out(sfile, ofile, &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = list_to_array(&argv_list, argv); + if (atf_is_error(err)) + goto out_list; + +out_list: + atf_list_fini(&argv_list); +out: + return err; +} + +atf_error_t +atf_build_cpp(const char *sfile, + const char *ofile, + const char *const optargs[], + char ***argv) +{ + atf_error_t err; + atf_list_t argv_list; + + err = atf_list_init(&argv_list); + if (atf_is_error(err)) + goto out; + + err = append_config_var("atf_build_cpp", &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = append_config_var("atf_build_cppflags", &argv_list); + if (atf_is_error(err)) + goto out_list; + + if (optargs != NULL) { + err = append_optargs(optargs, &argv_list); + if (atf_is_error(err)) + goto out_list; + } + + err = append_arg2("-o", ofile, &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = append_arg1(sfile, &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = list_to_array(&argv_list, argv); + if (atf_is_error(err)) + goto out_list; + +out_list: + atf_list_fini(&argv_list); +out: + return err; +} + +atf_error_t +atf_build_cxx_o(const char *sfile, + const char *ofile, + const char *const optargs[], + char ***argv) +{ + atf_error_t err; + atf_list_t argv_list; + + err = atf_list_init(&argv_list); + if (atf_is_error(err)) + goto out; + + err = append_config_var("atf_build_cxx", &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = append_config_var("atf_build_cppflags", &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = append_config_var("atf_build_cxxflags", &argv_list); + if (atf_is_error(err)) + goto out_list; + + if (optargs != NULL) { + err = append_optargs(optargs, &argv_list); + if (atf_is_error(err)) + goto out_list; + } + + err = append_src_out(sfile, ofile, &argv_list); + if (atf_is_error(err)) + goto out_list; + + err = list_to_array(&argv_list, argv); + if (atf_is_error(err)) + goto out_list; + +out_list: + atf_list_fini(&argv_list); +out: + return err; +} |