1/* Copyright (c) 2008 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/tp.h" 27 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31#include <unistd.h> 32 33#include "atf-c/detail/fs.h" 34#include "atf-c/detail/map.h" 35#include "atf-c/detail/sanity.h" 36#include "atf-c/error.h" 37#include "atf-c/tc.h" 38 39struct atf_tp_impl { 40 atf_list_t m_tcs; 41 atf_map_t m_config; 42}; 43 44/* --------------------------------------------------------------------- 45 * Auxiliary functions. 46 * --------------------------------------------------------------------- */ 47 48static 49const atf_tc_t * 50find_tc(const atf_tp_t *tp, const char *ident) 51{ 52 const atf_tc_t *tc; 53 atf_list_citer_t iter; 54 55 tc = NULL; 56 atf_list_for_each_c(iter, &tp->pimpl->m_tcs) { 57 const atf_tc_t *tc2; 58 tc2 = atf_list_citer_data(iter); 59 if (strcmp(atf_tc_get_ident(tc2), ident) == 0) { 60 tc = tc2; 61 break; 62 } 63 } 64 return tc; 65} 66 67/* --------------------------------------------------------------------- 68 * The "atf_tp" type. 69 * --------------------------------------------------------------------- */ 70 71/* 72 * Constructors/destructors. 73 */ 74 75atf_error_t 76atf_tp_init(atf_tp_t *tp, const char *const *config) 77{ 78 atf_error_t err; 79 80 PRE(config != NULL); 81 82 tp->pimpl = malloc(sizeof(struct atf_tp_impl)); 83 if (tp->pimpl == NULL) 84 return atf_no_memory_error(); 85 86 err = atf_list_init(&tp->pimpl->m_tcs); 87 if (atf_is_error(err)) 88 goto out; 89 90 err = atf_map_init_charpp(&tp->pimpl->m_config, config); 91 if (atf_is_error(err)) { 92 atf_list_fini(&tp->pimpl->m_tcs); 93 goto out; 94 } 95 96 INV(!atf_is_error(err)); 97out: 98 return err; 99} 100 101void 102atf_tp_fini(atf_tp_t *tp) 103{ 104 atf_list_iter_t iter; 105 106 atf_map_fini(&tp->pimpl->m_config); 107 108 atf_list_for_each(iter, &tp->pimpl->m_tcs) { 109 atf_tc_t *tc = atf_list_iter_data(iter); 110 atf_tc_fini(tc); 111 } 112 atf_list_fini(&tp->pimpl->m_tcs); 113 114 free(tp->pimpl); 115} 116 117/* 118 * Getters. 119 */ 120 121char ** 122atf_tp_get_config(const atf_tp_t *tp) 123{ 124 return atf_map_to_charpp(&tp->pimpl->m_config); 125} 126 127bool 128atf_tp_has_tc(const atf_tp_t *tp, const char *id) 129{ 130 const atf_tc_t *tc = find_tc(tp, id); 131 return tc != NULL; 132} 133 134const atf_tc_t * 135atf_tp_get_tc(const atf_tp_t *tp, const char *id) 136{ 137 const atf_tc_t *tc = find_tc(tp, id); 138 PRE(tc != NULL); 139 return tc; 140} 141 142const atf_tc_t *const * 143atf_tp_get_tcs(const atf_tp_t *tp) 144{ 145 const atf_tc_t **array; 146 atf_list_citer_t iter; 147 size_t i; 148 149 array = malloc(sizeof(atf_tc_t *) * 150 (atf_list_size(&tp->pimpl->m_tcs) + 1)); 151 if (array == NULL) 152 goto out; 153 154 i = 0; 155 atf_list_for_each_c(iter, &tp->pimpl->m_tcs) { 156 array[i] = atf_list_citer_data(iter); 157 if (array[i] == NULL) { 158 free(array); 159 array = NULL; 160 goto out; 161 } 162 163 i++; 164 } 165 array[i] = NULL; 166 167out: 168 return array; 169} 170 171/* 172 * Modifiers. 173 */ 174 175atf_error_t 176atf_tp_add_tc(atf_tp_t *tp, atf_tc_t *tc) 177{ 178 atf_error_t err; 179 180 PRE(find_tc(tp, atf_tc_get_ident(tc)) == NULL); 181 182 err = atf_list_append(&tp->pimpl->m_tcs, tc, false); 183 184 POST(find_tc(tp, atf_tc_get_ident(tc)) != NULL); 185 186 return err; 187} 188 189/* --------------------------------------------------------------------- 190 * Free functions. 191 * --------------------------------------------------------------------- */ 192 193atf_error_t 194atf_tp_run(const atf_tp_t *tp, const char *tcname, const char *resfile) 195{ 196 const atf_tc_t *tc; 197 198 tc = find_tc(tp, tcname); 199 PRE(tc != NULL); 200 201 return atf_tc_run(tc, resfile); 202} 203 204atf_error_t 205atf_tp_cleanup(const atf_tp_t *tp, const char *tcname) 206{ 207 const atf_tc_t *tc; 208 209 tc = find_tc(tp, tcname); 210 PRE(tc != NULL); 211 212 return atf_tc_cleanup(tc); 213} 214