106c3fb27SDimitry Andric //===----------------------------------------------------------------------===////
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===////
806c3fb27SDimitry Andric
906c3fb27SDimitry Andric #ifndef FILESYSTEM_FORMAT_STRING_H
1006c3fb27SDimitry Andric #define FILESYSTEM_FORMAT_STRING_H
1106c3fb27SDimitry Andric
1206c3fb27SDimitry Andric #include <__assert>
1306c3fb27SDimitry Andric #include <__config>
1406c3fb27SDimitry Andric #include <array>
1506c3fb27SDimitry Andric #include <cstdarg>
1606c3fb27SDimitry Andric #include <cstddef>
1706c3fb27SDimitry Andric #include <cstdio>
1806c3fb27SDimitry Andric #include <string>
1906c3fb27SDimitry Andric
2006c3fb27SDimitry Andric #if defined(_LIBCPP_WIN32API)
2106c3fb27SDimitry Andric # define PATHSTR(x) (L##x)
2206c3fb27SDimitry Andric # define PATH_CSTR_FMT "\"%ls\""
2306c3fb27SDimitry Andric #else
2406c3fb27SDimitry Andric # define PATHSTR(x) (x)
2506c3fb27SDimitry Andric # define PATH_CSTR_FMT "\"%s\""
2606c3fb27SDimitry Andric #endif
2706c3fb27SDimitry Andric
2806c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
2906c3fb27SDimitry Andric
3006c3fb27SDimitry Andric namespace detail {
3106c3fb27SDimitry Andric
vformat_string(const char * msg,va_list ap)3206c3fb27SDimitry Andric inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {
3306c3fb27SDimitry Andric array<char, 256> buf;
3406c3fb27SDimitry Andric
3506c3fb27SDimitry Andric va_list apcopy;
3606c3fb27SDimitry Andric va_copy(apcopy, ap);
3706c3fb27SDimitry Andric int ret = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);
3806c3fb27SDimitry Andric va_end(apcopy);
3906c3fb27SDimitry Andric
4006c3fb27SDimitry Andric string result;
4106c3fb27SDimitry Andric if (static_cast<size_t>(ret) < buf.size()) {
4206c3fb27SDimitry Andric result.assign(buf.data(), static_cast<size_t>(ret));
4306c3fb27SDimitry Andric } else {
4406c3fb27SDimitry Andric // we did not provide a long enough buffer on our first attempt. The
4506c3fb27SDimitry Andric // return value is the number of bytes (excluding the null byte) that are
4606c3fb27SDimitry Andric // needed for formatting.
4706c3fb27SDimitry Andric size_t size_with_null = static_cast<size_t>(ret) + 1;
4806c3fb27SDimitry Andric result.__resize_default_init(size_with_null - 1);
4906c3fb27SDimitry Andric ret = ::vsnprintf(&result[0], size_with_null, msg, ap);
50*1db9f3b2SDimitry Andric _LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(ret) == (size_with_null - 1), "TODO");
5106c3fb27SDimitry Andric }
5206c3fb27SDimitry Andric return result;
5306c3fb27SDimitry Andric }
5406c3fb27SDimitry Andric
format_string(const char * msg,...)5506c3fb27SDimitry Andric inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {
5606c3fb27SDimitry Andric string ret;
5706c3fb27SDimitry Andric va_list ap;
5806c3fb27SDimitry Andric va_start(ap, msg);
5906c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6006c3fb27SDimitry Andric try {
6106c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
6206c3fb27SDimitry Andric ret = detail::vformat_string(msg, ap);
6306c3fb27SDimitry Andric #ifndef _LIBCPP_HAS_NO_EXCEPTIONS
6406c3fb27SDimitry Andric } catch (...) {
6506c3fb27SDimitry Andric va_end(ap);
6606c3fb27SDimitry Andric throw;
6706c3fb27SDimitry Andric }
6806c3fb27SDimitry Andric #endif // _LIBCPP_HAS_NO_EXCEPTIONS
6906c3fb27SDimitry Andric va_end(ap);
7006c3fb27SDimitry Andric return ret;
7106c3fb27SDimitry Andric }
7206c3fb27SDimitry Andric
7306c3fb27SDimitry Andric } // end namespace detail
7406c3fb27SDimitry Andric
7506c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM
7606c3fb27SDimitry Andric
7706c3fb27SDimitry Andric #endif // FILESYSTEM_FORMAT_STRING_H
78