xref: /netbsd-src/external/gpl3/gdb/dist/libiberty/vasprintf.c (revision 5173eb0a33e5d83890ba976253e703be4c92557c)
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