mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 20:37:35 +00:00
LibC+AK: Implement all sorts of wprintf variants
This commit is contained in:
parent
db7a6d6e74
commit
f0709c7a24
6 changed files with 93 additions and 37 deletions
|
@ -19,8 +19,8 @@ struct SingleEntryListNext {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename PutChFunc, typename ArgumentListRefT, template<typename T, typename U = ArgumentListRefT> typename NextArgument>
|
||||
struct PrintfImpl : public PrintfImplementation::PrintfImpl<PutChFunc, ArgumentListRefT, NextArgument> {
|
||||
template<typename PutChFunc, typename ArgumentListRefT, template<typename T, typename U = ArgumentListRefT> typename NextArgument, typename CharType>
|
||||
struct PrintfImpl : public PrintfImplementation::PrintfImpl<PutChFunc, ArgumentListRefT, NextArgument, CharType> {
|
||||
ALWAYS_INLINE PrintfImpl(PutChFunc& putch, char*& bufptr, const int& nwritten)
|
||||
: PrintfImplementation::PrintfImpl<PutChFunc, ArgumentListRefT, NextArgument>(putch, bufptr, nwritten)
|
||||
{
|
||||
|
|
|
@ -479,12 +479,6 @@ long double wcstold(wchar_t const*, wchar_t**)
|
|||
TODO();
|
||||
}
|
||||
|
||||
int swprintf(wchar_t*, size_t, wchar_t const*, ...)
|
||||
{
|
||||
dbgln("TODO: Implement swprintf()");
|
||||
TODO();
|
||||
}
|
||||
|
||||
int wcwidth(wchar_t wc)
|
||||
{
|
||||
if (wc == L'\0')
|
||||
|
|
|
@ -61,7 +61,6 @@ unsigned long long wcstoull(const wchar_t*, wchar_t**, int);
|
|||
float wcstof(const wchar_t*, wchar_t**);
|
||||
double wcstod(const wchar_t*, wchar_t**);
|
||||
long double wcstold(const wchar_t*, wchar_t**);
|
||||
int swprintf(wchar_t*, size_t, const wchar_t*, ...);
|
||||
int wcwidth(wchar_t);
|
||||
size_t wcsrtombs(char*, const wchar_t**, size_t, mbstate_t*);
|
||||
size_t mbsrtowcs(wchar_t*, const char**, size_t, mbstate_t*);
|
||||
|
@ -81,4 +80,11 @@ wchar_t* fgetws(wchar_t* __restrict ws, int n, FILE* __restrict stream);
|
|||
int fputws(const wchar_t* __restrict ws, FILE* __restrict stream);
|
||||
int fwide(FILE* stream, int mode);
|
||||
|
||||
int wprintf(const wchar_t* __restrict format, ...);
|
||||
int fwprintf(FILE* __restrict stream, const wchar_t* __restrict format, ...);
|
||||
int swprintf(wchar_t* __restrict wcs, size_t maxlen, const wchar_t* __restrict format, ...);
|
||||
int vwprintf(const wchar_t* __restrict format, va_list args);
|
||||
int vfwprintf(FILE* __restrict stream, const wchar_t* __restrict format, va_list args);
|
||||
int vswprintf(wchar_t* __restrict wcs, size_t maxlen, const wchar_t* __restrict format, va_list args);
|
||||
|
||||
__END_DECLS
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/BitCast.h>
|
||||
#include <AK/PrintfImplementation.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
#include <AK/Types.h>
|
||||
#include <bits/stdio_file_implementation.h>
|
||||
|
@ -118,4 +119,59 @@ int fputws(wchar_t const* __restrict ws, FILE* __restrict stream)
|
|||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
int wprintf(wchar_t const* __restrict format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
auto rc = vfwprintf(stdout, format, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int fwprintf(FILE* __restrict stream, wchar_t const* __restrict format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
auto rc = vfwprintf(stream, format, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int swprintf(wchar_t* __restrict wcs, size_t max_length, wchar_t const* __restrict format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
auto rc = vswprintf(wcs, max_length, format, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int vwprintf(wchar_t const* __restrict format, va_list args)
|
||||
{
|
||||
return vfwprintf(stdout, format, args);
|
||||
}
|
||||
|
||||
int vfwprintf(FILE* __restrict stream, wchar_t const* __restrict format, va_list args)
|
||||
{
|
||||
auto const* fmt = bit_cast<wchar_t const*>(format);
|
||||
return printf_internal([stream](wchar_t*&, wchar_t wc) {
|
||||
putwc(wc, stream);
|
||||
},
|
||||
nullptr, fmt, args);
|
||||
}
|
||||
|
||||
int vswprintf(wchar_t* __restrict wcs, size_t max_length, wchar_t const* __restrict format, va_list args)
|
||||
{
|
||||
auto const* fmt = bit_cast<wchar_t const*>(format);
|
||||
size_t length_so_far = 0;
|
||||
printf_internal([max_length, &length_so_far](wchar_t*& buffer, wchar_t wc) {
|
||||
if (length_so_far > max_length)
|
||||
return;
|
||||
*buffer++ = wc;
|
||||
++length_so_far;
|
||||
},
|
||||
wcs, fmt, args);
|
||||
return static_cast<int>(length_so_far);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
exit(1);
|
||||
}
|
||||
|
||||
template<typename PutChFunc, typename ArgumentListRefT, template<typename T, typename U = ArgumentListRefT> typename NextArgument>
|
||||
struct PrintfImpl : public PrintfImplementation::PrintfImpl<PutChFunc, ArgumentListRefT, NextArgument> {
|
||||
template<typename PutChFunc, typename ArgumentListRefT, template<typename T, typename U = ArgumentListRefT> typename NextArgument, typename CharType>
|
||||
requires(IsSame<CharType, char>) struct PrintfImpl : public PrintfImplementation::PrintfImpl<PutChFunc, ArgumentListRefT, NextArgument, CharType> {
|
||||
ALWAYS_INLINE PrintfImpl(PutChFunc& putch, char*& bufptr, const int& nwritten)
|
||||
: PrintfImplementation::PrintfImpl<PutChFunc, ArgumentListRefT, NextArgument>(putch, bufptr, nwritten)
|
||||
{
|
||||
|
@ -273,7 +273,7 @@ int main(int argc, char** argv)
|
|||
auto previous_argc = 0;
|
||||
do {
|
||||
previous_argc = argc;
|
||||
PrintfImplementation::printf_internal<decltype(putch), PrintfImpl, ArgvWithCount, ArgvNextArgument>(putch, nullptr, format_string, arg);
|
||||
PrintfImplementation::printf_internal<decltype(putch), PrintfImpl, ArgvWithCount, ArgvNextArgument, char>(putch, nullptr, format_string, arg);
|
||||
} while (argc && previous_argc != argc);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue