1706f2543Smrg/** 2706f2543Smrg * @file 3706f2543Smrg * 4706f2543Smrg * @section DESCRIPTION 5706f2543Smrg * 6706f2543Smrg * These functions provide a portable implementation of the common (but not 7706f2543Smrg * yet universal) asprintf & vasprintf routines to allocate a buffer big 8706f2543Smrg * enough to sprintf the arguments to. The XNF variants terminate the server 9706f2543Smrg * if the allocation fails. 10706f2543Smrg */ 11706f2543Smrg/* 12706f2543Smrg * Copyright (c) 2004 Alexander Gottwald 13706f2543Smrg * 14706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 15706f2543Smrg * copy of this software and associated documentation files (the "Software"), 16706f2543Smrg * to deal in the Software without restriction, including without limitation 17706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 18706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 19706f2543Smrg * Software is furnished to do so, subject to the following conditions: 20706f2543Smrg * 21706f2543Smrg * The above copyright notice and this permission notice shall be included in 22706f2543Smrg * all copies or substantial portions of the Software. 23706f2543Smrg * 24706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 27706f2543Smrg * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 28706f2543Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 29706f2543Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 30706f2543Smrg * DEALINGS IN THE SOFTWARE. 31706f2543Smrg * 32706f2543Smrg * Except as contained in this notice, the name(s) of the above copyright 33706f2543Smrg * holders shall not be used in advertising or otherwise to promote the sale, 34706f2543Smrg * use or other dealings in this Software without prior written authorization. 35706f2543Smrg */ 36706f2543Smrg/* 37706f2543Smrg * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 38706f2543Smrg * 39706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining a 40706f2543Smrg * copy of this software and associated documentation files (the "Software"), 41706f2543Smrg * to deal in the Software without restriction, including without limitation 42706f2543Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 43706f2543Smrg * and/or sell copies of the Software, and to permit persons to whom the 44706f2543Smrg * Software is furnished to do so, subject to the following conditions: 45706f2543Smrg * 46706f2543Smrg * The above copyright notice and this permission notice (including the next 47706f2543Smrg * paragraph) shall be included in all copies or substantial portions of the 48706f2543Smrg * Software. 49706f2543Smrg * 50706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 51706f2543Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 52706f2543Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 53706f2543Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 54706f2543Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 55706f2543Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 56706f2543Smrg * DEALINGS IN THE SOFTWARE. 57706f2543Smrg */ 58706f2543Smrg 59706f2543Smrg#ifdef HAVE_DIX_CONFIG_H 60706f2543Smrg#include <dix-config.h> 61706f2543Smrg#endif 62706f2543Smrg 63706f2543Smrg#include <X11/Xos.h> 64706f2543Smrg#include "os.h" 65706f2543Smrg#include <stdarg.h> 66706f2543Smrg#include <stdio.h> 67706f2543Smrg 68706f2543Smrg#ifdef asprintf 69706f2543Smrg# undef asprintf 70706f2543Smrg#endif 71706f2543Smrg#ifdef vasprintf 72706f2543Smrg# undef vasprintf 73706f2543Smrg#endif 74706f2543Smrg 75706f2543Smrg#ifndef va_copy 76706f2543Smrg# ifdef __va_copy 77706f2543Smrg# define va_copy __va_copy 78706f2543Smrg# else 79706f2543Smrg# error "no working va_copy was found" 80706f2543Smrg# endif 81706f2543Smrg#endif 82706f2543Smrg 83706f2543Smrg/** 84706f2543Smrg * Varargs sprintf that allocates a string buffer the right size for 85706f2543Smrg * the pattern & data provided and prints the requested data to it. 86706f2543Smrg * 87706f2543Smrg * @param ret Pointer to which the newly allocated buffer is written 88706f2543Smrg * (contents undefined on error) 89706f2543Smrg * @param format printf style format string 90706f2543Smrg * @param va variable argument list 91706f2543Smrg * @return size of allocated buffer, or -1 on error. 92706f2543Smrg */ 93706f2543Smrgint 94706f2543SmrgXvasprintf(char **ret, const char * _X_RESTRICT_KYWD format, va_list va) 95706f2543Smrg{ 96706f2543Smrg#ifdef HAVE_VASPRINTF 97706f2543Smrg return vasprintf(ret, format, va); 98706f2543Smrg#else 99706f2543Smrg int size; 100706f2543Smrg va_list va2; 101706f2543Smrg 102706f2543Smrg va_copy(va2, va); 103706f2543Smrg size = vsnprintf(NULL, 0, format, va2); 104706f2543Smrg va_end(va2); 105706f2543Smrg 106706f2543Smrg *ret = malloc(size + 1); 107706f2543Smrg if (*ret == NULL) 108706f2543Smrg return -1; 109706f2543Smrg 110706f2543Smrg vsnprintf(*ret, size + 1, format, va); 111706f2543Smrg (*ret)[size] = 0; 112706f2543Smrg return size; 113706f2543Smrg#endif 114706f2543Smrg} 115706f2543Smrg 116706f2543Smrg#ifndef HAVE_VASPRINTF 117706f2543Smrg# define vasprintf Xvasprintf 118706f2543Smrg#endif 119706f2543Smrg 120706f2543Smrg/** 121706f2543Smrg * sprintf that allocates a string buffer the right size for 122706f2543Smrg * the pattern & data provided and prints the requested data to it. 123706f2543Smrg * 124706f2543Smrg * @param ret Pointer to which the newly allocated buffer is written 125706f2543Smrg * (contents undefined on error) 126706f2543Smrg * @param format printf style format string 127706f2543Smrg * @param ... arguments for specified format 128706f2543Smrg * @return size of allocated buffer, or -1 on error. 129706f2543Smrg */ 130706f2543Smrgint 131706f2543SmrgXasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...) 132706f2543Smrg{ 133706f2543Smrg int size; 134706f2543Smrg va_list va; 135706f2543Smrg va_start(va, format); 136706f2543Smrg size = vasprintf(ret, format, va); 137706f2543Smrg va_end(va); 138706f2543Smrg return size; 139706f2543Smrg} 140706f2543Smrg 141706f2543Smrg/** 142706f2543Smrg * Varargs sprintf that allocates a string buffer the right size for 143706f2543Smrg * the pattern & data provided and prints the requested data to it. 144706f2543Smrg * On failure, issues a FatalError message and aborts the server. 145706f2543Smrg * 146706f2543Smrg * @param ret Pointer to which the newly allocated buffer is written 147706f2543Smrg * (contents undefined on error) 148706f2543Smrg * @param format printf style format string 149706f2543Smrg * @param va variable argument list 150706f2543Smrg * @return size of allocated buffer 151706f2543Smrg */ 152706f2543Smrgint 153706f2543SmrgXNFvasprintf(char **ret, const char * _X_RESTRICT_KYWD format, va_list va) 154706f2543Smrg{ 155706f2543Smrg int size = vasprintf(ret, format, va); 156706f2543Smrg if ((size == -1) || (*ret == NULL)) { 157706f2543Smrg Error("XNFvasprintf"); 158706f2543Smrg FatalError("XNFvasprintf failed"); 159706f2543Smrg } 160706f2543Smrg return size; 161706f2543Smrg} 162706f2543Smrg 163706f2543Smrg/** 164706f2543Smrg * sprintf that allocates a string buffer the right size for 165706f2543Smrg * the pattern & data provided and prints the requested data to it. 166706f2543Smrg * On failure, issues a FatalError message and aborts the server. 167706f2543Smrg * 168706f2543Smrg * @param ret Pointer to which the newly allocated buffer is written 169706f2543Smrg * (contents undefined on error) 170706f2543Smrg * @param format printf style format string 171706f2543Smrg * @param ... arguments for specified format 172706f2543Smrg * @return size of allocated buffer 173706f2543Smrg */ 174706f2543Smrgint 175706f2543SmrgXNFasprintf(char ** ret, const char * _X_RESTRICT_KYWD format, ...) 176706f2543Smrg{ 177706f2543Smrg int size; 178706f2543Smrg va_list va; 179706f2543Smrg va_start(va, format); 180706f2543Smrg size = XNFvasprintf(ret, format, va); 181706f2543Smrg va_end(va); 182706f2543Smrg return size; 183706f2543Smrg} 184706f2543Smrg 185706f2543Smrg/* Old api, now deprecated, may be removed in the future */ 186706f2543Smrgchar * 187706f2543SmrgXvprintf(const char *format, va_list va) 188706f2543Smrg{ 189706f2543Smrg char *ret; 190706f2543Smrg 191706f2543Smrg if (vasprintf(&ret, format, va) == -1) 192706f2543Smrg ret = NULL; 193706f2543Smrg 194706f2543Smrg return ret; 195706f2543Smrg} 196706f2543Smrg 197706f2543Smrgchar *Xprintf(const char *format, ...) 198706f2543Smrg{ 199706f2543Smrg char *ret; 200706f2543Smrg va_list va; 201706f2543Smrg va_start(va, format); 202706f2543Smrg if (vasprintf(&ret, format, va) == -1) 203706f2543Smrg ret = NULL; 204706f2543Smrg va_end(va); 205706f2543Smrg return ret; 206706f2543Smrg} 207706f2543Smrg 208706f2543Smrgchar * 209706f2543SmrgXNFvprintf(const char *format, va_list va) 210706f2543Smrg{ 211706f2543Smrg char *ret; 212706f2543Smrg 213706f2543Smrg XNFvasprintf(&ret, format, va); 214706f2543Smrg 215706f2543Smrg return ret; 216706f2543Smrg} 217706f2543Smrg 218706f2543Smrgchar *XNFprintf(const char *format, ...) 219706f2543Smrg{ 220706f2543Smrg char *ret; 221706f2543Smrg va_list va; 222706f2543Smrg va_start(va, format); 223706f2543Smrg XNFvasprintf(&ret, format, va); 224706f2543Smrg va_end(va); 225706f2543Smrg return ret; 226706f2543Smrg} 227