diff --git a/CMakeLists.txt b/CMakeLists.txt index 7104bdc5f..8e36c44c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ include(GNUInstallDirs) option(MRDOX_BUILD_TESTS "Build tests" ${BUILD_TESTING}) option(MRDOX_BUILD_SHARED "Link shared" OFF) -option(MRDOX_BUILD_DOCS "Configure install target" OFF) +option(MRDOX_BUILD_DOCS "Build documentation" OFF) option(MRDOX_INSTALL "Configure install target" ON) option(MRDOX_PACKAGE "Build install package" ON) option(MRDOX_GENERATE_REFERENCE "Generate reference.xml/reference.adoc" ON) @@ -115,9 +115,9 @@ find_package(fmt REQUIRED CONFIG) file( GLOB_RECURSE LIB_SOURCES CONFIGURE_DEPENDS - lib/*.cpp - lib/*.hpp - lib/*.natvis + src/lib/*.cpp + src/lib/*.hpp + src/lib/*.natvis include/*.hpp include/*.natvis SourceFileNames.cpp) @@ -128,7 +128,7 @@ target_include_directories(mrdox-core "$" "$" PRIVATE - "${PROJECT_SOURCE_DIR}/lib" + "${PROJECT_SOURCE_DIR}/src" "${PROJECT_SOURCE_DIR}/include") target_compile_definitions( mrdox-core @@ -202,8 +202,9 @@ endif () # #------------------------------------------------- -file(GLOB_RECURSE TOOL_SOURCES CONFIGURE_DEPENDS tool/*.cpp tool/*.hpp) +file(GLOB_RECURSE TOOL_SOURCES CONFIGURE_DEPENDS src/tool/*.cpp src/tool/*.hpp) add_executable(mrdox ${TOOL_SOURCES}) +target_compile_definitions(mrdox PRIVATE -DMRDOX_TOOL) target_include_directories(mrdox PUBLIC @@ -211,8 +212,7 @@ target_include_directories(mrdox "$" PRIVATE "${PROJECT_SOURCE_DIR}/include" - "${PROJECT_SOURCE_DIR}/lib" - "${PROJECT_SOURCE_DIR}/tool" + "${PROJECT_SOURCE_DIR}/src" ) target_compile_definitions(mrdox PRIVATE -DMRDOX_TOOL) @@ -225,39 +225,6 @@ if (MRDOX_CLANG) ) endif () - -#------------------------------------------------- -# -# Tests -# -#------------------------------------------------- - -file(GLOB TEST_SOURCES CONFIGURE_DEPENDS - test/*.cpp - test/*.hpp) -add_executable(mrdox-test ${TEST_SOURCES}) - -target_include_directories(mrdox-test - PRIVATE - "${PROJECT_SOURCE_DIR}/include" - "${PROJECT_SOURCE_DIR}/lib" - "${PROJECT_SOURCE_DIR}/test" - "${PROJECT_SOURCE_DIR}/tool" -) - -target_compile_definitions(mrdox PRIVATE -DMRDOX_TOOL) -target_link_libraries(mrdox-test PUBLIC mrdox-core) - -if (MRDOX_CLANG) - target_compile_options( - mrdox-test - PRIVATE - -Wno-covered-switch-default - ) -endif () - -#------------------------------------------------------------------------------- - set_property(GLOBAL PROPERTY USE_FOLDERS ON) #source_group(TREE ${PROJECT_SOURCE_DIR} PREFIX "" FILES CMakeLists.txt) source_group(TREE ${PROJECT_SOURCE_DIR}/include/mrdox PREFIX "include" FILES ${INCLUDES}) @@ -270,8 +237,25 @@ source_group(TREE ${PROJECT_SOURCE_DIR}/source PREFIX "source" FILES ${SOURCES}) #------------------------------------------------- if (MRDOX_BUILD_TESTS) - # if we run tests, we need the addons in the right place. + #------------------------------------------------- + # Unit tests + #------------------------------------------------- + include(CTest) + file(GLOB_RECURSE TEST_SUITE_FILES CONFIGURE_DEPENDS src/test/test_suite/*.cpp src/test/test_suite/*.hpp) + file(GLOB_RECURSE UNIT_TEST_SOURCES CONFIGURE_DEPENDS src/test/unit/*.cpp src/test/unit/*.hpp) + add_executable(mrdox-test ${TEST_SUITE_FILES} ${UNIT_TEST_SOURCES}) + target_include_directories(mrdox-test + PRIVATE + "${PROJECT_SOURCE_DIR}/include" + "${PROJECT_SOURCE_DIR}/src" + ) + target_link_libraries(mrdox-test PUBLIC mrdox-core) + if (MRDOX_CLANG) + target_compile_options(mrdox-test PRIVATE -Wno-covered-switch-default) + endif () + target_compile_definitions(mrdox-test PRIVATE -DMRDOX_TEST_FILES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/test-files") add_custom_command( + # if we run tests, we need the addons in the right place. TARGET mrdox-test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy @@ -280,25 +264,28 @@ if (MRDOX_BUILD_TESTS) BYPRODUCTS ${CMAKE_BINARY_DIR}/addons DEPENDS ${CMAKE_SOURCE_DIR}/addons ) + add_test(NAME mrdox-test COMMAND mrdox-test --action test "${PROJECT_SOURCE_DIR}/test-files/old-tests") - file(GLOB_RECURSE TEST_SOURCES CONFIGURE_DEPENDS source/*.cpp source/*.hpp) - enable_testing() - add_test(NAME mrdox-test COMMAND mrdox-test --action test - "${PROJECT_SOURCE_DIR}/test-files/old-tests" - ) - + #------------------------------------------------- + # Reference documentation + #------------------------------------------------- if (MRDOX_GENERATE_REFERENCE) # test run + file(GLOB_RECURSE REFERENCE_SOURCES CONFIGURE_DEPENDS source/*.cpp source/*.hpp) + set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) include(mrdox.cmake) - mrdox(FORMAT adoc CONFIG docs/mrdox.yml SOURCES ${TEST_SOURCES}) - mrdox(FORMAT xml CONFIG docs/mrdox.yml SOURCES ${TEST_SOURCES}) + mrdox(FORMAT adoc CONFIG docs/mrdox.yml SOURCES ${REFERENCE_SOURCES}) + mrdox(FORMAT xml CONFIG docs/mrdox.yml SOURCES ${REFERENCE_SOURCES}) add_custom_target(reference_adoc ALL DEPENDS reference.adoc) add_custom_target(reference_xml ALL DEPENDS reference.xml) endif() + #------------------------------------------------- + # XML lint + #------------------------------------------------- find_package(LibXml2) if (LibXml2_FOUND) find_package(Java REQUIRED Runtime) @@ -321,9 +308,6 @@ if (MRDOX_BUILD_TESTS) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endif() - add_executable(handlebars-test test/unit/handlebars.cpp) - target_link_libraries(handlebars-test PUBLIC mrdox-core) - target_compile_definitions(handlebars-test PRIVATE -DMRDOX_UNIT_TEST_DIR="${CMAKE_CURRENT_SOURCE_DIR}/test/unit") endif() diff --git a/include/mrdox/Platform.hpp b/include/mrdox/Platform.hpp index 7ebdac14c..139b63ee1 100644 --- a/include/mrdox/Platform.hpp +++ b/include/mrdox/Platform.hpp @@ -78,8 +78,10 @@ namespace mrdox { # endif #endif -#if ! defined(__GNUC__) && defined(_MSC_VER) -#define FMT_CONSTEVAL +#ifndef FMT_CONSTEVAL +# if !defined(__GNUC__) && defined(_MSC_VER) +# define FMT_CONSTEVAL +# endif #endif } // mrdox diff --git a/include/mrdox/Support/Handlebars.hpp b/include/mrdox/Support/Handlebars.hpp index 4f64932c9..d65b8640a 100644 --- a/include/mrdox/Support/Handlebars.hpp +++ b/include/mrdox/Support/Handlebars.hpp @@ -1191,8 +1191,8 @@ isEmpty(dom::Value const& arg); execution. For example, the each iterator creates a single frame which is reused for all child execution. - @param arg The value to test - @return True if the value is empty, false otherwise + @param parent The underlying frame object + @return The overlay object @see https://mustache.github.io/mustache.5.html#Sections */ @@ -1200,27 +1200,24 @@ MRDOX_DECL dom::Object createFrame(dom::Object const& parent); -/** Create child data objects. +/** Create a wrapper for a safe string. - This function can be used by block helpers to create child - data objects. - - The child data object is an overlay frame object implementation - that will first look for a value in the child object and if - not found will look in the parent object. + This string wrapper prevents the string from being escaped + when the template is rendered. - Helpers that modify the data state should create a new frame - object when doing so, to isolate themselves and avoid corrupting - the state of any parents. + When a helper returns a safe string, it will be marked + as safe and will not be escaped when rendered. The + string will be rendered as if converted to a `dom::Value` + and rendered as-is. - Generally, only one frame needs to be created per helper - execution. For example, the each iterator creates a single - frame which is reused for all child execution. + When constructing the string that will be marked as safe, any + external content should be properly escaped using the + `escapeExpression` function to avoid potential security concerns. - @param arg The value to test - @return True if the value is empty, false otherwise + @param str The string to mark as safe + @return The safe string wrapper - @see https://mustache.github.io/mustache.5.html#Sections + @see https://handlebarsjs.com/api-reference/utilities.html#handlebars-safestring-string */ MRDOX_DECL detail::safeStringWrapper diff --git a/lib/-XML/CXXTags.cpp b/src/lib/-XML/CXXTags.cpp similarity index 100% rename from lib/-XML/CXXTags.cpp rename to src/lib/-XML/CXXTags.cpp diff --git a/lib/-XML/CXXTags.hpp b/src/lib/-XML/CXXTags.hpp similarity index 99% rename from lib/-XML/CXXTags.hpp rename to src/lib/-XML/CXXTags.hpp index 376051db4..8a400e524 100644 --- a/lib/-XML/CXXTags.hpp +++ b/src/lib/-XML/CXXTags.hpp @@ -10,8 +10,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_XML_CXXTAGS_HPP -#define MRDOX_TOOL_XML_CXXTAGS_HPP +#ifndef MRDOX_LIB_XML_CXXTAGS_HPP +#define MRDOX_LIB_XML_CXXTAGS_HPP #include "XMLTags.hpp" #include diff --git a/lib/-XML/XMLGenerator.cpp b/src/lib/-XML/XMLGenerator.cpp similarity index 92% rename from lib/-XML/XMLGenerator.cpp rename to src/lib/-XML/XMLGenerator.cpp index a9fb5a1dd..d3646bc44 100644 --- a/lib/-XML/XMLGenerator.cpp +++ b/src/lib/-XML/XMLGenerator.cpp @@ -11,8 +11,8 @@ #include "XMLGenerator.hpp" #include "XMLWriter.hpp" -#include "Support/Radix.hpp" -#include "Support/RawOstream.hpp" +#include "lib/Support/Radix.hpp" +#include "lib/Support/RawOstream.hpp" #include #include diff --git a/lib/-XML/XMLGenerator.hpp b/src/lib/-XML/XMLGenerator.hpp similarity index 93% rename from lib/-XML/XMLGenerator.hpp rename to src/lib/-XML/XMLGenerator.hpp index 61cb74bde..a901ff72b 100644 --- a/lib/-XML/XMLGenerator.hpp +++ b/src/lib/-XML/XMLGenerator.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_XML_XMLGENERATOR_HPP -#define MRDOX_TOOL_XML_XMLGENERATOR_HPP +#ifndef MRDOX_LIB_XML_XMLGENERATOR_HPP +#define MRDOX_LIB_XML_XMLGENERATOR_HPP #include #include diff --git a/lib/-XML/XMLTags.cpp b/src/lib/-XML/XMLTags.cpp similarity index 99% rename from lib/-XML/XMLTags.cpp rename to src/lib/-XML/XMLTags.cpp index e0ab73b3a..1978fc9bf 100644 --- a/lib/-XML/XMLTags.cpp +++ b/src/lib/-XML/XMLTags.cpp @@ -10,7 +10,7 @@ // #include "XMLTags.hpp" -#include "Support/Radix.hpp" +#include "lib/Support/Radix.hpp" #include namespace clang { diff --git a/lib/-XML/XMLTags.hpp b/src/lib/-XML/XMLTags.hpp similarity index 98% rename from lib/-XML/XMLTags.hpp rename to src/lib/-XML/XMLTags.hpp index d4790cf94..4fb23d70c 100644 --- a/lib/-XML/XMLTags.hpp +++ b/src/lib/-XML/XMLTags.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_XML_XMLTAGS_HPP -#define MRDOX_TOOL_XML_XMLTAGS_HPP +#ifndef MRDOX_LIB_XML_XMLTAGS_HPP +#define MRDOX_LIB_XML_XMLTAGS_HPP #include #include diff --git a/lib/-XML/XMLWriter.cpp b/src/lib/-XML/XMLWriter.cpp similarity index 99% rename from lib/-XML/XMLWriter.cpp rename to src/lib/-XML/XMLWriter.cpp index 53f868fd1..01d9bcc6d 100644 --- a/lib/-XML/XMLWriter.cpp +++ b/src/lib/-XML/XMLWriter.cpp @@ -12,10 +12,10 @@ #include "CXXTags.hpp" #include "XMLWriter.hpp" -#include "Lib/ConfigImpl.hpp" -#include "Support/Yaml.hpp" -#include "Support/Radix.hpp" -#include "Support/SafeNames.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Support/Yaml.hpp" +#include "lib/Support/Radix.hpp" +#include "lib/Support/SafeNames.hpp" #include #include #include diff --git a/lib/-XML/XMLWriter.hpp b/src/lib/-XML/XMLWriter.hpp similarity index 96% rename from lib/-XML/XMLWriter.hpp rename to src/lib/-XML/XMLWriter.hpp index 074910f27..3b7e76998 100644 --- a/lib/-XML/XMLWriter.hpp +++ b/src/lib/-XML/XMLWriter.hpp @@ -9,11 +9,11 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_XML_XMLWRITER_HPP -#define MRDOX_TOOL_XML_XMLWRITER_HPP +#ifndef MRDOX_LIB_XML_XMLWRITER_HPP +#define MRDOX_LIB_XML_XMLWRITER_HPP #include "XMLTags.hpp" -#include "Support/YamlFwd.hpp" +#include "lib/Support/YamlFwd.hpp" #include #include #include diff --git a/lib/-adoc/AdocCorpus.cpp b/src/lib/-adoc/AdocCorpus.cpp similarity index 100% rename from lib/-adoc/AdocCorpus.cpp rename to src/lib/-adoc/AdocCorpus.cpp diff --git a/lib/-adoc/AdocCorpus.hpp b/src/lib/-adoc/AdocCorpus.hpp similarity index 90% rename from lib/-adoc/AdocCorpus.hpp rename to src/lib/-adoc/AdocCorpus.hpp index 585e5bf58..048246738 100644 --- a/lib/-adoc/AdocCorpus.hpp +++ b/src/lib/-adoc/AdocCorpus.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_ADOC_ADOCCORPUS_HPP -#define MRDOX_TOOL_ADOC_ADOCCORPUS_HPP +#ifndef MRDOX_LIB_ADOC_ADOCCORPUS_HPP +#define MRDOX_LIB_ADOC_ADOCCORPUS_HPP #include #include diff --git a/lib/-adoc/AdocGenerator.cpp b/src/lib/-adoc/AdocGenerator.cpp similarity index 98% rename from lib/-adoc/AdocGenerator.cpp rename to src/lib/-adoc/AdocGenerator.cpp index b49a74f40..a2837e694 100644 --- a/lib/-adoc/AdocGenerator.cpp +++ b/src/lib/-adoc/AdocGenerator.cpp @@ -14,7 +14,7 @@ #include "Builder.hpp" #include "MultiPageVisitor.hpp" #include "SinglePageVisitor.hpp" -#include "Support/SafeNames.hpp" +#include "lib/Support/SafeNames.hpp" #include #include #include diff --git a/lib/-adoc/AdocGenerator.hpp b/src/lib/-adoc/AdocGenerator.hpp similarity index 92% rename from lib/-adoc/AdocGenerator.hpp rename to src/lib/-adoc/AdocGenerator.hpp index 5bf024251..11ce4bda5 100644 --- a/lib/-adoc/AdocGenerator.hpp +++ b/src/lib/-adoc/AdocGenerator.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_ADOC_ADOCGENERATOR_HPP -#define MRDOX_TOOL_ADOC_ADOCGENERATOR_HPP +#ifndef MRDOX_LIB_ADOC_ADOCGENERATOR_HPP +#define MRDOX_LIB_ADOC_ADOCGENERATOR_HPP #include #include diff --git a/lib/-adoc/Builder.cpp b/src/lib/-adoc/Builder.cpp similarity index 99% rename from lib/-adoc/Builder.cpp rename to src/lib/-adoc/Builder.cpp index 945176a09..648c9deec 100644 --- a/lib/-adoc/Builder.cpp +++ b/src/lib/-adoc/Builder.cpp @@ -9,7 +9,7 @@ // #include "Builder.hpp" -#include "Support/Radix.hpp" +#include "lib/Support/Radix.hpp" #include #include #include diff --git a/lib/-adoc/Builder.hpp b/src/lib/-adoc/Builder.hpp similarity index 97% rename from lib/-adoc/Builder.hpp rename to src/lib/-adoc/Builder.hpp index d8043ff0c..485cdb72b 100644 --- a/lib/-adoc/Builder.hpp +++ b/src/lib/-adoc/Builder.hpp @@ -12,7 +12,7 @@ #define MRDOX_LIB_ADOC_BUILDER_HPP #include "Options.hpp" -#include "Support/Radix.hpp" +#include "lib/Support/Radix.hpp" #include #include #include diff --git a/lib/-adoc/MultiPageVisitor.cpp b/src/lib/-adoc/MultiPageVisitor.cpp similarity index 100% rename from lib/-adoc/MultiPageVisitor.cpp rename to src/lib/-adoc/MultiPageVisitor.cpp diff --git a/lib/-adoc/MultiPageVisitor.hpp b/src/lib/-adoc/MultiPageVisitor.hpp similarity index 100% rename from lib/-adoc/MultiPageVisitor.hpp rename to src/lib/-adoc/MultiPageVisitor.hpp diff --git a/lib/-adoc/Options.cpp b/src/lib/-adoc/Options.cpp similarity index 97% rename from lib/-adoc/Options.cpp rename to src/lib/-adoc/Options.cpp index 5af30fb53..d8737b22d 100644 --- a/lib/-adoc/Options.cpp +++ b/src/lib/-adoc/Options.cpp @@ -10,8 +10,8 @@ // #include "Options.hpp" -#include "Support/Yaml.hpp" -#include "Lib/ConfigImpl.hpp" // VFALCO This is a problem +#include "lib/Support/Yaml.hpp" +#include "lib/Lib/ConfigImpl.hpp" // VFALCO This is a problem #include #include #include diff --git a/lib/-adoc/Options.hpp b/src/lib/-adoc/Options.hpp similarity index 90% rename from lib/-adoc/Options.hpp rename to src/lib/-adoc/Options.hpp index a84614d8d..39cd7c99f 100644 --- a/lib/-adoc/Options.hpp +++ b/src/lib/-adoc/Options.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_ADOC_OPTIONS_HPP -#define MRDOX_TOOL_ADOC_OPTIONS_HPP +#ifndef MRDOX_LIB_ADOC_OPTIONS_HPP +#define MRDOX_LIB_ADOC_OPTIONS_HPP #include #include diff --git a/lib/-adoc/SinglePageVisitor.cpp b/src/lib/-adoc/SinglePageVisitor.cpp similarity index 100% rename from lib/-adoc/SinglePageVisitor.cpp rename to src/lib/-adoc/SinglePageVisitor.cpp diff --git a/lib/-adoc/SinglePageVisitor.hpp b/src/lib/-adoc/SinglePageVisitor.hpp similarity index 100% rename from lib/-adoc/SinglePageVisitor.hpp rename to src/lib/-adoc/SinglePageVisitor.hpp diff --git a/lib/-bitcode/BitcodeGenerator.cpp b/src/lib/-bitcode/BitcodeGenerator.cpp similarity index 97% rename from lib/-bitcode/BitcodeGenerator.cpp rename to src/lib/-bitcode/BitcodeGenerator.cpp index 223883b7f..d0a4f0362 100644 --- a/lib/-bitcode/BitcodeGenerator.cpp +++ b/src/lib/-bitcode/BitcodeGenerator.cpp @@ -10,9 +10,9 @@ // #include "BitcodeGenerator.hpp" -#include "Support/Error.hpp" -#include "Support/SafeNames.hpp" -#include "AST/Bitcode.hpp" +#include "lib/Support/Error.hpp" +#include "lib/Support/SafeNames.hpp" +#include "lib/AST/Bitcode.hpp" #include #include diff --git a/lib/-bitcode/BitcodeGenerator.hpp b/src/lib/-bitcode/BitcodeGenerator.hpp similarity index 92% rename from lib/-bitcode/BitcodeGenerator.hpp rename to src/lib/-bitcode/BitcodeGenerator.hpp index 28b9eb10a..6c6ddfcac 100644 --- a/lib/-bitcode/BitcodeGenerator.hpp +++ b/src/lib/-bitcode/BitcodeGenerator.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_BITCODE_BITCODEGENERATOR_HPP -#define MRDOX_TOOL_BITCODE_BITCODEGENERATOR_HPP +#ifndef MRDOX_LIB_BITCODE_BITCODEGENERATOR_HPP +#define MRDOX_LIB_BITCODE_BITCODEGENERATOR_HPP #include #include diff --git a/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp similarity index 99% rename from lib/AST/ASTVisitor.cpp rename to src/lib/AST/ASTVisitor.cpp index bbb7fd1a5..d6f75415a 100644 --- a/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -14,9 +14,9 @@ #include "ASTVisitorHelpers.hpp" #include "Bitcode.hpp" #include "ParseJavadoc.hpp" -#include "Support/Path.hpp" -#include "Support/Debug.hpp" -#include "Lib/Diagnostics.hpp" +#include "lib/Support/Path.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Lib/Diagnostics.hpp" #include #include #include diff --git a/lib/AST/ASTVisitor.hpp b/src/lib/AST/ASTVisitor.hpp similarity index 84% rename from lib/AST/ASTVisitor.hpp rename to src/lib/AST/ASTVisitor.hpp index 578636636..8207c78ae 100644 --- a/lib/AST/ASTVisitor.hpp +++ b/src/lib/AST/ASTVisitor.hpp @@ -10,11 +10,11 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_ASTVISITOR_HPP -#define MRDOX_TOOL_AST_ASTVISITOR_HPP +#ifndef MRDOX_LIB_AST_ASTVISITOR_HPP +#define MRDOX_LIB_AST_ASTVISITOR_HPP -#include "Lib/ConfigImpl.hpp" -#include "Lib/ExecutionContext.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Lib/ExecutionContext.hpp" #include #include #include diff --git a/lib/AST/ASTVisitorHelpers.hpp b/src/lib/AST/ASTVisitorHelpers.hpp similarity index 99% rename from lib/AST/ASTVisitorHelpers.hpp rename to src/lib/AST/ASTVisitorHelpers.hpp index 7fe9f226f..3a6229ea4 100644 --- a/lib/AST/ASTVisitorHelpers.hpp +++ b/src/lib/AST/ASTVisitorHelpers.hpp @@ -7,8 +7,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_ASTVISITORHELPERS_HPP -#define MRDOX_TOOL_AST_ASTVISITORHELPERS_HPP +#ifndef MRDOX_LIB_AST_ASTVISITORHELPERS_HPP +#define MRDOX_LIB_AST_ASTVISITORHELPERS_HPP #include #include diff --git a/lib/AST/AnyBlock.hpp b/src/lib/AST/AnyBlock.hpp similarity index 99% rename from lib/AST/AnyBlock.hpp rename to src/lib/AST/AnyBlock.hpp index f8488ab54..4d18bdceb 100644 --- a/lib/AST/AnyBlock.hpp +++ b/src/lib/AST/AnyBlock.hpp @@ -10,13 +10,13 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_ANYBLOCK_HPP -#define MRDOX_TOOL_AST_ANYBLOCK_HPP +#ifndef MRDOX_LIB_AST_ANYBLOCK_HPP +#define MRDOX_LIB_AST_ANYBLOCK_HPP #include "BitcodeReader.hpp" #include "DecodeRecord.hpp" -#include "Support/Debug.hpp" -#include "Support/Error.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Error.hpp" namespace clang { namespace mrdox { diff --git a/lib/AST/Bitcode.cpp b/src/lib/AST/Bitcode.cpp similarity index 100% rename from lib/AST/Bitcode.cpp rename to src/lib/AST/Bitcode.cpp diff --git a/lib/AST/Bitcode.hpp b/src/lib/AST/Bitcode.hpp similarity index 97% rename from lib/AST/Bitcode.hpp rename to src/lib/AST/Bitcode.hpp index be31b2561..0d73ea969 100644 --- a/lib/AST/Bitcode.hpp +++ b/src/lib/AST/Bitcode.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_BITCODE_HPP -#define MRDOX_TOOL_AST_BITCODE_HPP +#ifndef MRDOX_LIB_AST_BITCODE_HPP +#define MRDOX_LIB_AST_BITCODE_HPP #include #include diff --git a/lib/AST/BitcodeIDs.hpp b/src/lib/AST/BitcodeIDs.hpp similarity index 98% rename from lib/AST/BitcodeIDs.hpp rename to src/lib/AST/BitcodeIDs.hpp index e7180743b..c1d71b601 100644 --- a/lib/AST/BitcodeIDs.hpp +++ b/src/lib/AST/BitcodeIDs.hpp @@ -10,8 +10,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_BITCODEIDS_HPP -#define MRDOX_TOOL_AST_BITCODEIDS_HPP +#ifndef MRDOX_LIB_AST_BITCODEIDS_HPP +#define MRDOX_LIB_AST_BITCODEIDS_HPP #include #include diff --git a/lib/AST/BitcodeReader.cpp b/src/lib/AST/BitcodeReader.cpp similarity index 99% rename from lib/AST/BitcodeReader.cpp rename to src/lib/AST/BitcodeReader.cpp index b275c0911..6d94c61de 100644 --- a/lib/AST/BitcodeReader.cpp +++ b/src/lib/AST/BitcodeReader.cpp @@ -12,8 +12,8 @@ #include "BitcodeReader.hpp" #include "AnyBlock.hpp" #include "DecodeRecord.hpp" -#include "Support/Debug.hpp" -#include "Support/Error.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Error.hpp" #include namespace clang { diff --git a/lib/AST/BitcodeReader.hpp b/src/lib/AST/BitcodeReader.hpp similarity index 96% rename from lib/AST/BitcodeReader.hpp rename to src/lib/AST/BitcodeReader.hpp index 1a01eea15..3637690fe 100644 --- a/lib/AST/BitcodeReader.hpp +++ b/src/lib/AST/BitcodeReader.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_BITCODEREADER_HPP -#define MRDOX_TOOL_AST_BITCODEREADER_HPP +#ifndef MRDOX_LIB_AST_BITCODEREADER_HPP +#define MRDOX_LIB_AST_BITCODEREADER_HPP // // This file implements a reader for parsing the diff --git a/lib/AST/BitcodeWriter.cpp b/src/lib/AST/BitcodeWriter.cpp similarity index 99% rename from lib/AST/BitcodeWriter.cpp rename to src/lib/AST/BitcodeWriter.cpp index 477eca250..723ee526a 100644 --- a/lib/AST/BitcodeWriter.cpp +++ b/src/lib/AST/BitcodeWriter.cpp @@ -13,7 +13,7 @@ #include "BitcodeWriter.hpp" #include "Bitcode.hpp" #include "ParseJavadoc.hpp" -#include "Support/Debug.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/AST/BitcodeWriter.hpp b/src/lib/AST/BitcodeWriter.hpp similarity index 98% rename from lib/AST/BitcodeWriter.hpp rename to src/lib/AST/BitcodeWriter.hpp index a2f2c4963..219a655d7 100644 --- a/lib/AST/BitcodeWriter.hpp +++ b/src/lib/AST/BitcodeWriter.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_BITCODEWRITER_HPP -#define MRDOX_TOOL_AST_BITCODEWRITER_HPP +#ifndef MRDOX_LIB_AST_BITCODEWRITER_HPP +#define MRDOX_LIB_AST_BITCODEWRITER_HPP // // This file implements a writer for serializing the diff --git a/lib/AST/DecodeRecord.hpp b/src/lib/AST/DecodeRecord.hpp similarity index 98% rename from lib/AST/DecodeRecord.hpp rename to src/lib/AST/DecodeRecord.hpp index 6946b944b..c9445353a 100644 --- a/lib/AST/DecodeRecord.hpp +++ b/src/lib/AST/DecodeRecord.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_DECODERECORD_HPP -#define MRDOX_TOOL_AST_DECODERECORD_HPP +#ifndef MRDOX_LIB_AST_DECODERECORD_HPP +#define MRDOX_LIB_AST_DECODERECORD_HPP #include "BitcodeReader.hpp" diff --git a/lib/AST/ParseJavadoc.cpp b/src/lib/AST/ParseJavadoc.cpp similarity index 100% rename from lib/AST/ParseJavadoc.cpp rename to src/lib/AST/ParseJavadoc.cpp diff --git a/lib/AST/ParseJavadoc.hpp b/src/lib/AST/ParseJavadoc.hpp similarity index 89% rename from lib/AST/ParseJavadoc.hpp rename to src/lib/AST/ParseJavadoc.hpp index 027a71466..30318d0f1 100644 --- a/lib/AST/ParseJavadoc.hpp +++ b/src/lib/AST/ParseJavadoc.hpp @@ -9,10 +9,10 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_AST_PARSEJAVADOC_HPP -#define MRDOX_TOOL_AST_PARSEJAVADOC_HPP +#ifndef MRDOX_LIB_AST_PARSEJAVADOC_HPP +#define MRDOX_LIB_AST_PARSEJAVADOC_HPP -#include "Lib/Diagnostics.hpp" +#include "lib/Lib/Diagnostics.hpp" #include #include #include diff --git a/lib/Lib/AbsoluteCompilationDatabase.cpp b/src/lib/Lib/AbsoluteCompilationDatabase.cpp similarity index 98% rename from lib/Lib/AbsoluteCompilationDatabase.cpp rename to src/lib/Lib/AbsoluteCompilationDatabase.cpp index 31fd3e64a..60c50196d 100644 --- a/lib/Lib/AbsoluteCompilationDatabase.cpp +++ b/src/lib/Lib/AbsoluteCompilationDatabase.cpp @@ -9,10 +9,10 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Debug.hpp" -#include "Support/Path.hpp" -#include "Lib/ConfigImpl.hpp" -#include "Lib/AbsoluteCompilationDatabase.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Path.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Lib/AbsoluteCompilationDatabase.hpp" #include #include #include diff --git a/lib/Lib/AbsoluteCompilationDatabase.hpp b/src/lib/Lib/AbsoluteCompilationDatabase.hpp similarity index 93% rename from lib/Lib/AbsoluteCompilationDatabase.hpp rename to src/lib/Lib/AbsoluteCompilationDatabase.hpp index e17f528c9..f1ef7f284 100644 --- a/lib/Lib/AbsoluteCompilationDatabase.hpp +++ b/src/lib/Lib/AbsoluteCompilationDatabase.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_TOOL_ABSOLUTECOMPILATIONDATABASE_HPP -#define MRDOX_TOOL_TOOL_ABSOLUTECOMPILATIONDATABASE_HPP +#ifndef MRDOX_LIB_TOOL_ABSOLUTECOMPILATIONDATABASE_HPP +#define MRDOX_LIB_TOOL_ABSOLUTECOMPILATIONDATABASE_HPP #include #include diff --git a/lib/Lib/Config.cpp b/src/lib/Lib/Config.cpp similarity index 94% rename from lib/Lib/Config.cpp rename to src/lib/Lib/Config.cpp index 770cab413..cc9c4b940 100644 --- a/lib/Lib/Config.cpp +++ b/src/lib/Lib/Config.cpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Lib/ConfigImpl.hpp" -#include "Support/Path.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Support/Path.hpp" #include #include #include diff --git a/lib/Lib/ConfigImpl.cpp b/src/lib/Lib/ConfigImpl.cpp similarity index 97% rename from lib/Lib/ConfigImpl.cpp rename to src/lib/Lib/ConfigImpl.cpp index c52527a2e..04dbe192c 100644 --- a/lib/Lib/ConfigImpl.cpp +++ b/src/lib/Lib/ConfigImpl.cpp @@ -9,11 +9,11 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Lib/ConfigImpl.hpp" -#include "Support/Debug.hpp" -#include "Support/Error.hpp" -#include "Support/Path.hpp" -#include "Support/Yaml.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Error.hpp" +#include "lib/Support/Path.hpp" +#include "lib/Support/Yaml.hpp" #include #include #include diff --git a/lib/Lib/ConfigImpl.hpp b/src/lib/Lib/ConfigImpl.hpp similarity index 98% rename from lib/Lib/ConfigImpl.hpp rename to src/lib/Lib/ConfigImpl.hpp index bc56de97d..dbac98659 100644 --- a/lib/Lib/ConfigImpl.hpp +++ b/src/lib/Lib/ConfigImpl.hpp @@ -9,10 +9,10 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_CONFIGIMPL_HPP -#define MRDOX_TOOL_CONFIGIMPL_HPP +#ifndef MRDOX_LIB_CONFIGIMPL_HPP +#define MRDOX_LIB_CONFIGIMPL_HPP -#include "Support/YamlFwd.hpp" +#include "lib/Support/YamlFwd.hpp" #include #include #include diff --git a/lib/Lib/Corpus.cpp b/src/lib/Lib/Corpus.cpp similarity index 97% rename from lib/Lib/Corpus.cpp rename to src/lib/Lib/Corpus.cpp index 056bf72c7..7f4e60b64 100644 --- a/lib/Lib/Corpus.cpp +++ b/src/lib/Lib/Corpus.cpp @@ -9,7 +9,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Lib/ConfigImpl.hpp" +#include "lib/Lib/ConfigImpl.hpp" #include #include #include diff --git a/lib/Lib/CorpusImpl.cpp b/src/lib/Lib/CorpusImpl.cpp similarity index 97% rename from lib/Lib/CorpusImpl.cpp rename to src/lib/Lib/CorpusImpl.cpp index 708777c31..b3ae194be 100644 --- a/lib/Lib/CorpusImpl.cpp +++ b/src/lib/Lib/CorpusImpl.cpp @@ -9,11 +9,11 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "AST/Bitcode.hpp" -#include "AST/ASTVisitor.hpp" +#include "lib/AST/Bitcode.hpp" +#include "lib/AST/ASTVisitor.hpp" #include "CorpusImpl.hpp" -#include "Metadata/Reduce.hpp" -#include "Support/Error.hpp" +#include "lib/Metadata/Reduce.hpp" +#include "lib/Support/Error.hpp" #include #include #include diff --git a/lib/Lib/CorpusImpl.hpp b/src/lib/Lib/CorpusImpl.hpp similarity index 93% rename from lib/Lib/CorpusImpl.hpp rename to src/lib/Lib/CorpusImpl.hpp index 6269992b1..70756121f 100644 --- a/lib/Lib/CorpusImpl.hpp +++ b/src/lib/Lib/CorpusImpl.hpp @@ -8,12 +8,12 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_CORPUSIMPL_HPP -#define MRDOX_TOOL_CORPUSIMPL_HPP +#ifndef MRDOX_LIB_CORPUSIMPL_HPP +#define MRDOX_LIB_CORPUSIMPL_HPP -#include "Lib/ConfigImpl.hpp" -#include "Lib/ToolExecutor.hpp" -#include "Support/Debug.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Lib/ToolExecutor.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/Lib/Diagnostics.hpp b/src/lib/Lib/Diagnostics.hpp similarity index 96% rename from lib/Lib/Diagnostics.hpp rename to src/lib/Lib/Diagnostics.hpp index 67cc538ff..ca92f6181 100644 --- a/lib/Lib/Diagnostics.hpp +++ b/src/lib/Lib/Diagnostics.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_TOOL_DIAGNOSTICS_HPP -#define MRDOX_TOOL_TOOL_DIAGNOSTICS_HPP +#ifndef MRDOX_LIB_TOOL_DIAGNOSTICS_HPP +#define MRDOX_LIB_TOOL_DIAGNOSTICS_HPP #include #include diff --git a/lib/Lib/ExecutionContext.cpp b/src/lib/Lib/ExecutionContext.cpp similarity index 100% rename from lib/Lib/ExecutionContext.cpp rename to src/lib/Lib/ExecutionContext.cpp diff --git a/lib/Lib/ExecutionContext.hpp b/src/lib/Lib/ExecutionContext.hpp similarity index 92% rename from lib/Lib/ExecutionContext.hpp rename to src/lib/Lib/ExecutionContext.hpp index 533472848..505836650 100644 --- a/lib/Lib/ExecutionContext.hpp +++ b/src/lib/Lib/ExecutionContext.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_TOOL_EXECUTIONCONTEXT_HPP -#define MRDOX_TOOL_TOOL_EXECUTIONCONTEXT_HPP +#ifndef MRDOX_LIB_TOOL_EXECUTIONCONTEXT_HPP +#define MRDOX_LIB_TOOL_EXECUTIONCONTEXT_HPP #include "Diagnostics.hpp" #include diff --git a/lib/Lib/SingleFileDB.hpp b/src/lib/Lib/SingleFileDB.hpp similarity index 96% rename from lib/Lib/SingleFileDB.hpp rename to src/lib/Lib/SingleFileDB.hpp index 424348a87..cc993577e 100644 --- a/lib/Lib/SingleFileDB.hpp +++ b/src/lib/Lib/SingleFileDB.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SINGLEFILEDB_HPP -#define MRDOX_TOOL_SINGLEFILEDB_HPP +#ifndef MRDOX_LIB_SINGLEFILEDB_HPP +#define MRDOX_LIB_SINGLEFILEDB_HPP #include #include diff --git a/lib/Lib/ToolExecutor.cpp b/src/lib/Lib/ToolExecutor.cpp similarity index 100% rename from lib/Lib/ToolExecutor.cpp rename to src/lib/Lib/ToolExecutor.cpp diff --git a/lib/Lib/ToolExecutor.hpp b/src/lib/Lib/ToolExecutor.hpp similarity index 96% rename from lib/Lib/ToolExecutor.hpp rename to src/lib/Lib/ToolExecutor.hpp index 8e703e4f0..3a03eaeca 100644 --- a/lib/Lib/ToolExecutor.hpp +++ b/src/lib/Lib/ToolExecutor.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_TOOL_TOOLEXECUTOR_HPP -#define MRDOX_TOOL_TOOL_TOOLEXECUTOR_HPP +#ifndef MRDOX_LIB_TOOL_TOOLEXECUTOR_HPP +#define MRDOX_LIB_TOOL_TOOLEXECUTOR_HPP #include "ExecutionContext.hpp" #include diff --git a/lib/Metadata/DomMetadata.cpp b/src/lib/Metadata/DomMetadata.cpp similarity index 99% rename from lib/Metadata/DomMetadata.cpp rename to src/lib/Metadata/DomMetadata.cpp index 654fbb8be..2651e85da 100644 --- a/lib/Metadata/DomMetadata.cpp +++ b/src/lib/Metadata/DomMetadata.cpp @@ -9,7 +9,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Radix.hpp" +#include "lib/Support/Radix.hpp" #include #include #include diff --git a/lib/Metadata/Enum.cpp b/src/lib/Metadata/Enum.cpp similarity index 100% rename from lib/Metadata/Enum.cpp rename to src/lib/Metadata/Enum.cpp diff --git a/lib/Metadata/Function.cpp b/src/lib/Metadata/Function.cpp similarity index 100% rename from lib/Metadata/Function.cpp rename to src/lib/Metadata/Function.cpp diff --git a/lib/Metadata/Info.cpp b/src/lib/Metadata/Info.cpp similarity index 98% rename from lib/Metadata/Info.cpp rename to src/lib/Metadata/Info.cpp index 0adf8010b..07af502d8 100644 --- a/lib/Metadata/Info.cpp +++ b/src/lib/Metadata/Info.cpp @@ -9,7 +9,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Radix.hpp" +#include "lib/Support/Radix.hpp" #include #include #include diff --git a/lib/Metadata/Interface.cpp b/src/lib/Metadata/Interface.cpp similarity index 99% rename from lib/Metadata/Interface.cpp rename to src/lib/Metadata/Interface.cpp index c69d6f06a..85b415018 100644 --- a/lib/Metadata/Interface.cpp +++ b/src/lib/Metadata/Interface.cpp @@ -9,7 +9,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Debug.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/Metadata/Javadoc.cpp b/src/lib/Metadata/Javadoc.cpp similarity index 99% rename from lib/Metadata/Javadoc.cpp rename to src/lib/Metadata/Javadoc.cpp index 612b8a168..44638c402 100644 --- a/lib/Metadata/Javadoc.cpp +++ b/src/lib/Metadata/Javadoc.cpp @@ -10,7 +10,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Debug.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/Metadata/Namespace.cpp b/src/lib/Metadata/Namespace.cpp similarity index 94% rename from lib/Metadata/Namespace.cpp rename to src/lib/Metadata/Namespace.cpp index 72419c975..6120752ee 100644 --- a/lib/Metadata/Namespace.cpp +++ b/src/lib/Metadata/Namespace.cpp @@ -10,7 +10,7 @@ // #include "Reduce.hpp" -#include "Support/Debug.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/Metadata/Overloads.cpp b/src/lib/Metadata/Overloads.cpp similarity index 100% rename from lib/Metadata/Overloads.cpp rename to src/lib/Metadata/Overloads.cpp diff --git a/lib/Metadata/Record.cpp b/src/lib/Metadata/Record.cpp similarity index 100% rename from lib/Metadata/Record.cpp rename to src/lib/Metadata/Record.cpp diff --git a/lib/Metadata/Reduce.cpp b/src/lib/Metadata/Reduce.cpp similarity index 100% rename from lib/Metadata/Reduce.cpp rename to src/lib/Metadata/Reduce.cpp diff --git a/lib/Metadata/Reduce.hpp b/src/lib/Metadata/Reduce.hpp similarity index 97% rename from lib/Metadata/Reduce.hpp rename to src/lib/Metadata/Reduce.hpp index 9c43e21dd..2ce9ec55b 100644 --- a/lib/Metadata/Reduce.hpp +++ b/src/lib/Metadata/Reduce.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_METADATA_REDUCE_HPP -#define MRDOX_TOOL_METADATA_REDUCE_HPP +#ifndef MRDOX_LIB_METADATA_REDUCE_HPP +#define MRDOX_LIB_METADATA_REDUCE_HPP #include #include diff --git a/lib/Metadata/Source.cpp b/src/lib/Metadata/Source.cpp similarity index 100% rename from lib/Metadata/Source.cpp rename to src/lib/Metadata/Source.cpp diff --git a/lib/Metadata/Specifiers.cpp b/src/lib/Metadata/Specifiers.cpp similarity index 100% rename from lib/Metadata/Specifiers.cpp rename to src/lib/Metadata/Specifiers.cpp diff --git a/lib/Metadata/Symbols.cpp b/src/lib/Metadata/Symbols.cpp similarity index 100% rename from lib/Metadata/Symbols.cpp rename to src/lib/Metadata/Symbols.cpp diff --git a/lib/Metadata/Template.cpp b/src/lib/Metadata/Template.cpp similarity index 100% rename from lib/Metadata/Template.cpp rename to src/lib/Metadata/Template.cpp diff --git a/lib/Metadata/Type.cpp b/src/lib/Metadata/Type.cpp similarity index 100% rename from lib/Metadata/Type.cpp rename to src/lib/Metadata/Type.cpp diff --git a/lib/Metadata/Typedef.cpp b/src/lib/Metadata/Typedef.cpp similarity index 100% rename from lib/Metadata/Typedef.cpp rename to src/lib/Metadata/Typedef.cpp diff --git a/lib/Support/Debug.cpp b/src/lib/Support/Debug.cpp similarity index 98% rename from lib/Support/Debug.cpp rename to src/lib/Support/Debug.cpp index 5a69ccb46..4d5b5cb17 100644 --- a/lib/Support/Debug.cpp +++ b/src/lib/Support/Debug.cpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Debug.hpp" -#include "Support/Radix.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Radix.hpp" #include #include #include diff --git a/lib/Support/Debug.hpp b/src/lib/Support/Debug.hpp similarity index 97% rename from lib/Support/Debug.hpp rename to src/lib/Support/Debug.hpp index 90be51c7d..e4cce87ee 100644 --- a/lib/Support/Debug.hpp +++ b/src/lib/Support/Debug.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_DEBUG_HPP -#define MRDOX_TOOL_SUPPORT_DEBUG_HPP +#ifndef MRDOX_LIB_SUPPORT_DEBUG_HPP +#define MRDOX_LIB_SUPPORT_DEBUG_HPP #include #if ! defined(NDEBUG) diff --git a/lib/Support/Dom.cpp b/src/lib/Support/Dom.cpp similarity index 100% rename from lib/Support/Dom.cpp rename to src/lib/Support/Dom.cpp diff --git a/lib/Support/Error.cpp b/src/lib/Support/Error.cpp similarity index 99% rename from lib/Support/Error.cpp rename to src/lib/Support/Error.cpp index a92837e7c..665eff9fc 100644 --- a/lib/Support/Error.cpp +++ b/src/lib/Support/Error.cpp @@ -8,7 +8,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Error.hpp" +#include "lib/Support/Error.hpp" #include #include #include diff --git a/lib/Support/Error.hpp b/src/lib/Support/Error.hpp similarity index 100% rename from lib/Support/Error.hpp rename to src/lib/Support/Error.hpp diff --git a/lib/Support/ExecutorGroup.cpp b/src/lib/Support/ExecutorGroup.cpp similarity index 100% rename from lib/Support/ExecutorGroup.cpp rename to src/lib/Support/ExecutorGroup.cpp diff --git a/lib/Support/Generator.cpp b/src/lib/Support/Generator.cpp similarity index 98% rename from lib/Support/Generator.cpp rename to src/lib/Support/Generator.cpp index 209b51b32..b8162f3d7 100644 --- a/lib/Support/Generator.cpp +++ b/src/lib/Support/Generator.cpp @@ -9,7 +9,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "AST/ParseJavadoc.hpp" +#include "lib/AST/ParseJavadoc.hpp" #include #include #include diff --git a/lib/Support/GeneratorsImpl.cpp b/src/lib/Support/GeneratorsImpl.cpp similarity index 100% rename from lib/Support/GeneratorsImpl.cpp rename to src/lib/Support/GeneratorsImpl.cpp diff --git a/lib/Support/GeneratorsImpl.hpp b/src/lib/Support/GeneratorsImpl.hpp similarity index 93% rename from lib/Support/GeneratorsImpl.hpp rename to src/lib/Support/GeneratorsImpl.hpp index 8d65ee9b4..5410ce98f 100644 --- a/lib/Support/GeneratorsImpl.hpp +++ b/src/lib/Support/GeneratorsImpl.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_GENERATORSIMPL_HPP -#define MRDOX_TOOL_SUPPORT_GENERATORSIMPL_HPP +#ifndef MRDOX_LIB_SUPPORT_GENERATORSIMPL_HPP +#define MRDOX_LIB_SUPPORT_GENERATORSIMPL_HPP #include #include diff --git a/lib/Support/Handlebars.cpp b/src/lib/Support/Handlebars.cpp similarity index 100% rename from lib/Support/Handlebars.cpp rename to src/lib/Support/Handlebars.cpp diff --git a/lib/Support/JavaScript.cpp b/src/lib/Support/JavaScript.cpp similarity index 100% rename from lib/Support/JavaScript.cpp rename to src/lib/Support/JavaScript.cpp diff --git a/lib/Support/Lua.cpp b/src/lib/Support/Lua.cpp similarity index 99% rename from lib/Support/Lua.cpp rename to src/lib/Support/Lua.cpp index bda10da15..cc0e8e8ea 100644 --- a/lib/Support/Lua.cpp +++ b/src/lib/Support/Lua.cpp @@ -11,11 +11,11 @@ #include #include #include -#include "../../lua/src/lua.hpp" +#include "../../../lua/src/lua.hpp" #include #include -#include "Support/LuaHandlebars.hpp" +#include "lib/Support/LuaHandlebars.hpp" namespace clang { namespace mrdox { diff --git a/lib/Support/LuaHandlebars.cpp b/src/lib/Support/LuaHandlebars.cpp similarity index 100% rename from lib/Support/LuaHandlebars.cpp rename to src/lib/Support/LuaHandlebars.cpp diff --git a/lib/Support/LuaHandlebars.hpp b/src/lib/Support/LuaHandlebars.hpp similarity index 100% rename from lib/Support/LuaHandlebars.hpp rename to src/lib/Support/LuaHandlebars.hpp diff --git a/lib/Support/Path.cpp b/src/lib/Support/Path.cpp similarity index 100% rename from lib/Support/Path.cpp rename to src/lib/Support/Path.cpp diff --git a/lib/Support/Path.hpp b/src/lib/Support/Path.hpp similarity index 94% rename from lib/Support/Path.hpp rename to src/lib/Support/Path.hpp index 8ff17bf86..a3c08af0f 100644 --- a/lib/Support/Path.hpp +++ b/src/lib/Support/Path.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_PATH_HPP -#define MRDOX_TOOL_SUPPORT_PATH_HPP +#ifndef MRDOX_LIB_SUPPORT_PATH_HPP +#define MRDOX_LIB_SUPPORT_PATH_HPP #include #include diff --git a/lib/Support/Radix.cpp b/src/lib/Support/Radix.cpp similarity index 99% rename from lib/Support/Radix.cpp rename to src/lib/Support/Radix.cpp index a0d8d5345..b39adfa1a 100644 --- a/lib/Support/Radix.cpp +++ b/src/lib/Support/Radix.cpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Radix.hpp" -#include "Support/Debug.hpp" +#include "lib/Support/Radix.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/Support/Radix.hpp b/src/lib/Support/Radix.hpp similarity index 92% rename from lib/Support/Radix.hpp rename to src/lib/Support/Radix.hpp index 853463d41..4de3f5cf6 100644 --- a/lib/Support/Radix.hpp +++ b/src/lib/Support/Radix.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_RADIX_HPP -#define MRDOX_TOOL_SUPPORT_RADIX_HPP +#ifndef MRDOX_LIB_SUPPORT_RADIX_HPP +#define MRDOX_LIB_SUPPORT_RADIX_HPP #include #include diff --git a/lib/Support/RawOstream.hpp b/src/lib/Support/RawOstream.hpp similarity index 91% rename from lib/Support/RawOstream.hpp rename to src/lib/Support/RawOstream.hpp index c6dc7c1f0..766c62e9b 100644 --- a/lib/Support/RawOstream.hpp +++ b/src/lib/Support/RawOstream.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_RAWOSTREAM_HPP -#define MRDOX_TOOL_SUPPORT_RAWOSTREAM_HPP +#ifndef MRDOX_LIB_SUPPORT_RAWOSTREAM_HPP +#define MRDOX_LIB_SUPPORT_RAWOSTREAM_HPP #include #include diff --git a/lib/Support/SafeNames.cpp b/src/lib/Support/SafeNames.cpp similarity index 98% rename from lib/Support/SafeNames.cpp rename to src/lib/Support/SafeNames.cpp index 67c2337fa..5d67d54fa 100644 --- a/lib/Support/SafeNames.cpp +++ b/src/lib/Support/SafeNames.cpp @@ -8,9 +8,9 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Radix.hpp" -#include "Support/SafeNames.hpp" -#include "Support/Validate.hpp" +#include "lib/Support/Radix.hpp" +#include "lib/Support/SafeNames.hpp" +#include "lib/Support/Validate.hpp" #include #include #include diff --git a/lib/Support/SafeNames.hpp b/src/lib/Support/SafeNames.hpp similarity index 95% rename from lib/Support/SafeNames.hpp rename to src/lib/Support/SafeNames.hpp index 4f0d1629c..6f8be8788 100644 --- a/lib/Support/SafeNames.hpp +++ b/src/lib/Support/SafeNames.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_SAFENAMES_HPP -#define MRDOX_TOOL_SUPPORT_SAFENAMES_HPP +#ifndef MRDOX_LIB_SUPPORT_SAFENAMES_HPP +#define MRDOX_LIB_SUPPORT_SAFENAMES_HPP #include #include diff --git a/lib/Support/ThreadPool.cpp b/src/lib/Support/ThreadPool.cpp similarity index 99% rename from lib/Support/ThreadPool.cpp rename to src/lib/Support/ThreadPool.cpp index 6960fd8ae..4e6b838a0 100644 --- a/lib/Support/ThreadPool.cpp +++ b/src/lib/Support/ThreadPool.cpp @@ -8,7 +8,7 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Debug.hpp" +#include "lib/Support/Debug.hpp" #include #include #include diff --git a/lib/Support/Validate.cpp b/src/lib/Support/Validate.cpp similarity index 100% rename from lib/Support/Validate.cpp rename to src/lib/Support/Validate.cpp diff --git a/lib/Support/Validate.hpp b/src/lib/Support/Validate.hpp similarity index 90% rename from lib/Support/Validate.hpp rename to src/lib/Support/Validate.hpp index d2b60fc09..f562dd050 100644 --- a/lib/Support/Validate.hpp +++ b/src/lib/Support/Validate.hpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_VALIDATE_HPP -#define MRDOX_TOOL_SUPPORT_VALIDATE_HPP +#ifndef MRDOX_LIB_SUPPORT_VALIDATE_HPP +#define MRDOX_LIB_SUPPORT_VALIDATE_HPP #include #include diff --git a/lib/Support/Yaml.cpp b/src/lib/Support/Yaml.cpp similarity index 95% rename from lib/Support/Yaml.cpp rename to src/lib/Support/Yaml.cpp index 7506a401f..3f98fa61b 100644 --- a/lib/Support/Yaml.cpp +++ b/src/lib/Support/Yaml.cpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Error.hpp" -#include "Support/Yaml.hpp" +#include "lib/Support/Error.hpp" +#include "lib/Support/Yaml.hpp" namespace clang { namespace mrdox { diff --git a/lib/Support/Yaml.hpp b/src/lib/Support/Yaml.hpp similarity index 100% rename from lib/Support/Yaml.hpp rename to src/lib/Support/Yaml.hpp diff --git a/lib/Support/YamlFwd.hpp b/src/lib/Support/YamlFwd.hpp similarity index 87% rename from lib/Support/YamlFwd.hpp rename to src/lib/Support/YamlFwd.hpp index fe2537688..73b9748cf 100644 --- a/lib/Support/YamlFwd.hpp +++ b/src/lib/Support/YamlFwd.hpp @@ -9,8 +9,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#ifndef MRDOX_TOOL_SUPPORT_YAMLFWD_HPP -#define MRDOX_TOOL_SUPPORT_YAMLFWD_HPP +#ifndef MRDOX_LIB_SUPPORT_YAMLFWD_HPP +#define MRDOX_LIB_SUPPORT_YAMLFWD_HPP #include diff --git a/lib/clang.natvis b/src/lib/clang.natvis similarity index 100% rename from lib/clang.natvis rename to src/lib/clang.natvis diff --git a/lib/llvm.natvis b/src/lib/llvm.natvis similarity index 100% rename from lib/llvm.natvis rename to src/lib/llvm.natvis diff --git a/lib/lua.cpp b/src/lib/lua.cpp similarity index 100% rename from lib/lua.cpp rename to src/lib/lua.cpp diff --git a/test/TestArgs.cpp b/src/test/test_suite/TestArgs.cpp similarity index 100% rename from test/TestArgs.cpp rename to src/test/test_suite/TestArgs.cpp diff --git a/test/TestArgs.hpp b/src/test/test_suite/TestArgs.hpp similarity index 100% rename from test/TestArgs.hpp rename to src/test/test_suite/TestArgs.hpp diff --git a/test/TestMain.cpp b/src/test/test_suite/TestMain.cpp similarity index 97% rename from test/TestMain.cpp rename to src/test/test_suite/TestMain.cpp index 3186ead6e..df3e42f28 100644 --- a/test/TestMain.cpp +++ b/src/test/test_suite/TestMain.cpp @@ -11,8 +11,8 @@ #include "test_suite.hpp" #include "TestArgs.hpp" #include "TestRunner.hpp" -#include "Support/Debug.hpp" -#include "Support/Error.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Error.hpp" #include #include #include diff --git a/test/TestRunner.cpp b/src/test/test_suite/TestRunner.cpp similarity index 97% rename from test/TestRunner.cpp rename to src/test/test_suite/TestRunner.cpp index 9af72a025..21f246d03 100644 --- a/test/TestRunner.cpp +++ b/src/test/test_suite/TestRunner.cpp @@ -10,13 +10,13 @@ #include "TestRunner.hpp" #include "TestArgs.hpp" -#include "Support/Error.hpp" -#include "Support/Path.hpp" -#include "Lib/AbsoluteCompilationDatabase.hpp" -#include "Lib/ConfigImpl.hpp" -#include "Lib/CorpusImpl.hpp" -#include "Lib/SingleFileDB.hpp" -#include "Lib/ToolExecutor.hpp" +#include "lib/Support/Error.hpp" +#include "lib/Support/Path.hpp" +#include "lib/Lib/AbsoluteCompilationDatabase.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Lib/CorpusImpl.hpp" +#include "lib/Lib/SingleFileDB.hpp" +#include "lib/Lib/ToolExecutor.hpp" #include #include #include diff --git a/test/TestRunner.hpp b/src/test/test_suite/TestRunner.hpp similarity index 98% rename from test/TestRunner.hpp rename to src/test/test_suite/TestRunner.hpp index 5ccf48057..2bdaf3d53 100644 --- a/test/TestRunner.hpp +++ b/src/test/test_suite/TestRunner.hpp @@ -11,7 +11,7 @@ #ifndef MRDOX_TEST_TESTRUNNER_HPP #define MRDOX_TEST_TESTRUNNER_HPP -#include "Lib/ConfigImpl.hpp" +#include "lib/Lib/ConfigImpl.hpp" #include #include #include diff --git a/src/test/test_suite/detail/decomposer.cpp b/src/test/test_suite/detail/decomposer.cpp new file mode 100644 index 000000000..97a11fc86 --- /dev/null +++ b/src/test/test_suite/detail/decomposer.cpp @@ -0,0 +1,36 @@ +// +// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/url +// + +#include "decomposer.hpp" + +#if __has_include() +#include +#endif + +namespace test_suite { +namespace detail { +std::string demangle(const char *mangled) +{ +#if __has_include() + int status; + char *demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status); + std::string result; + if (status == 0) { + result = demangled; + } else { + result = mangled; + } + std::free(demangled); + return result; +#else + return mangled; +#endif +} +} // detail +} // test_suite diff --git a/test/unit/test_macros.hpp b/src/test/test_suite/detail/decomposer.hpp similarity index 54% rename from test/unit/test_macros.hpp rename to src/test/test_suite/detail/decomposer.hpp index 5cefbf1b3..4e5486052 100644 --- a/test/unit/test_macros.hpp +++ b/src/test/test_suite/detail/decomposer.hpp @@ -5,92 +5,103 @@ // https://www.boost.org/LICENSE_1_0.txt // -#ifndef MRDOX_TEST_MACROS_H -#define MRDOX_TEST_MACROS_H +#ifndef MRDOX_TEST_DECOMPOSER_HPP +#define MRDOX_TEST_DECOMPOSER_HPP -#include -#include #include #include #include -#if __has_include() - -#include - +#if defined(__has_include) && __has_include() +#include +#include +#define MRDOX_TEST_HAS_FMT #endif // These are test macros we can use to test our code without having to // integrate a test framework for now. -namespace test::detail { +namespace test_suite::detail +{ template - struct has_ostream_op : std::false_type { - }; + struct has_ostream_op : std::false_type + {}; template struct has_ostream_op() << std::declval())>> - : std::true_type { - }; + : std::true_type + {}; - std::string demangle(const char *mangled) { -#if __has_include() - int status; - char *demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status); - std::string result; - if (status == 0) { - result = demangled; - } else { - result = mangled; - } - std::free(demangled); - return result; -#else - return mangled; -#endif + std::string + demangle(const char *mangled); + + template + std::string + demangle() + { + return demangle(typeid(T).name()); } template - std::string format_value(const T &value) { + std::string + format_value(T const& value) + { std::string out; +#ifdef MRDOX_TEST_HAS_FMT if constexpr (fmt::has_formatter::value) { out += fmt::format("{}", value); - } else if constexpr (has_ostream_op::value) { + } else +#endif + if constexpr (has_ostream_op::value) { std::stringstream ss; ss << value; out += ss.str(); } else { - out += fmt::format("{}", demangle(typeid(T).name())); + out += demangle(); } return out; } template - class binary_operands { + class binary_operands + { bool result_; T lhs_; std::string_view op_; U rhs_; - public: - binary_operands(bool comparisonResult, T lhs, std::string_view op, U rhs) - : result_(comparisonResult), - lhs_(lhs), - op_(op), - rhs_(rhs) {} - [[nodiscard]] bool get_result() const { + public: + binary_operands( + bool result, T lhs, std::string_view op, U rhs) + : result_(result), lhs_(lhs), op_(op), rhs_(rhs) {} + + [[nodiscard]] + bool + get_result() const + { return result_; } - [[nodiscard]] std::string format() const { - return fmt::format("{} {} {}", format_value(lhs_), op_, format_value(rhs_)); + [[nodiscard]] + std::string + format() const + { + std::string out; + out += format_value(lhs_); + out += " "; + out += op_; + out += " "; + out += format_value(rhs_); + return out; } }; - // Wraps the first element in an expression so that other elements are also evaluated as wrappers - // when compared with it + // Wraps the first element in an expression so that other + // elements can also be evaluated as wrappers when compared + // with it template - class first_operand { + class first_operand + { T lhs_; public: @@ -98,55 +109,73 @@ namespace test::detail { template friend - binary_operands operator==(first_operand &&lhs, U &&rhs) { + binary_operands + operator==(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ == rhs ), lhs.lhs_, "==", rhs}; } template friend - binary_operands operator!=(first_operand &&lhs, U &&rhs) { + binary_operands + operator!=(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ != rhs ), lhs.lhs_, "!=", rhs}; } template friend - binary_operands operator<(first_operand &&lhs, U &&rhs) { + binary_operands + operator<(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ < rhs ), lhs.lhs_, "<", rhs}; } template friend - binary_operands operator<=(first_operand &&lhs, U &&rhs) { + binary_operands + operator<=(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ <= rhs ), lhs.lhs_, "<=", rhs}; } template friend - binary_operands operator>(first_operand &&lhs, U &&rhs) { + binary_operands + operator>(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ > rhs ), lhs.lhs_, ">", rhs}; } template friend - binary_operands operator>=(first_operand &&lhs, U &&rhs) { + binary_operands + operator>=(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ >= rhs ), lhs.lhs_, ">=", rhs}; } template friend - binary_operands operator|(first_operand &&lhs, U &&rhs) { + binary_operands + operator|(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ | rhs ), lhs.lhs_, "|", rhs}; } template friend - binary_operands operator&(first_operand &&lhs, U &&rhs) { + binary_operands + operator&(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ & rhs ), lhs.lhs_, "&", rhs}; } template friend - binary_operands operator^(first_operand &&lhs, U &&rhs) { + binary_operands + operator^(first_operand &&lhs, U &&rhs) + { return {static_cast( lhs.lhs_ ^ rhs ), lhs.lhs_, "^", rhs}; } @@ -154,33 +183,47 @@ namespace test::detail { // use two requires instead of && template friend - binary_operands operator&&(first_operand &&lhs, U &&rhs) = delete; + binary_operands + operator&&(first_operand &&lhs, U &&rhs) = delete; // && and || are not supported because of operator precedence // use parenthesis instead of || template friend - binary_operands operator||(first_operand &&lhs, U &&rhs) = delete; + binary_operands + operator||(first_operand &&lhs, U &&rhs) = delete; - [[nodiscard]] std::string format() const { + [[nodiscard]] + std::string + format() const + { return format_value(lhs_); } }; - // Converts the first elements in the expression to an first_operand wrapper + // Converts the first elements in the expression to a first_operand wrapper // first_operand wrapper will then wrap the other elements in the expression // These wrappers allow the application to have access to all elements in an // expression and evaluate them as needed to generate proper error messages - struct decomposer { + struct decomposer + { template - friend auto operator<=(decomposer &&, T &&lhs) -> first_operand { + friend + first_operand + operator<=(decomposer &&, T &&lhs) + { return first_operand{lhs}; } }; } -#define DETAIL_STRINGIFY(...) #__VA_ARGS__ - +/* + * Macros to suppress -Wparentheses warnings + * + * These warnings are suppressed because they are triggered by macros + * including extra parentheses to avoid errors related to operator + * precedence. + */ #if defined(__clang__) # define DETAIL_START_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic push" ) # define DETAIL_STOP_WARNINGS_SUPPRESSION _Pragma( "clang diagnostic pop" ) @@ -197,18 +240,4 @@ namespace test::detail { # define DETAIL_SUPPRESS_PARENTHESES_WARNINGS #endif -#define DETAIL_REQUIRE(macro_name, operation, ...) \ - if (!(operation static_cast(__VA_ARGS__))) { \ - DETAIL_START_WARNINGS_SUPPRESSION \ - DETAIL_SUPPRESS_PARENTHESES_WARNINGS \ - fmt::println("{} failed:\n {} ({})\n file: {}\n line: {}", DETAIL_STRINGIFY(macro_name), DETAIL_STRINGIFY(__VA_ARGS__), (test::detail::decomposer() <= __VA_ARGS__).format(), __FILE__, __LINE__); \ - DETAIL_STOP_WARNINGS_SUPPRESSION \ - return EXIT_FAILURE; \ - } \ - (void) 0 - -#define REQUIRE(...) DETAIL_REQUIRE(REQUIRE, true ==, __VA_ARGS__) - -#define REQUIRE_FALSE(...) DETAIL_REQUIRE(REQUIRE_FALSE, false ==, __VA_ARGS__) - -#endif //MRDOX_TEST_MACROS_H +#endif //MRDOX_TEST_DECOMPOSER_HPP diff --git a/test/unit/diff.hpp b/src/test/test_suite/diff.cpp similarity index 54% rename from test/unit/diff.hpp rename to src/test/test_suite/diff.cpp index 2472ee6bd..00afa3e81 100644 --- a/test/unit/diff.hpp +++ b/src/test/test_suite/diff.cpp @@ -1,64 +1,68 @@ // -// Copyright (c) 2023 alandefreitas (alandefreitas@gmail.com) +// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com) // -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/url // -#ifndef MRDOX_DIFF_H -#define MRDOX_DIFF_H - -#include -#include -#include -#include +#include "diff.hpp" #include #include +#include "test_suite.hpp" -namespace { - struct DiffStringsResult { - std::string diff; - int added{0}; - int removed{0}; - int unchanged{0}; -}; +#if defined(__has_include) && __has_include() +#include +#include +#define MRDOX_TEST_HAS_FMT +#else +#include +#endif -std::string_view -trim_spaces(std::string_view expression) +namespace test_suite { +// Diff two strings and return the result as a string with additional stats +DiffStringsResult +diffStrings(std::string_view str1, std::string_view str2, std::size_t context_size = 3) { - auto pos = expression.find_first_not_of(" \t\r\n"); - if (pos == std::string_view::npos) - return ""; - expression.remove_prefix(pos); - pos = expression.find_last_not_of(" \t\r\n"); - if (pos == std::string_view::npos) - return ""; - expression.remove_suffix(expression.size() - pos - 1); - return expression; -} - -void splitLines(std::string_view text, std::vector &lines) { - size_t pos = 0; - while (pos < text.length()) { - size_t newPos = text.find('\n', pos); - if (newPos == std::string::npos) { - newPos = text.length(); + static constexpr auto splitLines = + [](std::string_view text, std::vector &lines) + { + size_t pos = 0; + while (pos < text.length()) + { + size_t newPos = text.find('\n', pos); + if (newPos == std::string::npos) + { + newPos = text.length(); + } + lines.push_back(text.substr(pos, newPos - pos)); + pos = newPos + 1; } - lines.push_back(text.substr(pos, newPos - pos)); - pos = newPos + 1; - } -} + }; + + static constexpr auto trim_spaces = + [](std::string_view expression) -> std::string_view + + { + auto pos = expression.find_first_not_of(" \t\r\n"); + if (pos == std::string_view::npos) + return ""; + expression.remove_prefix(pos); + pos = expression.find_last_not_of(" \t\r\n"); + if (pos == std::string_view::npos) + return ""; + expression.remove_suffix(expression.size() - pos - 1); + return expression; + }; -// Diff two strings and return the result as a string with additional stats -DiffStringsResult -diffStrings(std::string_view str1, std::string_view str2, std::size_t context_size = 3) { std::vector lines1; splitLines(str1, lines1); std::vector lines2; splitLines(str2, lines2); // Initialize the Longest Common Subsequence (LCS) table - // A Longest Common Subsequence (LCS) is a sequence that appears + // The Longest Common Subsequence (LCS) is a sequence that appears // as a subsequence in two or more given sequences. // In diff, the LCS refers to the longest sequence of lines that are // common between two multiline strings. @@ -78,14 +82,19 @@ diffStrings(std::string_view str1, std::string_view str2, std::size_t context_si // line of lines1 with each line of lines2. // The LCS algorithm populates the table based on the lengths // of the longest common subsequences found so far - for (size_t i = 0; i < lines1.size(); ++i) { - for (size_t j = 0; j < lines2.size(); ++j) { - if (trim_spaces(lines1[i]) == trim_spaces(lines2[j])) { + for (size_t i = 0; i < lines1.size(); ++i) + { + for (size_t j = 0; j < lines2.size(); ++j) + { + if (trim_spaces(lines1[i]) == trim_spaces(lines2[j])) + { // If the lines are equal, it means they contribute to the common subsequence. // In this case, the value in the current cell lcsTable[i + 1][j + 1] is set // to the value in the diagonal cell lcsTable[i][j] incremented by 1 lcsTable[i + 1][j + 1] = lcsTable[i][j] + 1; - } else { + } + else + { // If the lines are not equal, the algorithm takes the maximum value between // the cell on the left (lcsTable[i + 1][j]) and the cell above (lcsTable[i][j + 1]) // and stores it in the current cell lcsTable[i + 1][j + 1]. @@ -98,7 +107,8 @@ diffStrings(std::string_view str1, std::string_view str2, std::size_t context_si // Traceback to find the differences DiffStringsResult result; - struct DiffLineResult { + struct DiffLineResult + { std::string line; bool added{false}; bool removed{false}; @@ -112,16 +122,20 @@ diffStrings(std::string_view str1, std::string_view str2, std::size_t context_si // The algorithm starts in the bottom right corner of the table // Starting from the bottom-right cell of the LCS table, it examines // the adjacent cells to determine the direction of the LCS - while (i > 0 && j > 0) { - if (lines1[i - 1] == lines2[j - 1]) { + while (i > 0 && j > 0) + { + if (lines1[i - 1] == lines2[j - 1]) + { // If the current lines lines1[i-1] and lines2[j-1] are equal, // it means the line is common to both multiline strings. It // is added to diffLines with a space prefix, indicating no change. diffLines.push_back({std::string(lines1[i - 1]), false, false}); --i; --j; - result.unchanged++; - } else if (lcsTable[i][j - 1] >= lcsTable[i - 1][j]) { + result.unmodified++; + } + else if (lcsTable[i][j - 1] >= lcsTable[i - 1][j]) + { // If the value in the cell on the left, lcsTable[i][j-1], is // greater than or equal to the value in the cell above, // lcsTable[i-1][j], it means the line in lines2[j-1] is @@ -130,7 +144,9 @@ diffStrings(std::string_view str1, std::string_view str2, std::size_t context_si diffLines.push_back({std::string(lines2[j - 1]), true, false}); --j; result.added++; - } else { + } + else + { // Otherwise, the line in lines1[i-1] is part of the LCS, and it // is added to diffLines with a "-" prefix to indicate a deletion. diffLines.push_back({std::string(lines1[i - 1]), false, true}); @@ -139,13 +155,15 @@ diffStrings(std::string_view str1, std::string_view str2, std::size_t context_si } } - while (i > 0) { + while (i > 0) + { diffLines.push_back({std::string(lines1[i - 1]), false, true}); --i; result.removed++; } - while (j > 0) { + while (j > 0) + { diffLines.push_back({std::string(lines2[j - 1]), true, false}); --j; result.added++; @@ -156,55 +174,127 @@ diffStrings(std::string_view str1, std::string_view str2, std::size_t context_si // Mark diffLines in context std::vector modifiedIndexes; - for (i = 0; i < diffLines.size(); ++i) { + for (i = 0; i < diffLines.size(); ++i) + { auto& diffLine = diffLines[i]; - if (diffLine.added || diffLine.removed) { + if (diffLine.added || diffLine.removed) + { modifiedIndexes.push_back(i); } } // Mark diffLines in context - for (i = 0; i < modifiedIndexes.size(); ++i) { + for (i = 0; i < modifiedIndexes.size(); ++i) + { auto& diffLine = diffLines[modifiedIndexes[i]]; diffLine.in_context = true; - for (j = 1; j <= context_size; ++j) { - if (modifiedIndexes[i] >= j) { + for (j = 1; j <= context_size; ++j) + { + if (modifiedIndexes[i] >= j) + { diffLines[modifiedIndexes[i] - j].in_context = true; } - if (modifiedIndexes[i] + j < diffLines.size()) { + if (modifiedIndexes[i] + j < diffLines.size()) + { diffLines[modifiedIndexes[i] + j].in_context = true; } } } - // Concatenate diff lines into a single string considering number of unchanged lines in the context + // Concatenate diff lines into a single string considering number + // of unmodified lines in the context std::size_t out_of_context = 0; - for (auto diffLine : diffLines) { - if (!diffLine.in_context) { + for (auto diffLine : diffLines) + { + if (!diffLine.in_context) + { out_of_context++; continue; } - if (out_of_context > 0) { + if (out_of_context > 0) + { +#ifdef MRDOX_TEST_HAS_FMT result.diff += fmt::format(fmt::fg(fmt::color::gray), "... {} unmodified line(s)\n", out_of_context); +#else + result.diff += "... " + std::to_string(out_of_context) + " unmodified line(s)\n"; +#endif out_of_context = 0; } - if (diffLine.added || diffLine.removed) { + if (diffLine.added || diffLine.removed) + { +#ifdef MRDOX_TEST_HAS_FMT result.diff += fmt::format( fmt::fg(diffLine.added ? fmt::color::light_green : fmt::color::orange_red), "{} {}\n", diffLine.added ? '+' : '-', diffLine.line.empty() ? " (empty line)" : diffLine.line); - } else { +#else + result.diff += (diffLine.added ? '+' : '-') + diffLine.line + '\n'; + result.diff += (diffLine.line.empty() ? " (empty line)" : diffLine.line) + '\n'; +#endif + } + else + { +#ifdef MRDOX_TEST_HAS_FMT result.diff += fmt::format("{}\n", diffLine.line); +#else + result.diff += diffLine.line + '\n'; +#endif } } - if (out_of_context > 0) { + if (out_of_context > 0) + { +#ifdef MRDOX_TEST_HAS_FMT result.diff += fmt::format(fmt::fg(fmt::color::gray), "... {} unmodified line(s)", out_of_context); +#else + result.diff += "... " + std::to_string(out_of_context) + " unmodified line(s)"; +#endif } return result; } +void +BOOST_TEST_DIFF( + std::string_view expected_contents, + std::string_view expected_contents_path, + std::string_view rendered_contents, + std::string_view error_output_path) +{ + // Compare template with reference + if (expected_contents.empty()) + { + // Write rendered template to file with ofstream + std::ofstream out((std::string(expected_contents_path))); + BOOST_TEST(out); +#ifdef MRDOX_TEST_HAS_FMT + fmt::println("Parsed template:\n{}", rendered_contents); +#else + std::cout << "Parsed template:\n" << rendered_contents << std::endl; +#endif + out << rendered_contents; + } + else + { + // Compare rendered template with reference + auto success_contents = expected_contents; + DiffStringsResult diff = diffStrings(success_contents, rendered_contents); + if (diff.added > 0 || diff.removed > 0) + { + std::ofstream out((std::string(error_output_path))); + BOOST_TEST(out); + out << rendered_contents; +#ifdef MRDOX_TEST_HAS_FMT + fmt::println("DIFF:\n=====================\n{}\n=====================", diff.diff); +#else + std::cout << "DIFF:\n=====================\n" << diff.diff << "\n=====================" << std::endl; +#endif + BOOST_TEST(diff.added == 0); + BOOST_TEST(diff.removed == 0); + } + BOOST_TEST(rendered_contents.size() == success_contents.size()); + BOOST_TEST(rendered_contents == success_contents); + } } -#endif //MRDOX_DIFF_H +} // test_suite diff --git a/src/test/test_suite/diff.hpp b/src/test/test_suite/diff.hpp new file mode 100644 index 000000000..db2585790 --- /dev/null +++ b/src/test/test_suite/diff.hpp @@ -0,0 +1,72 @@ +// +// Copyright (c) 2023 alandefreitas (alandefreitas@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// + +#ifndef MRDOX_TEST_DIFF_HPP +#define MRDOX_TEST_DIFF_HPP + +#include +#include + +namespace test_suite +{ + +/** Result of a diff between two strings + */ +struct DiffStringsResult +{ + /** The diff between the two strings + * + * The diff is a string that contains the differences between the two + * strings. + * + * New lines are prefixed with '+' and removed lines are prefixed with '-'. + */ + std::string diff; + + /// The number of lines added in the contents + int added{0}; + + /// The number of lines removed in the contents + int removed{0}; + + /// The number of unmodified lines in the contents + int unmodified{0}; +}; + +/** Perform a diff between two strings and check if they are equal + + This function is used to compare the contents of a file with the expected + contents of a file. If they are different, the diff is printed to the + console and the test fails. + + The procedure assumes the expected_contents are never empty. + If the expected_contents is empty, the rendered_contents is always + considered valid, the test passes and the rendered contents are + considered the expected contents, so it's saved to the expected + contents path for the next execution. + + If the expected_contents is not empty, the rendered_contents is + compared to the expected contents with the LCS algorithm. + If the rendered_contents is different from the expected contents, + the difference between the contents is printed to the console and + the test fails. + + @param expected_contents The expected contents of the file + @param expected_contents_path The path to the expected contents file + @param rendered_contents The rendered contents of the file + @param error_output_path The path to the error output file + */ +void +BOOST_TEST_DIFF( + std::string_view expected_contents, + std::string_view expected_contents_path, + std::string_view rendered_contents, + std::string_view error_output_path); + +} + +#endif //MRDOX_TEST_DIFF_HPP diff --git a/test/test_suite.cpp b/src/test/test_suite/test_suite.cpp similarity index 95% rename from test/test_suite.cpp rename to src/test/test_suite/test_suite.cpp index f337c5543..8639173dc 100644 --- a/test/test_suite.cpp +++ b/src/test/test_suite/test_suite.cpp @@ -133,7 +133,7 @@ instance() noexcept std::vector v_; public: - virtual ~suites_impl() = default; + ~suites_impl() override = default; void insert(any_suite const& t) override @@ -318,7 +318,7 @@ operator<<( os.precision()}; os << std::fixed << std::setprecision(1) << - (ms.count() / 1000.0) << "s"; + (static_cast(ms.count()) / 1000.0) << "s"; os.precision(precision); os.width(width); } @@ -339,7 +339,7 @@ class simple_runner : public any_runner { char const* name; clock_type::time_point start; - clock_type::duration elapsed; + clock_type::duration elapsed{}; std::atomic failed; std::atomic total; @@ -377,7 +377,7 @@ class simple_runner : public any_runner v_.reserve(256); } - virtual ~simple_runner() + ~simple_runner() override { log_ << elapsed{clock_type::now() - @@ -459,7 +459,7 @@ test( (void)func; log_ << "#" << id << " " << - filename(file) << "(" << line << ") " + file << "(" << line << ") " "failed: " << expr << //" in " << func << "\n"; @@ -499,7 +499,7 @@ run(std::ostream& out, std::vector args; args.reserve(argc - 1); for(int i = 0; i < argc - 1; ++i) - args.push_back(argv[i + 1]); + args.emplace_back(argv[i + 1]); for(auto const& e : suites::instance()) { std::string s(e->name()); @@ -528,8 +528,8 @@ run(std::ostream& out, //------------------------------------------------ -// Simple main used to produce stand -// alone executables that run unit tests. +// Simple main used to produce standalone +// executables that run unit tests. int unit_test_main(int argc, char const* const* argv) { #if 0 @@ -540,8 +540,8 @@ int unit_test_main(int argc, char const* const* argv) #endif #endif - ::test_suite::debug_stream log(std::cerr); - return ::test_suite::detail::run(log, argc, argv); + ::test_suite::debug_stream dstream(std::cerr); + return ::test_suite::detail::run(dstream, argc, argv); } } // test_suite diff --git a/test/test_suite.hpp b/src/test/test_suite/test_suite.hpp similarity index 61% rename from test/test_suite.hpp rename to src/test/test_suite/test_suite.hpp index 2c6b3cd06..4887e3320 100644 --- a/test/test_suite.hpp +++ b/src/test/test_suite/test_suite.hpp @@ -7,8 +7,8 @@ // Official repository: https://github.com/boostorg/url // -#ifndef BOOST_URL_EXTRA_TEST_SUITE_HPP -#define BOOST_URL_EXTRA_TEST_SUITE_HPP +#ifndef MRDOX_TEST_HPP +#define MRDOX_TEST_HPP #if defined(_MSC_VER) # pragma once @@ -18,6 +18,7 @@ #include #include #include +#include "detail/decomposer.hpp" // This is a derivative work // Copyright 2002-2018 Peter Dimov @@ -141,52 +142,6 @@ struct make_void template using void_t = typename make_void::type; -template -struct is_streamable : std::false_type -{}; - -template -struct is_streamable< - T, void_t() << std::declval()) - > > : std::true_type -{}; - -template -auto -test_output_impl(T const& v) -> - typename std::enable_if< - is_streamable::value, - T const&>::type -{ - return v; -} - -template -auto -test_output_impl(T const&) -> - typename std::enable_if< - ! is_streamable::value, - std::string>::type -{ - return "?"; -} - -// specialize test output for char pointers to avoid printing as cstring -template - const void* test_output_impl(T volatile* v) { return const_cast(v); } -inline const void* test_output_impl(const char* v) { return v; } -inline const void* test_output_impl(const unsigned char* v) { return v; } -inline const void* test_output_impl(const signed char* v) { return v; } -inline const void* test_output_impl(char* v) { return v; } -inline const void* test_output_impl(unsigned char* v) { return v; } -inline const void* test_output_impl(signed char* v) { return v; } -inline const void* test_output_impl(std::nullptr_t) { return nullptr; } - -// print chars as numeric -inline int test_output_impl( signed char const& v ) { return v; } -inline unsigned test_output_impl( unsigned char const& v ) { return v; } - // Whether wchar_t is signed is implementation-defined template struct lwt_long_type {}; template<> struct lwt_long_type { typedef long type; }; @@ -254,130 +209,8 @@ no_throw_failed_impl( char const* file, int line); -struct lw_test_eq -{ - template - bool operator()(const T& t, const U& u) const - { - return t == u; - } -}; - -struct lw_test_ne -{ - - template - bool operator()(const T& t, const U& u) const - { - return t != u; - } -}; - -struct lw_test_lt -{ - template - bool operator()(const T& t, const U& u) const - { - return t < u; - } -}; - -struct lw_test_gt -{ - template - bool operator()(const T& t, const U& u) const - { - return t > u; - } -}; - -struct lw_test_le -{ - template - bool operator()(const T& t, const U& u) const - { - return t <= u; - } -}; - -struct lw_test_ge -{ - template - bool operator()(const T& t, const U& u) const - { - return t >= u; - } -}; - -// lwt_predicate_name - -template char const * lwt_predicate_name( T const& ) -{ - return "~="; -} - -inline char const * lwt_predicate_name( lw_test_eq const& ) -{ - return "=="; -} - -inline char const * lwt_predicate_name( lw_test_ne const& ) -{ - return "!="; -} - -inline char const * lwt_predicate_name( lw_test_lt const& ) -{ - return "<"; -} - -inline char const * lwt_predicate_name( lw_test_le const& ) -{ - return "<="; -} - -inline char const * lwt_predicate_name( lw_test_gt const& ) -{ - return ">"; -} - -inline char const * lwt_predicate_name( lw_test_ge const& ) -{ - return ">="; -} - //------------------------------------------------ -template -bool -test_with_impl( - Pred pred, - char const* expr1, - char const* expr2, - char const* func, - char const* file, - int line, - T const& t, U const& u) -{ - if(pred(t, u)) - { - any_runner::instance().test( - true, "", func, file, line); - return true; - } - std::stringstream ss; - ss << - "\"" << test_output_impl(t) << "\" " << - lwt_predicate_name(pred) << - " \"" << test_output_impl(u) << "\" (" << - expr1 << " " << - lwt_predicate_name(pred) << - " " << expr2 << ")"; - any_runner::instance().test( - false, ss.str().c_str(), func, file, line); - return false; -} - #if defined(__clang__) && defined(__has_warning) # if __has_warning("-Wsign-compare") # pragma clang diagnostic pop @@ -410,46 +243,59 @@ struct log_type */ constexpr detail::log_type log{}; -#define BOOST_TEST(expr) ( \ - ::test_suite::detail::test_impl( \ - (expr) ? true : false, #expr, \ - "@anon", __FILE__, __LINE__ ) ) +#define DETAIL_STRINGIFY(...) #__VA_ARGS__ + +#define BOOST_TEST(...) \ + [&] { \ + if (!(static_cast(__VA_ARGS__))) \ + { \ + DETAIL_START_WARNINGS_SUPPRESSION \ + std::string d = DETAIL_STRINGIFY(__VA_ARGS__); \ + d += " ("; \ + DETAIL_SUPPRESS_PARENTHESES_WARNINGS \ + d += (test_suite::detail::decomposer() <= __VA_ARGS__).format(); \ + DETAIL_STOP_WARNINGS_SUPPRESSION \ + d += ")"; \ + return ::test_suite::detail::test_impl( \ + false, \ + d.data(), \ + "@anon", \ + __FILE__, \ + __LINE__ ); \ + } else { \ + return ::test_suite::detail::test_impl( \ + true, \ + DETAIL_STRINGIFY(__VA_ARGS__), \ + "@anon", \ + __FILE__, \ + __LINE__ ); \ + } \ + }() #define BOOST_ERROR(msg) \ ::test_suite::detail::test_impl( \ false, msg, "@anon", __FILE__, __LINE__ ) -#define BOOST_TEST_WITH(expr1,expr2,predicate) ( \ - ::test_suite::detail::test_with_impl( \ - predicate, #expr1, #expr2, "@anon", \ - __FILE__, __LINE__, expr1, expr2) ) - #define BOOST_TEST_EQ(expr1,expr2) \ - BOOST_TEST_WITH( expr1, expr2, \ - ::test_suite::detail::lw_test_eq() ) + BOOST_TEST( (expr1) == (expr2) ) #define BOOST_TEST_CSTR_EQ(expr1,expr2) \ - BOOST_TEST_EQ( string_view(expr1), string_view(expr2) ) + BOOST_TEST( string_view(expr1) == string_view(expr2) ) #define BOOST_TEST_NE(expr1,expr2) \ - BOOST_TEST_WITH( expr1, expr2, \ - ::test_suite::detail::lw_test_ne() ) + BOOST_TEST( (expr1) != (expr2) ) #define BOOST_TEST_LT(expr1,expr2) \ - BOOST_TEST_WITH( expr1, expr2, \ - ::test_suite::detail::lw_test_lt() ) + BOOST_TEST( (expr1) < (expr2) ) #define BOOST_TEST_LE(expr1,expr2) \ - BOOST_TEST_WITH( expr1, expr2, \ - ::test_suite::detail::lw_test_le() ) + BOOST_TEST( (expr1) <= (expr2) ) #define BOOST_TEST_GT(expr1,expr2) \ - BOOST_TEST_WITH( expr1, expr2, \ - ::test_suite::detail::lw_test_gt() ) + BOOST_TEST( (expr1) > (expr2) ) #define BOOST_TEST_GE(expr1,expr2) \ - BOOST_TEST_WITH( expr1, expr2, \ - ::test_suite::detail::lw_test_ge() ) + BOOST_TEST ( (expr1) >= (expr2) ) #define BOOST_TEST_PASS() BOOST_TEST(true) diff --git a/src/test/unit/Support/Handlebars.cpp b/src/test/unit/Support/Handlebars.cpp new file mode 100644 index 000000000..e73d4c76a --- /dev/null +++ b/src/test/unit/Support/Handlebars.cpp @@ -0,0 +1,661 @@ +// +// Copyright (c) 2023 alandefreitas (alandefreitas@gmail.com) +// +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace clang { +namespace mrdox { + +struct Handlebars_test +{ + +static constexpr +std::string_view +to_string(clang::mrdox::dom::Kind const& value) +{ + switch (value) + { + case clang::mrdox::dom::Kind::Null: + return "null"; + case clang::mrdox::dom::Kind::Boolean: + return "boolean"; + case clang::mrdox::dom::Kind::Integer: + return "integer"; + case clang::mrdox::dom::Kind::String: + return "string"; + case clang::mrdox::dom::Kind::Array: + return "array"; + case clang::mrdox::dom::Kind::Object: + return "object"; + } + return "unknown"; +} + +struct master_fixtures +{ + Handlebars hbs; + dom::Object context; + HandlebarsOptions options; + std::string_view template_path; + std::string template_str; + std::string master_file_contents; + std::vector partial_paths; + std::string_view output_path; + std::string_view error_output_path; + std::string master_logger_output; + std::string_view logger_output_path; + std::string_view logger_error_output_path; + std::string log; +} master; + +void +setup_fixtures() +{ + master.template_path = + MRDOX_TEST_FILES_DIR "/handlebars/features_test.adoc.hbs"; + master.partial_paths = { + MRDOX_TEST_FILES_DIR "/handlebars/record-detail.adoc.hbs", + MRDOX_TEST_FILES_DIR "/handlebars/escaped.adoc.hbs"}; + master.output_path = + MRDOX_TEST_FILES_DIR "/handlebars/features_test.adoc"; + master.error_output_path = + MRDOX_TEST_FILES_DIR "/handlebars/features_test_error.adoc"; + master.logger_output_path = + MRDOX_TEST_FILES_DIR "/handlebars/logger_output.txt"; + master.logger_error_output_path = + MRDOX_TEST_FILES_DIR "/handlebars/logger_output_error.txt"; + + Expected template_text_r = + files::getFileText(master.template_path); + BOOST_TEST(template_text_r); + master.template_str = *template_text_r; + BOOST_TEST_NOT(master.template_str.empty()); + + auto master_file_contents_r = + files::getFileText(master.output_path); + if (master_file_contents_r) + { + master.master_file_contents = *master_file_contents_r; + } + + auto master_logger_output_r = + files::getFileText(master.logger_output_path); + if (master_logger_output_r) + { + master.master_logger_output = *master_logger_output_r; + } + + master.options.noEscape = true; +} + +void +setup_context() +{ + dom::Object page; + page.set("kind", "record"); + page.set("name", "from_chars"); + page.set("decl", "std::from_chars"); + page.set("loc", "charconv"); + dom::Object javadoc; + javadoc.set("brief", "Converts strings to numbers"); + javadoc.set("details", "This function converts strings to numbers"); + page.set("javadoc", javadoc); + page.set("synopsis", "This is the from_chars function"); + dom::Object person; + person.set("firstname", "John"); + person.set("lastname", "Doe"); + page.set("person", person); + dom::Array people = dom::newArray(); + auto first_and_last_names = { + std::make_pair("Alice", "Doe"), + std::make_pair("Bob", "Doe"), + std::make_pair("Carol", "Smith")}; + for (auto [firstname, lastname]: first_and_last_names) + { + person = {}; + person.set("firstname", firstname); + person.set("lastname", lastname); + dom::Array arr = dom::newArray(); + arr.emplace_back(dom::Object{}); + arr.emplace_back(dom::Object{}); + arr.emplace_back(dom::Object{}); + arr.emplace_back(dom::Object{}); + person.set("book", arr); + people.emplace_back(person); + } + page.set("people", people); + page.set("prefix", "Hello"); + page.set("specialChars", "& < > \" ' ` ="); + page.set("url", "https://cppalliance.org/"); + dom::Object page_author; + page_author.set("firstname", "Yehuda"); + page_author.set("lastname", "Katz"); + page.set("author", page_author); + master.context.set("page", page); + dom::Array nav = dom::newArray(); + dom::Object nav1; + nav1.set("url", "foo"); + nav1.set("test", true); + nav1.set("title", "bar"); + nav.emplace_back(nav1); + dom::Object nav2; + nav2.set("url", "bar"); + nav.emplace_back(nav2); + master.context.set("nav", nav); + master.context.set("myVariable", "lookupMyPartial"); + dom::Object myOtherContext; + myOtherContext.set("information", "Interesting!"); + master.context.set("myOtherContext", myOtherContext); + master.context.set("favoriteNumber", 123); + master.context.set("prefix", "Hello"); + master.context.set("title", "My Title"); + master.context.set("body", "My Body"); + dom::Object story; + story.set("intro", "Before the jump"); + story.set("body", "After the jump"); + master.context.set("story", story); + dom::Array comments = dom::newArray(); + dom::Object comment1; + comment1.set("subject", "subject 1"); + comment1.set("body", "body 1"); + comments.emplace_back(comment1); + dom::Object comment2; + comment2.set("subject", "subject 2"); + comment2.set("body", "body 2"); + comments.emplace_back(comment2); + master.context.set("comments", comments); + master.context.set("isActive", true); + master.context.set("isInactive", false); + dom::Object peopleObj; + for (auto [firstname, lastname]: first_and_last_names) + { + person = {}; + person.set("firstname", firstname); + person.set("lastname", lastname); + peopleObj.set(firstname, person); + } + master.context.set("peopleobj", peopleObj); + master.context.set("author", true); + master.context.set("firstname", "Yehuda"); + master.context.set("lastname", "Katz"); + dom::Array names = dom::newArray(); + names.emplace_back("Yehuda Katz"); + names.emplace_back("Alan Johnson"); + names.emplace_back("Charles Jolley"); + master.context.set("names", names); + dom::Object namesobj; + namesobj.set("Yehuda", "Yehuda Katz"); + namesobj.set("Alan", "Alan Johnson"); + namesobj.set("Charles", "Charles Jolley"); + master.context.set("namesobj", namesobj); + dom::Object city; + city.set("name", "San Francisco"); + city.set("summary", "San Francisco is the cultural center of Northern California"); + dom::Object location; + location.set("north", "37.73,"); + location.set("east", "-122.44"); + city.set("location", location); + city.set("population", 883305); + master.context.set("city", city); + + dom::Object lookup_test; + dom::Array people_lookup = dom::newArray(); + people_lookup.emplace_back("Nils"); + people_lookup.emplace_back("Yehuda"); + lookup_test.set("people", people_lookup); + dom::Array cities_lookup = dom::newArray(); + cities_lookup.emplace_back("Darmstadt"); + cities_lookup.emplace_back("San Francisco"); + lookup_test.set("cities", cities_lookup); + master.context.set("lookup_test", lookup_test); + + dom::Object lookup_test2; + dom::Array persons = dom::newArray(); + dom::Object person1; + person1.set("name", "Nils"); + person1.set("resident-in", "darmstadt"); + persons.emplace_back(person1); + dom::Object person2; + person2.set("name", "Yehuda"); + person2.set("resident-in", "san-francisco"); + persons.emplace_back(person2); + lookup_test2.set("persons", persons); + dom::Object cities; + dom::Object darmstadt; + darmstadt.set("name", "Darmstadt"); + darmstadt.set("country", "Germany"); + cities.set("darmstadt", darmstadt); + dom::Object san_francisco; + san_francisco.set("name", "San Francisco"); + san_francisco.set("country", "USA"); + cities.set("san-francisco", san_francisco); + lookup_test2.set("cities", cities); + master.context.set("lookup_test2", lookup_test2); + + dom::Object containers; + dom::Array array; + array.emplace_back("a"); + array.emplace_back("b"); + array.emplace_back("c"); + array.emplace_back("d"); + array.emplace_back("e"); + array.emplace_back("f"); + array.emplace_back("g"); + containers.set("array", array); + + dom::Array array2; + array2.emplace_back("e"); + array2.emplace_back("f"); + array2.emplace_back("g"); + array2.emplace_back("h"); + array2.emplace_back("i"); + array2.emplace_back("j"); + array2.emplace_back("k"); + containers.set("array2", array2); + + dom::Object object; + object.set("a", "a"); + object.set("b", "b"); + object.set("c", "c"); + object.set("d", "d"); + object.set("e", "e"); + object.set("f", "f"); + object.set("g", "g"); + containers.set("object", object); + + dom::Object object2; + object2.set("e", "e"); + object2.set("f", "f"); + object2.set("g", "g"); + object2.set("h", "h"); + object2.set("i", "i"); + object2.set("j", "j"); + object2.set("k", "k"); + containers.set("object2", object2); + + dom::Array object_array; + dom::Object account_x10; + account_x10.set("account_id", "account-x10"); + account_x10.set("product", "Chair"); + object_array.emplace_back(account_x10); + dom::Object account_x11; + account_x11.set("account_id", "account-x10"); + account_x11.set("product", "Bookcase"); + object_array.emplace_back(account_x11); + dom::Object account_x12; + account_x12.set("account_id", "account-x11"); + account_x12.set("product", "Desk"); + object_array.emplace_back(account_x12); + containers.set("object_array", object_array); + + master.context.set("containers", containers); +} + +void +setup_helpers() +{ + helpers::registerAntoraHelpers(master.hbs); + helpers::registerStringHelpers(master.hbs); + helpers::registerContainerHelpers(master.hbs); + + master.hbs.registerHelper("progress", [](dom::Array const& args) + { + if (args.size() < 3) + { + return fmt::format("progress helper requires 3 arguments: {} provided", args.size()); + } + if (!args[0].isString()) + { + return fmt::format("progress helper requires string argument: {} received", args[0]); + } + if (!args[1].isInteger()) + { + return fmt::format("progress helper requires number argument: {} received", args[1]); + } + if (!args[2].isBoolean()) + { + return fmt::format("progress helper requires boolean argument: {} received", args[2]); + } + dom::Value nameV = args[0]; + std::string_view name = nameV.getString(); + std::uint64_t percent = args[1].getInteger(); + bool stalled = args[2].getBool(); + std::uint64_t barWidth = percent / 5; + std::string bar = std::string(20, '*').substr(0, barWidth); + std::string stalledStr = stalled ? "stalled" : ""; + std::string res = bar; + res += ' '; + res += std::to_string(percent); + res += "% "; + res += name; + res += ' '; + res += stalledStr; + return res; + }); + + master.hbs.registerHelper("noop", helpers::noop_fn); + master.hbs.registerHelper("raw", helpers::noop_fn); + + master.hbs.registerHelper("link", []( + dom::Array const& args, HandlebarsCallback const& cb) -> std::string { + if (args.empty()) + { + return "no arguments provided to link helper"; + } + for (std::size_t i = 1; i < args.size(); ++i) + { + if (!args[i].isString()) + { + return fmt::format("link helper requires string arguments: {} provided", args.size()); + } + } + + std::string out; + auto h = cb.hashes().find("href"); + if (h.isString()) + { + out += h.getString(); + } + else if (args.size() > 1) + { + if (!args[1].isString()) + { + return fmt::format("link helper requires string argument: {} provided", to_string(args[1].kind())); + } + auto href = args[1]; + out += href.getString(); + } + else + { + out += "#"; + } + + out += '['; + out += args[0].getString(); + // more attributes from hashes + for (auto const& [key, value] : cb.hashes()) + { + if (key == "href" || !value.isString()) + { + continue; + } + out += ','; + out += key; + out += '='; + out += value.getString(); + } + out += ']'; + + return out; + }); + + master.hbs.registerHelper("loud", []( + dom::Array const& args, + HandlebarsCallback const& cb) -> std::string + { + std::string res; + if (cb.isBlock()) + { + res = cb.fn(); + } + else + { + if (args.empty()) + { + return "loud helper requires at least one argument"; + } + if (!args[0].isString()) + { + return fmt::format("loud helper requires string argument: {} provided", to_string(args[0].kind())); + } + res = args[0].getString(); + } + for (char& c : res) + { + if (c >= 'a' && c <= 'z') + c += 'A' - 'a'; + } + return res; + }); + + master.hbs.registerHelper("to_string", []( + dom::Array const& args) -> std::string { + if (args.empty()) + { + return "to_string helper requires at least one argument"; + } + dom::Value arg = args[0]; + return JSON_stringify(arg); + }); + + master.hbs.registerHelper("bold", []( + dom::Array const& /* args */, + HandlebarsCallback const& cb) { + return fmt::format(R"(
{}
)", cb.fn()); + }); + + master.hbs.registerHelper("list", []( + dom::Array const& args, + HandlebarsCallback const& cb) { + // Built-in helper to change the context for each object in args + if (args.size() != 1) + { + return fmt::format("list helper requires 1 argument: {} provided", args.size()); + } + if (!args[0].isArray()) + { + return fmt::format("list helper requires array argument: {} provided", to_string(args[0].kind())); + } + + dom::Object data = createFrame(cb.data()); + dom::Value itemsV = args[0]; + dom::Array const& items = itemsV.getArray(); + if (!items.empty()) + { + std::string out = "(i)); + data.set("first", i == 0); + data.set("last", i == items.size() - 1); + data.set("index", static_cast(i)); + out += "
  • " + cb.fn(item, data, {}) + "
  • "; + } + return out + ""; + } + return cb.inverse(); + }); + + master.hbs.registerHelper("isdefined", + [](dom::Array const& args) -> dom::Value + { + if (args.empty()) + { + return "isdefined helper requires at least one argument"; + } + // This is an example from the handlebars.js documentation + // There's no distinction between null and undefined in mrdox::dom + return !args[0].isNull(); + }); + + master.hbs.registerHelper("helperMissing", + [](dom::Array const& args, HandlebarsCallback const& cb) + { + std::string out; + OutputRef os(out); + os << "Missing: "; + os << cb.name(); + os << "("; + for (std::size_t i = 0; i < args.size(); ++i) { + if (i != 0) { + os << ", "; + } + os << args[i]; + } + os << ")"; + return out; + }); + + master.hbs.registerHelper("blockHelperMissing", + [](dom::Array const& args, HandlebarsCallback const& cb) + { + std::string out; + OutputRef os(out); + os << "Helper '"; + os << cb.name(); + os << "' not found. Printing block: "; + os << cb.fn(); + return out; + }); +} + +void +setup_logger() +{ + master.hbs.registerLogger( + [this](dom::Value level, dom::Array const& args) + { + master.log += fmt::format("[{}] ", level); + for (std::size_t i = 0; i < args.size(); ++i) { + if (i != 0) { + master.log += ", "; + } + master.log += args[i].getString(); + } + master.log += '\n'; + }); +} + +void +setup_partials() +{ + // From files + for (auto partial_path: master.partial_paths) + { + auto partial_text_r = files::getFileText(partial_path); + BOOST_TEST(partial_text_r); + std::string_view filename = files::getFileName(partial_path); + auto pos = filename.find('.'); + if (pos != std::string_view::npos) + { + filename = filename.substr(0, pos); + } + master.hbs.registerPartial(filename, *partial_text_r); + } + + // Dynamic partial helpers + master.hbs.registerHelper("whichPartial", []() { + return "dynamicPartial"; + }); + + // Literal partials + master.hbs.registerPartial("dynamicPartial", "Dynamo!"); + master.hbs.registerPartial("lookupMyPartial", "Found!"); + master.hbs.registerPartial("myPartialContext", "{{information}}"); + master.hbs.registerPartial("myPartialParam", "The result is {{parameter}}"); + master.hbs.registerPartial("myPartialParam2", "{{prefix}}, {{firstname}} {{lastname}}"); + master.hbs.registerPartial("layoutTemplate", "Site Content {{> @partial-block }}"); + master.hbs.registerPartial("pageLayout", "
    \n {{> nav}}\n
    \n
    \n {{> content}}\n
    "); +} + +void +master_test() +{ + setup_fixtures(); + setup_context(); + setup_helpers(); + setup_logger(); + setup_partials(); + + std::string rendered_text = master.hbs.render( + master.template_str, + master.context, + master.options); + BOOST_TEST_NOT(rendered_text.empty()); + + test_suite::BOOST_TEST_DIFF( + master.master_file_contents, + master.output_path, + rendered_text, + master.error_output_path); + + test_suite::BOOST_TEST_DIFF( + master.master_logger_output, + master.logger_output_path, + master.log, + master.logger_error_output_path); +} + +void +safe_string() +{ + Handlebars hbs; + hbs.registerHelper("bold", [](dom::Array const& args) -> dom::Value + { + if (args.empty() || !args[0].isString()) { + return "bold helper requires at least one argument"; + } + std::string_view text = args[0].getString().get(); + return fmt::format("{}", text); + }); + std::string templ = "{{bold 'text'}}"; + std::string res = hbs.render(templ, {}); + BOOST_TEST_NOT(res == "text"); + BOOST_TEST(res == "<b>text</b>"); + + HandlebarsOptions options; + options.noEscape = true; + res = hbs.render(templ, {}, options); + BOOST_TEST(res == "text"); + BOOST_TEST_NOT(res == "<b>text</b>"); + + hbs.registerHelper("bold", [](dom::Array const& args) { + if (args.empty() || !args[0].isString()) { + return safeString("bold helper requires at least one argument"); + } + std::string_view text = args[0].getString().get(); + return safeString(fmt::format("{}", text)); + }); + res = hbs.render(templ, {}); + BOOST_TEST(res == "text"); + BOOST_TEST_NOT(res == "<b>text</b>"); +} + +void run() +{ + master_test(); + safe_string(); +} + +}; + +TEST_SUITE( + Handlebars_test, + "clang.mrdox.Handlebars"); + +} // mrdox +} // clang + diff --git a/test/Support/Path.cpp b/src/test/unit/Support/Path.cpp similarity index 91% rename from test/Support/Path.cpp rename to src/test/unit/Support/Path.cpp index 889266819..ddddcfeb3 100644 --- a/test/Support/Path.cpp +++ b/src/test/unit/Support/Path.cpp @@ -8,8 +8,8 @@ // Official repository: https://github.com/cppalliance/mrdox // -#include "Support/Path.hpp" -#include "test_suite.hpp" +#include "lib/Support/Path.hpp" +#include namespace clang { namespace mrdox { diff --git a/tool/Addons.cpp b/src/tool/Addons.cpp similarity index 100% rename from tool/Addons.cpp rename to src/tool/Addons.cpp diff --git a/tool/Addons.hpp b/src/tool/Addons.hpp similarity index 100% rename from tool/Addons.hpp rename to src/tool/Addons.hpp diff --git a/tool/GenerateAction.cpp b/src/tool/GenerateAction.cpp similarity index 95% rename from tool/GenerateAction.cpp rename to src/tool/GenerateAction.cpp index b28c65bef..0a56fa658 100644 --- a/tool/GenerateAction.cpp +++ b/src/tool/GenerateAction.cpp @@ -10,10 +10,10 @@ // #include "ToolArgs.hpp" -#include "Lib/AbsoluteCompilationDatabase.hpp" -#include "Lib/ConfigImpl.hpp" -#include "Lib/CorpusImpl.hpp" -#include "Lib/ToolExecutor.hpp" +#include "lib/Lib/AbsoluteCompilationDatabase.hpp" +#include "lib/Lib/ConfigImpl.hpp" +#include "lib/Lib/CorpusImpl.hpp" +#include "lib/Lib/ToolExecutor.hpp" #include #include #include diff --git a/tool/ToolArgs.cpp b/src/tool/ToolArgs.cpp similarity index 100% rename from tool/ToolArgs.cpp rename to src/tool/ToolArgs.cpp diff --git a/tool/ToolArgs.hpp b/src/tool/ToolArgs.hpp similarity index 100% rename from tool/ToolArgs.hpp rename to src/tool/ToolArgs.hpp diff --git a/tool/ToolMain.cpp b/src/tool/ToolMain.cpp similarity index 97% rename from tool/ToolMain.cpp rename to src/tool/ToolMain.cpp index 718ba6135..809ef971b 100644 --- a/tool/ToolMain.cpp +++ b/src/tool/ToolMain.cpp @@ -11,8 +11,8 @@ #include "Addons.hpp" #include "ToolArgs.hpp" -#include "Support/Debug.hpp" -#include "Support/Error.hpp" +#include "lib/Support/Debug.hpp" +#include "lib/Support/Error.hpp" #include #include #include diff --git a/test/unit/fixtures/escaped.adoc.hbs b/test-files/handlebars/escaped.adoc.hbs similarity index 100% rename from test/unit/fixtures/escaped.adoc.hbs rename to test-files/handlebars/escaped.adoc.hbs diff --git a/test/unit/fixtures/handlebars_features_test.adoc.hbs b/test-files/handlebars/features_test.adoc.hbs similarity index 100% rename from test/unit/fixtures/handlebars_features_test.adoc.hbs rename to test-files/handlebars/features_test.adoc.hbs diff --git a/test/unit/fixtures/logger_output.txt b/test-files/handlebars/logger_output.txt similarity index 100% rename from test/unit/fixtures/logger_output.txt rename to test-files/handlebars/logger_output.txt diff --git a/test/unit/fixtures/record-detail.adoc.hbs b/test-files/handlebars/record-detail.adoc.hbs similarity index 100% rename from test/unit/fixtures/record-detail.adoc.hbs rename to test-files/handlebars/record-detail.adoc.hbs diff --git a/test/unit/fixtures/handlebars_features_test.adoc b/test/unit/fixtures/handlebars_features_test.adoc deleted file mode 100644 index 80e27ecac..000000000 --- a/test/unit/fixtures/handlebars_features_test.adoc +++ /dev/null @@ -1,840 +0,0 @@ -== from_chars - - - -=== Synopsis - -[,cpp] ----- -std::from_chars ----- - - -Declared in file - - -This is the from_chars function - - - - - - - -// Record detail partial -[,cpp] ----- -struct from_chars -{ -}; ----- - - -// #with to change context -Person: John Doe in page about `from_chars` - - -// #each to iterate, change context, and access parent context -People: -* Person: Alice Doe in page about `from_chars` -* Person: Bob Doe in page about `from_chars` -* Person: Carol Smith in page about `from_chars` - - -== Expressions - -// Render complete context with "." as key -[object Object] - -// Use to_string -{"page":{"kind":"record","name":"from_chars","decl":"std::from_chars","loc":"charconv","javadoc":{"brief":"Converts strings to numbers","details":"This function converts strings to numbers"},"synopsis":"This is the from_chars function","person":{"firstname":"John","lastname":"Doe"},"people":[{"firstname":"Alice","lastname":"Doe","book":[{},{},{},{}]},{"firstname":"Bob","lastname":"Doe","book":[{},{},{},{}]},{"firstname":"Carol","lastname":"Smith","book":[{},{},{},{}]}],"prefix":"Hello","specialChars":"& < > " ' ` =","url":"https://cppalliance.org/","author":{"firstname":"Yehuda","lastname":"Katz"}},"nav":[{"url":"foo","test":true,"title":"bar"},{"url":"bar"}],"myVariable":"lookupMyPartial","myOtherContext":{"information":"Interesting!"},"favoriteNumber":123,"prefix":"Hello","title":"My Title","body":"My Body","story":{"intro":"Before the jump","body":"After the jump"},"comments":[{"subject":"subject 1","body":"body 1"},{"subject":"subject 2","body":"body 2"}],"isActive":true,"isInactive":false,"peopleobj":{"Alice":{"firstname":"Alice","lastname":"Doe"},"Bob":{"firstname":"Bob","lastname":"Doe"},"Carol":{"firstname":"Carol","lastname":"Smith"}},"author":true,"firstname":"Yehuda","lastname":"Katz","names":["Yehuda Katz","Alan Johnson","Charles Jolley"],"namesobj":{"Yehuda":"Yehuda Katz","Alan":"Alan Johnson","Charles":"Charles Jolley"},"city":{"name":"San Francisco","summary":"San Francisco is the cultural center of Northern California","location":{"north":"37.73,","east":"-122.44"},"population":883305},"lookup_test":{"people":["Nils","Yehuda"],"cities":["Darmstadt","San Francisco"]},"lookup_test2":{"persons":[{"name":"Nils","resident-in":"darmstadt"},{"name":"Yehuda","resident-in":"san-francisco"}],"cities":{"darmstadt":{"name":"Darmstadt","country":"Germany"},"san-francisco":{"name":"San Francisco","country":"USA"}}},"containers":{"array":["a","b","c","d","e","f","g"],"array2":["e","f","g","h","i","j","k"],"object":{"a":"a","b":"b","c":"c","d":"d","e":"e","f":"f","g":"g"},"object2":{"e":"e","f":"f","g":"g","h":"h","i":"i","j":"j","k":"k"},"object_array":[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}]},"symbol":{"tag":"struct","kind":"record","name":"T"}} - -// Literals -true = true -false = false -null = null -undefined = null -./[true] = true -./[false] = false -./[null] = null -./[undefined] = null -'See Website' = See Website -"See Website" = See Website - -// Arrays -Second person is Bob Doe -Second person is Bob Doe - -// Dot segments -Second person is Bob Doe - -// Special characters (disabled for adoc) -raw: & < > " ' ` = -html-escaped: & < > " ' ` = - -// Helpers -JOHN DOE -https://cppalliance.org/[See Website] - -// Helpers with literal values -[source] ----- -** 10% Search -****************** 90% Upload stalled -******************** 100% Finish ----- - -// Undefined helper -Missing: undefinedhelper("Doe") - -// Helpers with hashes -https://chat.asciidoc.org[*project chat*^,role=green] - -// Subexpressions -****************** 90% Upload stalled -****************** 90% Upload stalled - -// Whitespace control -barEmpty - - -// Inline escapes -escaped -true - -// Raw blocks -{{escaped}} - - -// Raw blocks -{{bar}} - - -// Raw block helper -{{BAR}} - - - -== Partials - -// Basic partials -[,cpp] ----- -struct from_chars -{ -}; ----- - -[,cpp] ----- -struct from_chars -{ -}; ----- - - -// Dynamic partials -Dynamo! -Found! - -// Partial context switch -Interesting! - -// Partial parameters -The result is 123 - - Hello, Alice Doe. - Hello, Bob Doe. - Hello, Carol Smith. - - -// Partial blocks - Failover content - - -// Pass templates to partials -Site Content My Content - - -// Inline partials - My Content - My Content - My Content - - -// Block inline partials - -
    - My Content -
    - -== Blocks - -// Block noop -
    -

    My Title

    -
    - My Body -
    -
    - -// Block function -
    -

    My Title

    -
    -
    My Body
    -
    -
    - -// Block helper parameter -
    -

    My Title

    -
    Before the jump
    -
    After the jump
    - -
    - -// Simple iterators -
    -

    My Title

    -
    Before the jump
    -
    After the jump
    - -
    -
    -
    -

    subject 1

    - body 1 -
    -
    -

    subject 2

    - body 2 -
    - -
    - -// Custom list helper - - -// Conditionals - Active - - - Active - - - - Inactive - - -// Chained blocks -// 1 - HIT Active 1 - - -// 2 - HIT Active 2 - - -// 3 - - HIT No User - - -// Block hash arguments - - -// Private variables -
    • 0. foo -
    • 1. bar -
    - -// Iterate objects - Id: 0, Key: Alice, Name: Alice Doe - Id: 1, Key: Bob, Name: Bob Doe - Id: 2, Key: Carol, Name: Carol Smith - - -// Block parameters - Id: 0 Name: Alice - Id: 1 Name: Bob - Id: 2 Name: Carol - - -// Recursive block parameters - User Id: 0 Book Id: 0 - User Id: 0 Book Id: 1 - User Id: 0 Book Id: 2 - User Id: 0 Book Id: 3 - - User Id: 1 Book Id: 0 - User Id: 1 Book Id: 1 - User Id: 1 Book Id: 2 - User Id: 1 Book Id: 3 - - User Id: 2 Book Id: 0 - User Id: 2 Book Id: 1 - User Id: 2 Book Id: 2 - User Id: 2 Book Id: 3 - - - -== Built-in Helpers - -// Author -

    Yehuda Katz

    - - -// Unknown -
    - -

    Unknown Author

    - -
    - -// Include zero -

    Does render

    - - - -

    Does render

    - - -// Custom -author defined -value2 undefined - -// unless -
    -

    WARNING: This entry does not have a license!

    - -
    - -// each with non objects -
      -
    • Yehuda Katz
    • -
    • Alan Johnson
    • -
    • Charles Jolley
    • - -
    - -// No paragraphs - -

    No paragraphs

    - - -// indexes and keys - 0: Yehuda Katz 1: Alan Johnson 2: Charles Jolley - Yehuda: Yehuda Katz Alan: Alan Johnson Charles: Charles Jolley - -// with -Yehuda Katz - - -// with block parameters - San Francisco: 37.73, -122.44 - - - -// with inverse - -No city found - - -// lookup - -Nils lives in Darmstadt -Yehuda lives in San Francisco - - -// lookup2 - Nils lives in Darmstadt (Germany) - - Yehuda lives in San Francisco (USA) - - - -// log (there should be no rendered output) - - - - - - - - -== Hooks - -// Helper missing -Missing: foo() -Missing: foo(true) -Missing: foo(2, true) -Missing: foo(true) -Helper 'foo' not found. Printing block: block content - -// Block helper missing -Helper 'person' not found. Printing block: Yehuda Katz - - -== String helpers - -// capitalize -Hello world! -Hello world! -Hello world! -Hello world! -// center - Hello world! - Hello world! --------------------Hello world!------------------- --------------------Hello world!------------------- -// ljust -Hello world! -Hello world! -Hello world!-------------------------------------- -Hello world!-------------------------------------- -// pad_end -Hello world! -Hello world! -Hello world!-------------------------------------- -Hello world!-------------------------------------- -// rjust - Hello world! - Hello world! ---------------------------------------Hello world! ---------------------------------------Hello world! -// pad_start - Hello world! - Hello world! ---------------------------------------Hello world! ---------------------------------------Hello world! -// count -2 -2 -1 -1 -1 -1 -// ends_with -true -true -true -true -true -true -false -false -// starts_with -true -true -true -true -true -true -false -false -// expandtabs -Hello world! -Hello world! -Hello world! -Hello world! -Helloworld! -Helloworld! -// find -6 -6 -// index_of -6 -6 -// includes -true -true -false -false -// rfind --1 --1 --1 --1 -// rindex_of --1 --1 --1 --1 -// last_index_of --1 --1 --1 --1 -// at -e -e -// char_at -e -e -// isalnum -true -true -false -false -// isalpha -true -true -true -true -false -false -// isascii -true -true -// isdecimal -false -false -true -true -// isdigit -false -false -true -true -// islower -false -false -false -false -// isupper -false -false -false -false -// isprintable -true -true -false -false -// isspace -false -false -true -true -true -true -// istitle -false -false -true -true -// upper -HELLO WORLD! -HELLO WORLD! -// to_upper -HELLO WORLD! -HELLO WORLD! -// lower -hello world! -hello world! -// to_lower -hello world! -hello world! -// swapcase -hELLO WORLD! -hELLO WORLD! -// join -Hello,world! -Hello,world! -// concat -Hello world!,Bye! -Hello world!,Bye! -// strip -Hello world! -Hello world! -Hello world! -Hello world! -// trim -Hello world! -Hello world! -Hello world! -Hello world!--------' -// lstrip -Hello world! -Hello world! -Hello world!-------- -Hello world!-------- -// trim_start -Hello world! -Hello world! -Hello world!-------- -Hello world!-------- -// rstrip - Hello world! - Hello world! ---------Hello world! ---------Hello world! -// trim_end - Hello world! - Hello world! ---------Hello world! ---------Hello world! -// partition -[Hello, ,world!] -[Hello, ,world!] -[Hello world!,,] -[Hello world!,,] -// rpartition -[Hello, ,world!] -[Hello, ,world!] -[Hello world!,,] -[Hello world!,,] -// remove_prefix - world! - world! -// remove_suffix -Hello -Hello -Hello world -Hello world -// replace -Hello! -Hello! -// split -[Hello,world!] -[Hello,world!] -[He,] -[He,] -// rsplit -[world!,Hell] -[world!,Hell] -[d!,o wo] -[d!,o wo] -// splitlines -[Hello world!\nBye!] -[Hello world!\nBye!] -// zfill -00000000000000000000000000000000000000Hello world! -00000000000000000000000000000000000000Hello world! -00000000000000000000000000000000000000000000000000000000000000000000000000000030 -00000000000000000000000000000000000000000000000000000000000000000000000000000030 --0000000000000000000000000000000000000000000000000000000000000000000000000000030 --0000000000000000000000000000000000000000000000000000000000000000000000000000030 -// repeat -Hello world!Hello world!Hello world! -Hello world!Hello world!Hello world! -// escape -Hello world! -Hello world! -<Hello world!></Hello> -<Hello world!></Hello> -// slice -ello -ello -ello world! -ello world! -ello world -ello world -ell -ell -// substr -ello -ello -ello world! -ello world! -ello world -ello world -ell -ell -// safe_anchor_id -hello-world! -hello-world! -// strip_namespace -Hello world! -Hello world! -memory_order -memory_order -memory_order_acquire -memory_order_acquire -basic_string -basic_string - -== Containers - -// size -7 -7 -3 -// len -7 -7 -3 -// keys - -[a,b,c,d,e,f,g] - -// list - -list helper requires array argument: object provided - -// iter - -[a,b,c,d,e,f,g] - -// values -[a,b,c,d,e,f,g] -[a,b,c,d,e,f,g] -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// del -[a,b,d,e,f,g] -{"a":"a","b":"b","d":"d","e":"e","f":"f","g":"g"} -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// delete -[a,b,d,e,f,g] -{"a":"a","b":"b","d":"d","e":"e","f":"f","g":"g"} -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// has -true -true -false -// exist -true -false -true -false -false -// contains -true -false -true -false -false -// has_any -true -false -false -true -false -false -false -// exist_any -true -true -false -// contains_any -true -true -false -// get -c -c -{"account_id":"account-x11","product":"Desk"} -// get_or -y -y -y -// items -[a,b,c,d,e,f,g] -[[a,a],[b,b],[c,c],[d,d],[e,e],[f,f],[g,g]] -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// entries -[a,b,c,d,e,f,g] -[[a,a],[b,b],[c,c],[d,d],[e,e],[f,f],[g,g]] -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// first -a -"a" -{"account_id":"account-x10","product":"Chair"} -// head -a -"a" -{"account_id":"account-x10","product":"Chair"} -// front -a -"a" -{"account_id":"account-x10","product":"Chair"} -// last -g -"g" -{"account_id":"account-x11","product":"Desk"} -// tail -g -"g" -{"account_id":"account-x11","product":"Desk"} -// back -g -"g" -{"account_id":"account-x11","product":"Desk"} -// reverse -[g,f,e,d,c,b,a] -[["g","g"],["f","f"],["e","e"],["d","d"],["c","c"],["b","b"],["a","a"]] -[{"account_id":"account-x11","product":"Desk"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x10","product":"Chair"}] -// reversed -[g,f,e,d,c,b,a] -[["g","g"],["f","f"],["e","e"],["d","d"],["c","c"],["b","b"],["a","a"]] -[{"account_id":"account-x11","product":"Desk"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x10","product":"Chair"}] -// update -[a,b,c,d,e,f,g,h,i,j,k] -{"e":"e","f":"f","g":"g","h":"h","i":"i","j":"j","k":"k","a":"a","b":"b","c":"c","d":"d"} -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"},"e","f","g","h","i","j","k"] -// merge -[a,b,c,d,e,f,g,h,i,j,k] -{"e":"e","f":"f","g":"g","h":"h","i":"i","j":"j","k":"k","a":"a","b":"b","c":"c","d":"d"} -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"},"e","f","g","h","i","j","k"] -// sort -[a,b,c,d,e,f,g] -{"a":"a","b":"b","c":"c","d":"d","e":"e","f":"f","g":"g"} -[{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x11","product":"Desk"}] -// sort_by - - -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// at -c -c -{"account_id":"account-x11","product":"Desk"} -// fill -[a,b,-,-,-,f,g] -[a,b,-,-,-,-,g] - - -// count -1 -1 -0 -// concat -[a,b,c,d,e,f,g,e,f,g,h,i,j,k] -[object Object] -[[object Object],[object Object],[object Object],e,f,g,h,i,j,k] -// replace -[a,b,d,d,e,f,g] -[a,b,d,d,e,f,g] -{"c":"d","a":"a","b":"b","c":"c","d":"d","e":"e","f":"f"} -[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"},{"account_id":"account-x11","product":"Desk"}] -// chunk -[[a,b,c],[d,e,f],[g]] -[{"a":"a","b":"b","c":"c"},{"d":"d","e":"e","f":"f"},{"g":"g"}] -[[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"}],[{"account_id":"account-x11","product":"Desk"}]] -// group_by - - -{"account-x10":[{"account_id":"account-x10","product":"Chair"},{"account_id":"account-x10","product":"Bookcase"}],"account-x11":[{"account_id":"account-x11","product":"Desk"}]} -{"Chair":[{"account_id":"account-x10","product":"Chair"}],"Bookcase":[{"account_id":"account-x10","product":"Bookcase"}],"Desk":[{"account_id":"account-x11","product":"Desk"}]} -// pluck - - -["account-x10","account-x10","account-x11"] -["Chair","Bookcase","Desk"] -// unique -["a","b","c","d","e","f","g","h","i","j","k"] - - - -// Inverse block with no helper expands expressions - - struct T - - - diff --git a/test/unit/fixtures/record.adoc.hbs b/test/unit/fixtures/record.adoc.hbs deleted file mode 100644 index f63dca3aa..000000000 --- a/test/unit/fixtures/record.adoc.hbs +++ /dev/null @@ -1,9 +0,0 @@ -{{#if symbol.template}} - {{>template-head symbol.template}} - {{symbol.tag}} {{symbol.name~}} - {{#if (neq symbol.template.kind "primary")~}} - {{>template-args args=symbol.template.args}} - {{/if}} -{{else}} - {{symbol.tag}} {{symbol.name~}} -{{/if}} diff --git a/test/unit/handlebars.cpp b/test/unit/handlebars.cpp deleted file mode 100644 index 78db04b9b..000000000 --- a/test/unit/handlebars.cpp +++ /dev/null @@ -1,619 +0,0 @@ -// -// Copyright (c) 2023 alandefreitas (alandefreitas@gmail.com) -// -// Distributed under the Boost Software License, Version 1.0. -// https://www.boost.org/LICENSE_1_0.txt -// - -#include -#include -#include -#include -#include "test_macros.hpp" -#include "diff.hpp" -#include -#include - -void splitLines(std::string_view text, std::vector &lines); - -using namespace clang::mrdox; - -template<> -class fmt::formatter { -public: - template - constexpr auto parse(ParseContext& ctx) { - return ctx.begin(); - } - - template - auto format(dom::Kind const& value, FormatContext& ctx) { - switch (value) { - case dom::Kind::Null: - return format_to(ctx.out(), "null"); - case dom::Kind::Boolean: - return format_to(ctx.out(), "boolean"); - case dom::Kind::Integer: - return format_to(ctx.out(), "integer"); - case dom::Kind::String: - return format_to(ctx.out(), "string"); - case dom::Kind::Array: - return format_to(ctx.out(), "array"); - case dom::Kind::Object: - return format_to(ctx.out(), "object"); - } - return format_to(ctx.out(), "unknown"); - } -}; - - -int -main() { - // ============================================================== - // Fixtures - // ============================================================== - std::string_view template_path = - MRDOX_UNIT_TEST_DIR "/fixtures/handlebars_features_test.adoc.hbs"; - std::string_view partial_paths[] = { - MRDOX_UNIT_TEST_DIR "/fixtures/record-detail.adoc.hbs", - MRDOX_UNIT_TEST_DIR "/fixtures/record.adoc.hbs", - MRDOX_UNIT_TEST_DIR "/fixtures/escaped.adoc.hbs"}; - std::string_view output_path = - MRDOX_UNIT_TEST_DIR "/fixtures/handlebars_features_test.adoc"; - std::string_view error_output_path = - MRDOX_UNIT_TEST_DIR "/fixtures/handlebars_features_test_error.adoc"; - std::string_view logger_output_path = - MRDOX_UNIT_TEST_DIR "/fixtures/logger_output.txt"; - std::string_view logger_error_output_path = - MRDOX_UNIT_TEST_DIR "/fixtures/logger_output_error.txt"; - - auto template_text_r = files::getFileText(template_path); - REQUIRE(template_text_r); - auto master_file_contents_r = files::getFileText(output_path); - auto template_str = *template_text_r; - REQUIRE_FALSE(template_str.empty()); - auto master_logger_output_r = files::getFileText(logger_output_path); - - HandlebarsOptions options; - options.noEscape = true; - - // ============================================================== - // Context - // ============================================================== - dom::Object context; - dom::Object page; - page.set("kind", "record"); - page.set("name", "from_chars"); - page.set("decl", "std::from_chars"); - page.set("loc", "charconv"); - dom::Object javadoc; - javadoc.set("brief", "Converts strings to numbers"); - javadoc.set("details", "This function converts strings to numbers"); - page.set("javadoc", javadoc); - page.set("synopsis", "This is the from_chars function"); - dom::Object person; - person.set("firstname", "John"); - person.set("lastname", "Doe"); - page.set("person", person); - dom::Array people = dom::newArray(); - auto first_and_last_names = { - std::make_pair("Alice", "Doe"), - std::make_pair("Bob", "Doe"), - std::make_pair("Carol", "Smith")}; - for (auto [firstname, lastname]: first_and_last_names) { - person = {}; - person.set("firstname", firstname); - person.set("lastname", lastname); - dom::Array arr = dom::newArray(); - arr.emplace_back(dom::Object{}); - arr.emplace_back(dom::Object{}); - arr.emplace_back(dom::Object{}); - arr.emplace_back(dom::Object{}); - person.set("book", arr); - people.emplace_back(person); - } - page.set("people", people); - page.set("prefix", "Hello"); - page.set("specialChars", "& < > \" ' ` ="); - page.set("url", "https://cppalliance.org/"); - dom::Object page_author; - page_author.set("firstname", "Yehuda"); - page_author.set("lastname", "Katz"); - page.set("author", page_author); - context.set("page", page); - dom::Array nav = dom::newArray(); - dom::Object nav1; - nav1.set("url", "foo"); - nav1.set("test", true); - nav1.set("title", "bar"); - nav.emplace_back(nav1); - dom::Object nav2; - nav2.set("url", "bar"); - nav.emplace_back(nav2); - context.set("nav", nav); - context.set("myVariable", "lookupMyPartial"); - dom::Object myOtherContext; - myOtherContext.set("information", "Interesting!"); - context.set("myOtherContext", myOtherContext); - context.set("favoriteNumber", 123); - context.set("prefix", "Hello"); - context.set("title", "My Title"); - context.set("body", "My Body"); - dom::Object story; - story.set("intro", "Before the jump"); - story.set("body", "After the jump"); - context.set("story", story); - dom::Array comments = dom::newArray(); - dom::Object comment1; - comment1.set("subject", "subject 1"); - comment1.set("body", "body 1"); - comments.emplace_back(comment1); - dom::Object comment2; - comment2.set("subject", "subject 2"); - comment2.set("body", "body 2"); - comments.emplace_back(comment2); - context.set("comments", comments); - context.set("isActive", true); - context.set("isInactive", false); - dom::Object peopleObj; - for (auto [firstname, lastname]: first_and_last_names) { - person = {}; - person.set("firstname", firstname); - person.set("lastname", lastname); - peopleObj.set(firstname, person); - } - context.set("peopleobj", peopleObj); - context.set("author", true); - context.set("firstname", "Yehuda"); - context.set("lastname", "Katz"); - dom::Array names = dom::newArray(); - names.emplace_back("Yehuda Katz"); - names.emplace_back("Alan Johnson"); - names.emplace_back("Charles Jolley"); - context.set("names", names); - dom::Object namesobj; - namesobj.set("Yehuda", "Yehuda Katz"); - namesobj.set("Alan", "Alan Johnson"); - namesobj.set("Charles", "Charles Jolley"); - context.set("namesobj", namesobj); - dom::Object city; - city.set("name", "San Francisco"); - city.set("summary", "San Francisco is the cultural center of Northern California"); - dom::Object location; - location.set("north", "37.73,"); - location.set("east", "-122.44"); - city.set("location", location); - city.set("population", 883305); - context.set("city", city); - - dom::Object lookup_test; - dom::Array people_lookup = dom::newArray(); - people_lookup.emplace_back("Nils"); - people_lookup.emplace_back("Yehuda"); - lookup_test.set("people", people_lookup); - dom::Array cities_lookup = dom::newArray(); - cities_lookup.emplace_back("Darmstadt"); - cities_lookup.emplace_back("San Francisco"); - lookup_test.set("cities", cities_lookup); - context.set("lookup_test", lookup_test); - - dom::Object lookup_test2; - dom::Array persons = dom::newArray(); - dom::Object person1; - person1.set("name", "Nils"); - person1.set("resident-in", "darmstadt"); - persons.emplace_back(person1); - dom::Object person2; - person2.set("name", "Yehuda"); - person2.set("resident-in", "san-francisco"); - persons.emplace_back(person2); - lookup_test2.set("persons", persons); - dom::Object cities; - dom::Object darmstadt; - darmstadt.set("name", "Darmstadt"); - darmstadt.set("country", "Germany"); - cities.set("darmstadt", darmstadt); - dom::Object san_francisco; - san_francisco.set("name", "San Francisco"); - san_francisco.set("country", "USA"); - cities.set("san-francisco", san_francisco); - lookup_test2.set("cities", cities); - context.set("lookup_test2", lookup_test2); - - dom::Object containers; - dom::Array array; - array.emplace_back("a"); - array.emplace_back("b"); - array.emplace_back("c"); - array.emplace_back("d"); - array.emplace_back("e"); - array.emplace_back("f"); - array.emplace_back("g"); - containers.set("array", array); - - dom::Array array2; - array2.emplace_back("e"); - array2.emplace_back("f"); - array2.emplace_back("g"); - array2.emplace_back("h"); - array2.emplace_back("i"); - array2.emplace_back("j"); - array2.emplace_back("k"); - containers.set("array2", array2); - - dom::Object object; - object.set("a", "a"); - object.set("b", "b"); - object.set("c", "c"); - object.set("d", "d"); - object.set("e", "e"); - object.set("f", "f"); - object.set("g", "g"); - containers.set("object", object); - - dom::Object object2; - object2.set("e", "e"); - object2.set("f", "f"); - object2.set("g", "g"); - object2.set("h", "h"); - object2.set("i", "i"); - object2.set("j", "j"); - object2.set("k", "k"); - containers.set("object2", object2); - - dom::Array object_array; - dom::Object account_x10; - account_x10.set("account_id", "account-x10"); - account_x10.set("product", "Chair"); - object_array.emplace_back(account_x10); - dom::Object account_x11; - account_x11.set("account_id", "account-x10"); - account_x11.set("product", "Bookcase"); - object_array.emplace_back(account_x11); - dom::Object account_x12; - account_x12.set("account_id", "account-x11"); - account_x12.set("product", "Desk"); - object_array.emplace_back(account_x12); - containers.set("object_array", object_array); - - context.set("containers", containers); - - dom::Object symbol; - symbol.set("tag", "struct"); - symbol.set("kind", "record"); - symbol.set("name", "T"); - context.set("symbol", symbol); - - // ============================================================== - // Register helpers - // ============================================================== - Handlebars hbs; - helpers::registerAntoraHelpers(hbs); - helpers::registerStringHelpers(hbs); - helpers::registerContainerHelpers(hbs); - - hbs.registerHelper("progress", [](dom::Array const& args) { - if (args.size() < 3) { - return fmt::format("progress helper requires 3 arguments: {} provided", args.size()); - } - if (!args[0].isString()) { - return fmt::format("progress helper requires string argument: {} received", args[0]); - } - if (!args[1].isInteger()) { - return fmt::format("progress helper requires number argument: {} received", args[1]); - } - if (!args[2].isBoolean()) { - return fmt::format("progress helper requires boolean argument: {} received", args[2]); - } - dom::Value nameV = args[0]; - std::string_view name = nameV.getString(); - std::uint64_t percent = args[1].getInteger(); - bool stalled = args[2].getBool(); - std::uint64_t barWidth = percent / 5; - std::string bar = std::string(20, '*').substr(0, barWidth); - std::string stalledStr = stalled ? "stalled" : ""; - std::string res = bar; - res += ' '; - res += std::to_string(percent); - res += "% "; - res += name; - res += ' '; - res += stalledStr; - return res; - }); - - hbs.registerHelper("noop", helpers::noop_fn); - hbs.registerHelper("raw", helpers::noop_fn); - - hbs.registerHelper("link", [](dom::Array const& args, HandlebarsCallback const& cb) -> std::string { - if (args.empty()) { - return "no arguments provided to link helper"; - } - for (std::size_t i = 1; i < args.size(); ++i) { - if (!args[i].isString()) { - return fmt::format("link helper requires string arguments: {} provided", args.size()); - } - } - - std::string out; - auto h = cb.hashes().find("href"); - if (h.isString()) { - out += h.getString(); - } else if (args.size() > 1) { - if (!args[1].isString()) { - return fmt::format("link helper requires string argument: {} provided", args[1].kind()); - } - auto href = args[1]; - out += href.getString(); - } else { - out += "#"; - } - - out += '['; - out += args[0].getString(); - // more attributes from hashes - for (auto const& [key, value] : cb.hashes()) { - if (key == "href" || !value.isString()) { - continue; - } - out += ','; - out += key; - out += '='; - out += value.getString(); - } - out += ']'; - - return out; - }); - - hbs.registerHelper("loud", []( - dom::Array const& args, - HandlebarsCallback const& cb) -> std::string { - std::string res; - if (cb.isBlock()) { - res = cb.fn(); - } else { - if (args.empty()) { - return "loud helper requires at least one argument"; - } - if (!args[0].isString()) { - return fmt::format("loud helper requires string argument: {} provided", args[0].kind()); - } - res = args[0].getString(); - } - for (char& c : res) { - if (c >= 'a' && c <= 'z') - c += 'A' - 'a'; - } - return res; - }); - - hbs.registerHelper("to_string", []( - dom::Array const& args) -> std::string { - if (args.empty()) { - return "to_string helper requires at least one argument"; - } - dom::Value arg = args[0]; - return JSON_stringify(arg); - }); - - hbs.registerHelper("bold", []( - dom::Array const& /* args */, - HandlebarsCallback const& cb) { - return fmt::format(R"(
    {}
    )", cb.fn()); - }); - - hbs.registerHelper("list", []( - dom::Array const& args, - HandlebarsCallback const& cb) { - // Built-in helper to change the context for each object in args - if (args.size() != 1) { - return fmt::format("list helper requires 1 argument: {} provided", args.size()); - } - if (!args[0].isArray()) { - return fmt::format("list helper requires array argument: {} provided", args[0].kind()); - } - - dom::Object data = createFrame(cb.data()); - dom::Value itemsV = args[0]; - dom::Array const& items = itemsV.getArray(); - if (!items.empty()) { - std::string out = "(i)); - data.set("first", i == 0); - data.set("last", i == items.size() - 1); - data.set("index", static_cast(i)); - out += "
  • " + cb.fn(item, data, {}) + "
  • "; - } - return out + ""; - } - return cb.inverse(); - }); - - hbs.registerHelper("isdefined", [](dom::Array const& args) -> dom::Value { - if (args.empty()) { - return "isdefined helper requires at least one argument"; - } - // This is an example from the handlebars.js documentation - // There's no distinction between null and undefined in mrdox::dom - return !args[0].isNull(); - }); - - hbs.registerHelper("helperMissing", []( - dom::Array const& args, - HandlebarsCallback const& cb) { - std::string out; - OutputRef os(out); - os << "Missing: "; - os << cb.name(); - os << "("; - for (std::size_t i = 0; i < args.size(); ++i) { - if (i != 0) { - os << ", "; - } - os << args[i]; - } - os << ")"; - return out; - }); - - hbs.registerHelper("blockHelperMissing", []( - dom::Array const& args, - HandlebarsCallback const& cb) { - std::string out; - OutputRef os(out); - os << "Helper '"; - os << cb.name(); - os << "' not found. Printing block: "; - os << cb.fn(); - return out; - }); - - // ============================================================== - // Register logger - // ============================================================== - std::string log; - hbs.registerLogger([&log](dom::Value level, dom::Array const& args){ - log += fmt::format("[{}] ", level); - for (std::size_t i = 0; i < args.size(); ++i) { - if (i != 0) { - log += ", "; - } - log += args[i].getString(); - } - log += '\n'; - }); - - // ============================================================== - // Register partials - // ============================================================== - // From files - for (auto partial_path: partial_paths) { - auto partial_text_r = files::getFileText(partial_path); - REQUIRE(partial_text_r); - std::string_view filename = files::getFileName(partial_path); - auto pos = filename.find('.'); - if (pos != std::string_view::npos) { - filename = filename.substr(0, pos); - } - hbs.registerPartial(filename, *partial_text_r); - } - - // Dynamic partial helpers - hbs.registerHelper("whichPartial", []() { - return "dynamicPartial"; - }); - - // Literal partials - hbs.registerPartial("dynamicPartial", "Dynamo!"); - hbs.registerPartial("lookupMyPartial", "Found!"); - hbs.registerPartial("myPartialContext", "{{information}}"); - hbs.registerPartial("myPartialParam", "The result is {{parameter}}"); - hbs.registerPartial("myPartialParam2", "{{prefix}}, {{firstname}} {{lastname}}"); - hbs.registerPartial("layoutTemplate", "Site Content {{> @partial-block }}"); - hbs.registerPartial("pageLayout", "
    \n {{> nav}}\n
    \n
    \n {{> content}}\n
    "); - - // ============================================================== - // Render and diff - // ============================================================== - std::string rendered_text = hbs.render(template_str, context, options); - REQUIRE_FALSE(rendered_text.empty()); - - // Compare template with reference - if (!master_file_contents_r || master_file_contents_r->empty()) { - // Write rendered template to file with ofstream - std::ofstream out((std::string(output_path))); - REQUIRE(out); - fmt::println("Parsed template:\n{}", rendered_text); - out << rendered_text; - } else { - // Compare rendered template with reference - auto master_file_contents = *master_file_contents_r; - DiffStringsResult diff = diffStrings(master_file_contents, rendered_text); - if (diff.added > 0 || diff.removed > 0) { - std::ofstream out((std::string(error_output_path))); - REQUIRE(out); - out << rendered_text; - - fmt::println("DIFF:\n=====================\n{}\n=====================", diff.diff); - REQUIRE(diff.added == 0); - REQUIRE(diff.removed == 0); - } - REQUIRE(rendered_text.size() == master_file_contents.size()); - REQUIRE(rendered_text == master_file_contents); - } - - // ============================================================== - // Render and diff logger output - // ============================================================== - // Compare template with reference - if (!master_logger_output_r || master_logger_output_r->empty()) { - // Write logger output to file with ofstream - std::ofstream out((std::string(logger_output_path))); - REQUIRE(out); - fmt::println("Logger output:\n{}", log); - out << log; - } else { - // Compare logger output with reference - auto master_logger_output = *master_logger_output_r; - DiffStringsResult diff = diffStrings(master_logger_output, log); - if (diff.added > 0 || diff.removed > 0) { - std::ofstream out((std::string(logger_error_output_path))); - REQUIRE(out); - out << log; - - fmt::println("DIFF:\n=====================\n{}\n=====================", diff.diff); - REQUIRE(diff.added == 0); - REQUIRE(diff.removed == 0); - } - REQUIRE(log.size() == master_logger_output.size()); - REQUIRE(log == master_logger_output); - } - - // ============================================================== - // Safe string - // ============================================================== - { - Handlebars hbs2; - hbs2.registerHelper("bold", [](dom::Array const& args) -> dom::Value { - if (args.empty() || !args[0].isString()) { - return "bold helper requires at least one argument"; - } - std::string_view text = args[0].getString().get(); - return fmt::format("{}", text); - }); - std::string templ = "{{bold 'text'}}"; - std::string res = hbs2.render(templ, {}); - REQUIRE_FALSE(res == "text"); - REQUIRE(res == "<b>text</b>"); - - res = hbs2.render(templ, {}, options); - REQUIRE(res == "text"); - REQUIRE_FALSE(res == "<b>text</b>"); - - hbs2.registerHelper("bold", [](dom::Array const& args) { - if (args.empty() || !args[0].isString()) { - return safeString("bold helper requires at least one argument"); - } - std::string_view text = args[0].getString().get(); - return safeString(fmt::format("{}", text)); - }); - res = hbs2.render(templ, {}); - REQUIRE(res == "text"); - REQUIRE_FALSE(res == "<b>text</b>"); - } - - fmt::println("All tests passed!"); - return EXIT_SUCCESS; -}