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