Home | History | Annotate | Line # | Download | only in libiberty
      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