[libc-commits] [libc] [libc] Support ls in printf (PR #178841)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Wed Feb 4 14:47:12 PST 2026


================
@@ -24,21 +33,63 @@ template <WriteMode write_mode>
 LIBC_INLINE int convert_string(Writer<write_mode> *writer,
                                const FormatSection &to_conv) {
   size_t string_len = 0;
-  const char *str_ptr = reinterpret_cast<const char *>(to_conv.conv_val_ptr);
+
+  if (to_conv.length_modifier == LengthModifier::l) {
+#ifndef LIBC_COPT_PRINTF_DISABLE_WIDE
+    const wchar_t *wstr_ptr =
+        reinterpret_cast<const wchar_t *>(to_conv.conv_val_ptr);
+
+#ifndef LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
+    if (wstr_ptr == nullptr) {
+      wstr_ptr = L"(null)";
+    }
+#endif // LIBC_COPT_PRINTF_NO_NULLPTR_CHECKS
+
+    char buffer[MB_LEN_MAX];
+    internal::mbstate mbstate;
+    size_t written = 0;
+    for (const wchar_t *cur_str = (wstr_ptr); cur_str[string_len];
+         ++string_len) {
+      wchar_t wc = cur_str[string_len];
+
+      auto ret = internal::wcrtomb(buffer, wc, &mbstate);
+      if (!ret.has_value()) {
+        return MB_CONVERSION_ERROR;
+      }
+      written += ret.value();
+
+      if (to_conv.precision >= 0 &&
+          static_cast<size_t>(to_conv.precision) < written) {
+        written -= ret.value();
+        break;
+      }
+    }
+    string_len = written;
----------------
michaelrj-google wrote:

you can get the string length in a simpler way by using the StringConverter directly:
```suggestion
    // Convert without writing anywhere to get the length of the wide string as
    // multibyte.
    internal::mbstate mbstate;

    internal::StringConverter<char32_t> str_conv(
        reinterpret_cast<const char32_t *>(wstr_ptr), &mbstate, precision);

    for (auto converted = str_conv.pop<char8_t>();
         converted.has_value() && converted.value() != '\0';
         converted = str_conv.pop<char8_t>()) {
      ++string_len;
    }
```
For this to work you need to add `#include "src/__support/wchar/string_converter.h"` to the top and the following to the definitions:
```C++
  size_t precision =
      to_conv.precision < 0 ? SIZE_MAX : static_cast<size_t>(to_conv.precision);
```

https://github.com/llvm/llvm-project/pull/178841


More information about the libc-commits mailing list