summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--addon/CMakeLists.txt4
-rw-r--r--addon/doxmlparser/examples/metrics/CMakeLists.txt2
-rw-r--r--addon/doxmlparser/test/CMakeLists.txt1
-rw-r--r--addon/doxyapp/CMakeLists.txt1
-rw-r--r--addon/doxyparse/CMakeLists.txt1
-rw-r--r--addon/doxysearch/CMakeLists.txt1
-rw-r--r--cmake/CompilerWarnings.cmake4
-rw-r--r--cmake/Coverage.cmake39
-rw-r--r--cmake/SearchReplace.cmake4
-rw-r--r--src/CMakeLists.txt34
-rw-r--r--src/define.cpp54
-rw-r--r--src/define.h32
-rw-r--r--src/doxygen.cpp35
-rw-r--r--src/doxygen.h3
-rw-r--r--src/pre.l66
16 files changed, 161 insertions, 122 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 20c87dc..16c0454 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,6 +26,7 @@ option(use_libclang "Add support for libclang parsing." OFF)
option(win_static "Link with /MT in stead of /MD on windows" OFF)
option(english_only "Only compile in support for the English language" OFF)
option(force_qt4 "Forces doxywizard to build using Qt4 even if Qt5 is installed" OFF)
+option(enable_coverage "Enable coverage reporting for gcc/clang [development]" OFF)
SET(enlarge_lex_buffers "262144" CACHE INTERNAL "Sets the lex input and read buffers to the specified size")
@@ -159,6 +160,7 @@ if (win_static)
endif()
include(cmake/CompilerWarnings.cmake)
+include(cmake/Coverage.cmake)
add_subdirectory(libmd5)
add_subdirectory(liblodepng)
diff --git a/addon/CMakeLists.txt b/addon/CMakeLists.txt
index fd8c73f..ec4706b 100644
--- a/addon/CMakeLists.txt
+++ b/addon/CMakeLists.txt
@@ -1,4 +1,6 @@
-add_subdirectory(doxmlparser)
+if (build_xmlparser)
+ add_subdirectory(doxmlparser)
+endif ()
if (build_app)
add_subdirectory(doxyapp)
diff --git a/addon/doxmlparser/examples/metrics/CMakeLists.txt b/addon/doxmlparser/examples/metrics/CMakeLists.txt
index 8e03246..255ae0e 100644
--- a/addon/doxmlparser/examples/metrics/CMakeLists.txt
+++ b/addon/doxmlparser/examples/metrics/CMakeLists.txt
@@ -11,4 +11,6 @@ main.cpp
target_link_libraries(doxmlparser_metrics
doxmlparser
qtools
+ ${COVERAGE_LINKER_FLAGS}
)
+
diff --git a/addon/doxmlparser/test/CMakeLists.txt b/addon/doxmlparser/test/CMakeLists.txt
index c38c8a5..2d92b72 100644
--- a/addon/doxmlparser/test/CMakeLists.txt
+++ b/addon/doxmlparser/test/CMakeLists.txt
@@ -12,4 +12,5 @@ main.cpp
target_link_libraries(doxmlparser_test
doxmlparser
qtools
+ ${COVERAGE_LINKER_FLAGS}
)
diff --git a/addon/doxyapp/CMakeLists.txt b/addon/doxyapp/CMakeLists.txt
index af4590d..9d74fbc 100644
--- a/addon/doxyapp/CMakeLists.txt
+++ b/addon/doxyapp/CMakeLists.txt
@@ -31,6 +31,7 @@ ${CMAKE_THREAD_LIBS_INIT}
${SQLITE3_LIBRARIES}
${EXTRA_LIBS}
${CLANG_LIBS}
+${COVERAGE_LINKER_FLAGS}
)
install(TARGETS doxyapp DESTINATION bin)
diff --git a/addon/doxyparse/CMakeLists.txt b/addon/doxyparse/CMakeLists.txt
index d2a8f63..8e0ad49 100644
--- a/addon/doxyparse/CMakeLists.txt
+++ b/addon/doxyparse/CMakeLists.txt
@@ -31,6 +31,7 @@ ${CMAKE_THREAD_LIBS_INIT}
${SQLITE3_LIBRARIES}
${EXTRA_LIBS}
${CLANG_LIBS}
+${COVERAGE_LINKER_FLAGS}
)
install(TARGETS doxyparse DESTINATION bin)
diff --git a/addon/doxysearch/CMakeLists.txt b/addon/doxysearch/CMakeLists.txt
index 54794a6..7a1e1c1 100644
--- a/addon/doxysearch/CMakeLists.txt
+++ b/addon/doxysearch/CMakeLists.txt
@@ -17,6 +17,7 @@ target_link_libraries(doxyindexer
${XAPIAN_LIBRARIES}
${ZLIB_LIBRARIES}
${WIN_EXTRA_LIBS}
+ ${COVERAGE_LINKER_FLAGS}
qtools
)
diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake
index e6c1539..8137f6f 100644
--- a/cmake/CompilerWarnings.cmake
+++ b/cmake/CompilerWarnings.cmake
@@ -100,9 +100,9 @@ function(set_project_warnings project_name)
if(MSVC)
set(PROJECT_WARNINGS ${MSVC_WARNINGS})
- elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") # e.g. Clang or AppleClang
set(PROJECT_WARNINGS ${CLANG_WARNINGS})
- else()
+ elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "7.0.0")
set(GCC_EXTRA_WARNINGS
-Wno-implicit-fallthrough
diff --git a/cmake/Coverage.cmake b/cmake/Coverage.cmake
new file mode 100644
index 0000000..31f8341
--- /dev/null
+++ b/cmake/Coverage.cmake
@@ -0,0 +1,39 @@
+if(enable_coverage)
+ FIND_PROGRAM( LCOV_PATH lcov )
+ FIND_PROGRAM( GENHTML_PATH genhtml )
+ set(COVERAGE_COMPILER_FLAGS -g --coverage -O0
+ CACHE INTERNAL "")
+ set(COVERAGE_LINKER_FLAGS --coverage
+ CACHE INTERNAL "")
+ add_custom_target(coverage-clean
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --zerocounters
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+ add_custom_target(coverage
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --directory . --capture --output-file cov.info
+ COMMAND ${LCOV_PATH} --rc lcov_branch_coverage=1 --remove cov.info '*/c++/*' '*/_ctype.h' '*/generated_src/*' --output-file cov.info.cleaned
+ COMMAND ${CMAKE_COMMAND} -Dsearch=${CMAKE_BINARY_DIR}
+ -Dreplace=${CMAKE_SOURCE_DIR}
+ -Dsrc=cov.info.cleaned
+ -Ddst=cov.info.final
+ -P ${CMAKE_SOURCE_DIR}/cmake/SearchReplace.cmake
+ COMMAND ${GENHTML_PATH} --rc genhtml_branch_coverage=1
+ --function-coverage --branch-coverage
+ --title "Doxygen Coverage Report" --num-spaces 2
+ --legend --prefix ${CMAKE_SOURCE_DIR} --demangle-cpp
+ --output-directory cov_output cov.info.final
+ COMMAND ${CMAKE_COMMAND} -E remove cov.info cov.info.cleaned cov.info.final
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ )
+ add_custom_command(TARGET coverage POST_BUILD
+ COMMAND ;
+ COMMENT "Open ./cov_output/index.html in your browser to view the coverage report"
+ )
+endif()
+
+function(set_project_coverage project_name)
+ if(enable_coverage)
+ target_compile_options(${project_name} PRIVATE ${COVERAGE_COMPILER_FLAGS})
+ endif()
+endfunction()
+
diff --git a/cmake/SearchReplace.cmake b/cmake/SearchReplace.cmake
new file mode 100644
index 0000000..116cd71
--- /dev/null
+++ b/cmake/SearchReplace.cmake
@@ -0,0 +1,4 @@
+message("Replacing ${search} by ${replace} in file ${src} and writing to ${dst}...")
+file(READ ${src} file_contents)
+string(REPLACE "${search}" "${replace}" file_contents ${file_contents})
+file(WRITE ${dst} ${file_contents})
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index fec251e..a002ff8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -128,12 +128,30 @@ foreach(lex_file ${LEX_FILES})
OUTPUT ${GENERATED_SRC}/${lex_file}.l.h
)
set_source_files_properties(${GENERATED_SRC}/${lex_file}.l.h PROPERTIES GENERATED 1)
+ # for code coverage we need the flex sources in the build src directory
+ add_custom_command(
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/src/${lex_file}.l ${CMAKE_BINARY_DIR}/src/${lex_file}.l
+ DEPENDS ${CMAKE_SOURCE_DIR}/src/${lex_file}.l
+ OUTPUT ${CMAKE_BINARY_DIR}/src/${lex_file}.l
+ )
- FLEX_TARGET(${lex_file} ${lex_file}.l ${GENERATED_SRC}/${lex_file}.cpp COMPILE_FLAGS "${LEX_FLAGS}")
+ FLEX_TARGET(${lex_file}
+ ${lex_file}.l
+ ${GENERATED_SRC}/${lex_file}.cpp
+ COMPILE_FLAGS "${LEX_FLAGS}")
endforeach()
-BISON_TARGET(constexp constexp.y ${GENERATED_SRC}/ce_parse.cpp COMPILE_FLAGS "${YACC_FLAGS}")
+BISON_TARGET(constexp
+ constexp.y
+ ${GENERATED_SRC}/ce_parse.cpp
+ COMPILE_FLAGS "${YACC_FLAGS}")
+
+add_custom_command(
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/src/constexp.y ${CMAKE_BINARY_DIR}/src
+ DEPENDS ${CMAKE_SOURCE_DIR}/src/constexp.y
+ OUTPUT ${CMAKE_BINARY_DIR}/src/constexp.y
+)
add_library(doxycfg STATIC
${GENERATED_SRC}/lang_cfg.h
@@ -204,7 +222,6 @@ add_library(doxymain STATIC
context.cpp
cppvalue.cpp
defgen.cpp
- define.cpp
definition.cpp
dia.cpp
diagram.cpp
@@ -291,8 +308,9 @@ endif()
##add_library(doxymain STATIC ${GENERATED_SRC}/${lex_file}.l.h)
##endforeach()
-add_executable(doxygen main.cpp)
-
+add_executable(doxygen
+ main.cpp
+)
if (use_libclang)
find_package(LLVM REQUIRED CONFIG)
@@ -328,6 +346,7 @@ target_link_libraries(doxygen
${CMAKE_THREAD_LIBS_INIT}
${EXTRA_LIBS}
${CLANG_LIBS}
+ ${COVERAGE_LINKER_FLAGS}
${DOXYGEN_EXTRA_LINK_OPTIONS}
)
@@ -335,5 +354,10 @@ set_project_warnings(doxycfg)
set_project_warnings(doxymain)
set_project_warnings(doxygen)
+set_project_coverage(qtools)
+set_project_coverage(doxycfg)
+set_project_coverage(doxymain)
+set_project_coverage(doxygen)
+
install(TARGETS doxygen DESTINATION bin)
diff --git a/src/define.cpp b/src/define.cpp
deleted file mode 100644
index b5d9170..0000000
--- a/src/define.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/******************************************************************************
- *
- *
- *
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation under the terms of the GNU General Public License is hereby
- * granted. No representations are made about the suitability of this software
- * for any purpose. It is provided "as is" without express or implied warranty.
- * See the GNU General Public License for more details.
- *
- * Documents produced by Doxygen are derivative works derived from the
- * input used in their production; they are not affected by this license.
- *
- */
-
-#include "define.h"
-#include "config.h"
-
-Define::Define()
-{
- fileDef=0;
- lineNr=1;
- columnNr=1;
- nargs=-1;
- undef=FALSE;
- varArgs=FALSE;
- isPredefined=FALSE;
- nonRecursive=FALSE;
-}
-
-Define::Define(const Define &d)
- : name(d.name),definition(d.definition),fileName(d.fileName)
-{
- //name=d.name; definition=d.definition; fileName=d.fileName;
- lineNr=d.lineNr;
- columnNr=d.columnNr;
- nargs=d.nargs;
- undef=d.undef;
- varArgs=d.varArgs;
- isPredefined=d.isPredefined;
- nonRecursive=d.nonRecursive;
- fileDef=0;
-}
-
-Define::~Define()
-{
-}
-
-bool Define::hasDocumentation()
-{
- return definition && (doc || Config_getBool(EXTRACT_ALL));
-}
diff --git a/src/define.h b/src/define.h
index 3627140..0a3d62c 100644
--- a/src/define.h
+++ b/src/define.h
@@ -1,6 +1,6 @@
/******************************************************************************
*
- * Copyright (C) 1997-2015 by Dimitri van Heesch.
+ * Copyright (C) 1997-2020 by Dimitri van Heesch.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation under the terms of the GNU General Public License is hereby
@@ -28,31 +28,21 @@ class FileDef;
class Define
{
public:
- Define();
- Define(const Define &d);
- ~Define();
- bool hasDocumentation();
QCString name;
QCString definition;
QCString fileName;
- QCString doc;
- QCString brief;
QCString args;
- QCString anchor;
- FileDef *fileDef;
- int lineNr;
- int columnNr;
- int nargs;
- bool undef;
- bool varArgs;
- bool isPredefined;
- bool nonRecursive;
+ FileDef *fileDef = 0;
+ int lineNr = 1;
+ int columnNr = 1;
+ int nargs = -1;
+ bool undef = FALSE;
+ bool varArgs = FALSE;
+ bool isPredefined = FALSE;
+ bool nonRecursive = FALSE;
};
-/** A dictionary of references to Define objects. */
-typedef std::map< std::string,Define* > DefineMapRef;
-
-/** A dictionary of managed Define objects. */
-typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning;
+/** List of all macro definitions */
+using DefineList = std::vector< std::unique_ptr<Define> >;
#endif
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 5f324fd..c7c9b45 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -160,6 +160,7 @@ bool Doxygen::generatingXmlOutput = FALSE;
bool Doxygen::markdownSupport = TRUE;
GenericsSDict *Doxygen::genericsDict;
Preprocessor *Doxygen::preprocessor = 0;
+DefineList Doxygen::macroDefinitions;
// locally accessible globals
static std::unordered_map< std::string, const Entry* > g_classEntries;
@@ -7698,6 +7699,36 @@ static void addSourceReferences()
//----------------------------------------------------------------------------
+// add the macro definitions found during preprocessing as file members
+static void buildDefineList()
+{
+ for (const auto &def : Doxygen::macroDefinitions)
+ {
+ std::unique_ptr<MemberDef> md { createMemberDef(
+ def->fileName,def->lineNr,def->columnNr,
+ "#define",def->name,def->args,0,
+ Public,Normal,FALSE,Member,MemberType_Define,
+ ArgumentList(),ArgumentList(),"") };
+
+ if (!def->args.isEmpty())
+ {
+ md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, def->args));
+ }
+ md->setInitializer(def->definition);
+ md->setFileDef(def->fileDef);
+ md->setDefinition("#define "+def->name);
+
+ MemberName *mn=Doxygen::functionNameLinkedMap->add(def->name);
+ if (def->fileDef)
+ {
+ def->fileDef->insertMember(md.get());
+ }
+ mn->push_back(std::move(md));
+ }
+}
+
+//----------------------------------------------------------------------------
+
static void sortMemberLists()
{
// sort class member lists
@@ -10876,6 +10907,10 @@ void parseInput()
* Gather information *
**************************************************************************/
+ g_s.begin("Building macro definition list...\n");
+ buildDefineList();
+ g_s.end();
+
g_s.begin("Building group list...\n");
buildGroupList(root.get());
organizeSubGroups(root.get());
diff --git a/src/doxygen.h b/src/doxygen.h
index d8cd1fc..b824b54 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -28,6 +28,7 @@
#include "membergroup.h"
#include "dirdef.h"
#include "memberlist.h"
+#include "define.h"
class RefList;
class PageSList;
@@ -107,7 +108,6 @@ class Doxygen
static FileNameLinkedMap *diaFileNameLinkedMap;
static MemberNameLinkedMap *memberNameLinkedMap;
static MemberNameLinkedMap *functionNameLinkedMap;
- static QStrList tagfileList;
static StringUnorderedMap namespaceAliasMap;
static GroupSDict *groupSDict;
static NamespaceSDict *namespaceSDict;
@@ -139,6 +139,7 @@ class Doxygen
static bool markdownSupport;
static GenericsSDict *genericsDict;
static Preprocessor *preprocessor;
+ static DefineList macroDefinitions;
};
void initDoxygen();
diff --git a/src/pre.l b/src/pre.l
index da67db5..ef97f0a 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -57,8 +57,6 @@
#include "condparser.h"
#include "config.h"
#include "filedef.h"
-#include "memberdef.h"
-#include "membername.h"
#define YY_NO_UNISTD_H 1
@@ -93,6 +91,12 @@ struct FileState
QCString fileName;
};
+/** A dictionary of references to Define objects. */
+typedef std::map< std::string,Define* > DefineMapRef;
+
+/** A dictionary of managed Define objects. */
+typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning;
+
/** @brief Singleton that manages the defines available while
* preprocessing files.
*/
@@ -415,7 +419,7 @@ static bool otherCaseDone(yyscan_t yyscanner);
static bool computeExpression(yyscan_t yyscanner,const QCString &expr);
static void startCondSection(yyscan_t yyscanner,const char *sectId);
static void endCondSection(yyscan_t yyscanner);
-static void addDefine(yyscan_t yyscanner);
+static void addMacroDefinition(yyscan_t yyscanner);
static std::unique_ptr<Define> newDefine(yyscan_t yyscanner);
static void setFileName(yyscan_t yyscanner,const char *name);
static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
@@ -1540,7 +1544,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
//printf("Define name='%s' text='%s' litTexti='%s'\n",yyextra->defName.data(),yyextra->defText.data(),yyextra->defLitText.data());
if (yyextra->includeStack.empty() || yyextra->curlyCount>0)
{
- addDefine(yyscanner);
+ addMacroDefinition(yyscanner);
}
def=g_defineManager.isDefined(yyextra->defName);
if (def==0) // new define
@@ -2787,60 +2791,46 @@ static std::unique_ptr<Define> newDefine(yyscan_t yyscanner)
return def;
}
-static void addDefine(yyscan_t yyscanner)
+static void addMacroDefinition(yyscan_t yyscanner)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
if (state->skip) return; // do not add this define as it is inside a
// conditional section (cond command) that is disabled.
- //printf("addDefine '%s' '%s'\n",state->defName.data(),state->defArgsStr.data());
- //ArgumentList *al = new ArgumentList;
- //stringToArgumentList(state->defArgsStr,al);
- std::unique_ptr<MemberDef> md { createMemberDef(
- state->yyFileName,state->yyLineNr-state->yyMLines,state->yyColNr,
- "#define",state->defName,state->defArgsStr,0,
- Public,Normal,FALSE,Member,MemberType_Define,ArgumentList(),ArgumentList(),"") };
- if (!state->defArgsStr.isEmpty())
- {
- //printf("addDefine() state->defName='%s' state->defArgsStr='%s'\n",state->defName.data(),state->defArgsStr.data());
- md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, state->defArgsStr));
- }
- //printf("Setting initializer for '%s' to '%s'\n",state->defName.data(),state->defText.data());
- int l=state->defLitText.find('\n');
- if (l>0 && state->defLitText.left(l).stripWhiteSpace()=="\\")
+ auto define = std::make_unique<Define>();
+ define->fileName = state->yyFileName;
+ define->lineNr = state->yyLineNr - state->yyMLines;
+ define->columnNr = state->yyColNr;
+ define->name = state->defName;
+ define->args = state->defArgsStr;
+ define->fileDef = state->inputFileDef;
+
+ QCString litText = state->defLitText;
+ int l=litText.find('\n');
+ if (l>0 && litText.left(l).stripWhiteSpace()=="\\")
{
// strip first line if it only contains a slash
- state->defLitText = state->defLitText.right(state->defLitText.length()-l-1);
+ litText = litText.right(litText.length()-l-1);
}
else if (l>0)
{
// align the items on the first line with the items on the second line
int k=l+1;
- const char *p=state->defLitText.data()+k;
+ const char *p=litText.data()+k;
char c;
while ((c=*p++) && (c==' ' || c=='\t')) k++;
- state->defLitText=state->defLitText.mid(l+1,k-l-1)+state->defLitText.stripWhiteSpace();
+ litText=litText.mid(l+1,k-l-1)+litText.stripWhiteSpace();
}
- QCString defLitTextStripped = state->defLitText.stripWhiteSpace();
- if (defLitTextStripped.contains('\n')>=1)
+ QCString litTextStripped = state->defLitText.stripWhiteSpace();
+ if (litTextStripped.contains('\n')>=1)
{
- md->setInitializer(state->defLitText);
+ define->definition = litText;
}
else
{
- md->setInitializer(defLitTextStripped);
- }
-
- //printf("pre.l: md->setFileDef(%p)\n",state->inputFileDef);
- md->setFileDef(state->inputFileDef);
- md->setDefinition("#define "+state->defName);
-
- MemberName *mn=Doxygen::functionNameLinkedMap->add(state->defName);
- if (state->yyFileDef)
- {
- state->yyFileDef->insertMember(md.get());
+ define->definition = litTextStripped;
}
- mn->push_back(std::move(md));
+ Doxygen::macroDefinitions.push_back(std::move(define));
}
static inline void outputChar(yyscan_t yyscanner,char c)