1 1.1 christos /* Like vsprintf but provides a pointer to malloc'd storage, which must 2 1.1 christos be freed by the caller. 3 1.1.1.7 christos Copyright (C) 1994-2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This file is part of the libiberty library. 6 1.1 christos Libiberty is free software; you can redistribute it and/or 7 1.1 christos modify it under the terms of the GNU Library General Public 8 1.1 christos License as published by the Free Software Foundation; either 9 1.1 christos version 2 of the License, or (at your option) any later version. 10 1.1 christos 11 1.1 christos Libiberty is distributed in the hope that it will be useful, 12 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 1.1 christos Library General Public License for more details. 15 1.1 christos 16 1.1 christos You should have received a copy of the GNU Library General Public 17 1.1.1.2 christos License along with libiberty; see the file COPYING.LIB. If not, write 18 1.1.1.2 christos to the Free Software Foundation, Inc., 51 Franklin Street - Fifth 19 1.1.1.2 christos Floor, Boston, MA 02110-1301, USA. */ 20 1.1 christos 21 1.1 christos #ifdef HAVE_CONFIG_H 22 1.1 christos #include "config.h" 23 1.1 christos #endif 24 1.1 christos #include <ansidecl.h> 25 1.1 christos #include <stdarg.h> 26 1.1 christos #if !defined (va_copy) && defined (__va_copy) 27 1.1 christos # define va_copy(d,s) __va_copy((d),(s)) 28 1.1 christos #endif 29 1.1 christos #include <stdio.h> 30 1.1 christos #ifdef HAVE_STRING_H 31 1.1 christos #include <string.h> 32 1.1 christos #endif 33 1.1 christos #ifdef HAVE_STDLIB_H 34 1.1 christos #include <stdlib.h> 35 1.1 christos #else 36 1.1.1.6 christos extern void *malloc (); 37 1.1 christos #endif 38 1.1 christos #include "libiberty.h" 39 1.1.1.2 christos #include "vprintf-support.h" 40 1.1 christos 41 1.1 christos #ifdef TEST 42 1.1 christos int global_total_width; 43 1.1 christos #endif 44 1.1 christos 45 1.1 christos /* 46 1.1 christos 47 1.1 christos @deftypefn Extension int vasprintf (char **@var{resptr}, @ 48 1.1 christos const char *@var{format}, va_list @var{args}) 49 1.1 christos 50 1.1 christos Like @code{vsprintf}, but instead of passing a pointer to a buffer, 51 1.1 christos you pass a pointer to a pointer. This function will compute the size 52 1.1 christos of the buffer needed, allocate memory with @code{malloc}, and store a 53 1.1 christos pointer to the allocated memory in @code{*@var{resptr}}. The value 54 1.1 christos returned is the same as @code{vsprintf} would return. If memory could 55 1.1 christos not be allocated, minus one is returned and @code{NULL} is stored in 56 1.1 christos @code{*@var{resptr}}. 57 1.1 christos 58 1.1 christos @end deftypefn 59 1.1 christos 60 1.1 christos */ 61 1.1 christos 62 1.1 christos static int int_vasprintf (char **, const char *, va_list); 63 1.1 christos 64 1.1 christos static int 65 1.1 christos int_vasprintf (char **result, const char *format, va_list args) 66 1.1 christos { 67 1.1.1.2 christos int total_width = libiberty_vprintf_buffer_size (format, args); 68 1.1 christos #ifdef TEST 69 1.1 christos global_total_width = total_width; 70 1.1 christos #endif 71 1.1 christos *result = (char *) malloc (total_width); 72 1.1 christos if (*result != NULL) 73 1.1 christos return vsprintf (*result, format, args); 74 1.1 christos else 75 1.1 christos return -1; 76 1.1 christos } 77 1.1 christos 78 1.1 christos int 79 1.1 christos vasprintf (char **result, const char *format, 80 1.1 christos #if defined (_BSD_VA_LIST_) && defined (__FreeBSD__) 81 1.1 christos _BSD_VA_LIST_ args) 82 1.1 christos #else 83 1.1 christos va_list args) 84 1.1 christos #endif 85 1.1 christos { 86 1.1 christos return int_vasprintf (result, format, args); 87 1.1 christos } 88 1.1 christos 89 1.1 christos #ifdef TEST 90 1.1 christos static void ATTRIBUTE_PRINTF_1 91 1.1 christos checkit (const char *format, ...) 92 1.1 christos { 93 1.1 christos char *result; 94 1.1.1.2 christos va_list args; 95 1.1.1.2 christos va_start (args, format); 96 1.1 christos vasprintf (&result, format, args); 97 1.1.1.2 christos va_end (args); 98 1.1 christos 99 1.1 christos if (strlen (result) < (size_t) global_total_width) 100 1.1 christos printf ("PASS: "); 101 1.1 christos else 102 1.1 christos printf ("FAIL: "); 103 1.1 christos printf ("%d %s\n", global_total_width, result); 104 1.1 christos 105 1.1 christos free (result); 106 1.1 christos } 107 1.1 christos 108 1.1 christos extern int main (void); 109 1.1 christos 110 1.1 christos int 111 1.1 christos main (void) 112 1.1 christos { 113 1.1 christos checkit ("%d", 0x12345678); 114 1.1 christos checkit ("%200d", 5); 115 1.1 christos checkit ("%.300d", 6); 116 1.1 christos checkit ("%100.150d", 7); 117 1.1 christos checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ 118 1.1 christos 777777777777777777333333333333366666666666622222222222777777777777733333"); 119 1.1 christos checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); 120 1.1 christos 121 1.1 christos return 0; 122 1.1 christos } 123 1.1 christos #endif /* TEST */ 124