LibC: Implement {,v}asprintf

These were added in POSIX issue 8
This commit is contained in:
Bananymous 2025-06-17 13:56:30 +03:00
parent a9f58e96d2
commit ff289b25b6
2 changed files with 67 additions and 0 deletions

View File

@ -56,6 +56,7 @@ extern FILE* __stderr;
extern FILE* __stddbg; extern FILE* __stddbg;
#define stddbg __stddbg #define stddbg __stddbg
int asprintf(char** __restrict ptr, const char* __restrict format, ...);
void clearerr(FILE* stream); void clearerr(FILE* stream);
char* ctermid(char* s); char* ctermid(char* s);
int dprintf(int fildes, const char* __restrict format, ...); int dprintf(int fildes, const char* __restrict format, ...);
@ -116,6 +117,7 @@ char* tempnam(const char* dir, const char* pfx);
FILE* tmpfile(void); FILE* tmpfile(void);
char* tmpnam(char* s); char* tmpnam(char* s);
int ungetc(int c, FILE* stream); int ungetc(int c, FILE* stream);
int vasprintf(char** __restrict ptr, const char* __restrict format, va_list ap);
int vdprintf(int fildes, const char* __restrict format, va_list ap); int vdprintf(int fildes, const char* __restrict format, va_list ap);
int vfprintf(FILE* __restrict stream, const char* __restrict format, va_list ap); int vfprintf(FILE* __restrict stream, const char* __restrict format, va_list ap);
int vfscanf(FILE* __restrict stream, const char* __restrict format, va_list arg); int vfscanf(FILE* __restrict stream, const char* __restrict format, va_list arg);

View File

@ -120,6 +120,15 @@ static void _init_stdio()
s_files[STDDBG_FILENO].buffer_type = _IOLBF; s_files[STDDBG_FILENO].buffer_type = _IOLBF;
} }
int asprintf(char** __restrict ptr, const char* __restrict format, ...)
{
va_list arguments;
va_start(arguments, format);
int ret = vasprintf(ptr, format, arguments);
va_end(arguments);
return ret;
}
void clearerr(FILE* file) void clearerr(FILE* file)
{ {
ScopeLock _(file); ScopeLock _(file);
@ -1023,6 +1032,62 @@ int ungetc(int c, FILE* stream)
return ungetc_unlocked(c, stream); return ungetc_unlocked(c, stream);
} }
int vasprintf(char** __restrict ptr, const char* __restrict format, va_list ap)
{
struct print_info
{
char* buffer;
size_t capacity;
size_t length;
};
print_info info {
.buffer = nullptr,
.capacity = 0,
.length = 0,
};
info.buffer = static_cast<char*>(malloc(16));
if (info.buffer == nullptr)
return -1;
info.capacity = 16;
const int ret = printf_impl(format, ap,
[](int c, void* _info) -> int
{
auto& info = *static_cast<print_info*>(_info);
if (info.length + 1 >= info.capacity)
{
const size_t new_capacity = info.capacity * 2;
void* new_buffer = realloc(info.buffer, new_capacity);
if (new_buffer == nullptr)
{
free(info.buffer);
info.buffer = nullptr;
return EOF;
}
info.buffer = static_cast<char*>(new_buffer);
info.capacity = new_capacity;
}
info.buffer[info.length++] = c;
return 0;
}, &info
);
if (info.buffer == nullptr)
return -1;
ASSERT(info.length < info.capacity);
info.buffer[info.length] = '\0';
*ptr = info.buffer;
return ret;
}
int vdprintf(int fildes, const char* __restrict format, va_list arguments) int vdprintf(int fildes, const char* __restrict format, va_list arguments)
{ {
struct print_info struct print_info