Merge from vendor branch CVS:
[dragonfly.git] / contrib / libarchive / archive_string_sprintf.c
1 /*-
2  * Copyright (c) 2003-2004 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD: src/lib/libarchive/archive_string_sprintf.c,v 1.6 2004/11/05 05:32:04 kientzle Exp $");
29
30 /*
31  * This uses 'printf' family functions, which can cause issues
32  * for size-critical applications.  I've separated it out to make
33  * this issue clear.  (Currently, it is called directly from within
34  * the core code, so it cannot easily be omitted.)
35  */
36
37 #include <stdio.h>
38
39 #include "archive_string.h"
40
41 /*
42  * Like 'vsprintf', but ensures the target is big enough, resizing if
43  * necessary.
44  */
45 void
46 __archive_string_vsprintf(struct archive_string *as, const char *fmt,
47     va_list ap)
48 {
49         size_t l;
50         va_list ap1;
51
52         if (fmt == NULL) {
53                 as->s[0] = 0;
54                 return;
55         }
56
57         va_copy(ap1, ap);
58         l = vsnprintf(as->s, as->buffer_length, fmt, ap);
59         /* If output is bigger than the buffer, resize and try again. */
60         if (l+1 >= as->buffer_length) {
61                 __archive_string_ensure(as, l + 1);
62                 l = vsnprintf(as->s, as->buffer_length, fmt, ap1);
63         }
64         as->length = l;
65         va_end(ap1);
66 }