Compare commits

...

17 Commits
text ... 2.1.1

Author SHA1 Message Date
ed5a862375 Update version 2016-04-11 15:17:15 -04:00
6f51274289 Update changelog and version 2016-04-11 15:13:36 -04:00
752e021106 Update version 2016-04-11 11:33:29 -04:00
7e3671865f make the install location for the generated cmake files configurable
By default the cmake files are installed to "<prefix>/lib/cmake/cppformat".
This can now be customized using the `FMT_CMAKE_DIR` cache variable.
Valid paths are documented in the cmake manual [1].

e.g., install the cmake files to "<prefix>/share/cmake/cppformat"
```
cmake -DFMT_CMAKE_DIR=share/cmake/cppformat <path-to-source>
```

Tip: Try `make package` to examine the result.

[1] https://cmake.org/cmake/help/v3.0/command/find_package.html
2016-04-11 09:51:15 -04:00
7d5400f833 Resolve overloads 2016-04-11 09:44:22 -04:00
8019387a55 Remove the build directory 2016-04-07 07:26:14 -07:00
76fba46190 Update changelog 2016-03-21 07:57:06 -07:00
d7ddd61545 Update CMake config and tests from the master branch 2016-03-17 07:25:50 -07:00
8c16747a80 Update version 2016-03-13 10:19:25 -07:00
038009b2e5 Install new CMake on travis 2016-03-10 08:13:34 -08:00
ee6b5a596e Add CMake config file 2016-03-10 07:46:39 -08:00
f5f9bf7f1f Update version 2016-03-10 07:20:20 -08:00
613f7df021 Update changelog 2016-03-10 07:19:17 -08:00
8c68e2ca04 Fix fileno causing compile error when #defined
Error:
expected unqualified-id before '(' token
 int fmt::BufferedFile::fileno() const {

This is an issue with Android NDK and mingw32.

c2ffa14684
2016-03-10 07:16:48 -08:00
368b66a806 Update changelog 2016-03-10 07:12:16 -08:00
1a166b0e1b Update docs 2016-03-10 07:00:42 -08:00
38275fb27f Update CMake config
to version 7ee287d3d9
2016-03-10 07:00:00 -08:00
41 changed files with 4046 additions and 3849 deletions

View File

@ -20,5 +20,12 @@ matrix:
- os: osx
env: BUILD=Doc
addons:
apt:
sources:
- kubuntu-backports # cmake 2.8.12
packages:
- cmake
script:
- support/travis-build.py

View File

@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE := cppformat_static
LOCAL_MODULE_FILENAME := libcppformat
LOCAL_SRC_FILES := format.cc
LOCAL_SRC_FILES := cppformat/format.cc
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)

View File

@ -1,6 +1,13 @@
message(STATUS "CMake version: ${CMAKE_VERSION}")
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 2.8.12)
# determine if cppformat is built as sub project (using add_subdirectory)
# or if it is the master project
set(MASTER_PROJECT OFF)
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
set(MASTER_PROJECT ON)
endif ()
# Set the default CMAKE_BUILD_TYPE to Release.
# This should be done before the project command since the latter can set
@ -13,50 +20,36 @@ endif ()
option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF)
# Options that control generation of various targets.
option(FMT_DOC "Generate the doc target." ON)
option(FMT_INSTALL "Generate the install target." ON)
option(FMT_TEST "Generate the test target." ON)
option(FMT_DOC "Generate the doc target." ${MASTER_PROJECT})
option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT})
option(FMT_TEST "Generate the test target." ${MASTER_PROJECT})
option(FMT_USE_CPP11 "Enable the addition of C++11 compiler flags." ON)
project(FORMAT)
# starting with cmake 3.0 VERSION is part of the project command
set(CPPFORMAT_VERSION 2.1.1)
if (NOT CPPFORMAT_VERSION MATCHES "^([0-9]+).([0-9]+).([0-9]+)$")
message(FATAL_ERROR "Invalid version format ${CPPFORMAT_VERSION}.")
endif ()
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag(-std=c++11 HAVE_STD_CPP11_FLAG)
if (HAVE_STD_CPP11_FLAG)
# Check if including cmath works with -std=c++11 and -O3.
# It may not in MinGW due to bug http://ehc.ac/p/mingw/bugs/2250/.
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -O3")
check_cxx_source_compiles("
#include <cmath>
int main() {}" FMT_CPP11_CMATH)
# Check if including <unistd.h> works with -std=c++11.
# It may not in MinGW due to bug http://sourceforge.net/p/mingw/bugs/2024/.
check_cxx_source_compiles("
#include <unistd.h>
int main() {}" FMT_CPP11_UNISTD_H)
if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H)
set(CPP11_FLAG -std=c++11)
else ()
check_cxx_compiler_flag(-std=gnu++11 HAVE_STD_GNUPP11_FLAG)
if (HAVE_STD_CPP11_FLAG)
set(CPP11_FLAG -std=gnu++11)
endif ()
endif ()
set(CMAKE_REQUIRED_FLAGS )
else ()
check_cxx_compiler_flag(-std=c++0x HAVE_STD_CPP0X_FLAG)
if (HAVE_STD_CPP0X_FLAG)
set(CPP11_FLAG -std=c++0x)
endif ()
endif ()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/support/cmake")
if (CMAKE_GENERATOR MATCHES "Visual Studio")
include(testCxx11)
if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -Wshadow -pedantic)
endif ()
if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio")
# If Microsoft SDK is installed create script run-msbuild.bat that
# calls SetEnv.cmd to to set up build environment and runs msbuild.
# It is useful when building Visual Studio projects with the SDK
@ -72,58 +65,14 @@ if (CMAKE_GENERATOR MATCHES "Visual Studio")
${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*")
endif ()
set(FMT_SOURCES format.cc format.h)
include(CheckSymbolExists)
if (WIN32)
check_symbol_exists(open io.h HAVE_OPEN)
else ()
check_symbol_exists(open fcntl.h HAVE_OPEN)
endif ()
if (HAVE_OPEN)
add_definitions(-DFMT_USE_FILE_DESCRIPTORS=1)
set(FMT_SOURCES ${FMT_SOURCES} posix.cc posix.h)
endif ()
if (CPP11_FLAG)
set(CMAKE_REQUIRED_FLAGS ${CPP11_FLAG})
endif ()
if (BIICODE)
include(support/cmake/biicode.cmake)
return()
endif ()
add_library(cppformat ${FMT_SOURCES})
if (BUILD_SHARED_LIBS AND UNIX AND NOT APPLE)
# Fix rpmlint warning:
# unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6.
target_link_libraries(cppformat -Wl,--as-needed)
endif ()
if (FMT_PEDANTIC AND
(CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang")))
set(FMT_EXTRA_COMPILE_FLAGS "-Wall -Wextra -Wshadow -pedantic")
endif ()
# If FMT_PEDANTIC is TRUE, then test compilation with both -std=c++11
# and the default flags. Otherwise use only the default flags.
# The library is distributed in the source form and users have full control
# over compile options, so the options used here only matter for testing.
if (CPP11_FLAG AND FMT_PEDANTIC)
set(FMT_EXTRA_COMPILE_FLAGS "${FMT_EXTRA_COMPILE_FLAGS} ${CPP11_FLAG}")
set(FMT_TEST_DEFAULT_FLAGS TRUE)
endif ()
set_target_properties(cppformat
PROPERTIES COMPILE_FLAGS "${FMT_EXTRA_COMPILE_FLAGS}")
set(CPPFORMAT_VERSION 2.0.0)
if (NOT CPPFORMAT_VERSION MATCHES "^([0-9]+).([0-9]+).([0-9]+)$")
message(FATAL_ERROR "Invalid version format ${CPPFORMAT_VERSION}.")
endif ()
set(CPACK_PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
set(CPACK_PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
set(CPACK_PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
add_subdirectory(cppformat)
if (FMT_DOC)
add_subdirectory(doc)
@ -134,12 +83,10 @@ if (FMT_TEST)
add_subdirectory(test)
endif ()
set_target_properties(cppformat PROPERTIES
VERSION ${CPPFORMAT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
if (EXISTS .gitignore)
set(gitignore ${PROJECT_SOURCE_DIR}/.gitignore)
if (MASTER_PROJECT AND EXISTS ${gitignore})
# Get the list of ignored files from .gitignore.
file (STRINGS ".gitignore" lines)
file (STRINGS ${gitignore} lines)
LIST(REMOVE_ITEM lines /doc/html)
foreach (line ${lines})
string(REPLACE "." "[.]" line "${line}")
@ -152,14 +99,7 @@ if (EXISTS .gitignore)
set(CPACK_SOURCE_GENERATOR ZIP)
set(CPACK_SOURCE_IGNORE_FILES ${ignored_files})
set(CPACK_SOURCE_PACKAGE_FILE_NAME cppformat-${CPPFORMAT_VERSION})
set(CPACK_RESOURCE_FILE_README ${FORMAT_SOURCE_DIR}/README.rst)
set(CPACK_PACKAGE_NAME cppformat)
set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.rst)
include(CPack)
endif ()
# Install targets.
if (FMT_INSTALL)
set(FMT_LIB_DIR lib CACHE STRING
"Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
install(TARGETS cppformat DESTINATION ${FMT_LIB_DIR})
install(FILES format.h DESTINATION include/cppformat)
endif ()

View File

@ -1,3 +1,50 @@
2.1.1 - 2016-04-11
------------------
* The install location for generated CMake files is now configurable via
the ``FMT_CMAKE_DIR`` CMake variable
(`#299 <https://github.com/cppformat/cppformat/pull/299>`_).
Thanks to `@niosHD <https://github.com/niosHD>`_.
* Documentation fixes (`#252 <https://github.com/cppformat/cppformat/issues/252>`_).
2.1.0 - 2016-03-21
------------------
* Project layout and build system improvements
(`#267 <https://github.com/cppformat/cppformat/pull/267>`_):
* The code have been moved to the ``cppformat`` directory.
Including ``format.h`` from the top-level directory is deprecated
but works via a proxy header which will be removed in the next
major version.
* C++ Format CMake targets now have proper interface definitions.
* Installed version of the library now supports the header-only
configuration.
* Targets ``doc``, ``install``, and ``test`` are now disabled if C++ Format
is included as a CMake subproject. They can be enabled by setting
``FMT_DOC``, ``FMT_INSTALL``, and ``FMT_TEST`` in the parent project.
Thanks to `@niosHD <https://github.com/niosHD>`_.
2.0.1 - 2016-03-13
------------------
* Improved CMake find and package support
(`#264 <https://github.com/cppformat/cppformat/issues/264>`_).
Thanks to `@niosHD <https://github.com/niosHD>`_.
* Fix compile error with Android NDK and mingw32
(`#241 <https://github.com/cppformat/cppformat/issues/241>`_).
Thanks to `@Gachapen (Magnus Bjerke Vik) <https://github.com/Gachapen>`_.
* Documentation fixes
(`#248 <https://github.com/cppformat/cppformat/issues/248>`_,
`#260 <https://github.com/cppformat/cppformat/issues/260>`_).
2.0.0 - 2015-12-01
------------------

View File

@ -28,9 +28,9 @@ Features
* Format API with `format string syntax
<http://cppformat.github.io/latest/syntax.html>`_
similar to the one used by `str.format
<http://docs.python.org/2/library/stdtypes.html#str.format>`_ in Python.
<https://docs.python.org/2/library/stdtypes.html#str.format>`_ in Python.
* Safe `printf implementation
<http://cppformat.github.io/latest/reference.html#printf-formatting-functions>`_
<http://cppformat.github.io/latest/api.html#printf-formatting-functions>`_
including the POSIX extension for positional arguments.
* Support for user-defined types.
* High speed: performance of the format API is close to that of
@ -103,10 +103,10 @@ An object of any user-defined type for which there is an overloaded
// s == "The date is 2012-12-9"
You can use the `FMT_VARIADIC
<http://cppformat.github.io/latest/reference.html#utilities>`_
<http://cppformat.github.io/latest/api.html#utilities>`_
macro to create your own functions similar to `format
<http://cppformat.github.io/latest/reference.html#format>`_ and
`print <http://cppformat.github.io/latest/reference.html#print>`_
<http://cppformat.github.io/latest/api.html#format>`_ and
`print <http://cppformat.github.io/latest/api.html#print>`_
which take arbitrary arguments:
.. code:: c++
@ -132,10 +132,10 @@ Projects using this library
* `AMPL/MP <https://github.com/ampl/mp>`_:
An open-source library for mathematical programming
* `HarpyWar/pvpgn <https://github.com/HarpyWar/pvpgn>`_:
* `HarpyWar/pvpgn <https://github.com/pvpgn/pvpgn-server>`_:
Player vs Player Gaming Network with tweaks
* `KBEngine <http://www.kbengine.org/>`_: An open-source MMOG server engine
* `KBEngine <http://kbengine.org/>`_: An open-source MMOG server engine
* `Lifeline <https://github.com/peter-clark/lifeline>`_: A 2D game
@ -148,7 +148,7 @@ Projects using this library
* `redis-cerberus <https://github.com/HunanTV/redis-cerberus>`_: A Redis cluster proxy
* `Saddy <https://code.google.com/p/saddy/>`_:
* `Saddy <https://github.com/mamontov-cpp/saddy-graphics-engine-2d>`_:
Small crossplatform 2D graphic engine
* `Salesforce Analytics Cloud <http://www.salesforce.com/analytics-cloud/overview/>`_:
@ -188,7 +188,7 @@ doesn't support user-defined types. Printf also has safety issues although
they are mostly solved with `__attribute__ ((format (printf, ...))
<http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html>`_ in GCC.
There is a POSIX extension that adds positional arguments required for
`i18n <http://en.wikipedia.org/wiki/Internationalization_and_localization>`_
`i18n <https://en.wikipedia.org/wiki/Internationalization_and_localization>`_
to printf but it is not a part of C99 and may not be available on some
platforms.
@ -376,7 +376,7 @@ C++ Format is distributed under the BSD `license
The `Format String Syntax
<http://cppformat.github.io/latest/syntax.html>`_
section in the documentation is based on the one from Python `string module
documentation <http://docs.python.org/3/library/string.html#module-string>`_
documentation <https://docs.python.org/3/library/string.html#module-string>`_
adapted for the current library. For this reason the documentation is
distributed under the Python Software Foundation license available in
`doc/python-license.txt
@ -409,4 +409,4 @@ formatting. Thanks `Ruslan Baratov <https://github.com/ruslo>`_ for comprehensiv
and useful comments regarding performance, `Boris Kaul <https://github.com/localvoid>`_ for
`C++ counting digits benchmark <https://github.com/localvoid/cxx-benchmark-count-digits>`_.
Thanks to `CarterLi <https://github.com/CarterLi>`_ for contributing various
improvements to the code.
improvements to the code.

82
cppformat/CMakeLists.txt Normal file
View File

@ -0,0 +1,82 @@
# Define the cppformat library, its includes and the needed defines.
# format.cc is added to FMT_HEADERS for the header-only configuration.
set(FMT_HEADERS format.h format.cc)
if (HAVE_OPEN)
set(FMT_HEADERS ${FMT_HEADERS} posix.h)
set(FMT_SOURCES ${FMT_SOURCES} posix.cc)
endif ()
add_library(cppformat ${FMT_SOURCES} ${FMT_HEADERS})
# Starting with cmake 3.1 the CXX_STANDARD property can be used instead.
target_compile_options(cppformat PUBLIC ${CPP11_FLAG})
if (FMT_PEDANTIC)
target_compile_options(cppformat PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
target_include_directories(cppformat INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
set_target_properties(cppformat PROPERTIES
VERSION ${CPPFORMAT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
if (BUILD_SHARED_LIBS)
if (UNIX AND NOT APPLE)
# Fix rpmlint warning:
# unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6.
target_link_libraries(cppformat -Wl,--as-needed)
endif ()
target_compile_definitions(cppformat PRIVATE FMT_EXPORT INTERFACE FMT_SHARED)
endif ()
#------------------------------------------------------------------------------
# additionally define a header only library when cmake is new enough
if (CMAKE_VERSION VERSION_GREATER 3.1.0 OR CMAKE_VERSION VERSION_EQUAL 3.1.0)
add_library(cppformat-header-only INTERFACE)
target_compile_definitions(cppformat-header-only INTERFACE FMT_HEADER_ONLY=1)
target_include_directories(cppformat-header-only INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>)
endif ()
# Install targets.
if (FMT_INSTALL)
include(CMakePackageConfigHelpers)
set(FMT_CMAKE_DIR lib/cmake/cppformat CACHE STRING
"Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.")
set(version_config ${PROJECT_BINARY_DIR}/cppformat-config-version.cmake)
set(project_config ${PROJECT_BINARY_DIR}/cppformat-config.cmake)
set(targets_export_name cppformat-targets)
set (INSTALL_TARGETS cppformat)
if (TARGET cppformat-header-only)
set(INSTALL_TARGETS ${INSTALL_TARGETS} cppformat-header-only)
endif ()
set(FMT_LIB_DIR lib CACHE STRING
"Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.")
# Generate the version, config and target files into the build directory.
write_basic_package_version_file(
${version_config}
VERSION ${CPPFORMAT_VERSION}
COMPATIBILITY AnyNewerVersion)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/support/cmake/cppformat-config.cmake.in
${project_config}
INSTALL_DESTINATION ${FMT_CMAKE_DIR})
export(TARGETS ${INSTALL_TARGETS} FILE ${PROJECT_BINARY_DIR}/${targets_export_name}.cmake)
# Install version, config and target files.
install(
FILES ${project_config} ${version_config}
DESTINATION ${FMT_CMAKE_DIR})
install(EXPORT ${targets_export_name} DESTINATION ${FMT_CMAKE_DIR})
# Install the library and headers.
install(TARGETS ${INSTALL_TARGETS} EXPORT ${targets_export_name} DESTINATION ${FMT_LIB_DIR})
install(FILES ${FMT_HEADERS} DESTINATION include/cppformat)
endif ()

3259
cppformat/format.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -55,11 +55,14 @@
# ifdef __MINGW32__
# define _SH_DENYNO 0x40
# undef fileno
# endif
#endif // _WIN32
#ifdef fileno
# undef fileno
#endif
namespace {
#ifdef _WIN32
// Return type of read and write functions.

344
cppformat/posix.h Normal file
View File

@ -0,0 +1,344 @@
/*
A C++ interface to POSIX functions.
Copyright (c) 2014 - 2015, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FMT_POSIX_H_
#define FMT_POSIX_H_
#ifdef __MINGW32__
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
# undef __STRICT_ANSI__
#endif
#include <errno.h>
#include <fcntl.h> // for O_RDONLY
#include <stdio.h>
#include <cstddef>
#include "format.h"
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) call
# ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#endif
#if FMT_GCC_VERSION >= 407
# define FMT_UNUSED __attribute__((unused))
#else
# define FMT_UNUSED
#endif
#ifndef FMT_USE_STATIC_ASSERT
# define FMT_USE_STATIC_ASSERT 0
#endif
#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
(FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
#else
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
# define FMT_STATIC_ASSERT(cond, message) \
typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
result = (expression); \
} while (result == error_result && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
namespace fmt {
// An error code.
class ErrorCode {
private:
int value_;
public:
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
int get() const FMT_NOEXCEPT { return value_; }
};
// A buffered file.
class BufferedFile {
private:
FILE *file_;
friend class File;
explicit BufferedFile(FILE *f) : file_(f) {}
public:
// Constructs a BufferedFile object which doesn't represent any file.
BufferedFile() FMT_NOEXCEPT : file_(0) {}
// Destroys the object closing the file it represents if any.
~BufferedFile() FMT_NOEXCEPT;
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct Proxy {
FILE *file;
};
public:
// A "move constructor" for moving from a temporary.
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
// A "move constructor" for for moving from an lvalue.
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
f.file_ = 0;
}
// A "move assignment operator" for moving from a temporary.
BufferedFile &operator=(Proxy p) {
close();
file_ = p.file;
return *this;
}
// A "move assignment operator" for moving from an lvalue.
BufferedFile &operator=(BufferedFile &other) {
close();
file_ = other.file_;
other.file_ = 0;
return *this;
}
// Returns a proxy object for moving from a temporary:
// BufferedFile file = BufferedFile(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {file_};
file_ = 0;
return p;
}
#else
private:
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
public:
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = 0;
}
BufferedFile& operator=(BufferedFile &&other) {
close();
file_ = other.file_;
other.file_ = 0;
return *this;
}
#endif
// Opens a file.
BufferedFile(CStringRef filename, CStringRef mode);
// Closes the file.
void close();
// Returns the pointer to a FILE object representing this file.
FILE *get() const FMT_NOEXCEPT { return file_; }
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
int (fileno)() const;
void print(CStringRef format_str, const ArgList &args) {
fmt::print(file_, format_str, args);
}
FMT_VARIADIC(void, print, CStringRef)
};
// A file. Closed file is represented by a File object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::SystemError in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class File {
private:
int fd_; // File descriptor.
// Constructs a File object with a given descriptor.
explicit File(int fd) : fd_(fd) {}
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
};
// Constructs a File object which doesn't represent any file.
File() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a File object representing this file.
File(CStringRef path, int oflag);
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct Proxy {
int fd;
};
public:
// A "move constructor" for moving from a temporary.
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
// A "move constructor" for for moving from an lvalue.
File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
// A "move assignment operator" for moving from a temporary.
File &operator=(Proxy p) {
close();
fd_ = p.fd;
return *this;
}
// A "move assignment operator" for moving from an lvalue.
File &operator=(File &other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
// Returns a proxy object for moving from a temporary:
// File file = File(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {fd_};
fd_ = -1;
return p;
}
#else
private:
FMT_DISALLOW_COPY_AND_ASSIGN(File);
public:
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
File& operator=(File &&other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
#endif
// Destroys the object closing the file it represents if any.
~File() FMT_NOEXCEPT;
// Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file.
void close();
// Returns the file size.
LongLong size() const;
// Attempts to read count bytes from the file into the specified buffer.
std::size_t read(void *buffer, std::size_t count);
// Attempts to write count bytes from the specified buffer to the file.
std::size_t write(const void *buffer, std::size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
static File dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
static void pipe(File &read_end, File &write_end);
// Creates a BufferedFile object associated with this file and detaches
// this File object from the file.
BufferedFile fdopen(const char *mode);
};
// Returns the memory page size.
long getpagesize();
} // namespace fmt
#if !FMT_USE_RVALUE_REFERENCES
namespace std {
// For compatibility with C++98.
inline fmt::BufferedFile &move(fmt::BufferedFile &f) { return f; }
inline fmt::File &move(fmt::File &f) { return f; }
}
#endif
#endif // FMT_POSIX_H_

View File

@ -53,6 +53,7 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-expanded="false">{{ version }} <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="http://cppformat.github.io/2.0.0/">2.0.0</a></li>
<li><a href="http://cppformat.github.io/1.1.0/">1.1.0</a></li>
<li><a href="http://cppformat.github.io/1.0.0/">1.0.0</a></li>
</ul>

View File

@ -8,8 +8,8 @@ All functions and classes provided by the C++ Format library reside
in namespace ``fmt`` and macros have prefix ``FMT_``. For brevity the
namespace is usually omitted in examples.
Formatting functions
====================
Format API
==========
The following functions use :ref:`format string syntax <syntax>` similar
to the one used by Python's `str.format
@ -36,8 +36,11 @@ arguments in the resulting string.
.. doxygenfunction:: print(std::ostream&, CStringRef, ArgList)
.. doxygenclass:: fmt::BasicFormatter
:members:
Printf formatting functions
===========================
---------------------------
The following functions use `printf format string syntax
<http://pubs.opengroup.org/onlinepubs/009695399/functions/fprintf.html>`_ with
@ -45,7 +48,9 @@ a POSIX extension for positional arguments.
.. doxygenfunction:: printf(CStringRef, ArgList)
.. doxygenfunction:: fprintf(std::FILE*, CStringRef, ArgList)
.. doxygenfunction:: fprintf(std::FILE *, CStringRef, ArgList)
.. doxygenfunction:: fprintf(std::ostream&, CStringRef, ArgList)
.. doxygenfunction:: sprintf(CStringRef, ArgList)
@ -61,13 +66,13 @@ Write API
.. doxygenclass:: fmt::BasicArrayWriter
:members:
.. doxygenfunction:: bin
.. doxygenfunction:: bin(int)
.. doxygenfunction:: oct
.. doxygenfunction:: oct(int)
.. doxygenfunction:: hex
.. doxygenfunction:: hex(int)
.. doxygenfunction:: hexu
.. doxygenfunction:: hexu(int)
.. doxygenfunction:: pad(int, unsigned, Char)

View File

@ -69,12 +69,14 @@ def build_docs(version='dev'):
XML_OUTPUT = doxyxml
ALIASES = "rst=\verbatim embed:rst"
ALIASES += "endrst=\endverbatim"
MACRO_EXPANSION = YES
PREDEFINED = _WIN32=1 \
FMT_USE_VARIADIC_TEMPLATES=1 \
FMT_USE_RVALUE_REFERENCES=1 \
FMT_USE_USER_DEFINED_LITERALS=1
FMT_USE_USER_DEFINED_LITERALS=1 \
FMT_API=
EXCLUDE_SYMBOLS = fmt::internal::* StringValue write_str
'''.format(os.path.dirname(doc_dir)).encode('UTF-8'))
'''.format(os.path.join(os.path.dirname(doc_dir), 'cppformat')).encode('UTF-8'))
if p.returncode != 0:
raise CalledProcessError(p.returncode, cmd)
check_call(['sphinx-build',

View File

@ -59,3 +59,8 @@ div.sphinxsidebar {
p.rubric {
margin-top: 10px;
}
.github-btn {
border: 0;
overflow: hidden;
}

3261
format.h

File diff suppressed because it is too large Load Diff

346
posix.h
View File

@ -1,344 +1,2 @@
/*
A C++ interface to POSIX functions.
Copyright (c) 2014 - 2015, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FMT_POSIX_H_
#define FMT_POSIX_H_
#ifdef __MINGW32__
// Workaround MinGW bug https://sourceforge.net/p/mingw/bugs/2024/.
# undef __STRICT_ANSI__
#endif
#include <errno.h>
#include <fcntl.h> // for O_RDONLY
#include <stdio.h>
#include <cstddef>
#include "format.h"
#ifndef FMT_POSIX
# if defined(_WIN32) && !defined(__MINGW32__)
// Fix warnings about deprecated symbols.
# define FMT_POSIX(call) _##call
# else
# define FMT_POSIX(call) call
# endif
#endif
// Calls to system functions are wrapped in FMT_SYSTEM for testability.
#ifdef FMT_SYSTEM
# define FMT_POSIX_CALL(call) FMT_SYSTEM(call)
#else
# define FMT_SYSTEM(call) call
# ifdef _WIN32
// Fix warnings about deprecated symbols.
# define FMT_POSIX_CALL(call) ::_##call
# else
# define FMT_POSIX_CALL(call) ::call
# endif
#endif
#if FMT_GCC_VERSION >= 407
# define FMT_UNUSED __attribute__((unused))
#else
# define FMT_UNUSED
#endif
#ifndef FMT_USE_STATIC_ASSERT
# define FMT_USE_STATIC_ASSERT 0
#endif
#if FMT_USE_STATIC_ASSERT || FMT_HAS_FEATURE(cxx_static_assert) || \
(FMT_GCC_VERSION >= 403 && FMT_HAS_GXX_CXX11) || _MSC_VER >= 1600
# define FMT_STATIC_ASSERT(cond, message) static_assert(cond, message)
#else
# define FMT_CONCAT_(a, b) FMT_CONCAT(a, b)
# define FMT_STATIC_ASSERT(cond, message) \
typedef int FMT_CONCAT_(Assert, __LINE__)[(cond) ? 1 : -1] FMT_UNUSED
#endif
// Retries the expression while it evaluates to error_result and errno
// equals to EINTR.
#ifndef _WIN32
# define FMT_RETRY_VAL(result, expression, error_result) \
do { \
result = (expression); \
} while (result == error_result && errno == EINTR)
#else
# define FMT_RETRY_VAL(result, expression, error_result) result = (expression)
#endif
#define FMT_RETRY(result, expression) FMT_RETRY_VAL(result, expression, -1)
namespace fmt {
// An error code.
class ErrorCode {
private:
int value_;
public:
explicit ErrorCode(int value = 0) FMT_NOEXCEPT : value_(value) {}
int get() const FMT_NOEXCEPT { return value_; }
};
// A buffered file.
class BufferedFile {
private:
FILE *file_;
friend class File;
explicit BufferedFile(FILE *f) : file_(f) {}
public:
// Constructs a BufferedFile object which doesn't represent any file.
BufferedFile() FMT_NOEXCEPT : file_(0) {}
// Destroys the object closing the file it represents if any.
~BufferedFile() FMT_NOEXCEPT;
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct Proxy {
FILE *file;
};
public:
// A "move constructor" for moving from a temporary.
BufferedFile(Proxy p) FMT_NOEXCEPT : file_(p.file) {}
// A "move constructor" for for moving from an lvalue.
BufferedFile(BufferedFile &f) FMT_NOEXCEPT : file_(f.file_) {
f.file_ = 0;
}
// A "move assignment operator" for moving from a temporary.
BufferedFile &operator=(Proxy p) {
close();
file_ = p.file;
return *this;
}
// A "move assignment operator" for moving from an lvalue.
BufferedFile &operator=(BufferedFile &other) {
close();
file_ = other.file_;
other.file_ = 0;
return *this;
}
// Returns a proxy object for moving from a temporary:
// BufferedFile file = BufferedFile(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {file_};
file_ = 0;
return p;
}
#else
private:
FMT_DISALLOW_COPY_AND_ASSIGN(BufferedFile);
public:
BufferedFile(BufferedFile &&other) FMT_NOEXCEPT : file_(other.file_) {
other.file_ = 0;
}
BufferedFile& operator=(BufferedFile &&other) {
close();
file_ = other.file_;
other.file_ = 0;
return *this;
}
#endif
// Opens a file.
BufferedFile(CStringRef filename, CStringRef mode);
// Closes the file.
void close();
// Returns the pointer to a FILE object representing this file.
FILE *get() const FMT_NOEXCEPT { return file_; }
// We place parentheses around fileno to workaround a bug in some versions
// of MinGW that define fileno as a macro.
int (fileno)() const;
void print(CStringRef format_str, const ArgList &args) {
fmt::print(file_, format_str, args);
}
FMT_VARIADIC(void, print, CStringRef)
};
// A file. Closed file is represented by a File object with descriptor -1.
// Methods that are not declared with FMT_NOEXCEPT may throw
// fmt::SystemError in case of failure. Note that some errors such as
// closing the file multiple times will cause a crash on Windows rather
// than an exception. You can get standard behavior by overriding the
// invalid parameter handler with _set_invalid_parameter_handler.
class File {
private:
int fd_; // File descriptor.
// Constructs a File object with a given descriptor.
explicit File(int fd) : fd_(fd) {}
public:
// Possible values for the oflag argument to the constructor.
enum {
RDONLY = FMT_POSIX(O_RDONLY), // Open for reading only.
WRONLY = FMT_POSIX(O_WRONLY), // Open for writing only.
RDWR = FMT_POSIX(O_RDWR) // Open for reading and writing.
};
// Constructs a File object which doesn't represent any file.
File() FMT_NOEXCEPT : fd_(-1) {}
// Opens a file and constructs a File object representing this file.
File(CStringRef path, int oflag);
#if !FMT_USE_RVALUE_REFERENCES
// Emulate a move constructor and a move assignment operator if rvalue
// references are not supported.
private:
// A proxy object to emulate a move constructor.
// It is private to make it impossible call operator Proxy directly.
struct Proxy {
int fd;
};
public:
// A "move constructor" for moving from a temporary.
File(Proxy p) FMT_NOEXCEPT : fd_(p.fd) {}
// A "move constructor" for for moving from an lvalue.
File(File &other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
// A "move assignment operator" for moving from a temporary.
File &operator=(Proxy p) {
close();
fd_ = p.fd;
return *this;
}
// A "move assignment operator" for moving from an lvalue.
File &operator=(File &other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
// Returns a proxy object for moving from a temporary:
// File file = File(...);
operator Proxy() FMT_NOEXCEPT {
Proxy p = {fd_};
fd_ = -1;
return p;
}
#else
private:
FMT_DISALLOW_COPY_AND_ASSIGN(File);
public:
File(File &&other) FMT_NOEXCEPT : fd_(other.fd_) {
other.fd_ = -1;
}
File& operator=(File &&other) {
close();
fd_ = other.fd_;
other.fd_ = -1;
return *this;
}
#endif
// Destroys the object closing the file it represents if any.
~File() FMT_NOEXCEPT;
// Returns the file descriptor.
int descriptor() const FMT_NOEXCEPT { return fd_; }
// Closes the file.
void close();
// Returns the file size.
LongLong size() const;
// Attempts to read count bytes from the file into the specified buffer.
std::size_t read(void *buffer, std::size_t count);
// Attempts to write count bytes from the specified buffer to the file.
std::size_t write(const void *buffer, std::size_t count);
// Duplicates a file descriptor with the dup function and returns
// the duplicate as a file object.
static File dup(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
void dup2(int fd);
// Makes fd be the copy of this file descriptor, closing fd first if
// necessary.
void dup2(int fd, ErrorCode &ec) FMT_NOEXCEPT;
// Creates a pipe setting up read_end and write_end file objects for reading
// and writing respectively.
static void pipe(File &read_end, File &write_end);
// Creates a BufferedFile object associated with this file and detaches
// this File object from the file.
BufferedFile fdopen(const char *mode);
};
// Returns the memory page size.
long getpagesize();
} // namespace fmt
#if !FMT_USE_RVALUE_REFERENCES
namespace std {
// For compatibility with C++98.
inline fmt::BufferedFile &move(fmt::BufferedFile &f) { return f; }
inline fmt::File &move(fmt::File &f) { return f; }
}
#endif
#endif // FMT_POSIX_H_
#include "cppformat/posix.h"
#warning Including posix.h from the top-level directory is deprecated.

View File

@ -1,18 +0,0 @@
# Initializes block variables
INIT_BIICODE_BLOCK()
# Actually create targets: EXEcutables and libraries.
ADD_BIICODE_TARGETS()
target_include_directories(${BII_BLOCK_TARGET} INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
if (HAVE_OPEN)
target_compile_definitions(${BII_BLOCK_TARGET} INTERFACE -DFMT_USE_FILE_DESCRIPTORS=1)
endif ()
if (CMAKE_COMPILER_IS_GNUCXX)
target_compile_options(${BII_BLOCK_TARGET} INTERFACE -Wall -Wextra -Wshadow -pedantic)
endif ()
if (CPP11_FLAG AND FMT_PEDANTIC)
target_compile_options(${BII_BLOCK_TARGET} INTERFACE ${CPP11_FLAG})
endif ()

View File

@ -0,0 +1,4 @@
@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/@targets_export_name@.cmake)
check_required_components(cppformat)

View File

@ -0,0 +1,60 @@
include(CheckCXXCompilerFlag)
if (FMT_USE_CPP11)
check_cxx_compiler_flag(-std=c++11 HAVE_STD_CPP11_FLAG)
if (HAVE_STD_CPP11_FLAG)
# Check if including cmath works with -std=c++11 and -O3.
# It may not in MinGW due to bug http://ehc.ac/p/mingw/bugs/2250/.
set(CMAKE_REQUIRED_FLAGS "-std=c++11 -O3")
check_cxx_source_compiles("
#include <cmath>
int main() {}" FMT_CPP11_CMATH)
# Check if including <unistd.h> works with -std=c++11.
# It may not in MinGW due to bug http://sourceforge.net/p/mingw/bugs/2024/.
check_cxx_source_compiles("
#include <unistd.h>
int main() {}" FMT_CPP11_UNISTD_H)
if (FMT_CPP11_CMATH AND FMT_CPP11_UNISTD_H)
set(CPP11_FLAG -std=c++11)
else ()
check_cxx_compiler_flag(-std=gnu++11 HAVE_STD_GNUPP11_FLAG)
if (HAVE_STD_CPP11_FLAG)
set(CPP11_FLAG -std=gnu++11)
endif ()
endif ()
set(CMAKE_REQUIRED_FLAGS )
else ()
check_cxx_compiler_flag(-std=c++0x HAVE_STD_CPP0X_FLAG)
if (HAVE_STD_CPP0X_FLAG)
set(CPP11_FLAG -std=c++0x)
endif ()
endif ()
endif ()
set(CMAKE_REQUIRED_FLAGS ${CPP11_FLAG})
# Check if variadic templates are working and not affected by GCC bug 39653:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39653
check_cxx_source_compiles("
template <class T, class ...Types>
struct S { typedef typename S<Types...>::type type; };
int main() {}" SUPPORTS_VARIADIC_TEMPLATES)
# Check if initializer lists are supported.
check_cxx_source_compiles("
#include <initializer_list>
int main() {}" SUPPORTS_INITIALIZER_LIST)
# Check if enum bases are available
check_cxx_source_compiles("
enum C : char {A};
int main() {}"
SUPPORTS_ENUM_BASE)
# Check if type traits are available
check_cxx_source_compiles("
#include <type_traits>
class C { void operator=(const C&); };
int main() { static_assert(!std::is_copy_assignable<C>::value, \"\"); }"
SUPPORTS_TYPE_TRAITS)
set(CMAKE_REQUIRED_FLAGS )

View File

@ -1,15 +1,15 @@
set(FMT_GMOCK_DIR ../gmock)
include_directories(.. ${FMT_GMOCK_DIR})
#------------------------------------------------------------------------------
# Build the google test library
# We compile Google Test ourselves instead of using pre-compiled libraries.
# See the Google Test FAQ "Why is it not recommended to install a
# pre-compiled copy of Google Test (for example, into /usr/local)?"
# at http://code.google.com/p/googletest/wiki/FAQ for more details.
add_library(gmock STATIC
${FMT_GMOCK_DIR}/gmock-gtest-all.cc ${FMT_GMOCK_DIR}/gmock/gmock.h
${FMT_GMOCK_DIR}/gtest/gtest.h ${FMT_GMOCK_DIR}/gtest/gtest-spi.h)
gmock-gtest-all.cc gmock/gmock.h gtest/gtest.h gtest/gtest-spi.h)
target_compile_options(gmock PUBLIC ${CPP11_FLAG})
target_include_directories(gmock PUBLIC .)
find_package(Threads)
if (Threads_FOUND)
target_link_libraries(gmock ${CMAKE_THREAD_LIBS_INIT})
@ -17,20 +17,8 @@ else ()
target_compile_definitions(gmock PUBLIC GTEST_HAS_PTHREAD=0)
endif ()
# Check if variadic templates are working and not affected by GCC bug 39653:
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39653
check_cxx_source_compiles("
template <class T, class ...Types>
struct S { typedef typename S<Types...>::type type; };
int main() {}" FMT_VARIADIC_TEMPLATES)
# Check if initializer lists are supported.
check_cxx_source_compiles("
#include <initializer_list>
int main() {}" FMT_INITIALIZER_LIST)
if (NOT FMT_VARIADIC_TEMPLATES OR NOT FMT_INITIALIZER_LIST)
add_definitions(-DGTEST_LANG_CXX11=0)
if (NOT SUPPORTS_VARIADIC_TEMPLATES OR NOT SUPPORTS_INITIALIZER_LIST)
target_compile_definitions(gmock PUBLIC GTEST_LANG_CXX11=0)
endif ()
# Workaround a bug in implementation of variadic templates in MSVC11.
@ -43,18 +31,39 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
target_compile_definitions(gmock PUBLIC GTEST_USE_OWN_TR1_TUPLE=1)
endif ()
#------------------------------------------------------------------------------
# Build the actual library tests
set(TEST_MAIN_SRC test-main.cc gtest-extra.cc gtest-extra.h util.cc)
add_library(test-main STATIC ${TEST_MAIN_SRC})
target_link_libraries(test-main cppformat gmock)
target_compile_definitions(test-main PUBLIC
FMT_USE_FILE_DESCRIPTORS=$<BOOL:${HAVE_OPEN}>)
target_link_libraries(test-main gmock cppformat)
# Workaround GTest bug https://github.com/google/googletest/issues/705.
check_cxx_compiler_flag(
-fno-delete-null-pointer-checks HAVE_FNO_DELETE_NULL_POINTER_CHECKS)
if (HAVE_FNO_DELETE_NULL_POINTER_CHECKS)
target_compile_options(test-main PUBLIC -fno-delete-null-pointer-checks)
endif ()
# relax pedantic flags for the tests
# TODO: fix warnings in tests to make this redundant. (e.g. -Wshadow,...)
if (CMAKE_COMPILER_IS_GNUCXX OR (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wno-long-long -Wno-variadic-macros)
endif ()
# Adds a test.
# Usage: add_fmt_test(name [CUSTOM_LINK] srcs...)
# Usage: add_fmt_test(name srcs...)
function(add_fmt_test name)
cmake_parse_arguments(add_fmt_test CUSTOM_LINK "" "" ${ARGN})
add_executable(${name} ${name}.cc ${add_fmt_test_UNPARSED_ARGUMENTS})
add_executable(${name} ${name}.cc ${ARGN})
target_link_libraries(${name} test-main)
if (NOT add_fmt_test_CUSTOM_LINK)
target_link_libraries(${name} cppformat)
# define if certain c++ features can be used
target_compile_definitions(${name} PRIVATE
FMT_USE_TYPE_TRAITS=$<BOOL:${SUPPORTS_TYPE_TRAITS}>
FMT_USE_ENUM_BASE=$<BOOL:${SUPPORTS_ENUM_BASE}>)
if (FMT_PEDANTIC)
target_compile_options(${name} PRIVATE ${PEDANTIC_COMPILE_FLAGS})
endif ()
add_test(NAME ${name} COMMAND ${name})
endfunction()
@ -62,56 +71,22 @@ endfunction()
add_fmt_test(assert-test)
add_fmt_test(gtest-extra-test)
add_fmt_test(format-test)
if (FMT_PEDANTIC AND MSVC)
set_target_properties(format-test PROPERTIES COMPILE_FLAGS /W4)
endif ()
add_fmt_test(format-impl-test CUSTOM_LINK)
add_fmt_test(format-impl-test)
add_fmt_test(printf-test)
foreach (target format-test printf-test)
if (FMT_PEDANTIC AND CMAKE_COMPILER_IS_GNUCXX)
set_target_properties(${target} PROPERTIES COMPILE_FLAGS
"-Wall -Wextra -pedantic -Wno-long-long -Wno-variadic-macros")
endif ()
if (CPP11_FLAG)
set_target_properties(${target} PROPERTIES COMPILE_FLAGS ${CPP11_FLAG})
endif ()
endforeach ()
add_fmt_test(util-test mock-allocator.h)
if (CPP11_FLAG)
set_target_properties(util-test PROPERTIES COMPILE_FLAGS ${CPP11_FLAG})
add_fmt_test(macro-test)
# Enable stricter options for one test to make sure that the header is free of
# warnings.
# TODO: make all tests warning free and add this flag to PEDANTIC_COMPILE_FLAGS
if (FMT_PEDANTIC AND MSVC)
target_compile_options(format-test PRIVATE /W4)
endif ()
check_cxx_source_compiles("
enum C : char {A};
int main() {}"
HAVE_ENUM_BASE)
if (HAVE_ENUM_BASE)
set_target_properties(util-test
PROPERTIES COMPILE_DEFINITIONS "FMT_USE_ENUM_BASE=1")
endif ()
foreach (src ${FMT_SOURCES})
set(FMT_TEST_SOURCES ${FMT_TEST_SOURCES} ../${src})
endforeach ()
check_cxx_source_compiles("
#include <type_traits>
class C { void operator=(const C&); };
int main() { static_assert(!std::is_copy_assignable<C>::value, \"\"); }"
HAVE_TYPE_TRAITS)
if (HAVE_TYPE_TRAITS)
foreach (target format-test util-test)
set_target_properties(${target}
PROPERTIES COMPILE_DEFINITIONS "FMT_USE_TYPE_TRAITS=1")
endforeach ()
endif ()
add_executable(macro-test macro-test.cc ${FMT_TEST_SOURCES} ${TEST_MAIN_SRC})
target_link_libraries(macro-test gmock)
if (HAVE_OPEN)
add_executable(posix-mock-test posix-mock-test.cc ../format.cc ${TEST_MAIN_SRC})
add_executable(posix-mock-test posix-mock-test.cc ../cppformat/format.cc ${TEST_MAIN_SRC})
target_include_directories(posix-mock-test PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_definitions(posix-mock-test PRIVATE FMT_USE_FILE_DESCRIPTORS=1)
target_link_libraries(posix-mock-test gmock)
add_test(NAME posix-mock-test COMMAND posix-mock-test)
add_fmt_test(posix-test)
@ -119,28 +94,28 @@ endif ()
add_executable(header-only-test
header-only-test.cc header-only-test2.cc test-main.cc)
set_target_properties(header-only-test
PROPERTIES COMPILE_DEFINITIONS "FMT_HEADER_ONLY=1")
target_link_libraries(header-only-test gmock)
if (TARGET cppformat-header-only)
target_link_libraries(header-only-test cppformat-header-only)
else ()
target_include_directories(header-only-test PRIVATE ${PROJECT_SOURCE_DIR})
target_compile_definitions(header-only-test PRIVATE FMT_HEADER_ONLY=1)
endif ()
# Test that the library can be compiled with exceptions disabled.
check_cxx_compiler_flag(-fno-exceptions HAVE_FNO_EXCEPTIONS_FLAG)
if (HAVE_FNO_EXCEPTIONS_FLAG)
add_library(noexception-test STATIC ../format.cc)
set_target_properties(noexception-test
PROPERTIES COMPILE_FLAGS -fno-exceptions)
endif ()
# Test compilation with default flags.
if (FMT_TEST_DEFAULT_FLAGS)
file(GLOB src RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cc *.h)
foreach (s ${FMT_SOURCES})
set(src ${src} ../${s})
endforeach ()
add_library(testformat STATIC ${src})
add_library(noexception-test ../cppformat/format.cc)
target_compile_options(noexception-test PRIVATE -fno-exceptions)
endif ()
if (FMT_PEDANTIC)
# Test that the library compiles without windows.h.
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
add_library(no-windows-h-test ../cppformat/format.cc)
target_compile_definitions(no-windows-h-test PRIVATE FMT_USE_WINDOWS_H=0)
endif ()
add_test(compile-test ${CMAKE_CTEST_COMMAND}
--build-and-test
"${CMAKE_CURRENT_SOURCE_DIR}/compile-test"
@ -148,8 +123,24 @@ if (FMT_PEDANTIC)
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${CMAKE_MAKE_PROGRAM})
# Test that the library compiles without windows.h.
add_library(no-windows-h-test ../format.cc)
set_target_properties(no-windows-h-test
PROPERTIES COMPILE_DEFINITIONS "FMT_USE_WINDOWS_H=0")
# test if the targets are findable from the build directory
add_test(find-package-test ${CMAKE_CTEST_COMMAND}
-C ${CMAKE_BUILD_TYPE}
--build-and-test
"${CMAKE_CURRENT_SOURCE_DIR}/find-package-test"
"${CMAKE_CURRENT_BINARY_DIR}/find-package-test"
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options "-Dcppformat_DIR=${PROJECT_BINARY_DIR}"
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
# test if the targets are findable when add_subdirectory is used
add_test(add-subdirectory-test ${CMAKE_CTEST_COMMAND}
-C ${CMAKE_BUILD_TYPE}
--build-and-test
"${CMAKE_CURRENT_SOURCE_DIR}/add-subdirectory-test"
"${CMAKE_CURRENT_BINARY_DIR}/add-subdirectory-test"
--build-generator ${CMAKE_GENERATOR}
--build-makeprogram ${CMAKE_MAKE_PROGRAM}
--build-options "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
endif ()

View File

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 2.8.12)
project(cppformat-test)
add_subdirectory(../.. cppformat)
add_executable(library-test "main.cpp")
target_link_libraries(library-test cppformat)
if (TARGET cppformat-header-only)
add_executable(header-only-test "main.cpp")
target_link_libraries(header-only-test cppformat-header-only)
endif ()

View File

@ -0,0 +1,8 @@
#include "cppformat/format.h"
int main(int argc, char** argv)
{
for(int i = 0; i < argc; ++i)
fmt::print("{}: {}\n", i, argv[i]);
return 0;
}

View File

@ -25,7 +25,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "format.h"
#include "cppformat/format.h"
#include "gtest/gtest.h"
#if GTEST_HAS_DEATH_TEST

View File

@ -5,23 +5,41 @@ cmake_minimum_required(VERSION 2.8)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/../..)
function (expect_compile_error code)
check_cxx_source_compiles("
#include \"format.cc\"
#include \"posix.h\"
function (generate_source result fragment)
set(${result} "
#define FMT_HEADER_ONLY 1
#include \"cppformat/format.h\"
int main() {
${code}
${fragment}
}
" compiles)
set (does_compile ${compiles})
" PARENT_SCOPE)
endfunction ()
function (expect_compile code)
generate_source(source "${code}")
check_cxx_source_compiles("${source}" compiles)
if (NOT compiles)
message(FATAL_ERROR "Compile error for: ${code}")
endif ()
# Unset the CMake cache variable compiles. Otherwise the compile test will
# just use cached information next time it runs.
unset(compiles CACHE)
if (does_compile)
endfunction ()
function (expect_compile_error code)
generate_source(source "${code}")
check_cxx_source_compiles("${source}" compiles)
if (compiles)
message(FATAL_ERROR "No compile error for: ${code}")
endif ()
# Unset the CMake cache variable compiles. Otherwise the compile test will
# just use cached information next time it runs.
unset(compiles CACHE)
endfunction ()
# check if the source file skeleton compiles
expect_compile("")
# MakeArg doesn't accept [const] volatile char *.
expect_compile_error("volatile char s[] = \"test\"; (fmt::internal::MakeArg<char>)(s);")
expect_compile_error("const volatile char s[] = \"test\"; (fmt::internal::MakeArg<char>)(s);")

View File

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 2.8.12)
project(cppformat-test)
find_package(cppformat REQUIRED)
add_executable(library-test "main.cpp")
target_link_libraries(library-test cppformat)
if (TARGET cppformat-header-only)
add_executable(header-only-test "main.cpp")
target_link_libraries(header-only-test cppformat-header-only)
endif ()

View File

@ -0,0 +1,8 @@
#include "cppformat/format.h"
int main(int argc, char** argv)
{
for(int i = 0; i < argc; ++i)
fmt::print("{}: {}\n", i, argv[i]);
return 0;
}

View File

@ -29,7 +29,7 @@
#include "test-assert.h"
// Include format.cc instead of format.h to test implementation-specific stuff.
#include "format.cc"
#include "cppformat/format.cc"
#include <cstring>

View File

@ -45,7 +45,7 @@
// Test that the library compiles if None is defined to 0 as done by xlib.h.
#define None 0
#include "format.h"
#include "cppformat/format.h"
#include "util.h"
#include "mock-allocator.h"
#include "gtest-extra.h"

View File

@ -36,6 +36,10 @@
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_H_
#ifdef __clang__
# pragma clang diagnostic ignored "-Wc99-extensions"
#endif
// This file implements the following syntax:
//
// ON_CALL(mock_object.Method(...))

View File

@ -31,14 +31,14 @@
#include <string>
#include <gtest/gtest.h>
#include "format.h"
#include "cppformat/format.h"
#ifndef FMT_USE_FILE_DESCRIPTORS
# define FMT_USE_FILE_DESCRIPTORS 0
#endif
#if FMT_USE_FILE_DESCRIPTORS
# include "posix.h"
# include "cppformat/posix.h"
#endif
#define FMT_TEST_THROW_(statement, expected_exception, expected_message, fail) \

View File

@ -25,4 +25,4 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "format.h"
#include "cppformat/format.h"

View File

@ -25,4 +25,4 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "format.h"
#include "cppformat/format.h"

View File

@ -29,7 +29,7 @@
#include <gtest/gtest.h>
#define FMT_USE_VARIADIC_TEMPLATES 0
#include "format.h"
#include "cppformat/format.h"
#define IDENTITY(x) x

View File

@ -29,7 +29,7 @@
#define _CRT_SECURE_NO_WARNINGS
#include "posix-mock.h"
#include "posix.cc"
#include "cppformat/posix.cc"
#include <errno.h>
#include <fcntl.h>

View File

@ -28,10 +28,10 @@
#include <cstring>
#include "gtest-extra.h"
#include "posix.h"
#include "cppformat/posix.h"
#include "util.h"
#ifdef __MINGW32__
#ifdef fileno
# undef fileno
#endif

View File

@ -29,7 +29,7 @@
#include <climits>
#include <cstring>
#include "format.h"
#include "cppformat/format.h"
#include "gtest-extra.h"
#include "util.h"

View File

@ -47,7 +47,7 @@
# include <windows.h>
#endif
#include "format.h"
#include "cppformat/format.h"
#undef max

View File

@ -29,7 +29,7 @@
#include <cstdio>
#include <string>
#include "posix.h"
#include "cppformat/posix.h"
enum {BUFFER_SIZE = 256};