Imported Upstream version 1.15.1
[deb_xorg-server.git] / os / xprintf.c
CommitLineData
a09e091a
JB
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#include <errno.h>
68#include <string.h>
69
70#ifdef asprintf
71#undef asprintf
72#endif
73#ifdef vasprintf
74#undef vasprintf
75#endif
76
77#ifndef va_copy
78#ifdef __va_copy
79#define va_copy __va_copy
80#else
81#error "no working va_copy was found"
82#endif
83#endif
84
85/**
86 * Varargs sprintf that allocates a string buffer the right size for
87 * the pattern & data provided and prints the requested data to it.
88 *
89 * @param ret Pointer to which the newly allocated buffer is written
90 * (contents undefined on error)
91 * @param format printf style format string
92 * @param va variable argument list
93 * @return size of allocated buffer, or -1 on error.
94 */
95int
96Xvasprintf(char **ret, const char *_X_RESTRICT_KYWD format, va_list va)
97{
98#ifdef HAVE_VASPRINTF
99 return vasprintf(ret, format, va);
100#else
101 int size;
102 va_list va2;
103
104 va_copy(va2, va);
105 size = vsnprintf(NULL, 0, format, va2);
106 va_end(va2);
107
108 *ret = malloc(size + 1);
109 if (*ret == NULL)
110 return -1;
111
112 vsnprintf(*ret, size + 1, format, va);
113 (*ret)[size] = 0;
114 return size;
115#endif
116}
117
118#ifndef HAVE_VASPRINTF
119#define vasprintf Xvasprintf
120#endif
121
122/**
123 * sprintf that allocates a string buffer the right size for
124 * the pattern & data provided and prints the requested data to it.
125 *
126 * @param ret Pointer to which the newly allocated buffer is written
127 * (contents undefined on error)
128 * @param format printf style format string
129 * @param ... arguments for specified format
130 * @return size of allocated buffer, or -1 on error.
131 */
132int
133Xasprintf(char **ret, const char *_X_RESTRICT_KYWD format, ...)
134{
135 int size;
136 va_list va;
137
138 va_start(va, format);
139 size = vasprintf(ret, format, va);
140 va_end(va);
141 return size;
142}
143
144/**
145 * Varargs sprintf that allocates a string buffer the right size for
146 * the pattern & data provided and prints the requested data to it.
147 * On failure, issues a FatalError message and aborts the server.
148 *
149 * @param ret Pointer to which the newly allocated buffer is written
150 * (contents undefined on error)
151 * @param format printf style format string
152 * @param va variable argument list
153 * @return size of allocated buffer
154 */
155int
156XNFvasprintf(char **ret, const char *_X_RESTRICT_KYWD format, va_list va)
157{
158 int size = vasprintf(ret, format, va);
159
160 if ((size == -1) || (*ret == NULL)) {
161 FatalError("XNFvasprintf failed: %s", strerror(errno));
162 }
163 return size;
164}
165
166/**
167 * sprintf that allocates a string buffer the right size for
168 * the pattern & data provided and prints the requested data to it.
169 * On failure, issues a FatalError message and aborts the server.
170 *
171 * @param ret Pointer to which the newly allocated buffer is written
172 * (contents undefined on error)
173 * @param format printf style format string
174 * @param ... arguments for specified format
175 * @return size of allocated buffer
176 */
177int
178XNFasprintf(char **ret, const char *_X_RESTRICT_KYWD format, ...)
179{
180 int size;
181 va_list va;
182
183 va_start(va, format);
184 size = XNFvasprintf(ret, format, va);
185 va_end(va);
186 return size;
187}
188
189/**
190 * Varargs snprintf that returns the actual number of bytes (excluding final
191 * '\0') that were copied into the buffer.
192 * This is opposed to the normal sprintf() usually returns the number of bytes
193 * that would have been written.
194 *
195 * @param s buffer to copy into
196 * @param n size of buffer s
197 * @param format printf style format string
198 * @param va variable argument list
199 * @return number of bytes actually copied, excluding final '\0'
200 */
201int
202Xvscnprintf(char *s, int n, const char *format, va_list args)
203{
204 int x;
205 if (n == 0)
206 return 0;
207 x = vsnprintf(s, n , format, args);
208 return (x >= n) ? (n - 1) : x;
209}
210
211/**
212 * snprintf that returns the actual number of bytes (excluding final '\0') that
213 * were copied into the buffer.
214 * This is opposed to the normal sprintf() usually returns the number of bytes
215 * that would have been written.
216 *
217 * @param s buffer to copy into
218 * @param n size of buffer s
219 * @param format printf style format string
220 * @param ... arguments for specified format
221 * @return number of bytes actually copied, excluding final '\0'
222 */
223int Xscnprintf(char *s, int n, const char *format, ...)
224{
225 int x;
226 va_list ap;
227 va_start(ap, format);
228 x = Xvscnprintf(s, n, format, ap);
229 va_end(ap);
230 return x;
231}
232
233/* Old api, now deprecated, may be removed in the future */
234char *
235Xvprintf(const char *format, va_list va)
236{
237 char *ret;
238
239 if (vasprintf(&ret, format, va) == -1)
240 ret = NULL;
241
242 return ret;
243}
244
245char *
246Xprintf(const char *format, ...)
247{
248 char *ret;
249 va_list va;
250
251 va_start(va, format);
252 if (vasprintf(&ret, format, va) == -1)
253 ret = NULL;
254 va_end(va);
255 return ret;
256}
257
258char *
259XNFvprintf(const char *format, va_list va)
260{
261 char *ret;
262
263 XNFvasprintf(&ret, format, va);
264
265 return ret;
266}
267
268char *
269XNFprintf(const char *format, ...)
270{
271 char *ret;
272 va_list va;
273
274 va_start(va, format);
275 XNFvasprintf(&ret, format, va);
276 va_end(va);
277 return ret;
278}