diff options
| -rw-r--r-- | tools/include/nolibc/stdio.h | 50 | ||||
| -rw-r--r-- | tools/testing/selftests/nolibc/nolibc-test.c | 24 |
2 files changed, 74 insertions, 0 deletions
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h index b6d14a58cfe7..ebdd413d13ec 100644 --- a/tools/include/nolibc/stdio.h +++ b/tools/include/nolibc/stdio.h @@ -795,6 +795,56 @@ int sprintf(char *buf, const char *fmt, ...) return ret; } +static __attribute__((unused, format(printf, 2, 0))) +int __nolibc_vasprintf(char **strp, const char *fmt, va_list args1, va_list args2) +{ + int len1, len2; + char *buf; + + len1 = vsnprintf(NULL, 0, fmt, args1); + if (len1 < 0) + return -1; + + buf = malloc(len1 + 1); + if (!buf) + return -1; + + len2 = vsnprintf(buf, len1 + 1, fmt, args2); + if (len2 < 0) { + free(buf); + return -1; + } + + *strp = buf; + return len1; +} + +static __attribute__((unused, format(printf, 2, 0))) +int vasprintf(char **strp, const char *fmt, va_list args) +{ + va_list args2; + int ret; + + va_copy(args2, args); + ret = __nolibc_vasprintf(strp, fmt, args, args2); + va_end(args2); + + return ret; +} + +static __attribute__((unused, format(printf, 2, 3))) +int asprintf(char **strp, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vasprintf(strp, fmt, args); + va_end(args); + + return ret; +} + static __attribute__((unused)) int vsscanf(const char *str, const char *format, va_list args) { diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 7606a8b68d28..91d95a152568 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1841,6 +1841,29 @@ static int test_printf_error(void) return 0; } +int test_asprintf(void) +{ + char *str; + int ret; + + ret = asprintf(&str, "foo%s", "bar"); + if (ret == -1) + return 1; + + if (ret != 6) { + free(str); + return 2; + } + + if (memcmp(str, "foobar", 6) != 0) { + free(str); + return 3; + } + + free(str); + return 0; +} + static int run_printf(int min, int max) { int test; @@ -1904,6 +1927,7 @@ static int run_printf(int min, int max) CASE_TEST(errno-neg); errno = -22; EXPECT_VFPRINTF(is_nolibc, "errno=-22 ", "%-12m"); break; CASE_TEST(scanf); EXPECT_ZR(1, test_scanf()); break; CASE_TEST(printf_error); EXPECT_ZR(1, test_printf_error()); break; + CASE_TEST(asprintf); EXPECT_ZR(1, test_asprintf()); break; case __LINE__: return ret; /* must be last */ /* note: do not set any defaults so as to permit holes above */ |
