xprintf.c revision 9ace9065
1/**
2 * @file
3 *
4 * @section DESCRIPTION
5 *
6 * These functions provide a portable implementation of the common (but not
7 * yet universal) asprintf & vasprintf routines to allocate a buffer big
8 * enough to sprintf the arguments to.  The XNF variants terminate the server
9 * if the allocation fails.
10 */
11/*
12 * Copyright (c) 2004 Alexander Gottwald
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
28 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 * DEALINGS IN THE SOFTWARE.
31 *
32 * Except as contained in this notice, the name(s) of the above copyright
33 * holders shall not be used in advertising or otherwise to promote the sale,
34 * use or other dealings in this Software without prior written authorization.
35 */
36/*
37 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
38 *
39 * Permission is hereby granted, free of charge, to any person obtaining a
40 * copy of this software and associated documentation files (the "Software"),
41 * to deal in the Software without restriction, including without limitation
42 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
43 * and/or sell copies of the Software, and to permit persons to whom the
44 * Software is furnished to do so, subject to the following conditions:
45 *
46 * The above copyright notice and this permission notice (including the next
47 * paragraph) shall be included in all copies or substantial portions of the
48 * Software.
49 *
50 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
53 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
55 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
56 * DEALINGS IN THE SOFTWARE.
57 */
58
59#ifdef HAVE_DIX_CONFIG_H
60#include <dix-config.h>
61#endif
62
63#include <X11/Xos.h>
64#include "os.h"
65#include <stdarg.h>
66#include <stdio.h>
67
68#ifdef asprintf
69# undef asprintf
70#endif
71#ifdef vasprintf
72# undef vasprintf
73#endif
74
75#ifndef va_copy
76# ifdef __va_copy
77#  define va_copy __va_copy
78# else
79#  error "no working va_copy was found"
80# endif
81#endif
82
83/**
84 * Varargs sprintf that allocates a string buffer the right size for
85 * the pattern & data provided and prints the requested data to it.
86 *
87 * @param ret     Pointer to which the newly allocated buffer is written
88 *                (contents undefined on error)
89 * @param format  printf style format string
90 * @param va      variable argument list
91 * @return        size of allocated buffer, or -1 on error.
92 */
93int
94Xvasprintf(char **ret, const char * _X_RESTRICT_KYWD format, va_list va)
95{
96#ifdef HAVE_VASPRINTF
97    return vasprintf(ret, format, va);
98#else
99    int size;
100    va_list va2;
101
102    va_copy(va2, va);
103    size = vsnprintf(NULL, 0, format, va2);
104    va_end(va2);
105
106    *ret = malloc(size + 1);
107    if (*ret == NULL)
108        return -1;
109
110    vsnprintf(*ret, size + 1, format, va);
111    (*ret)[size] = 0;
112    return size;
113#endif
114}
115
116#ifndef HAVE_VASPRINTF
117# define vasprintf Xvasprintf
118#endif
119
120/**
121 * sprintf that allocates a string buffer the right size for
122 * the pattern & data provided and prints the requested data to it.
123 *
124 * @param ret     Pointer to which the newly allocated buffer is written
125 *                (contents undefined on error)
126 * @param format  printf style format string
127 * @param ...     arguments for specified format
128 * @return        size of allocated buffer, or -1 on error.
129 */
130int
131Xasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...)
132{
133    int size;
134    va_list va;
135    va_start(va, format);
136    size = vasprintf(ret, format, va);
137    va_end(va);
138    return size;
139}
140
141/**
142 * Varargs sprintf that allocates a string buffer the right size for
143 * the pattern & data provided and prints the requested data to it.
144 * On failure, issues a FatalError message and aborts the server.
145 *
146 * @param ret     Pointer to which the newly allocated buffer is written
147 *                (contents undefined on error)
148 * @param format  printf style format string
149 * @param va      variable argument list
150 * @return        size of allocated buffer
151 */
152int
153XNFvasprintf(char **ret, const char * _X_RESTRICT_KYWD format, va_list va)
154{
155    int size = vasprintf(ret, format, va);
156    if ((size == -1) || (*ret == NULL)) {
157	Error("XNFvasprintf");
158	FatalError("XNFvasprintf failed");
159    }
160    return size;
161}
162
163/**
164 * sprintf that allocates a string buffer the right size for
165 * the pattern & data provided and prints the requested data to it.
166 * On failure, issues a FatalError message and aborts the server.
167 *
168 * @param ret     Pointer to which the newly allocated buffer is written
169 *                (contents undefined on error)
170 * @param format  printf style format string
171 * @param ...     arguments for specified format
172 * @return        size of allocated buffer
173 */
174int
175XNFasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...)
176{
177    int size;
178    va_list va;
179    va_start(va, format);
180    size = XNFvasprintf(ret, format, va);
181    va_end(va);
182    return size;
183}
184
185/* Old api, now deprecated, may be removed in the future */
186char *
187Xvprintf(const char *format, va_list va)
188{
189    char *ret;
190
191    if (vasprintf(&ret, format, va) == -1)
192	ret = NULL;
193
194    return ret;
195}
196
197char *Xprintf(const char *format, ...)
198{
199    char *ret;
200    va_list va;
201    va_start(va, format);
202    if (vasprintf(&ret, format, va) == -1)
203	ret = NULL;
204    va_end(va);
205    return ret;
206}
207
208char *
209XNFvprintf(const char *format, va_list va)
210{
211    char *ret;
212
213    XNFvasprintf(&ret, format, va);
214
215    return ret;
216}
217
218char *XNFprintf(const char *format, ...)
219{
220    char *ret;
221    va_list va;
222    va_start(va, format);
223    XNFvasprintf(&ret, format, va);
224    va_end(va);
225    return ret;
226}
227