[libc-commits] [libc] [libc][stdio] Add support for the %m modifier (PR #218312)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Tue Aug 25 16:47:52 PDT 2026


================
@@ -52,26 +78,61 @@ int convert_string(Reader<T> *reader, const FormatSection &to_conv) {
       break;
     }
     // if the NO_WRITE flag is not set, write to the output.
-    if ((to_conv.flags & NO_WRITE) == 0)
+    if ((to_conv.flags & NO_WRITE) == 0) {
       output[i] = cur_char;
+#ifndef LIBC_COPT_SCANF_DISABLE_ALLOCATION
+      if (((to_conv.flags & ALLOCATE) != 0) && (i + 1) == alloc_size &&
+          alloc_size < max_width) {
+        alloc_size *= ALLOCATION_SCALE;
+        if (alloc_size > max_width + 1)
+          alloc_size = max_width + 1;
+        char *tmp = new (ac) char[alloc_size];
+        if (!ac) {
+          delete[] output;
+          libc_errno = ENOMEM;
+          reader->ungetc(cur_char);
+          return ALLOCATION_FAILURE;
+        }
+        inline_memcpy(tmp, output, i + 1);
+        delete[] output;
+        output = tmp;
+      }
+#endif
+    }
     cur_char = reader->getc();
   }
 
   // We always read one more character than will be used, so we have to put the
   // last one back.
   reader->ungetc(cur_char);
 
+  bool null_terminate =
+      (to_conv.conv_name != 'c') || ((to_conv.flags & ALLOCATE) != 0);
+
   // If this is %s or %[]
-  if (to_conv.conv_name != 'c' && (to_conv.flags & NO_WRITE) == 0) {
+  if (null_terminate && (to_conv.flags & NO_WRITE) == 0) {
     // Always null terminate the string. This may cause a write to the
     // (max_width + 1) byte, which is correct. The max width describes the max
     // number of characters read from the input string, and doesn't necessarily
     // correspond to the output.
     output[i] = '\0';
   }
 
-  if (i == 0)
+  if (i == 0) {
+#ifndef LIBC_COPT_SCANF_DISABLE_ALLOCATION
+    if ((to_conv.flags & ALLOCATE) != 0 && output)
+      delete[] output;
+#endif
     return MATCHING_FAILURE;
+  }
+
+#ifndef LIBC_COPT_SCANF_DISABLE_ALLOCATION
+  if ((to_conv.flags & ALLOCATE) != 0) {
+    char **outptr = reinterpret_cast<char **>(to_conv.output_ptr);
+    *outptr = output;
----------------
michaelrj-google wrote:

Simplify
```suggestion
    *reinterpret_cast<char **>(to_conv.output_ptr) = output;
```

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


More information about the libc-commits mailing list