198b9484cSchristos /* Like vsprintf but provides a pointer to malloc'd storage, which must 298b9484cSchristos be freed by the caller. 3*5173eb0aSchristos Copyright (C) 1994-2024 Free Software Foundation, Inc. 498b9484cSchristos 598b9484cSchristos This file is part of the libiberty library. 698b9484cSchristos Libiberty is free software; you can redistribute it and/or 798b9484cSchristos modify it under the terms of the GNU Library General Public 898b9484cSchristos License as published by the Free Software Foundation; either 998b9484cSchristos version 2 of the License, or (at your option) any later version. 1098b9484cSchristos 1198b9484cSchristos Libiberty is distributed in the hope that it will be useful, 1298b9484cSchristos but WITHOUT ANY WARRANTY; without even the implied warranty of 1398b9484cSchristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1498b9484cSchristos Library General Public License for more details. 1598b9484cSchristos 1698b9484cSchristos You should have received a copy of the GNU Library General Public 17837edd6bSchristos License along with libiberty; see the file COPYING.LIB. If not, write 18837edd6bSchristos to the Free Software Foundation, Inc., 51 Franklin Street - Fifth 19837edd6bSchristos Floor, Boston, MA 02110-1301, USA. */ 2098b9484cSchristos 2198b9484cSchristos #ifdef HAVE_CONFIG_H 2298b9484cSchristos #include "config.h" 2398b9484cSchristos #endif 2498b9484cSchristos #include <ansidecl.h> 2598b9484cSchristos #include <stdarg.h> 2698b9484cSchristos #if !defined (va_copy) && defined (__va_copy) 2798b9484cSchristos # define va_copy(d,s) __va_copy((d),(s)) 2898b9484cSchristos #endif 2998b9484cSchristos #include <stdio.h> 3098b9484cSchristos #ifdef HAVE_STRING_H 3198b9484cSchristos #include <string.h> 3298b9484cSchristos #endif 3398b9484cSchristos #ifdef HAVE_STDLIB_H 3498b9484cSchristos #include <stdlib.h> 3598b9484cSchristos #else 364b169a6bSchristos extern void *malloc (); 3798b9484cSchristos #endif 3898b9484cSchristos #include "libiberty.h" 39837edd6bSchristos #include "vprintf-support.h" 4098b9484cSchristos 4198b9484cSchristos #ifdef TEST 4298b9484cSchristos int global_total_width; 4398b9484cSchristos #endif 4498b9484cSchristos 4598b9484cSchristos /* 4698b9484cSchristos 4798b9484cSchristos @deftypefn Extension int vasprintf (char **@var{resptr}, @ 4898b9484cSchristos const char *@var{format}, va_list @var{args}) 4998b9484cSchristos 5098b9484cSchristos Like @code{vsprintf}, but instead of passing a pointer to a buffer, 5198b9484cSchristos you pass a pointer to a pointer. This function will compute the size 5298b9484cSchristos of the buffer needed, allocate memory with @code{malloc}, and store a 5398b9484cSchristos pointer to the allocated memory in @code{*@var{resptr}}. The value 5498b9484cSchristos returned is the same as @code{vsprintf} would return. If memory could 5598b9484cSchristos not be allocated, minus one is returned and @code{NULL} is stored in 5698b9484cSchristos @code{*@var{resptr}}. 5798b9484cSchristos 5898b9484cSchristos @end deftypefn 5998b9484cSchristos 6098b9484cSchristos */ 6198b9484cSchristos 6298b9484cSchristos static int int_vasprintf (char **, const char *, va_list); 6398b9484cSchristos 6498b9484cSchristos static int 6598b9484cSchristos int_vasprintf (char **result, const char *format, va_list args) 6698b9484cSchristos { 67837edd6bSchristos int total_width = libiberty_vprintf_buffer_size (format, args); 6898b9484cSchristos #ifdef TEST 6998b9484cSchristos global_total_width = total_width; 7098b9484cSchristos #endif 7198b9484cSchristos *result = (char *) malloc (total_width); 7298b9484cSchristos if (*result != NULL) 7398b9484cSchristos return vsprintf (*result, format, args); 7498b9484cSchristos else 7598b9484cSchristos return -1; 7698b9484cSchristos } 7798b9484cSchristos 7898b9484cSchristos int 7998b9484cSchristos vasprintf (char **result, const char *format, 8098b9484cSchristos #if defined (_BSD_VA_LIST_) && defined (__FreeBSD__) 8198b9484cSchristos _BSD_VA_LIST_ args) 8298b9484cSchristos #else 8398b9484cSchristos va_list args) 8498b9484cSchristos #endif 8598b9484cSchristos { 8698b9484cSchristos return int_vasprintf (result, format, args); 8798b9484cSchristos } 8898b9484cSchristos 8998b9484cSchristos #ifdef TEST 9098b9484cSchristos static void ATTRIBUTE_PRINTF_1 9198b9484cSchristos checkit (const char *format, ...) 9298b9484cSchristos { 9398b9484cSchristos char *result; 94837edd6bSchristos va_list args; 95837edd6bSchristos va_start (args, format); 9698b9484cSchristos vasprintf (&result, format, args); 97837edd6bSchristos va_end (args); 9898b9484cSchristos 9998b9484cSchristos if (strlen (result) < (size_t) global_total_width) 10098b9484cSchristos printf ("PASS: "); 10198b9484cSchristos else 10298b9484cSchristos printf ("FAIL: "); 10398b9484cSchristos printf ("%d %s\n", global_total_width, result); 10498b9484cSchristos 10598b9484cSchristos free (result); 10698b9484cSchristos } 10798b9484cSchristos 10898b9484cSchristos extern int main (void); 10998b9484cSchristos 11098b9484cSchristos int 11198b9484cSchristos main (void) 11298b9484cSchristos { 11398b9484cSchristos checkit ("%d", 0x12345678); 11498b9484cSchristos checkit ("%200d", 5); 11598b9484cSchristos checkit ("%.300d", 6); 11698b9484cSchristos checkit ("%100.150d", 7); 11798b9484cSchristos checkit ("%s", "jjjjjjjjjiiiiiiiiiiiiiiioooooooooooooooooppppppppppppaa\n\ 11898b9484cSchristos 777777777777777777333333333333366666666666622222222222777777777777733333"); 11998b9484cSchristos checkit ("%f%s%d%s", 1.0, "foo", 77, "asdjffffffffffffffiiiiiiiiiiixxxxx"); 12098b9484cSchristos 12198b9484cSchristos return 0; 12298b9484cSchristos } 12398b9484cSchristos #endif /* TEST */ 124