Switch to plain cmake, no biicode anymore.

This commit is contained in:
Sebastian Messmer 2016-02-10 00:58:03 +01:00
parent 7d532d8115
commit ee702471f0
525 changed files with 176875 additions and 284 deletions

31
.gitignore vendored
View File

@ -1,28 +1,3 @@
# Compiled Object files build
*.slo cmake
*.lo .idea
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View File

@ -1,103 +1,5 @@
INCLUDE(messmer/cmake/tools) cmake_minimum_required(VERSION 3.0)
# Actually create targets: EXEcutables and libraries.
ADD_BII_TARGETS()
ACTIVATE_CPP14()
ADD_BOOST(filesystem system thread)
# This is needed by boost thread
IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
TARGET_LINK_LIBRARIES(${BII_BLOCK_TARGET} INTERFACE rt)
ENDIF(CMAKE_SYSTEM_NAME)
TARGET_LINK_LIBRARIES(${BII_BLOCK_TARGET} INTERFACE curl)
ENABLE_STYLE_WARNINGS()
# You can safely delete lines from here...
###############################################################################
# REFERENCE #
###############################################################################
#
# This CMakeLists.txt file helps defining your block building and compiling
# To learn more about the CMake use with biicode, visit http://docs.biicode.com/c++.html
#
# ----------------------------------------------------
# NEW FEATURE! Include cmake files from remote blocks:
# -----------------------------------------------------
# Now you can handle cmake dependencies alike you do with c/c++:
#
# INCLUDE(user/block/myrecipe) # include myrecipe.cmake from remote user/block
#
# > EXAMPLE: Include our recipes and activate C++11 in your block (http://www.biicode.com/biicode/cmake)
#
# INCLUDE(biicode/cmake/tools) # Include tools.cmake file from "cmake" block from the "biicode" user
# ACTIVATE_CPP11(INTERFACE ${BII_BLOCK_TARGET})
#
# Remember to run "bii find" to download out cmake tools file
#
# ---------------------
# INIT_BIICODE_BLOCK()
# ---------------------
# This function creates several helper variables as ${BII_BLOCK_NAME} and ${BII_BLOCK_USER}
# Also it loads variables from the cmake/bii_user_block_vars.cmake
# ${BII_LIB_SRC} File list to create the library
# ${BII_LIB_TYPE} Empty (default, STATIC most casess) STATIC or SHARED
# ${BII_LIB_DEPS} Dependencies to other libraries (user2_block2, user3_blockX)
# ${BII_LIB_SYSTEM_HEADERS} System linking requirements as windows.h, pthread.h, etc
#
# You can use or modify them here, for example, to add or remove files from targets based on OS
# Or use typical cmake configurations done BEFORE defining targets. Examples:
# ADD_DEFINITIONS(-DFOO)
# FIND_PACKAGE(OpenGL QUIET)
# You can add INCLUDE_DIRECTORIES here too
#
# ---------------------
# ADD_BIICODE_TARGETS()
# ---------------------
#
# This function creates the following variables:
# ${BII_BLOCK_TARGET} Interface (no files) target for convenient configuration of all
# targets in this block, as the rest of targets always depend on it
# has name in the form "user_block_interface"
# ${BII_LIB_TARGET} Target library name, usually in the form "user_block". May not exist
# if BII_LIB_SRC is empty
# ${BII_BLOCK_TARGETS} List of all targets defined in this block
# ${BII_BLOCK_EXES} List of executables targets defined in this block
# ${BII_exe_name_TARGET}: Executable target (e.g. ${BII_main_TARGET}. You can also use
# directly the name of the executable target (e.g. user_block_main)
#
# > EXAMPLE: Add include directories to all targets of this block
#
# TARGET_INCLUDE_DIRECTORIES(${BII_BLOCK_TARGET} INTERFACE myincludedir)
#
# You can add private include directories to the Lib (if existing)
#
# > EXAMPLE: Link with pthread:
#
# TARGET_LINK_LIBRARIES(${BII_BLOCK_TARGET} INTERFACE pthread)
# or link against library:
# TARGET_LINK_LIBRARIES(${BII_LIB_TARGET} PUBLIC pthread)
# or directly use the library target name:
# TARGET_LINK_LIBRARIES(user_block PUBLIC pthread)
#
# NOTE: This can be also done adding pthread to ${BII_LIB_DEPS}
# BEFORE calling ADD_BIICODE_TARGETS()
#
# > EXAMPLE: how to activate C++11
#
# IF(APPLE)
# TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++11 -stdlib=libc++")
# ELSEIF (WIN32 OR UNIX)
# TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE "-std=c++11")
# ENDIF(APPLE)
#
# > EXAMPLE: Set properties to target
#
# SET_TARGET_PROPERTIES(${BII_BLOCK_TARGET} PROPERTIES COMPILE_DEFINITIONS "IOV_MAX=255")
#
add_subdirectory(vendor)
add_subdirectory(src)
add_subdirectory(test)

View File

@ -1,46 +0,0 @@
# Biicode configuration file
[requirements]
cryptopp/cryptopp: 8
google/gmock: 4
google/gtest: 11
messmer/cmake: 3
messmer/scrypt: 1
messmer/spdlog: 1
[parent]
messmer/cpp-utils: 9
[paths]
# Local directories to look for headers (within block)
# /
# include
[dependencies]
# Manual adjust file implicit dependencies, add (+), remove (-), or overwrite (=)
# hello.h + hello_imp.cpp hello_imp2.cpp
# *.h + *.cpp
test/main.cpp + test/*.cpp
[mains]
# Manual adjust of files that define an executable
# !main.cpp # Do not build executable from this file
# main2.cpp # Build it (it doesnt have a main() function, but maybe it includes it)
[hooks]
# These are defined equal to [dependencies],files names matching bii*stage*hook.py
# will be launched as python scripts at stage = {post_process, clean}
# CMakeLists.txt + bii/my_post_process1_hook.py bii_clean_hook.py
[includes]
# Mapping of include patterns to external blocks
# hello*.h: user3/depblock # includes will be processed as user3/depblock/hello*.h
[data]
# Manually define data files dependencies, that will be copied to bin for execution
# By default they are copied to bin/user/block/... which should be taken into account
# when loading from disk such data
# image.cpp + image.jpg # code should write open("user/block/image.jpg")
[tests]
test/*

101
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,101 @@
include(CheckCXXCompilerFlag)
###################################################
# Activate C++14
#
# Uses: ACTIVATE_CPP14()
###################################################
macro(ACTIVATE_CPP14)
CHECK_CXX_COMPILER_FLAG("-std=c++14" COMPILER_HAS_CPP14_SUPPORT)
IF (COMPILER_HAS_CPP14_SUPPORT)
TARGET_COMPILE_OPTIONS(${PROJECT_NAME} PUBLIC -std=c++14)
ELSE()
CHECK_CXX_COMPILER_FLAG("-std=c++1y" COMPILER_HAS_CPP14_PARTIAL_SUPPORT)
IF (COMPILER_HAS_CPP14_PARTIAL_SUPPORT)
TARGET_COMPILE_OPTIONS(${PROJECT_NAME} PUBLIC -std=c++1y)
ELSE()
MESSAGE(FATAL_ERROR "Compiler doesn't support C++14")
ENDIF()
ENDIF()
IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
TARGET_COMPILE_OPTIONS(${PROJECT_NAME} PUBLIC -stdlib=libc++)
ENDIF()
endmacro(ACTIVATE_CPP14)
#################################################
# Enable style compiler warnings
#################################################
macro(ENABLE_STYLE_WARNINGS)
# TARGET_COMPILE_OPTIONS(${BII_BLOCK_TARGET} INTERFACE -Wall -Wextra -Weffc++)
TARGET_COMPILE_OPTIONS(${PROJECT_NAME} PRIVATE -Wall -Wextra)
endmacro(ENABLE_STYLE_WARNINGS)
##################################################
# Add boost to the project
#
# Uses:
# ADD_BOOST() # if you're only using header-only boost libs
# ADD_BOOST(system filesystem) # list all libraries to link against in the dependencies
##################################################
function(ADD_BOOST)
# Load boost libraries
find_package(Boost 1.57.0 #TODO Which min version?
REQUIRED
COMPONENTS ${ARGN})
set(Boost_USE_STATIC_LIBS ON)
target_include_directories(${PROJECT_NAME} SYSTEM PRIVATE ${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${Boost_LIBRARIES})
endfunction()
cmake_minimum_required(VERSION 3.0)
project (cpp-utils)
set(SOURCES
crypto/symmetric/ciphers.cpp
crypto/kdf/DerivedKey.cpp
crypto/kdf/Scrypt.cpp
crypto/kdf/DerivedKeyConfig.cpp
crypto/RandomPadding.cpp
process/daemonize.cpp
process/subprocess.cpp
tempfile/TempFile.cpp
tempfile/TempDir.cpp
network/HttpClient.cpp
network/CurlHttpClient.cpp
network/FakeHttpClient.cpp
io/Console.cpp
io/pipestream.cpp
thread/LoopThread.cpp
thread/ThreadSystem.cpp
random/Random.cpp
random/RandomGeneratorThread.cpp
random/OSRandomGenerator.cpp
random/PseudoRandomPool.cpp
random/RandomDataBuffer.cpp
random/RandomGenerator.cpp
lock/LockPool.cpp
data/Serializer.cpp
data/Deserializer.cpp
data/DataFixture.cpp
data/DataUtils.cpp
data/Data.cpp
assert/backtrace.cpp
assert/AssertFailed.cpp
)
add_library(${PROJECT_NAME} STATIC ${SOURCES})
# This is needed by boost thread
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE rt)
endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
TARGET_LINK_LIBRARIES(${PROJECT_NAME} PRIVATE curl)
# TODO From Crypto++ 5.7 on, it should support cmake with find_package().
find_library(CryptoPP cryptopp)
target_link_libraries(${PROJECT_NAME} PRIVATE ${CryptoPP} scrypt)
ADD_BOOST(filesystem system thread)
ENABLE_STYLE_WARNINGS()
ACTIVATE_CPP14()

View File

@ -5,7 +5,7 @@
#include "../../macros.h" #include "../../macros.h"
#include "../../random/Random.h" #include "../../random/Random.h"
extern "C" { extern "C" {
#include <messmer/scrypt/lib/crypto/crypto_scrypt.h> #include "../../../vendor/scrypt-1.2.0/lib/crypto/crypto_scrypt.h"
} }
#include <stdexcept> #include <stdexcept>
#include "DerivedKey.h" #include "DerivedKey.h"

View File

@ -6,7 +6,7 @@
#include "../../data/Data.h" #include "../../data/Data.h"
#include "../../random/Random.h" #include "../../random/Random.h"
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <cryptopp/cryptopp/modes.h> #include <cryptopp/modes.h>
#include "Cipher.h" #include "Cipher.h"
namespace cpputils { namespace cpputils {

View File

@ -5,7 +5,7 @@
#include "../../data/FixedSizeData.h" #include "../../data/FixedSizeData.h"
#include "../../data/Data.h" #include "../../data/Data.h"
#include "../../random/Random.h" #include "../../random/Random.h"
#include <cryptopp/cryptopp/gcm.h> #include <cryptopp/gcm.h>
#include "Cipher.h" #include "Cipher.h"
namespace cpputils { namespace cpputils {

View File

@ -2,11 +2,11 @@
#ifndef MESSMER_CPPUTILS_CRYPTO_SYMMETRIC_CIPHERS_H_ #ifndef MESSMER_CPPUTILS_CRYPTO_SYMMETRIC_CIPHERS_H_
#define MESSMER_CPPUTILS_CRYPTO_SYMMETRIC_CIPHERS_H_ #define MESSMER_CPPUTILS_CRYPTO_SYMMETRIC_CIPHERS_H_
#include <cryptopp/cryptopp/aes.h> #include <cryptopp/aes.h>
#include <cryptopp/cryptopp/twofish.h> #include <cryptopp/twofish.h>
#include <cryptopp/cryptopp/serpent.h> #include <cryptopp/serpent.h>
#include <cryptopp/cryptopp/cast.h> #include <cryptopp/cast.h>
#include <cryptopp/cryptopp/mars.h> #include <cryptopp/mars.h>
#include "GCM_Cipher.h" #include "GCM_Cipher.h"
#include "CFB_Cipher.h" #include "CFB_Cipher.h"

View File

@ -2,7 +2,7 @@
#ifndef MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_ #ifndef MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
#define MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_ #define MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
#include <cryptopp/cryptopp/hex.h> #include <cryptopp/hex.h>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include "../assert/assert.h" #include "../assert/assert.h"

View File

@ -2,7 +2,7 @@
#ifndef MESSMER_CPPUTILS_LOGGING_LOGGER_H #ifndef MESSMER_CPPUTILS_LOGGING_LOGGER_H
#define MESSMER_CPPUTILS_LOGGING_LOGGER_H #define MESSMER_CPPUTILS_LOGGING_LOGGER_H
#include <messmer/spdlog/include/spdlog/spdlog.h> #include "../../vendor/spdlog/spdlog.h"
#include "../macros.h" #include "../macros.h"
namespace cpputils { namespace cpputils {

View File

@ -3,7 +3,7 @@
#define MESSMER_CPPUTILS_RANDOM_OSRANDOMGENERATOR_H #define MESSMER_CPPUTILS_RANDOM_OSRANDOMGENERATOR_H
#include "RandomGenerator.h" #include "RandomGenerator.h"
#include <cryptopp/cryptopp/osrng.h> #include <cryptopp/osrng.h>
namespace cpputils { namespace cpputils {
class OSRandomGenerator final : public RandomGenerator { class OSRandomGenerator final : public RandomGenerator {

View File

@ -4,7 +4,7 @@
#include "../thread/LoopThread.h" #include "../thread/LoopThread.h"
#include "ThreadsafeRandomDataBuffer.h" #include "ThreadsafeRandomDataBuffer.h"
#include <cryptopp/cryptopp/osrng.h> #include <cryptopp/osrng.h>
namespace cpputils { namespace cpputils {
//TODO Test //TODO Test

60
test/CMakeLists.txt Normal file
View File

@ -0,0 +1,60 @@
project (cpp-utils-test)
set(SOURCES
EitherIncludeTest.cpp
crypto/symmetric/CipherTest.cpp
crypto/symmetric/testutils/FakeAuthenticatedCipher.cpp
crypto/kdf/SCryptTest.cpp
crypto/kdf/DerivedKeyTest.cpp
crypto/kdf/DerivedKeyConfigTest.cpp
MacrosIncludeTest.cpp
pointer/unique_ref_test.cpp
pointer/cast_include_test.cpp
pointer/cast_test.cpp
pointer/unique_ref_boost_optional_gtest_workaround_include_test.cpp
pointer/optional_ownership_ptr_include_test.cpp
pointer/optional_ownership_ptr_test.cpp
pointer/unique_ref_include_test.cpp
process/daemonize_include_test.cpp
process/subprocess_include_test.cpp
tempfile/TempFileTest.cpp
tempfile/TempFileIncludeTest.cpp
tempfile/TempDirIncludeTest.cpp
tempfile/TempDirTest.cpp
network/CurlHttpClientTest.cpp
network/FakeHttpClientTest.cpp
io/ConsoleIncludeTest.cpp
io/ConsoleTest_AskYesNo.cpp
io/ConsoleTest_Print.cpp
io/ConsoleTest_Ask.cpp
random/RandomIncludeTest.cpp
lock/LockPoolIncludeTest.cpp
lock/ConditionBarrierIncludeTest.cpp
lock/MutexPoolLockIncludeTest.cpp
data/FixedSizeDataTest.cpp
data/DataFixtureIncludeTest.cpp
data/DataFixtureTest.cpp
data/DataTest.cpp
data/FixedSizeDataIncludeTest.cpp
data/DataIncludeTest.cpp
logging/LoggingLevelTest.cpp
logging/LoggerTest.cpp
logging/LoggingTest.cpp
logging/LoggerIncludeTest.cpp
logging/LoggingIncludeTest.cpp
EitherTest.cpp
assert/assert_release_test.cpp
assert/backtrace_include_test.cpp
assert/assert_include_test.cpp
assert/assert_debug_test.cpp
)
enable_testing()
include_directories(${PROJECT_NAME} SYSTEM ${gtest_INCLUDE_DIRS}/include SYSTEM ${gmock_INCLUDE_DIRS}/include)
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} gtest gmock gmock_main)
add_test(${PROJECT_NAME} ${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} cpp-utils)
enable_style_warnings()
activate_cpp14()

View File

@ -1,3 +1,3 @@
#include "../either.h" #include "../src/either.h"
//Test that either can be included without needing additional dependencies //Test that either can be included without needing additional dependencies

View File

@ -1,8 +1,8 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include <google/gmock/gmock.h> #include <gmock/gmock.h>
#include <boost/optional/optional_io.hpp> #include <boost/optional/optional_io.hpp>
#include "../either.h" #include "../src/either.h"
#include "../macros.h" #include "../src/macros.h"
#include <sstream> #include <sstream>
//TODO Go through all test cases and think about whether it makes sense to add the same test case but with primitive types. //TODO Go through all test cases and think about whether it makes sense to add the same test case but with primitive types.

View File

@ -1,3 +1,3 @@
#include "../macros.h" #include "../src/macros.h"
// Test that macros.h can be included without needing additional dependencies // Test that macros.h can be included without needing additional dependencies

View File

@ -1,9 +1,9 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include <google/gmock/gmock.h> #include <gmock/gmock.h>
//Include the ASSERT macro for a debug build //Include the ASSERT macro for a debug build
#undef NDEBUG #undef NDEBUG
#include "../../assert/assert.h" #include "../../src/assert/assert.h"
using testing::MatchesRegex; using testing::MatchesRegex;

View File

@ -1,3 +1,3 @@
#include "../../assert/assert.h" #include "../../src/assert/assert.h"
// Test the header can be included without needing additional dependencies // Test the header can be included without needing additional dependencies

View File

@ -1,9 +1,9 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include <google/gmock/gmock.h> #include <gmock/gmock.h>
//Include the ASSERT macro for a release build //Include the ASSERT macro for a release build
#define NDEBUG #define NDEBUG
#include "../../assert/assert.h" #include "../../src/assert/assert.h"
using testing::MatchesRegex; using testing::MatchesRegex;

View File

@ -1,4 +1,4 @@
#include "../../assert/backtrace.h" #include "../../src/assert/backtrace.h"
// Test the header can be included without needing additional dependencies // Test the header can be included without needing additional dependencies

View File

@ -1,6 +1,6 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include "../../../crypto/kdf/DerivedKeyConfig.h" #include "../../../src/crypto/kdf/DerivedKeyConfig.h"
#include "../../../data/DataFixture.h" #include "../../../src/data/DataFixture.h"
#include <sstream> #include <sstream>
using namespace cpputils; using namespace cpputils;

View File

@ -1,6 +1,6 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include "../../../crypto/kdf/DerivedKey.h" #include "../../../src/crypto/kdf/DerivedKey.h"
#include "../../../data/DataFixture.h" #include "../../../src/data/DataFixture.h"
using namespace cpputils; using namespace cpputils;

View File

@ -1,5 +1,5 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include "../../../crypto/kdf/Scrypt.h" #include "../../../src/crypto/kdf/Scrypt.h"
using namespace cpputils; using namespace cpputils;

View File

@ -1,10 +1,10 @@
#include <google/gtest/gtest.h> #include <gtest/gtest.h>
#include "../../../crypto/symmetric/Cipher.h" #include "../../../src/crypto/symmetric/Cipher.h"
#include "../../../crypto/symmetric/ciphers.h" #include "../../../src/crypto/symmetric/ciphers.h"
#include "testutils/FakeAuthenticatedCipher.h" #include "testutils/FakeAuthenticatedCipher.h"
#include "../../../data/DataFixture.h" #include "../../../src/data/DataFixture.h"
#include "../../../data/Data.h" #include "../../../src/data/Data.h"
#include <boost/optional/optional_io.hpp> #include <boost/optional/optional_io.hpp>
using namespace cpputils; using namespace cpputils;

View File

@ -2,10 +2,10 @@
#ifndef MESSMER_CPPUTILS_TEST_CRYPTO_SYMMETRIC_TESTUTILS_FAKEAUTHENTICATEDCIPHER_H_ #ifndef MESSMER_CPPUTILS_TEST_CRYPTO_SYMMETRIC_TESTUTILS_FAKEAUTHENTICATEDCIPHER_H_
#define MESSMER_CPPUTILS_TEST_CRYPTO_SYMMETRIC_TESTUTILS_FAKEAUTHENTICATEDCIPHER_H_ #define MESSMER_CPPUTILS_TEST_CRYPTO_SYMMETRIC_TESTUTILS_FAKEAUTHENTICATEDCIPHER_H_
#include "../../../../crypto/symmetric/Cipher.h" #include "../../../../src/crypto/symmetric/Cipher.h"
#include "../../../../data/FixedSizeData.h" #include "../../../../src/data/FixedSizeData.h"
#include "../../../../data/Data.h" #include "../../../../src/data/Data.h"
#include "../../../../random/RandomGenerator.h" #include "../../../../src/random/RandomGenerator.h"
namespace cpputils { namespace cpputils {

View File

@ -1,3 +1,3 @@
#include "../../data/DataFixture.h" #include "../../src/data/DataFixture.h"
// Test the header can be included without needing additional dependencies // Test the header can be included without needing additional dependencies

View File

@ -1,7 +1,7 @@
#include "google/gtest/gtest.h" #include <gtest/gtest.h>
#include "../../data/Data.h" #include "../../src/data/Data.h"
#include "../../data/DataFixture.h" #include "../../src/data/DataFixture.h"
using ::testing::Test; using ::testing::Test;
using ::testing::WithParamInterface; using ::testing::WithParamInterface;

View File

@ -1,3 +1,3 @@
#include "../../data/Data.h" #include "../../src/data/Data.h"
// Test the header can be included without needing additional dependencies // Test the header can be included without needing additional dependencies

View File

@ -1,8 +1,8 @@
#include "../../data/DataFixture.h" #include "../../src/data/DataFixture.h"
#include "../../data/Data.h" #include "../../src/data/Data.h"
#include "google/gtest/gtest.h" #include <gtest/gtest.h>
#include "../../tempfile/TempFile.h" #include "../../src/tempfile/TempFile.h"
#include <fstream> #include <fstream>

View File

@ -1,3 +1,3 @@
#include "../../data/FixedSizeData.h" #include "../../src/data/FixedSizeData.h"
// Test the header can be included without needing additional dependencies // Test the header can be included without needing additional dependencies

Some files were not shown because too many files have changed in this diff Show More