diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-12-19 22:58:28 +0330 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-12-21 21:24:36 +0330 |
commit | f0709c7a24098ef5fbd568c37a99670d56f15616 (patch) | |
tree | 133ca0dab42f360a690988b2d8d5cad7dbf80218 /Userland | |
parent | db7a6d6e74c6483cbe392235560176d1e0992363 (diff) | |
download | serenity-f0709c7a24098ef5fbd568c37a99670d56f15616.zip |
LibC+AK: Implement all sorts of wprintf variants
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Applications/Spreadsheet/CellType/Format.cpp | 4 | ||||
-rw-r--r-- | Userland/Libraries/LibC/wchar.cpp | 6 | ||||
-rw-r--r-- | Userland/Libraries/LibC/wchar.h | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibC/wstdio.cpp | 56 | ||||
-rw-r--r-- | Userland/Utilities/printf.cpp | 6 |
5 files changed, 68 insertions, 12 deletions
diff --git a/Userland/Applications/Spreadsheet/CellType/Format.cpp b/Userland/Applications/Spreadsheet/CellType/Format.cpp index bcdce48acf..f33d11e320 100644 --- a/Userland/Applications/Spreadsheet/CellType/Format.cpp +++ b/Userland/Applications/Spreadsheet/CellType/Format.cpp @@ -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) { diff --git a/Userland/Libraries/LibC/wchar.cpp b/Userland/Libraries/LibC/wchar.cpp index 13c5081317..801b7d6d72 100644 --- a/Userland/Libraries/LibC/wchar.cpp +++ b/Userland/Libraries/LibC/wchar.cpp @@ -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') diff --git a/Userland/Libraries/LibC/wchar.h b/Userland/Libraries/LibC/wchar.h index d17b432180..034009e3ba 100644 --- a/Userland/Libraries/LibC/wchar.h +++ b/Userland/Libraries/LibC/wchar.h @@ -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 diff --git a/Userland/Libraries/LibC/wstdio.cpp b/Userland/Libraries/LibC/wstdio.cpp index 521551a208..d98fb71925 100644 --- a/Userland/Libraries/LibC/wstdio.cpp +++ b/Userland/Libraries/LibC/wstdio.cpp @@ -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); +} } diff --git a/Userland/Utilities/printf.cpp b/Userland/Utilities/printf.cpp index 576db3d5c8..1ea46d54b4 100644 --- a/Userland/Utilities/printf.cpp +++ b/Userland/Utilities/printf.cpp @@ -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; |