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 39 struct atf_tp_impl { 40 atf_list_t m_tcs; 41 atf_map_t m_config; 42 }; 43 44 /* --------------------------------------------------------------------- 45 * Auxiliary functions. 46 * --------------------------------------------------------------------- */ 47 48 static 49 const atf_tc_t * 50 find_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 75 atf_error_t 76 atf_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)); 97 out: 98 return err; 99 } 100 101 void 102 atf_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 121 char ** 122 atf_tp_get_config(const atf_tp_t *tp) 123 { 124 return atf_map_to_charpp(&tp->pimpl->m_config); 125 } 126 127 bool 128 atf_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 134 const atf_tc_t * 135 atf_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 142 const atf_tc_t *const * 143 atf_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 167 out: 168 return array; 169 } 170 171 /* 172 * Modifiers. 173 */ 174 175 atf_error_t 176 atf_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 193 atf_error_t 194 atf_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 204 atf_error_t 205 atf_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