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.
36 #include "atf-c/dynstr.h"
37 #include "atf-c/error.h"
38 #include "atf-c/sanity.h"
39 #include "atf-c/text.h"
41 /* ---------------------------------------------------------------------
42 * Auxiliary functions.
43 * --------------------------------------------------------------------- */
47 resize(atf_dynstr_t
*ad
, size_t newsize
)
52 PRE(newsize
> ad
->m_datasize
);
54 newdata
= (char *)malloc(newsize
);
55 if (newdata
== NULL
) {
56 err
= atf_no_memory_error();
58 strcpy(newdata
, ad
->m_data
);
61 ad
->m_datasize
= newsize
;
70 prepend_or_append(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
,
79 err
= atf_text_format_ap(&aux
, fmt
, ap2
);
81 if (atf_is_error(err
))
83 newlen
= ad
->m_length
+ strlen(aux
);
85 if (newlen
+ sizeof(char) > ad
->m_datasize
) {
86 err
= resize(ad
, newlen
+ sizeof(char));
87 if (atf_is_error(err
))
92 memmove(ad
->m_data
+ strlen(aux
), ad
->m_data
, ad
->m_length
+ 1);
93 memcpy(ad
->m_data
, aux
, strlen(aux
));
95 strcpy(ad
->m_data
+ ad
->m_length
, aux
);
96 ad
->m_length
= newlen
;
105 /* ---------------------------------------------------------------------
106 * The "atf_dynstr" type.
107 * --------------------------------------------------------------------- */
113 const size_t atf_dynstr_npos
= SIZE_MAX
;
116 * Constructors and destructors.
120 atf_dynstr_init(atf_dynstr_t
*ad
)
124 atf_object_init(&ad
->m_object
);
126 ad
->m_data
= (char *)malloc(sizeof(char));
127 if (ad
->m_data
== NULL
) {
128 err
= atf_no_memory_error();
132 ad
->m_data
[0] = '\0';
135 err
= atf_no_error();
139 atf_object_fini(&ad
->m_object
);
145 atf_dynstr_init_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
149 atf_object_init(&ad
->m_object
);
151 ad
->m_datasize
= strlen(fmt
) + 1;
159 ad
->m_data
= (char *)malloc(ad
->m_datasize
);
160 if (ad
->m_data
== NULL
) {
161 err
= atf_no_memory_error();
166 ret
= vsnprintf(ad
->m_data
, ad
->m_datasize
, fmt
, ap2
);
170 err
= atf_libc_error(errno
, "Cannot format string");
175 if ((size_t)ret
>= ad
->m_datasize
) {
180 } while (ad
->m_length
>= ad
->m_datasize
);
182 err
= atf_no_error();
186 atf_object_fini(&ad
->m_object
);
188 POST(atf_is_error(err
) || ad
->m_data
!= NULL
);
193 atf_dynstr_init_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
199 err
= atf_dynstr_init_ap(ad
, fmt
, ap
);
206 atf_dynstr_init_raw(atf_dynstr_t
*ad
, const void *mem
, size_t memlen
)
210 atf_object_init(&ad
->m_object
);
212 if (memlen
>= SIZE_MAX
- 1) {
213 err
= atf_no_memory_error();
217 ad
->m_data
= (char *)malloc(memlen
+ 1);
218 if (ad
->m_data
== NULL
) {
219 err
= atf_no_memory_error();
223 ad
->m_datasize
= memlen
+ 1;
224 memcpy(ad
->m_data
, mem
, memlen
);
225 ad
->m_data
[memlen
] = '\0';
226 ad
->m_length
= strlen(ad
->m_data
);
227 INV(ad
->m_length
<= memlen
);
228 err
= atf_no_error();
232 atf_object_fini(&ad
->m_object
);
238 atf_dynstr_init_rep(atf_dynstr_t
*ad
, size_t len
, char ch
)
242 atf_object_init(&ad
->m_object
);
244 if (len
== SIZE_MAX
) {
245 err
= atf_no_memory_error();
249 ad
->m_datasize
= (len
+ 1) * sizeof(char);
250 ad
->m_data
= (char *)malloc(ad
->m_datasize
);
251 if (ad
->m_data
== NULL
) {
252 err
= atf_no_memory_error();
256 memset(ad
->m_data
, ch
, len
);
257 ad
->m_data
[len
] = '\0';
259 err
= atf_no_error();
263 atf_object_fini(&ad
->m_object
);
269 atf_dynstr_init_substr(atf_dynstr_t
*ad
, const atf_dynstr_t
*src
,
270 size_t beg
, size_t end
)
272 if (beg
> src
->m_length
)
275 if (end
== atf_dynstr_npos
|| end
> src
->m_length
)
278 return atf_dynstr_init_raw(ad
, src
->m_data
+ beg
, end
- beg
);
282 atf_dynstr_copy(atf_dynstr_t
*dest
, const atf_dynstr_t
*src
)
286 atf_object_copy(&dest
->m_object
, &src
->m_object
);
288 dest
->m_data
= (char *)malloc(src
->m_datasize
);
289 if (dest
->m_data
== NULL
)
290 err
= atf_no_memory_error();
292 memcpy(dest
->m_data
, src
->m_data
, src
->m_datasize
);
293 dest
->m_datasize
= src
->m_datasize
;
294 dest
->m_length
= src
->m_length
;
295 err
= atf_no_error();
302 atf_dynstr_fini(atf_dynstr_t
*ad
)
304 INV(ad
->m_data
!= NULL
);
307 atf_object_fini(&ad
->m_object
);
311 atf_dynstr_fini_disown(atf_dynstr_t
*ad
)
313 atf_object_fini(&ad
->m_object
);
315 INV(ad
->m_data
!= NULL
);
324 atf_dynstr_cstring(const atf_dynstr_t
*ad
)
330 atf_dynstr_length(const atf_dynstr_t
*ad
)
336 atf_dynstr_rfind_ch(const atf_dynstr_t
*ad
, char ch
)
340 for (pos
= ad
->m_length
; pos
> 0 && ad
->m_data
[pos
- 1] != ch
; pos
--)
343 return pos
== 0 ? atf_dynstr_npos
: pos
- 1;
351 atf_dynstr_append_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
357 err
= prepend_or_append(ad
, fmt
, ap2
, false);
364 atf_dynstr_append_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
370 err
= prepend_or_append(ad
, fmt
, ap
, false);
377 atf_dynstr_clear(atf_dynstr_t
*ad
)
379 ad
->m_data
[0] = '\0';
384 atf_dynstr_prepend_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
390 err
= prepend_or_append(ad
, fmt
, ap2
, true);
397 atf_dynstr_prepend_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
403 err
= prepend_or_append(ad
, fmt
, ap
, true);
414 atf_equal_dynstr_cstring(const atf_dynstr_t
*ad
, const char *str
)
416 return strcmp(ad
->m_data
, str
) == 0;
420 atf_equal_dynstr_dynstr(const atf_dynstr_t
*s1
, const atf_dynstr_t
*s2
)
422 return strcmp(s1
->m_data
, s2
->m_data
) == 0;