1 /* $NetBSD: dynstr.c,v 1.3 2014/12/10 04:38:03 christos Exp $ */
4 * Automated Testing Framework (atf)
6 * Copyright (c) 2008 The NetBSD Foundation, Inc.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
19 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
27 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include "atf-c/error.h"
45 /* ---------------------------------------------------------------------
46 * Auxiliary functions.
47 * --------------------------------------------------------------------- */
51 resize(atf_dynstr_t
*ad
, size_t newsize
)
56 PRE(newsize
> ad
->m_datasize
);
58 newdata
= (char *)malloc(newsize
);
59 if (newdata
== NULL
) {
60 err
= atf_no_memory_error();
62 strcpy(newdata
, ad
->m_data
);
65 ad
->m_datasize
= newsize
;
74 prepend_or_append(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
,
83 err
= atf_text_format_ap(&aux
, fmt
, ap2
);
85 if (atf_is_error(err
))
87 newlen
= ad
->m_length
+ strlen(aux
);
89 if (newlen
+ sizeof(char) > ad
->m_datasize
) {
90 err
= resize(ad
, newlen
+ sizeof(char));
91 if (atf_is_error(err
))
96 memmove(ad
->m_data
+ strlen(aux
), ad
->m_data
, ad
->m_length
+ 1);
97 memcpy(ad
->m_data
, aux
, strlen(aux
));
99 strcpy(ad
->m_data
+ ad
->m_length
, aux
);
100 ad
->m_length
= newlen
;
101 err
= atf_no_error();
109 /* ---------------------------------------------------------------------
110 * The "atf_dynstr" type.
111 * --------------------------------------------------------------------- */
117 const size_t atf_dynstr_npos
= SIZE_MAX
;
120 * Constructors and destructors.
124 atf_dynstr_init(atf_dynstr_t
*ad
)
128 ad
->m_data
= (char *)malloc(sizeof(char));
129 if (ad
->m_data
== NULL
) {
130 err
= atf_no_memory_error();
134 ad
->m_data
[0] = '\0';
137 err
= atf_no_error();
144 atf_dynstr_init_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
148 ad
->m_datasize
= strlen(fmt
) + 1;
156 ad
->m_data
= (char *)malloc(ad
->m_datasize
);
157 if (ad
->m_data
== NULL
) {
158 err
= atf_no_memory_error();
163 ret
= vsnprintf(ad
->m_data
, ad
->m_datasize
, fmt
, ap2
);
167 err
= atf_libc_error(errno
, "Cannot format string");
172 if ((size_t)ret
>= ad
->m_datasize
) {
177 } while (ad
->m_length
>= ad
->m_datasize
);
179 err
= atf_no_error();
181 POST(atf_is_error(err
) || ad
->m_data
!= NULL
);
186 atf_dynstr_init_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
192 err
= atf_dynstr_init_ap(ad
, fmt
, ap
);
199 atf_dynstr_init_raw(atf_dynstr_t
*ad
, const void *mem
, size_t memlen
)
203 if (memlen
>= SIZE_MAX
- 1) {
204 err
= atf_no_memory_error();
208 ad
->m_data
= (char *)malloc(memlen
+ 1);
209 if (ad
->m_data
== NULL
) {
210 err
= atf_no_memory_error();
214 ad
->m_datasize
= memlen
+ 1;
215 memcpy(ad
->m_data
, mem
, memlen
);
216 ad
->m_data
[memlen
] = '\0';
217 ad
->m_length
= strlen(ad
->m_data
);
218 INV(ad
->m_length
<= memlen
);
219 err
= atf_no_error();
226 atf_dynstr_init_rep(atf_dynstr_t
*ad
, size_t len
, char ch
)
230 if (len
== SIZE_MAX
) {
231 err
= atf_no_memory_error();
235 ad
->m_datasize
= (len
+ 1) * sizeof(char);
236 ad
->m_data
= (char *)malloc(ad
->m_datasize
);
237 if (ad
->m_data
== NULL
) {
238 err
= atf_no_memory_error();
242 memset(ad
->m_data
, ch
, len
);
243 ad
->m_data
[len
] = '\0';
245 err
= atf_no_error();
252 atf_dynstr_init_substr(atf_dynstr_t
*ad
, const atf_dynstr_t
*src
,
253 size_t beg
, size_t end
)
255 if (beg
> src
->m_length
)
258 if (end
== atf_dynstr_npos
|| end
> src
->m_length
)
261 return atf_dynstr_init_raw(ad
, src
->m_data
+ beg
, end
- beg
);
265 atf_dynstr_copy(atf_dynstr_t
*dest
, const atf_dynstr_t
*src
)
269 dest
->m_data
= (char *)malloc(src
->m_datasize
);
270 if (dest
->m_data
== NULL
)
271 err
= atf_no_memory_error();
273 memcpy(dest
->m_data
, src
->m_data
, src
->m_datasize
);
274 dest
->m_datasize
= src
->m_datasize
;
275 dest
->m_length
= src
->m_length
;
276 err
= atf_no_error();
283 atf_dynstr_fini(atf_dynstr_t
*ad
)
285 INV(ad
->m_data
!= NULL
);
290 atf_dynstr_fini_disown(atf_dynstr_t
*ad
)
292 INV(ad
->m_data
!= NULL
);
301 atf_dynstr_cstring(const atf_dynstr_t
*ad
)
307 atf_dynstr_length(const atf_dynstr_t
*ad
)
313 atf_dynstr_rfind_ch(const atf_dynstr_t
*ad
, char ch
)
317 for (pos
= ad
->m_length
; pos
> 0 && ad
->m_data
[pos
- 1] != ch
; pos
--)
320 return pos
== 0 ? atf_dynstr_npos
: pos
- 1;
328 atf_dynstr_append_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
334 err
= prepend_or_append(ad
, fmt
, ap2
, false);
341 atf_dynstr_append_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
347 err
= prepend_or_append(ad
, fmt
, ap
, false);
354 atf_dynstr_clear(atf_dynstr_t
*ad
)
356 ad
->m_data
[0] = '\0';
361 atf_dynstr_prepend_ap(atf_dynstr_t
*ad
, const char *fmt
, va_list ap
)
367 err
= prepend_or_append(ad
, fmt
, ap2
, true);
374 atf_dynstr_prepend_fmt(atf_dynstr_t
*ad
, const char *fmt
, ...)
380 err
= prepend_or_append(ad
, fmt
, ap
, true);
391 atf_equal_dynstr_cstring(const atf_dynstr_t
*ad
, const char *str
)
393 return strcmp(ad
->m_data
, str
) == 0;
397 atf_equal_dynstr_dynstr(const atf_dynstr_t
*s1
, const atf_dynstr_t
*s2
)
399 return strcmp(s1
->m_data
, s2
->m_data
) == 0;