/* * asprintf.c * * Author: Intel A80486DX2-66 * License: Creative Commons Zero 1.0 Universal */ #include "asprintf.h" ssize_t asprintf(char** strp, char* format, ...) { va_list args; va_start(args, format); ssize_t result = (ssize_t) vsnprintf(NULL, 0, format, args); if (result < 0) { va_end(args); return -1; } size_t size = (size_t) result + 1; *strp = malloc(size * sizeof(char)); if (*strp == NULL) { va_end(args); return -1; } result = (ssize_t) vsnprintf(*strp, size, format, args); va_end(args); if (result < 0) { free(*strp); return -1; } return result; } #ifdef TEST # include # include # include # define PRINT_ASSERT(caption, test) do { \ bool test_result = (test); \ printf("[test] " caption ": %s\n", test_result ? "OK" : "failed"); \ if (test_result == false) \ exit(EXIT_FAILURE); \ } while (0); int main(void) { const char* world = " world"; char* output; size_t result = asprintf(&output, "Hello%s! -- Unsigned 32-bit type is " "constrained to lie\nwithin the range of integer values from " "%" PRIu32 " to %" PRIu32 " inclusive.", world, 0, (uint32_t) (powf(2.0f, 32.0f) - 1.0f)); PRINT_ASSERT("segmentation fault", true); PRINT_ASSERT("no errors", errno == 0); PRINT_ASSERT("zero termination test", output[result] == '\0'); printf("[asprintf (%zu)] '%s'\n", result, output); return 0; } #endif