69 lines · c
1//===----------------------------------------------------------------------===////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-exception6//7//===----------------------------------------------------------------------===////8 9#ifndef FILESYSTEM_FORMAT_STRING_H10#define FILESYSTEM_FORMAT_STRING_H11 12#include <__assert>13#include <__config>14#include <__utility/scope_guard.h>15#include <array>16#include <cstdarg>17#include <cstddef>18#include <cstdio>19#include <string>20 21#if defined(_LIBCPP_WIN32API)22# define PATHSTR(x) (L##x)23# define PATH_CSTR_FMT "\"%ls\""24#else25# define PATHSTR(x) (x)26# define PATH_CSTR_FMT "\"%s\""27#endif28 29_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM30 31namespace detail {32 33inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string vformat_string(const char* msg, va_list ap) {34 array<char, 256> buf;35 36 va_list apcopy;37 va_copy(apcopy, ap);38 int size = ::vsnprintf(buf.data(), buf.size(), msg, apcopy);39 va_end(apcopy);40 41 string result;42 if (static_cast<size_t>(size) < buf.size()) {43 result.assign(buf.data(), static_cast<size_t>(size));44 } else {45 // we did not provide a long enough buffer on our first attempt. The46 // return value is the number of bytes (excluding the null byte) that are47 // needed for formatting.48 result.resize_and_overwrite(size, [&](char* res, size_t n) { return ::vsnprintf(res, n, msg, ap); });49 _LIBCPP_ASSERT_INTERNAL(static_cast<size_t>(size) == result.size(),50 "vsnprintf did not result in the same number of characters as the first attempt?");51 }52 return result;53}54 55inline _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) {56 string ret;57 va_list ap;58 va_start(ap, msg);59 __scope_guard guard([&] { va_end(ap); });60 ret = detail::vformat_string(msg, ap);61 return ret;62}63 64} // namespace detail65 66_LIBCPP_END_NAMESPACE_FILESYSTEM67 68#endif // FILESYSTEM_FORMAT_STRING_H69