21 |
|
|
22 |
#include <assert.h> |
#include <assert.h> |
23 |
#include <errno.h> |
#include <errno.h> |
24 |
|
#include <limits.h> |
25 |
#include <stdarg.h> |
#include <stdarg.h> |
26 |
#include <stdio.h> |
#include <stdio.h> |
27 |
#include <string.h> |
#include <string.h> |
347 |
list = next; |
list = next; |
348 |
} |
} |
349 |
} |
} |
350 |
|
|
351 |
|
#ifndef HAVE_VASPRINTF |
352 |
|
int vasprintf(char ** s, const char * template, va_list a) { |
353 |
|
int size = 100; |
354 |
|
*s = malloc(size); |
355 |
|
if (*s == NULL) { |
356 |
|
return -1; |
357 |
|
} |
358 |
|
|
359 |
|
va_list copy; |
360 |
|
va_copy(copy, a); |
361 |
|
int result = vsnprintf(*s, size, template, copy); |
362 |
|
if (result >= size) { |
363 |
|
/* TODO: check for overflow? */ |
364 |
|
int new_size = result; |
365 |
|
if (new_size == INT_MAX) { |
366 |
|
free(*s); |
367 |
|
return - 1; |
368 |
|
} |
369 |
|
new_size++; |
370 |
|
char * new_s = realloc(*s, new_size); |
371 |
|
if (new_s == NULL) { |
372 |
|
free(*s); |
373 |
|
return -1; |
374 |
|
} |
375 |
|
*s = new_s; |
376 |
|
size = new_size; |
377 |
|
va_copy(copy, a); |
378 |
|
result = vsnprintf(*s, size, template, copy); |
379 |
|
assert(result == size - 1); |
380 |
|
} |
381 |
|
else if (result == -1) { |
382 |
|
while (result == -1) { |
383 |
|
if (size > INT_MAX / 2) { |
384 |
|
free(*s); |
385 |
|
return - 1; |
386 |
|
} |
387 |
|
int new_size = 2 * size; |
388 |
|
char * new_s = realloc(*s, new_size); |
389 |
|
if (new_s == NULL) { |
390 |
|
free(*s); |
391 |
|
return -1; |
392 |
|
} |
393 |
|
*s = new_s; |
394 |
|
size = new_size; |
395 |
|
va_copy(copy, a); |
396 |
|
result = vsnprintf(*s, size, template, copy); |
397 |
|
} |
398 |
|
assert(result <= size - 1); |
399 |
|
} |
400 |
|
|
401 |
|
return result; |
402 |
|
} |
403 |
|
#endif |
404 |
|
|
405 |
|
#ifndef HAVE_ASPRINTF |
406 |
|
int asprintf(char ** s, const char * template, ...) { |
407 |
|
va_list a; |
408 |
|
va_start(a, template); |
409 |
|
int result = vasprintf(s, template, a); |
410 |
|
va_end(a); |
411 |
|
return result; |
412 |
|
} |
413 |
|
#endif |
414 |
|
|