LibC: Implement {,v}asprintf
These were added in POSIX issue 8
This commit is contained in:
parent
a9f58e96d2
commit
ff289b25b6
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue