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