2 * Automated Testing Framework (atf)
4 * Copyright (c) 2008 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.
37 #include "atf-c/error.h"
43 /* ---------------------------------------------------------------------
44 * Auxiliary functions.
45 * --------------------------------------------------------------------- */
49 resize(atf_dynstr_t
*ad
, size_t newsize
)
54 PRE(newsize
> ad
->m_datasize
);
56 newdata
= (char *)malloc(newsize
);
57 if (newdata
== NULL
) {
58 err
= atf_no_memory_error();
60 strcpy(newdata
, ad
->m_data
);
63 ad
->m_datasize
= newsize
;
70 ATF_DEFS_ATTRIBUTE_FORMAT_PRINTF(2, 0)
73 prepend_or_append(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
,
82 err
= atf_text_format_ap(&aux
, fmt
, ap2
);
84 if (atf_is_error(err
))
86 newlen
= ad
->m_length
+ strlen(aux
);
88 if (newlen
+ sizeof(char) > ad
->m_datasize
) {
89 err
= resize(ad
, newlen
+ sizeof(char));
90 if (atf_is_error(err
))
95 memmove(ad
->m_data
+ strlen(aux
), ad
->m_data
, ad
->m_length
+ 1);
96 memcpy(ad
->m_data
, aux
, strlen(aux
));
98 strcpy(ad
->m_data
+ ad
->m_length
, aux
);
99 ad
->m_length
= newlen
;
100 err
= atf_no_error();
108 /* ---------------------------------------------------------------------
109 * The "atf_dynstr" type.
110 * --------------------------------------------------------------------- */
116 const size_t atf_dynstr_npos
= SIZE_MAX
;
119 * Constructors and destructors.
123 atf_dynstr_init(atf_dynstr_t
*ad
)
127 ad
->m_data
= (char *)malloc(sizeof(char));
128 if (ad
->m_data
== NULL
) {
129 err
= atf_no_memory_error();
133 ad
->m_data
[0] = '\0';
136 err
= atf_no_error();
143 atf_dynstr_init_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
147 ad
->m_datasize
= strlen(fmt
) + 1;
155 ad
->m_data
= (char *)malloc(ad
->m_datasize
);
156 if (ad
->m_data
== NULL
) {
157 err
= atf_no_memory_error();
162 ret
= vsnprintf(ad
->m_data
, ad
->m_datasize
, fmt
, ap2
);
166 err
= atf_libc_error(errno
, "Cannot format string");
171 if ((size_t)ret
>= ad
->m_datasize
) {
176 } while (ad
->m_length
>= ad
->m_datasize
);
178 err
= atf_no_error();
180 POST(atf_is_error(err
) || ad
->m_data
!= NULL
);
185 atf_dynstr_init_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
191 err
= atf_dynstr_init_ap(ad
, fmt
, ap
);
198 atf_dynstr_init_raw(atf_dynstr_t
*ad
, const void *mem
, size_t memlen
)
202 if (memlen
>= SIZE_MAX
- 1) {
203 err
= atf_no_memory_error();
207 ad
->m_data
= (char *)malloc(memlen
+ 1);
208 if (ad
->m_data
== NULL
) {
209 err
= atf_no_memory_error();
213 ad
->m_datasize
= memlen
+ 1;
214 memcpy(ad
->m_data
, mem
, memlen
);
215 ad
->m_data
[memlen
] = '\0';
216 ad
->m_length
= strlen(ad
->m_data
);
217 INV(ad
->m_length
<= memlen
);
218 err
= atf_no_error();
225 atf_dynstr_init_rep(atf_dynstr_t
*ad
, size_t len
, char ch
)
229 if (len
== SIZE_MAX
) {
230 err
= atf_no_memory_error();
234 ad
->m_datasize
= (len
+ 1) * sizeof(char);
235 ad
->m_data
= (char *)malloc(ad
->m_datasize
);
236 if (ad
->m_data
== NULL
) {
237 err
= atf_no_memory_error();
241 memset(ad
->m_data
, ch
, len
);
242 ad
->m_data
[len
] = '\0';
244 err
= atf_no_error();
251 atf_dynstr_init_substr(atf_dynstr_t
*ad
, const atf_dynstr_t
*src
,
252 size_t beg
, size_t end
)
254 if (beg
> src
->m_length
)
257 if (end
== atf_dynstr_npos
|| end
> src
->m_length
)
260 return atf_dynstr_init_raw(ad
, src
->m_data
+ beg
, end
- beg
);
264 atf_dynstr_copy(atf_dynstr_t
*dest
, const atf_dynstr_t
*src
)
268 dest
->m_data
= (char *)malloc(src
->m_datasize
);
269 if (dest
->m_data
== NULL
)
270 err
= atf_no_memory_error();
272 memcpy(dest
->m_data
, src
->m_data
, src
->m_datasize
);
273 dest
->m_datasize
= src
->m_datasize
;
274 dest
->m_length
= src
->m_length
;
275 err
= atf_no_error();
282 atf_dynstr_fini(atf_dynstr_t
*ad
)
284 INV(ad
->m_data
!= NULL
);
289 atf_dynstr_fini_disown(atf_dynstr_t
*ad
)
291 INV(ad
->m_data
!= NULL
);
300 atf_dynstr_cstring(const atf_dynstr_t
*ad
)
306 atf_dynstr_length(const atf_dynstr_t
*ad
)
312 atf_dynstr_rfind_ch(const atf_dynstr_t
*ad
, char ch
)
316 for (pos
= ad
->m_length
; pos
> 0 && ad
->m_data
[pos
- 1] != ch
; pos
--)
319 return pos
== 0 ? atf_dynstr_npos
: pos
- 1;
327 atf_dynstr_append_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
333 err
= prepend_or_append(ad
, fmt
, ap2
, false);
340 atf_dynstr_append_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
346 err
= prepend_or_append(ad
, fmt
, ap
, false);
353 atf_dynstr_clear(atf_dynstr_t
*ad
)
355 ad
->m_data
[0] = '\0';
360 atf_dynstr_prepend_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
366 err
= prepend_or_append(ad
, fmt
, ap2
, true);
373 atf_dynstr_prepend_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
379 err
= prepend_or_append(ad
, fmt
, ap
, true);
390 atf_equal_dynstr_cstring(const atf_dynstr_t
*ad
, const char *str
)
392 return strcmp(ad
->m_data
, str
) == 0;
396 atf_equal_dynstr_dynstr(const atf_dynstr_t
*s1
, const atf_dynstr_t
*s2
)
398 return strcmp(s1
->m_data
, s2
->m_data
) == 0;