@@ -259,4 +259,91 @@ size_t strerrorlen_s(errno_t errnum)
259259
260260#endif /* !HAVE_STRERRORLEN_S */
261261
262+ #ifndef HAVE_ASPRINTF
263+
264+ extern int vasprintf (char * * str , const char * fmt , va_list ap );
265+
266+ extern int asprintf (char * * str , const char * fmt , ...);
267+
268+ #ifdef C89STRINGUTILS_IMPLEMENTATION
269+
270+ #define HAVE_ASPRINTF
271+
272+ #include <errno.h>
273+ #include <limits.h> /* for INT_MAX */
274+ #include <stdlib.h>
275+
276+ #ifndef VA_COPY
277+ # if defined(HAVE_VA_COPY ) || defined(va_copy )
278+ # define VA_COPY (dest , src ) va_copy(dest, src)
279+ # else
280+ # ifdef HAVE___VA_COPY
281+ # define VA_COPY (dest , src ) __va_copy(dest, src)
282+ # else
283+ # define VA_COPY (dest , src ) (dest) = (src)
284+ # endif
285+ # endif
286+ #endif /* ! VA_COPY */
287+
288+ #define INIT_SZ 128
289+
290+ extern int
291+ vasprintf (char * * str , const char * fmt , va_list ap )
292+ {
293+ int ret ;
294+ va_list ap2 ;
295+ char * string , * newstr ;
296+ size_t len ;
297+
298+ if ((string = (char * ) malloc (INIT_SZ )) == NULL )
299+ goto fail ;
300+
301+ VA_COPY (ap2 , ap );
302+ ret = vsnprintf (string , INIT_SZ , fmt , ap2 );
303+ va_end (ap2 );
304+ if (ret >= 0 && ret < INIT_SZ ) { /* succeeded with initial alloc */
305+ * str = string ;
306+ } else if (ret == INT_MAX || ret < 0 ) { /* Bad length */
307+ free (string );
308+ goto fail ;
309+ } else { /* bigger than initial, realloc allowing for nul */
310+ len = (size_t )ret + 1 ;
311+ if ((newstr = (char * )realloc (string , len )) == NULL ) {
312+ free (string );
313+ goto fail ;
314+ }
315+ VA_COPY (ap2 , ap );
316+ ret = vsnprintf (newstr , len , fmt , ap2 );
317+ va_end (ap2 );
318+ if (ret < 0 || (size_t )ret >= len ) { /* failed with realloc'ed string */
319+ free (newstr );
320+ goto fail ;
321+ }
322+ * str = newstr ;
323+ }
324+ return ret ;
325+
326+ fail :
327+ * str = NULL ;
328+ errno = ENOMEM ;
329+ return -1 ;
330+ }
331+
332+ extern int asprintf (char * * str , const char * fmt , ...)
333+ {
334+ va_list ap ;
335+ int ret ;
336+
337+ * str = NULL ;
338+ va_start (ap , fmt );
339+ ret = vasprintf (str , fmt , ap );
340+ va_end (ap );
341+
342+ return ret ;
343+ }
344+
345+ #endif /* C89STRINGUTILS_IMPLEMENTATION */
346+
347+ #endif /* !HAVE_ASPRINTF */
348+
262349#endif /* ! C89STRINGUTILS_STRING_EXTRAS_H */
0 commit comments