[libc-commits] [libc] [libc] Implement vasprintf and asprintf (PR #98824)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Mon Jul 29 13:45:53 PDT 2024


================
@@ -0,0 +1,70 @@
+//===-- Internal Implementation of asprintf ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/arg_list.h"
+#include "src/stdio/printf.h"
+#include "src/stdio/printf_core/core_structs.h"
+#include "src/stdio/printf_core/printf_main.h"
+#include "src/stdio/printf_core/writer.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h> // malloc, realloc, free
+
+namespace LIBC_NAMESPACE {
+namespace printf_core {
+
+LIBC_INLINE int resize_overflow_hook(cpp::string_view new_str, void *target) {
+  printf_core::WriteBuffer *wb =
+      reinterpret_cast<printf_core::WriteBuffer *>(target);
+  size_t new_size = new_str.size() + wb->buff_cur;
+  const bool isBuffOnStack = (wb->buff == wb->init_buff);
+  char *new_buff = static_cast<char *>(
+      isBuffOnStack ? malloc(new_size + 1)
+                    : realloc(wb->buff, new_size + 1)); // +1 for null
+  if (new_buff == nullptr) {
+    if (wb->buff != wb->init_buff)
+      free(wb->buff);
+    return printf_core::ALLOCATION_ERROR;
+  }
+  if (isBuffOnStack)
+    inline_memcpy(new_buff, wb->buff, wb->buff_cur);
+  wb->buff = new_buff;
+  inline_memcpy(wb->buff + wb->buff_cur, new_str.data(), new_str.size());
+  wb->buff_cur = new_size;
+  wb->buff_len = new_size;
+  return printf_core::WRITE_OK;
+}
+
+inline constexpr size_t DEFAULT_BUFFER_SIZE = 200;
+
+LIBC_INLINE int vasprintf_internal(char **ret, const char *format,
+                                   internal::ArgList args) {
+  char init_buff_on_stack[DEFAULT_BUFFER_SIZE];
+  printf_core::WriteBuffer wb(init_buff_on_stack, DEFAULT_BUFFER_SIZE,
+                              resize_overflow_hook);
+  printf_core::Writer writer(&wb);
+
+  auto ret_val = printf_core::printf_main(&writer, format, args);
+  if (ret_val < 0) {
+    *ret = nullptr;
+    return -1;
+  }
+  if (wb.buff == init_buff_on_stack) {
+    *ret = static_cast<char *>(malloc(ret_val + 1));
+    if (ret == nullptr)
+      return -1;
----------------
michaelrj-google wrote:

nit: `return printf_core::ALLOCATION_ERROR`

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


More information about the libc-commits mailing list