1//==============================================================================
2//
3// Copyright (C) 2005 Jason Evans <jasone@canonware.com>.  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 are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice(s),
9//    this list of conditions and the following disclaimer unmodified other than
10//    the allowable addition of one or more copyright notices.
11//
12// 2. Redistributions in binary form must reproduce the above copyright
13//    notice(s), this list of conditions and the following disclaimer in the
14//    documentation and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) `AS IS' AND ANY EXPRESS
17// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
19// NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22// OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27//==============================================================================
28//
29// Emulate vasprintf() and asprintf().
30//
31//==============================================================================
32
33#include <stdlib.h>
34#include <stdio.h>
35#include <stdarg.h>
36
37static inline int
38vasprintf(char **rResult, const char *aFormat, va_list aAp)
39{
40    int rVal;
41    char *result;
42    va_list ap;
43#define XarAsprintfStartLen 16
44
45    result = (char *) malloc(XarAsprintfStartLen);
46    if (result == NULL)
47    {
48	rVal = -1;
49	goto RETURN;
50    }
51
52    va_copy(ap, aAp);
53    rVal = vsnprintf(result, XarAsprintfStartLen, aFormat, ap);
54    va_end(ap);
55
56    if (rVal == -1)
57    {
58	goto RETURN;
59    }
60    else if (rVal >= XarAsprintfStartLen)
61    {
62	free(result);
63	result = (char *) malloc(rVal + 1);
64	if (result == NULL)
65	{
66	    rVal = -1;
67	    goto RETURN;
68	}
69
70	va_copy(ap, aAp);
71	rVal = vsnprintf(result, rVal + 1, aFormat, aAp);
72	va_end(ap);
73    }
74
75    *rResult = result;
76    RETURN:
77#undef XarAsprintfStartLen
78    return rVal;
79}
80
81static int
82asprintf(char **rResult, const char *aFormat, ...)
83{
84    int rVal;
85    va_list ap;
86
87    va_start(ap, aFormat);
88    rVal = vasprintf(rResult, aFormat, ap);
89    va_end(ap);
90
91    return rVal;
92}
93