summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-12-19 22:58:28 +0330
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-12-21 21:24:36 +0330
commitf0709c7a24098ef5fbd568c37a99670d56f15616 (patch)
tree133ca0dab42f360a690988b2d8d5cad7dbf80218 /Userland
parentdb7a6d6e74c6483cbe392235560176d1e0992363 (diff)
downloadserenity-f0709c7a24098ef5fbd568c37a99670d56f15616.zip
LibC+AK: Implement all sorts of wprintf variants
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Applications/Spreadsheet/CellType/Format.cpp4
-rw-r--r--Userland/Libraries/LibC/wchar.cpp6
-rw-r--r--Userland/Libraries/LibC/wchar.h8
-rw-r--r--Userland/Libraries/LibC/wstdio.cpp56
-rw-r--r--Userland/Utilities/printf.cpp6
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;