Warning: This file is not a C or C++ file. It does not have highlighting.

1//===-- Internal Implementation of asprintf ---------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "hdr/func/free.h"
10#include "hdr/func/malloc.h"
11#include "hdr/func/realloc.h"
12#include "src/__support/arg_list.h"
13#include "src/stdio/printf.h"
14#include "src/stdio/printf_core/core_structs.h"
15#include "src/stdio/printf_core/printf_main.h"
16#include "src/stdio/printf_core/writer.h"
17
18namespace LIBC_NAMESPACE_DECL {
19namespace printf_core {
20
21LIBC_INLINE int resize_overflow_hook(cpp::string_view new_str, void *target) {
22 WriteBuffer<Mode<WriteMode::RESIZE_AND_FILL_BUFF>::value> *wb =
23 reinterpret_cast<
24 WriteBuffer<Mode<WriteMode::RESIZE_AND_FILL_BUFF>::value> *>(target);
25 size_t new_size = new_str.size() + wb->buff_cur;
26 const bool isBuffOnStack = (wb->buff == wb->init_buff);
27 char *new_buff = static_cast<char *>(
28 isBuffOnStack ? malloc(new_size + 1)
29 : realloc(wb->buff, new_size + 1)); // +1 for null
30 if (new_buff == nullptr) {
31 if (wb->buff != wb->init_buff)
32 free(wb->buff);
33 return printf_core::ALLOCATION_ERROR;
34 }
35 if (isBuffOnStack)
36 inline_memcpy(new_buff, wb->buff, wb->buff_cur);
37 wb->buff = new_buff;
38 inline_memcpy(wb->buff + wb->buff_cur, new_str.data(), new_str.size());
39 wb->buff_cur = new_size;
40 wb->buff_len = new_size;
41 return printf_core::WRITE_OK;
42}
43
44constexpr size_t DEFAULT_BUFFER_SIZE = 200;
45
46LIBC_INLINE int vasprintf_internal(char **ret, const char *__restrict format,
47 internal::ArgList args) {
48 char init_buff_on_stack[DEFAULT_BUFFER_SIZE];
49 printf_core::WriteBuffer<Mode<WriteMode::RESIZE_AND_FILL_BUFF>::value> wb(
50 init_buff_on_stack, DEFAULT_BUFFER_SIZE, resize_overflow_hook);
51 printf_core::Writer writer(wb);
52
53 auto ret_val = printf_core::printf_main(&writer, format, args);
54 if (ret_val < 0) {
55 *ret = nullptr;
56 return -1;
57 }
58 if (wb.buff == init_buff_on_stack) {
59 *ret = static_cast<char *>(malloc(ret_val + 1));
60 if (ret == nullptr)
61 return printf_core::ALLOCATION_ERROR;
62 inline_memcpy(*ret, wb.buff, ret_val);
63 } else {
64 *ret = wb.buff;
65 }
66 (*ret)[ret_val] = '\0';
67 return ret_val;
68}
69} // namespace printf_core
70} // namespace LIBC_NAMESPACE_DECL
71

Warning: This file is not a C or C++ file. It does not have highlighting.

source code of libc/src/stdio/printf_core/vasprintf_internal.h