1273929Sjmmv/* Copyright (c) 2008 The NetBSD Foundation, Inc.
2240116Smarcel * All rights reserved.
3240116Smarcel *
4240116Smarcel * Redistribution and use in source and binary forms, with or without
5240116Smarcel * modification, are permitted provided that the following conditions
6240116Smarcel * are met:
7240116Smarcel * 1. Redistributions of source code must retain the above copyright
8240116Smarcel *    notice, this list of conditions and the following disclaimer.
9240116Smarcel * 2. Redistributions in binary form must reproduce the above copyright
10240116Smarcel *    notice, this list of conditions and the following disclaimer in the
11240116Smarcel *    documentation and/or other materials provided with the distribution.
12240116Smarcel *
13240116Smarcel * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
14240116Smarcel * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
15240116Smarcel * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
16240116Smarcel * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17240116Smarcel * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
18240116Smarcel * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19240116Smarcel * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20240116Smarcel * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21240116Smarcel * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22240116Smarcel * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23240116Smarcel * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24273929Sjmmv * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */
25240116Smarcel
26273929Sjmmv#include "atf-c/tp.h"
27273929Sjmmv
28240116Smarcel#include <stdio.h>
29240116Smarcel#include <stdlib.h>
30240116Smarcel#include <string.h>
31240116Smarcel#include <unistd.h>
32240116Smarcel
33273929Sjmmv#include "atf-c/detail/fs.h"
34273929Sjmmv#include "atf-c/detail/map.h"
35273929Sjmmv#include "atf-c/detail/sanity.h"
36240116Smarcel#include "atf-c/error.h"
37240116Smarcel#include "atf-c/tc.h"
38240116Smarcel
39240116Smarcelstruct atf_tp_impl {
40240116Smarcel    atf_list_t m_tcs;
41240116Smarcel    atf_map_t m_config;
42240116Smarcel};
43240116Smarcel
44240116Smarcel/* ---------------------------------------------------------------------
45240116Smarcel * Auxiliary functions.
46240116Smarcel * --------------------------------------------------------------------- */
47240116Smarcel
48240116Smarcelstatic
49240116Smarcelconst atf_tc_t *
50240116Smarcelfind_tc(const atf_tp_t *tp, const char *ident)
51240116Smarcel{
52240116Smarcel    const atf_tc_t *tc;
53240116Smarcel    atf_list_citer_t iter;
54240116Smarcel
55240116Smarcel    tc = NULL;
56240116Smarcel    atf_list_for_each_c(iter, &tp->pimpl->m_tcs) {
57240116Smarcel        const atf_tc_t *tc2;
58240116Smarcel        tc2 = atf_list_citer_data(iter);
59240116Smarcel        if (strcmp(atf_tc_get_ident(tc2), ident) == 0) {
60240116Smarcel            tc = tc2;
61240116Smarcel            break;
62240116Smarcel        }
63240116Smarcel    }
64240116Smarcel    return tc;
65240116Smarcel}
66240116Smarcel
67240116Smarcel/* ---------------------------------------------------------------------
68240116Smarcel * The "atf_tp" type.
69240116Smarcel * --------------------------------------------------------------------- */
70240116Smarcel
71240116Smarcel/*
72240116Smarcel * Constructors/destructors.
73240116Smarcel */
74240116Smarcel
75240116Smarcelatf_error_t
76240116Smarcelatf_tp_init(atf_tp_t *tp, const char *const *config)
77240116Smarcel{
78240116Smarcel    atf_error_t err;
79240116Smarcel
80240116Smarcel    PRE(config != NULL);
81240116Smarcel
82240116Smarcel    tp->pimpl = malloc(sizeof(struct atf_tp_impl));
83240116Smarcel    if (tp->pimpl == NULL)
84240116Smarcel        return atf_no_memory_error();
85240116Smarcel
86240116Smarcel    err = atf_list_init(&tp->pimpl->m_tcs);
87240116Smarcel    if (atf_is_error(err))
88240116Smarcel        goto out;
89240116Smarcel
90240116Smarcel    err = atf_map_init_charpp(&tp->pimpl->m_config, config);
91240116Smarcel    if (atf_is_error(err)) {
92240116Smarcel        atf_list_fini(&tp->pimpl->m_tcs);
93240116Smarcel        goto out;
94240116Smarcel    }
95240116Smarcel
96240116Smarcel    INV(!atf_is_error(err));
97240116Smarcelout:
98240116Smarcel    return err;
99240116Smarcel}
100240116Smarcel
101240116Smarcelvoid
102240116Smarcelatf_tp_fini(atf_tp_t *tp)
103240116Smarcel{
104240116Smarcel    atf_list_iter_t iter;
105240116Smarcel
106240116Smarcel    atf_map_fini(&tp->pimpl->m_config);
107240116Smarcel
108240116Smarcel    atf_list_for_each(iter, &tp->pimpl->m_tcs) {
109240116Smarcel        atf_tc_t *tc = atf_list_iter_data(iter);
110240116Smarcel        atf_tc_fini(tc);
111240116Smarcel    }
112240116Smarcel    atf_list_fini(&tp->pimpl->m_tcs);
113240116Smarcel
114240116Smarcel    free(tp->pimpl);
115240116Smarcel}
116240116Smarcel
117240116Smarcel/*
118240116Smarcel * Getters.
119240116Smarcel */
120240116Smarcel
121240116Smarcelchar **
122240116Smarcelatf_tp_get_config(const atf_tp_t *tp)
123240116Smarcel{
124240116Smarcel    return atf_map_to_charpp(&tp->pimpl->m_config);
125240116Smarcel}
126240116Smarcel
127240116Smarcelbool
128240116Smarcelatf_tp_has_tc(const atf_tp_t *tp, const char *id)
129240116Smarcel{
130240116Smarcel    const atf_tc_t *tc = find_tc(tp, id);
131240116Smarcel    return tc != NULL;
132240116Smarcel}
133240116Smarcel
134240116Smarcelconst atf_tc_t *
135240116Smarcelatf_tp_get_tc(const atf_tp_t *tp, const char *id)
136240116Smarcel{
137240116Smarcel    const atf_tc_t *tc = find_tc(tp, id);
138240116Smarcel    PRE(tc != NULL);
139240116Smarcel    return tc;
140240116Smarcel}
141240116Smarcel
142240116Smarcelconst atf_tc_t *const *
143240116Smarcelatf_tp_get_tcs(const atf_tp_t *tp)
144240116Smarcel{
145240116Smarcel    const atf_tc_t **array;
146240116Smarcel    atf_list_citer_t iter;
147240116Smarcel    size_t i;
148240116Smarcel
149240116Smarcel    array = malloc(sizeof(atf_tc_t *) *
150240116Smarcel                   (atf_list_size(&tp->pimpl->m_tcs) + 1));
151240116Smarcel    if (array == NULL)
152240116Smarcel        goto out;
153240116Smarcel
154240116Smarcel    i = 0;
155240116Smarcel    atf_list_for_each_c(iter, &tp->pimpl->m_tcs) {
156240116Smarcel        array[i] = atf_list_citer_data(iter);
157240116Smarcel        if (array[i] == NULL) {
158240116Smarcel            free(array);
159240116Smarcel            array = NULL;
160240116Smarcel            goto out;
161240116Smarcel        }
162240116Smarcel
163240116Smarcel        i++;
164240116Smarcel    }
165240116Smarcel    array[i] = NULL;
166240116Smarcel
167240116Smarcelout:
168240116Smarcel    return array;
169240116Smarcel}
170240116Smarcel
171240116Smarcel/*
172240116Smarcel * Modifiers.
173240116Smarcel */
174240116Smarcel
175240116Smarcelatf_error_t
176240116Smarcelatf_tp_add_tc(atf_tp_t *tp, atf_tc_t *tc)
177240116Smarcel{
178240116Smarcel    atf_error_t err;
179240116Smarcel
180240116Smarcel    PRE(find_tc(tp, atf_tc_get_ident(tc)) == NULL);
181240116Smarcel
182240116Smarcel    err = atf_list_append(&tp->pimpl->m_tcs, tc, false);
183240116Smarcel
184240116Smarcel    POST(find_tc(tp, atf_tc_get_ident(tc)) != NULL);
185240116Smarcel
186240116Smarcel    return err;
187240116Smarcel}
188240116Smarcel
189240116Smarcel/* ---------------------------------------------------------------------
190240116Smarcel * Free functions.
191240116Smarcel * --------------------------------------------------------------------- */
192240116Smarcel
193240116Smarcelatf_error_t
194240116Smarcelatf_tp_run(const atf_tp_t *tp, const char *tcname, const char *resfile)
195240116Smarcel{
196240116Smarcel    const atf_tc_t *tc;
197240116Smarcel
198240116Smarcel    tc = find_tc(tp, tcname);
199240116Smarcel    PRE(tc != NULL);
200240116Smarcel
201240116Smarcel    return atf_tc_run(tc, resfile);
202240116Smarcel}
203240116Smarcel
204240116Smarcelatf_error_t
205240116Smarcelatf_tp_cleanup(const atf_tp_t *tp, const char *tcname)
206240116Smarcel{
207240116Smarcel    const atf_tc_t *tc;
208240116Smarcel
209240116Smarcel    tc = find_tc(tp, tcname);
210240116Smarcel    PRE(tc != NULL);
211240116Smarcel
212240116Smarcel    return atf_tc_cleanup(tc);
213240116Smarcel}
214