1 |
/* Like vsprintf but provides a pointer to malloc'd storage, which must |
/* Like vsprintf but provides a pointer to malloc'd storage, which must |
2 |
be freed by the caller. |
be freed by the caller. |
3 |
Copyright (C) 1994 Free Software Foundation, Inc. |
Copyright (C) 1994, 2003 Free Software Foundation, Inc. |
4 |
|
|
5 |
This file is part of the libiberty library. |
This file is part of the libiberty library. |
6 |
Libiberty is free software; you can redistribute it and/or |
Libiberty is free software; you can redistribute it and/or |
28 |
#include <varargs.h> |
#include <varargs.h> |
29 |
#endif |
#endif |
30 |
#include <stdio.h> |
#include <stdio.h> |
31 |
|
#ifdef HAVE_STRING_H |
32 |
#include <string.h> |
#include <string.h> |
33 |
|
#endif |
34 |
#ifdef HAVE_STDLIB_H |
#ifdef HAVE_STDLIB_H |
35 |
#include <stdlib.h> |
#include <stdlib.h> |
36 |
#else |
#else |
43 |
int global_total_width; |
int global_total_width; |
44 |
#endif |
#endif |
45 |
|
|
46 |
|
/* |
47 |
|
|
48 |
|
@deftypefn Extension int vasprintf (char **@var{resptr}, 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 PARAMS ((char **, const char *, va_list *)); |
static int int_vasprintf PARAMS ((char **, const char *, va_list)); |
63 |
|
|
64 |
static int |
static int |
65 |
int_vasprintf (result, format, args) |
int_vasprintf (result, format, args) |
66 |
char **result; |
char **result; |
67 |
const char *format; |
const char *format; |
68 |
va_list *args; |
va_list args; |
69 |
{ |
{ |
70 |
const char *p = format; |
const char *p = format; |
71 |
/* Add one to make sure that it is never zero, which might cause malloc |
/* Add one to make sure that it is never zero, which might cause malloc |
73 |
int total_width = strlen (format) + 1; |
int total_width = strlen (format) + 1; |
74 |
va_list ap; |
va_list ap; |
75 |
|
|
76 |
memcpy ((PTR) &ap, (PTR) args, sizeof (va_list)); |
#ifdef va_copy |
77 |
|
va_copy (ap, args); |
78 |
|
#else |
79 |
|
memcpy ((PTR) &ap, (PTR) &args, sizeof (va_list)); |
80 |
|
#endif |
81 |
|
|
82 |
while (*p != '\0') |
while (*p != '\0') |
83 |
{ |
{ |
139 |
p++; |
p++; |
140 |
} |
} |
141 |
} |
} |
142 |
|
#ifdef va_copy |
143 |
|
va_end (ap); |
144 |
|
#endif |
145 |
#ifdef TEST |
#ifdef TEST |
146 |
global_total_width = total_width; |
global_total_width = total_width; |
147 |
#endif |
#endif |
148 |
*result = malloc (total_width); |
*result = (char *) malloc (total_width); |
149 |
if (*result != NULL) |
if (*result != NULL) |
150 |
return vsprintf (*result, format, *args); |
return vsprintf (*result, format, args); |
151 |
else |
else |
152 |
return 0; |
return -1; |
153 |
} |
} |
154 |
|
|
155 |
int |
int |
162 |
va_list args; |
va_list args; |
163 |
#endif |
#endif |
164 |
{ |
{ |
165 |
return int_vasprintf (result, format, &args); |
return int_vasprintf (result, format, args); |
166 |
} |
} |
167 |
|
|
168 |
#ifdef TEST |
#ifdef TEST |
169 |
static void checkit PARAMS ((const char *, ...)); |
static void ATTRIBUTE_PRINTF_1 |
170 |
|
checkit VPARAMS ((const char *format, ...)) |
|
static void |
|
|
checkit VPARAMS ((const char* format, ...)) |
|
171 |
{ |
{ |
|
va_list args; |
|
172 |
char *result; |
char *result; |
173 |
#ifndef ANSI_PROTOTYPES |
VA_OPEN (args, format); |
174 |
const char *format; |
VA_FIXEDARG (args, const char *, format); |
|
#endif |
|
|
|
|
|
VA_START (args, format); |
|
|
|
|
|
#ifndef ANSI_PROTOTYPES |
|
|
format = va_arg (args, const char *); |
|
|
#endif |
|
|
|
|
175 |
vasprintf (&result, format, args); |
vasprintf (&result, format, args); |
176 |
|
VA_CLOSE (args); |
177 |
|
|
178 |
if (strlen (result) < (size_t) global_total_width) |
if (strlen (result) < (size_t) global_total_width) |
179 |
printf ("PASS: "); |
printf ("PASS: "); |
180 |
else |
else |
181 |
printf ("FAIL: "); |
printf ("FAIL: "); |
182 |
printf ("%d %s\n", global_total_width, result); |
printf ("%d %s\n", global_total_width, result); |
183 |
|
|
184 |
|
free (result); |
185 |
} |
} |
186 |
|
|
187 |
extern int main PARAMS ((void)); |
extern int main PARAMS ((void)); |