2 * Automated Testing Framework (atf)
4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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.
32 #include "atf-c/error.h"
34 #include "atf-c/sanity.h"
35 #include "atf-c/tcr.h"
37 /* ---------------------------------------------------------------------
38 * Auxiliary types and functions.
39 * --------------------------------------------------------------------- */
43 state_allows_reason(atf_tcr_state_t state
)
45 return state
== atf_tcr_failed_state
|| state
== atf_tcr_skipped_state
;
50 format_reason(atf_dynstr_t
*reason
, const char *fmt
, va_list ap
)
57 err
= atf_dynstr_init_ap(&tmp
, fmt
, ap2
);
59 if (atf_is_error(err
))
62 /* There is no reason for calling rfind instead of find other than
63 * find is not implemented. */
64 if (atf_dynstr_rfind_ch(&tmp
, '\n') == atf_dynstr_npos
) {
65 err
= atf_dynstr_copy(reason
, &tmp
);
69 err
= atf_dynstr_init_fmt(reason
, "BOGUS REASON (THE ORIGINAL "
71 if (atf_is_error(err
))
74 for (iter
= atf_dynstr_cstring(&tmp
); *iter
!= '\0'; iter
++) {
76 err
= atf_dynstr_append_fmt(reason
, "<<NEWLINE>>");
78 err
= atf_dynstr_append_fmt(reason
, "%c", *iter
);
80 if (atf_is_error(err
)) {
81 atf_dynstr_fini(reason
);
88 atf_dynstr_fini(&tmp
);
93 /* ---------------------------------------------------------------------
95 * --------------------------------------------------------------------- */
100 const atf_tcr_state_t atf_tcr_passed_state
= 0;
101 const atf_tcr_state_t atf_tcr_failed_state
= 1;
102 const atf_tcr_state_t atf_tcr_skipped_state
= 2;
105 * Constructors/destructors.
109 atf_tcr_init(atf_tcr_t
*tcr
, atf_tcr_state_t state
)
113 PRE(!state_allows_reason(state
));
115 atf_object_init(&tcr
->m_object
);
117 tcr
->m_state
= state
;
119 err
= atf_dynstr_init(&tcr
->m_reason
);
120 if (atf_is_error(err
))
123 INV(!atf_is_error(err
));
127 atf_object_fini(&tcr
->m_object
);
133 atf_tcr_init_reason_ap(atf_tcr_t
*tcr
, atf_tcr_state_t state
,
134 const char *fmt
, va_list ap
)
139 PRE(state_allows_reason(state
));
141 atf_object_init(&tcr
->m_object
);
143 tcr
->m_state
= state
;
146 err
= format_reason(&tcr
->m_reason
, fmt
, ap2
);
148 if (atf_is_error(err
))
151 INV(!atf_is_error(err
));
155 atf_object_fini(&tcr
->m_object
);
161 atf_tcr_init_reason_fmt(atf_tcr_t
*tcr
, atf_tcr_state_t state
,
162 const char *fmt
, ...)
168 err
= atf_tcr_init_reason_ap(tcr
, state
, fmt
, ap
);
175 atf_tcr_fini(atf_tcr_t
*tcr
)
177 atf_dynstr_fini(&tcr
->m_reason
);
179 atf_object_fini(&tcr
->m_object
);
187 atf_tcr_get_state(const atf_tcr_t
*tcr
)
193 atf_tcr_get_reason(const atf_tcr_t
*tcr
)
195 PRE(state_allows_reason(tcr
->m_state
));
196 return &tcr
->m_reason
;
200 atf_tcr_has_reason(const atf_tcr_t
*tcr
)
202 return state_allows_reason(tcr
->m_state
);
210 atf_equal_tcr_tcr(const atf_tcr_t
*tcr1
, const atf_tcr_t
*tcr2
)
212 const bool ar1
= state_allows_reason(tcr1
->m_state
);
213 const bool ar2
= state_allows_reason(tcr2
->m_state
);
218 equal
= tcr1
->m_state
== tcr2
->m_state
&&
219 atf_equal_dynstr_dynstr(&tcr1
->m_reason
, &tcr2
->m_reason
);
220 } else if (ar1
&& !ar2
) {
222 } else if (!ar1
&& ar2
) {
226 equal
= tcr1
->m_state
== tcr2
->m_state
;
237 atf_tcr_serialize(const atf_tcr_t
*tcr
, const int fd
)
240 const atf_tcr_state_t s
= atf_tcr_get_state(tcr
);
243 if (s
== atf_tcr_passed_state
)
245 else if (s
== atf_tcr_failed_state
)
247 else if (s
== atf_tcr_skipped_state
)
254 err
= atf_io_write_fmt(fd
, "%s\n", str
);
255 if (atf_is_error(err
))
258 if (atf_tcr_has_reason(tcr
)) {
259 const atf_dynstr_t
*r
= atf_tcr_get_reason(tcr
);
260 err
= atf_io_write_fmt(fd
, "%s\n", atf_dynstr_cstring(r
));
261 if (atf_is_error(err
))
265 INV(!atf_is_error(err
));
272 atf_tcr_deserialize(atf_tcr_t
*tcr
, const int fd
)
275 atf_dynstr_t state
, reason
;
278 err
= atf_dynstr_init(&state
);
279 if (atf_is_error(err
))
282 err
= atf_dynstr_init(&reason
);
283 if (atf_is_error(err
))
286 err
= atf_io_readline(fd
, &state
, &eof
);
287 if (atf_is_error(err
))
291 if (atf_equal_dynstr_cstring(&state
, "passed"))
292 err
= atf_tcr_init(tcr
, atf_tcr_passed_state
);
294 err
= atf_io_readline(fd
, &reason
, &eof
);
295 if (atf_is_error(err
))
299 if (atf_equal_dynstr_cstring(&state
, "failed"))
300 err
= atf_tcr_init_reason_fmt(tcr
, atf_tcr_failed_state
, "%s",
301 atf_dynstr_cstring(&reason
));
302 else if (atf_equal_dynstr_cstring(&state
, "skipped"))
303 err
= atf_tcr_init_reason_fmt(tcr
, atf_tcr_skipped_state
, "%s",
304 atf_dynstr_cstring(&reason
));
310 atf_dynstr_fini(&reason
);
312 atf_dynstr_fini(&state
);