Skip to content

Commit

Permalink
Merge branch 'fmtlib:master' into zig-pkg
Browse files Browse the repository at this point in the history
  • Loading branch information
kassane authored Nov 18, 2023
2 parents 1524602 + 864a8b5 commit 1d6831f
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 62 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/scorecard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
persist-credentials: false

- name: "Run analysis"
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # v2.2.0
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
with:
results_file: results.sarif
results_format: sarif
Expand All @@ -60,6 +60,6 @@ jobs:

# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@00e563ead9f72a8461b24876bee2d0c2e8bd2ee8 # v2.21.5
uses: github/codeql-action/upload-sarif@74483a38d39275f33fcff5f35b679b5ca4a26a99 # v2.22.5
with:
sarif_file: results.sarif
23 changes: 16 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.8...3.26)

# Fallback for using newer policies on CMake <3.12.
if(${CMAKE_VERSION} VERSION_LESS 3.12)
if (${CMAKE_VERSION} VERSION_LESS 3.12)
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()
endif ()

# Determine if fmt is built as a subproject (using add_subdirectory)
# or if it is the master project.
Expand Down Expand Up @@ -162,10 +162,10 @@ set(FMT_SYSTEM_HEADERS_ATTRIBUTE "")
if (FMT_SYSTEM_HEADERS)
set(FMT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
endif ()
if(CMAKE_SYSTEM_NAME STREQUAL "MSDOS")
if (CMAKE_SYSTEM_NAME STREQUAL "MSDOS")
set(FMT_TEST OFF)
message(STATUS "MSDOS is incompatible with gtest")
endif()
endif ()

# Get version from core.h
file(READ include/fmt/core.h core_h)
Expand Down Expand Up @@ -312,7 +312,15 @@ set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.")
set_target_properties(fmt PROPERTIES
VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR}
PUBLIC_HEADER "${FMT_HEADERS}"
DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}")
DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}"

# Workaround for Visual Studio 2017:
# Ensure the .pdb is created with the same name and in the same directory
# as the .lib. Newer VS versions already do this by default, but there is no
# harm in setting it for those too. Ignored by other generators.
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
COMPILE_PDB_NAME "fmt"
COMPILE_PDB_NAME_DEBUG "fmt${FMT_DEBUG_POSTFIX}")

# Set FMT_LIB_NAME for pkg-config fmt.pc. We cannot use the OUTPUT_NAME target
# property because it's not set by default.
Expand All @@ -326,15 +334,16 @@ if (BUILD_SHARED_LIBS)
endif ()
if (FMT_SAFE_DURATION_CAST)
target_compile_definitions(fmt PUBLIC FMT_SAFE_DURATION_CAST)
endif()
endif ()

add_library(fmt-header-only INTERFACE)
add_library(fmt::fmt-header-only ALIAS fmt-header-only)

target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1)
target_compile_features(fmt-header-only INTERFACE cxx_std_11)

target_include_directories(fmt-header-only ${FMT_SYSTEM_HEADERS_ATTRIBUTE} INTERFACE
target_include_directories(fmt-header-only
${FMT_SYSTEM_HEADERS_ATTRIBUTE} INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${FMT_INC_DIR}>)

Expand Down
12 changes: 6 additions & 6 deletions doc/_static/bootstrap.min.js

Large diffs are not rendered by default.

11 changes: 7 additions & 4 deletions include/fmt/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -1958,11 +1958,12 @@ auto write_escaped_string(OutputIt out, basic_string_view<Char> str)

template <typename Char, typename OutputIt>
auto write_escaped_char(OutputIt out, Char v) -> OutputIt {
Char v_array[1] = {v};
*out++ = static_cast<Char>('\'');
if ((needs_escape(static_cast<uint32_t>(v)) && v != static_cast<Char>('"')) ||
v == static_cast<Char>('\'')) {
out = write_escaped_cp(
out, find_escape_result<Char>{&v, &v + 1, static_cast<uint32_t>(v)});
out, find_escape_result<Char>{v_array, v_array + 1, static_cast<uint32_t>(v)});
} else {
*out++ = v;
}
Expand Down Expand Up @@ -2341,9 +2342,10 @@ template <typename Char, typename OutputIt>
FMT_CONSTEXPR auto write(OutputIt out, const Char* s,
const format_specs<Char>& specs, locale_ref)
-> OutputIt {
return specs.type != presentation_type::pointer
? write(out, basic_string_view<Char>(s), specs, {})
: write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
if (specs.type == presentation_type::pointer)
return write_ptr<Char>(out, bit_cast<uintptr_t>(s), &specs);
if (!s) throw_format_error("string pointer is null");
return write(out, basic_string_view<Char>(s), specs, {});
}

template <typename Char, typename OutputIt, typename T,
Expand Down Expand Up @@ -4052,6 +4054,7 @@ struct formatter<T, Char, enable_if_t<detail::has_format_as<T>::value>>
: private formatter<detail::format_as_t<T>, Char> {
using base = formatter<detail::format_as_t<T>, Char>;
using base::parse;
using base::set_debug_format;

template <typename FormatContext>
auto format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) {
Expand Down
9 changes: 6 additions & 3 deletions include/fmt/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
#include <cstdio>
#include <system_error> // std::system_error

#include "format.h"

#if defined __APPLE__ || defined(__FreeBSD__)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
# if FMT_HAS_INCLUDE(<xlocale.h>)
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
# endif
#endif

#include "format.h"

#ifndef FMT_USE_FCNTL
// UWP doesn't provide _pipe.
# if FMT_HAS_INCLUDE("winapifamily.h")
Expand Down Expand Up @@ -46,6 +48,7 @@

// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_HAS_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) ::call
Expand Down
77 changes: 43 additions & 34 deletions include/fmt/std.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,42 +59,51 @@
# endif
#endif

#ifdef __cpp_lib_filesystem
// For older Xcode versions, __cpp_lib_xxx flags are inaccurately defined.
#ifndef FMT_CPP_LIB_FILESYSTEM
# ifdef __cpp_lib_filesystem
# define FMT_CPP_LIB_FILESYSTEM __cpp_lib_filesystem
# else
# define FMT_CPP_LIB_FILESYSTEM 0
# endif
#endif

#ifndef FMT_CPP_LIB_VARIANT
# ifdef __cpp_lib_variant
# define FMT_CPP_LIB_VARIANT __cpp_lib_variant
# else
# define FMT_CPP_LIB_VARIANT 0
# endif
#endif

#if FMT_CPP_LIB_FILESYSTEM
FMT_BEGIN_NAMESPACE

namespace detail {

template <typename Char> auto get_path_string(const std::filesystem::path& p) {
return p.string<Char>();
template <typename Char, typename PathChar> auto get_path_string(
const std::filesystem::path& p, const std::basic_string<PathChar>& native) {
if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>)
return to_utf8<wchar_t>(native, to_utf8_error_policy::replace);
else
return p.string<Char>();
}

template <typename Char>
template <typename Char, typename PathChar>
void write_escaped_path(basic_memory_buffer<Char>& quoted,
const std::filesystem::path& p) {
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
}

# ifdef _WIN32
template <> inline auto get_path_string<char>(const std::filesystem::path& p) {
return to_utf8<wchar_t>(p.native(), to_utf8_error_policy::replace);
}

template <>
inline void write_escaped_path<char>(memory_buffer& quoted,
const std::filesystem::path& p) {
auto buf = basic_memory_buffer<wchar_t>();
write_escaped_string<wchar_t>(std::back_inserter(buf), p.native());
bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
FMT_ASSERT(valid, "invalid utf16");
}
# endif // _WIN32

template <>
inline void write_escaped_path<std::filesystem::path::value_type>(
basic_memory_buffer<std::filesystem::path::value_type>& quoted,
const std::filesystem::path& p) {
write_escaped_string<std::filesystem::path::value_type>(
std::back_inserter(quoted), p.native());
const std::filesystem::path& p,
const std::basic_string<PathChar>& native) {
if constexpr (std::is_same_v<Char, char> && std::is_same_v<PathChar, wchar_t>) {
auto buf = basic_memory_buffer<wchar_t>();
write_escaped_string<wchar_t>(std::back_inserter(buf), native);
bool valid = to_utf8<wchar_t>::convert(quoted, {buf.data(), buf.size()});
FMT_ASSERT(valid, "invalid utf16");
} else if constexpr (std::is_same_v<Char, PathChar>) {
write_escaped_string<std::filesystem::path::value_type>(
std::back_inserter(quoted), native);
} else {
write_escaped_string<Char>(std::back_inserter(quoted), p.string<Char>());
}
}

} // namespace detail
Expand Down Expand Up @@ -130,18 +139,18 @@ template <typename Char> struct formatter<std::filesystem::path, Char> {
detail::handle_dynamic_spec<detail::width_checker>(specs.width, width_ref_,
ctx);
if (!debug_) {
auto s = detail::get_path_string<Char>(p);
auto s = detail::get_path_string<Char>(p, p.native());
return detail::write(ctx.out(), basic_string_view<Char>(s), specs);
}
auto quoted = basic_memory_buffer<Char>();
detail::write_escaped_path(quoted, p);
detail::write_escaped_path(quoted, p, p.native());
return detail::write(ctx.out(),
basic_string_view<Char>(quoted.data(), quoted.size()),
specs);
}
};
FMT_END_NAMESPACE
#endif
#endif // FMT_CPP_LIB_FILESYSTEM

FMT_BEGIN_NAMESPACE
FMT_EXPORT
Expand Down Expand Up @@ -219,7 +228,7 @@ struct formatter<std::optional<T>, Char,
FMT_END_NAMESPACE
#endif // __cpp_lib_optional

#ifdef __cpp_lib_variant
#if FMT_CPP_LIB_VARIANT
FMT_BEGIN_NAMESPACE
namespace detail {

Expand Down Expand Up @@ -310,7 +319,7 @@ struct formatter<
}
};
FMT_END_NAMESPACE
#endif // __cpp_lib_variant
#endif // FMT_CPP_LIB_VARIANT

FMT_BEGIN_NAMESPACE
FMT_EXPORT
Expand Down
14 changes: 9 additions & 5 deletions src/os.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
# include <sys/stat.h>
# include <sys/types.h>

# ifdef _WRS_KERNEL // VxWorks7 kernel
# include <ioLib.h> // getpagesize
# ifdef _WRS_KERNEL // VxWorks7 kernel
# include <ioLib.h> // getpagesize
# endif

# ifndef _WIN32
Expand Down Expand Up @@ -182,10 +182,14 @@ void buffered_file::close() {
}

int buffered_file::descriptor() const {
#ifdef fileno // fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
int fd = fileno(file_);
#else
#if !defined(fileno)
int fd = FMT_POSIX_CALL(fileno(file_));
#elif defined(FMT_HAS_SYSTEM)
// fileno is a macro on OpenBSD so we cannot use FMT_POSIX_CALL.
# define FMT_DISABLE_MACRO
int fd = FMT_SYSTEM(fileno FMT_DISABLE_MACRO(file_));
#else
int fd = fileno(file_);
#endif
if (fd == -1)
FMT_THROW(system_error(errno, FMT_STRING("cannot get file descriptor")));
Expand Down
6 changes: 5 additions & 1 deletion test/format-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1531,8 +1531,12 @@ TEST(format_test, format_cstring) {
EXPECT_EQ("test", fmt::format("{0:s}", "test"));
char nonconst[] = "nonconst";
EXPECT_EQ("nonconst", fmt::format("{0}", nonconst));
auto nullstr = static_cast<const char*>(nullptr);
EXPECT_THROW_MSG(
(void)fmt::format(runtime("{0}"), static_cast<const char*>(nullptr)),
(void)fmt::format("{}", nullstr),
format_error, "string pointer is null");
EXPECT_THROW_MSG(
(void)fmt::format("{:s}", nullstr),
format_error, "string pointer is null");
}

Expand Down
30 changes: 30 additions & 0 deletions test/std-test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,36 @@ TEST(std_test, optional) {
#endif
}

namespace my_nso {
enum class my_number {
one,
two,
};
auto format_as(my_number number) -> fmt::string_view {
return number == my_number::one ? "first" : "second";
}

class my_class {
public:
int av;

private:
friend auto format_as(const my_class& elm) -> std::string {
return fmt::to_string(elm.av);
}
};
} // namespace my_nso
TEST(std_test, optional_format_as) {
#ifdef __cpp_lib_optional
EXPECT_EQ(fmt::format("{}", std::optional<my_nso::my_number>{}), "none");
EXPECT_EQ(fmt::format("{}", std::optional{my_nso::my_number::one}),
"optional(\"first\")");
EXPECT_EQ(fmt::format("{}", std::optional<my_nso::my_class>{}), "none");
EXPECT_EQ(fmt::format("{}", std::optional{my_nso::my_class{7}}),
"optional(\"7\")");
#endif
}

struct throws_on_move {
throws_on_move() = default;

Expand Down

0 comments on commit 1d6831f

Please sign in to comment.