xref: /llvm-project/libcxx/src/filesystem/format_string.h (revision ba87515fea90b5d55836a8e3be63a7e683ce299d)
1c7d3c844SLouis Dionne //===----------------------------------------------------------------------===////
2c7d3c844SLouis Dionne //
3c7d3c844SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c7d3c844SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5c7d3c844SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c7d3c844SLouis Dionne //
7c7d3c844SLouis Dionne //===----------------------------------------------------------------------===////
8c7d3c844SLouis Dionne 
9c7d3c844SLouis Dionne #ifndef FILESYSTEM_FORMAT_STRING_H
10c7d3c844SLouis Dionne #define FILESYSTEM_FORMAT_STRING_H
11c7d3c844SLouis Dionne 
12c7d3c844SLouis Dionne #include <__assert>
13c7d3c844SLouis Dionne #include <__config>
14c7d3c844SLouis Dionne #include <array>
15c7d3c844SLouis Dionne #include <cstdarg>
16c7d3c844SLouis Dionne #include <cstddef>
17c7d3c844SLouis Dionne #include <cstdio>
18c7d3c844SLouis Dionne #include <string>
19c7d3c844SLouis Dionne 
20c7d3c844SLouis Dionne #if defined(_LIBCPP_WIN32API)
21c7d3c844SLouis Dionne #  define PATHSTR(x) (L##x)
22c7d3c844SLouis Dionne #  define PATH_CSTR_FMT "\"%ls\""
23c7d3c844SLouis Dionne #else
24c7d3c844SLouis Dionne #  define PATHSTR(x) (x)
25c7d3c844SLouis Dionne #  define PATH_CSTR_FMT "\"%s\""
26c7d3c844SLouis Dionne #endif
27c7d3c844SLouis Dionne 
28c7d3c844SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
29c7d3c844SLouis Dionne 
30c7d3c844SLouis Dionne namespace detail {
31c7d3c844SLouis Dionne 
3221853b96SLouis Dionne inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {
33c7d3c844SLouis Dionne   array<char, 256> buf;
34c7d3c844SLouis Dionne 
35c7d3c844SLouis Dionne   va_list apcopy;
36c7d3c844SLouis Dionne   va_copy(apcopy, ap);
37c7d3c844SLouis Dionne   int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
38c7d3c844SLouis Dionne   va_end(apcopy);
39c7d3c844SLouis Dionne 
40c7d3c844SLouis Dionne   string result;
41c7d3c844SLouis Dionne   if (static_cast<size_t>(ret) < buf.size()) {
42c7d3c844SLouis Dionne     result.assign(buf.data(), static_cast<size_t>(ret));
43c7d3c844SLouis Dionne   } else {
44c7d3c844SLouis Dionne     // we did not provide a long enough buffer on our first attempt. The
45c7d3c844SLouis Dionne     // return value is the number of bytes (excluding the null byte) that are
46c7d3c844SLouis Dionne     // needed for formatting.
47c7d3c844SLouis Dionne     size_t size_with_null = static_cast<size_t>(ret) + 1;
48c7d3c844SLouis Dionne     result.__resize_default_init(size_with_null - 1);
49c7d3c844SLouis Dionne     ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
504f215fddSKonstantin Varlamov     _LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
51c7d3c844SLouis Dionne   }
52c7d3c844SLouis Dionne   return result;
53c7d3c844SLouis Dionne }
54c7d3c844SLouis Dionne 
5521853b96SLouis Dionne inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {
56c7d3c844SLouis Dionne   string ret;
57c7d3c844SLouis Dionne   va_list ap;
58c7d3c844SLouis Dionne   va_start(ap, msg);
59*ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS
60c7d3c844SLouis Dionne   try {
61*ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS
62c7d3c844SLouis Dionne     ret = detail::vformat_string(msg, ap);
63*ba87515fSNikolas Klauser #if _LIBCPP_HAS_EXCEPTIONS
64c7d3c844SLouis Dionne   } catch (...) {
65c7d3c844SLouis Dionne     va_end(ap);
66c7d3c844SLouis Dionne     throw;
67c7d3c844SLouis Dionne   }
68*ba87515fSNikolas Klauser #endif // _LIBCPP_HAS_EXCEPTIONS
69c7d3c844SLouis Dionne   va_end(ap);
70c7d3c844SLouis Dionne   return ret;
71c7d3c844SLouis Dionne }
72c7d3c844SLouis Dionne 
73953af0e7SLouis Dionne } // namespace detail
74c7d3c844SLouis Dionne 
75c7d3c844SLouis Dionne _LIBCPP_END_NAMESPACE_FILESYSTEM
76c7d3c844SLouis Dionne 
77c7d3c844SLouis Dionne #endif // FILESYSTEM_FORMAT_STRING_H
78