summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDimitri van Heesch <doxygen@gmail.com>2020-08-01 11:27:31 (GMT)
committerGitHub <noreply@github.com>2020-08-01 11:27:31 (GMT)
commit8d96d4594188e4bcdffe8051a097bab8e40596f8 (patch)
tree905dd9b59c9c8004de3506a0b3799450a23c26eb /src
parent88e70b5242b2446f33ab700e6d10e7f25ae2c349 (diff)
parent4a1c9f98bc5f9c82e81a694160fecc5a22f0e02c (diff)
downloadDoxygen-8d96d4594188e4bcdffe8051a097bab8e40596f8.zip
Doxygen-8d96d4594188e4bcdffe8051a097bab8e40596f8.tar.gz
Doxygen-8d96d4594188e4bcdffe8051a097bab8e40596f8.tar.bz2
Merge branch 'master' into feature/bug_xml_lang
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt27
-rw-r--r--src/cite.cpp212
-rw-r--r--src/cite.h5
-rw-r--r--src/clangparser.cpp573
-rw-r--r--src/clangparser.h71
-rw-r--r--src/classdef.cpp22
-rw-r--r--src/commentcnv.l3
-rw-r--r--src/commentscan.h8
-rw-r--r--src/commentscan.l2541
-rw-r--r--src/condparser.cpp16
-rw-r--r--src/config.h31
-rw-r--r--src/config.xml38
-rwxr-xr-xsrc/configgen.py122
-rw-r--r--src/configimpl.h91
-rw-r--r--src/configimpl.l562
-rw-r--r--src/context.cpp28
-rw-r--r--src/debug.cpp13
-rw-r--r--src/debug.h5
-rw-r--r--src/define.h7
-rw-r--r--src/definition.cpp20
-rw-r--r--src/definition.h2
-rw-r--r--src/definitionimpl.h4
-rw-r--r--src/dirdef.cpp29
-rw-r--r--src/dirdef.h4
-rw-r--r--src/docparser.cpp21
-rw-r--r--src/docparser.h103
-rw-r--r--src/doctokenizer.h8
-rw-r--r--src/doctokenizer.l141
-rw-r--r--src/dot.cpp3
-rw-r--r--src/dotfilepatcher.cpp2
-rw-r--r--src/dotgraph.cpp2
-rw-r--r--src/dotrunner.cpp3
-rw-r--r--src/doxygen.cpp638
-rw-r--r--src/doxygen.h10
-rw-r--r--src/entry.cpp21
-rw-r--r--src/entry.h3
-rw-r--r--src/filedef.cpp222
-rw-r--r--src/filedef.h39
-rw-r--r--src/fortranscanner.h11
-rw-r--r--src/fortranscanner.l14
-rw-r--r--src/ftextstream.h3
-rw-r--r--src/ftvhelp.cpp5
-rw-r--r--src/groupdef.cpp29
-rw-r--r--src/growbuf.h1
-rw-r--r--src/htags.cpp32
-rw-r--r--src/htmlgen.cpp51
-rw-r--r--src/htmlhelp.cpp9
-rw-r--r--src/index.cpp39
-rw-r--r--src/latexdocvisitor.cpp165
-rw-r--r--src/latexgen.cpp20
-rw-r--r--src/layout.cpp496
-rw-r--r--src/mangen.cpp158
-rw-r--r--src/markdown.cpp895
-rw-r--r--src/markdown.h88
-rw-r--r--src/memberdef.cpp45
-rw-r--r--src/memberlist.cpp9
-rw-r--r--src/message.cpp2
-rw-r--r--src/namespacedef.cpp12
-rw-r--r--src/outputlist.cpp5
-rw-r--r--src/outputlist.h5
-rw-r--r--src/pagedef.cpp57
-rw-r--r--src/parserintf.h26
-rw-r--r--src/perlmodgen.cpp13
-rw-r--r--src/plantuml.cpp28
-rw-r--r--src/pre.l653
-rw-r--r--src/pyscanner.h15
-rw-r--r--src/pyscanner.l84
-rwxr-xr-xsrc/res2cc_cmd.py9
-rw-r--r--src/resourcemgr.cpp12
-rw-r--r--src/resourcemgr.h2
-rw-r--r--src/rtfgen.cpp4
-rw-r--r--src/scanner.h13
-rw-r--r--src/scanner.l76
-rw-r--r--src/sqlite3gen.cpp28
-rw-r--r--src/tagreader.cpp2
-rw-r--r--src/template.cpp6
-rw-r--r--src/translator.h6
-rw-r--r--src/translator_adapter.h3
-rw-r--r--src/translator_br.h9
-rw-r--r--src/translator_cn.h8
-rw-r--r--src/translator_cz.h8
-rw-r--r--src/translator_de.h8
-rw-r--r--src/translator_en.h8
-rw-r--r--src/translator_eo.h1
-rw-r--r--src/translator_es.h8
-rw-r--r--src/translator_fr.h8
-rw-r--r--src/translator_gr.h32
-rw-r--r--src/translator_hu.h8
-rw-r--r--src/translator_it.h8
-rw-r--r--src/translator_jp.h8
-rw-r--r--src/translator_kr.h8
-rw-r--r--src/translator_lv.h1
-rw-r--r--src/translator_nl.h8
-rw-r--r--src/translator_pt.h9
-rw-r--r--src/translator_ro.h8
-rw-r--r--src/translator_ru.h8
-rw-r--r--src/translator_sk.h8
-rw-r--r--src/translator_sv.h8
-rw-r--r--src/translator_tw.h8
-rw-r--r--src/translator_ua.h1
-rw-r--r--src/util.cpp157
-rw-r--r--src/util.h4
-rw-r--r--src/vhdldocgen.cpp33
-rw-r--r--src/vhdljjparser.cpp175
-rwxr-xr-xsrc/vhdljjparser.h8
-rw-r--r--src/xmlgen.cpp10
106 files changed, 4840 insertions, 4509 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 598f73c..8b11a2d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -136,14 +136,14 @@ foreach(lex_file ${LEX_FILES})
)
FLEX_TARGET(${lex_file}
- ${lex_file}.l
+ ${CMAKE_CURRENT_LIST_DIR}/${lex_file}.l
${GENERATED_SRC}/${lex_file}.cpp
COMPILE_FLAGS "${LEX_FLAGS}")
endforeach()
BISON_TARGET(constexp
- constexp.y
+ ${CMAKE_CURRENT_LIST_DIR}/constexp.y
${GENERATED_SRC}/ce_parse.cpp
COMPILE_FLAGS "${YACC_FLAGS}")
@@ -167,6 +167,7 @@ add_library(doxycfg STATIC
message.cpp
debug.cpp
)
+add_sanitizers(doxycfg)
add_library(doxymain STATIC
# generated for/by flex/bison
@@ -296,6 +297,7 @@ add_library(doxymain STATIC
xmldocvisitor.cpp
xmlgen.cpp
)
+add_sanitizers(doxymain)
# LLVM/clang headers give a lot of warnings with -Wshadow and -Wcast-align so we disable them for
# the one file that includes them
@@ -311,6 +313,7 @@ endif()
add_executable(doxygen
main.cpp
)
+add_sanitizers(doxygen)
if (use_libclang)
find_package(LLVM REQUIRED CONFIG)
@@ -319,20 +322,23 @@ if (use_libclang)
cmake_minimum_required(VERSION 3.1)
target_compile_features(doxymain PRIVATE cxx_alignof)
target_compile_features(doxygen PRIVATE cxx_alignof)
- target_compile_options(doxymain PRIVATE -stdlib=libc++)
- target_compile_options(doxygen PRIVATE -stdlib=libc++)
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
- target_compile_options(doxymain PRIVATE -std=c++11)
- target_compile_options(doxygen PRIVATE -std=c++11)
+ if (use_libc++)
+ target_compile_options(doxymain PRIVATE -stdlib=libc++)
+ target_compile_options(doxygen PRIVATE -stdlib=libc++)
+ endif()
endif()
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
- llvm_map_components_to_libnames(llvm_libs support core option)
+ if (static_libclang)
+ set(CLANG_LIBS libclang clangTooling)
+ else() # dynamically linked version of clang
+ llvm_config(doxymain USE_SHARED support)
+ set(CLANG_LIBS libclang clang-cpp)
+ endif()
target_compile_definitions(doxygen PRIVATE ${LLVM_DEFINITIONS})
- set(CLANG_LIBS libclang clangTooling ${llvm_libs})
endif()
-target_link_libraries(doxygen
+target_link_libraries(doxygen PRIVATE
doxymain
doxycfg
qtools
@@ -359,5 +365,6 @@ set_project_coverage(doxycfg)
set_project_coverage(doxymain)
set_project_coverage(doxygen)
+
install(TARGETS doxygen DESTINATION bin)
diff --git a/src/cite.cpp b/src/cite.cpp
index dac2bcd..fd6fe3e 100644
--- a/src/cite.cpp
+++ b/src/cite.cpp
@@ -4,8 +4,8 @@
* Based on a patch by David Munger
*
* 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
+ * 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.
*
@@ -22,6 +22,7 @@
#include "portable.h"
#include "resourcemgr.h"
#include "util.h"
+#include "debug.h"
#include <qfile.h>
#include <qfileinfo.h>
@@ -30,10 +31,6 @@
#include <map>
#include <string>
-// Remove the temporary files
-#define RM_TMP_FILES (true)
-//#define RM_TMP_FILES (false)
-
const char *bibTmpFile = "bibTmpFile_";
const char *bibTmpDir = "bibTmpDir/";
@@ -94,7 +91,7 @@ void CitationManager::clear()
bool CitationManager::isEmpty() const
{
- uint numFiles = Config_getList(CITE_BIB_FILES).count();
+ size_t numFiles = Config_getList(CITE_BIB_FILES).size();
return (numFiles==0 || p->entries.empty());
}
@@ -108,72 +105,147 @@ const char *CitationManager::anchorPrefix() const
return "CITEREF_";
}
-void CitationManager::generatePage()
+void CitationManager::insertCrossReferencesForBibFile(const QCString &bibFile)
{
- //printf("** CitationManager::generatePage() count=%d\n",m_ordering.count());
+ // sanity checks
+ if (bibFile.isEmpty())
+ {
+ return;
+ }
+ QFileInfo fi(bibFile);
+ if (!fi.exists())
+ {
+ err("bib file %s not found!\n",bibFile.data());
+ return;
+ }
+ QFile f(bibFile);
+ if (!f.open(IO_ReadOnly))
+ {
+ err("could not open file %s for reading\n",bibFile.data());
+ return;
+ }
- // do not generate an empty citations page
- if (isEmpty()) return; // nothing to cite
+ // convert file to string
+ QCString doc;
+ QCString input(fi.size()+1);
+ f.readBlock(input.rawData(),fi.size());
+ f.close();
+ input.at(fi.size())='\0';
- // 0. add cross references from the bib files to the cite dictionary
- QFile f;
- const QStrList &citeDataList = Config_getList(CITE_BIB_FILES);
- QStrListIterator li(citeDataList);
- const char *bibdata = 0;
- for (li.toFirst() ; (bibdata = li.current()) ; ++li)
+ int pos=0;
+ int s;
+
+ // helper lambda function to get the next line of input and update pos accordingly
+ auto get_next_line = [&input,&pos,&s]()
{
- QCString bibFile = bibdata;
- if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
- QFileInfo fi(bibFile);
- if (fi.exists())
+ uint prevPos = (uint)pos;
+ pos=s+1;
+ return input.mid(prevPos,(uint)(s-prevPos));
+ };
+
+ // helper lambda function to return if the end of the input has reached
+ auto end_of_input = [&s]()
+ {
+ return s==-1;
+ };
+
+ // helper lambda function to proceed to the next line in the input, and update s
+ // to point to the start of the line. Return true as long as there is a new line.
+ auto has_next_line = [&input,&pos,&s]()
+ {
+ s=input.find('\n',pos);
+ return s!=-1;
+ };
+
+ // search for citation cross references
+ QCString citeName;
+ while (has_next_line())
+ {
+ QCString line = get_next_line();
+
+ int i;
+ if (line.stripWhiteSpace().startsWith("@"))
{
- if (!bibFile.isEmpty())
+ // assumption entry like: "@book { name," or "@book { name" (spaces optional)
+ int j = line.find('{');
+ // when no {, go hunting for it
+ while (j==-1 && has_next_line())
{
- f.setName(bibFile);
- if (!f.open(IO_ReadOnly))
- {
- err("could not open file %s for reading\n",bibFile.data());
- }
- QCString doc;
- QCString input(fi.size()+1);
- f.readBlock(input.rawData(),fi.size());
- f.close();
- input.at(fi.size())='\0';
- int pos=0;
- int s;
- while ((s=input.find('\n',pos))!=-1)
+ line = get_next_line();
+ j = line.find('{');
+ }
+ // search for the name
+ citeName = "";
+ if (!end_of_input() && j!=-1) // to prevent something like "@manual ," and no { found
+ {
+ int k = line.find(',',j);
+ j++;
+ // found a line "@....{.....,...." or "@.....{....."
+ // ^=j ^=k ^=j k=-1
+ while (!end_of_input() && citeName.isEmpty())
{
- QCString line = input.mid((uint)pos,(uint)(s-pos));
- pos=s+1;
-
- int i;
- if ((i = line.find("crossref")) != -1) /* assumption cross reference is on one line and the only item */
+ if (k!=-1)
+ {
+ citeName = line.mid((uint)(j),(uint)(k-j));
+ }
+ else
{
- int j=line.find("{",i);
- int k=line.find("}",i);
- if (j!=-1 && k!=-1)
- {
- QCString label = line.mid((uint)(j+1),(uint)(k-j-1));
- if (p->entries.find(label.data())==p->entries.end()) // not found yet
- {
- insert(label);
- }
- }
+ citeName = line.mid((uint)(j));
+ }
+ citeName = citeName.stripWhiteSpace();
+ j = 0;
+ if (citeName.isEmpty() && has_next_line())
+ {
+ line = get_next_line();
+ k = line.find(',');
}
}
}
+ //printf("citeName = #%s#\n",citeName.data());
}
- else if (!fi.exists())
+ else if ((i=line.find("crossref"))!=-1 && !citeName.isEmpty()) /* assumption cross reference is on one line and the only item */
{
- err("bib file %s not found!\n",bibFile.data());
+ int j = line.find('{',i);
+ int k = line.find('}',i);
+ if (j>i && k>j)
+ {
+ QCString crossrefName = line.mid((uint)(j+1),(uint)(k-j-1));
+ // check if the reference with the cross reference is used
+ // insert cross refererence when cross reference has not yet been added.
+ if ((p->entries.find(citeName.data())!=p->entries.end()) &&
+ (p->entries.find(crossrefName.data())==p->entries.end())) // not found yet
+ {
+ insert(crossrefName);
+ }
+ }
}
}
+}
+
+void CitationManager::generatePage()
+{
+ //printf("** CitationManager::generatePage() count=%d\n",m_ordering.count());
+
+ // do not generate an empty citations page
+ if (isEmpty()) return; // nothing to cite
+
+ bool citeDebug = Debug::isFlagSet(Debug::Cite);
+
+ // 0. add cross references from the bib files to the cite dictionary
+ QFile f;
+ const StringVector &citeDataList = Config_getList(CITE_BIB_FILES);
+ for (const auto &bibdata : citeDataList)
+ {
+ QCString bibFile = bibdata.c_str();
+ if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
+ insertCrossReferencesForBibFile(bibFile);
+ }
// 1. generate file with markers and citations to OUTPUT_DIRECTORY
QCString outputDir = Config_getString(OUTPUT_DIRECTORY);
QCString citeListFile = outputDir+"/citelist.doc";
f.setName(citeListFile);
- if (!f.open(IO_WriteOnly))
+ if (!f.open(IO_WriteOnly))
{
err("could not open file %s for writing\n",citeListFile.data());
}
@@ -205,11 +277,15 @@ void CitationManager::generatePage()
QCString bibOutputDir = outputDir+"/"+bibTmpDir;
QCString bibOutputFiles = "";
QDir thisDir;
- thisDir.mkdir(bibOutputDir);
+ if (!thisDir.exists(bibOutputDir) && !thisDir.mkdir(bibOutputDir))
+ {
+ err("Failed to create temporary output directory '%s', skipping citations\n",bibOutputDir.data());
+ return;
+ }
int i = 0;
- for (li.toFirst() ; (bibdata = li.current()) ; ++li)
+ for (const auto &bibdata : citeDataList)
{
- QCString bibFile = bibdata;
+ QCString bibFile = bibdata.c_str();
if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
QFileInfo fi(bibFile);
if (fi.exists())
@@ -231,7 +307,7 @@ void CitationManager::generatePage()
int exitCode;
Portable::sysTimerStop();
if ((exitCode=Portable::system("perl","\""+bib2xhtmlFile+"\" "+bibOutputFiles+" \""+
- citeListFile+"\"")) != 0)
+ citeListFile+"\"" + (citeDebug ? " -d" : ""))) != 0)
{
err("Problems running bibtex. Verify that the command 'perl --version' works from the command line. Exit code: %d\n",
exitCode);
@@ -242,7 +318,7 @@ void CitationManager::generatePage()
// 6. read back the file
f.setName(citeListFile);
- if (!f.open(IO_ReadOnly))
+ if (!f.open(IO_ReadOnly))
{
err("could not open file %s for reading\n",citeListFile.data());
}
@@ -294,16 +370,16 @@ void CitationManager::generatePage()
// 7. add it as a page
addRelatedPage(fileName(),theTranslator->trCiteReferences(),doc,fileName(),1);
- // 8. for latex we just copy the bib files to the output and let
+ // 8. for latex we just copy the bib files to the output and let
// latex do this work.
if (Config_getBool(GENERATE_LATEX))
{
// copy bib files to the latex output dir
QCString latexOutputDir = Config_getString(LATEX_OUTPUT)+"/";
i = 0;
- for (li.toFirst() ; (bibdata = li.current()) ; ++li)
+ for (const auto &bibdata : citeDataList)
{
- QCString bibFile = bibdata;
+ QCString bibFile = bibdata.c_str();
// Note: file can now have multiple dots
if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
fi.setFile(bibFile);
@@ -325,7 +401,7 @@ void CitationManager::generatePage()
}
// 9. Remove temporary files
- if (RM_TMP_FILES)
+ if (!citeDebug)
{
thisDir.remove(citeListFile);
thisDir.remove(doxygenBstFile);
@@ -333,9 +409,9 @@ void CitationManager::generatePage()
// we might try to remove too many files as empty files didn't get a corresponding new file
// but the remove function does not emit an error for it and we don't catch the error return
// so no problem.
- for (unsigned int j = 1; j <= citeDataList.count(); j++)
+ for (size_t j = 1; j <= citeDataList.size(); j++)
{
- thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(j) + ".bib");
+ thisDir.remove(bibOutputDir + bibTmpFile + QCString().setNum(static_cast<ulong>(j)) + ".bib");
}
thisDir.rmdir(bibOutputDir);
}
@@ -370,13 +446,11 @@ void CitationManager::writeLatexBibliography(FTextStream &t) const
}
t << "\\bibliographystyle{" << style << "}\n"
"\\bibliography{";
- QStrList &citeDataList = Config_getList(CITE_BIB_FILES);
+ const StringVector &citeDataList = Config_getList(CITE_BIB_FILES);
int i = 0;
- QStrListIterator li(citeDataList);
- const char *bibdata = 0;
- for (li.toFirst() ; (bibdata = li.current()) ; ++li)
+ for (const auto &bibdata : citeDataList)
{
- QCString bibFile = bibdata;
+ QCString bibFile = bibdata.c_str();
// Note: file can now have multiple dots
if (!bibFile.isEmpty() && bibFile.right(4)!=".bib") bibFile+=".bib";
QFileInfo fi(bibFile);
diff --git a/src/cite.h b/src/cite.h
index 4666d5a..9fea954 100644
--- a/src/cite.h
+++ b/src/cite.h
@@ -4,8 +4,8 @@
* Based on a patch by David Munger
*
* 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
+ * 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.
*
@@ -70,6 +70,7 @@ class CitationManager
private:
/** Create the database, with an expected maximum of \a size entries */
CitationManager();
+ void insertCrossReferencesForBibFile(const QCString &bibFile);
struct Private;
std::unique_ptr<Private> p;
};
diff --git a/src/clangparser.cpp b/src/clangparser.cpp
index 0754888..d0ed573 100644
--- a/src/clangparser.cpp
+++ b/src/clangparser.cpp
@@ -20,17 +20,22 @@
#include "membername.h"
#include "filename.h"
#include "tooltip.h"
+#if MULTITHREADED_INPUT
+#include <mutex>
+#endif
+#endif
-static Definition *g_currentDefinition=0;
-static MemberDef *g_currentMemberDef=0;
-static uint g_currentLine=0;
-static bool g_searchForBody=FALSE;
-static bool g_insideBody=FALSE;
-static uint g_bracketCount=0;
+//--------------------------------------------------------------------------
+
+#if MULTITHREADED_INPUT
+std::mutex g_clangMutex;
#endif
ClangParser *ClangParser::instance()
{
+#if MULTITHREADED_INPUT
+ std::lock_guard<std::mutex> lock(g_clangMutex);
+#endif
if (!s_instance) s_instance = new ClangParser;
return s_instance;
}
@@ -40,29 +45,7 @@ ClangParser *ClangParser::s_instance = 0;
//--------------------------------------------------------------------------
#if USE_LIBCLANG
-class ClangParser::Private
-{
- public:
- enum DetectedLang { Detected_Cpp, Detected_ObjC, Detected_ObjCpp };
- Private() : tu(0), tokens(0), numTokens(0), cursors(0),
- ufs(0), sources(0), numFiles(0), fileMapping(257),
- detectedLang(Detected_Cpp)
- { fileMapping.setAutoDelete(TRUE); }
- int getCurrentTokenLine();
- CXIndex index;
- CXTranslationUnit tu;
- QCString fileName;
- CXToken *tokens;
- uint numTokens;
- CXCursor *cursors;
- uint curLine;
- uint curToken;
- CXUnsavedFile *ufs;
- QCString *sources;
- uint numFiles;
- QDict<uint> fileMapping;
- DetectedLang detectedLang;
-};
+enum class DetectedLang { Cpp, ObjC, ObjCpp };
static QCString detab(const QCString &s)
{
@@ -118,99 +101,110 @@ static QCString detab(const QCString &s)
return out.get();
}
-/** Callback function called for each include in a translation unit */
-static void inclusionVisitor(CXFile includedFile,
- CXSourceLocation* /*inclusionStack*/,
- unsigned /*includeLen*/,
- CXClientData clientData)
+static QCString keywordToType(const char *keyword)
{
- QDict<void> *fileDict = (QDict<void> *)clientData;
- CXString incFileName = clang_getFileName(includedFile);
- //printf("--- file %s includes %s\n",fileName,clang_getCString(incFileName));
- fileDict->insert(clang_getCString(incFileName),(void*)0x8);
- clang_disposeString(incFileName);
+ static const StringUnorderedSet flowKeywords({
+ "break", "case", "catch", "continue", "default", "do",
+ "else", "finally", "for", "foreach", "for each", "goto",
+ "if", "return", "switch", "throw", "throws", "try",
+ "while", "@try", "@catch", "@finally" });
+ static const StringUnorderedSet typeKeywords({
+ "bool", "char", "double", "float", "int", "long", "object",
+ "short", "signed", "unsigned", "void", "wchar_t", "size_t",
+ "boolean", "id", "SEL", "string", "nullptr" });
+ if (flowKeywords.find(keyword)!=flowKeywords.end()) return "keywordflow";
+ if (typeKeywords.find(keyword)!=typeKeywords.end()) return "keywordtype";
+ return "keyword";
}
-/** filter the \a files and only keep those that are found as include files
- * within the current translation unit.
- * @param[in,out] files The list of files to filter.
- */
-void ClangParser::determineInputFilesInSameTu(QStrList &files)
+
+//--------------------------------------------------------------------------
+
+class ClangTUParser::Private
+{
+ public:
+ Private(const ClangParser &p,const FileDef *fd)
+ : parser(p), fileDef(fd) {}
+ const ClangParser &parser;
+ const FileDef *fileDef;
+ CXIndex index;
+ uint curToken = 0;
+ DetectedLang detectedLang = DetectedLang::Cpp;
+ uint numFiles = 0;
+ std::vector<QCString> sources;
+ std::vector<CXUnsavedFile> ufs;
+ std::vector<CXCursor> cursors;
+ std::unordered_map<std::string,uint> fileMapping;
+ CXTranslationUnit tu;
+ CXToken *tokens = 0;
+ uint numTokens = 0;
+ StringVector filesInSameTU;
+
+ // state while parsing sources
+ MemberDef *currentMemberDef=0;
+ uint currentLine=0;
+ bool searchForBody=FALSE;
+ bool insideBody=FALSE;
+ uint bracketCount=0;
+};
+
+ClangTUParser::ClangTUParser(const ClangParser &parser,const FileDef *fd)
+ : p(std::make_unique<Private>(parser,fd))
{
- // put the files in this translation unit in a dictionary
- QDict<void> incFound(257);
- clang_getInclusions(p->tu,
- inclusionVisitor,
- (CXClientData)&incFound
- );
- // create a new filtered file list
- QStrList resultIncludes;
- QStrListIterator it2(files);
- for (it2.toFirst();it2.current();++it2)
- {
- if (incFound.find(it2.current()))
- {
- resultIncludes.append(it2.current());
- }
- }
- // replace the original list
- files=resultIncludes;
}
-void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
+StringVector ClangTUParser::filesInSameTU() const
{
- static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
- static QStrList &includePath = Config_getList(INCLUDE_PATH);
- static QStrList clangOptions = Config_getList(CLANG_OPTIONS);
- static QCString clangCompileDatabase = Config_getString(CLANG_DATABASE_PATH);
+ return p->filesInSameTU;
+}
+
+void ClangTUParser::parse()
+{
+ QCString fileName = p->fileDef->absFilePath();
+ p->fileDef->getAllIncludeFilesRecursively(p->filesInSameTU);
+ //printf("ClangTUParser::ClangTUParser(fileName=%s,#filesInSameTU=%d)\n",
+ // qPrint(fileName),(int)p->filesInSameTU.size());
+ bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
+ bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
+ const StringVector &includePath = Config_getList(INCLUDE_PATH);
+ const StringVector &clangOptions = Config_getList(CLANG_OPTIONS);
if (!clangAssistedParsing) return;
//printf("ClangParser::start(%s)\n",fileName);
- p->fileName = fileName;
p->index = clang_createIndex(0, 0);
- p->curLine = 1;
p->curToken = 0;
int argc=0;
- std::string error;
- // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
- // this only needs to be loaded once, and could be refactored to a higher level function
- static std::unique_ptr<clang::tooling::CompilationDatabase> db =
- clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error);
- int clang_option_len = 0;
+ size_t clang_option_len = 0;
std::vector<clang::tooling::CompileCommand> command;
- if (qstrcmp(clangCompileDatabase, "0") != 0)
+ if (p->parser.database()!=nullptr)
{
- if (db == nullptr)
- {
- // user specified a path, but DB file was not found
- err("%s using clang compilation database path of: \"%s\"\n", error.c_str(),
- clangCompileDatabase.data());
- }
- else
- {
- // check if the file we are parsing is in the DB
- command = db->getCompileCommands(fileName);
- if (!command.empty() )
- {
- // it's possible to have multiple entries for the same file, so use the last entry
- clang_option_len = command[command.size()-1].CommandLine.size();
- }
- }
+ // check if the file we are parsing is in the DB
+ command = p->parser.database()->getCompileCommands(fileName.data());
+ if (!command.empty() )
+ {
+ // it's possible to have multiple entries for the same file, so use the last entry
+ clang_option_len = command[command.size()-1].CommandLine.size();
+ }
}
char **argv = (char**)malloc(sizeof(char*)*
(4+Doxygen::inputPaths.size()+
- includePath.count()+
- clangOptions.count()+
+ includePath.size()+
+ clangOptions.size()+
clang_option_len));
if (!command.empty() )
{
- std::vector<std::string> options = command[command.size()-1].CommandLine;
- // copy each compiler option used from the database. Skip the first which is compiler exe.
- for (auto option = options.begin()+1; option != options.end(); option++)
- {
- argv[argc++] = qstrdup(option->c_str());
- }
- // this extra addition to argv is accounted for as we are skipping the first entry in
- argv[argc++]=qstrdup("-w"); // finally, turn off warnings.
+ std::vector<std::string> options = command[command.size()-1].CommandLine;
+ // copy each compiler option used from the database. Skip the first which is compiler exe.
+ for (auto option = options.begin()+1; option != options.end(); option++)
+ {
+ argv[argc++] = qstrdup(option->c_str());
+ }
+ // user specified options
+ for (size_t i=0;i<clangOptions.size();i++)
+ {
+ argv[argc++]=qstrdup(clangOptions[i].c_str());
+ }
+ // this extra addition to argv is accounted for as we are skipping the first entry in
+ argv[argc++]=qstrdup("-w"); // finally, turn off warnings.
}
else
{
@@ -218,19 +212,19 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
for (const std::string &path : Doxygen::inputPaths)
{
QCString inc = QCString("-I")+path.data();
- argv[argc]=qstrdup(inc.data());
+ argv[argc++]=qstrdup(inc.data());
//printf("argv[%d]=%s\n",argc,argv[argc]);
}
// add external include paths
- for (uint i=0;i<includePath.count();i++)
+ for (size_t i=0;i<includePath.size();i++)
{
- QCString inc = QCString("-I")+includePath.at(i);
+ QCString inc = QCString("-I")+includePath[i].c_str();
argv[argc++]=qstrdup(inc.data());
}
// user specified options
- for (uint i=0;i<clangOptions.count();i++)
+ for (size_t i=0;i<clangOptions.size();i++)
{
- argv[argc++]=qstrdup(clangOptions.at(i));
+ argv[argc++]=qstrdup(clangOptions[i].c_str());
}
// extra options
argv[argc++]=qstrdup("-ferror-limit=0");
@@ -241,67 +235,63 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
// we use the source file to detected the language. Detection will fail if you
// pass a bunch of .h files containing ObjC code, and no sources :-(
SrcLangExt lang = getLanguageFromFileName(fileName);
- if (lang==SrcLangExt_ObjC || p->detectedLang!=ClangParser::Private::Detected_Cpp)
+ if (lang==SrcLangExt_ObjC || p->detectedLang!=DetectedLang::Cpp)
{
QCString fn = fileName;
- if (p->detectedLang==ClangParser::Private::Detected_Cpp &&
+ if (p->detectedLang!=DetectedLang::Cpp &&
(fn.right(4).lower()==".cpp" || fn.right(4).lower()==".cxx" ||
fn.right(3).lower()==".cc" || fn.right(2).lower()==".c"))
{ // fall back to C/C++ once we see an extension that indicates this
- p->detectedLang = ClangParser::Private::Detected_Cpp;
+ p->detectedLang = DetectedLang::Cpp;
}
else if (fn.right(3).lower()==".mm") // switch to Objective C++
{
- p->detectedLang = ClangParser::Private::Detected_ObjCpp;
+ p->detectedLang = DetectedLang::ObjCpp;
}
else if (fn.right(2).lower()==".m") // switch to Objective C
{
- p->detectedLang = ClangParser::Private::Detected_ObjC;
+ p->detectedLang = DetectedLang::ObjC;
}
}
- switch(p->detectedLang)
+ switch (p->detectedLang)
{
- case ClangParser::Private::Detected_Cpp:
- argv[argc++]=qstrdup("c++");
- break;
- case ClangParser::Private::Detected_ObjC:
- argv[argc++]=qstrdup("objective-c");
- break;
- case ClangParser::Private::Detected_ObjCpp:
- argv[argc++]=qstrdup("objective-c++");
- break;
+ case DetectedLang::Cpp: argv[argc++]=qstrdup("c++"); break;
+ case DetectedLang::ObjC: argv[argc++]=qstrdup("objective-c"); break;
+ case DetectedLang::ObjCpp: argv[argc++]=qstrdup("objective-c++"); break;
}
// provide the input and and its dependencies as unsaved files so we can
// pass the filtered versions
argv[argc++]=qstrdup(fileName);
}
- static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
//printf("source %s ----------\n%s\n-------------\n\n",
// fileName,p->source.data());
- int numUnsavedFiles = filesInTranslationUnit.count()+1;
+ int numUnsavedFiles = static_cast<int>(p->filesInSameTU.size()+1);
p->numFiles = numUnsavedFiles;
- p->sources = new QCString[numUnsavedFiles];
- p->ufs = new CXUnsavedFile[numUnsavedFiles];
+ p->sources.resize(numUnsavedFiles);
+ p->ufs.resize(numUnsavedFiles);
p->sources[0] = detab(fileToString(fileName,filterSourceFiles,TRUE));
p->ufs[0].Filename = qstrdup(fileName);
p->ufs[0].Contents = p->sources[0].data();
p->ufs[0].Length = p->sources[0].length();
- QStrListIterator it(filesInTranslationUnit);
+ p->fileMapping.insert({fileName.data(),0});
int i=1;
- for (it.toFirst();it.current() && i<numUnsavedFiles;++it,i++)
+ for (auto it = p->filesInSameTU.begin();
+ it != p->filesInSameTU.end() && i<numUnsavedFiles;
+ ++it, i++)
{
- p->fileMapping.insert(it.current(),new uint(i));
- p->sources[i] = detab(fileToString(it.current(),filterSourceFiles,TRUE));
- p->ufs[i].Filename = qstrdup(it.current());
+ p->fileMapping.insert({it->c_str(),static_cast<uint>(i)});
+ p->sources[i] = detab(fileToString(it->c_str(),filterSourceFiles,TRUE));
+ p->ufs[i].Filename = qstrdup(it->c_str());
p->ufs[i].Contents = p->sources[i].data();
p->ufs[i].Length = p->sources[i].length();
}
// let libclang do the actual parsing
p->tu = clang_parseTranslationUnit(p->index, 0,
- argv, argc, p->ufs, numUnsavedFiles,
+ argv, argc, p->ufs.data(), numUnsavedFiles,
CXTranslationUnit_DetailedPreprocessingRecord);
+ //printf(" tu=%p\n",p->tu);
// free arguments
for (i=0;i<argc;++i)
{
@@ -311,9 +301,6 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
if (p->tu)
{
- // filter out any includes not found by the clang parser
- determineInputFilesInSameTu(filesInTranslationUnit);
-
// show any warnings that the compiler produced
int n=clang_getNumDiagnostics(p->tu);
for (i=0; i!=n; ++i)
@@ -325,105 +312,74 @@ void ClangParser::start(const char *fileName,QStrList &filesInTranslationUnit)
clang_disposeString(string);
clang_disposeDiagnostic(diag);
}
-
- // create a source range for the given file
- QFileInfo fi(fileName);
- CXFile f = clang_getFile(p->tu, fileName);
- CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
- CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[0].Length);
- CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd);
-
- // produce a token stream for the file
- clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);
-
- // produce cursors for each token in the stream
- p->cursors=new CXCursor[p->numTokens];
- clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
}
else
{
p->tokens = 0;
p->numTokens = 0;
- p->cursors = 0;
- err("clang: Failed to parse translation unit %s\n",fileName);
- }
-}
-
-void ClangParser::switchToFile(const char *fileName)
-{
- if (p->tu)
- {
- delete[] p->cursors;
- clang_disposeTokens(p->tu,p->tokens,p->numTokens);
- p->tokens = 0;
- p->numTokens = 0;
- p->cursors = 0;
-
- QFileInfo fi(fileName);
- CXFile f = clang_getFile(p->tu, fileName);
- uint *pIndex=p->fileMapping.find(fileName);
- if (pIndex && *pIndex<p->numFiles)
- {
- uint i=*pIndex;
- //printf("switchToFile %s: len=%ld\n",fileName,p->ufs[i].Length);
- CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
- CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[i].Length);
- CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd);
-
- clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);
- p->cursors=new CXCursor[p->numTokens];
- clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors);
-
- p->curLine = 1;
- p->curToken = 0;
- }
- else
- {
- err("clang: Failed to find input file %s in mapping\n",fileName);
- }
+ p->cursors.clear();
+ err("clang: Failed to parse translation unit %s\n",qPrint(fileName));
}
}
-void ClangParser::finish()
+ClangTUParser::~ClangTUParser()
{
+ //printf("ClangTUParser::~ClangTUParser() tu=%p\n",p->tu);
static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
if (!clangAssistedParsing) return;
if (p->tu)
{
- //printf("ClangParser::finish()\n");
- delete[] p->cursors;
+ p->cursors.clear();
clang_disposeTokens(p->tu,p->tokens,p->numTokens);
clang_disposeTranslationUnit(p->tu);
clang_disposeIndex(p->index);
p->fileMapping.clear();
p->tokens = 0;
p->numTokens = 0;
- p->cursors = 0;
}
for (uint i=0;i<p->numFiles;i++)
{
free((void *)p->ufs[i].Filename);
}
- delete[] p->ufs;
- delete[] p->sources;
- p->ufs = 0;
- p->sources = 0;
+ p->ufs.clear();
+ p->sources.clear();
p->numFiles = 0;
p->tu = 0;
}
-int ClangParser::Private::getCurrentTokenLine()
+void ClangTUParser::switchToFile(FileDef *fd)
{
- uint l, c;
- if (numTokens==0) return 1;
- // guard against filters that reduce the number of lines
- if (curToken>=numTokens) curToken=numTokens-1;
- CXSourceLocation start = clang_getTokenLocation(tu,tokens[curToken]);
- clang_getSpellingLocation(start, 0, &l, &c, 0);
- return l;
+ //printf("ClangTUParser::switchToFile(%s)\n",qPrint(fd->absFilePath()));
+ if (p->tu)
+ {
+ p->cursors.clear();
+ clang_disposeTokens(p->tu,p->tokens,p->numTokens);
+ p->tokens = 0;
+ p->numTokens = 0;
+
+ CXFile f = clang_getFile(p->tu, fd->absFilePath());
+ auto it = p->fileMapping.find(fd->absFilePath().data());
+ if (it!=p->fileMapping.end() && it->second < p->numFiles)
+ {
+ uint i = it->second;
+ //printf("switchToFile %s: len=%ld\n",fileName,p->ufs[i].Length);
+ CXSourceLocation fileBegin = clang_getLocationForOffset(p->tu, f, 0);
+ CXSourceLocation fileEnd = clang_getLocationForOffset(p->tu, f, p->ufs[i].Length);
+ CXSourceRange fileRange = clang_getRange(fileBegin, fileEnd);
+
+ clang_tokenize(p->tu,fileRange,&p->tokens,&p->numTokens);
+ p->cursors.resize(p->numTokens);
+ clang_annotateTokens(p->tu,p->tokens,p->numTokens,p->cursors.data());
+ p->curToken = 0;
+ }
+ else
+ {
+ err("clang: Failed to find input file %s in mapping\n",qPrint(fd->absFilePath()));
+ }
+ }
}
-QCString ClangParser::lookup(uint line,const char *symbol)
+QCString ClangTUParser::lookup(uint line,const char *symbol)
{
//printf("ClangParser::lookup(%d,%s)\n",line,symbol);
QCString result;
@@ -431,19 +387,30 @@ QCString ClangParser::lookup(uint line,const char *symbol)
static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
if (!clangAssistedParsing) return result;
+ auto getCurrentTokenLine = [=]() -> uint
+ {
+ uint l, c;
+ if (p->numTokens==0) return 1;
+ // guard against filters that reduce the number of lines
+ if (p->curToken>=p->numTokens) p->curToken=p->numTokens-1;
+ CXSourceLocation start = clang_getTokenLocation(p->tu,p->tokens[p->curToken]);
+ clang_getSpellingLocation(start, 0, &l, &c, 0);
+ return l;
+ };
+
int sl = strlen(symbol);
- uint l = p->getCurrentTokenLine();
+ uint l = getCurrentTokenLine();
while (l>=line && p->curToken>0)
{
if (l==line) // already at the right line
{
p->curToken--; // linear search to start of the line
- l = p->getCurrentTokenLine();
+ l = getCurrentTokenLine();
}
else
{
p->curToken/=2; // binary search backward
- l = p->getCurrentTokenLine();
+ l = getCurrentTokenLine();
}
}
bool found=FALSE;
@@ -468,7 +435,7 @@ QCString ClangParser::lookup(uint line,const char *symbol)
{
break; // end of token stream
}
- l = p->getCurrentTokenLine();
+ l = getCurrentTokenLine();
clang_disposeString(tokenString);
tokenString = clang_getTokenSpelling(p->tu, p->tokens[p->curToken]);
ts = clang_getCString(tokenString);
@@ -505,7 +472,7 @@ QCString ClangParser::lookup(uint line,const char *symbol)
p->curToken++;
if (p->curToken<p->numTokens)
{
- l = p->getCurrentTokenLine();
+ l = getCurrentTokenLine();
}
}
//if (!found)
@@ -519,78 +486,23 @@ QCString ClangParser::lookup(uint line,const char *symbol)
return result;
}
-static QCString keywordToType(const char *keyword)
-{
- static bool init=TRUE;
- static QDict<void> flowKeywords(47);
- static QDict<void> typeKeywords(47);
- if (init)
- {
- flowKeywords.insert("break",(void*)0x8);
- flowKeywords.insert("case",(void*)0x8);
- flowKeywords.insert("catch",(void*)0x8);
- flowKeywords.insert("continue",(void*)0x8);
- flowKeywords.insert("default",(void*)0x8);
- flowKeywords.insert("do",(void*)0x8);
- flowKeywords.insert("else",(void*)0x8);
- flowKeywords.insert("finally",(void*)0x8);
- flowKeywords.insert("for",(void*)0x8);
- flowKeywords.insert("foreach",(void*)0x8);
- flowKeywords.insert("for each",(void*)0x8);
- flowKeywords.insert("goto",(void*)0x8);
- flowKeywords.insert("if",(void*)0x8);
- flowKeywords.insert("return",(void*)0x8);
- flowKeywords.insert("switch",(void*)0x8);
- flowKeywords.insert("throw",(void*)0x8);
- flowKeywords.insert("throws",(void*)0x8);
- flowKeywords.insert("try",(void*)0x8);
- flowKeywords.insert("while",(void*)0x8);
- flowKeywords.insert("@try",(void*)0x8);
- flowKeywords.insert("@catch",(void*)0x8);
- flowKeywords.insert("@finally",(void*)0x8);
-
- typeKeywords.insert("bool",(void*)0x8);
- typeKeywords.insert("char",(void*)0x8);
- typeKeywords.insert("double",(void*)0x8);
- typeKeywords.insert("float",(void*)0x8);
- typeKeywords.insert("int",(void*)0x8);
- typeKeywords.insert("long",(void*)0x8);
- typeKeywords.insert("object",(void*)0x8);
- typeKeywords.insert("short",(void*)0x8);
- typeKeywords.insert("signed",(void*)0x8);
- typeKeywords.insert("unsigned",(void*)0x8);
- typeKeywords.insert("void",(void*)0x8);
- typeKeywords.insert("wchar_t",(void*)0x8);
- typeKeywords.insert("size_t",(void*)0x8);
- typeKeywords.insert("boolean",(void*)0x8);
- typeKeywords.insert("id",(void*)0x8);
- typeKeywords.insert("SEL",(void*)0x8);
- typeKeywords.insert("string",(void*)0x8);
- typeKeywords.insert("nullptr",(void*)0x8);
- init=FALSE;
- }
- if (flowKeywords[keyword]) return "keywordflow";
- if (typeKeywords[keyword]) return "keywordtype";
- return "keyword";
-}
-static void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line)
+void ClangTUParser::writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line)
{
Definition *d = fd ? fd->getSourceDefinition(line) : 0;
if (d && d->isLinkable())
{
- g_currentDefinition=d;
- g_currentLine=line;
+ p->currentLine=line;
MemberDef *md = fd->getSourceMember(line);
if (md && md->isLinkable()) // link to member
{
- if (g_currentMemberDef!=md) // new member, start search for body
+ if (p->currentMemberDef!=md) // new member, start search for body
{
- g_searchForBody=TRUE;
- g_insideBody=FALSE;
- g_bracketCount=0;
+ p->searchForBody=TRUE;
+ p->insideBody=FALSE;
+ p->bracketCount=0;
}
- g_currentMemberDef=md;
+ p->currentMemberDef=md;
ol.writeLineNumber(md->getReference(),
md->getOutputFileBase(),
md->anchor(),
@@ -598,7 +510,7 @@ static void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line)
}
else // link to compound
{
- g_currentMemberDef=0;
+ p->currentMemberDef=0;
ol.writeLineNumber(d->getReference(),
d->getOutputFileBase(),
d->anchor(),
@@ -621,8 +533,8 @@ static void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line)
//printf("writeLineNumber(%d) g_searchForBody=%d\n",line,g_searchForBody);
}
-static void codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
- uint &line,uint &column,const char *fontClass=0)
+void ClangTUParser::codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
+ uint &line,uint &column,const char *fontClass)
{
if (fontClass) ol.startFontClass(fontClass);
const char *p=text,*sp=p;
@@ -657,7 +569,7 @@ static void codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
if (fontClass) ol.endFontClass();
}
-static void writeMultiLineCodeLink(CodeOutputInterface &ol,
+void ClangTUParser::writeMultiLineCodeLink(CodeOutputInterface &ol,
FileDef *fd,uint &line,uint &column,
Definition *d,
const char *text)
@@ -698,7 +610,7 @@ static void writeMultiLineCodeLink(CodeOutputInterface &ol,
}
}
-void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd,
+void ClangTUParser::linkInclude(CodeOutputInterface &ol,FileDef *fd,
uint &line,uint &column,const char *text)
{
QCString incName = text;
@@ -732,7 +644,7 @@ void ClangParser::linkInclude(CodeOutputInterface &ol,FileDef *fd,
}
}
-void ClangParser::linkMacro(CodeOutputInterface &ol,FileDef *fd,
+void ClangTUParser::linkMacro(CodeOutputInterface &ol,FileDef *fd,
uint &line,uint &column,const char *text)
{
MemberName *mn=Doxygen::functionNameLinkedMap->find(text);
@@ -751,7 +663,7 @@ void ClangParser::linkMacro(CodeOutputInterface &ol,FileDef *fd,
}
-void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
+void ClangTUParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
uint &line,uint &column,const char *text,int tokenIndex)
{
CXCursor c = p->cursors[tokenIndex];
@@ -782,11 +694,11 @@ void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
//}
if (d && d->isLinkable())
{
- if (g_insideBody &&
- g_currentMemberDef && d->definitionType()==Definition::TypeMember &&
- (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference
+ if (p->insideBody &&
+ p->currentMemberDef && d->definitionType()==Definition::TypeMember &&
+ (p->currentMemberDef!=d || p->currentLine<line)) // avoid self-reference
{
- addDocCrossReference(g_currentMemberDef,dynamic_cast<MemberDef *>(d));
+ addDocCrossReference(p->currentMemberDef,dynamic_cast<MemberDef *>(d));
}
writeMultiLineCodeLink(ol,fd,line,column,d,text);
}
@@ -797,45 +709,44 @@ void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
clang_disposeString(usr);
}
-static void detectFunctionBody(const char *s)
+void ClangTUParser::detectFunctionBody(const char *s)
{
//printf("punct=%s g_searchForBody=%d g_insideBody=%d g_bracketCount=%d\n",
// s,g_searchForBody,g_insideBody,g_bracketCount);
- if (g_searchForBody && (qstrcmp(s,":")==0 || qstrcmp(s,"{")==0)) // start of 'body' (: is for constructor)
+ if (p->searchForBody && (qstrcmp(s,":")==0 || qstrcmp(s,"{")==0)) // start of 'body' (: is for constructor)
{
- g_searchForBody=FALSE;
- g_insideBody=TRUE;
+ p->searchForBody=FALSE;
+ p->insideBody=TRUE;
}
- else if (g_searchForBody && qstrcmp(s,";")==0) // declaration only
+ else if (p->searchForBody && qstrcmp(s,";")==0) // declaration only
{
- g_searchForBody=FALSE;
- g_insideBody=FALSE;
+ p->searchForBody=FALSE;
+ p->insideBody=FALSE;
}
- if (g_insideBody && qstrcmp(s,"{")==0) // increase scoping level
+ if (p->insideBody && qstrcmp(s,"{")==0) // increase scoping level
{
- g_bracketCount++;
+ p->bracketCount++;
}
- if (g_insideBody && qstrcmp(s,"}")==0) // decrease scoping level
+ if (p->insideBody && qstrcmp(s,"}")==0) // decrease scoping level
{
- g_bracketCount--;
- if (g_bracketCount<=0) // got outside of function body
+ p->bracketCount--;
+ if (p->bracketCount<=0) // got outside of function body
{
- g_insideBody=FALSE;
- g_bracketCount=0;
+ p->insideBody=FALSE;
+ p->bracketCount=0;
}
}
}
-void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd)
+void ClangTUParser::writeSources(CodeOutputInterface &ol,FileDef *fd)
{
// (re)set global parser state
- g_currentDefinition=0;
- g_currentMemberDef=0;
- g_currentLine=0;
- g_searchForBody=FALSE;
- g_insideBody=FALSE;
- g_bracketCount=0;
+ p->currentMemberDef=0;
+ p->currentLine=0;
+ p->searchForBody=FALSE;
+ p->insideBody=FALSE;
+ p->bracketCount=0;
unsigned int line=1,column=1;
QCString lineNumber,lineAnchor;
@@ -939,49 +850,79 @@ void ClangParser::writeSources(CodeOutputInterface &ol,FileDef *fd)
ol.endCodeLine();
}
-ClangParser::ClangParser()
+//--------------------------------------------------------------------------
+
+class ClangParser::Private
{
- p = new Private;
+ public:
+ Private()
+ {
+ std::string error;
+ QCString clangCompileDatabase = Config_getString(CLANG_DATABASE_PATH);
+ // load a clang compilation database (https://clang.llvm.org/docs/JSONCompilationDatabase.html)
+ db = clang::tooling::CompilationDatabase::loadFromDirectory(clangCompileDatabase.data(), error);
+ if (clangCompileDatabase!="0" && db==nullptr)
+ {
+ // user specified a path, but DB file was not found
+ err("%s using clang compilation database path of: \"%s\"\n", error.c_str(),
+ clangCompileDatabase.data());
+ }
+ }
+
+ std::unique_ptr<clang::tooling::CompilationDatabase> db;
+};
+
+const clang::tooling::CompilationDatabase *ClangParser::database() const
+{
+ return p->db.get();
}
-ClangParser::~ClangParser()
+ClangParser::ClangParser() : p(std::make_unique<Private>())
{
- delete p;
}
-//--------------------------------------------------------------------------
-#else // use stubbed functionality in case libclang support is disabled.
+ClangParser::~ClangParser()
+{
+}
-void ClangParser::start(const char *,QStrList &)
+std::unique_ptr<ClangTUParser> ClangParser::createTUParser(const FileDef *fd) const
{
+ return std::make_unique<ClangTUParser>(*this,fd);
}
-void ClangParser::switchToFile(const char *)
+
+//--------------------------------------------------------------------------
+#else // use stubbed functionality in case libclang support is disabled.
+
+void ClangTUParser::switchToFile(FileDef *fd)
{
}
-void ClangParser::finish()
+void ClangTUParser::parse()
{
}
-QCString ClangParser::lookup(uint,const char *)
+QCString ClangTUParser::lookup(uint,const char *)
{
return "";
}
-void ClangParser::writeSources(CodeOutputInterface &,FileDef *)
+class ClangParser::Private
{
-}
+};
-ClangParser::ClangParser()
+ClangParser::ClangParser() : p(std::make_unique<Private>())
{
- p = NULL;
}
ClangParser::~ClangParser()
{
}
+std::unique_ptr<ClangTUParser> ClangParser::createTUParser(const FileDef *) const
+{
+ return nullptr;
+}
#endif
//--------------------------------------------------------------------------
diff --git a/src/clangparser.h b/src/clangparser.h
index 8bb9aba..8ee1bdb 100644
--- a/src/clangparser.h
+++ b/src/clangparser.h
@@ -3,39 +3,41 @@
#include <qcstring.h>
#include <qstrlist.h>
+#include "containers.h"
+#include <memory>
class CodeOutputInterface;
class FileDef;
+class ClangParser;
+class Definition;
-/** @brief Wrapper for to let libclang assisted parsing. */
-class ClangParser
+namespace clang { namespace tooling {
+ class CompilationDatabase;
+} }
+
+/** @brief Clang parser object for a single translation unit, which consists of a source file
+ * and the directly or indirectly included headers
+ */
+class ClangTUParser
{
public:
- /** Returns the one and only instance of the class */
- static ClangParser *instance();
-
- /** Start parsing a file.
- * @param[in] fileName The name of the file to parse.
- * @param[in,out] filesInTranslationUnit Other files that are
- * part of the input and included by the file.
- * The function will return a subset of the files,
- * only including the ones that were actually found
- * during parsing.
+ ClangTUParser(const ClangParser &parser,const FileDef *fd);
+ virtual ~ClangTUParser();
+
+ /** Parse the file given at construction time as a translation unit
+ * This file should already be preprocessed by doxygen preprocessor at the time of calling.
*/
- void start(const char *fileName,QStrList &filesInTranslationUnit);
+ void parse();
- /** Switches to another file within the translation unit started
- * with start().
+ /** Switches to another file within the translation unit started with start().
* @param[in] fileName The name of the file to switch to.
*/
- void switchToFile(const char *fileName);
+ void switchToFile(FileDef *fd);
- /** Finishes parsing a translation unit. Free any resources that
- * were needed for parsing.
- */
- void finish();
+ /** Returns the list of files for this translation unit */
+ StringVector filesInSameTU() const;
- /** Looks for \a symbol which should be found at \a line and
+ /** Looks for \a symbol which should be found at \a line.
* returns a clang unique reference to the symbol.
*/
QCString lookup(uint line,const char *symbol);
@@ -47,6 +49,13 @@ class ClangParser
void writeSources(CodeOutputInterface &ol,FileDef *fd);
private:
+ void detectFunctionBody(const char *s);
+ void writeLineNumber(CodeOutputInterface &ol,FileDef *fd,uint line);
+ void codifyLines(CodeOutputInterface &ol,FileDef *fd,const char *text,
+ uint &line,uint &column,const char *fontClass=0);
+ void writeMultiLineCodeLink(CodeOutputInterface &ol,
+ FileDef *fd,uint &line,uint &column,
+ Definition *d, const char *text);
void linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
uint &line,uint &column,
const char *text,int tokenIndex);
@@ -56,9 +65,25 @@ class ClangParser
void linkInclude(CodeOutputInterface &ol,FileDef *fd,
uint &line,uint &column,
const char *text);
- void determineInputFilesInSameTu(QStrList &filesInTranslationUnit);
+ ClangTUParser(const ClangTUParser &) = delete;
+ ClangTUParser &operator=(const ClangTUParser &) = delete;
+ class Private;
+ std::unique_ptr<Private> p;
+};
+
+/** @brief Wrapper for to let libclang assisted parsing. */
+class ClangParser
+{
+ friend class ClangTUParser;
+ public:
+ /** Returns the one and only instance of the class */
+ static ClangParser *instance();
+ std::unique_ptr<ClangTUParser> createTUParser(const FileDef *fd) const;
+
+ private:
+ const clang::tooling::CompilationDatabase *database() const;
class Private;
- Private *p;
+ std::unique_ptr<Private> p;
ClangParser();
virtual ~ClangParser();
static ClangParser *s_instance;
diff --git a/src/classdef.cpp b/src/classdef.cpp
index 5e300ce..5dee0dc 100644
--- a/src/classdef.cpp
+++ b/src/classdef.cpp
@@ -1431,7 +1431,8 @@ void ClassDefImpl::writeBriefDescription(OutputList &ol,bool exampleFlag) const
ol.writeString(" - ");
ol.popGeneratorState();
ol.generateDoc(briefFile(),briefLine(),this,0,
- briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ briefDescription(),TRUE,FALSE,0,
+ TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.pushGeneratorState();
ol.disable(OutputGenerator::RTF);
ol.writeString(" \n");
@@ -1462,7 +1463,8 @@ void ClassDefImpl::writeDetailedDocumentationBody(OutputList &ol) const
// repeat brief description
if (!briefDescription().isEmpty() && repeatBrief)
{
- ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
if (!briefDescription().isEmpty() && repeatBrief &&
!documentation().isEmpty())
@@ -1475,7 +1477,8 @@ void ClassDefImpl::writeDetailedDocumentationBody(OutputList &ol) const
// write documentation
if (!documentation().isEmpty())
{
- ol.generateDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,documentation(),TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
// write type constraints
writeTypeConstraints(ol,this,m_impl->typeConstraints);
@@ -1848,16 +1851,15 @@ void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const
if (m_impl->incInfo)
{
QCString nm;
- QStrList paths = Config_getList(STRIP_FROM_PATH);
- if (!paths.isEmpty() && m_impl->incInfo->fileDef)
+ const StringVector &paths = Config_getList(STRIP_FROM_PATH);
+ if (!paths.empty() && m_impl->incInfo->fileDef)
{
QCString abs = m_impl->incInfo->fileDef->absFilePath();
- const char *s = paths.first();
QCString potential;
unsigned int length = 0;
- while (s)
+ for (const auto &s : paths)
{
- QFileInfo info(s);
+ QFileInfo info(s.c_str());
if (info.exists())
{
QCString prefix = info.absFilePath().utf8();
@@ -1872,7 +1874,6 @@ void ClassDefImpl::writeIncludeFilesForSlice(OutputList &ol) const
length = prefix.length();
potential = abs.right(abs.length() - prefix.length());
}
- s = paths.next();
}
}
@@ -2574,7 +2575,8 @@ void ClassDefImpl::writeDeclarationLink(OutputList &ol,bool &found,const char *h
if (!briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
{
DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
- briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ briefDescription(),FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (rootNode && !rootNode->isEmpty())
{
ol.startMemberDescription(anchor());
diff --git a/src/commentcnv.l b/src/commentcnv.l
index e05634a..a7d74ef 100644
--- a/src/commentcnv.l
+++ b/src/commentcnv.l
@@ -870,6 +870,9 @@ MAILADR ("mailto:")?[a-z_A-Z0-9.+-]+"@"[a-z_A-Z0-9-]+("."[a-z_A-Z0-9\-]+)+[a-z
copyToOutput(yyscanner,yytext,(int)yyleng);
}
+<*>. {
+ copyToOutput(yyscanner,yytext,(int)yyleng);
+ }
%%
static void replaceCommentMarker(yyscan_t yyscanner,const char *s,int len)
diff --git a/src/commentscan.h b/src/commentscan.h
index be92920..a111352 100644
--- a/src/commentscan.h
+++ b/src/commentscan.h
@@ -3,8 +3,8 @@
* 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
+ * 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.
*
@@ -60,6 +60,7 @@ class CommentScanner
* @param[out] newEntryNeeded Boolean that is TRUE if the comment block parser
* finds that a the comment block finishes the entry and a new one
* needs to be started.
+ * @param[in] markdownEnabled Indicates if markdown specific processing should be done.
* @returns TRUE if the comment requires further processing. The
* parameter \a newEntryNeeded will typically be true in this case and
* \a position will indicate the offset inside the \a comment string
@@ -76,7 +77,8 @@ class CommentScanner
bool isInbody,
Protection &prot,
int &position,
- bool &newEntryNeeded
+ bool &newEntryNeeded,
+ bool markdownEnabled
);
void initGroupInfo(Entry *entry);
void enterFile(const char *fileName,int lineNr);
diff --git a/src/commentscan.l b/src/commentscan.l
index 309a334..a1dd0e1 100644
--- a/src/commentscan.l
+++ b/src/commentscan.l
@@ -3,8 +3,8 @@
* 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
- * granted. No representations are made about the suitability of this software
+ * 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.
*
@@ -24,12 +24,13 @@
%{
/*
- * includes
+ * includes
*/
#include <map>
#include <stack>
#include <string>
+#include <mutex>
#include <stdio.h>
#include <stdlib.h>
@@ -118,7 +119,6 @@ static bool handleHideReferencedByRelation(yyscan_t yyscanner,const QCString &,
static bool handleReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &);
static bool handleHideReferencesRelation(yyscan_t yyscanner,const QCString &, const QCStringList &);
static bool handleInternal(yyscan_t yyscanner,const QCString &, const QCStringList &);
-static bool handleLineBr(yyscan_t yyscanner,const QCString &, const QCStringList &);
static bool handleStatic(yyscan_t yyscanner,const QCString &, const QCStringList &);
static bool handlePure(yyscan_t yyscanner,const QCString &, const QCStringList &);
static bool handlePrivate(yyscan_t yyscanner,const QCString &, const QCStringList &);
@@ -144,156 +144,162 @@ static const char *stateToString(int state);
typedef bool (*DocCmdFunc)(yyscan_t yyscanner,const QCString &name, const QCStringList &optList);
+enum class CommandSpacing
+{
+ Invisible, // command sets some property but does not appear in the output.
+ Inline, // command appears inline in the output which can be a brief description.
+ Block // command starts a new paragraphs / ends a brief description.
+};
+
struct DocCmdMap
{
- DocCmdMap(DocCmdFunc h,bool b) : handler(h), endsBrief(b) {}
+ DocCmdMap(DocCmdFunc h,CommandSpacing s) : handler(h), spacing(s) {}
DocCmdFunc handler;
- bool endsBrief;
+ CommandSpacing spacing;
};
// map of command to handler function
static const std::map< std::string, DocCmdMap > docCmdMap =
{
- // command name handler function ends brief description
- { "brief", { &handleBrief, FALSE }},
- { "short", { &handleBrief, FALSE }},
- { "fn", { &handleFn, TRUE }},
- { "var", { &handleFn, TRUE }},
- { "typedef", { &handleFn, TRUE }},
- { "property", { &handleFn, TRUE }},
- { "def", { &handleDef, TRUE }},
- { "overload", { &handleOverload, FALSE }},
- { "enum", { &handleEnum, TRUE }},
- { "defgroup", { &handleDefGroup, TRUE }},
- { "addtogroup", { &handleAddToGroup, TRUE }},
- { "weakgroup", { &handleWeakGroup, TRUE }},
- { "namespace", { &handleNamespace, TRUE }},
- { "package", { &handlePackage, TRUE }},
- { "class", { &handleClass, TRUE }},
- { "headerfile", { &handleHeaderFile, FALSE }},
- { "protocol", { &handleProtocol, TRUE }},
- { "category", { &handleCategory, TRUE }},
- { "union", { &handleUnion, TRUE }},
- { "struct", { &handleStruct, TRUE }},
- { "interface", { &handleInterface, TRUE }},
- { "idlexcept", { &handleIdlException, TRUE }},
- { "page", { &handlePage, TRUE }},
- { "mainpage", { &handleMainpage, TRUE }},
- { "file", { &handleFile, TRUE }},
- { "dir", { &handleDir, TRUE }},
- { "example", { &handleExample, FALSE }},
- { "details", { &handleDetails, TRUE }},
- { "name", { &handleName, FALSE }},
- { "todo", { &handleTodo, FALSE }}, // end brief will be done differently
- { "test", { &handleTest, FALSE }}, // end brief will be done differently
- { "bug", { &handleBug, FALSE }}, // end brief will be done differently
- { "deprecated", { &handleDeprecated, FALSE }}, // end brief will be done differently
- { "xrefitem", { &handleXRefItem, FALSE }}, // end brief will be done differently
- { "related", { &handleRelated, TRUE }},
- { "relates", { &handleRelated, TRUE }},
- { "relatedalso", { &handleRelatedAlso, TRUE }},
- { "relatesalso", { &handleRelatedAlso, TRUE }},
- { "parblock", { &handleParBlock, TRUE }},
- { "endparblock", { &handleEndParBlock, TRUE }},
- { "refitem", { &handleRefItem, TRUE }},
- { "cite", { &handleCite, FALSE }},
- { "subpage", { &handleSubpage, TRUE }},
- { "section", { &handleSection, TRUE }},
- { "subsection", { &handleSection, TRUE }},
- { "subsubsection", { &handleSection, TRUE }},
- { "paragraph", { &handleSection, TRUE }},
- { "anchor", { &handleAnchor, TRUE }},
- { "verbatim", { &handleFormatBlock, TRUE }},
- { "latexonly", { &handleFormatBlock, FALSE }},
- { "htmlonly", { &handleFormatBlock, FALSE }},
- { "xmlonly", { &handleFormatBlock, FALSE }},
- { "docbookonly", { &handleFormatBlock, FALSE }},
- { "rtfonly", { &handleFormatBlock, FALSE }},
- { "manonly", { &handleFormatBlock, FALSE }},
- { "dot", { &handleFormatBlock, TRUE }},
- { "msc", { &handleFormatBlock, TRUE }},
- { "startuml", { &handleFormatBlock, TRUE }},
- { "code", { &handleFormatBlock, TRUE }},
- { "addindex", { &handleAddIndex, FALSE }},
- { "if", { &handleIf, FALSE }},
- { "ifnot", { &handleIfNot, FALSE }},
- { "elseif", { &handleElseIf, FALSE }},
- { "else", { &handleElse, FALSE }},
- { "endif", { &handleEndIf, FALSE }},
- { "ingroup", { &handleIngroup, TRUE }},
- { "nosubgrouping", { &handleNoSubGrouping, FALSE }},
- { "showinitializer", { &handleShowInitializer, FALSE }},
- { "hideinitializer", { &handleHideInitializer, FALSE }},
- { "callgraph", { &handleCallgraph, FALSE }},
- { "hidecallgraph", { &handleHideCallgraph, FALSE }},
- { "callergraph", { &handleCallergraph, FALSE }},
- { "hidecallergraph", { &handleHideCallergraph, FALSE }},
- { "showrefby", { &handleReferencedByRelation, FALSE }},
- { "hiderefby", { &handleHideReferencedByRelation, FALSE }},
- { "showrefs", { &handleReferencesRelation, FALSE }},
- { "hiderefs", { &handleHideReferencesRelation, FALSE }},
- { "internal", { &handleInternal, TRUE }},
- { "_linebr", { &handleLineBr, FALSE }},
- { "static", { &handleStatic, FALSE }},
- { "pure", { &handlePure, FALSE }},
- { "private", { &handlePrivate, FALSE }},
- { "privatesection", { &handlePrivateSection, FALSE }},
- { "protected", { &handleProtected, FALSE }},
- { "protectedsection",{ &handleProtectedSection, FALSE }},
- { "public", { &handlePublic, FALSE }},
- { "publicsection", { &handlePublicSection, FALSE }},
- { "tableofcontents", { &handleToc, FALSE }},
- { "inherit", { &handleInherit, TRUE }},
- { "extends", { &handleExtends, TRUE }},
- { "implements", { &handleExtends, TRUE }},
- { "memberof", { &handleMemberOf, TRUE }},
- { "arg", { 0, TRUE }},
- { "attention", { 0, TRUE }},
- { "author", { 0, TRUE }},
- { "authors", { 0, TRUE }},
- { "copydoc", { &handleCopyDoc, TRUE }},
- { "copybrief", { &handleCopyBrief, FALSE }},
- { "copydetails", { &handleCopyDetails, TRUE }},
- { "copyright", { 0, TRUE }},
- { "date", { 0, TRUE }},
- { "dotfile", { 0, TRUE }},
- { "htmlinclude", { 0, FALSE }},
- { "image", { 0, TRUE }},
- { "include", { 0, TRUE }},
- { "includelineno", { 0, TRUE }},
- { "invariant", { 0, TRUE }},
- { "latexinclude", { 0, FALSE }},
- { "li", { 0, TRUE }},
- { "line", { 0, TRUE }},
- { "note", { 0, TRUE }},
- { "par", { 0, TRUE }},
- { "param", { &handleParam, TRUE }},
- { "tparam", { 0, TRUE }},
- { "post", { 0, TRUE }},
- { "pre", { 0, TRUE }},
- { "remark", { 0, TRUE }},
- { "remarks", { 0, TRUE }},
- { "result", { 0, TRUE }},
- { "return", { 0, TRUE }},
- { "returns", { 0, TRUE }},
- { "exception", { 0, TRUE }},
- { "retval", { &handleRetval, TRUE }},
- { "sa", { 0, TRUE }},
- { "see", { 0, TRUE }},
- { "since", { 0, TRUE }},
- { "throw", { 0, TRUE }},
- { "throws", { 0, TRUE }},
- { "until", { 0, TRUE }},
- { "verbinclude", { 0, FALSE }},
- { "version", { 0, TRUE }},
- { "warning", { 0, TRUE }},
- { "snippet", { 0, TRUE }},
- { "snippetlineno", { 0, TRUE }},
- { "noop", { &handleNoop, TRUE }},
- { "rtfinclude", { 0, FALSE }},
- { "docbookinclude", { 0, FALSE }},
- { "maninclude", { 0, FALSE }},
- { "xmlinclude", { 0, FALSE }}
+ // command name handler function command spacing
+ { "addindex", { &handleAddIndex, CommandSpacing::Invisible }},
+ { "addtogroup", { &handleAddToGroup, CommandSpacing::Invisible }},
+ { "anchor", { &handleAnchor, CommandSpacing::Invisible }},
+ { "arg", { 0, CommandSpacing::Block }},
+ { "attention", { 0, CommandSpacing::Block }},
+ { "author", { 0, CommandSpacing::Block }},
+ { "authors", { 0, CommandSpacing::Block }},
+ { "brief", { &handleBrief, CommandSpacing::Invisible }},
+ { "bug", { &handleBug, CommandSpacing::Block }},
+ { "callergraph", { &handleCallergraph, CommandSpacing::Invisible }},
+ { "callgraph", { &handleCallgraph, CommandSpacing::Invisible }},
+ { "category", { &handleCategory, CommandSpacing::Invisible }},
+ { "cite", { &handleCite, CommandSpacing::Inline }},
+ { "class", { &handleClass, CommandSpacing::Invisible }},
+ { "code", { &handleFormatBlock, CommandSpacing::Block }},
+ { "copybrief", { &handleCopyBrief, CommandSpacing::Invisible }},
+ { "copydetails", { &handleCopyDetails, CommandSpacing::Block }},
+ { "copydoc", { &handleCopyDoc, CommandSpacing::Block }},
+ { "copyright", { 0, CommandSpacing::Block }},
+ { "date", { 0, CommandSpacing::Block }},
+ { "def", { &handleDef, CommandSpacing::Invisible }},
+ { "defgroup", { &handleDefGroup, CommandSpacing::Invisible }},
+ { "deprecated", { &handleDeprecated, CommandSpacing::Block }},
+ { "details", { &handleDetails, CommandSpacing::Block }},
+ { "dir", { &handleDir, CommandSpacing::Invisible }},
+ { "docbookinclude", { 0, CommandSpacing::Inline }},
+ { "docbookonly", { &handleFormatBlock, CommandSpacing::Invisible }},
+ { "dot", { &handleFormatBlock, CommandSpacing::Block }},
+ { "dotfile", { 0, CommandSpacing::Block }},
+ { "else", { &handleElse, CommandSpacing::Inline }},
+ { "elseif", { &handleElseIf, CommandSpacing::Inline }},
+ { "endif", { &handleEndIf, CommandSpacing::Inline }},
+ { "endparblock", { &handleEndParBlock, CommandSpacing::Block }},
+ { "enum", { &handleEnum, CommandSpacing::Invisible }},
+ { "example", { &handleExample, CommandSpacing::Invisible }},
+ { "exception", { 0, CommandSpacing::Block }},
+ { "extends", { &handleExtends, CommandSpacing::Invisible }},
+ { "file", { &handleFile, CommandSpacing::Invisible }},
+ { "fn", { &handleFn, CommandSpacing::Invisible }},
+ { "headerfile", { &handleHeaderFile, CommandSpacing::Invisible }},
+ { "hidecallergraph", { &handleHideCallergraph, CommandSpacing::Invisible }},
+ { "hidecallgraph", { &handleHideCallgraph, CommandSpacing::Invisible }},
+ { "hideinitializer", { &handleHideInitializer, CommandSpacing::Invisible }},
+ { "hiderefby", { &handleHideReferencedByRelation, CommandSpacing::Invisible }},
+ { "hiderefs", { &handleHideReferencesRelation, CommandSpacing::Invisible }},
+ { "htmlinclude", { 0, CommandSpacing::Inline }},
+ { "htmlonly", { &handleFormatBlock, CommandSpacing::Invisible }},
+ { "idlexcept", { &handleIdlException, CommandSpacing::Invisible }},
+ { "if", { &handleIf, CommandSpacing::Inline }},
+ { "ifnot", { &handleIfNot, CommandSpacing::Inline }},
+ { "image", { 0, CommandSpacing::Block }},
+ { "implements", { &handleExtends, CommandSpacing::Invisible }},
+ { "include", { 0, CommandSpacing::Block }},
+ { "includelineno", { 0, CommandSpacing::Block }},
+ { "ingroup", { &handleIngroup, CommandSpacing::Invisible }},
+ { "inherit", { &handleInherit, CommandSpacing::Invisible }},
+ { "interface", { &handleInterface, CommandSpacing::Invisible }},
+ { "internal", { &handleInternal, CommandSpacing::Block }},
+ { "invariant", { 0, CommandSpacing::Block }},
+ { "latexinclude", { 0, CommandSpacing::Inline }},
+ { "latexonly", { &handleFormatBlock, CommandSpacing::Invisible }},
+ { "li", { 0, CommandSpacing::Block }},
+ { "line", { 0, CommandSpacing::Invisible }},
+ { "mainpage", { &handleMainpage, CommandSpacing::Invisible }},
+ { "maninclude", { 0, CommandSpacing::Inline }},
+ { "manonly", { &handleFormatBlock, CommandSpacing::Invisible }},
+ { "memberof", { &handleMemberOf, CommandSpacing::Invisible }},
+ { "msc", { &handleFormatBlock, CommandSpacing::Block }},
+ { "name", { &handleName, CommandSpacing::Invisible }},
+ { "namespace", { &handleNamespace, CommandSpacing::Invisible }},
+ { "noop", { &handleNoop, CommandSpacing::Invisible }},
+ { "nosubgrouping", { &handleNoSubGrouping, CommandSpacing::Invisible }},
+ { "note", { 0, CommandSpacing::Block }},
+ { "overload", { &handleOverload, CommandSpacing::Invisible }},
+ { "package", { &handlePackage, CommandSpacing::Invisible }},
+ { "page", { &handlePage, CommandSpacing::Invisible }},
+ { "par", { 0, CommandSpacing::Block }},
+ { "paragraph", { &handleSection, CommandSpacing::Block }},
+ { "param", { &handleParam, CommandSpacing::Block }},
+ { "parblock", { &handleParBlock, CommandSpacing::Block }},
+ { "post", { 0, CommandSpacing::Block }},
+ { "pre", { 0, CommandSpacing::Block }},
+ { "private", { &handlePrivate, CommandSpacing::Invisible }},
+ { "privatesection", { &handlePrivateSection, CommandSpacing::Invisible }},
+ { "property", { &handleFn, CommandSpacing::Invisible }},
+ { "protected", { &handleProtected, CommandSpacing::Invisible }},
+ { "protectedsection",{ &handleProtectedSection, CommandSpacing::Invisible }},
+ { "protocol", { &handleProtocol, CommandSpacing::Invisible }},
+ { "public", { &handlePublic, CommandSpacing::Invisible }},
+ { "publicsection", { &handlePublicSection, CommandSpacing::Invisible }},
+ { "pure", { &handlePure, CommandSpacing::Invisible }},
+ { "refitem", { &handleRefItem, CommandSpacing::Inline }},
+ { "related", { &handleRelated, CommandSpacing::Invisible }},
+ { "relatedalso", { &handleRelatedAlso, CommandSpacing::Invisible }},
+ { "relates", { &handleRelated, CommandSpacing::Invisible }},
+ { "relatesalso", { &handleRelatedAlso, CommandSpacing::Invisible }},
+ { "remark", { 0, CommandSpacing::Block }},
+ { "remarks", { 0, CommandSpacing::Block }},
+ { "result", { 0, CommandSpacing::Block }},
+ { "return", { 0, CommandSpacing::Block }},
+ { "returns", { 0, CommandSpacing::Block }},
+ { "retval", { &handleRetval, CommandSpacing::Block }},
+ { "rtfinclude", { 0, CommandSpacing::Inline }},
+ { "rtfonly", { &handleFormatBlock, CommandSpacing::Invisible }},
+ { "sa", { 0, CommandSpacing::Block }},
+ { "section", { &handleSection, CommandSpacing::Block }},
+ { "see", { 0, CommandSpacing::Block }},
+ { "short", { &handleBrief, CommandSpacing::Invisible }},
+ { "showinitializer", { &handleShowInitializer, CommandSpacing::Invisible }},
+ { "showrefby", { &handleReferencedByRelation, CommandSpacing::Invisible }},
+ { "showrefs", { &handleReferencesRelation, CommandSpacing::Invisible }},
+ { "since", { 0, CommandSpacing::Block }},
+ { "snippet", { 0, CommandSpacing::Block }},
+ { "snippetlineno", { 0, CommandSpacing::Block }},
+ { "startuml", { &handleFormatBlock, CommandSpacing::Block }},
+ { "static", { &handleStatic, CommandSpacing::Invisible }},
+ { "struct", { &handleStruct, CommandSpacing::Invisible }},
+ { "subpage", { &handleSubpage, CommandSpacing::Inline }},
+ { "subsection", { &handleSection, CommandSpacing::Block }},
+ { "subsubsection", { &handleSection, CommandSpacing::Block }},
+ { "tableofcontents", { &handleToc, CommandSpacing::Invisible }},
+ { "test", { &handleTest, CommandSpacing::Block }},
+ { "throw", { 0, CommandSpacing::Block }},
+ { "throws", { 0, CommandSpacing::Block }},
+ { "todo", { &handleTodo, CommandSpacing::Block }},
+ { "tparam", { 0, CommandSpacing::Block }},
+ { "typedef", { &handleFn, CommandSpacing::Invisible }},
+ { "union", { &handleUnion, CommandSpacing::Invisible }},
+ { "until", { 0, CommandSpacing::Block }},
+ { "var", { &handleFn, CommandSpacing::Invisible }},
+ { "verbatim", { &handleFormatBlock, CommandSpacing::Block }},
+ { "verbinclude", { 0, CommandSpacing::Inline }},
+ { "version", { 0, CommandSpacing::Block }},
+ { "warning", { 0, CommandSpacing::Block }},
+ { "weakgroup", { &handleWeakGroup, CommandSpacing::Invisible }},
+ { "xmlinclude", { 0, CommandSpacing::Inline }},
+ { "xmlonly", { &handleFormatBlock, CommandSpacing::Invisible }},
+ { "xrefitem", { &handleXRefItem, CommandSpacing::Block }}
};
#define YY_NO_INPUT 1
@@ -329,11 +335,11 @@ enum GuardType
class GuardedSection
{
public:
- GuardedSection(bool enabled,bool parentVisible)
+ GuardedSection(bool enabled,bool parentVisible)
: m_enabled(enabled),m_parentVisible(parentVisible) {}
bool isEnabled() const { return m_enabled; }
bool parentVisible() const { return m_parentVisible; }
-
+
private:
bool m_enabled;
bool m_parentVisible;
@@ -341,13 +347,14 @@ class GuardedSection
/* -----------------------------------------------------------------
*
- * statics
+ * statics
*/
struct commentscanYY_state
{
OutlineParserInterface *langParser = 0; // the language parser that is calling us
QCString inputString; // input string
+ QCString currentCmd; // the command used
int inputPosition = 0; // read pointer
QCString fileName; // file name that is read from
int lineNr = 0; // line number in the input
@@ -398,8 +405,16 @@ struct commentscanYY_state
bool inInternalDocs = FALSE;
int prevPosition = 0;
DocGroup docGroup;
+ bool markdownSupport = TRUE;
};
+
+#if MULTITHREADED_INPUT
+static std::mutex g_sectionMutex;
+static std::mutex g_formulaMutex;
+static std::mutex g_citeMutex;
+#endif
+
//-----------------------------------------------------------------------------
static QCString stripQuotes(const char *s);
@@ -428,20 +443,20 @@ static void addCite(yyscan_t yyscanner);
//-----------------------------------------------------------------------------
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) result=yyread(yyscanner,buf,max_size);
%}
/* start command character */
-CMD ("\\"|"@")
-XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem")
+CMD ("\\"|"@")
+XREFCMD {CMD}("bug"|"deprecated"|"test"|"todo"|"xrefitem")
PRE [pP][rR][eE]
-TABLE [tT][aA][bB][lL][eE]
-P [pP]
+TABLE [tT][aA][bB][lL][eE]
+P [pP]
UL [uU][lL]
-OL [oO][lL]
-DL [dD][lL]
+OL [oO][lL]
+DL [dD][lL]
IMG [iI][mM][gG]
HR [hH][rR]
PARA [pP][aA][rR][aA]
@@ -452,13 +467,13 @@ DIV [dD][iI][vV]
DETAILEDHTML {CENTER}|{DIV}|{PRE}|{UL}|{TABLE}|{OL}|{DL}|{P}|[Hh][1-6]|{IMG}|{HR}|{PARA}
DETAILEDHTMLOPT {CODE}
BN [ \t\n\r]
-BL [ \t\r]*"\n"
+BL [ \t\r]*"\n"
B [ \t]
BS ^(({B}*"//")?)(({B}*"*"+)?){B}*
ATTR ({B}+[^>\n]*)?
-DOCNL "\n"|"\\_linebr"
+DOCNL "\n"|"\\ilinebr"
LC "\\"{B}*"\n"
-NW [^a-z_A-Z0-9]
+NW [^a-z_A-Z0-9]
FILESCHAR [a-z_A-Z0-9\x80-\xFF\\:\\\/\-\+@&#]
FILEECHAR [a-z_A-Z0-9\x80-\xFF\-\+@&#]
FILE ({FILESCHAR}*{FILEECHAR}+("."{FILESCHAR}*{FILEECHAR}+)*)|("\""[^\n\"]*"\"")
@@ -470,7 +485,7 @@ CITEID {CITESCHAR}{CITEECHAR}*("."{CITESCHAR}{CITEECHAR}*)*|"\""{CITESCHAR}{C
SCOPEID {ID}({ID}*{BN}*"::"{BN}*)*({ID}?)
SCOPENAME "$"?(({ID}?{BN}*("::"|"."){BN}*)*)((~{BN}*)?{ID})
TMPLSPEC "<"{BN}*[^>]+{BN}*">"
-MAILADDR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+
+MAILADDR [a-z_A-Z0-9.+\-]+"@"[a-z_A-Z0-9\-]+("."[a-z_A-Z0-9\-]+)+[a-z_A-Z0-9\-]+
RCSTAG "$"{ID}":"[^\n$]+"$"
%option noyywrap
@@ -489,34 +504,34 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
%x XRefItemParam3
%x FileDocArg1
%x ParamArg1
-%x EnumDocArg1
-%x NameSpaceDocArg1
-%x PackageDocArg1
-%x GroupDocArg1
-%x GroupDocArg2
-%x SectionLabel
-%x SectionTitle
-%x SubpageLabel
-%x SubpageTitle
-%x FormatBlock
-%x LineParam
-%x GuardParam
-%x GuardParamEnd
-%x SkipGuardedSection
-%x SkipInternal
+%x EnumDocArg1
+%x NameSpaceDocArg1
+%x PackageDocArg1
+%x GroupDocArg1
+%x GroupDocArg2
+%x SectionLabel
+%x SectionTitle
+%x SubpageLabel
+%x SubpageTitle
+%x FormatBlock
+%x LineParam
+%x GuardParam
+%x GuardParamEnd
+%x SkipGuardedSection
+%x SkipInternal
%x NameParam
-%x InGroupParam
-%x FnParam
-%x OverloadParam
-%x InheritParam
-%x ExtendsParam
+%x InGroupParam
+%x FnParam
+%x OverloadParam
+%x InheritParam
+%x ExtendsParam
%x ReadFormulaShort
-%x ReadFormulaLong
-%x AnchorLabel
+%x ReadFormulaLong
+%x AnchorLabel
%x HtmlComment
%x SkipLang
-%x CiteLabel
-%x CopyDoc
+%x CiteLabel
+%x CopyDoc
%x GuardExpr
%x CdataSection
%x Noop
@@ -540,52 +555,52 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
* XML commands, <summary></summary><remarks></remarks>
*/
-<Comment>{CMD}{CMD}[a-z_A-Z]+{B}* { // escaped command
- addOutput(yyscanner,yytext);
- }
-<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
- addOutput(yyscanner,yytext);
- }
-<Comment>{MAILADDR} { // mail address
- addOutput(yyscanner,yytext);
- }
-<Comment>"\""[^"\n]*"\"" { // quoted text
+<Comment>{CMD}{CMD}[a-z_A-Z]+{B}* { // escaped command
+ addOutput(yyscanner,yytext);
+ }
+<Comment>{CMD}{CMD}"~"[a-z_A-Z]* { // escaped command
+ addOutput(yyscanner,yytext);
+ }
+<Comment>{MAILADDR} { // mail address
+ addOutput(yyscanner,yytext);
+ }
+<Comment>"\""[^"\n]*"\"" { // quoted text
+ addOutput(yyscanner,yytext);
+ }
+<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
addOutput(yyscanner,yytext);
- }
-<Comment>("\\"[a-z_A-Z]+)+"\\" { // directory (or chain of commands!)
- addOutput(yyscanner,yytext);
- }
-<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
- setOutput(yyscanner,OutputDoc);
- // continue with the same input
+ }
+<Comment>"<"{DETAILEDHTML}{ATTR}">" { // HTML command that ends a brief description
+ setOutput(yyscanner,OutputDoc);
+ // continue with the same input
REJECT;
- }
-<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML command that ends a brief description
- if (yyextra->current->lang==SrcLangExt_CSharp)
+ }
+<Comment>"<"{DETAILEDHTMLOPT}{ATTR}">" { // HTML command that ends a brief description
+ if (yyextra->current->lang==SrcLangExt_CSharp)
{
setOutput(yyscanner,OutputDoc);
}
- // continue with the same input
+ // continue with the same input
REJECT;
- }
-<Comment>"<summary>" { // start of a .NET XML style brief description
- setOutput(yyscanner,OutputBrief);
+ }
+<Comment>"<summary>" { // start of a .NET XML style brief description
+ setOutput(yyscanner,OutputBrief);
addOutput(yyscanner,yytext);
- }
-<Comment>"<remarks>" { // start of a .NET XML style detailed description
- setOutput(yyscanner,OutputDoc);
+ }
+<Comment>"<remarks>" { // start of a .NET XML style detailed description
+ setOutput(yyscanner,OutputDoc);
addOutput(yyscanner,yytext);
- }
-<Comment>"</summary>" { // start of a .NET XML style detailed description
- setOutput(yyscanner,OutputBrief);
+ }
+<Comment>"</summary>" { // start of a .NET XML style detailed description
+ setOutput(yyscanner,OutputBrief);
addOutput(yyscanner,yytext);
- setOutput(yyscanner,OutputDoc);
- }
-<Comment>"</remarks>" { // end of a brief or detailed description
-
- setOutput(yyscanner,OutputDoc);
+ setOutput(yyscanner,OutputDoc);
+ }
+<Comment>"</remarks>" { // end of a brief or detailed description
+
+ setOutput(yyscanner,OutputDoc);
addOutput(yyscanner,yytext);
- }
+ }
<Comment>"<"{CAPTION}{ATTR}">" {
QCString tag=yytext;
int s=tag.find("id=");
@@ -616,22 +631,25 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
setOutput(yyscanner,OutputDoc);
REJECT;
}
-<Comment>"<!--" {
+<Comment>"<!--" {
BEGIN(HtmlComment);
}
<Comment>"<!\[CDATA\[" {
BEGIN(CdataSection);
}
-<Comment>{B}*{CMD}"endinternal"{B}* {
- addOutput(yyscanner," \\endinternal ");
+<Comment>{B}*{CMD}"endinternal"{B}* {
+ addOutput(yyscanner," \\endinternal ");
if (!yyextra->inInternalDocs)
- warn(yyextra->fileName,yyextra->lineNr,
+ warn(yyextra->fileName,yyextra->lineNr,
"found \\endinternal without matching \\internal"
);
yyextra->inInternalDocs = FALSE;
- }
+ }
+<Comment>{B}*"\\ilinebr"{B}* { // preserve spacing around \\ilinebr
+ addOutput(yyscanner,yytext);
+ }
<Comment>{B}*{CMD}[a-z_A-Z]+"{"[a-zA-Z_,:0-9\. ]*"}"{B}* |
-<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
+<Comment>{B}*{CMD}[a-z_A-Z]+{B}* { // potentially interesting command
// the {B}* in the front was added for bug620924
QCString fullMatch = QCString(yytext);
int idx = fullMatch.find('{');
@@ -650,84 +668,84 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
QCString optStr = fullMatch.mid(idx+1,idxEnd-idx-1).stripWhiteSpace();
optList = QCStringList::split(',',optStr);
}
- auto it = docCmdMap.find(cmdName.data());
- if (it!=docCmdMap.end()) // special action is required
- {
+ auto it = docCmdMap.find(cmdName.data());
+ if (it!=docCmdMap.end()) // special action is required
+ {
int i=0;
while (yytext[i]==' ' || yytext[i]=='\t') i++;
- yyextra->spaceBeforeCmd = QCString(yytext).left(i);
- if (it->second.endsBrief && !(yyextra->inContext==OutputXRef && cmdName=="parblock"))
- {
- yyextra->briefEndsAtDot=FALSE;
- // this command forces the end of brief description
- setOutput(yyscanner,OutputDoc);
- }
+ yyextra->spaceBeforeCmd = QCString(yytext).left(i);
+ if (it->second.spacing==CommandSpacing::Block && !(yyextra->inContext==OutputXRef && cmdName=="parblock"))
+ {
+ yyextra->briefEndsAtDot=FALSE;
+ // this command forces the end of brief description
+ setOutput(yyscanner,OutputDoc);
+ }
//if (i>0) addOutput(yyscanner,QCString(yytext).left(i)); // removed for bug 689341
- if (it->second.handler && it->second.handler(yyscanner, cmdName, optList))
- {
- // implicit split of the comment block into two
- // entries. Restart the next block at the start
- // of this command.
- yyextra->parseMore=TRUE;
-
- // yuk, this is probably not very portable across lex implementations,
- // but we need to know the position in the input buffer where this
- // rule matched.
- // for flex 2.5.33+ we should use YY_CURRENT_BUFFER_LVALUE
+ if (it->second.handler && it->second.handler(yyscanner, cmdName, optList))
+ {
+ // implicit split of the comment block into two
+ // entries. Restart the next block at the start
+ // of this command.
+ yyextra->parseMore=TRUE;
+
+ // yuk, this is probably not very portable across lex implementations,
+ // but we need to know the position in the input buffer where this
+ // rule matched.
+ // for flex 2.5.33+ we should use YY_CURRENT_BUFFER_LVALUE
#if YY_FLEX_MAJOR_VERSION>=2 && (YY_FLEX_MINOR_VERSION>5 || (YY_FLEX_MINOR_VERSION==5 && YY_FLEX_SUBMINOR_VERSION>=33))
- yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
+ yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);
#else
- yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf);
+ yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf);
#endif
- yyterminate();
- }
- else if (it->second.handler==0)
- {
- // command without handler, to be processed
- // later by parsedoc.cpp
- addOutput(yyscanner,yytext);
- }
- }
- else // command not relevant
- {
- addOutput(yyscanner,yytext);
- }
- }
-<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command
- addOutput(yyscanner,yytext);
- }
-<Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command
+ yyterminate();
+ }
+ else if (it->second.handler==0)
+ {
+ // command without handler, to be processed
+ // later by parsedoc.cpp
+ addOutput(yyscanner,yytext);
+ }
+ }
+ else // command not relevant
+ {
+ addOutput(yyscanner,yytext);
+ }
+ }
+<Comment>{B}*({CMD}{CMD})"f"[$\[{] { // escaped formula command
+ addOutput(yyscanner,yytext);
+ }
+<Comment>{B}*{CMD}"~"[a-z_A-Z-]* { // language switch command
QCString langId = QCString(yytext).stripWhiteSpace().data()+2;
- if (!langId.isEmpty() &&
- qstricmp(Config_getEnum(OUTPUT_LANGUAGE),langId)!=0)
- { // enable language specific section
- BEGIN(SkipLang);
- }
- }
+ if (!langId.isEmpty() &&
+ qstricmp(Config_getEnum(OUTPUT_LANGUAGE),langId)!=0)
+ { // enable language specific section
+ BEGIN(SkipLang);
+ }
+ }
<Comment>{B}*{CMD}"f{"[^}\n]+"}"("{"?) { // start of a formula with custom environment
- setOutput(yyscanner,OutputDoc);
- yyextra->formulaText="\\begin";
- yyextra->formulaEnv=QCString(yytext).stripWhiteSpace().data()+2;
- if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{')
- {
- // remove trailing open brace
- yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1);
- }
- yyextra->formulaText+=yyextra->formulaEnv;
- yyextra->formulaNewLines=0;
- BEGIN(ReadFormulaLong);
- }
-<Comment>{B}*{CMD}"f$" { // start of a inline formula
- yyextra->formulaText="$";
- yyextra->formulaNewLines=0;
- BEGIN(ReadFormulaShort);
- }
-<Comment>{B}*{CMD}"f[" { // start of a block formula
- setOutput(yyscanner,OutputDoc);
- yyextra->formulaText="\\[";
- yyextra->formulaNewLines=0;
- BEGIN(ReadFormulaLong);
- }
+ setOutput(yyscanner,OutputDoc);
+ yyextra->formulaText="\\begin";
+ yyextra->formulaEnv=QCString(yytext).stripWhiteSpace().data()+2;
+ if (yyextra->formulaEnv.at(yyextra->formulaEnv.length()-1)=='{')
+ {
+ // remove trailing open brace
+ yyextra->formulaEnv=yyextra->formulaEnv.left(yyextra->formulaEnv.length()-1);
+ }
+ yyextra->formulaText+=yyextra->formulaEnv;
+ yyextra->formulaNewLines=0;
+ BEGIN(ReadFormulaLong);
+ }
+<Comment>{B}*{CMD}"f$" { // start of a inline formula
+ yyextra->formulaText="$";
+ yyextra->formulaNewLines=0;
+ BEGIN(ReadFormulaShort);
+ }
+<Comment>{B}*{CMD}"f[" { // start of a block formula
+ setOutput(yyscanner,OutputDoc);
+ yyextra->formulaText="\\[";
+ yyextra->formulaNewLines=0;
+ BEGIN(ReadFormulaLong);
+ }
<Comment>{B}*{CMD}"{" { // begin of a group
//yyextra->langParser->handleGroupStartCommand(yyextra->memberGroupHeader);
yyextra->docGroup.open(yyextra->current,yyextra->fileName,yyextra->lineNr);
@@ -735,51 +753,51 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
<Comment>{B}*{CMD}"}" { // end of a group
//yyextra->langParser->handleGroupEndCommand();
yyextra->docGroup.close(yyextra->current,yyextra->fileName,yyextra->lineNr,TRUE);
- yyextra->docGroup.clearHeader();
- yyextra->parseMore=TRUE;
+ yyextra->docGroup.clearHeader();
+ yyextra->parseMore=TRUE;
yyextra->needNewEntry = TRUE;
#if YY_FLEX_MAJOR_VERSION>=2 && (YY_FLEX_MINOR_VERSION>5 || (YY_FLEX_MINOR_VERSION==5 && YY_FLEX_SUBMINOR_VERSION>=33))
- yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext);
+ yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf) + (int)strlen(yytext);
#else
- yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf) + (int)strlen(yytext);
+ yyextra->inputPosition=yyextra->prevPosition + (int)(yy_bp - yy_current_buffer->yy_ch_buf) + (int)strlen(yytext);
#endif
- yyterminate();
- }
-<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
- addOutput(yyscanner,yytext);
- }
-<Comment>[a-z_A-Z]+ { // normal word
- addOutput(yyscanner,yytext);
- }
+ yyterminate();
+ }
+<Comment>{B}*{CMD}[$@\\&~<>#%] { // escaped character
+ addOutput(yyscanner,yytext);
+ }
+<Comment>[a-z_A-Z]+ { // normal word
+ addOutput(yyscanner,yytext);
+ }
<Comment>^{B}*"."{B}*/\n { // explicit end autolist: e.g " ."
- addOutput(yyscanner,yytext);
- }
+ addOutput(yyscanner,yytext);
+ }
<Comment>^{B}*[1-9][0-9]*"."{B}+ |
-<Comment>^{B}*[*+]{B}+ { // start of autolist
- if (!Doxygen::markdownSupport)
+<Comment>^{B}*[*+]{B}+ { // start of autolist
+ if (!yyextra->markdownSupport)
{
REJECT;
}
else
{
- if (yyextra->inContext!=OutputXRef)
+ if (yyextra->inContext!=OutputXRef)
{
yyextra->briefEndsAtDot=FALSE;
setOutput(yyscanner,OutputDoc);
}
- addOutput(yyscanner,yytext);
+ addOutput(yyscanner,yytext);
}
- }
-<Comment>^{B}*"-"{B}+ { // start of autolist
- if (yyextra->inContext!=OutputXRef)
- {
- yyextra->briefEndsAtDot=FALSE;
- setOutput(yyscanner,OutputDoc);
- }
- addOutput(yyscanner,yytext);
- }
+ }
+<Comment>^{B}*"-"{B}+ { // start of autolist
+ if (yyextra->inContext!=OutputXRef)
+ {
+ yyextra->briefEndsAtDot=FALSE;
+ setOutput(yyscanner,OutputDoc);
+ }
+ addOutput(yyscanner,yytext);
+ }
<Comment>^{B}*([\-:|]{B}*)*("--"|"---")({B}*[\-:|])*{B}*/\n { // horizontal line (dashed)
- addOutput(yyscanner,yytext);
+ addOutput(yyscanner,yytext);
}
<Comment>{CMD}"---" { // escaped mdash
addOutput(yyscanner,yytext);
@@ -788,10 +806,10 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
addOutput(yyscanner,yytext);
}
<Comment>"---" { // mdash
- addOutput(yyscanner,yyextra->insidePre || Doxygen::markdownSupport ? yytext : "&mdash;");
+ addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext : "&mdash;");
}
<Comment>"--" { // ndash
- addOutput(yyscanner,yyextra->insidePre || Doxygen::markdownSupport ? yytext : "&ndash;");
+ addOutput(yyscanner,yyextra->insidePre || yyextra->markdownSupport ? yytext : "&ndash;");
}
<Comment>"-#"{B}+ { // numbered item
if (yyextra->inContext!=OutputXRef)
@@ -801,85 +819,85 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
}
addOutput(yyscanner,yytext);
}
-<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
- addOutput(yyscanner,yytext);
- }
-<Comment>".\\"[ \t] { // . with escaped space.
- addOutput(yyscanner,yytext[0]);
- addOutput(yyscanner,yytext[2]);
- }
-<Comment>".," { // . with comma such as "e.g.,"
- addOutput(yyscanner,yytext);
- }
-<Comment>"...\\"[ \t] { // ellipsis with escaped space.
- addOutput(yyscanner,"... ");
- }
-<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
- addOutput(yyscanner,yytext);
- }
-<Comment>(\n|\\_linebr)({B}*(\n|\\_linebr))+ { // at least one blank line (or blank line command)
- if (yyextra->inContext==OutputXRef)
- {
- // see bug 613024, we need to put the newlines after ending the XRef section.
- if (!yyextra->insideParBlock) setOutput(yyscanner,OutputDoc);
+<Comment>("."+)[a-z_A-Z0-9\)] { // . at start or in the middle of a word, or ellipsis
+ addOutput(yyscanner,yytext);
+ }
+<Comment>".\\"[ \t] { // . with escaped space.
+ addOutput(yyscanner,yytext[0]);
+ addOutput(yyscanner,yytext[2]);
+ }
+<Comment>".," { // . with comma such as "e.g.,"
+ addOutput(yyscanner,yytext);
+ }
+<Comment>"...\\"[ \t] { // ellipsis with escaped space.
+ addOutput(yyscanner,"... ");
+ }
+<Comment>".."[\.]?/[^ \t\n] { // internal ellipsis
+ addOutput(yyscanner,yytext);
+ }
+<Comment>(\n|\\ilinebr)({B}*(\n|\\ilinebr))+ { // at least one blank line (or blank line command)
+ if (yyextra->inContext==OutputXRef)
+ {
+ // see bug 613024, we need to put the newlines after ending the XRef section.
+ if (!yyextra->insideParBlock) setOutput(yyscanner,OutputDoc);
yy_size_t i;
for (i=0;i<(yy_size_t)yyleng;)
{
if (yytext[i]=='\n') addOutput(yyscanner,'\n'),i++;
- else if (strcmp(yytext+i,"\\_linebr")==0) addOutput(yyscanner,'\n'),i+=8;
+ else if (strcmp(yytext+i,"\\ilinebr")==0) addOutput(yyscanner,"\\ilinebr"),i+=8;
else i++;
}
- }
- else if (yyextra->inContext!=OutputBrief)
- {
+ }
+ else if (yyextra->inContext!=OutputBrief)
+ {
yy_size_t i;
for (i=0;i<(yy_size_t)yyleng;)
{
if (yytext[i]=='\n') addOutput(yyscanner,'\n'),i++;
- else if (strcmp(yytext+i,"\\_linebr")==0) addOutput(yyscanner,'\n'),i+=8;
+ else if (strcmp(yytext+i,"\\ilinebr")==0) addOutput(yyscanner,"\\ilinebr"),i+=8;
else i++;
}
- setOutput(yyscanner,OutputDoc);
- }
- else // yyextra->inContext==OutputBrief
- { // only go to the detailed description if we have
- // found some brief description and not just whitespace
- endBrief(yyscanner,FALSE);
- }
- lineCount(yyscanner);
- }
-<Comment>"." { // potential end of a JavaDoc style comment
- addOutput(yyscanner,*yytext);
- if (yyextra->briefEndsAtDot)
- {
- setOutput(yyscanner,OutputDoc);
- yyextra->briefEndsAtDot=FALSE;
- }
- }
-<Comment>\n { // newline
- addOutput(yyscanner,*yytext);
- yyextra->lineNr++;
- }
-<Comment>. { // catch-all for anything else
- addOutput(yyscanner,*yytext);
- }
+ setOutput(yyscanner,OutputDoc);
+ }
+ else // yyextra->inContext==OutputBrief
+ { // only go to the detailed description if we have
+ // found some brief description and not just whitespace
+ endBrief(yyscanner,FALSE);
+ }
+ lineCount(yyscanner);
+ }
+<Comment>"." { // potential end of a JavaDoc style comment
+ addOutput(yyscanner,*yytext);
+ if (yyextra->briefEndsAtDot)
+ {
+ setOutput(yyscanner,OutputDoc);
+ yyextra->briefEndsAtDot=FALSE;
+ }
+ }
+<Comment>\n { // newline
+ addOutput(yyscanner,*yytext);
+ yyextra->lineNr++;
+ }
+<Comment>. { // catch-all for anything else
+ addOutput(yyscanner,*yytext);
+ }
/* -------------- Rules for handling HTML comments ----------- */
-<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
-<HtmlComment>{DOCNL} {
- if (*yytext=='\n') yyextra->lineNr++;
- }
-<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
- }
-<HtmlComment>. { // ignore every else
- }
+<HtmlComment>"--"[!]?">"{B}* { BEGIN( Comment ); }
+<HtmlComment>{DOCNL} {
+ if (*yytext=='\n') yyextra->lineNr++;
+ }
+<HtmlComment>[^\\\n\-]+ { // ignore unimportant characters
+ }
+<HtmlComment>. { // ignore every else
+ }
<CdataSection>"\]\]>" {
BEGIN( Comment );
}
-<CdataSection>{DOCNL} {
+<CdataSection>{DOCNL} {
addOutput(yyscanner,'\n');
if (*yytext=='\n') yyextra->lineNr++;
}
@@ -890,262 +908,272 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
<CdataSection>[^\\\n\]<>&]+ {
addOutput(yyscanner,yytext);
}
-<CdataSection>. {
+<CdataSection>. {
addOutput(yyscanner,*yytext);
}
/* -------------- Rules for handling formulas ---------------- */
-
-<ReadFormulaShort>{CMD}"f$" { // end of inline formula
- yyextra->formulaText+="$";
- addOutput(yyscanner," "+addFormula(yyscanner));
- BEGIN(Comment);
- }
-<ReadFormulaLong>{CMD}"f]" { // end of block formula
- yyextra->formulaText+="\\]";
- addOutput(yyscanner," "+addFormula(yyscanner));
- BEGIN(Comment);
- }
-<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
- yyextra->formulaText+="\\end";
- yyextra->formulaText+=yyextra->formulaEnv;
- addOutput(yyscanner," "+addFormula(yyscanner));
- BEGIN(Comment);
- }
+
+<ReadFormulaShort>{CMD}"f$" { // end of inline formula
+ yyextra->formulaText+="$";
+ addOutput(yyscanner," "+addFormula(yyscanner));
+ BEGIN(Comment);
+ }
+<ReadFormulaLong>{CMD}"f]" { // end of block formula
+ yyextra->formulaText+="\\]";
+ addOutput(yyscanner," "+addFormula(yyscanner));
+ BEGIN(Comment);
+ }
+<ReadFormulaLong>{CMD}"f}" { // end of custom env formula
+ yyextra->formulaText+="\\end";
+ yyextra->formulaText+=yyextra->formulaEnv;
+ addOutput(yyscanner," "+addFormula(yyscanner));
+ BEGIN(Comment);
+ }
<ReadFormulaLong,ReadFormulaShort>[^\\@\n]+ { // any non-special character
- yyextra->formulaText+=yytext;
- }
-<ReadFormulaLong,ReadFormulaShort>\n { // new line
+ yyextra->formulaText+=yytext;
+ }
+<ReadFormulaLong,ReadFormulaShort>\n { // new line
yyextra->formulaNewLines++;
- yyextra->formulaText+=*yytext;
- yyextra->lineNr++;
- }
+ yyextra->formulaText+=*yytext;
+ yyextra->lineNr++;
+ }
<ReadFormulaLong,ReadFormulaShort>. { // any other character
- yyextra->formulaText+=*yytext;
- }
+ yyextra->formulaText+=*yytext;
+ }
/* ------------ handle argument of enum command --------------- */
-<EnumDocArg1>{SCOPEID} { // handle argument
- yyextra->current->name = yytext;
- BEGIN( Comment );
- }
-<EnumDocArg1>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
+<EnumDocArg1>{SCOPEID} { // handle argument
+ yyextra->current->name = yytext;
+ BEGIN( Comment );
+ }
+<EnumDocArg1>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
}
-<EnumDocArg1>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
+<EnumDocArg1>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
"missing argument after \\enum."
);
- addOutput(yyscanner,'\n');
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<EnumDocArg1>. { // ignore other stuff
- }
+ unput('\n');
+ //addOutput(yyscanner,'\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ BEGIN( Comment );
+ }
+<EnumDocArg1>. { // ignore other stuff
+ }
/* ------------ handle argument of namespace command --------------- */
-<NameSpaceDocArg1>{SCOPENAME} { // handle argument
- yyextra->current->name = substitute(yytext,".","::");
- BEGIN( Comment );
- }
-<NameSpaceDocArg1>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
+<NameSpaceDocArg1>{SCOPENAME} { // handle argument
+ yyextra->current->name = substitute(yytext,".","::");
+ BEGIN( Comment );
+ }
+<NameSpaceDocArg1>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
}
-<NameSpaceDocArg1>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
+<NameSpaceDocArg1>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
"missing argument after "
- "\\namespace."
+ "\\namespace."
);
- addOutput(yyscanner,'\n');
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<NameSpaceDocArg1>. { // ignore other stuff
- }
+ unput('\n');
+ //addOutput(yyscanner,'\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ BEGIN( Comment );
+ }
+<NameSpaceDocArg1>. { // ignore other stuff
+ }
/* ------------ handle argument of package command --------------- */
-<PackageDocArg1>{ID}("."{ID})* { // handle argument
- yyextra->current->name = yytext;
- BEGIN( Comment );
- }
-<PackageDocArg1>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
+<PackageDocArg1>{ID}("."{ID})* { // handle argument
+ yyextra->current->name = yytext;
+ BEGIN( Comment );
}
-<PackageDocArg1>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
+<PackageDocArg1>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<PackageDocArg1>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
"missing argument after "
- "\\package."
+ "\\package."
);
- addOutput(yyscanner,'\n');
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<PackageDocArg1>. { // ignore other stuff
- }
+ unput('\n');
+ //addOutput(yyscanner,'\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ BEGIN( Comment );
+ }
+<PackageDocArg1>. { // ignore other stuff
+ }
/* ------ handle argument of class/struct/union command --------------- */
-<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
- yyextra->current->name = substitute(removeRedundantWhiteSpace(yytext),".","::");
- BEGIN( ClassDocArg2 );
- }
-<ClassDocArg1>{SCOPENAME} { // first argument
- yyextra->current->name = substitute(yytext,".","::");
- if (yyextra->current->section==Entry::PROTOCOLDOC_SEC)
- {
- yyextra->current->name+="-p";
- }
- // prepend outer scope name
- BEGIN( ClassDocArg2 );
- }
+<ClassDocArg1>{SCOPENAME}{TMPLSPEC} {
+ yyextra->current->name = substitute(removeRedundantWhiteSpace(yytext),".","::");
+ BEGIN( ClassDocArg2 );
+ }
+<ClassDocArg1>{SCOPENAME} { // first argument
+ yyextra->current->name = substitute(yytext,".","::");
+ if (yyextra->current->section==Entry::PROTOCOLDOC_SEC)
+ {
+ yyextra->current->name+="-p";
+ }
+ // prepend outer scope name
+ BEGIN( ClassDocArg2 );
+ }
<CategoryDocArg1>{SCOPENAME}{B}*"("[^\)]+")" {
- yyextra->current->name = substitute(yytext,".","::");
- BEGIN( ClassDocArg2 );
- }
+ yyextra->current->name = substitute(yytext,".","::");
+ BEGIN( ClassDocArg2 );
+ }
<ClassDocArg1,CategoryDocArg1>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
}
-<ClassDocArg1,CategoryDocArg1>{DOCNL} {
- warn(yyextra->fileName,yyextra->lineNr,
+<ClassDocArg1,CategoryDocArg1>{DOCNL} {
+ warn(yyextra->fileName,yyextra->lineNr,
"missing argument after "
- "\\%s.",YY_START==ClassDocArg1?"class":"category"
+ "'\\%s'.",yyextra->currentCmd.data()
);
- addOutput(yyscanner,'\n');
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
- }
-
-<ClassDocArg2>{FILE}|"<>" { // second argument; include file
- yyextra->current->includeFile = yytext;
- BEGIN( ClassDocArg3 );
- }
-<ClassDocArg2>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<ClassDocArg2>{DOCNL} {
- addOutput(yyscanner,'\n');
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<ClassDocArg2>. { // ignore other stuff
- }
-
-<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
- yyextra->current->includeName = yytext;
- BEGIN( Comment );
- }
-<ClassDocArg3>{LC} { // line continuation
+ //addOutput(yyscanner,'\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ unput('\n');
+ BEGIN( Comment );
+ }
+<ClassDocArg1,CategoryDocArg1>. { // ignore other stuff
+ }
+
+<ClassDocArg2>{FILE}|"<>" { // second argument; include file
+ yyextra->current->includeFile = yytext;
+ BEGIN( ClassDocArg3 );
+ }
+<ClassDocArg2>{LC} { // line continuation
yyextra->lineNr++;
- addOutput(yyscanner,'\n');
+ addOutput(yyscanner,'\n');
+ }
+<ClassDocArg2>{DOCNL} {
+ //addOutput(yyscanner,'\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ unput('\n');
+ BEGIN( Comment );
+ }
+<ClassDocArg2>. { // ignore other stuff
+ }
+
+<ClassDocArg3>[<"]?{FILE}?[">]? { // third argument; include file name
+ yyextra->current->includeName = yytext;
+ BEGIN( Comment );
+ }
+<ClassDocArg3>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<ClassDocArg3>{DOCNL} {
+ //if (*yytext=='\n') yyextra->lineNr++;
+ unput('\n');
+ BEGIN( Comment );
+ }
+<ClassDocArg3>. { // ignore other stuff
}
-<ClassDocArg3>{DOCNL} {
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<ClassDocArg3>. { // ignore other stuff
- }
/* --------- handle arguments of {def,add,weak}group commands --------- */
-<GroupDocArg1>{LABELID}(".html"?) { // group name
- yyextra->current->name = yytext;
- //lastDefGroup.groupname = yytext;
- //lastDefGroup.pri = yyextra->current->groupingPri();
- // the .html stuff is for Qt compatibility
- if (yyextra->current->name.right(5)==".html")
- {
- yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5);
- }
- yyextra->current->type.resize(0);
- BEGIN(GroupDocArg2);
- }
-<GroupDocArg1>"\\"{B}*"\n" { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<GroupDocArg1>{DOCNL} { // missing argument!
- warn(yyextra->fileName,yyextra->lineNr,
+<GroupDocArg1>{LABELID}(".html"?) { // group name
+ yyextra->current->name = yytext;
+ //lastDefGroup.groupname = yytext;
+ //lastDefGroup.pri = yyextra->current->groupingPri();
+ // the .html stuff is for Qt compatibility
+ if (yyextra->current->name.right(5)==".html")
+ {
+ yyextra->current->name=yyextra->current->name.left(yyextra->current->name.length()-5);
+ }
+ yyextra->current->type.resize(0);
+ BEGIN(GroupDocArg2);
+ }
+<GroupDocArg1>"\\"{B}*"\n" { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<GroupDocArg1>{DOCNL} { // missing argument!
+ warn(yyextra->fileName,yyextra->lineNr,
"missing group name after %s",
- yyextra->current->groupDocCmd()
+ yyextra->current->groupDocCmd()
);
- addOutput(yyscanner,'\n');
- if (*yytext=='\n') yyextra->lineNr++;
- BEGIN( Comment );
- }
-<GroupDocArg1>. { // ignore other stuff
- }
-<GroupDocArg2>"\\"{B}*"\n" { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<GroupDocArg2>[^\n\\]+ { // title (stored in type)
- yyextra->current->type += yytext;
- yyextra->current->type = yyextra->current->type.stripWhiteSpace();
- }
-<GroupDocArg2>{DOCNL} {
+ //addOutput(yyscanner,'\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ unput('\n');
+ BEGIN( Comment );
+ }
+<GroupDocArg1>. { // ignore other stuff
+ }
+<GroupDocArg2>"\\"{B}*"\n" { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<GroupDocArg2>[^\n\\]+ { // title (stored in type)
+ yyextra->current->type += yytext;
+ yyextra->current->type = yyextra->current->type.stripWhiteSpace();
+ }
+<GroupDocArg2>{DOCNL} {
if ( yyextra->current->groupDocType==Entry::GROUPDOC_NORMAL &&
- yyextra->current->type.isEmpty()
- ) // defgroup requires second argument
- {
- warn(yyextra->fileName,yyextra->lineNr,
+ yyextra->current->type.isEmpty()
+ ) // defgroup requires second argument
+ {
+ warn(yyextra->fileName,yyextra->lineNr,
"missing title after "
- "\\defgroup %s", yyextra->current->name.data()
+ "\\defgroup %s", yyextra->current->name.data()
);
- }
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
+ }
+ unput('\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
<GroupDocArg2>. { // title (stored in type)
- yyextra->current->type += yytext;
- yyextra->current->type = yyextra->current->type.stripWhiteSpace();
+ yyextra->current->type += yytext;
+ yyextra->current->type = yyextra->current->type.stripWhiteSpace();
}
/* --------- handle arguments of page/mainpage command ------------------- */
-<PageDocArg1>{FILE} { // first argument; page name
- yyextra->current->name = stripQuotes(yytext);
- yyextra->current->args = "";
- BEGIN( PageDocArg2 );
- }
-<PageDocArg1>{LC} { yyextra->lineNr++;
- addOutput(yyscanner,'\n');
+<PageDocArg1>{FILE} { // first argument; page name
+ yyextra->current->name = stripQuotes(yytext);
+ yyextra->current->args = "";
+ BEGIN( PageDocArg2 );
+ }
+<PageDocArg1>{LC} { yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
}
-<PageDocArg1>{DOCNL} {
- warn(yyextra->fileName,yyextra->lineNr,
+<PageDocArg1>{DOCNL} {
+ warn(yyextra->fileName,yyextra->lineNr,
"missing argument after "
- "\\page."
+ "\\page."
);
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<PageDocArg1>. { // ignore other stuff
- }
-<PageDocArg2>{DOCNL} { // second argument; page title
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<PageDocArg2>{CMD}[<>] {
- // bug 748927
- QCString tmp = yytext;
- tmp = substitute(substitute(tmp,"@<","&lt;"),"@>","&gt;");
- tmp = substitute(substitute(tmp,"\\<","&lt;"),"\\>","&gt;");
- yyextra->current->args += tmp;
- }
-<PageDocArg2>. {
- yyextra->current->args += yytext;
+ unput('\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<PageDocArg1>. { // ignore other stuff
+ }
+<PageDocArg2>{DOCNL} { // second argument; page title
+ unput('\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<PageDocArg2>{CMD}[<>] {
+ // bug 748927
+ QCString tmp = yytext;
+ tmp = substitute(substitute(tmp,"@<","&lt;"),"@>","&gt;");
+ tmp = substitute(substitute(tmp,"\\<","&lt;"),"\\>","&gt;");
+ yyextra->current->args += tmp;
+ }
+<PageDocArg2>. {
+ yyextra->current->args += yytext;
}
/* --------- handle arguments of the param command ------------ */
<ParamArg1>{ID}/{B}*"," {
@@ -1165,288 +1193,291 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
/* --------- handle arguments of the file/dir/example command ------------ */
-<FileDocArg1>{DOCNL} { // no file name specified
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<FileDocArg1>{FILE} { // first argument; name
- yyextra->current->name = stripQuotes(yytext);
- BEGIN( Comment );
- }
-<FileDocArg1>{LC} { yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<FileDocArg1>. { // ignore other stuff
- }
+<FileDocArg1>{DOCNL} { // no file name specified
+ unput('\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<FileDocArg1>{FILE} { // first argument; name
+ yyextra->current->name = stripQuotes(yytext);
+ BEGIN( Comment );
+ }
+<FileDocArg1>{LC} { yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<FileDocArg1>. { // ignore other stuff
+ }
/* --------- handle arguments of the xrefitem command ------------ */
-<XRefItemParam1>{LABELID} { // first argument
- yyextra->newXRefItemKey=yytext;
+<XRefItemParam1>{LABELID} { // first argument
+ yyextra->newXRefItemKey=yytext;
setOutput(yyscanner,OutputXRef);
- BEGIN(XRefItemParam2);
- }
-<XRefItemParam1>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<XRefItemParam1>{DOCNL} { // missing arguments
- warn(yyextra->fileName,yyextra->lineNr,
- "Missing first argument of \\xrefitem"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- yyextra->inContext = OutputDoc;
- BEGIN( Comment );
- }
-<XRefItemParam1>. { // ignore other stuff
- }
-
-<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
- yyextra->xrefItemTitle = stripQuotes(yytext);
- BEGIN(XRefItemParam3);
- }
-<XRefItemParam2>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<XRefItemParam2>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "Missing second argument of \\xrefitem"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- yyextra->inContext = OutputDoc;
- BEGIN( Comment );
- }
-<XRefItemParam2>. { // ignore other stuff
- }
-
-<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
- yyextra->xrefListTitle = stripQuotes(yytext);
+ BEGIN(XRefItemParam2);
+ }
+<XRefItemParam1>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<XRefItemParam1>{DOCNL} { // missing arguments
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Missing first argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ yyextra->inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam1>. { // ignore other stuff
+ }
+
+<XRefItemParam2>"\""[^\n\"]*"\"" { // second argument
+ yyextra->xrefItemTitle = stripQuotes(yytext);
+ BEGIN(XRefItemParam3);
+ }
+<XRefItemParam2>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<XRefItemParam2>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Missing second argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ yyextra->inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam2>. { // ignore other stuff
+ }
+
+<XRefItemParam3>"\""[^\n\"]*"\"" { // third argument
+ yyextra->xrefListTitle = stripQuotes(yytext);
yyextra->xrefKind = XRef_Item;
- BEGIN( Comment );
- }
-<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<XRefItemParam3>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "Missing third argument of \\xrefitem"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- yyextra->inContext = OutputDoc;
- BEGIN( Comment );
- }
-<XRefItemParam3>. { // ignore other stuff
- }
+ BEGIN( Comment );
+ }
+<XRefItemParam2,XRefItemParam3>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<XRefItemParam3>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Missing third argument of \\xrefitem"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ yyextra->inContext = OutputDoc;
+ BEGIN( Comment );
+ }
+<XRefItemParam3>. { // ignore other stuff
+ }
/* ----- handle arguments of the relates(also)/memberof command ------- */
-<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
- yyextra->current->relates = yytext;
- //if (yyextra->current->mGrpId!=DOX_NOGROUP)
+<RelatesParam1>({ID}("::"|"."))*{ID} { // argument
+ yyextra->current->relates = yytext;
+ //if (yyextra->current->mGrpId!=DOX_NOGROUP)
//{
// memberGroupRelates = yytext;
//}
- BEGIN( Comment );
- }
-<RelatesParam1>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<RelatesParam1>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "Missing argument of \\relates or \\memberof command"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<RelatesParam1>. { // ignore other stuff
- }
+ BEGIN( Comment );
+ }
+<RelatesParam1>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<RelatesParam1>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Missing argument of '\\%s' command",yyextra->currentCmd.data()
+ );
+ unput('\n');
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<RelatesParam1>. { // ignore other stuff
+ }
/* ----- handle arguments of the relates(also)/addindex commands ----- */
-<LineParam>{DOCNL} { // end of argument
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<LineParam>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<LineParam>. { // ignore other stuff
- addOutput(yyscanner,*yytext);
- }
+<LineParam>{DOCNL} { // end of argument
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ unput('\n');
+ BEGIN( Comment );
+ }
+<LineParam>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<LineParam>. { // ignore other stuff
+ addOutput(yyscanner,*yytext);
+ }
/* ----- handle arguments of the section/subsection/.. commands ------- */
-<SectionLabel>{LABELID} { // first argument
- yyextra->sectionLabel=yytext;
+<SectionLabel>{LABELID} { // first argument
+ yyextra->sectionLabel=yytext;
addOutput(yyscanner,yytext);
- yyextra->sectionTitle.resize(0);
- BEGIN(SectionTitle);
- }
-<SectionLabel>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "\\section command has no label"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<SectionLabel>. { // invalid character for section label
- warn(yyextra->fileName,yyextra->lineNr,
- "Invalid or missing section label"
- );
- BEGIN(Comment);
- }
+ yyextra->sectionTitle.resize(0);
+ BEGIN(SectionTitle);
+ }
+<SectionLabel>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "\\section command has no label"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<SectionLabel>. { // invalid character for section label
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Invalid or missing section label"
+ );
+ BEGIN(Comment);
+ }
<SectionTitle>[^\n@\\*]*/"\n" { // end of section title
- addSection(yyscanner);
+ addSection(yyscanner);
+ addOutput(yyscanner,yytext);
+ BEGIN( Comment );
+ }
+<SectionTitle>[^\n@\\]*/"\\ilinebr" { // end of section title
+ addSection(yyscanner);
+ addOutput(yyscanner,yytext);
+ BEGIN( Comment );
+ }
+<SectionTitle>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<SectionTitle>[^\n@\\]* { // any character without special meaning
+ yyextra->sectionTitle+=yytext;
addOutput(yyscanner,yytext);
- BEGIN( Comment );
- }
-<SectionTitle>[^\n@\\]*/"\\_linebr" { // end of section title
- addSection(yyscanner);
+ }
+<SectionTitle>({CMD}{CMD}){ID} { // unescape escaped command
+ yyextra->sectionTitle+=&yytext[1];
+ addOutput(yyscanner,yytext);
+ }
+<SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character
+ yyextra->sectionTitle+=yytext[1];
addOutput(yyscanner,yytext);
- BEGIN( Comment );
- }
-<SectionTitle>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<SectionTitle>[^\n@\\]* { // any character without special meaning
- yyextra->sectionTitle+=yytext;
- addOutput(yyscanner,yytext);
- }
-<SectionTitle>({CMD}{CMD}){ID} { // unescape escaped command
- yyextra->sectionTitle+=&yytext[1];
- addOutput(yyscanner,yytext);
- }
-<SectionTitle>{CMD}[$@\\&~<>#%] { // unescape escaped character
- yyextra->sectionTitle+=yytext[1];
- addOutput(yyscanner,yytext);
- }
-<SectionTitle>. { // anything else
- yyextra->sectionTitle+=yytext;
- addOutput(yyscanner,*yytext);
- }
+ }
+<SectionTitle>. { // anything else
+ yyextra->sectionTitle+=yytext;
+ addOutput(yyscanner,*yytext);
+ }
/* ----- handle arguments of the subpage command ------- */
-<SubpageLabel>{LABELID} { // first argument
+<SubpageLabel>{LABELID} { // first argument
+ addOutput(yyscanner,yytext);
+ // we add subpage labels as a kind of "inheritance" relation to prevent
+ // needing to add another list to the Entry class.
+ yyextra->current->extends.push_back(BaseInfo(yytext,Public,Normal));
+ BEGIN(SubpageTitle);
+ }
+<SubpageLabel>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "\\subpage command has no label"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<SubpageTitle>{DOCNL} { // no title, end command
+ addOutput(yyscanner,yytext);
+ BEGIN( Comment );
+ }
+<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
addOutput(yyscanner,yytext);
- // we add subpage labels as a kind of "inheritance" relation to prevent
- // needing to add another list to the Entry class.
- yyextra->current->extends.push_back(BaseInfo(yytext,Public,Normal));
- BEGIN(SubpageTitle);
- }
-<SubpageLabel>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "\\subpage command has no label"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<SubpageTitle>{DOCNL} { // no title, end command
- addOutput(yyscanner,yytext);
- BEGIN( Comment );
- }
-<SubpageTitle>[ \t]*"\""[^\"\n]*"\"" { // add title, end of command
- addOutput(yyscanner,yytext);
- BEGIN( Comment );
- }
-<SubpageTitle>. { // no title, end of command
- unput(*yytext);
- BEGIN( Comment );
- }
+ BEGIN( Comment );
+ }
+<SubpageTitle>. { // no title, end of command
+ unput(*yytext);
+ BEGIN( Comment );
+ }
/* ----- handle arguments of the anchor command ------- */
-<AnchorLabel>{LABELID} { // found argument
+<AnchorLabel>{LABELID} { // found argument
addAnchor(yyscanner,yytext);
- addOutput(yyscanner,yytext);
- BEGIN( Comment );
- }
-<AnchorLabel>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "\\anchor command has no label"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<AnchorLabel>. { // invalid character for anchor label
- warn(yyextra->fileName,yyextra->lineNr,
- "Invalid or missing anchor label"
- );
- BEGIN(Comment);
- }
+ addOutput(yyscanner,yytext);
+ BEGIN( Comment );
+ }
+<AnchorLabel>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "\\anchor command has no label"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<AnchorLabel>. { // invalid character for anchor label
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Invalid or missing anchor label"
+ );
+ BEGIN(Comment);
+ }
/* ----- handle arguments of the preformatted block commands ------- */
<FormatBlock>{CMD}("endverbatim"|"endlatexonly"|"endhtmlonly"|"endxmlonly"|"enddocbookonly"|"endrtfonly"|"endmanonly"|"enddot"|"endcode"|"endmsc"|"endvhdlflow")/{NW} { // possible ends
- addOutput(yyscanner,yytext);
- if (&yytext[4]==yyextra->blockName) // found end of the block
- {
- BEGIN(Comment);
- }
- }
+ addOutput(yyscanner,yytext);
+ if (&yytext[4]==yyextra->blockName) // found end of the block
+ {
+ BEGIN(Comment);
+ }
+ }
<FormatBlock>{CMD}"enduml" {
- addOutput(yyscanner,yytext);
- if (yyextra->blockName=="startuml") // found end of the block
- {
- BEGIN(Comment);
- }
- }
-<FormatBlock>[^ \@\*\/\\\n]* { // some word
- addOutput(yyscanner,yytext);
- }
-<FormatBlock>{DOCNL} { // new line
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<FormatBlock>"/*" { // start of a C-comment
- if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim")) yyextra->commentCount++;
- addOutput(yyscanner,yytext);
- }
-<FormatBlock>"*/" { // end of a C-comment
- addOutput(yyscanner,yytext);
- if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim"))
+ addOutput(yyscanner,yytext);
+ if (yyextra->blockName=="startuml") // found end of the block
+ {
+ BEGIN(Comment);
+ }
+ }
+<FormatBlock>[^ \@\*\/\\\n]* { // some word
+ addOutput(yyscanner,yytext);
+ }
+<FormatBlock>{DOCNL} { // new line
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<FormatBlock>"/*" { // start of a C-comment
+ if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim")) yyextra->commentCount++;
+ addOutput(yyscanner,yytext);
+ }
+<FormatBlock>"*/" { // end of a C-comment
+ addOutput(yyscanner,yytext);
+ if (!(yyextra->blockName=="code" || yyextra->blockName=="verbatim"))
{
yyextra->commentCount--;
- if (yyextra->commentCount<0)
- {
- warn(yyextra->fileName,yyextra->lineNr,
- "found */ without matching /* while inside a \\%s block! Perhaps a missing \\end%s?\n",yyextra->blockName.data(),yyextra->blockName.data());
- }
- }
- }
-<FormatBlock>. {
- addOutput(yyscanner,*yytext);
- }
-<FormatBlock><<EOF>> {
+ if (yyextra->commentCount<0)
+ {
+ warn(yyextra->fileName,yyextra->lineNr,
+ "found */ without matching /* while inside a \\%s block! Perhaps a missing \\end%s?\n",yyextra->blockName.data(),yyextra->blockName.data());
+ }
+ }
+ }
+<FormatBlock>. {
+ addOutput(yyscanner,*yytext);
+ }
+<FormatBlock><<EOF>> {
QCString endTag = "end"+yyextra->blockName;
if (yyextra->blockName=="startuml") endTag="enduml";
warn(yyextra->fileName,yyextra->lineNr,
- "reached end of comment while inside a \\%s block; check for missing \\%s tag!",
- yyextra->blockName.data(),endTag.data()
- );
- yyterminate();
- }
+ "reached end of comment while inside a \\%s block; check for missing \\%s tag!",
+ yyextra->blockName.data(),endTag.data()
+ );
+ yyterminate();
+ }
/* ----- handle arguments of if/ifnot commands ------- */
-<GuardParam>{B}*"(" {
+<GuardParam>{B}*"(" {
yyextra->guardExpr=yytext;
yyextra->roundCount=1;
BEGIN(GuardExpr);
@@ -1467,383 +1498,388 @@ RCSTAG "$"{ID}":"[^\n$]+"$"
}
}
<GuardExpr>\n {
- warn(yyextra->fileName,yyextra->lineNr,
- "invalid expression '%s' for yyextra->guards",yyextra->guardExpr.data());
+ warn(yyextra->fileName,yyextra->lineNr,
+ "invalid expression '%s' for yyextra->guards",yyextra->guardExpr.data());
unput(*yytext);
BEGIN(GuardParam);
}
-<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot yyextra->guards
+<GuardParam>{B}*[a-z_A-Z0-9.\-]+ { // parameter of if/ifnot yyextra->guards
handleGuard(yyscanner,yytext);
- }
-<GuardParam>{DOCNL} { // end of argument
- if (*yytext=='\n') yyextra->lineNr++;
- //next line is commented out due to bug620924
- //addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<GuardParam>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<GuardParam>. { // ignore other stuff
- addOutput(yyscanner,*yytext);
- }
-<GuardParamEnd>{B}*{DOCNL} {
- lineCount(yyscanner);
- yyextra->spaceBeforeIf.resize(0);
- BEGIN(Comment);
- }
-<GuardParamEnd>{B}* {
- if (!yyextra->spaceBeforeIf.isEmpty()) // needed for 665313 in combination with bug620924
- {
- addOutput(yyscanner,yyextra->spaceBeforeIf);
- }
- yyextra->spaceBeforeIf.resize(0);
- BEGIN(Comment);
- }
-<GuardParamEnd>. {
- unput(*yytext);
- BEGIN(Comment);
- }
+ }
+<GuardParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyextra->lineNr++;
+ //next line is commented out due to bug620924
+ //addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<GuardParam>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<GuardParam>. { // ignore other stuff
+ addOutput(yyscanner,*yytext);
+ }
+<GuardParamEnd>{B}*{DOCNL} {
+ lineCount(yyscanner);
+ yyextra->spaceBeforeIf.resize(0);
+ BEGIN(Comment);
+ }
+<GuardParamEnd>{B}* {
+ if (!yyextra->spaceBeforeIf.isEmpty()) // needed for 665313 in combination with bug620924
+ {
+ addOutput(yyscanner,yyextra->spaceBeforeIf);
+ }
+ yyextra->spaceBeforeIf.resize(0);
+ BEGIN(Comment);
+ }
+<GuardParamEnd>. {
+ unput(*yytext);
+ BEGIN(Comment);
+ }
/* ----- handle skipping of conditional sections ------- */
-<SkipGuardedSection>{CMD}"ifnot"/{NW} {
+<SkipGuardedSection>{CMD}"ifnot"/{NW} {
yyextra->guardType = Guard_IfNot;
- BEGIN( GuardParam );
- }
-<SkipGuardedSection>{CMD}"if"/{NW} {
+ BEGIN( GuardParam );
+ }
+<SkipGuardedSection>{CMD}"if"/{NW} {
yyextra->guardType = Guard_If;
- BEGIN( GuardParam );
- }
-<SkipGuardedSection>{CMD}"endif"/{NW} {
- if (yyextra->guards.empty())
- {
- warn(yyextra->fileName,yyextra->lineNr,
- "found \\endif without matching start command");
- }
- else
- {
- GuardedSection s = yyextra->guards.top();
+ BEGIN( GuardParam );
+ }
+<SkipGuardedSection>{CMD}"endif"/{NW} {
+ if (yyextra->guards.empty())
+ {
+ warn(yyextra->fileName,yyextra->lineNr,
+ "found \\endif without matching start command");
+ }
+ else
+ {
+ GuardedSection s = yyextra->guards.top();
yyextra->guards.pop();
bool parentVisible = s.parentVisible();
if (parentVisible)
{
- yyextra->enabledSectionFound=TRUE;
- BEGIN( GuardParamEnd );
+ yyextra->enabledSectionFound=TRUE;
+ BEGIN( GuardParamEnd );
+ }
+ }
+ }
+<SkipGuardedSection>{CMD}"else"/{NW} {
+ if (yyextra->guards.empty())
+ {
+ warn(yyextra->fileName,yyextra->lineNr,
+ "found \\else without matching start command");
+ }
+ else
+ {
+ if (!yyextra->enabledSectionFound && yyextra->guards.top().parentVisible())
+ {
+ yyextra->guards.pop();
+ yyextra->guards.push(GuardedSection(TRUE,TRUE));
+ yyextra->enabledSectionFound=TRUE;
+ BEGIN( GuardParamEnd );
}
- }
- }
-<SkipGuardedSection>{CMD}"else"/{NW} {
- if (yyextra->guards.empty())
- {
- warn(yyextra->fileName,yyextra->lineNr,
- "found \\else without matching start command");
- }
- else
- {
- if (!yyextra->enabledSectionFound && yyextra->guards.top().parentVisible())
- {
- yyextra->guards.pop();
- yyextra->guards.push(GuardedSection(TRUE,TRUE));
- yyextra->enabledSectionFound=TRUE;
- BEGIN( GuardParamEnd );
- }
- }
- }
+ }
+ }
<SkipGuardedSection>{CMD}"elseif"/{NW} {
- if (yyextra->guards.empty())
- {
- warn(yyextra->fileName,yyextra->lineNr,
- "found \\elseif without matching start command");
- }
- else
- {
- if (!yyextra->enabledSectionFound && yyextra->guards.top().parentVisible())
- {
+ if (yyextra->guards.empty())
+ {
+ warn(yyextra->fileName,yyextra->lineNr,
+ "found \\elseif without matching start command");
+ }
+ else
+ {
+ if (!yyextra->enabledSectionFound && yyextra->guards.top().parentVisible())
+ {
yyextra->guardType=Guard_If;
- yyextra->guards.pop();
- BEGIN( GuardParam );
- }
- }
- }
-<SkipGuardedSection>{DOCNL} { // skip line
- if (*yytext=='\n') yyextra->lineNr++;
- //addOutput(yyscanner,'\n');
- }
-<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
- }
-<SkipGuardedSection>. { // any other character
- }
+ yyextra->guards.pop();
+ BEGIN( GuardParam );
+ }
+ }
+ }
+<SkipGuardedSection>{DOCNL} { // skip line
+ if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ }
+<SkipGuardedSection>[^ \\@\n]+ { // skip non-special characters
+ }
+<SkipGuardedSection>. { // any other character
+ }
/* ----- handle skipping of internal section ------- */
-<SkipInternal>{DOCNL} { // skip line
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<SkipInternal>[@\\]"if"/[ \t] {
+<SkipInternal>{DOCNL} { // skip line
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<SkipInternal>[@\\]"if"/[ \t] {
yyextra->condCount++;
- }
-<SkipInternal>[@\\]"ifnot"/[ \t] {
+ }
+<SkipInternal>[@\\]"ifnot"/[ \t] {
yyextra->condCount++;
- }
-<SkipInternal>[@\\]/"endif" {
+ }
+<SkipInternal>[@\\]/"endif" {
yyextra->condCount--;
- if (yyextra->condCount<0) // handle conditional section around of \internal, see bug607743
- {
- unput('\\');
- BEGIN(Comment);
- }
- }
-<SkipInternal>[@\\]/"section"[ \t] {
- if (yyextra->sectionLevel>0)
- {
- unput('\\');
- BEGIN(Comment);
- }
- }
-<SkipInternal>[@\\]/"subsection"[ \t] {
- if (yyextra->sectionLevel>1)
- {
- unput('\\');
- BEGIN(Comment);
- }
- }
-<SkipInternal>[@\\]/"subsubsection"[ \t] {
- if (yyextra->sectionLevel>2)
- {
- unput('\\');
- BEGIN(Comment);
- }
- }
-<SkipInternal>[@\\]/"paragraph"[ \t] {
- if (yyextra->sectionLevel>3)
- {
- unput('\\');
- BEGIN(Comment);
- }
- }
+ if (yyextra->condCount<0) // handle conditional section around of \internal, see bug607743
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"section"[ \t] {
+ if (yyextra->sectionLevel>0)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"subsection"[ \t] {
+ if (yyextra->sectionLevel>1)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"subsubsection"[ \t] {
+ if (yyextra->sectionLevel>2)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
+<SkipInternal>[@\\]/"paragraph"[ \t] {
+ if (yyextra->sectionLevel>3)
+ {
+ unput('\\');
+ BEGIN(Comment);
+ }
+ }
<SkipInternal>[@\\]"endinternal"[ \t]* {
- BEGIN(Comment);
- }
-<SkipInternal>[^ \\@\n]+ { // skip non-special characters
- }
-<SkipInternal>. { // any other character
- }
+ BEGIN(Comment);
+ }
+<SkipInternal>[^ \\@\n]+ { // skip non-special characters
+ }
+<SkipInternal>. { // any other character
+ }
/* ----- handle argument of name command ------- */
-<NameParam>{DOCNL} { // end of argument
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<NameParam>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- yyextra->docGroup.appendHeader(' ');
- }
-<NameParam>. { // ignore other stuff
- yyextra->docGroup.appendHeader(*yytext);
- yyextra->current->name+=*yytext;
- }
+<NameParam>{DOCNL} { // end of argument
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ unput('\n');
+ BEGIN( Comment );
+ }
+<NameParam>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ yyextra->docGroup.appendHeader(' ');
+ }
+<NameParam>. { // ignore other stuff
+ yyextra->docGroup.appendHeader(*yytext);
+ yyextra->current->name+=*yytext;
+ }
/* ----- handle argument of noop command ------- */
-<Noop>{DOCNL} { // end of argument
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<Noop>. { // ignore other stuff
- }
+<Noop>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<Noop>. { // ignore other stuff
+ }
/* ----- handle argument of ingroup command ------- */
-<InGroupParam>{LABELID} { // group id
- yyextra->current->groups.push_back(
- Grouping(yytext, Grouping::GROUPING_INGROUP)
- );
- yyextra->inGroupParamFound=TRUE;
- }
-<InGroupParam>{DOCNL} { // missing argument
- if (!yyextra->inGroupParamFound)
- {
- warn(yyextra->fileName,yyextra->lineNr,
- "Missing group name for \\ingroup command"
- );
- }
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<InGroupParam>{LC} { // line continuation
- yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- }
-<InGroupParam>. { // ignore other stuff
- addOutput(yyscanner,*yytext);
- }
+<InGroupParam>{LABELID} { // group id
+ yyextra->current->groups.push_back(
+ Grouping(yytext, Grouping::GROUPING_INGROUP)
+ );
+ yyextra->inGroupParamFound=TRUE;
+ }
+<InGroupParam>{DOCNL} { // missing argument
+ if (!yyextra->inGroupParamFound)
+ {
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Missing group name for \\ingroup command"
+ );
+ }
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ unput('\n');
+ BEGIN( Comment );
+ }
+<InGroupParam>{LC} { // line continuation
+ yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ }
+<InGroupParam>. { // ignore other stuff
+ addOutput(yyscanner,*yytext);
+ }
/* ----- handle argument of fn command ------- */
-<FnParam>{DOCNL} { // end of argument
- if (yyextra->braceCount==0)
- {
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- yyextra->langParser->parsePrototype(yyextra->functionProto);
- BEGIN( Comment );
- }
- }
-<FnParam>{LC} { // line continuation
- yyextra->lineNr++;
- yyextra->functionProto+=' ';
- }
-<FnParam>[^@\\\n()]+ { // non-special characters
+<FnParam>{DOCNL} { // end of argument
+ if (yyextra->braceCount==0)
+ {
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ unput('\n');
+ yyextra->langParser->parsePrototype(yyextra->functionProto);
+ BEGIN( Comment );
+ }
+ }
+<FnParam>{LC} { // line continuation
+ yyextra->lineNr++;
+ yyextra->functionProto+=' ';
+ }
+<FnParam>[^@\\\n()]+ { // non-special characters
yyextra->functionProto+=yytext;
- }
-<FnParam>"(" {
+ }
+<FnParam>"(" {
yyextra->functionProto+=yytext;
- yyextra->braceCount++;
- }
-<FnParam>")" {
+ yyextra->braceCount++;
+ }
+<FnParam>")" {
yyextra->functionProto+=yytext;
- yyextra->braceCount--;
- }
-<FnParam>. { // add other stuff
+ yyextra->braceCount--;
+ }
+<FnParam>. { // add other stuff
yyextra->functionProto+=*yytext;
- }
+ }
/* ----- handle argument of overload command ------- */
-<OverloadParam>{DOCNL} { // end of argument
- if (*yytext=='\n') yyextra->lineNr++;
- if (yyextra->functionProto.stripWhiteSpace().isEmpty())
- { // plain overload command
- addOutput(yyscanner,getOverloadDocs());
- addOutput(yyscanner,'\n');
- }
- else // overload declaration
- {
+<OverloadParam>{DOCNL} { // end of argument
+ if (*yytext=='\n') yyextra->lineNr++;
+ if (yyextra->functionProto.stripWhiteSpace().isEmpty())
+ { // plain overload command
+ addOutput(yyscanner,getOverloadDocs());
+ addOutput(yyscanner,'\n');
+ }
+ else // overload declaration
+ {
makeStructuralIndicator(yyscanner,Entry::OVERLOADDOC_SEC);
- yyextra->langParser->parsePrototype(yyextra->functionProto);
- }
- BEGIN( Comment );
- }
-<OverloadParam>{LC} { // line continuation
- yyextra->lineNr++;
- yyextra->functionProto+=' ';
- }
-<OverloadParam>. { // add other stuff
+ yyextra->langParser->parsePrototype(yyextra->functionProto);
+ }
+ BEGIN( Comment );
+ }
+<OverloadParam>{LC} { // line continuation
+ yyextra->lineNr++;
+ yyextra->functionProto+=' ';
+ }
+<OverloadParam>. { // add other stuff
yyextra->functionProto+=*yytext;
- }
+ }
/* ----- handle argument of inherit command ------- */
-<InheritParam>({ID}("::"|"."))*{ID} { // found argument
- yyextra->current->extends.push_back(
- BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
- );
- BEGIN( Comment );
- }
-<InheritParam>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "\\inherit command has no argument"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<InheritParam>. { // invalid character for anchor label
- warn(yyextra->fileName,yyextra->lineNr,
- "Invalid or missing name for \\inherit command"
- );
- BEGIN(Comment);
- }
+<InheritParam>({ID}("::"|"."))*{ID} { // found argument
+ yyextra->current->extends.push_back(
+ BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
+ );
+ BEGIN( Comment );
+ }
+<InheritParam>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "\\inherit command has no argument"
+ );
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ BEGIN( Comment );
+ }
+<InheritParam>. { // invalid character for anchor label
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Invalid or missing name for \\inherit command"
+ );
+ BEGIN(Comment);
+ }
/* ----- handle argument of extends and implements commands ------- */
-<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
- yyextra->current->extends.push_back(
- BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
- );
- BEGIN( Comment );
- }
-<ExtendsParam>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "\\extends or \\implements command has no argument"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<ExtendsParam>. { // ignore other stuff
- }
+<ExtendsParam>({ID}("::"|"."))*{ID} { // found argument
+ yyextra->current->extends.push_back(
+ BaseInfo(removeRedundantWhiteSpace(yytext),Public,Normal)
+ );
+ BEGIN( Comment );
+ }
+<ExtendsParam>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "'\\%s' command has no argument",yyextra->currentCmd.data()
+ );
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ unput('\n');
+ BEGIN( Comment );
+ }
+<ExtendsParam>. { // ignore other stuff
+ }
/* ----- handle language specific sections ------- */
-<SkipLang>[\\@]"~"[a-zA-Z-]* { /* language switch */
- QCString langId = &yytext[2];
- if (langId.isEmpty() ||
- qstricmp(Config_getEnum(OUTPUT_LANGUAGE),langId)==0)
- { // enable language specific section
- BEGIN(Comment);
- }
- }
-<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
- }
-<SkipLang>{DOCNL} { /* new line in verbatim block */
- if (*yytext=='\n') yyextra->lineNr++;
- }
-<SkipLang>. { /* any other character */
- }
+<SkipLang>[\\@]"~"[a-zA-Z-]* { /* language switch */
+ QCString langId = &yytext[2];
+ if (langId.isEmpty() ||
+ qstricmp(Config_getEnum(OUTPUT_LANGUAGE),langId)==0)
+ { // enable language specific section
+ BEGIN(Comment);
+ }
+ }
+<SkipLang>[^*@\\\n]* { /* any character not a *, @, backslash or new line */
+ }
+<SkipLang>{DOCNL} { /* new line in verbatim block */
+ if (*yytext=='\n') yyextra->lineNr++;
+ }
+<SkipLang>. { /* any other character */
+ }
/* ----- handle arguments of the cite command ------- */
-<CiteLabel>{CITEID} { // found argument
- addCite(yyscanner);
+<CiteLabel>{CITEID} { // found argument
+ addCite(yyscanner);
addOutput(yyscanner,yytext);
- BEGIN(Comment);
- }
-<CiteLabel>{DOCNL} { // missing argument
- warn(yyextra->fileName,yyextra->lineNr,
- "\\cite command has no label"
- );
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- BEGIN( Comment );
- }
-<CiteLabel>. { // invalid character for cite label
- warn(yyextra->fileName,yyextra->lineNr,
- "Invalid or missing cite label"
- );
- BEGIN(Comment);
- }
+ BEGIN(Comment);
+ }
+<CiteLabel>{DOCNL} { // missing argument
+ warn(yyextra->fileName,yyextra->lineNr,
+ "\\cite command has no label"
+ );
+ //if (*yytext=='\n') yyextra->lineNr++;
+ //addOutput(yyscanner,'\n');
+ unput('\n');
+ BEGIN( Comment );
+ }
+<CiteLabel>. { // invalid character for cite label
+ warn(yyextra->fileName,yyextra->lineNr,
+ "Invalid or missing cite label"
+ );
+ BEGIN(Comment);
+ }
/* ----- handle argument of the copydoc command ------- */
-<CopyDoc><<EOF>> |
-<CopyDoc>{DOCNL} {
- if (*yytext=='\n') yyextra->lineNr++;
- addOutput(yyscanner,'\n');
- setOutput(yyscanner,OutputDoc);
+<CopyDoc><<EOF>> |
+<CopyDoc>{DOCNL} {
+ if (*yytext=='\n') yyextra->lineNr++;
+ addOutput(yyscanner,'\n');
+ setOutput(yyscanner,OutputDoc);
addOutput(yyscanner," \\copydetails ");
- addOutput(yyscanner,yyextra->copyDocArg);
- addOutput(yyscanner,"\n");
- BEGIN(Comment);
- }
-<CopyDoc>[^\n\\]+ {
- yyextra->copyDocArg+=yytext;
- addOutput(yyscanner,yytext);
- }
-<CopyDoc>. {
- yyextra->copyDocArg+=yytext;
- addOutput(yyscanner,yytext);
- }
+ addOutput(yyscanner,yyextra->copyDocArg);
+ addOutput(yyscanner,"\n");
+ BEGIN(Comment);
+ }
+<CopyDoc>[^\n\\]+ {
+ yyextra->copyDocArg+=yytext;
+ addOutput(yyscanner,yytext);
+ }
+<CopyDoc>. {
+ yyextra->copyDocArg+=yytext;
+ addOutput(yyscanner,yytext);
+ }
%%
@@ -1897,7 +1933,6 @@ static bool handleDefGroup(yyscan_t yyscanner,const QCString &, const QCStringLi
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::GROUPDOC_SEC);
yyextra->current->groupDocType = Entry::GROUPDOC_NORMAL;
- setOutput(yyscanner,OutputBrief);
BEGIN( GroupDocArg1 );
return stop;
}
@@ -1936,11 +1971,12 @@ static bool handlePackage(yyscan_t yyscanner,const QCString &, const QCStringLis
return stop;
}
-static bool handleClass(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleClass(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::CLASSDOC_SEC);
- BEGIN( ClassDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( ClassDocArg1 );
return stop;
}
@@ -1951,51 +1987,57 @@ static bool handleHeaderFile(yyscan_t yyscanner,const QCString &, const QCString
return FALSE;
}
-static bool handleProtocol(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleProtocol(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{ // Obj-C protocol
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::PROTOCOLDOC_SEC);
- BEGIN( ClassDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( ClassDocArg1 );
return stop;
}
-static bool handleCategory(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleCategory(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{ // Obj-C category
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::CATEGORYDOC_SEC);
- BEGIN( CategoryDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( CategoryDocArg1 );
return stop;
}
-static bool handleUnion(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleUnion(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::UNIONDOC_SEC);
- BEGIN( ClassDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( ClassDocArg1 );
return stop;
}
-static bool handleStruct(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleStruct(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::STRUCTDOC_SEC);
- BEGIN( ClassDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( ClassDocArg1 );
return stop;
}
-static bool handleInterface(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleInterface(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::INTERFACEDOC_SEC);
- BEGIN( ClassDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( ClassDocArg1 );
return stop;
}
-static bool handleIdlException(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleIdlException(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::EXCEPTIONDOC_SEC);
- BEGIN( ClassDocArg1 );
+ yyextra->currentCmd = cmd;
+ BEGIN( ClassDocArg1 );
return stop;
}
@@ -2012,7 +2054,7 @@ static bool handleMainpage(yyscan_t yyscanner,const QCString &, const QCStringLi
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::MAINPAGEDOC_SEC);
yyextra->current->name = "";
- if (!stop)
+ if (!stop)
{
yyextra->current->name = "mainpage";
}
@@ -2024,7 +2066,7 @@ static bool handleFile(yyscan_t yyscanner,const QCString &, const QCStringList &
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
bool stop=makeStructuralIndicator(yyscanner,Entry::FILEDOC_SEC);
- if (!stop)
+ if (!stop)
{
yyextra->current->name = yyextra->fileName;
}
@@ -2074,7 +2116,7 @@ static bool handleExample(yyscan_t yyscanner,const QCString &cmd, const QCString
else
{
warn(yyextra->fileName,yyextra->lineNr,
- "unsupported option '%s' for command '\\%s'",qPrint(opt),qPrint(cmd));
+ "unsupported option '%s' for command '\\%s'",qPrint(opt),qPrint(cmd));
}
}
bool stop=makeStructuralIndicator(yyscanner,section);
@@ -2168,9 +2210,9 @@ static bool handleParBlock(yyscan_t yyscanner,const QCString &, const QCStringLi
if (yyextra->insideParBlock)
{
warn(yyextra->fileName,yyextra->lineNr,
- "found \\parblock command while already in a parblock!");
+ "found \\parblock command while already in a parblock!");
}
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2186,7 +2228,7 @@ static bool handleEndParBlock(yyscan_t yyscanner,const QCString &, const QCStrin
if (!yyextra->insideParBlock)
{
warn(yyextra->fileName,yyextra->lineNr,
- "found \\endparblock command without matching \\parblock!");
+ "found \\endparblock command without matching \\parblock!");
}
addOutput(yyscanner,"@endparblock");
setOutput(yyscanner,OutputDoc); // to end a parblock inside a xrefitem like context
@@ -2194,41 +2236,43 @@ static bool handleEndParBlock(yyscan_t yyscanner,const QCString &, const QCStrin
return FALSE;
}
-static bool handleRelated(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleRelated(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (!yyextra->current->relates.isEmpty())
{
warn(yyextra->fileName,yyextra->lineNr,
- "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition");
+ "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition");
}
yyextra->current->relatesType = Simple;
BEGIN(RelatesParam1);
return FALSE;
}
-static bool handleRelatedAlso(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleRelatedAlso(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (!yyextra->current->relates.isEmpty())
{
warn(yyextra->fileName,yyextra->lineNr,
- "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition");
+ "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition");
}
yyextra->current->relatesType = Duplicate;
+ yyextra->currentCmd = cmd;
BEGIN(RelatesParam1);
return FALSE;
}
-static bool handleMemberOf(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleMemberOf(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
if (!yyextra->current->relates.isEmpty())
{
warn(yyextra->fileName,yyextra->lineNr,
- "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition");
+ "found multiple \\relates, \\relatesalso or \\memberof commands in a comment block, using last definition");
}
yyextra->current->relatesType = MemberOf;
+ yyextra->currentCmd = cmd;
BEGIN(RelatesParam1);
return FALSE;
}
@@ -2257,15 +2301,15 @@ static bool handleSection(yyscan_t yyscanner,const QCString &s, const QCStringLi
static bool handleSubpage(yyscan_t yyscanner,const QCString &s, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- if (yyextra->current->section!=Entry::EMPTY_SEC &&
+ if (yyextra->current->section!=Entry::EMPTY_SEC &&
yyextra->current->section!=Entry::PAGEDOC_SEC &&
yyextra->current->section!=Entry::MAINPAGEDOC_SEC
)
{
warn(yyextra->fileName,yyextra->lineNr,
- "found \\subpage command in a comment block that is not marked as a page!");
+ "found \\subpage command in a comment block that is not marked as a page!");
}
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2286,7 +2330,7 @@ static bool handleAnchor(yyscan_t yyscanner,const QCString &s, const QCStringLis
static bool handleCite(yyscan_t yyscanner,const QCString &s, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2348,7 +2392,7 @@ static bool handleElseIf(yyscan_t yyscanner,const QCString &, const QCStringList
if (yyextra->guards.empty())
{
warn(yyextra->fileName,yyextra->lineNr,
- "found \\else without matching start command");
+ "found \\else without matching start command");
}
else
{
@@ -2365,7 +2409,7 @@ static bool handleElse(yyscan_t yyscanner,const QCString &, const QCStringList &
if (yyextra->guards.empty())
{
warn(yyextra->fileName,yyextra->lineNr,
- "found \\else without matching start command");
+ "found \\else without matching start command");
}
else
{
@@ -2381,14 +2425,14 @@ static bool handleEndIf(yyscan_t yyscanner,const QCString &, const QCStringList
if (yyextra->guards.empty())
{
warn(yyextra->fileName,yyextra->lineNr,
- "found \\endif without matching start command");
+ "found \\endif without matching start command");
}
else
{
yyextra->guards.pop();
}
yyextra->enabledSectionFound=FALSE;
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2408,7 +2452,7 @@ static bool handleIngroup(yyscan_t yyscanner,const QCString &, const QCStringLis
static bool handleNoSubGrouping(yyscan_t yyscanner,const QCString &, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- yyextra->current->subGrouping = FALSE;
+ yyextra->current->subGrouping = FALSE;
return FALSE;
}
@@ -2490,7 +2534,7 @@ static bool handleInternal(yyscan_t yyscanner,const QCString &, const QCStringLi
// make sure some whitespace before a \internal command
// is not treated as "documentation"
if (yyextra->current->doc.stripWhiteSpace().isEmpty())
- {
+ {
yyextra->current->doc.resize(0);
}
yyextra->condCount=0;
@@ -2499,31 +2543,23 @@ static bool handleInternal(yyscan_t yyscanner,const QCString &, const QCStringLi
else
{
// re-enabled for bug640828
- addOutput(yyscanner," \\internal ");
+ addOutput(yyscanner," \\internal ");
yyextra->inInternalDocs = TRUE;
}
return FALSE;
}
-static bool handleLineBr(yyscan_t yyscanner,const QCString &, const QCStringList &)
-{
- addOutput(yyscanner,'\n');
- return FALSE;
-}
-
static bool handleStatic(yyscan_t yyscanner,const QCString &, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- endBrief(yyscanner);
- yyextra->current->stat = TRUE;
+ yyextra->current->stat = TRUE;
return FALSE;
}
static bool handlePure(yyscan_t yyscanner,const QCString &, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- endBrief(yyscanner);
- yyextra->current->virt = Pure;
+ yyextra->current->virt = Pure;
return FALSE;
}
@@ -2572,7 +2608,7 @@ static bool handlePublicSection(yyscan_t yyscanner,const QCString &, const QCStr
static bool handleToc(yyscan_t yyscanner,const QCString &, const QCStringList &optList)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
- if (yyextra->current->section==Entry::PAGEDOC_SEC ||
+ if (yyextra->current->section==Entry::PAGEDOC_SEC ||
yyextra->current->section==Entry::MAINPAGEDOC_SEC)
{
QCStringList::ConstIterator it;
@@ -2637,9 +2673,10 @@ static bool handleInherit(yyscan_t yyscanner,const QCString &, const QCStringLis
return FALSE;
}
-static bool handleExtends(yyscan_t yyscanner,const QCString &, const QCStringList &)
+static bool handleExtends(yyscan_t yyscanner,const QCString &cmd, const QCStringList &)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
+ yyextra->currentCmd = cmd;
BEGIN(ExtendsParam);
return FALSE;
}
@@ -2653,7 +2690,7 @@ static bool handleCopyBrief(yyscan_t yyscanner,const QCString &, const QCStringL
// otherwise it will be copied inline (see bug691315 & bug700788)
setOutput(yyscanner,OutputBrief);
}
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2666,7 +2703,7 @@ static bool handleCopyDetails(yyscan_t yyscanner,const QCString &, const QCStrin
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
setOutput(yyscanner,OutputDoc);
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2679,7 +2716,7 @@ static bool handleCopyDoc(yyscan_t yyscanner,const QCString &, const QCStringLis
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
setOutput(yyscanner,OutputBrief);
- if (!yyextra->spaceBeforeCmd.isEmpty())
+ if (!yyextra->spaceBeforeCmd.isEmpty())
{
addOutput(yyscanner,yyextra->spaceBeforeCmd);
yyextra->spaceBeforeCmd.resize(0);
@@ -2727,7 +2764,7 @@ static bool getDocSectionName(int s)
case Entry::EXAMPLE_SEC:
case Entry::MEMBERGRP_SEC:
return TRUE;
- default:
+ default:
return FALSE;
}
}
@@ -2785,11 +2822,15 @@ static void addXRefItem(yyscan_t yyscanner,
if (listName==0) return;
//printf("addXRefItem(%s,%s,%s,%d)\n",listName,itemTitle,listTitle,append);
+#if MULTITHREADED_INPUT
+ std::unique_lock<std::mutex> lock(g_sectionMutex);
+#endif
+
RefList *refList = RefListManager::instance().add(listName,listTitle,itemTitle);
RefItem *item = 0;
for (RefItem *i : yyextra->current->sli)
{
- if (i && qstrcmp(i->list()->listName(),listName)==0)
+ if (i && qstrcmp(i->list()->listName(),listName)==0)
{
//printf("found %s lii->type=%s\n",listName,lii->type);
item = i;
@@ -2825,26 +2866,28 @@ static void addXRefItem(yyscan_t yyscanner,
yyextra->current->doc += cmdString;
}
- SectionManager &sm = SectionManager::instance();
- const SectionInfo *si = sm.find(anchorLabel);
- if (si)
{
- if (si->lineNr() != -1)
+ SectionManager &sm = SectionManager::instance();
+ const SectionInfo *si = sm.find(anchorLabel);
+ if (si)
{
- warn(listName,yyextra->lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",anchorLabel.data(),si->fileName().data(),si->lineNr());
+ if (si->lineNr() != -1)
+ {
+ warn(listName,yyextra->lineNr,"multiple use of section label '%s', (first occurrence: %s, line %d)",anchorLabel.data(),si->fileName().data(),si->lineNr());
+ }
+ else
+ {
+ warn(listName,yyextra->lineNr,"multiple use of section label '%s', (first occurrence: %s)",anchorLabel.data(),si->fileName().data());
+ }
}
else
{
- warn(listName,yyextra->lineNr,"multiple use of section label '%s', (first occurrence: %s)",anchorLabel.data(),si->fileName().data());
+ si = sm.add(anchorLabel,listName,yyextra->lineNr,
+ yyextra->sectionTitle,SectionType::Anchor,
+ yyextra->sectionLevel);
+ yyextra->current->anchors.push_back(si);
}
}
- else
- {
- si = sm.add(anchorLabel,listName,yyextra->lineNr,
- yyextra->sectionTitle,SectionType::Anchor,
- yyextra->sectionLevel);
- yyextra->current->anchors.push_back(si);
- }
}
yyextra->outputXRef.resize(0);
}
@@ -2855,13 +2898,16 @@ static void addXRefItem(yyscan_t yyscanner,
// not already added. Returns the label of the formula.
static QCString addFormula(yyscan_t yyscanner)
{
+#if MULTITHREADED_INPUT
+ std::unique_lock<std::mutex> lock(g_formulaMutex);
+#endif
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
QCString formLabel;
QCString fText=yyextra->formulaText.simplifyWhiteSpace();
int id = FormulaManager::instance().addFormula(fText);
formLabel.sprintf("\\_form#%d",id);
for (int i=0;i<yyextra->formulaNewLines;i++) formLabel+="@_fakenl"; // add fake newlines to
- // keep the warnings
+ // keep the warnings
// correctly aligned.
return formLabel;
}
@@ -2876,6 +2922,9 @@ static SectionType sectionLevelToType(int level)
static void addSection(yyscan_t yyscanner)
{
+#if MULTITHREADED_INPUT
+ std::unique_lock<std::mutex> lock(g_sectionMutex);
+#endif
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
SectionManager &sm = SectionManager::instance();
const SectionInfo *si = sm.find(yyextra->sectionLabel);
@@ -2908,6 +2957,9 @@ static void addSection(yyscan_t yyscanner)
static void addCite(yyscan_t yyscanner)
{
+#if MULTITHREADED_INPUT
+ std::unique_lock<std::mutex> lock(g_citeMutex);
+#endif
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
QCString name=yytext;
if (yytext[0] =='"')
@@ -2926,8 +2978,24 @@ static void stripTrailingWhiteSpace(QCString &s)
uint len = s.length();
int i = (int)len-1;
char c;
- while (i>=0 && ((c = s.at(i))==' ' || c=='\t' || c=='\r')) i--;
- if (i!=(int)len-1)
+ while (i>=0)
+ {
+ c = s.at(i);
+ if (c==' ' || c=='\t' || c=='\r') // normal whitespace
+ {
+ i--;
+ }
+ else if (c=='r' && i>=7 && qstrncmp("\\ilinebr",s.data()+i-7,8)==0) // special line break marker
+ {
+ i-=8;
+ }
+ else // non-whitespace
+ {
+ break;
+ }
+ }
+ //printf("stripTrailingWhitespace(%s) i=%d len=%d\n",s.data(),i,len);
+ if (i!=(int)len-1)
{
s.resize(i+2); // string up to and including char at pos i and \0 terminator
}
@@ -2942,8 +3010,8 @@ static inline void setOutput(yyscan_t yyscanner,OutputContext ctx)
yyextra->xrefAppendFlag = !yyextra->inBody &&
yyextra->inContext==OutputXRef && ctx==OutputXRef && // two consecutive xref items
yyextra->newXRefKind==yyextra->xrefKind && // of the same kind
- (yyextra->xrefKind!=XRef_Item ||
- yyextra->newXRefItemKey==yyextra->xrefItemKey); // with the same key if \xrefitem
+ (yyextra->xrefKind!=XRef_Item ||
+ yyextra->newXRefItemKey==yyextra->xrefItemKey); // with the same key if \xrefitem
//printf("%d && %d && %d && (%d || %d)\n",
// yyextra->inContext==OutputXRef,
// ctx==OutputXRef,
@@ -2951,10 +3019,10 @@ static inline void setOutput(yyscan_t yyscanner,OutputContext ctx)
// yyextra->xrefKind!=XRef_Item,
// yyextra->newXRefItemKey==yyextra->xrefItemKey);
//printf("refKind=%d yyextra->newXRefKind=%d xrefAppendToPrev=%d yyextra->xrefAppendFlag=%d\n",
- // yyextra->xrefKind,yyextra->newXRefKind,xrefAppendToPrev,yyextra->xrefAppendFlag);
+ // yyextra->xrefKind,yyextra->newXRefKind,xrefAppendToPrev,yyextra->xrefAppendFlag);
//printf("setOutput(yyscanner,yyextra->inContext=%d ctx=%d)\n",yyextra->inContext,ctx);
- if (yyextra->inContext==OutputXRef) // end of XRef section => add the item
+ if (yyextra->inContext==OutputXRef) // end of XRef section => add the item
{
// See if we can append this new xref item to the previous one.
// We know this at the start of the next item of the same
@@ -3059,6 +3127,9 @@ static inline void setOutput(yyscan_t yyscanner,OutputContext ctx)
static void addAnchor(yyscan_t yyscanner,const char *anchor)
{
+#if MULTITHREADED_INPUT
+ std::unique_lock<std::mutex> lock(g_sectionMutex);
+#endif
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
SectionManager &sm = SectionManager::instance();
const SectionInfo *si = sm.find(anchor);
@@ -3156,15 +3227,16 @@ CommentScanner::~CommentScanner()
bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *parser,
/* in */ Entry *curEntry,
/* in */ const QCString &comment,
- /* in */ const QCString &fileName,
- /* in,out */ int &lineNr,
- /* in */ bool isBrief,
- /* in */ bool isAutoBriefOn,
- /* in */ bool isInbody,
- /* in,out */ Protection &prot,
- /* in,out */ int &position,
- /* out */ bool &newEntryNeeded
- )
+ /* in */ const QCString &fileName,
+ /* in,out */ int &lineNr,
+ /* in */ bool isBrief,
+ /* in */ bool isAutoBriefOn,
+ /* in */ bool isInbody,
+ /* in,out */ Protection &prot,
+ /* in,out */ int &position,
+ /* out */ bool &newEntryNeeded,
+ /* in */ bool markdownSupport
+ )
{
yyscan_t yyscanner = p->yyscanner;
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
@@ -3179,8 +3251,8 @@ bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *pars
yyextra->inputString = comment;
yyextra->inputString.append(" ");
yyextra->inputPosition = position;
- yyextra->lineNr = lineNr;
- yyextra->fileName = fileName;
+ yyextra->lineNr = lineNr;
+ yyextra->fileName = fileName;
yyextra->protection = prot;
yyextra->needNewEntry = FALSE;
yyextra->xrefKind = XRef_None;
@@ -3188,6 +3260,7 @@ bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *pars
yyextra->insidePre = FALSE;
yyextra->parseMore = FALSE;
yyextra->inBody = isInbody;
+ yyextra->markdownSupport= markdownSupport;
yyextra->outputXRef.resize(0);
if (!isBrief && !isAutoBriefOn && !yyextra->current->doc.isEmpty())
{ // add newline separator between detailed comment blocks
@@ -3209,7 +3282,7 @@ bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *pars
Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\n"
"input=[\n%s]\n",qPrint(fileName),lineNr,qPrint(yyextra->inputString)
);
-
+
commentscanYYrestart( 0, yyscanner );
BEGIN( Comment );
commentscanYYlex(yyscanner);
@@ -3228,7 +3301,7 @@ bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *pars
if (yyextra->insideParBlock)
{
warn(yyextra->fileName,yyextra->lineNr,
- "Documentation block ended while inside a \\parblock. Missing \\endparblock");
+ "Documentation block ended while inside a \\parblock. Missing \\endparblock");
}
yyextra->current->doc=stripLeadingAndTrailingEmptyLines(yyextra->current->doc,yyextra->current->docLine);
@@ -3248,14 +3321,14 @@ bool CommentScanner::parseCommentBlock(/* in */ OutlineParserInterface *pars
Debug::print(Debug::CommentScan,0,"-----------\nCommentScanner: %s:%d\noutput=[\n"
"brief=[line=%d\n%s]\ndocs=[line=%d\n%s]\ninbody=[line=%d\n%s]\n]\n===========\n",
qPrint(fileName),lineNr,
- yyextra->current->briefLine,qPrint(yyextra->current->brief),
+ yyextra->current->briefLine,qPrint(yyextra->current->brief),
yyextra->current->docLine,qPrint(yyextra->current->doc),
yyextra->current->inbodyLine,qPrint(yyextra->current->inbodyDocs)
);
-
+
checkFormula(yyscanner);
prot = yyextra->protection;
-
+
yyextra->docGroup.addDocs(curEntry);
newEntryNeeded = yyextra->needNewEntry;
@@ -3285,7 +3358,7 @@ static void handleGuard(yyscan_t yyscanner,const QCString &expr)
if (parentEnabled)
{
if (
- (sectionEnabled && yyextra->guardType==Guard_If) ||
+ (sectionEnabled && yyextra->guardType==Guard_If) ||
(!sectionEnabled && yyextra->guardType==Guard_IfNot)
) // section is visible
{
diff --git a/src/condparser.cpp b/src/condparser.cpp
index e76b164..ac6ff61 100644
--- a/src/condparser.cpp
+++ b/src/condparser.cpp
@@ -2,8 +2,8 @@
* 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
+ * 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.
*
@@ -19,6 +19,8 @@
* ! NOT operator
*/
+#include <algorithm>
+
#include "condparser.h"
#include "config.h"
#include "message.h"
@@ -27,7 +29,7 @@
/**
* parses and evaluates the given expression.
- * @returns
+ * @returns
* - On error, an error message is returned.
* - On success, the result of the expression is either "1" or "0".
*/
@@ -123,13 +125,13 @@ int CondParser::getOperatorId(const QCString &opName)
/**
* Get next token in the current string expr.
- * Uses the data in m_expr pointed to by m_e to
+ * Uses the data in m_expr pointed to by m_e to
* produce m_tokenType and m_token, set m_err in case of an error
*/
void CondParser::getToken()
{
m_tokenType = NOTHING;
- m_token.resize(0);
+ m_token.resize(0);
//printf("\tgetToken e:{%c}, ascii=%i, col=%i\n", *e, *e, e-expr);
@@ -303,7 +305,7 @@ bool CondParser::evalOperator(int opId, bool lhs, bool rhs)
*/
bool CondParser::evalVariable(const char *varName)
{
- if (Config_getList(ENABLED_SECTIONS).find(varName)==-1) return FALSE;
- return TRUE;
+ const StringVector &list = Config_getList(ENABLED_SECTIONS);
+ return std::find(list.begin(),list.end(),varName)!=list.end();
}
diff --git a/src/config.h b/src/config.h
index 1b79b1e..31be3a1 100644
--- a/src/config.h
+++ b/src/config.h
@@ -24,19 +24,24 @@ class FTextStream;
//! @{
//! some convenience macros for accessing the config options
//! mainly done like this for backward compatibility
-#if DYNAMIC_LOOKUP // for debug purposes
-#define Config_getString(val) (ConfigValues::instance().*((ConfigValues::InfoString*)ConfigValues::instance().get(#val))->item)
-#define Config_getBool(val) (ConfigValues::instance().*((ConfigValues::InfoBool*)ConfigValues::instance().get(#val))->item)
-#define Config_getInt(val) (ConfigValues::instance().*((ConfigValues::InfoInt*)ConfigValues::instance().get(#val))->item)
-#define Config_getEnum(val) (ConfigValues::instance().*((ConfigValues::InfoString*)ConfigValues::instance().get(#val))->item)
-#define Config_getList(val) (ConfigValues::instance().*((ConfigValues::InfoList*)ConfigValues::instance().get(#val))->item)
-#else // direct access
-#define Config_getString(val) (ConfigValues::instance().val)
-#define Config_getBool(val) (ConfigValues::instance().val)
-#define Config_getInt(val) (ConfigValues::instance().val)
-#define Config_getEnum(val) (ConfigValues::instance().val)
-#define Config_getList(val) (ConfigValues::instance().val)
-#endif
+//#if DYNAMIC_LOOKUP // for debug purposes
+//#define Config_getString(val) (ConfigValues::instance().*((ConfigValues::InfoString*)ConfigValues::instance().get(#val))->item)
+//#define Config_getBool(val) (ConfigValues::instance().*((ConfigValues::InfoBool*)ConfigValues::instance().get(#val))->item)
+//#define Config_getInt(val) (ConfigValues::instance().*((ConfigValues::InfoInt*)ConfigValues::instance().get(#val))->item)
+//#define Config_getEnum(val) (ConfigValues::instance().*((ConfigValues::InfoString*)ConfigValues::instance().get(#val))->item)
+//#define Config_getList(val) (ConfigValues::instance().*((ConfigValues::InfoList*)ConfigValues::instance().get(#val))->item)
+//#else // direct access
+#define Config_getString(name) (ConfigValues::instance().name())
+#define Config_getBool(name) (ConfigValues::instance().name())
+#define Config_getInt(name) (ConfigValues::instance().name())
+#define Config_getEnum(name) (ConfigValues::instance().name())
+#define Config_getList(name) (ConfigValues::instance().name())
+#define Config_updateString(name,value) (ConfigValues::instance().update_##name(value));
+#define Config_updateBool(name,value) (ConfigValues::instance().update_##name(value));
+#define Config_updateInt(name,value) (ConfigValues::instance().update_##name(value));
+#define Config_updateEnum(name,value) (ConfigValues::instance().update_##name(value));
+#define Config_updateList(name,...) (ConfigValues::instance().update_##name(__VA_ARGS__));
+//#endif
//! @}
/** \brief Public function to deal with the configuration file. */
diff --git a/src/config.xml b/src/config.xml
index 6a87a0b..81610c0 100644
--- a/src/config.xml
+++ b/src/config.xml
@@ -950,7 +950,7 @@ Go to the <a href="commands.html">next</a> section or return to the
will only generate file names in lower-case letters. If set to
\c YES, upper-case letters are also allowed. This is useful if you have
classes or files whose names only differ in case and if your file system
- supports case sensitive file names. Windows (including Cygwin) ands
+ supports case sensitive file names. Windows (including Cygwin) and
Mac users are advised to set this option to \c NO.
]]>
</docs>
@@ -1705,10 +1705,12 @@ to disable this feature.
<docs>
<![CDATA[
If clang assisted parsing is enabled you can provide the clang parser with the
- path to the <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html">
- compilation database</a> used when the files were built. This is equivalent to
- specifying the "-p" option to a clang tool, such as clang-check. These options
- will then be passed to the parser.
+ path to the directory containing a file called compile_commands.json.
+ This file is the <a href="http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html">
+ compilation database</a> containing the options used when the source files were built.
+ This is equivalent to specifying the "-p" option to a clang tool, such as clang-check.
+ These options will then be passed to the parser. Any options specified with
+ \ref cfg_clang_options "CLANG_OPTIONS" will be added as well.
@note The availability of this option depends on whether or not doxygen
was generated with the `-Duse_libclang=ON` option for CMake.
@@ -2154,7 +2156,7 @@ The \c DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
<![CDATA[
The \c GENERATE_CHI flag
controls if a separate `.chi` index file is generated (\c YES) or that
- it should be included in the master `.chm` file (\c NO).
+ it should be included in the main `.chm` file (\c NO).
]]>
</docs>
</option>
@@ -2756,9 +2758,12 @@ or
<option type='bool' id='USE_PDFLATEX' defval='1' depends='GENERATE_LATEX'>
<docs>
<![CDATA[
- If the \c USE_PDFLATEX tag is set to \c YES, doxygen will use
- \c pdflatex to generate the PDF file directly from the \f$\mbox{\LaTeX}\f$
+ If the \c USE_PDFLATEX tag is set to \c YES, doxygen will use the engine
+ as specified with \ref cfg_latex_cmd_name "LATEX_CMD_NAME"
+ to generate the PDF file directly from the \f$\mbox{\LaTeX}\f$
files. Set this option to \c YES, to get a higher quality PDF documentation.
+<br>
+ See also section \ref cfg_latex_cmd_name "LATEX_CMD_NAME" for selecting the engine.
]]>
</docs>
</option>
@@ -3029,9 +3034,8 @@ front of it.
</docs>
</option>
</group>
-<!--
- <group name='Sqlite3' docs='Configuration options related to Sqlite3 output'>
- <option type='bool' id='GENERATE_SQLITE3' defval='0'>
+ <group name='Sqlite3' setting='USE_SQLITE3' docs='Configuration options related to Sqlite3 output'>
+ <option type='bool' id='GENERATE_SQLITE3' setting='USE_SQLITE3' defval='0'>
<docs>
<![CDATA[
If the \c GENERATE_SQLITE3 tag is set to \c YES doxygen will generate a
@@ -3039,7 +3043,7 @@ If the \c GENERATE_SQLITE3 tag is set to \c YES doxygen will generate a
]]>
</docs>
</option>
- <option type='string' id='SQLITE3_OUTPUT' format='dir' defval='sqlite3' depends='GENERATE_SQLITE3'>
+ <option type='string' id='SQLITE3_OUTPUT' format='dir' defval='sqlite3' setting='USE_SQLITE3' depends='GENERATE_SQLITE3'>
<docs>
<![CDATA[
The \c SQLITE3_OUTPUT tag is used to specify where the \c Sqlite3 database will be put.
@@ -3048,9 +3052,17 @@ put in front of it.
]]>
</docs>
</option>
+ <option type='bool' id='SQLITE3_RECREATE_DB' defval='1' setting='USE_SQLITE3' depends='GENERATE_SQLITE3'>
+ <docs>
+<![CDATA[
+The \c SQLITE3_OVERWRITE_DB tag is set to \c YES, the existing doxygen_sqlite3.db
+database file will be recreated with each doxygen run.
+If set to \c NO, doxygen will warn if an a database file is already found and not modify it.
+]]>
+ </docs>
+ </option>
</group>
--->
<group name='PerlMod' docs='Configuration options related to the Perl module output'>
<option type='bool' id='GENERATE_PERLMOD' defval='0'>
<docs>
diff --git a/src/configgen.py b/src/configgen.py
index 6720116..4ffa8f8 100755
--- a/src/configgen.py
+++ b/src/configgen.py
@@ -345,6 +345,9 @@ def parseOption(node):
def parseGroups(node):
name = node.getAttribute('name')
doc = node.getAttribute('docs')
+ setting = node.getAttribute('setting')
+ if len(setting) > 0:
+ print("#if %s" % (setting))
print("%s%s" % (" //-----------------------------------------",
"----------------------------------"))
print(" cfg->addInfo(\"%s\",\"%s\");" % (name, doc))
@@ -354,9 +357,40 @@ def parseGroups(node):
for n in node.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
parseOption(n)
+ if len(setting) > 0:
+ print("#endif")
+
+
+def parseGroupMapGetter(node):
+ map = { 'bool':'bool', 'string':'const QCString &', 'enum':'const QCString &', 'int':'int', 'list':'const StringVector &' }
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ setting = n.getAttribute('setting')
+ if len(setting) > 0:
+ print("#if %s" % (setting))
+ type = n.getAttribute('type')
+ name = n.getAttribute('id')
+ if type in map:
+ print(" %-20s %-30s const { return m_%s; }" % (map[type],name+'()',name))
+ if len(setting) > 0:
+ print("#endif")
+
+def parseGroupMapSetter(node):
+ map = { 'bool':'bool', 'string':'const QCString &', 'enum':'const QCString &', 'int':'int', 'list':'const StringVector &' }
+ for n in node.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ setting = n.getAttribute('setting')
+ if len(setting) > 0:
+ print("#if %s" % (setting))
+ type = n.getAttribute('type')
+ name = n.getAttribute('id')
+ if type in map:
+ print(" %-20s update_%-46s { m_%s = v; return m_%s; }" % (map[type],name+'('+map[type]+' v)',name,name))
+ if len(setting) > 0:
+ print("#endif")
-def parseGroupMap(node):
- map = { 'bool':'bool', 'string':'QCString', 'enum':'QCString', 'int':'int', 'list':'QStrList' }
+def parseGroupMapVar(node):
+ map = { 'bool':'bool', 'string':'QCString', 'enum':'QCString', 'int':'int', 'list':'StringVector' }
for n in node.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
setting = n.getAttribute('setting')
@@ -365,7 +399,7 @@ def parseGroupMap(node):
type = n.getAttribute('type')
name = n.getAttribute('id')
if type in map:
- print(" %-8s %s;" % (map[type],name))
+ print(" %-12s m_%s;" % (map[type],name))
if len(setting) > 0:
print("#endif")
@@ -379,7 +413,7 @@ def parseGroupInit(node):
type = n.getAttribute('type')
name = n.getAttribute('id')
if type in map:
- print(" %-25s = ConfigImpl::instance()->get%s(__FILE__,__LINE__,\"%s\");" % (name,map[type],name))
+ print(" %-25s = ConfigImpl::instance()->get%s(__FILE__,__LINE__,\"%s\");" % ('m_'+name,map[type],name))
if len(setting) > 0:
print("#endif")
@@ -393,7 +427,7 @@ def parseGroupMapInit(node):
type = n.getAttribute('type')
name = n.getAttribute('id')
if type in map:
- print(" m_map.insert(\"%s\",new Info%s(&ConfigValues::%s));" % (name,map[type],name))
+ print(" { %-25s Info{ %-13s &ConfigValues::m_%s }}," % ('\"'+name+'\",','Info::'+map[type]+',',name))
if len(setting) > 0:
print("#endif")
@@ -652,6 +686,7 @@ def main():
print("#include <qdict.h>")
print("#include <qstrlist.h>")
print("#include <qcstring.h>")
+ print("#include \"containers.h\"")
print("#include \"settings.h\"")
print("")
print("class ConfigValues")
@@ -661,42 +696,38 @@ def main():
for n in elem.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
if (n.nodeName == "group"):
- parseGroupMap(n)
+ parseGroupMapGetter(n)
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ parseGroupMapSetter(n)
print(" void init();")
- print(" struct Info")
- print(" {")
- print(" enum Type { Bool, Int, String, List, Unknown };")
- print(" Info(Type t) : type(t) {}")
- print(" virtual ~Info() {}")
- print(" Type type;")
- print(" };")
- print(" struct InfoBool : public Info")
- print(" {")
- print(" InfoBool(bool ConfigValues::*ptm) : Info(Info::Bool), item(ptm) {}")
- print(" bool ConfigValues::*item;")
- print(" };")
- print(" struct InfoInt : public Info")
- print(" {")
- print(" InfoInt(int ConfigValues::*ptm) : Info(Info::Int), item(ptm) {}")
- print(" int ConfigValues::*item;")
- print(" };")
- print(" struct InfoString : public Info")
- print(" {")
- print(" InfoString(QCString ConfigValues::*ptm) : Info(Info::String), item(ptm) {}")
- print(" QCString ConfigValues::*item;")
- print(" };")
- print(" struct InfoList : public Info")
- print(" {")
- print(" InfoList(QStrList ConfigValues::*ptm) : Info(Info::List), item(ptm) {}")
- print(" QStrList ConfigValues::*item;")
- print(" };")
- print(" const Info *get(const char *tag) const")
- print(" {")
- print(" return m_map.find(tag);")
- print(" }")
+ print(" struct Info");
+ print(" {");
+ print(" enum Type { Bool, Int, String, List, Unknown };");
+ print(" Info(Type t,bool ConfigValues::*b) : type(t), value(b) {}");
+ print(" Info(Type t,int ConfigValues::*i) : type(t), value(i) {}");
+ print(" Info(Type t,QCString ConfigValues::*s) : type(t), value(s) {}");
+ print(" Info(Type t,StringVector ConfigValues::*l) : type(t), value(l) {}");
+ print(" Type type;");
+ print(" union Item");
+ print(" {");
+ print(" Item(bool ConfigValues::*v) : b(v) {}");
+ print(" Item(int ConfigValues::*v) : i(v) {}");
+ print(" Item(QCString ConfigValues::*v) : s(v) {}");
+ print(" Item(StringVector ConfigValues::*v) : l(v) {}");
+ print(" bool ConfigValues::*b;");
+ print(" int ConfigValues::*i;");
+ print(" QCString ConfigValues::*s;");
+ print(" StringVector ConfigValues::*l;");
+ print(" } value;");
+ print(" };");
+ print(" const Info *get(const char *tag) const;");
print(" private:")
- print(" ConfigValues();")
- print(" QDict<Info> m_map;")
+ for n in elem.childNodes:
+ if n.nodeType == Node.ELEMENT_NODE:
+ if (n.nodeName == "group"):
+ parseGroupMapVar(n)
print("};")
print("")
print("#endif")
@@ -707,15 +738,20 @@ def main():
print(" */")
print("#include \"configvalues.h\"")
print("#include \"configimpl.h\"")
+ print("#include <unordered_map>")
print("")
- print("ConfigValues::ConfigValues() : m_map(257)")
- print("{")
- print(" m_map.setAutoDelete(TRUE);")
+ print("const ConfigValues::Info *ConfigValues::get(const char *tag) const");
+ print("{");
+ print(" static const std::unordered_map< std::string, Info > configMap =");
+ print(" {");
for n in elem.childNodes:
if n.nodeType == Node.ELEMENT_NODE:
if (n.nodeName == "group"):
parseGroupMapInit(n)
- print("}")
+ print(" };");
+ print(" auto it = configMap.find(tag);");
+ print(" return it!=configMap.end() ? &it->second : nullptr;");
+ print("}");
print("")
print("void ConfigValues::init()")
print("{")
diff --git a/src/configimpl.h b/src/configimpl.h
index 6134088..a267cc6 100644
--- a/src/configimpl.h
+++ b/src/configimpl.h
@@ -1,13 +1,13 @@
/******************************************************************************
*
- *
+ *
*
*
* 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
+ * 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.
*
@@ -24,6 +24,7 @@
#include <qlist.h>
#include <qregexp.h>
#include "ftextstream.h"
+#include "containers.h"
/** Abstract base class for any configuration option.
@@ -35,8 +36,8 @@ class ConfigOption
public:
/*! The type of option */
- enum OptionType
- {
+ enum OptionType
+ {
O_Info, //!< A section header
O_List, //!< A list of items
O_Enum, //!< A fixed set of items
@@ -46,14 +47,14 @@ class ConfigOption
O_Obsolete, //!< An obsolete option
O_Disabled //!< Disabled compile time option
};
- enum
- {
- /*! Maximum length of an option in the config file. Used for
+ enum
+ {
+ /*! Maximum length of an option in the config file. Used for
* alignment purposes.
*/
- MAX_OPTION_LENGTH = 23
+ MAX_OPTION_LENGTH = 23
};
- ConfigOption(OptionType t) : m_kind(t)
+ ConfigOption(OptionType t) : m_kind(t)
{
m_spaces.fill(' ',40);
}
@@ -81,8 +82,8 @@ class ConfigOption
void writeBoolValue(FTextStream &t,bool v);
void writeIntValue(FTextStream &t,int i);
- void writeStringValue(FTextStream &t,QCString &s);
- void writeStringList(FTextStream &t,QStrList &l);
+ void writeStringValue(FTextStream &t,const QCString &s);
+ void writeStringList(FTextStream &t,const StringVector &l);
QCString m_spaces;
QCString m_name;
@@ -98,7 +99,7 @@ class ConfigOption
class ConfigInfo : public ConfigOption
{
public:
- ConfigInfo(const char *name,const char *doc)
+ ConfigInfo(const char *name,const char *doc)
: ConfigOption(O_Info)
{
m_name = name;
@@ -115,25 +116,25 @@ class ConfigList : public ConfigOption
{
public:
enum WidgetType { String, File, Dir, FileAndDir };
- ConfigList(const char *name,const char *doc)
+ ConfigList(const char *name,const char *doc)
: ConfigOption(O_List)
{
m_name = name;
m_doc = doc;
m_widgetType = String;
}
- void addValue(const char *v) { m_defaultValue.append(v); }
+ void addValue(const char *v) { m_defaultValue.push_back(v); }
void setWidgetType(WidgetType w) { m_widgetType = w; }
WidgetType widgetType() const { return m_widgetType; }
- QStrList *valueRef() { return &m_value; }
- QStrList getDefault() { return m_defaultValue; }
+ StringVector *valueRef() { return &m_value; }
+ StringVector getDefault() { return m_defaultValue; }
void writeTemplate(FTextStream &t,bool sl,bool);
void compareDoxyfile(FTextStream &t);
void substEnvVars();
void init() { m_value = m_defaultValue; }
private:
- QStrList m_value;
- QStrList m_defaultValue;
+ StringVector m_value;
+ StringVector m_defaultValue;
WidgetType m_widgetType;
};
@@ -142,7 +143,7 @@ class ConfigList : public ConfigOption
class ConfigEnum : public ConfigOption
{
public:
- ConfigEnum(const char *name,const char *doc,const char *defVal)
+ ConfigEnum(const char *name,const char *doc,const char *defVal)
: ConfigOption(O_Enum)
{
m_name = name;
@@ -151,7 +152,7 @@ class ConfigEnum : public ConfigOption
m_defValue = defVal;
}
void addValue(const char *v) { m_valueRange.append(v); }
- QStrListIterator iterator()
+ QStrListIterator iterator()
{
return QStrListIterator(m_valueRange);
}
@@ -174,7 +175,7 @@ class ConfigString : public ConfigOption
{
public:
enum WidgetType { String, File, Dir, Image };
- ConfigString(const char *name,const char *doc)
+ ConfigString(const char *name,const char *doc)
: ConfigOption(O_String)
{
m_name = name;
@@ -193,7 +194,7 @@ class ConfigString : public ConfigOption
void substEnvVars();
void init() { m_value = m_defValue.copy(); }
void emptyValueToDefault() { if(m_value.isEmpty()) m_value=m_defValue; };
-
+
private:
QCString m_value;
QCString m_defValue;
@@ -205,7 +206,7 @@ class ConfigString : public ConfigOption
class ConfigInt : public ConfigOption
{
public:
- ConfigInt(const char *name,const char *doc,int minVal,int maxVal,int defVal)
+ ConfigInt(const char *name,const char *doc,int minVal,int maxVal,int defVal)
: ConfigOption(O_Int)
{
m_name = name;
@@ -237,7 +238,7 @@ class ConfigInt : public ConfigOption
class ConfigBool : public ConfigOption
{
public:
- ConfigBool(const char *name,const char *doc,bool defVal)
+ ConfigBool(const char *name,const char *doc,bool defVal)
: ConfigOption(O_Bool)
{
m_name = name;
@@ -264,7 +265,7 @@ class ConfigBool : public ConfigOption
class ConfigObsolete : public ConfigOption
{
public:
- ConfigObsolete(const char *name) : ConfigOption(O_Obsolete)
+ ConfigObsolete(const char *name) : ConfigOption(O_Obsolete)
{ m_name = name; }
void writeTemplate(FTextStream &,bool,bool);
void compareDoxyfile(FTextStream &) {}
@@ -276,7 +277,7 @@ class ConfigObsolete : public ConfigOption
class ConfigDisabled : public ConfigOption
{
public:
- ConfigDisabled(const char *name) : ConfigOption(O_Disabled)
+ ConfigDisabled(const char *name) : ConfigOption(O_Disabled)
{ m_name = name; }
void writeTemplate(FTextStream &,bool,bool);
void compareDoxyfile(FTextStream &) {}
@@ -297,7 +298,7 @@ class ConfigDisabled : public ConfigOption
* read from a user-supplied configuration file.
* The static member instance() can be used to get
* a pointer to the one and only instance.
- *
+ *
* Set all variables to their default values by
* calling Config::instance()->init()
*
@@ -321,8 +322,8 @@ class ConfigImpl
delete m_instance;
m_instance=0;
}
-
- /*! Returns an iterator that can by used to iterate over the
+
+ /*! Returns an iterator that can by used to iterate over the
* configuration options.
*/
QListIterator<ConfigOption> iterator()
@@ -330,36 +331,36 @@ class ConfigImpl
return QListIterator<ConfigOption>(*m_options);
}
- /*!
+ /*!
* @name Getting configuration values.
* @{
*/
- /*! Returns the value of the string option with name \a fileName.
+ /*! Returns the value of the string option with name \a fileName.
* The arguments \a num and \a name are for debugging purposes only.
* There is a convenience function Config_getString() for this.
*/
QCString &getString(const char *fileName,int num,const char *name) const;
- /*! Returns the value of the list option with name \a fileName.
+ /*! Returns the value of the list option with name \a fileName.
* The arguments \a num and \a name are for debugging purposes only.
* There is a convenience function Config_getList() for this.
*/
- QStrList &getList(const char *fileName,int num,const char *name) const;
+ StringVector &getList(const char *fileName,int num,const char *name) const;
- /*! Returns the value of the enum option with name \a fileName.
+ /*! Returns the value of the enum option with name \a fileName.
* The arguments \a num and \a name are for debugging purposes only.
* There is a convenience function Config_getEnum() for this.
*/
QCString &getEnum(const char *fileName,int num,const char *name) const;
- /*! Returns the value of the integer option with name \a fileName.
+ /*! Returns the value of the integer option with name \a fileName.
* The arguments \a num and \a name are for debugging purposes only.
* There is a convenience function Config_getInt() for this.
*/
int &getInt(const char *fileName,int num,const char *name) const;
- /*! Returns the value of the boolean option with name \a fileName.
+ /*! Returns the value of the boolean option with name \a fileName.
* The arguments \a num and \a name are for debugging purposes only.
* There is a convenience function Config_getBool() for this.
*/
@@ -370,12 +371,12 @@ class ConfigImpl
*/
ConfigOption *get(const char *name) const
{
- return m_dict->find(name);
+ return m_dict->find(name);
}
/* @} */
- /*!
- * @name Adding configuration options.
+ /*!
+ * @name Adding configuration options.
* @{
*/
@@ -402,7 +403,7 @@ class ConfigImpl
}
/*! Adds a new enumeration option with \a name and documentation \a doc
- * and initial value \a defVal.
+ * and initial value \a defVal.
* \returns An object representing the option.
*/
ConfigEnum *addEnum(const char *name,
@@ -510,18 +511,18 @@ class ConfigImpl
/*! Parse a configuration data in string \a str.
* \returns TRUE if successful, or FALSE if the string could not be
* parsed.
- */
+ */
//bool parseString(const char *fn,const char *str);
bool parseString(const char *fn,const char *str,bool upd = FALSE);
/*! Parse a configuration file with name \a fn.
- * \returns TRUE if successful, FALSE if the file could not be
+ * \returns TRUE if successful, FALSE if the file could not be
* opened or read.
- */
+ */
bool parse(const char *fn,bool upd = FALSE);
/*! Called from the constructor, will add doxygen's default options
- * to the configuration object
+ * to the configuration object
*/
void create();
diff --git a/src/configimpl.l b/src/configimpl.l
index da94484..9eda61d 100644
--- a/src/configimpl.l
+++ b/src/configimpl.l
@@ -1,10 +1,10 @@
/******************************************************************************
*
- * 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
- * granted. No representations are made about the suitability of this software
+ * 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.
*
@@ -29,11 +29,12 @@
#include <qfileinfo.h>
#include <qdir.h>
-#include <qtextstream.h>
#include <qregexp.h>
#include <qstack.h>
#include <qglobal.h>
+
#include <thread>
+#include <algorithm>
#include "configimpl.h"
#include "version.h"
@@ -61,7 +62,7 @@ void config_err(const char *fmt, ...)
va_list args;
va_start(args, fmt);
vfprintf(stderr, (QCString(error_str) + fmt).data(), args);
- va_end(args);
+ va_end(args);
}
void config_term(const char *fmt, ...)
{
@@ -141,7 +142,7 @@ void ConfigOption::writeIntValue(FTextStream &t,int i)
t << " " << i;
}
-void ConfigOption::writeStringValue(FTextStream &t,QCString &s)
+void ConfigOption::writeStringValue(FTextStream &t,const QCString &s)
{
char c;
bool needsEscaping=FALSE;
@@ -151,10 +152,10 @@ void ConfigOption::writeStringValue(FTextStream &t,QCString &s)
if (p)
{
t << " ";
- while ((c=*p++)!=0 && !needsEscaping)
+ while ((c=*p++)!=0 && !needsEscaping)
needsEscaping = (c==' ' || c=='\n' || c=='\t' || c=='"' || c=='#');
if (needsEscaping)
- {
+ {
t << "\"";
p=se.data();
while (*p)
@@ -172,19 +173,17 @@ void ConfigOption::writeStringValue(FTextStream &t,QCString &s)
}
}
-void ConfigOption::writeStringList(FTextStream &t,QStrList &l)
+void ConfigOption::writeStringList(FTextStream &t,const StringVector &l)
{
- const char *p = l.first();
bool first=TRUE;
- while (p)
+ for (const auto &p : l)
{
- QCString s=p;
+ if (!first) t << " \\" << endl;
+ QCString s=p.c_str();
if (!first)
t << " ";
- first=FALSE;
writeStringValue(t,s);
- p = l.next();
- if (p) t << " \\" << endl;
+ first=FALSE;
}
}
@@ -193,7 +192,7 @@ void ConfigOption::writeStringList(FTextStream &t,QStrList &l)
ConfigImpl *ConfigImpl::m_instance = 0;
-void ConfigInt::convertStrToVal()
+void ConfigInt::convertStrToVal()
{
if (!m_valueString.isEmpty())
{
@@ -216,7 +215,7 @@ void ConfigBool::convertStrToVal()
QCString val = m_valueString.stripWhiteSpace().lower();
if (!val.isEmpty())
{
- if (val=="yes" || val=="true" || val=="1" || val=="all")
+ if (val=="yes" || val=="true" || val=="1" || val=="all")
{
m_value=TRUE;
}
@@ -259,7 +258,7 @@ void ConfigEnum::convertStrToVal()
QCString &ConfigImpl::getString(const char *fileName,int num,const char *name) const
{
ConfigOption *opt = m_dict->find(name);
- if (opt==0)
+ if (opt==0)
{
config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
}
@@ -270,10 +269,10 @@ QCString &ConfigImpl::getString(const char *fileName,int num,const char *name) c
return *((ConfigString *)opt)->valueRef();
}
-QStrList &ConfigImpl::getList(const char *fileName,int num,const char *name) const
+StringVector &ConfigImpl::getList(const char *fileName,int num,const char *name) const
{
ConfigOption *opt = m_dict->find(name);
- if (opt==0)
+ if (opt==0)
{
config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
}
@@ -287,7 +286,7 @@ QStrList &ConfigImpl::getList(const char *fileName,int num,const char *name) con
QCString &ConfigImpl::getEnum(const char *fileName,int num,const char *name) const
{
ConfigOption *opt = m_dict->find(name);
- if (opt==0)
+ if (opt==0)
{
config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
}
@@ -301,7 +300,7 @@ QCString &ConfigImpl::getEnum(const char *fileName,int num,const char *name) con
int &ConfigImpl::getInt(const char *fileName,int num,const char *name) const
{
ConfigOption *opt = m_dict->find(name);
- if (opt==0)
+ if (opt==0)
{
config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
}
@@ -315,7 +314,7 @@ int &ConfigImpl::getInt(const char *fileName,int num,const char *name) const
bool &ConfigImpl::getBool(const char *fileName,int num,const char *name) const
{
ConfigOption *opt = m_dict->find(name);
- if (opt==0)
+ if (opt==0)
{
config_term("%s<%d>: Internal error: Requested unknown option %s!\n",fileName,num,name);
}
@@ -358,71 +357,33 @@ void ConfigList::writeTemplate(FTextStream &t,bool sl,bool)
void ConfigList::compareDoxyfile(FTextStream &t)
{
- const char *p = m_value.first();
- const char *q = m_defaultValue.first();
- int defCnt = 0;
- int valCnt = 0;
-
- // count non empty elements
- while (p)
- {
- QCString s=p;
- if (!s.stripWhiteSpace().isEmpty()) valCnt += 1;
- p = m_value.next();
- }
-
- while (q)
- {
- QCString s=q;
- if (!s.stripWhiteSpace().isEmpty()) defCnt += 1;
- q = m_defaultValue.next();
- }
+ auto get_stripped = [](std::string s) { return QCString(s.c_str()).stripWhiteSpace(); };
+ auto is_not_empty = [get_stripped](std::string s) { return !get_stripped(s).isEmpty(); };
+ int defCnt = std::count_if( m_value.begin(), m_value.end(),is_not_empty);
+ int valCnt = std::count_if(m_defaultValue.begin(),m_defaultValue.end(),is_not_empty);
if ( valCnt != defCnt)
{
writeTemplate(t,TRUE,TRUE);
return;
}
-
- // get first non empry element
- q = m_defaultValue.first();
- p = m_value.first();
- QCString sp = p;
- while (p && sp.stripWhiteSpace().isEmpty())
+ auto it1 = m_value.begin();
+ auto it2 = m_defaultValue.begin();
+ while (it1!=m_value.end() && it2!=m_defaultValue.end())
{
- p = m_value.next();
- sp = p;
- }
- QCString sq = q;
- while (q && sq.stripWhiteSpace().isEmpty())
- {
- q = m_value.next();
- sq = q;
- }
- while (p)
- {
- // skip empty elements
- sp = p;
- while (p && sp.stripWhiteSpace().isEmpty())
+ // skip over empty values
+ while (it1!=m_value.end() && !is_not_empty(*it1))
{
- p = m_value.next();
- sp = p;
+ ++it1;
}
- sq = q;
- while (q && sq.stripWhiteSpace().isEmpty())
+ if (it1!=m_value.end()) // non-empty value
{
- q = m_value.next();
- sq = q;
- }
- // be sure we have still an element (p and q have same number of 'filled' elements)
- if (p)
- {
- if (sp.stripWhiteSpace() != sq.stripWhiteSpace())
+ if (get_stripped(*it1) != get_stripped(*it2)) // not the default, write as difference
{
writeTemplate(t,TRUE,TRUE);
return;
}
- p = m_value.next();
- q = m_defaultValue.next();
+ ++it1;
+ ++it2;
}
}
}
@@ -544,7 +505,7 @@ struct ConfigFileState
YY_BUFFER_STATE oldState;
YY_BUFFER_STATE newState;
QCString fileName;
-};
+};
static const char *g_inputString;
static int g_inputPosition;
@@ -553,11 +514,11 @@ static QCString g_yyFileName;
static QCString g_tmpString;
static QCString *g_string=0;
static bool *g_bool=0;
-static QStrList *g_list=0;
+static StringVector *g_list=0;
static int g_lastState;
static QCString g_elemStr;
-static QStrList g_includePathList;
-static QStack<ConfigFileState> g_includeStack;
+static StringVector g_includePathList;
+static QStack<ConfigFileState> g_includeStack;
static int g_includeDepth;
static bool g_configUpdate = FALSE;
static QCString g_encoding;
@@ -571,7 +532,7 @@ static ConfigImpl *g_config;
static yy_size_t yyread(char *buf,yy_size_t max_size)
{
// no file included
- if (g_includeStack.isEmpty())
+ if (g_includeStack.isEmpty())
{
yy_size_t c=0;
if (g_inputString==0) return c;
@@ -602,7 +563,7 @@ static QCString configStringRecode(
int outputSize=inputSize*4+1;
QCString output(outputSize);
void *cd = portable_iconv_open(outputEncoding,inputEncoding);
- if (cd==(void *)(-1))
+ if (cd==(void *)(-1))
{
config_term("Error: unsupported character conversion: '%s'->'%s'\n",
inputEncoding.data(),outputEncoding.data());
@@ -646,7 +607,7 @@ static FILE *tryPath(const char *path,const char *fileName)
return 0;
}
-static void substEnvVarsInStrList(QStrList &sl);
+static void substEnvVarsInStrList(StringVector &sl);
static void substEnvVarsInString(QCString &s);
static FILE *findFile(const char *fileName)
@@ -660,13 +621,11 @@ static FILE *findFile(const char *fileName)
return tryPath(NULL, fileName);
}
substEnvVarsInStrList(g_includePathList);
- char *s=g_includePathList.first();
- while (s) // try each of the include paths
+ for (const auto &s : g_includePathList)
{
- FILE *f = tryPath(s,fileName);
+ FILE *f = tryPath(s.c_str(),fileName);
if (f) return f;
- s=g_includePathList.next();
- }
+ }
// try cwd if g_includePathList fails
return tryPath(".",fileName);
}
@@ -676,7 +635,7 @@ static void readIncludeFile(const char *incName)
if (g_includeDepth==MAX_INCLUDE_DEPTH) {
config_term("maximum include depth (%d) reached, %s is not included. Aborting...\n",
MAX_INCLUDE_DEPTH,incName);
- }
+ }
QCString inc = incName;
substEnvVarsInString(inc);
@@ -697,7 +656,7 @@ static void readIncludeFile(const char *incName)
msg("@INCLUDE = %s: parsing...\n",inc.data());
#endif
- // store the state of the old file
+ // store the state of the old file
ConfigFileState *fs=new ConfigFileState;
fs->oldState=YY_CURRENT_BUFFER;
fs->lineNr=g_yyLineNr;
@@ -710,7 +669,7 @@ static void readIncludeFile(const char *incName)
fs->newState=YY_CURRENT_BUFFER;
g_yyFileName=inc;
g_includeDepth++;
- }
+ }
else
{
config_term("@INCLUDE = %s: not found!\n",inc.data());
@@ -745,12 +704,12 @@ static void readIncludeFile(const char *incName)
<Start,GetString,GetStrList,GetStrList1,GetBool,SkipInvalid>"##".*"\n" { g_config->appendUserComment(yytext);g_yyLineNr++;}
<Start,GetString,GetStrList,GetStrList1,GetBool,SkipInvalid>"#" { BEGIN(SkipComment); }
<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"=" { QCString cmd=yytext;
- cmd=cmd.left(cmd.length()-1).stripWhiteSpace();
+ cmd=cmd.left(cmd.length()-1).stripWhiteSpace();
ConfigOption *option = g_config->get(cmd);
if (option==0) // oops not known
{
config_warn("ignoring unsupported tag '%s' at line %d, file %s\n",
- cmd.data(),g_yyLineNr,g_yyFileName.data());
+ cmd.data(),g_yyLineNr,g_yyFileName.data());
BEGIN(SkipInvalid);
}
else // known tag
@@ -806,7 +765,7 @@ static void readIncludeFile(const char *incName)
{
config_warn("Tag '%s' at line %d of file '%s' has become obsolete.\n"
" To avoid this warning please remove this line from your configuration "
- "file or upgrade it using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
+ "file or upgrade it using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
}
BEGIN(SkipInvalid);
break;
@@ -820,7 +779,7 @@ static void readIncludeFile(const char *incName)
{
config_warn("Tag '%s' at line %d of file '%s' belongs to an option that was not enabled at compile time.\n"
" To avoid this warning please remove this line from your configuration "
- "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
+ "file or upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
}
BEGIN(SkipInvalid);
break;
@@ -828,12 +787,12 @@ static void readIncludeFile(const char *incName)
}
}
<Start>[a-z_A-Z][a-z_A-Z0-9]*[ \t]*"+=" { QCString cmd=yytext;
- cmd=cmd.left(cmd.length()-2).stripWhiteSpace();
+ cmd=cmd.left(cmd.length()-2).stripWhiteSpace();
ConfigOption *option = g_config->get(cmd);
if (option==0) // oops not known
{
config_warn("ignoring unsupported tag '%s' at line %d, file %s\n",
- cmd.data(),g_yyLineNr,g_yyFileName.data());
+ cmd.data(),g_yyLineNr,g_yyFileName.data());
BEGIN(SkipInvalid);
}
else // known tag
@@ -862,19 +821,19 @@ static void readIncludeFile(const char *incName)
case ConfigOption::O_Int:
case ConfigOption::O_Bool:
config_warn("operator += not supported for '%s'. Ignoring line at line %d, file %s\n",
- yytext,g_yyLineNr,g_yyFileName.data());
+ yytext,g_yyLineNr,g_yyFileName.data());
BEGIN(SkipInvalid);
break;
case ConfigOption::O_Obsolete:
config_warn("Tag '%s' at line %d of file %s has become obsolete.\n"
"To avoid this warning please update your configuration "
- "file using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
+ "file using \"doxygen -u\"\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
BEGIN(SkipInvalid);
break;
case ConfigOption::O_Disabled:
config_warn("Tag '%s' at line %d of file %s belongs to an option that was not enabled at compile time.\n"
"To avoid this warning please remove this line from your configuration "
- "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
+ "file, upgrade it using \"doxygen -u\", or recompile doxygen with this feature enabled.\n", cmd.data(),g_yyLineNr,g_yyFileName.data());
BEGIN(SkipInvalid);
break;
}
@@ -883,8 +842,8 @@ static void readIncludeFile(const char *incName)
<Start>"@INCLUDE_PATH"[ \t]*"=" { BEGIN(GetStrList); g_list=&g_includePathList; g_list->clear(); g_elemStr=""; }
/* include a g_config file */
<Start>"@INCLUDE"[ \t]*"=" { BEGIN(Include);}
-<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
- readIncludeFile(configStringRecode(yytext,g_encoding,"UTF-8"));
+<Include>([^ \"\t\r\n]+)|("\""[^\n\"]+"\"") {
+ readIncludeFile(configStringRecode(yytext,g_encoding,"UTF-8"));
BEGIN(Start);
}
<<EOF>> {
@@ -912,19 +871,19 @@ static void readIncludeFile(const char *incName)
<Start>[a-z_A-Z0-9]+ { config_warn("ignoring unknown tag '%s' at line %d, file %s\n",yytext,g_yyLineNr,g_yyFileName.data()); }
<GetString,GetBool,SkipInvalid>\n { g_yyLineNr++; BEGIN(Start); }
<GetStrList,GetStrList1>\n {
- g_yyLineNr++;
+ g_yyLineNr++;
if (!g_elemStr.isEmpty())
{
//printf("elemStr1='%s'\n",g_elemStr.data());
- g_list->append(g_elemStr);
+ g_list->push_back(g_elemStr.data());
}
- BEGIN(Start);
+ BEGIN(Start);
}
<GetStrList1>[ \t]+ {
if (!g_elemStr.isEmpty())
{
//printf("elemStr2='%s'\n",g_elemStr.data());
- g_list->append(g_elemStr);
+ g_list->push_back(g_elemStr.data());
}
g_elemStr.resize(0);
}
@@ -932,18 +891,18 @@ static void readIncludeFile(const char *incName)
if (!g_elemStr.isEmpty())
{
//printf("elemStr2='%s'\n",g_elemStr.data());
- g_list->append(g_elemStr);
+ g_list->push_back(g_elemStr.data());
}
g_elemStr.resize(0);
}
-<GetString>[^ \"\t\r\n]+ { (*g_string)+=configStringRecode(yytext,g_encoding,"UTF-8");
+<GetString>[^ \"\t\r\n]+ { (*g_string)+=configStringRecode(yytext,g_encoding,"UTF-8");
checkEncoding();
}
<GetString,GetStrList,GetStrList1,SkipInvalid>"\"" { g_lastState=YY_START;
- BEGIN(GetQuotedString);
- g_tmpString.resize(0);
+ BEGIN(GetQuotedString);
+ g_tmpString.resize(0);
}
-<GetQuotedString>"\""|"\n" {
+<GetQuotedString>"\""|"\n" {
// we add a bogus space to signal that the string was quoted. This space will be stripped later on.
g_tmpString+=" ";
//printf("Quoted String = '%s'\n",g_tmpString.data());
@@ -967,16 +926,16 @@ static void readIncludeFile(const char *incName)
g_tmpString+='"';
}
<GetQuotedString>. { g_tmpString+=*yytext; }
-<GetBool>[a-zA-Z]+ {
- QCString bs=yytext;
+<GetBool>[a-zA-Z]+ {
+ QCString bs=yytext;
bs=bs.upper();
if (bs=="YES" || bs=="1")
*g_bool=TRUE;
else if (bs=="NO" || bs=="0")
*g_bool=FALSE;
- else
+ else
{
- *g_bool=FALSE;
+ *g_bool=FALSE;
config_warn("Invalid value '%s' for "
"boolean tag in line %d, file %s; use YES or NO\n",
bs.data(),g_yyLineNr,g_yyFileName.data());
@@ -991,7 +950,7 @@ static void readIncludeFile(const char *incName)
<SkipComment>\n { g_yyLineNr++; BEGIN(Start); }
<SkipComment>\\[ \r\t]*\n { g_yyLineNr++; BEGIN(Start); }
<*>\\[ \r\t]*\n { g_yyLineNr++; }
-<*>.
+<*>.
<*>\n { g_yyLineNr++ ; }
%%
@@ -1004,7 +963,7 @@ void ConfigImpl::writeTemplate(FTextStream &t,bool sl,bool upd)
/* print first lines of user comment that were at the beginning of the file, might have special meaning for editors */
if (m_startComment)
{
- t << takeStartComment() << endl;
+ t << takeStartComment() << endl;
}
t << "# Doxyfile " << getDoxygenVersion() << endl << endl;
if (!sl)
@@ -1078,12 +1037,12 @@ static void substEnvVarsInString(QCString &s)
//printf("substEnvVarInString(%s) end\n",s.data());
}
-static void substEnvVarsInStrList(QStrList &sl)
+static void substEnvVarsInStrList(StringVector &sl)
{
- char *s = sl.first();
- while (s)
+ StringVector results;
+ for (const auto &s : sl)
{
- QCString result(s);
+ QCString result = s.c_str();
// an argument with quotes will have an extra space at the end, so wasQuoted will be TRUE.
bool wasQuoted = (result.find(' ')!=-1) || (result.find('\t')!=-1);
// here we strip the quote again
@@ -1093,8 +1052,8 @@ static void substEnvVarsInStrList(QStrList &sl)
if (!wasQuoted) /* as a result of the expansion, a single string
may have expanded into a list, which we'll
- add to sl. If the original string already
- contained multiple elements no further
+ add to sl. If the original string already
+ contained multiple elements no further
splitting is done to allow quoted items with spaces! */
{
int l=result.length();
@@ -1105,7 +1064,7 @@ static void substEnvVarsInStrList(QStrList &sl)
{
char c=0;
// skip until start of new word
- while (i<l && ((c=result.at(i))==' ' || c=='\t')) i++;
+ while (i<l && ((c=result.at(i))==' ' || c=='\t')) i++;
p=i; // p marks the start index of the word
// skip until end of a word
while (i<l && ((c=result.at(i))!=' ' && c!='\t' && c!='"')) i++;
@@ -1119,11 +1078,9 @@ static void substEnvVarsInStrList(QStrList &sl)
c=result.at(i);
if (c=='"') // end quote
{
- // replace the string in the list and go to the next item.
- sl.insert(sl.at(),result.mid(p,i-p)); // insert new item before current item.
- sl.next(); // current item is now the old item
+ results.push_back(result.mid(p,i-p).data());
p=i+1;
- break;
+ break;
}
else if (c=='\\') // skip escaped stuff
{
@@ -1133,33 +1090,22 @@ static void substEnvVarsInStrList(QStrList &sl)
}
else if (c==' ' || c=='\t') // separator
{
- // replace the string in the list and go to the next item.
- sl.insert(sl.at(),result.mid(p,i-p)); // insert new item before current item.
- sl.next(); // current item is now the old item
+ if (i>p) results.push_back(result.mid(p,i-p).data());
p=i+1;
}
}
}
if (p!=l) // add the leftover as a string
{
- // replace the string in the list and go to the next item.
- sl.insert(sl.at(),result.right(l-p)); // insert new item before current item.
- sl.next(); // current item is now the old item
+ results.push_back(result.right(l-p).data());
}
}
else // just goto the next element in the list
{
- sl.insert(sl.at(),result);
- sl.next();
+ if (!result.isEmpty()) results.push_back(result.data());
}
- // remove the old unexpanded string from the list
- int i=sl.at();
- sl.remove(); // current item index changes if the last element is removed.
- if (sl.at()==i) // not last item
- s = sl.current();
- else // just removed last item
- s = 0;
}
+ sl = results;
}
void ConfigString::substEnvVars()
@@ -1226,7 +1172,7 @@ void ConfigImpl::init()
void ConfigImpl::create()
{
- if (m_initialized) return;
+ if (m_initialized) return;
m_initialized = TRUE;
addConfigOptions(this);
}
@@ -1249,7 +1195,7 @@ static QCString configFileToString(const char *name)
while ((size=f.readBlock(contents.rawData()+totalSize,bSize))==bSize)
{
totalSize+=bSize;
- contents.resize(totalSize+bSize);
+ contents.resize(totalSize+bSize);
}
totalSize+=size+2;
contents.resize(totalSize);
@@ -1274,7 +1220,7 @@ static QCString configFileToString(const char *name)
QCString contents(fsize+2);
f.readBlock(contents.rawData(),fsize);
f.close();
- if (fsize==0 || contents[fsize-1]=='\n')
+ if (fsize==0 || contents[fsize-1]=='\n')
contents[fsize]='\0';
else
contents[fsize]='\n'; // to help the scanner
@@ -1282,7 +1228,7 @@ static QCString configFileToString(const char *name)
return contents;
}
}
- if (!fileOpened)
+ if (!fileOpened)
{
config_term("cannot open file '%s' for reading\n",name);
}
@@ -1313,59 +1259,42 @@ bool ConfigImpl::parse(const char *fn,bool update)
int retval;
g_encoding = "UTF-8";
printlex(yy_flex_debug, TRUE, __FILE__, fn);
- retval = parseString(fn,configFileToString(fn), update);
+ retval = parseString(fn,configFileToString(fn), update);
printlex(yy_flex_debug, FALSE, __FILE__, fn);
return retval;
}
//----------------------------------------------------------------------
-static void cleanUpPaths(QStrList &str)
+static void cleanUpPaths(StringVector &str)
{
- char *sfp = str.first();
- while (sfp)
+ for (size_t i=0;i<str.size();i++)
{
- char *p = sfp;
- if (p)
- {
- char c;
- while ((c=*p))
- {
- if (c=='\\') *p='/';
- p++;
- }
- }
- QCString path = sfp;
- if ((path.at(0)!='/' && (path.length()<=2 || path.at(1)!=':')) ||
- path.at(path.length()-1)!='/'
- )
+ std::string path = str[i];
+ std::replace(path.begin(),path.end(),'\\','/');
+ if ((path[0]!='/' && (path.size()<=2 || path[1]!=':')) || path[path.size()-1]!='/')
{
- QFileInfo fi(path);
+ QFileInfo fi(path.c_str());
if (fi.exists() && fi.isDir())
{
- int i = str.at();
- QCString path_str = fi.absFilePath().utf8();
- if (path_str[path_str.length()-1]!='/') path_str+='/';
- str.remove();
- if (str.at()==i) // did not remove last item
- str.insert(i,path_str);
- else
- str.append(path_str);
+ path = fi.absFilePath().utf8().data();
+ if (path[path.size()-1]!='/') path+='/';
}
}
- sfp = str.next();
+ str[i]=path;
}
}
-static void checkFileName(QCString &s,const char *optionName)
+static bool checkFileName(const QCString &s,const char *optionName)
{
QCString val = s.stripWhiteSpace().lower();
if ((val=="yes" || val=="true" || val=="1" || val=="all") ||
(val=="no" || val=="false" || val=="0" || val=="none"))
{
err("file name expected for option %s, got %s instead. Ignoring...\n",optionName,s.data());
- s=""; // note the use of &s above: this will change the option value!
+ return false;
}
+ return true;
}
#include "config.h"
@@ -1375,12 +1304,11 @@ void Config::init()
ConfigImpl::instance()->init();
}
-static void checkList(QStrList &list,const char *name, bool equalRequired,bool valueRequired)
+static void checkList(const StringVector &list,const char *name, bool equalRequired,bool valueRequired)
{
- const char *s=list.first();
- while (s)
+ for (const auto &s: list)
{
- QCString item=s;
+ QCString item=s.c_str();
item=item.stripWhiteSpace();
int i=item.find('=');
if (i==-1 && equalRequired)
@@ -1403,7 +1331,6 @@ static void checkList(QStrList &list,const char *name, bool equalRequired,bool v
}
}
}
- s=list.next();
}
}
@@ -1411,17 +1338,18 @@ void Config::checkAndCorrect()
{
ConfigValues::instance().init();
- QCString &warnFormat = Config_getString(WARN_FORMAT);
+ //------------------------
+ // check WARN_FORMAT
+ QCString warnFormat = Config_getString(WARN_FORMAT);
if (warnFormat.stripWhiteSpace().isEmpty())
{
- warnFormat="$file:$line $text";
+ Config_updateString(WARN_FORMAT,"$file:$line $text");
}
else
{
if (warnFormat.find("$file")==-1)
{
warn_uncond("warning format does not contain a $file tag!\n");
-
}
if (warnFormat.find("$line")==-1)
{
@@ -1433,15 +1361,17 @@ void Config::checkAndCorrect()
}
}
- QCString &manExtension = Config_getString(MAN_EXTENSION);
-
+ //------------------------
// set default man page extension if non is given by the user
+ QCString manExtension = Config_getString(MAN_EXTENSION);
if (manExtension.isEmpty())
{
- manExtension=".3";
+ Config_updateString(MAN_EXTENSION,".3");
}
- QCString &paperType = Config_getEnum(PAPER_TYPE);
+ //------------------------
+ // check and correct PAPER_TYPE
+ QCString paperType = Config_getEnum(PAPER_TYPE);
paperType=paperType.lower().stripWhiteSpace();
if (paperType.isEmpty() || paperType=="a4wide")
{
@@ -1453,42 +1383,53 @@ void Config::checkAndCorrect()
err("Unknown page type specified\n");
paperType="a4";
}
+ Config_updateEnum(PAPER_TYPE,paperType);
- QCString &outputLanguage=Config_getEnum(OUTPUT_LANGUAGE);
+ //------------------------
+ // check & correct OUTPUT_LANGUAGE
+ QCString outputLanguage=Config_getEnum(OUTPUT_LANGUAGE);
outputLanguage=outputLanguage.stripWhiteSpace();
if (outputLanguage.isEmpty())
{
outputLanguage = "English";
}
+ Config_updateEnum(OUTPUT_LANGUAGE,outputLanguage);
- QCString &htmlFileExtension=Config_getString(HTML_FILE_EXTENSION);
+ //------------------------
+ // check & correct HTML_FILE_EXTENSION
+ QCString htmlFileExtension=Config_getString(HTML_FILE_EXTENSION);
htmlFileExtension=htmlFileExtension.stripWhiteSpace();
if (htmlFileExtension.isEmpty())
{
htmlFileExtension = ".html";
}
+ Config_updateString(HTML_FILE_EXTENSION,htmlFileExtension);
- // expand the relative stripFromPath values
- QStrList &stripFromPath = Config_getList(STRIP_FROM_PATH);
- char *sfp = stripFromPath.first();
- if (sfp==0) // by default use the current path
+ //------------------------
+ // check & correct STRIP_FROM_PATH
+ StringVector stripFromPath = Config_getList(STRIP_FROM_PATH);
+ if (stripFromPath.empty()) // by default use the current path
{
QString p = QDir::currentDirPath();
if (p.at(p.length()-1)!='/')
p.append('/');
- stripFromPath.append(p.utf8());
+ stripFromPath.push_back(p.utf8().data());
}
else
{
cleanUpPaths(stripFromPath);
}
+ Config_updateList(STRIP_FROM_PATH,stripFromPath);
- // expand the relative stripFromPath values
- QStrList &stripFromIncPath = Config_getList(STRIP_FROM_INC_PATH);
+ //------------------------
+ // check & correct STRIP_FROM_INC_PATH
+ StringVector stripFromIncPath = Config_getList(STRIP_FROM_INC_PATH);
cleanUpPaths(stripFromIncPath);
+ Config_updateList(STRIP_FROM_INC_PATH,stripFromIncPath);
+ //------------------------
// Test to see if HTML header is valid
- QCString &headerFile = Config_getString(HTML_HEADER);
+ QCString headerFile = Config_getString(HTML_HEADER);
if (!headerFile.isEmpty())
{
QFileInfo fi(headerFile);
@@ -1498,8 +1439,10 @@ void Config::checkAndCorrect()
"does not exist\n",headerFile.data());
}
}
+
+ //------------------------
// Test to see if HTML footer is valid
- QCString &footerFile = Config_getString(HTML_FOOTER);
+ QCString footerFile = Config_getString(HTML_FOOTER);
if (!footerFile.isEmpty())
{
QFileInfo fi(footerFile);
@@ -1510,29 +1453,31 @@ void Config::checkAndCorrect()
}
}
+ //------------------------
// Test to see if MathJax code file is valid
if (Config_getBool(USE_MATHJAX))
{
- QCString &MathJaxCodefile = Config_getString(MATHJAX_CODEFILE);
- if (!MathJaxCodefile.isEmpty())
+ QCString mathJaxCodefile = Config_getString(MATHJAX_CODEFILE);
+ if (!mathJaxCodefile.isEmpty())
{
- QFileInfo fi(MathJaxCodefile);
+ QFileInfo fi(mathJaxCodefile);
if (!fi.exists())
{
config_term("tag MATHJAX_CODEFILE file '%s' "
- "does not exist\n",MathJaxCodefile.data());
+ "does not exist\n",mathJaxCodefile.data());
}
}
- QCString &path = Config_getString(MATHJAX_RELPATH);
+ QCString path = Config_getString(MATHJAX_RELPATH);
if (!path.isEmpty() && path.at(path.length()-1)!='/')
{
path+="/";
}
-
+ Config_updateString(MATHJAX_RELPATH,path);
}
+ //------------------------
// Test to see if LaTeX header is valid
- QCString &latexHeaderFile = Config_getString(LATEX_HEADER);
+ QCString latexHeaderFile = Config_getString(LATEX_HEADER);
if (!latexHeaderFile.isEmpty())
{
QFileInfo fi(latexHeaderFile);
@@ -1542,8 +1487,10 @@ void Config::checkAndCorrect()
"does not exist\n",latexHeaderFile.data());
}
}
+
+ //------------------------
// Test to see if LaTeX footer is valid
- QCString &latexFooterFile = Config_getString(LATEX_FOOTER);
+ QCString latexFooterFile = Config_getString(LATEX_FOOTER);
if (!latexFooterFile.isEmpty())
{
QFileInfo fi(latexFooterFile);
@@ -1554,25 +1501,24 @@ void Config::checkAndCorrect()
}
}
+ //------------------------
// check include path
- QStrList &includePath = Config_getList(INCLUDE_PATH);
- char *s=includePath.first();
- while (s)
+ const StringVector &includePath = Config_getList(INCLUDE_PATH);
+ for (const auto &s : includePath)
{
- QFileInfo fi(s);
+ QFileInfo fi(s.c_str());
if (!fi.exists()) warn_uncond("tag INCLUDE_PATH: include path '%s' "
- "does not exist\n",s);
- s=includePath.next();
+ "does not exist\n",s.c_str());
}
+ //------------------------
// check PREDEFINED
if (Config_getBool(ENABLE_PREPROCESSING))
{
- QStrList &predefList = Config_getList(PREDEFINED);
- s=predefList.first();
- while (s)
+ const StringVector &predefList = Config_getList(PREDEFINED);
+ for (const auto &s : predefList)
{
- QCString predef=s;
+ QCString predef=s.c_str();
predef=predef.stripWhiteSpace();
int i_equals=predef.find('=');
int i_obrace=predef.find('(');
@@ -1580,79 +1526,85 @@ void Config::checkAndCorrect()
{
err("Illegal PREDEFINED format '%s', no define name specified\n",predef.data());
}
- s=predefList.next();
}
}
+ //------------------------
// check ALIASES
- QStrList &aliasList = Config_getList(ALIASES);
- s=aliasList.first();
- while (s)
+ const StringVector &aliasList = Config_getList(ALIASES);
+ for (const auto &s : aliasList)
{
QRegExp re1("[a-z_A-Z][a-z_A-Z0-9]*[ \t]*="); // alias without argument
QRegExp re2("[a-z_A-Z][a-z_A-Z0-9]*{[0-9]+}[ \t]*="); // alias with argument
- QCString alias=s;
+ QCString alias=s.c_str();
alias=alias.stripWhiteSpace();
if (alias.find(re1)!=0 && alias.find(re2)!=0)
{
err("Illegal ALIASES format '%s'. Use \"name=value\" or \"name{n}=value\", where n is the number of arguments\n",
alias.data());
}
- s=aliasList.next();
}
+ //------------------------
// check EXTENSION_MAPPING
checkList(Config_getList(EXTENSION_MAPPING),"EXTENSION_MAPPING",TRUE,TRUE);
+ //------------------------
// check FILTER_PATTERNS
checkList(Config_getList(FILTER_PATTERNS),"FILTER_PATTERNS",TRUE,TRUE);
+ //------------------------
// check FILTER_SOURCE_PATTERNS
checkList(Config_getList(FILTER_SOURCE_PATTERNS),"FILTER_SOURCE_PATTERNS",FALSE,FALSE);
+ //------------------------
// check TAGFILES
checkList(Config_getList(TAGFILES),"TAGFILES",FALSE,TRUE);
+ //------------------------
// check EXTRA_SEARCH_MAPPINGS
if (Config_getBool(SEARCHENGINE) && Config_getBool(GENERATE_HTML))
{
checkList(Config_getList(EXTRA_SEARCH_MAPPINGS),"EXTRA_SEARCH_MAPPING",TRUE,TRUE);
}
+ //------------------------
// check if GENERATE_TREEVIEW and GENERATE_HTMLHELP are both enabled
if (Config_getBool(GENERATE_TREEVIEW) && Config_getBool(GENERATE_HTMLHELP))
{
err("When enabling GENERATE_HTMLHELP the tree view (GENERATE_TREEVIEW) should be disabled. I'll do it for you.\n");
- Config_getBool(GENERATE_TREEVIEW)=FALSE;
+ Config_updateBool(GENERATE_TREEVIEW,FALSE);
}
+
+ //------------------------
+ // check if SEARCHENGINE and GENERATE_HTMLHELP are both enabled
if (Config_getBool(SEARCHENGINE) && Config_getBool(GENERATE_HTMLHELP))
{
err("When enabling GENERATE_HTMLHELP the search engine (SEARCHENGINE) should be disabled. I'll do it for you.\n");
- Config_getBool(SEARCHENGINE)=FALSE;
+ Config_updateBool(SEARCHENGINE,FALSE);
}
+ //------------------------
// check if SEPARATE_MEMBER_PAGES and INLINE_GROUPED_CLASSES are both enabled
if (Config_getBool(SEPARATE_MEMBER_PAGES) && Config_getBool(INLINE_GROUPED_CLASSES))
{
err("When enabling INLINE_GROUPED_CLASSES the SEPARATE_MEMBER_PAGES option should be disabled. I'll do it for you.\n");
- Config_getBool(SEPARATE_MEMBER_PAGES)=FALSE;
+ Config_updateBool(SEPARATE_MEMBER_PAGES,FALSE);
}
- // check dot image format
- QCString &dotImageFormat=Config_getEnum(DOT_IMAGE_FORMAT);
+ //------------------------
+ // check and correct DOT_IMAGE_FORMAT
+ QCString dotImageFormat=Config_getEnum(DOT_IMAGE_FORMAT);
dotImageFormat=dotImageFormat.stripWhiteSpace();
if (dotImageFormat.isEmpty())
{
dotImageFormat = "png";
}
- //else if (dotImageFormat!="gif" && dotImageFormat!="png" && dotImageFormat!="jpg")
- //{
- // err("Invalid value for DOT_IMAGE_FORMAT: '%s'. Using the default.\n",dotImageFormat.data());
- // dotImageFormat = "png";
- //}
+ Config_updateEnum(DOT_IMAGE_FORMAT,dotImageFormat);
+ //------------------------
// correct DOT_FONTNAME if needed
- QCString &dotFontName=Config_getString(DOT_FONTNAME);
+ QCString dotFontName=Config_getString(DOT_FONTNAME);
if (dotFontName=="FreeSans" || dotFontName=="FreeSans.ttf")
{
warn_uncond("doxygen no longer ships with the FreeSans font.\n"
@@ -1663,9 +1615,11 @@ void Config::checkAndCorrect()
{
dotFontName = "Helvetica";
}
+ Config_updateString(DOT_FONTNAME,dotFontName);
+ //------------------------
// clip dotFontSize against the maximum bounds
- int &dotFontSize = Config_getInt(DOT_FONTSIZE);
+ int dotFontSize = Config_getInt(DOT_FONTSIZE);
if (dotFontSize<4)
{
dotFontSize=4;
@@ -1674,9 +1628,11 @@ void Config::checkAndCorrect()
{
dotFontSize=24;
}
+ Config_updateInt(DOT_FONTSIZE,dotFontSize);
+ //------------------------
// clip number of threads
- int &dotNumThreads = Config_getInt(DOT_NUM_THREADS);
+ int dotNumThreads = Config_getInt(DOT_NUM_THREADS);
if (dotNumThreads>32)
{
dotNumThreads=32;
@@ -1685,9 +1641,11 @@ void Config::checkAndCorrect()
{
dotNumThreads=QMAX(2,std::thread::hardware_concurrency()+1);
}
+ Config_updateInt(DOT_NUM_THREADS,dotNumThreads);
+ //------------------------
// check dot path
- QCString &dotPath = Config_getString(DOT_PATH);
+ QCString dotPath = Config_getString(DOT_PATH);
if (!dotPath.isEmpty())
{
QFileInfo fi(dotPath);
@@ -1717,9 +1675,11 @@ void Config::checkAndCorrect()
{
dotPath="";
}
+ Config_updateString(DOT_PATH,dotPath);
+ //------------------------
// check plantuml path
- QCString &plantumlJarPath = Config_getString(PLANTUML_JAR_PATH);
+ QCString plantumlJarPath = Config_getString(PLANTUML_JAR_PATH);
if (!plantumlJarPath.isEmpty())
{
QFileInfo pu(plantumlJarPath);
@@ -1748,9 +1708,11 @@ void Config::checkAndCorrect()
plantumlJarPath="";
}
}
+ Config_updateString(PLANTUML_JAR_PATH,plantumlJarPath);
+ //------------------------
// check dia path
- QCString &diaPath = Config_getString(DIA_PATH);
+ QCString diaPath = Config_getString(DIA_PATH);
if (!diaPath.isEmpty())
{
QFileInfo dp(diaPath+"/dia"+Portable::commandExtension());
@@ -1772,52 +1734,52 @@ void Config::checkAndCorrect()
{
diaPath="";
}
+ Config_updateString(DIA_PATH,diaPath);
- // check input
- QStrList &inputSources=Config_getList(INPUT);
- if (inputSources.count()==0)
+ //------------------------
+ // check INPUT
+ StringVector inputSources=Config_getList(INPUT);
+ if (inputSources.empty())
{
// use current dir as the default
- inputSources.append(QDir::currentDirPath().utf8());
+ inputSources.push_back(QDir::currentDirPath().utf8().data());
}
else
{
- s=inputSources.first();
- while (s)
+ for (const auto &s : inputSources)
{
- QFileInfo fi(s);
+ QFileInfo fi(s.c_str());
if (!fi.exists())
{
- warn_uncond("tag INPUT: input source '%s' does not exist\n",s);
+ warn_uncond("tag INPUT: input source '%s' does not exist\n",s.c_str());
}
- s=inputSources.next();
}
}
+ Config_updateList(INPUT,inputSources);
+ //------------------------
// add default file patterns if needed
- QStrList &filePatternList = Config_getList(FILE_PATTERNS);
- if (filePatternList.isEmpty())
+ StringVector filePatternList = Config_getList(FILE_PATTERNS);
+ if (filePatternList.empty())
{
ConfigOption * opt = ConfigImpl::instance()->get("FILE_PATTERNS");
if (opt->kind()==ConfigOption::O_List)
{
- QStrList l = ((ConfigList*)opt)->getDefault();
- const char *p = l.first();
- while (p)
- {
- filePatternList.append(p);
- p = l.next();
- }
+ filePatternList = ((ConfigList*)opt)->getDefault();
}
}
+ Config_updateList(FILE_PATTERNS,filePatternList);
+ //------------------------
// add default pattern if needed
- QStrList &examplePatternList = Config_getList(EXAMPLE_PATTERNS);
- if (examplePatternList.isEmpty())
+ StringVector examplePatternList = Config_getList(EXAMPLE_PATTERNS);
+ if (examplePatternList.empty())
{
- examplePatternList.append("*");
+ examplePatternList.push_back("*");
+ Config_updateList(EXAMPLE_PATTERNS,examplePatternList);
}
+ //------------------------
// if no output format is enabled, warn the user
if (!Config_getBool(GENERATE_HTML) &&
!Config_getBool(GENERATE_LATEX) &&
@@ -1834,6 +1796,7 @@ void Config::checkAndCorrect()
warn_uncond("No output formats selected! Set at least one of the main GENERATE_* options to YES.\n");
}
+ //------------------------
// check HTMLHELP creation requirements
if (!Config_getBool(GENERATE_HTML) &&
Config_getBool(GENERATE_HTMLHELP))
@@ -1841,36 +1804,40 @@ void Config::checkAndCorrect()
warn_uncond("GENERATE_HTMLHELP=YES requires GENERATE_HTML=YES.\n");
}
+ //------------------------
// check QHP creation requirements
if (Config_getBool(GENERATE_QHP))
{
if (Config_getString(QHP_NAMESPACE).isEmpty())
{
err("GENERATE_QHP=YES requires QHP_NAMESPACE to be set. Using 'org.doxygen.doc' as default!.\n");
- Config_getString(QHP_NAMESPACE)="org.doxygen.doc";
+ Config_updateString(QHP_NAMESPACE,"org.doxygen.doc");
}
if (Config_getString(QHP_VIRTUAL_FOLDER).isEmpty())
{
err("GENERATE_QHP=YES requires QHP_VIRTUAL_FOLDER to be set. Using 'doc' as default!\n");
- Config_getString(QHP_VIRTUAL_FOLDER)="doc";
+ Config_updateString(QHP_VIRTUAL_FOLDER,"doc");
}
}
+ //------------------------
if (Config_getBool(OPTIMIZE_OUTPUT_JAVA) && Config_getBool(INLINE_INFO))
{
// don't show inline info for Java output, since Java has no inline
// concept.
- Config_getBool(INLINE_INFO)=FALSE;
+ Config_updateBool(INLINE_INFO,FALSE);
}
- int &depth = Config_getInt(MAX_DOT_GRAPH_DEPTH);
+ //------------------------
+ int depth = Config_getInt(MAX_DOT_GRAPH_DEPTH);
if (depth==0)
{
- depth=1000;
+ Config_updateInt(MAX_DOT_GRAPH_DEPTH,1000);
}
- int &hue = Config_getInt(HTML_COLORSTYLE_HUE);
+ //------------------------
+ int hue = Config_getInt(HTML_COLORSTYLE_HUE);
if (hue<0)
{
hue=0;
@@ -1879,8 +1846,10 @@ void Config::checkAndCorrect()
{
hue=hue%360;
}
+ Config_updateInt(HTML_COLORSTYLE_HUE,hue);
- int &sat = Config_getInt(HTML_COLORSTYLE_SAT);
+ //------------------------
+ int sat = Config_getInt(HTML_COLORSTYLE_SAT);
if (sat<0)
{
sat=0;
@@ -1889,7 +1858,11 @@ void Config::checkAndCorrect()
{
sat=255;
}
- int &gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
+ Config_updateInt(HTML_COLORSTYLE_SAT,sat);
+
+
+ //------------------------
+ int gamma = Config_getInt(HTML_COLORSTYLE_GAMMA);
if (gamma<40)
{
gamma=40;
@@ -1898,32 +1871,30 @@ void Config::checkAndCorrect()
{
gamma=240;
}
+ Config_updateInt(HTML_COLORSTYLE_GAMMA,gamma);
+ //------------------------
QCString mathJaxFormat = Config_getEnum(MATHJAX_FORMAT);
if (!mathJaxFormat.isEmpty() && mathJaxFormat!="HTML-CSS" &&
mathJaxFormat!="NativeMML" && mathJaxFormat!="SVG")
{
err("Unsupported value for MATHJAX_FORMAT: Should be one of HTML-CSS, NativeMML, or SVG\n");
- Config_getEnum(MATHJAX_FORMAT)="HTML-CSS";
+ Config_updateEnum(MATHJAX_FORMAT,"HTML-CSS");
}
+ //------------------------
// add default words if needed
- QStrList &annotationFromBrief = Config_getList(ABBREVIATE_BRIEF);
- if (annotationFromBrief.isEmpty())
- {
- annotationFromBrief.append("The $name class");
- annotationFromBrief.append("The $name widget");
- annotationFromBrief.append("The $name file");
- annotationFromBrief.append("is");
- annotationFromBrief.append("provides");
- annotationFromBrief.append("specifies");
- annotationFromBrief.append("contains");
- annotationFromBrief.append("represents");
- annotationFromBrief.append("a");
- annotationFromBrief.append("an");
- annotationFromBrief.append("the");
+ const StringVector &annotationFromBrief = Config_getList(ABBREVIATE_BRIEF);
+ if (annotationFromBrief.empty())
+ {
+ Config_updateList(ABBREVIATE_BRIEF,
+ { "The $name class", "The $name widget",
+ "The $name file", "is", "provides", "specifies",
+ "contains", "represents", "a", "an", "the"
+ });
}
+ //------------------------
// some default settings for vhdl
if (Config_getBool(OPTIMIZE_OUTPUT_VHDL) &&
(Config_getBool(INLINE_INHERITED_MEMB) ||
@@ -1953,15 +1924,18 @@ void Config::checkAndCorrect()
"%s%s%s%s%s%s",s1,s2,s3,s4,s5,s6
);
- Config_getBool(INLINE_INHERITED_MEMB) = FALSE;
- Config_getBool(INHERIT_DOCS) = FALSE;
- Config_getBool(HIDE_SCOPE_NAMES) = TRUE;
- Config_getBool(EXTRACT_PRIVATE) = TRUE;
- Config_getBool(ENABLE_PREPROCESSING) = FALSE;
- Config_getBool(EXTRACT_PACKAGE) = TRUE;
+ Config_updateBool(INLINE_INHERITED_MEMB, FALSE);
+ Config_updateBool(INHERIT_DOCS, FALSE);
+ Config_updateBool(HIDE_SCOPE_NAMES, TRUE);
+ Config_updateBool(EXTRACT_PRIVATE, TRUE);
+ Config_updateBool(ENABLE_PREPROCESSING, FALSE);
+ Config_updateBool(EXTRACT_PACKAGE, TRUE);
}
- checkFileName(Config_getString(GENERATE_TAGFILE),"GENERATE_TAGFILE");
+ if (!checkFileName(Config_getString(GENERATE_TAGFILE),"GENERATE_TAGFILE"))
+ {
+ Config_updateString(GENERATE_TAGFILE,"");
+ }
#if 0 // TODO: this breaks test 25; SOURCEBROWSER = NO and SOURCE_TOOLTIPS = YES.
// So this and other regressions should be analysed and fixed before this can be enabled
@@ -2016,10 +1990,10 @@ void Config::postProcess(bool clearHeaderAndFooter, bool compare)
// refers to the files that we are supposed to parse.
if (clearHeaderAndFooter)
{
- Config_getString(HTML_HEADER)="";
- Config_getString(HTML_FOOTER)="";
- Config_getString(LATEX_HEADER)="";
- Config_getString(LATEX_FOOTER)="";
+ Config_updateString(HTML_HEADER ,"");
+ Config_updateString(HTML_FOOTER ,"");
+ Config_updateString(LATEX_HEADER,"");
+ Config_updateString(LATEX_FOOTER,"");
}
}
diff --git a/src/context.cpp b/src/context.cpp
index 9684870..83e8e7a 100644
--- a/src/context.cpp
+++ b/src/context.cpp
@@ -298,18 +298,16 @@ class ConfigContext::Private
public:
Private() { m_cachedLists.setAutoDelete(TRUE); }
virtual ~Private() { }
- TemplateVariant fetchList(const QCString &name,const QStrList *list)
+ TemplateVariant fetchList(const QCString &name,const StringVector &list)
{
TemplateVariant *v = m_cachedLists.find(name);
if (v==0)
{
TemplateList *tlist = TemplateList::alloc();
m_cachedLists.insert(name,new TemplateVariant(tlist));
- QStrListIterator li(*list);
- char *s;
- for (li.toFirst();(s=li.current());++li)
+ for (const auto &s : list)
{
- tlist->append(s);
+ tlist->append(s.c_str());
}
return tlist;
}
@@ -345,23 +343,23 @@ TemplateVariant ConfigContext::get(const char *name) const
{
case ConfigValues::Info::Bool:
{
- bool b = ConfigValues::instance().*((ConfigValues::InfoBool*)option)->item;
+ bool b = ConfigValues::instance().*(option->value.b);
return TemplateVariant(b);
}
case ConfigValues::Info::Int:
{
- int i = ConfigValues::instance().*((ConfigValues::InfoInt*)option)->item;
+ int i = ConfigValues::instance().*(option->value.i);
return TemplateVariant(i);
}
case ConfigValues::Info::String:
{
- QCString s = ConfigValues::instance().*((ConfigValues::InfoString*)option)->item;
+ QCString s = ConfigValues::instance().*(option->value.s);
return TemplateVariant(s);
}
case ConfigValues::Info::List:
{
- const QStrList &l = ConfigValues::instance().*((ConfigValues::InfoList*)option)->item;
- return p->fetchList(name,&l);
+ const StringVector &l = ConfigValues::instance().*(option->value.l);
+ return p->fetchList(name,l);
}
default:
break;
@@ -1264,7 +1262,8 @@ static TemplateVariant parseDoc(const Definition *def,const QCString &file,int l
const QCString &relPath,const QCString &docStr,bool isBrief)
{
TemplateVariant result;
- DocRoot *root = validatingParseDoc(file,line,def,0,docStr,TRUE,FALSE,0,isBrief,FALSE);
+ DocRoot *root = validatingParseDoc(file,line,def,0,docStr,TRUE,FALSE,
+ 0,isBrief,FALSE,Config_getBool(MARKDOWN_SUPPORT));
QGString docs;
{
FTextStream ts(&docs);
@@ -1775,10 +1774,7 @@ class IncludeInfoListContext::Private : public GenericNodeListContext
IncludeInfo *ii;
for (li.toFirst();(ii=li.current());++li)
{
- if (!ii->indirect)
- {
- append(IncludeInfoContext::alloc(ii,lang));
- }
+ append(IncludeInfoContext::alloc(ii,lang));
}
}
};
@@ -10345,7 +10341,7 @@ void generateTemplateFiles(const char *templateDir)
QCString outDir = QCString(templateDir)+"/html";
if (!thisDir.exists(outDir) && !thisDir.mkdir(outDir))
{
- err("Failed to create output directory '%s'\n",templateDir);
+ err("Failed to create output directory '%s'\n",outDir.data());
return;
}
ResourceMgr::instance().writeCategory("html",outDir);
diff --git a/src/debug.cpp b/src/debug.cpp
index ca3c1e9..f56ef3a 100644
--- a/src/debug.cpp
+++ b/src/debug.cpp
@@ -42,7 +42,8 @@ static std::map< std::string, Debug::DebugMask > s_labels =
{ "filteroutput", Debug::FilterOutput },
{ "lex", Debug::Lex },
{ "plantuml", Debug::Plantuml },
- { "fortranfixed2free", Debug::FortranFixed2Free }
+ { "fortranfixed2free", Debug::FortranFixed2Free },
+ { "cite", Debug::Cite }
};
//------------------------------------------------------------------------
@@ -114,11 +115,11 @@ class Timer
{
m_startTime = std::chrono::system_clock::now();
}
- int elapsedTimeMs()
+ double elapsedTimeS()
{
- return std::chrono::duration_cast<
+ return (std::chrono::duration_cast<
std::chrono::milliseconds>(
- std::chrono::system_clock::now() - m_startTime).count();
+ std::chrono::system_clock::now() - m_startTime).count()) / 1000.0;
}
private:
std::chrono::time_point<std::chrono::system_clock> m_startTime;
@@ -131,8 +132,8 @@ void Debug::startTimer()
g_runningTime.start();
}
-int Debug::elapsedTime()
+double Debug::elapsedTime()
{
- return g_runningTime.elapsedTimeMs();
+ return g_runningTime.elapsedTimeS();
}
diff --git a/src/debug.h b/src/debug.h
index 0c046f4..e71595f 100644
--- a/src/debug.h
+++ b/src/debug.h
@@ -36,7 +36,8 @@ class Debug
FilterOutput = 0x00001000,
Lex = 0x00002000,
Plantuml = 0x00004000,
- FortranFixed2Free = 0x00008000
+ FortranFixed2Free = 0x00008000,
+ Cite = 0x00010000
};
static void print(DebugMask mask,int prio,const char *fmt,...);
@@ -47,7 +48,7 @@ class Debug
static void setPriority(int p);
static void startTimer();
- static int elapsedTime();
+ static double elapsedTime();
private:
static DebugMask curMask;
diff --git a/src/define.h b/src/define.h
index 0a3d62c..015d399 100644
--- a/src/define.h
+++ b/src/define.h
@@ -16,11 +16,13 @@
#ifndef DEFINE_H
#define DEFINE_H
-#include <map>
-#include <string>
+#include <vector>
#include <memory>
+#include <string>
+#include <unordered_map>
#include <qcstring.h>
+#include "containers.h"
class FileDef;
@@ -44,5 +46,6 @@ class Define
/** List of all macro definitions */
using DefineList = std::vector< std::unique_ptr<Define> >;
+using DefinesPerFileList = std::unordered_map< std::string, DefineList >;
#endif
diff --git a/src/definition.cpp b/src/definition.cpp
index 09b4f56..3ed331c 100644
--- a/src/definition.cpp
+++ b/src/definition.cpp
@@ -159,13 +159,12 @@ void DefinitionImpl::setDefFile(const QCString &df,int defLine,int defCol)
static bool matchExcludedSymbols(const char *name)
{
- static QStrList &exclSyms = Config_getList(EXCLUDE_SYMBOLS);
- if (exclSyms.count()==0) return FALSE; // nothing specified
- const char *pat = exclSyms.first();
+ const StringVector &exclSyms = Config_getList(EXCLUDE_SYMBOLS);
+ if (exclSyms.empty()) return FALSE; // nothing specified
QCString symName = name;
- while (pat)
+ for (const auto &pat : exclSyms)
{
- QCString pattern = pat;
+ QCString pattern = pat.c_str();
bool forceStart=FALSE;
bool forceEnd=FALSE;
if (pattern.at(0)=='^')
@@ -210,7 +209,6 @@ static bool matchExcludedSymbols(const char *name)
}
}
}
- pat = exclSyms.next();
}
//printf("--> name=%s: no match\n",name);
return FALSE;
@@ -1930,15 +1928,13 @@ QCString abbreviate(const char *s,const char *name)
result=result.left(result.length()-1);
// strip any predefined prefix
- QStrList &briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF);
- const char *p = briefDescAbbrev.first();
- while (p)
+ const StringVector &briefDescAbbrev = Config_getList(ABBREVIATE_BRIEF);
+ for (const auto &p : briefDescAbbrev)
{
- QCString str = p;
+ QCString str = p.c_str();
str.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name
str += " ";
stripWord(result,str);
- p = briefDescAbbrev.next();
}
// capitalize first word
@@ -2181,7 +2177,7 @@ QCString DefinitionImpl::externalReference(const QCString &relPath) const
return relPath;
}
-QCString DefinitionImpl::name() const
+const QCString &DefinitionImpl::name() const
{
return m_impl->name;
}
diff --git a/src/definition.h b/src/definition.h
index 2d167dc..8ad15b2 100644
--- a/src/definition.h
+++ b/src/definition.h
@@ -111,7 +111,7 @@ class Definition : public DefinitionIntf
virtual bool isAlias() const = 0;
/*! Returns the name of the definition */
- virtual QCString name() const = 0;
+ virtual const QCString &name() const = 0;
/*! Returns TRUE iff this definition has an artificially generated name
* (typically starting with a @) that is used for nameless definitions
diff --git a/src/definitionimpl.h b/src/definitionimpl.h
index c35a89e..e91d989 100644
--- a/src/definitionimpl.h
+++ b/src/definitionimpl.h
@@ -31,7 +31,7 @@ class DefinitionImpl : virtual public Definition
virtual ~DefinitionImpl();
virtual bool isAlias() const { return FALSE; }
- virtual QCString name() const;
+ virtual const QCString &name() const;
virtual bool isAnonymous() const;
virtual QCString localName() const;
virtual QCString qualifiedName() const;
@@ -142,7 +142,7 @@ class DefinitionAliasImpl : virtual public Definition
virtual ~DefinitionAliasImpl();
virtual bool isAlias() const { return TRUE; }
- virtual QCString name() const
+ virtual const QCString &name() const
{ return m_def->name(); }
virtual bool isAnonymous() const
{ return m_def->isAnonymous(); }
diff --git a/src/dirdef.cpp b/src/dirdef.cpp
index 0f8f04b..b058f86 100644
--- a/src/dirdef.cpp
+++ b/src/dirdef.cpp
@@ -69,7 +69,7 @@ class DirDefImpl : public DefinitionImpl, public DirDef
void endMemberDeclarations(OutputList &ol);
static DirDef *createNewDir(const char *path);
- static bool matchPath(const QCString &path,QStrList &l);
+ static bool matchPath(const QCString &path,const StringVector &l);
DirList m_subdirs;
QCString m_dispName;
@@ -223,7 +223,8 @@ void DirDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title)
// repeat brief description
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
{
- ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
// separator between brief and details
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
@@ -243,7 +244,8 @@ void DirDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title)
// write documentation
if (!documentation().isEmpty())
{
- ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
}
}
@@ -253,7 +255,8 @@ void DirDefImpl::writeBriefDescription(OutputList &ol)
if (hasBriefDescription())
{
DocRoot *rootNode = validatingParseDoc(
- briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE);
+ briefFile(),briefLine(),this,0,briefDescription(),TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (rootNode && !rootNode->isEmpty())
{
ol.startParagraph();
@@ -341,7 +344,8 @@ void DirDefImpl::writeSubDirList(OutputList &ol)
FALSE, // isExample
0, // exampleName
TRUE, // single line
- TRUE // link from index
+ TRUE, // link from index
+ Config_getBool(MARKDOWN_SUPPORT)
);
ol.endMemberDescription();
}
@@ -412,7 +416,8 @@ void DirDefImpl::writeFileList(OutputList &ol)
FALSE, // isExample
0, // exampleName
TRUE, // single line
- TRUE // link from index
+ TRUE, // link from index
+ Config_getBool(MARKDOWN_SUPPORT)
);
ol.endMemberDescription();
}
@@ -750,7 +755,7 @@ int FilePairDict::compareValues(const FilePair *left,const FilePair *right) cons
//----------------------------------------------------------------------
-UsedDir::UsedDir(DirDef *dir,bool inherited) :
+UsedDir::UsedDir(const DirDef *dir,bool inherited) :
m_dir(dir), m_filePairs(7), m_inherited(inherited)
{
m_filePairs.setAutoDelete(TRUE);
@@ -792,17 +797,15 @@ DirDef *DirDefImpl::createNewDir(const char *path)
return dir;
}
-bool DirDefImpl::matchPath(const QCString &path,QStrList &l)
+bool DirDefImpl::matchPath(const QCString &path,const StringVector &l)
{
- const char *s=l.first();
- while (s)
+ for (const auto &s : l)
{
- QCString prefix = s;
- if (qstricmp(prefix.left(path.length()),path)==0) // case insensitive compare
+ std::string prefix = s.substr(0,path.length());
+ if (qstricmp(prefix.c_str(),path)==0) // case insensitive compare
{
return TRUE;
}
- s = l.next();
}
return FALSE;
}
diff --git a/src/dirdef.h b/src/dirdef.h
index 399e0c2..468901d 100644
--- a/src/dirdef.h
+++ b/src/dirdef.h
@@ -104,7 +104,7 @@ class FilePairDict : public SDict<FilePair>
class UsedDir
{
public:
- UsedDir(DirDef *dir,bool inherited);
+ UsedDir(const DirDef *dir,bool inherited);
virtual ~UsedDir();
void addFileDep(FileDef *srcFd,FileDef *dstFd);
FilePair *findFilePair(const char *name);
@@ -114,7 +114,7 @@ class UsedDir
void sort();
private:
- DirDef *m_dir;
+ const DirDef *m_dir;
FilePairDict m_filePairs;
bool m_inherited;
};
diff --git a/src/docparser.cpp b/src/docparser.cpp
index 00f287c..73131f6 100644
--- a/src/docparser.cpp
+++ b/src/docparser.cpp
@@ -114,6 +114,7 @@ static uint g_includeFileOffset;
static uint g_includeFileLength;
static int g_includeFileLine;
static bool g_includeFileShowLineNo;
+static bool g_markdownSupport;
/** Parser's context to store all global variables.
@@ -1799,7 +1800,7 @@ static int internalValidatingParseDoc(DocNode *parent,QList<DocNode> &children,
if (doc.isEmpty()) return retval;
- doctokenizerYYinit(doc,g_fileName);
+ doctokenizerYYinit(doc,g_fileName,g_markdownSupport);
// first parse any number of paragraphs
bool isFirst=TRUE;
@@ -1846,18 +1847,16 @@ static void readTextFileByName(const QCString &file,QCString &text)
return;
}
}
- QStrList &examplePathList = Config_getList(EXAMPLE_PATH);
- char *s=examplePathList.first();
- while (s)
+ const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
+ for (const auto &s : examplePathList)
{
- QCString absFileName = QCString(s)+Portable::pathSeparator()+file;
+ QCString absFileName = QCString(s.c_str())+Portable::pathSeparator()+file;
QFileInfo fi(absFileName);
if (fi.exists())
{
text = fileToString(absFileName,Config_getBool(FILTER_SOURCE_FILES));
return;
}
- s=examplePathList.next();
}
// as a fallback we also look in the exampleNameDict
@@ -2569,7 +2568,7 @@ void DocRef::parse()
DocCite::DocCite(DocNode *parent,const QCString &target,const QCString &) //context)
{
- static uint numBibFiles = Config_getList(CITE_BIB_FILES).count();
+ size_t numBibFiles = Config_getList(CITE_BIB_FILES).size();
m_parent = parent;
//printf("DocCite::DocCite(target=%s)\n",target.data());
ASSERT(!target.isEmpty());
@@ -7567,7 +7566,8 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine,
const Definition *ctx,const MemberDef *md,
const char *input,bool indexWords,
bool isExample, const char *exampleName,
- bool singleLine, bool linkFromIndex)
+ bool singleLine, bool linkFromIndex,
+ bool markdownSupport)
{
//printf("validatingParseDoc(%s,%s)=[%s]\n",ctx?ctx->name().data():"<none>",
// md?md->name().data():"<none>",
@@ -7724,6 +7724,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine,
g_retvalsFound.clear();
g_paramsFound.setAutoDelete(FALSE);
g_paramsFound.clear();
+ g_markdownSupport = markdownSupport;
//printf("Starting comment block at %s:%d\n",g_fileName.data(),startLine);
doctokenizerYYlineno=startLine;
@@ -7734,7 +7735,7 @@ DocRoot *validatingParseDoc(const char *fileName,int startLine,
inpStr+='\n';
}
//printf("processCopyDoc(in='%s' out='%s')\n",input,inpStr.data());
- doctokenizerYYinit(inpStr,g_fileName);
+ doctokenizerYYinit(inpStr,g_fileName,markdownSupport);
// build abstract syntax tree
DocRoot *root = new DocRoot(md!=0,singleLine);
@@ -7802,7 +7803,7 @@ DocText *validatingParseText(const char *input)
if (input)
{
doctokenizerYYlineno=1;
- doctokenizerYYinit(input,g_fileName);
+ doctokenizerYYinit(input,g_fileName,Config_getBool(MARKDOWN_SUPPORT));
// build abstract syntax tree
txt->parse();
diff --git a/src/docparser.h b/src/docparser.h
index d05dea9..1dc6b3f 100644
--- a/src/docparser.h
+++ b/src/docparser.h
@@ -1,13 +1,13 @@
/******************************************************************************
*
- *
+ *
*
*
* 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
+ * 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.
*
@@ -52,7 +52,7 @@ QCString getJsDirEmbeddingChar(QString::Direction textDir);
* @param md Member definition to which the documentation belongs.
* Can be 0.
* @param input String representation of the documentation block.
- * @param indexWords Indicates whether or not words should be put in the
+ * @param indexWords Indicates whether or not words should be put in the
* search index.
* @param isExample TRUE if the documentation belongs to an example.
* @param exampleName Base name of the example file (0 if isExample is FALSE).
@@ -61,16 +61,19 @@ QCString getJsDirEmbeddingChar(QString::Direction textDir);
* @param linkFromIndex TRUE if the documentation is generated from an
* index page. In this case context is not used to determine
* the relative path when making a link.
+ * @param markdownSupport TRUE if the input needs to take markdown markup into
+ * account.
* @returns Root node of the abstract syntax tree. Ownership of the
* pointer is handed over to the caller.
*/
DocRoot *validatingParseDoc(const char *fileName,int startLine,
const Definition *context, const MemberDef *md,
const char *input,bool indexWords,
- bool isExample,const char *exampleName=0,
- bool singleLine=FALSE,bool linkFromIndex=FALSE);
+ bool isExample,const char *exampleName,
+ bool singleLine,bool linkFromIndex,
+ bool markdownSupport);
-/*! Main entry point for parsing simple text fragments. These
+/*! Main entry point for parsing simple text fragments. These
* fragments are limited to words, whitespace and symbols.
*/
DocText *validatingParseText(const char *input);
@@ -87,11 +90,11 @@ class DocNode
{
public:
/*! Available node types. */
- enum Kind { Kind_Root = 0,
- Kind_Word = 1,
- Kind_WhiteSpace = 2,
- Kind_Para = 3,
- Kind_AutoList = 4,
+ enum Kind { Kind_Root = 0,
+ Kind_Word = 1,
+ Kind_WhiteSpace = 2,
+ Kind_Para = 3,
+ Kind_AutoList = 4,
Kind_AutoListItem = 5,
Kind_Symbol = 6,
Kind_URL = 7,
@@ -158,7 +161,7 @@ class DocNode
/*! Sets a new parent for this node. */
void setParent(DocNode *parent) { m_parent = parent; }
- /*! Acceptor function for node visitors. Part of the visitor pattern.
+ /*! Acceptor function for node visitors. Part of the visitor pattern.
* @param v Abstract visitor.
*/
virtual void accept(DocVisitor *v) = 0;
@@ -185,14 +188,14 @@ template<class T> class CompAccept : public DocNode
{
public:
CompAccept() { m_children.setAutoDelete(TRUE); }
- void accept(DocVisitor *v)
+ void accept(DocVisitor *v)
{
T *obj = dynamic_cast<T *>(this);
- v->visitPre(obj);
+ v->visitPre(obj);
QListIterator<DocNode> cli(m_children);
DocNode *n;
for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
- v->visitPost(obj);
+ v->visitPost(obj);
}
const QList<DocNode> &children() const { return m_children; }
QList<DocNode> &children() { return m_children; }
@@ -228,13 +231,13 @@ template<class T> class CompAccept : public DocNode
{
return getTextBasicDir(0);
}
-
+
protected:
QList<DocNode> m_children;
};
-/** Node representing a word
+/** Node representing a word
*/
class DocWord : public DocNode
{
@@ -282,7 +285,7 @@ class DocLinkedWord : public DocNode
class DocURL : public DocNode
{
public:
- DocURL(DocNode *parent,const QCString &url,bool isEmail) :
+ DocURL(DocNode *parent,const QCString &url,bool isEmail) :
m_url(url), m_isEmail(isEmail) { m_parent=parent; }
QCString url() const { return m_url; }
Kind kind() const { return Kind_URL; }
@@ -482,7 +485,7 @@ class DocSymbol : public DocNode
const char *symb;
const PerlType type;
}PerlSymb;
- DocSymbol(DocNode *parent,SymType s) :
+ DocSymbol(DocNode *parent,SymType s) :
m_symbol(s) { m_parent = parent; }
SymType symbol() const { return m_symbol; }
Kind kind() const { return Kind_Symbol; }
@@ -512,7 +515,7 @@ class DocEmoji : public DocNode
class DocWhiteSpace : public DocNode
{
public:
- DocWhiteSpace(DocNode *parent,const QCString &chars) :
+ DocWhiteSpace(DocNode *parent,const QCString &chars) :
m_chars(chars) { m_parent = parent; }
Kind kind() const { return Kind_WhiteSpace; }
QCString chars() const { return m_chars; }
@@ -625,7 +628,7 @@ class DocIncOperator : public DocNode
public:
enum Type { Line, SkipLine, Skip, Until };
DocIncOperator(DocNode *parent,Type t,const QCString &pat,
- const QCString &context,bool isExample,const QCString &exampleFile) :
+ const QCString &context,bool isExample,const QCString &exampleFile) :
m_type(t), m_pattern(pat), m_context(context),
m_isFirst(FALSE), m_isLast(FALSE),
m_isExample(isExample), m_exampleFile(exampleFile) { m_parent = parent; }
@@ -695,7 +698,7 @@ class DocFormula : public DocNode
class DocIndexEntry : public DocNode
{
public:
- DocIndexEntry(DocNode *parent,const Definition *scope,const MemberDef *md)
+ DocIndexEntry(DocNode *parent,const Definition *scope,const MemberDef *md)
: m_scope(scope), m_member(md){ m_parent = parent; }
Kind kind() const { return Kind_IndexEntry; }
int parse();
@@ -962,7 +965,7 @@ class DocHRef : public CompAccept<DocHRef>
{
public:
DocHRef(DocNode *parent,const HtmlAttribList &attribs,const QCString &url,
- const QCString &relPath) :
+ const QCString &relPath) :
m_attribs(attribs), m_url(url), m_relPath(relPath) { m_parent = parent; }
int parse();
QCString url() const { return m_url; }
@@ -980,7 +983,7 @@ class DocHRef : public CompAccept<DocHRef>
class DocHtmlHeader : public CompAccept<DocHtmlHeader>
{
public:
- DocHtmlHeader(DocNode *parent,const HtmlAttribList &attribs,int level) :
+ DocHtmlHeader(DocNode *parent,const HtmlAttribList &attribs,int level) :
m_level(level), m_attribs(attribs) { m_parent = parent; }
int level() const { return m_level; }
Kind kind() const { return Kind_HtmlHeader; }
@@ -996,7 +999,7 @@ class DocHtmlHeader : public CompAccept<DocHtmlHeader>
class DocHtmlDescTitle : public CompAccept<DocHtmlDescTitle>
{
public:
- DocHtmlDescTitle(DocNode *parent,const HtmlAttribList &attribs) :
+ DocHtmlDescTitle(DocNode *parent,const HtmlAttribList &attribs) :
m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlDescTitle; }
const HtmlAttribList &attribs() const { return m_attribs; }
@@ -1025,7 +1028,7 @@ class DocSection : public CompAccept<DocSection>
{
public:
DocSection(DocNode *parent,int level,const QCString &id) :
- m_level(level), m_id(id) { m_parent = parent; }
+ m_level(level), m_id(id) { m_parent = parent; }
Kind kind() const { return Kind_Section; }
int level() const { return m_level; }
QCString title() const { return m_title; }
@@ -1046,7 +1049,7 @@ class DocSection : public CompAccept<DocSection>
class DocSecRefItem : public CompAccept<DocSecRefItem>
{
public:
- DocSecRefItem(DocNode *parent,const QCString &target) :
+ DocSecRefItem(DocNode *parent,const QCString &target) :
m_target(target) { m_parent = parent; }
Kind kind() const { return Kind_SecRefItem; }
QCString target() const { return m_target; }
@@ -1110,7 +1113,7 @@ class DocHtmlList : public CompAccept<DocHtmlList>
{
public:
enum Type { Unordered, Ordered };
- DocHtmlList(DocNode *parent,const HtmlAttribList &attribs,Type t) :
+ DocHtmlList(DocNode *parent,const HtmlAttribList &attribs,Type t) :
m_type(t), m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlList; }
Type type() const { return m_type; }
@@ -1127,8 +1130,8 @@ class DocHtmlList : public CompAccept<DocHtmlList>
class DocSimpleSect : public CompAccept<DocSimpleSect>
{
public:
- enum Type
- {
+ enum Type
+ {
Unknown, See, Return, Author, Authors, Version, Since, Date,
Note, Warning, Copyright, Pre, Post, Invar, Remark, Attention, User, Rcs
};
@@ -1150,7 +1153,7 @@ class DocSimpleSect : public CompAccept<DocSimpleSect>
};
/** Node representing a separator between two simple sections of the
- * same type.
+ * same type.
*/
class DocSimpleSectSep : public DocNode
{
@@ -1167,16 +1170,16 @@ class DocParamSect : public CompAccept<DocParamSect>
{
friend class DocParamList;
public:
- enum Type
- {
+ enum Type
+ {
Unknown, Param, RetVal, Exception, TemplateParam
};
enum Direction
{
In=1, Out=2, InOut=3, Unspecified=0
};
- DocParamSect(DocNode *parent,Type t)
- : m_type(t), m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE)
+ DocParamSect(DocNode *parent,Type t)
+ : m_type(t), m_hasInOutSpecifier(FALSE), m_hasTypeSpecifier(FALSE)
{ m_parent = parent; }
int parse(const QCString &cmdName,bool xmlContext,Direction d);
Kind kind() const { return Kind_ParamSect; }
@@ -1194,7 +1197,7 @@ class DocParamSect : public CompAccept<DocParamSect>
class DocPara : public CompAccept<DocPara>
{
public:
- DocPara(DocNode *parent) :
+ DocPara(DocNode *parent) :
m_isFirst(FALSE), m_isLast(FALSE) { m_parent = parent; }
int parse();
Kind kind() const { return Kind_Para; }
@@ -1241,12 +1244,12 @@ class DocPara : public CompAccept<DocPara>
class DocParamList : public DocNode
{
public:
- DocParamList(DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d)
+ DocParamList(DocNode *parent,DocParamSect::Type t,DocParamSect::Direction d)
: m_type(t), m_dir(d), m_isFirst(TRUE), m_isLast(TRUE)
- { m_paragraphs.setAutoDelete(TRUE);
- m_params.setAutoDelete(TRUE);
+ { m_paragraphs.setAutoDelete(TRUE);
+ m_params.setAutoDelete(TRUE);
m_paramTypes.setAutoDelete(TRUE);
- m_parent = parent;
+ m_parent = parent;
}
virtual ~DocParamList() { }
Kind kind() const { return Kind_ParamList; }
@@ -1259,12 +1262,12 @@ class DocParamList : public DocNode
bool isFirst() const { return m_isFirst; }
bool isLast() const { return m_isLast; }
void accept(DocVisitor *v)
- {
- v->visitPre(this);
+ {
+ v->visitPre(this);
QListIterator<DocPara> cli(m_paragraphs);
DocNode *n;
for (cli.toFirst();(n=cli.current());++cli) n->accept(v);
- v->visitPost(this);
+ v->visitPost(this);
}
int parse(const QCString &cmdName);
int parseXml(const QCString &paramName);
@@ -1290,9 +1293,9 @@ class DocSimpleListItem : public DocNode
Kind kind() const { return Kind_SimpleListItem; }
void accept(DocVisitor *v)
{
- v->visitPre(this);
+ v->visitPre(this);
m_paragraph->accept(v);
- v->visitPost(this);
+ v->visitPost(this);
}
private:
@@ -1303,7 +1306,7 @@ class DocSimpleListItem : public DocNode
class DocHtmlListItem : public CompAccept<DocHtmlListItem>
{
public:
- DocHtmlListItem(DocNode *parent,const HtmlAttribList &attribs,int num) :
+ DocHtmlListItem(DocNode *parent,const HtmlAttribList &attribs,int num) :
m_attribs(attribs), m_itemNum(num) { m_parent = parent; }
Kind kind() const { return Kind_HtmlListItem; }
int itemNumber() const { return m_itemNum; }
@@ -1335,7 +1338,7 @@ class DocHtmlCell : public CompAccept<DocHtmlCell>
friend class DocHtmlTable;
public:
enum Alignment { Left, Right, Center };
- DocHtmlCell(DocNode *parent,const HtmlAttribList &attribs,bool isHeading) :
+ DocHtmlCell(DocNode *parent,const HtmlAttribList &attribs,bool isHeading) :
m_isHeading(isHeading), m_attribs(attribs) { m_parent = parent; }
bool isHeading() const { return m_isHeading; }
bool isFirst() const { return m_isFirst; }
@@ -1387,7 +1390,7 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>
{
friend class DocHtmlTable;
public:
- DocHtmlRow(DocNode *parent,const HtmlAttribList &attribs) :
+ DocHtmlRow(DocNode *parent,const HtmlAttribList &attribs) :
m_attribs(attribs) { m_parent = parent; }
Kind kind() const { return Kind_HtmlRow; }
uint numCells() const { return m_children.count(); }
@@ -1422,7 +1425,7 @@ class DocHtmlRow : public CompAccept<DocHtmlRow>
class DocHtmlTable : public CompAccept<DocHtmlTable>
{
public:
- DocHtmlTable(DocNode *parent,const HtmlAttribList &attribs)
+ DocHtmlTable(DocNode *parent,const HtmlAttribList &attribs)
: m_attribs(attribs) { m_caption=0; m_numCols=0; m_parent = parent; }
~DocHtmlTable() { delete m_caption; }
Kind kind() const { return Kind_HtmlTable; }
diff --git a/src/doctokenizer.h b/src/doctokenizer.h
index e01f045..f43cd07 100644
--- a/src/doctokenizer.h
+++ b/src/doctokenizer.h
@@ -6,8 +6,8 @@
* 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
+ * 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.
*
@@ -78,7 +78,7 @@ struct TokenInfo
QCString text;
// comment blocks
-
+
// list token info
bool isEnumList = false;
int indent = 0;
@@ -124,7 +124,7 @@ const char *tokToString(int token);
// operations on the scanner
void doctokenizerYYFindSections(const char *input,const Definition *d,
const char *fileName);
-void doctokenizerYYinit(const char *input,const char *fileName);
+void doctokenizerYYinit(const char *input,const char *fileName,bool markdownSupport);
void doctokenizerYYcleanup();
void doctokenizerYYpushContext();
bool doctokenizerYYpopContext();
diff --git a/src/doctokenizer.l b/src/doctokenizer.l
index 5317de5..ac5b6d2 100644
--- a/src/doctokenizer.l
+++ b/src/doctokenizer.l
@@ -60,6 +60,7 @@ static const char *g_inputString;
static QCString g_fileName;
static bool g_insidePre;
static int g_sharpCount=0;
+static bool g_markdownSupport=TRUE;
// context for section finding phase
static const Definition *g_definition;
@@ -113,6 +114,20 @@ bool doctokenizerYYpopContext()
return TRUE;
}
+QCString extractPartAfterNewLine(const QCString &text)
+{
+ int nl1 = text.findRev('\n');
+ if (nl1!=-1)
+ {
+ return text.mid(nl1+1);
+ }
+ int nl2 = text.findRev("\\ilinebr");
+ if (nl2!=-1)
+ {
+ return text.mid(nl2+8);
+ }
+ return text;
+}
//--------------------------------------------------------------------------
@@ -377,7 +392,7 @@ SPCMD2 {CMD}[\\@<>&$#%~".+=|-]
SPCMD3 {CMD}_form#[0-9]+
SPCMD4 {CMD}"::"
SPCMD5 {CMD}":"
-INOUT "inout"|"in"|"out"|("in"{BLANK}*","{BLANK}*"out")|("out"{BLANK}*","{BLANK}*"in")
+INOUT "in"|"out"|("in"{BLANK}*","?{BLANK}*"out")|("out"{BLANK}*","?{BLANK}*"in")
PARAMIO {CMD}param{BLANK}*"["{BLANK}*{INOUT}{BLANK}*"]"
VARARGS "..."
TEMPCHAR [a-z_A-Z0-9.,: \t\*\&\(\)\[\]]
@@ -487,7 +502,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
return TK_LISTITEM;
}
<St_Para>^{MLISTITEM} { /* list item */
- if (!Doxygen::markdownSupport || g_insidePre)
+ if (!g_markdownSupport || g_insidePre)
{
REJECT;
}
@@ -503,7 +518,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
}
<St_Para>^{OLISTITEM} { /* numbered list item */
- if (!Doxygen::markdownSupport || g_insidePre)
+ if (!g_markdownSupport || g_insidePre)
{
REJECT;
}
@@ -519,25 +534,23 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
return TK_LISTITEM;
}
}
-<St_Para>{BLANK}*\n{LISTITEM} { /* list item on next line */
- QCString text=yytext;
- text=text.right(text.length()-text.find('\n')-1);
+<St_Para>{BLANK}*(\n|"\\ilinebr"){LISTITEM} { /* list item on next line */
+ QCString text=extractPartAfterNewLine(yytext);
int dashPos = text.findRev('-');
g_token->isEnumList = text.at(dashPos+1)=='#';
g_token->id = -1;
g_token->indent = computeIndent(text,dashPos);
return TK_LISTITEM;
}
-<St_Para>{BLANK}*\n{MLISTITEM} { /* list item on next line */
- if (!Doxygen::markdownSupport || g_insidePre)
+<St_Para>{BLANK}*(\n|"\\ilinebr"){MLISTITEM} { /* list item on next line */
+ if (!g_markdownSupport || g_insidePre)
{
REJECT;
}
else
{
- QCString text=yytext;
+ QCString text=extractPartAfterNewLine(yytext);
static QRegExp re("[*+]");
- text=text.right(text.length()-text.find('\n')-1);
int markPos = text.findRev(re);
g_token->isEnumList = FALSE;
g_token->id = -1;
@@ -545,17 +558,14 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
return TK_LISTITEM;
}
}
-<St_Para>{BLANK}*\n{OLISTITEM} { /* list item on next line */
- if (!Doxygen::markdownSupport || g_insidePre)
+<St_Para>{BLANK}*(\n|"\\ilinebr"){OLISTITEM} { /* list item on next line */
+ if (!g_markdownSupport || g_insidePre)
{
REJECT;
}
else
{
- QCString text=yytext;
- int nl=text.findRev('\n');
- int len=text.length();
- text=text.right(len-nl-1);
+ QCString text=extractPartAfterNewLine(yytext);
static QRegExp re("[1-9]");
int digitPos = text.find(re);
int dotPos = text.find('.',digitPos);
@@ -570,11 +580,10 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->indent = computeIndent(yytext,dotPos);
return TK_ENDLIST;
}
-<St_Para>{BLANK}*\n{ENDLIST} { /* end list on next line */
- QCString text=yytext;
- text=text.right(text.length()-text.find('\n')-1);
+<St_Para>{BLANK}*(\n|"\\ilinebr"){ENDLIST} { /* end list on next line */
+ QCString text=extractPartAfterNewLine(yytext);
int dotPos = text.findRev('.');
- g_token->indent = computeIndent(text,dotPos);
+ g_token->indent = computeIndent(text,dotPos);
return TK_ENDLIST;
}
<St_Para>"{"{BLANK}*"@link"/{BLANK}+ {
@@ -585,9 +594,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->name = "inheritdoc";
return TK_COMMAND_AT;
}
-<St_Para>"@_fakenl" { // artificial new line
- yylineno++;
- }
+<St_Para>"@_fakenl" { // artificial new line
+ yylineno++;
+ }
<St_Para>{SPCMD3} {
g_token->name = "_form";
bool ok;
@@ -602,6 +611,8 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->paramDir=TokenInfo::Unspecified;
return TK_COMMAND_SEL();
}
+<St_Para>"\\ilinebr" {
+ }
<St_Para>{SPCMD1} |
<St_Para>{SPCMD2} |
<St_Para>{SPCMD5} |
@@ -768,13 +779,13 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
}
<St_Para>({BLANK}*\n)+{BLANK}*\n/{MLISTITEM} { /* skip trailing paragraph followed by new list item */
- if (!Doxygen::markdownSupport || g_insidePre || g_autoListLevel==0)
+ if (!g_markdownSupport || g_insidePre || g_autoListLevel==0)
{
REJECT;
}
}
<St_Para>({BLANK}*\n)+{BLANK}*\n/{OLISTITEM} { /* skip trailing paragraph followed by new list item */
- if (!Doxygen::markdownSupport || g_insidePre || g_autoListLevel==0)
+ if (!g_markdownSupport || g_insidePre || g_autoListLevel==0)
{
REJECT;
}
@@ -799,9 +810,10 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->name = g_token->name.mid(i+1,g_token->name.length()-i-2);
BEGIN(St_Code);
}
+<St_CodeOpt>"\\ilinebr" |
<St_CodeOpt>\n |
<St_CodeOpt>. {
- unput(*yytext);
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
BEGIN(St_Code);
}
<St_Code>{WS}*{CMD}"endcode" {
@@ -823,6 +835,10 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
BEGIN(St_HtmlOnly);
}
+<St_HtmlOnlyOption>"\\ilinebr" {
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
+ BEGIN(St_HtmlOnly);
+ }
<St_HtmlOnly>{CMD}"endhtmlonly" {
return RetVal_OK;
}
@@ -914,10 +930,15 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->sectionId = QCString(yytext).stripWhiteSpace();
return RetVal_OK;
}
+<St_PlantUMLOpt>{BLANK}*{FILEMASK}{BLANK}*/"\\ilinebr" { // case 5: plain file name specified without title or attributes
+ g_token->sectionId = QCString(yytext).stripWhiteSpace();
+ return RetVal_OK;
+ }
+<St_PlantUMLOpt>"\\ilinebr" |
<St_PlantUMLOpt>"\n" |
<St_PlantUMLOpt>. {
g_token->sectionId = "";
- unput(*yytext);
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
return RetVal_OK;
}
<St_PlantUML>{CMD}"enduml" {
@@ -943,12 +964,20 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
+<St_Title>"\\ilinebr" {
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
+ return 0;
+ }
<St_TitleN>"&"{ID}";" { /* symbol */
g_token->name = yytext;
return TK_SYMBOL;
}
<St_TitleN>{HTMLTAG} {
}
+<St_TitleN>(\n|"\\ilinebr") { /* new line => end of title */
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
+ return 0;
+ }
<St_TitleN>{SPCMD1} |
<St_TitleN>{SPCMD2} { /* special command */
g_token->name = yytext+1;
@@ -975,14 +1004,14 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->chars=yytext;
return TK_WHITESPACE;
}
-<St_TitleN>\n { /* new line => end of title */
- unput(*yytext);
- return 0;
- }
<St_TitleQ>"&"{ID}";" { /* symbol */
g_token->name = yytext;
return TK_SYMBOL;
}
+<St_TitleQ>(\n|"\\ilinebr") { /* new line => end of title */
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
+ return 0;
+ }
<St_TitleQ>{SPCMD1} |
<St_TitleQ>{SPCMD2} { /* special command */
g_token->name = yytext+1;
@@ -1002,10 +1031,6 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
BEGIN(St_TitleA);
return 0;
}
-<St_TitleQ>\n { /* new line => end of title */
- unput(*yytext);
- return 0;
- }
<St_TitleA>{BLANK}*{ID}{BLANK}*"="{BLANK}* { // title attribute
g_token->name = yytext;
g_token->name = g_token->name.left(g_token->name.find('=')).stripWhiteSpace();
@@ -1020,8 +1045,8 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(*yytext);
return 0;
}
-<St_TitleV,St_TitleA>\n {
- unput(*yytext);
+<St_TitleV,St_TitleA>(\n|"\\ilinebr") {
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
return 0;
}
@@ -1049,8 +1074,8 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
unput(' ');
return 0;
}
-<St_Cite>\n { // new line
- unput(*yytext);
+<St_Cite>(\n|"\\ilinebr") { // new line
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
return 0;
}
<St_Cite>. { // any other character
@@ -1076,8 +1101,8 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<St_Ref>{WS}+"\""{WS}* { // white space following by quoted string
BEGIN(St_Ref2);
}
-<St_Ref>\n { // new line
- unput(*yytext);
+<St_Ref>(\n|"\\ilinebr") { // new line
+ for (int i=yyleng-1;i>=0;i--) unput(yytext[i]);
return 0;
}
<St_Ref>. { // any other character
@@ -1123,6 +1148,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->name = yytext;
return TK_SYMBOL;
}
+<St_Ref2>"\""|\n|"\\ilinebr" { /* " or \n => end of title */
+ return 0;
+ }
<St_Ref2>{SPCMD1} |
<St_Ref2>{SPCMD2} { /* special command */
g_token->name = yytext+1;
@@ -1139,9 +1167,6 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
g_token->chars=yytext;
return TK_WHITESPACE;
}
-<St_Ref2>"\""|\n { /* " or \n => end of title */
- return 0;
- }
<St_XRefItem>{LABELID} {
g_token->name=yytext;
}
@@ -1235,7 +1260,7 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
/* State for skipping title (all chars until the end of the line) */
<St_SkipTitle>.
-<St_SkipTitle>\n { return 0; }
+<St_SkipTitle>(\n|"\\ilinebr") { return 0; }
/* State for the pass used to find the anchors and sections */
@@ -1341,9 +1366,9 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
}
<St_SecSkip>[^a-z_A-Z0-9\-\\\@]+
<St_SecSkip>.
-<St_SecSkip>\n
+<St_SecSkip>(\n|"\\ilinebr")
<St_Sections>.
-<St_Sections>\n
+<St_Sections>(\n|"\\ilinebr")
<St_SecLabel1>{LABELID} {
g_secLabel = yytext;
processSection();
@@ -1359,6 +1384,10 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
<St_SecTitle>[^\n]*\n {
g_secTitle = yytext;
g_secTitle = g_secTitle.stripWhiteSpace();
+ if (g_secTitle.right(8)=="\\ilinebr")
+ {
+ g_secTitle.left(g_secTitle.length()-8);
+ }
processSection();
BEGIN(St_Sections);
}
@@ -1366,17 +1395,23 @@ REFWORD_NOCV {FILEMASK}|{LABELID}|{REFWORD2_NOCV}|{REFWORD3}|{REFWORD4_NOCV}
warn(g_fileName,yylineno,"Unexpected character '%s' while looking for section label or title",yytext);
}
-<St_Snippet>[^\n]+ |
-<St_Snippet>[^\n]*\n {
- g_token->name = yytext;
+<St_Snippet>[^\\\n]+ {
+ g_token->name += yytext;
+ }
+<St_Snippet>"\\" {
+ g_token->name += yytext;
+ }
+<St_Snippet>(\n|"\\ilinebr") {
g_token->name = g_token->name.stripWhiteSpace();
- return TK_WORD;
+ return TK_WORD;
}
/* Generic rules that work for all states */
<*>\n {
warn(g_fileName,yylineno,"Unexpected new line character");
}
+<*>"\\ilinebr" {
+ }
<*>[\\@<>&$#%~"=] { /* unescaped special character */
//warn(g_fileName,yylineno,"Unexpected character '%s', assuming command \\%s was meant.",yytext,yytext);
g_token->name = yytext;
@@ -1405,13 +1440,14 @@ void doctokenizerYYFindSections(const char *input,const Definition *d,
printlex(yy_flex_debug, FALSE, __FILE__, fileName);
}
-void doctokenizerYYinit(const char *input,const char *fileName)
+void doctokenizerYYinit(const char *input,const char *fileName,bool markdownSupport)
{
g_autoListLevel = 0;
g_inputString = input;
g_inputPos = 0;
g_fileName = fileName;
g_insidePre = FALSE;
+ g_markdownSupport = markdownSupport;
BEGIN(St_Para);
}
@@ -1569,6 +1605,7 @@ void doctokenizerYYsetStateAnchor()
void doctokenizerYYsetStateSnippet()
{
+ g_token->name="";
BEGIN(St_Snippet);
}
diff --git a/src/dot.cpp b/src/dot.cpp
index 675ead6..ddabbc7 100644
--- a/src/dot.cpp
+++ b/src/dot.cpp
@@ -13,7 +13,8 @@
*
*/
-#include <stdlib.h>
+#include <cstdlib>
+#include <cassert>
#include <qdir.h>
diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp
index 20ce4c1..17f8cb7 100644
--- a/src/dotfilepatcher.cpp
+++ b/src/dotfilepatcher.cpp
@@ -460,7 +460,7 @@ bool DotFilePatcher::run() const
convertMapFile(tt,map->mapFile,map->relPath,map->urlOnly,map->context);
if (!result.isEmpty())
{
- t << "<map name=\"" << map->label << "\" id=\"" << map->label << "\">" << endl;
+ t << "<map name=\"" << map->label << "\" id=\"" << correctId(map->label) << "\">" << endl;
t << result;
t << "</map>" << endl;
}
diff --git a/src/dotgraph.cpp b/src/dotgraph.cpp
index c0cc4fd..1ad85e1 100644
--- a/src/dotgraph.cpp
+++ b/src/dotgraph.cpp
@@ -236,7 +236,7 @@ void DotGraph::generateCode(FTextStream &t)
else // add link to bitmap file with image map
{
if (!m_noDivTag) t << "<div class=\"center\">";
- t << "<img src=\"" << relImgName() << "\" border=\"0\" usemap=\"#" << getMapLabel() << "\" alt=\"" << getImgAltText() << "\"/>";
+ t << "<img src=\"" << relImgName() << "\" border=\"0\" usemap=\"#" << correctId(getMapLabel()) << "\" alt=\"" << getImgAltText() << "\"/>";
if (!m_noDivTag) t << "</div>";
t << endl;
if (m_regenerate || !insertMapFile(t, absMapName(), m_relPath, getMapLabel()))
diff --git a/src/dotrunner.cpp b/src/dotrunner.cpp
index 8cf09fa..a1bbc52 100644
--- a/src/dotrunner.cpp
+++ b/src/dotrunner.cpp
@@ -13,6 +13,8 @@
*
*/
+#include <cassert>
+
#include "dotrunner.h"
#include "qstring.h"
@@ -151,7 +153,6 @@ DotRunner::DotRunner(const std::string& absDotName, const std::string& md5Hash)
, m_md5Hash(md5Hash.data())
, m_dotExe(Config_getString(DOT_PATH)+"dot")
, m_cleanUp(Config_getBool(DOT_CLEANUP))
- , m_jobs()
{
}
diff --git a/src/doxygen.cpp b/src/doxygen.cpp
index 1824ceb..dab7549 100644
--- a/src/doxygen.cpp
+++ b/src/doxygen.cpp
@@ -104,6 +104,7 @@
#include "plantuml.h"
#include "stlsupport.h"
#include "threadpool.h"
+#include "clangparser.h"
// provided by the generated file resources.cpp
extern void initResources();
@@ -158,9 +159,9 @@ int Doxygen::subpageNestingLevel = 0;
bool Doxygen::userComments = FALSE;
QCString Doxygen::spaces;
bool Doxygen::generatingXmlOutput = FALSE;
-bool Doxygen::markdownSupport = TRUE;
GenericsSDict *Doxygen::genericsDict;
-DefineList Doxygen::macroDefinitions;
+DefinesPerFileList Doxygen::macroDefinitions;
+bool Doxygen::clangAssistedParsing = FALSE;
// locally accessible globals
static std::unordered_map< std::string, const Entry* > g_classEntries;
@@ -628,7 +629,7 @@ static void addIncludeFile(ClassDef *cd,FileDef *ifd,const Entry *root)
iName=fd->name();
}
}
- else if (!Config_getList(STRIP_FROM_INC_PATH).isEmpty())
+ else if (!Config_getList(STRIP_FROM_INC_PATH).empty())
{
iName=stripFromIncludePath(fd->absFilePath());
}
@@ -3443,7 +3444,7 @@ static void buildFunctionList(const Entry *root)
{
// merge argument lists
ArgumentList mergedArgList = root->argList;
- mergeArguments(mdAl,mergedArgList,!root->proto);
+ mergeArguments(mdAl,mergedArgList,!root->doc.isEmpty());
// merge documentation
if (md->documentation().isEmpty() && !root->doc.isEmpty())
{
@@ -4952,7 +4953,7 @@ static void addMemberDocs(const Entry *root,
{
ArgumentList mergedAl = *al;
//printf("merging arguments (1) docs=%d\n",root->doc.isEmpty());
- mergeArguments(mdAl,mergedAl,!root->proto);
+ mergeArguments(mdAl,mergedAl,!root->doc.isEmpty());
}
else
{
@@ -4965,7 +4966,7 @@ static void addMemberDocs(const Entry *root,
{
//printf("merging arguments (2)\n");
ArgumentList mergedArgList = root->argList;
- mergeArguments(mdAl,mergedArgList,!root->proto);
+ mergeArguments(mdAl,mergedArgList,!root->doc.isEmpty());
}
}
if (over_load) // the \overload keyword was used
@@ -5645,7 +5646,7 @@ static void addMemberFunction(const Entry *root,
root->protection,root->stat,root->virt,spec,relates);
return;
}
- if (md->argsString()==argListToString(root->argList,TRUE,FALSE))
+ if (md->argsString()==argListToString(root->argList,FALSE,FALSE))
{ // exact argument list match -> remember
ucd = ecd = ccd;
umd = emd = cmd;
@@ -7478,18 +7479,18 @@ static void generateFileSources()
if (!Doxygen::inputNameLinkedMap->empty())
{
#if USE_LIBCLANG
- static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
- if (clangAssistedParsing)
+ if (Doxygen::clangAssistedParsing)
{
- QDict<void> g_processedFiles(10007);
+ StringUnorderedSet processedFiles;
// create a dictionary with files to process
- QDict<void> g_filesToProcess(10007);
+ StringUnorderedSet filesToProcess;
+
for (const auto &fn : *Doxygen::inputNameLinkedMap)
{
for (const auto &fd : *fn)
{
- g_filesToProcess.insert(fd->absFilePath(),(void*)0x8);
+ filesToProcess.insert(fd->absFilePath().str());
}
}
// process source files (and their include dependencies)
@@ -7499,51 +7500,49 @@ static void generateFileSources()
{
if (fd->isSource() && !fd->isReference())
{
- QStrList filesInSameTu;
- fd->getAllIncludeFilesRecursively(filesInSameTu);
- fd->startParsing();
+ auto clangParser = ClangParser::instance()->createTUParser(fd.get());
if (fd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output
{
msg("Generating code for file %s...\n",fd->docName().data());
- fd->writeSource(*g_outputList,FALSE,filesInSameTu);
+ clangParser->parse();
+ fd->writeSource(*g_outputList,clangParser.get());
}
else if (!fd->isReference() && Doxygen::parseSourcesNeeded)
// we needed to parse the sources even if we do not show them
{
msg("Parsing code for file %s...\n",fd->docName().data());
- fd->parseSource(FALSE,filesInSameTu);
+ clangParser->parse();
+ fd->parseSource(clangParser.get());
}
- char *incFile = filesInSameTu.first();
- while (incFile && g_filesToProcess.find(incFile))
+ for (auto incFile : clangParser->filesInSameTU())
{
- if (fd->absFilePath()!=incFile && !g_processedFiles.find(incFile))
+ if (filesToProcess.find(incFile)!=filesToProcess.end() && // part of input
+ fd->absFilePath()!=incFile && // not same file
+ processedFiles.find(incFile)==processedFiles.end()) // not yet marked as processed
{
- QStrList moreFiles;
+ StringVector moreFiles;
bool ambig;
- FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile,ambig);
+ FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
if (ifd && !ifd->isReference())
{
if (ifd->generateSourceFile() && !g_useOutputTemplate) // sources need to be shown in the output
{
msg(" Generating code for file %s...\n",ifd->docName().data());
- ifd->writeSource(*g_outputList,TRUE,moreFiles);
-
+ ifd->writeSource(*g_outputList,clangParser.get());
}
else if (!ifd->isReference() && Doxygen::parseSourcesNeeded)
// we needed to parse the sources even if we do not show them
{
msg(" Parsing code for file %s...\n",ifd->docName().data());
- ifd->parseSource(TRUE,moreFiles);
+ ifd->parseSource(clangParser.get());
}
- g_processedFiles.insert(incFile,(void*)0x8);
+ processedFiles.insert(incFile);
}
}
- incFile = filesInSameTu.next();
}
- fd->finishParsing();
- g_processedFiles.insert(fd->absFilePath(),(void*)0x8);
+ processedFiles.insert(fd->absFilePath().str());
}
}
}
@@ -7552,23 +7551,23 @@ static void generateFileSources()
{
for (const auto &fd : *fn)
{
- if (!g_processedFiles.find(fd->absFilePath())) // not yet processed
+ if (processedFiles.find(fd->absFilePath().str())==processedFiles.end()) // not yet processed
{
- QStrList filesInSameTu;
- fd->startParsing();
+ auto clangParser = ClangParser::instance()->createTUParser(fd.get());
if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output
{
msg("Generating code for file %s...\n",fd->docName().data());
- fd->writeSource(*g_outputList,FALSE,filesInSameTu);
+ clangParser->parse();
+ fd->writeSource(*g_outputList,clangParser.get());
}
else if (!fd->isReference() && Doxygen::parseSourcesNeeded)
// we needed to parse the sources even if we do not show them
{
msg("Parsing code for file %s...\n",fd->docName().data());
- fd->parseSource(FALSE,filesInSameTu);
+ clangParser->parse();
+ fd->parseSource(clangParser.get());
}
- fd->finishParsing();
}
}
}
@@ -7580,21 +7579,20 @@ static void generateFileSources()
{
for (const auto &fd : *fn)
{
- QStrList filesInSameTu;
- fd->startParsing();
+ StringVector filesInSameTu;
+ fd->getAllIncludeFilesRecursively(filesInSameTu);
if (fd->generateSourceFile() && !Htags::useHtags && !g_useOutputTemplate) // sources need to be shown in the output
{
msg("Generating code for file %s...\n",fd->docName().data());
- fd->writeSource(*g_outputList,FALSE,filesInSameTu);
+ fd->writeSource(*g_outputList,nullptr);
}
else if (!fd->isReference() && Doxygen::parseSourcesNeeded)
// we needed to parse the sources even if we do not show them
{
msg("Parsing code for file %s...\n",fd->docName().data());
- fd->parseSource(FALSE,filesInSameTu);
+ fd->parseSource(nullptr);
}
- fd->finishParsing();
}
}
}
@@ -7702,28 +7700,35 @@ static void addSourceReferences()
// add the macro definitions found during preprocessing as file members
static void buildDefineList()
{
- for (const auto &def : Doxygen::macroDefinitions)
+ for (const auto &s : g_inputFiles)
{
- 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())
+ auto it = Doxygen::macroDefinitions.find(s);
+ if (it!=Doxygen::macroDefinitions.end())
{
- md->moveArgumentList(stringToArgumentList(SrcLangExt_Cpp, def->args));
- }
- md->setInitializer(def->definition);
- md->setFileDef(def->fileDef);
- md->setDefinition("#define "+def->name);
+ for (const auto &def : it->second)
+ {
+ 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(),"") };
- MemberName *mn=Doxygen::functionNameLinkedMap->add(def->name);
- if (def->fileDef)
- {
- def->fileDef->insertMember(md.get());
+ 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));
+ }
}
- mn->push_back(std::move(md));
}
}
@@ -8632,7 +8637,10 @@ static void generateExampleDocs()
pd->documentation()+"\n\n\\include"+lineNoOptStr+" "+pd->name(), // docs
TRUE, // index words
TRUE, // is example
- pd->name()
+ pd->name(),
+ FALSE,
+ FALSE,
+ Config_getBool(MARKDOWN_SUPPORT)
);
endFile(*g_outputList); // contains g_outputList->endContents()
}
@@ -8856,10 +8864,10 @@ static void readTagFile(const std::shared_ptr<Entry> &root,const char *tl)
//----------------------------------------------------------------------------
static void copyLatexStyleSheet()
{
- QStrList latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
- for (uint i=0; i<latexExtraStyleSheet.count(); ++i)
+ const StringVector &latexExtraStyleSheet = Config_getList(LATEX_EXTRA_STYLESHEET);
+ for (const auto &sheet : latexExtraStyleSheet)
{
- QCString fileName(latexExtraStyleSheet.at(i));
+ QCString fileName = sheet.c_str();
if (!fileName.isEmpty())
{
QFileInfo fi(fileName);
@@ -8883,14 +8891,14 @@ static void copyLatexStyleSheet()
//----------------------------------------------------------------------------
static void copyStyleSheet()
{
- QCString &htmlStyleSheet = Config_getString(HTML_STYLESHEET);
+ QCString htmlStyleSheet = Config_getString(HTML_STYLESHEET);
if (!htmlStyleSheet.isEmpty())
{
QFileInfo fi(htmlStyleSheet);
if (!fi.exists())
{
err("Style sheet '%s' specified by HTML_STYLESHEET does not exist!\n",htmlStyleSheet.data());
- htmlStyleSheet.resize(0); // revert to the default
+ htmlStyleSheet = Config_updateString(HTML_STYLESHEET,""); // revert to the default
}
else
{
@@ -8898,10 +8906,10 @@ static void copyStyleSheet()
copyFile(htmlStyleSheet,destFileName);
}
}
- QStrList htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
- for (uint i=0; i<htmlExtraStyleSheet.count(); ++i)
+ const StringVector &htmlExtraStyleSheet = Config_getList(HTML_EXTRA_STYLESHEET);
+ for (const auto &sheet : htmlExtraStyleSheet)
{
- QCString fileName(htmlExtraStyleSheet.at(i));
+ QCString fileName = sheet.c_str();
if (!fileName.isEmpty())
{
QFileInfo fi(fileName);
@@ -8924,14 +8932,14 @@ static void copyStyleSheet()
static void copyLogo(const QCString &outputOption)
{
- QCString &projectLogo = Config_getString(PROJECT_LOGO);
+ QCString projectLogo = Config_getString(PROJECT_LOGO);
if (!projectLogo.isEmpty())
{
QFileInfo fi(projectLogo);
if (!fi.exists())
{
err("Project logo '%s' specified by PROJECT_LOGO does not exist!\n",projectLogo.data());
- projectLogo.resize(0); // revert to the default
+ projectLogo = Config_updateString(PROJECT_LOGO,""); // revert to the default
}
else
{
@@ -8942,13 +8950,11 @@ static void copyLogo(const QCString &outputOption)
}
}
-static void copyExtraFiles(QStrList files,const QCString &filesOption,const QCString &outputOption)
+static void copyExtraFiles(const StringVector &files,const QCString &filesOption,const QCString &outputOption)
{
- uint i;
- for (i=0; i<files.count(); ++i)
+ for (const auto &file : files)
{
- QCString fileName(files.at(i));
-
+ QCString fileName = file.c_str();
if (!fileName.isEmpty())
{
QFileInfo fi(fileName);
@@ -9054,13 +9060,8 @@ static std::unique_ptr<OutlineParserInterface> getParserForFile(const char *fn)
static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser,
FileDef *fd,const char *fn,
- bool sameTu,QStrList &filesInSameTu)
+ ClangTUParser *clangParser,bool newTU)
{
-#if USE_LIBCLANG
- static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
-#else
- static bool clangAssistedParsing = FALSE;
-#endif
QCString fileName=fn;
QCString extension;
int ei = fileName.findRev('.');
@@ -9080,12 +9081,10 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser,
parser.needsPreprocessing(extension))
{
Preprocessor preprocessor;
- QStrList &includePath = Config_getList(INCLUDE_PATH);
- char *s=includePath.first();
- while (s)
+ const StringVector &includePath = Config_getList(INCLUDE_PATH);
+ for (const auto &s : includePath)
{
- preprocessor.addSearchDir(QFileInfo(s).absFilePath().utf8());
- s=includePath.next();
+ preprocessor.addSearchDir(QFileInfo(s.c_str()).absFilePath().utf8());
}
BufStr inBuf(fi.size()+4096);
msg("Preprocessing %s...\n",fn);
@@ -9109,35 +9108,41 @@ static std::shared_ptr<Entry> parseFile(OutlineParserInterface &parser,
convBuf.addChar('\0');
- if (clangAssistedParsing && !sameTu)
- {
- fd->getAllIncludeFilesRecursively(filesInSameTu);
- }
-
std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>();
// use language parse to parse the file
- parser.parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu);
+ if (clangParser)
+ {
+ if (newTU) clangParser->parse();
+ clangParser->switchToFile(fd);
+ }
+ parser.parseInput(fileName,convBuf.data(),fileRoot,clangParser);
fileRoot->setFileDef(fd);
return fileRoot;
}
+#if MULTITHREADED_INPUT
+
//! parse the list of input files
static void parseFiles(const std::shared_ptr<Entry> &root)
{
#if USE_LIBCLANG
- static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
- if (clangAssistedParsing)
+ if (Doxygen::clangAssistedParsing)
{
- QDict<void> g_processedFiles(10007);
+ StringUnorderedSet processedFiles;
// create a dictionary with files to process
- QDict<void> g_filesToProcess(10007);
+ StringUnorderedSet filesToProcess;
for (const auto &s : g_inputFiles)
{
- g_filesToProcess.insert(s.c_str(),(void*)0x8);
+ filesToProcess.insert(s);
}
+ std::mutex processedFilesLock;
// process source files (and their include dependencies)
+ std::size_t numThreads = std::thread::hardware_concurrency();
+ msg("Processing input using %lu threads.\n",numThreads);
+ ThreadPool threadPool(numThreads);
+ std::vector< std::future< std::vector< std::shared_ptr<Entry> > > > results;
for (const auto &s : g_inputFiles)
{
bool ambig;
@@ -9145,70 +9150,89 @@ static void parseFiles(const std::shared_ptr<Entry> &root)
ASSERT(fd!=0);
if (fd->isSource() && !fd->isReference()) // this is a source file
{
- QStrList filesInSameTu;
- std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
- parser->startTranslationUnit(s.c_str());
- std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),FALSE,filesInSameTu);
- root->moveToSubEntryAndKeep(fileRoot);
- //printf(" got %d extra files in tu\n",filesInSameTu.count());
-
- // Now process any include files in the same translation unit
- // first. When libclang is used this is much more efficient.
- char *incFile = filesInSameTu.first();
- while (incFile && g_filesToProcess.find(incFile))
- {
- if (qstrcmp(incFile,s.c_str()) && !g_processedFiles.find(incFile))
+ // lambda representing the work to executed by a thread
+ auto processFile = [s,&filesToProcess,&processedFilesLock,&processedFiles]() {
+ bool ambig;
+ std::vector< std::shared_ptr<Entry> > roots;
+ FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
+ auto clangParser = ClangParser::instance()->createTUParser(fd);
+ auto parser = getParserForFile(s.c_str());
+ auto fileRoot { parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true) };
+ roots.push_back(fileRoot);
+
+ // Now process any include files in the same translation unit
+ // first. When libclang is used this is much more efficient.
+ for (auto incFile : clangParser->filesInSameTU())
{
- FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile,ambig);
- if (ifd && !ifd->isReference())
+ if (filesToProcess.find(incFile)!=filesToProcess.end())
{
- QStrList moreFiles;
- //printf(" Processing %s in same translation unit as %s\n",incFile,s->c_str());
- fileRoot = parseFile(*parser.get(),ifd,incFile,TRUE,moreFiles);
- root->moveToSubEntryAndKeep(fileRoot);
- g_processedFiles.insert(incFile,(void*)0x8);
+ bool needsToBeProcessed;
+ {
+ std::lock_guard<std::mutex> lock(processedFilesLock);
+ needsToBeProcessed = processedFiles.find(incFile)==processedFiles.end();
+ if (needsToBeProcessed) processedFiles.insert(incFile);
+ }
+ if (incFile!=s && needsToBeProcessed)
+ {
+ FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
+ if (ifd && !ifd->isReference())
+ {
+ //printf(" Processing %s in same translation unit as %s\n",incFile,s->c_str());
+ fileRoot = parseFile(*parser.get(),ifd,incFile.c_str(),clangParser.get(),false);
+ roots.push_back(fileRoot);
+ }
+ }
}
}
- incFile = filesInSameTu.next();
- }
- parser->finishTranslationUnit();
- g_processedFiles.insert(s.c_str(),(void*)0x8);
+ return roots;
+ };
+ // dispatch the work and collect the future results
+ results.emplace_back(threadPool.queue(processFile));
+ }
+ }
+ // synchronise with the Entry result lists produced and add them to the root
+ for (auto &f : results)
+ {
+ auto l = f.get();
+ for (auto &e : l)
+ {
+ root->moveToSubEntryAndKeep(e);
}
}
// process remaining files
+ results.clear();
for (const auto &s : g_inputFiles)
{
- if (!g_processedFiles.find(s.c_str())) // not yet processed
+ if (processedFiles.find(s)==processedFiles.end()) // not yet processed
{
- bool ambig;
- QStrList filesInSameTu;
- FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
- ASSERT(fd!=0);
- std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
- parser->startTranslationUnit(s.c_str());
- std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),FALSE,filesInSameTu);
- root->moveToSubEntryAndKeep(fileRoot);
- parser->finishTranslationUnit();
- g_processedFiles.insert(s.c_str(),(void*)0x8);
+ // lambda representing the work to executed by a thread
+ auto processFile = [s]() {
+ bool ambig;
+ std::vector< std::shared_ptr<Entry> > roots;
+ FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
+ auto clangParser = ClangParser::instance()->createTUParser(fd);
+ auto parser { getParserForFile(s.c_str()) };
+ auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
+ roots.push_back(fileRoot);
+ return roots;
+ };
+ // dispatch the work and collect the future results
+ results.emplace_back(threadPool.queue(processFile));
+ }
+ }
+ // synchronise with the Entry result lists produced and add them to the root
+ for (auto &f : results)
+ {
+ auto l = f.get();
+ for (auto &e : l)
+ {
+ root->moveToSubEntryAndKeep(e);
}
}
}
else // normal processing
#endif
{
-#if !MULTITHREADED_INPUT
- for (const auto &s : g_inputFiles)
- {
- bool ambig;
- QStrList filesInSameTu;
- FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
- ASSERT(fd!=0);
- std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
- parser->startTranslationUnit(s.c_str());
- std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),FALSE,filesInSameTu);
- root->moveToSubEntryAndKeep(fileRoot);
- }
-#else
std::size_t numThreads = std::thread::hardware_concurrency();
msg("Processing input using %lu threads.\n",numThreads);
ThreadPool threadPool(numThreads);
@@ -9218,12 +9242,10 @@ static void parseFiles(const std::shared_ptr<Entry> &root)
// lambda representing the work to executed by a thread
auto processFile = [s]() {
bool ambig;
- QStrList filesInSameTu;
FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
- ASSERT(fd!=0);
- std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
- parser->startTranslationUnit(s.c_str());
- std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),FALSE,filesInSameTu);
+ auto clangParser = ClangParser::instance()->createTUParser(fd);
+ auto parser = getParserForFile(s.c_str());
+ auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
return fileRoot;
};
// dispatch the work and collect the future results
@@ -9235,10 +9257,92 @@ static void parseFiles(const std::shared_ptr<Entry> &root)
root->moveToSubEntryAndKeep(f.get());
}
#warning "Multi-threaded input enabled. This is a highly experimental feature. Only use for doxygen development."
+ }
+}
+
+#else // !MULTITHREADED_INPUT
+
+//! parse the list of input files
+static void parseFiles(const std::shared_ptr<Entry> &root)
+{
+#if USE_LIBCLANG
+ if (Doxygen::clangAssistedParsing)
+ {
+ StringUnorderedSet processedFiles;
+
+ // create a dictionary with files to process
+ StringUnorderedSet filesToProcess;
+ for (const auto &s : g_inputFiles)
+ {
+ filesToProcess.insert(s);
+ }
+
+ // process source files (and their include dependencies)
+ for (const auto &s : g_inputFiles)
+ {
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
+ ASSERT(fd!=0);
+ if (fd->isSource() && !fd->isReference()) // this is a source file
+ {
+ auto clangParser = ClangParser::instance()->createTUParser(fd);
+ auto parser { getParserForFile(s.c_str()) };
+ auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
+ root->moveToSubEntryAndKeep(fileRoot);
+ processedFiles.insert(s);
+
+ // Now process any include files in the same translation unit
+ // first. When libclang is used this is much more efficient.
+ for (auto incFile : clangParser->filesInSameTU())
+ {
+ //printf(" file %s\n",incFile.c_str());
+ if (filesToProcess.find(incFile)!=filesToProcess.end() && // file need to be processed
+ processedFiles.find(incFile)==processedFiles.end()) // and is not processed already
+ {
+ FileDef *ifd=findFileDef(Doxygen::inputNameLinkedMap,incFile.c_str(),ambig);
+ if (ifd && !ifd->isReference())
+ {
+ //printf(" Processing %s in same translation unit as %s\n",incFile.c_str(),s.c_str());
+ fileRoot = parseFile(*parser.get(),ifd,incFile.c_str(),clangParser.get(),false);
+ root->moveToSubEntryAndKeep(fileRoot);
+ processedFiles.insert(incFile);
+ }
+ }
+ }
+ }
+ }
+ // process remaining files
+ for (const auto &s : g_inputFiles)
+ {
+ if (processedFiles.find(s)==processedFiles.end()) // not yet processed
+ {
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
+ auto clangParser = ClangParser::instance()->createTUParser(fd);
+ auto parser { getParserForFile(s.c_str()) };
+ auto fileRoot = parseFile(*parser.get(),fd,s.c_str(),clangParser.get(),true);
+ root->moveToSubEntryAndKeep(fileRoot);
+ processedFiles.insert(s);
+ }
+ }
+ }
+ else // normal processing
#endif
+ {
+ for (const auto &s : g_inputFiles)
+ {
+ bool ambig;
+ FileDef *fd=findFileDef(Doxygen::inputNameLinkedMap,s.c_str(),ambig);
+ ASSERT(fd!=0);
+ std::unique_ptr<OutlineParserInterface> parser { getParserForFile(s.c_str()) };
+ std::shared_ptr<Entry> fileRoot = parseFile(*parser.get(),fd,s.c_str(),nullptr,true);
+ root->moveToSubEntryAndKeep(fileRoot);
+ }
}
}
+#endif
+
// resolves a path that may include symlinks, if a recursive symlink is
// found an empty string is returned.
static QCString resolveSymlink(QCString path)
@@ -9318,8 +9422,8 @@ static QDict<void> g_pathsVisited(1009);
static int readDir(QFileInfo *fi,
FileNameLinkedMap *fnMap,
StringUnorderedSet *exclSet,
- QStrList *patList,
- QStrList *exclPatList,
+ const StringVector *patList,
+ const StringVector *exclPatList,
StringVector *resultList,
StringUnorderedSet *resultSet,
bool errorIfNotExist,
@@ -9366,8 +9470,8 @@ static int readDir(QFileInfo *fi,
}
else if (cfi->isFile() &&
(!Config_getBool(EXCLUDE_SYMLINKS) || !cfi->isSymLink()) &&
- (patList==0 || patternMatch(*cfi,patList)) &&
- !patternMatch(*cfi,exclPatList) &&
+ (patList==0 || patternMatch(*cfi,*patList)) &&
+ (exclPatList==0 || !patternMatch(*cfi,*exclPatList)) &&
(killSet==0 || killSet->find(cfi->absFilePath().utf8().data())==killSet->end())
)
{
@@ -9391,7 +9495,7 @@ static int readDir(QFileInfo *fi,
else if (recursive &&
(!Config_getBool(EXCLUDE_SYMLINKS) || !cfi->isSymLink()) &&
cfi->isDir() &&
- !patternMatch(*cfi,exclPatList) &&
+ (exclPatList==0 || !patternMatch(*cfi,*exclPatList)) &&
cfi->fileName().at(0)!='.') // skip "." ".." and ".dir"
{
cfi->setFile(cfi->absFilePath());
@@ -9414,8 +9518,8 @@ static int readDir(QFileInfo *fi,
int readFileOrDirectory(const char *s,
FileNameLinkedMap *fnMap,
StringUnorderedSet *exclSet,
- QStrList *patList,
- QStrList *exclPatList,
+ const StringVector *patList,
+ const StringVector *exclPatList,
StringVector *resultList,
StringUnorderedSet *resultSet,
bool recursive,
@@ -9524,7 +9628,7 @@ static void escapeAliases()
value.mid(in,14)!="\\nosubgrouping"
)
{
- newValue+="\\_linebr ";
+ newValue+="\\ilinebr ";
}
else
{
@@ -9539,7 +9643,7 @@ static void escapeAliases()
while ((in=value.find("^^",p))!=-1)
{
newValue+=value.mid(p,in-p);
- newValue+="\\\\_linebr ";
+ newValue+="\\ilinebr ";
p=in+2;
}
newValue+=value.mid(p,value.length()-p);
@@ -9554,13 +9658,12 @@ void readAliases()
{
// add aliases to a dictionary
Doxygen::aliasDict.setAutoDelete(TRUE);
- QStrList &aliasList = Config_getList(ALIASES);
- const char *s=aliasList.first();
- while (s)
+ const StringVector &aliasList = Config_getList(ALIASES);
+ for (const auto &s : aliasList)
{
- if (Doxygen::aliasDict[s]==0)
+ QCString alias=s.c_str();
+ if (Doxygen::aliasDict[alias]==0)
{
- QCString alias=s;
int i=alias.find('=');
if (i>0)
{
@@ -9581,7 +9684,6 @@ void readAliases()
}
}
}
- s=aliasList.next();
}
expandAliases();
escapeAliases();
@@ -9709,9 +9811,7 @@ static const char *getArg(int argc,char **argv,int &optind)
class NullOutlineParser : public OutlineParserInterface
{
public:
- void startTranslationUnit(const char *) {}
- void finishTranslationUnit() {}
- void parseInput(const char *, const char *,const std::shared_ptr<Entry> &, bool, QStrList &) {}
+ void parseInput(const char *, const char *,const std::shared_ptr<Entry> &, ClangTUParser*) {}
bool needsPreprocessing(const QCString &) const { return FALSE; }
void parsePrototype(const char *) {}
};
@@ -10302,21 +10402,17 @@ void adjustConfiguration()
Config_getBool(REFERENCES_RELATION) ||
Config_getBool(REFERENCED_BY_RELATION);
- Doxygen::markdownSupport = Config_getBool(MARKDOWN_SUPPORT);
-
/**************************************************************************
* Add custom extension mappings
**************************************************************************/
- QStrList &extMaps = Config_getList(EXTENSION_MAPPING);
- char *mapping = extMaps.first();
- while (mapping)
+ const StringVector &extMaps = Config_getList(EXTENSION_MAPPING);
+ for (const auto &mapping : extMaps)
{
- QCString mapStr = mapping;
+ QCString mapStr = mapping.c_str();
int i=mapStr.find('=');
if (i==-1)
{
- mapping = extMaps.next();
continue;
}
else
@@ -10325,7 +10421,6 @@ void adjustConfiguration()
QCString language = mapStr.mid(i+1).stripWhiteSpace().lower();
if (ext.isEmpty() || language.isEmpty())
{
- mapping = extMaps.next();
continue;
}
@@ -10341,23 +10436,20 @@ void adjustConfiguration()
ext.data(),language.data());
}
}
- mapping = extMaps.next();
}
// add predefined macro name to a dictionary
- QStrList &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
- char *s=expandAsDefinedList.first();
- while (s)
+ const StringVector &expandAsDefinedList =Config_getList(EXPAND_AS_DEFINED);
+ for (const auto &s : expandAsDefinedList)
{
- Doxygen::expandAsDefinedSet.insert(s);
- s=expandAsDefinedList.next();
+ Doxygen::expandAsDefinedSet.insert(s.c_str());
}
// read aliases and store them in a dictionary
readAliases();
// store number of spaces in a tab into Doxygen::spaces
- int &tabSize = Config_getInt(TAB_SIZE);
+ int tabSize = Config_getInt(TAB_SIZE);
Doxygen::spaces.resize(tabSize+1);
int sp;for (sp=0;sp<tabSize;sp++) Doxygen::spaces.at(sp)=' ';
Doxygen::spaces.at(tabSize)='\0';
@@ -10387,7 +10479,7 @@ static void stopDoxygen(int)
static void writeTagFile()
{
- QCString &generateTagFile = Config_getString(GENERATE_TAGFILE);
+ QCString generateTagFile = Config_getString(GENERATE_TAGFILE);
if (generateTagFile.isEmpty()) return;
QFile tag(generateTagFile);
@@ -10490,26 +10582,26 @@ static void exitDoxygen()
}
static QCString createOutputDirectory(const QCString &baseDirName,
- QCString &formatDirName,
+ const QCString &formatDirName,
const char *defaultDirName)
{
- // Note the & on the next line, we modify the formatDirOption!
- if (formatDirName.isEmpty())
+ QCString result = formatDirName;
+ if (result.isEmpty())
{
- formatDirName = baseDirName + defaultDirName;
+ result = baseDirName + defaultDirName;
}
else if (formatDirName[0]!='/' && (formatDirName.length()==1 || formatDirName[1]!=':'))
{
- formatDirName.prepend(baseDirName+'/');
+ result.prepend(baseDirName+'/');
}
- QDir formatDir(formatDirName);
- if (!formatDir.exists() && !formatDir.mkdir(formatDirName))
+ QDir formatDir(result);
+ if (!formatDir.exists() && !formatDir.mkdir(result))
{
- err("Could not create output directory %s\n", formatDirName.data());
+ err("Could not create output directory %s\n", result.data());
cleanUpDoxygen();
exit(1);
}
- return formatDirName;
+ return result;
}
static QCString getQchFileName()
@@ -10533,23 +10625,20 @@ void searchInputFiles()
{
StringUnorderedSet killSet;
- QStrList &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
+ const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
bool alwaysRecursive = Config_getBool(RECURSIVE);
StringUnorderedSet excludeNameSet;
// gather names of all files in the include path
g_s.begin("Searching for include files...\n");
killSet.clear();
- QStrList &includePathList = Config_getList(INCLUDE_PATH);
- char *s=includePathList.first();
- while (s)
+ const StringVector &includePathList = Config_getList(INCLUDE_PATH);
+ for (const auto &s : includePathList)
{
- QStrList &pl = Config_getList(INCLUDE_FILE_PATTERNS);
- if (pl.count()==0)
- {
- pl = Config_getList(FILE_PATTERNS);
- }
- readFileOrDirectory(s, // s
+ size_t plSize = Config_getList(INCLUDE_FILE_PATTERNS).size();
+ const StringVector &pl = plSize==0 ? Config_getList(FILE_PATTERNS) :
+ Config_getList(INCLUDE_FILE_PATTERNS);
+ readFileOrDirectory(s.c_str(), // s
Doxygen::includeNameLinkedMap, // fnDict
0, // exclSet
&pl, // patList
@@ -10559,17 +10648,15 @@ void searchInputFiles()
alwaysRecursive, // recursive
TRUE, // errorIfNotExist
&killSet); // killSet
- s=includePathList.next();
}
g_s.end();
g_s.begin("Searching for example files...\n");
killSet.clear();
- QStrList &examplePathList = Config_getList(EXAMPLE_PATH);
- s=examplePathList.first();
- while (s)
+ const StringVector &examplePathList = Config_getList(EXAMPLE_PATH);
+ for (const auto &s : examplePathList)
{
- readFileOrDirectory(s, // s
+ readFileOrDirectory(s.c_str(), // s
Doxygen::exampleNameLinkedMap, // fnDict
0, // exclSet
&Config_getList(EXAMPLE_PATTERNS), // patList
@@ -10579,17 +10666,15 @@ void searchInputFiles()
(alwaysRecursive || Config_getBool(EXAMPLE_RECURSIVE)), // recursive
TRUE, // errorIfNotExist
&killSet); // killSet
- s=examplePathList.next();
}
g_s.end();
g_s.begin("Searching for images...\n");
killSet.clear();
- QStrList &imagePathList=Config_getList(IMAGE_PATH);
- s=imagePathList.first();
- while (s)
+ const StringVector &imagePathList=Config_getList(IMAGE_PATH);
+ for (const auto &s : imagePathList)
{
- readFileOrDirectory(s, // s
+ readFileOrDirectory(s.c_str(), // s
Doxygen::imageNameLinkedMap, // fnDict
0, // exclSet
0, // patList
@@ -10599,17 +10684,15 @@ void searchInputFiles()
alwaysRecursive, // recursive
TRUE, // errorIfNotExist
&killSet); // killSet
- s=imagePathList.next();
}
g_s.end();
g_s.begin("Searching for dot files...\n");
killSet.clear();
- QStrList &dotFileList=Config_getList(DOTFILE_DIRS);
- s=dotFileList.first();
- while (s)
+ const StringVector &dotFileList=Config_getList(DOTFILE_DIRS);
+ for (const auto &s : dotFileList)
{
- readFileOrDirectory(s, // s
+ readFileOrDirectory(s.c_str(), // s
Doxygen::dotFileNameLinkedMap, // fnDict
0, // exclSet
0, // patList
@@ -10619,17 +10702,15 @@ void searchInputFiles()
alwaysRecursive, // recursive
TRUE, // errorIfNotExist
&killSet); // killSet
- s=dotFileList.next();
}
g_s.end();
g_s.begin("Searching for msc files...\n");
killSet.clear();
- QStrList &mscFileList=Config_getList(MSCFILE_DIRS);
- s=mscFileList.first();
- while (s)
+ const StringVector &mscFileList=Config_getList(MSCFILE_DIRS);
+ for (const auto &s : mscFileList)
{
- readFileOrDirectory(s, // s
+ readFileOrDirectory(s.c_str(), // s
Doxygen::mscFileNameLinkedMap, // fnDict
0, // exclSet
0, // patList
@@ -10639,17 +10720,15 @@ void searchInputFiles()
alwaysRecursive, // recursive
TRUE, // errorIfNotExist
&killSet); // killSet
- s=mscFileList.next();
}
g_s.end();
g_s.begin("Searching for dia files...\n");
killSet.clear();
- QStrList &diaFileList=Config_getList(DIAFILE_DIRS);
- s=diaFileList.first();
- while (s)
+ const StringVector &diaFileList=Config_getList(DIAFILE_DIRS);
+ for (const auto &s : diaFileList)
{
- readFileOrDirectory(s, // s
+ readFileOrDirectory(s.c_str(), // s
Doxygen::diaFileNameLinkedMap, // fnDict
0, // exclSet
0, // patList
@@ -10659,16 +10738,14 @@ void searchInputFiles()
alwaysRecursive, // recursive
TRUE, // errorIfNotExist
&killSet); // killSet
- s=diaFileList.next();
}
g_s.end();
g_s.begin("Searching for files to exclude\n");
- QStrList &excludeList = Config_getList(EXCLUDE);
- s=excludeList.first();
- while (s)
+ const StringVector &excludeList = Config_getList(EXCLUDE);
+ for (const auto &s : excludeList)
{
- readFileOrDirectory(s, // s
+ readFileOrDirectory(s.c_str(), // s
0, // fnDict
0, // exclSet
&Config_getList(FILE_PATTERNS), // patList
@@ -10677,7 +10754,6 @@ void searchInputFiles()
&excludeNameSet, // resultSet
alwaysRecursive, // recursive
FALSE); // errorIfNotExist
- s=excludeList.next(); // killSet
}
g_s.end();
@@ -10688,11 +10764,10 @@ void searchInputFiles()
g_s.begin("Searching INPUT for files to process...\n");
killSet.clear();
Doxygen::inputPaths.clear();
- QStrList &inputList=Config_getList(INPUT);
- s=inputList.first();
- while (s)
+ const StringVector &inputList=Config_getList(INPUT);
+ for (const auto &s : inputList)
{
- QCString path=s;
+ QCString path=s.c_str();
uint l = path.length();
if (l>0)
{
@@ -10712,7 +10787,6 @@ void searchInputFiles()
&killSet, // killSet
&Doxygen::inputPaths); // paths
}
- s=inputList.next();
}
std::sort(Doxygen::inputNameLinkedMap->begin(),
Doxygen::inputNameLinkedMap->end(),
@@ -10730,6 +10804,10 @@ void parseInput()
{
atexit(exitDoxygen);
+#if USE_LIBCLANG
+ Doxygen::clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
+#endif
+
// we would like to show the versionString earlier, but we first have to handle the configuration file
// to know the value of the QUIET setting.
QCString versionString = getFullVersion();
@@ -10738,10 +10816,10 @@ void parseInput()
/**************************************************************************
* Make sure the output directory exists
**************************************************************************/
- QCString &outputDirectory = Config_getString(OUTPUT_DIRECTORY);
+ QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
if (outputDirectory.isEmpty())
{
- outputDirectory=QDir::currentDirPath().utf8();
+ outputDirectory = Config_updateString(OUTPUT_DIRECTORY,QDir::currentDirPath().utf8());
}
else
{
@@ -10763,7 +10841,7 @@ void parseInput()
}
dir.cd(outputDirectory);
}
- outputDirectory=dir.absPath().utf8();
+ outputDirectory = Config_updateString(OUTPUT_DIRECTORY,dir.absPath().utf8());
}
/**************************************************************************
@@ -10795,39 +10873,62 @@ void parseInput()
**************************************************************************/
QCString htmlOutput;
- bool &generateHtml = Config_getBool(GENERATE_HTML);
+ bool generateHtml = Config_getBool(GENERATE_HTML);
if (generateHtml || g_useOutputTemplate /* TODO: temp hack */)
+ {
htmlOutput = createOutputDirectory(outputDirectory,Config_getString(HTML_OUTPUT),"/html");
+ Config_updateString(HTML_OUTPUT,htmlOutput);
+ }
QCString docbookOutput;
- bool &generateDocbook = Config_getBool(GENERATE_DOCBOOK);
+ bool generateDocbook = Config_getBool(GENERATE_DOCBOOK);
if (generateDocbook)
+ {
docbookOutput = createOutputDirectory(outputDirectory,Config_getString(DOCBOOK_OUTPUT),"/docbook");
+ Config_updateString(DOCBOOK_OUTPUT,docbookOutput);
+ }
QCString xmlOutput;
- bool &generateXml = Config_getBool(GENERATE_XML);
+ bool generateXml = Config_getBool(GENERATE_XML);
if (generateXml)
+ {
xmlOutput = createOutputDirectory(outputDirectory,Config_getString(XML_OUTPUT),"/xml");
+ Config_updateString(XML_OUTPUT,xmlOutput);
+ }
QCString latexOutput;
- bool &generateLatex = Config_getBool(GENERATE_LATEX);
+ bool generateLatex = Config_getBool(GENERATE_LATEX);
if (generateLatex)
- latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT),"/latex");
+ {
+ latexOutput = createOutputDirectory(outputDirectory,Config_getString(LATEX_OUTPUT), "/latex");
+ Config_updateString(LATEX_OUTPUT,latexOutput);
+ }
QCString rtfOutput;
- bool &generateRtf = Config_getBool(GENERATE_RTF);
+ bool generateRtf = Config_getBool(GENERATE_RTF);
if (generateRtf)
+ {
rtfOutput = createOutputDirectory(outputDirectory,Config_getString(RTF_OUTPUT),"/rtf");
+ Config_updateString(RTF_OUTPUT,rtfOutput);
+ }
QCString manOutput;
- bool &generateMan = Config_getBool(GENERATE_MAN);
+ bool generateMan = Config_getBool(GENERATE_MAN);
if (generateMan)
+ {
manOutput = createOutputDirectory(outputDirectory,Config_getString(MAN_OUTPUT),"/man");
+ Config_updateString(MAN_OUTPUT,manOutput);
+ }
- //QCString sqlOutput;
- //bool &generateSql = Config_getBool(GENERATE_SQLITE3);
- //if (generateSql)
- // sqlOutput = createOutputDirectory(outputDirectory,"SQLITE3_OUTPUT","/sqlite3");
+#if USE_SQLITE3
+ QCString sqlOutput;
+ bool generateSql = Config_getBool(GENERATE_SQLITE3);
+ if (generateSql)
+ {
+ sqlOutput = createOutputDirectory(outputDirectory,Config_getString(SQLITE3_OUTPUT),"/sqlite3");
+ Config_updateString(SQLITE3_OUTPUT,sqlOutput);
+ }
+#endif
if (Config_getBool(HAVE_DOT))
{
@@ -10856,11 +10957,11 @@ void parseInput()
**************************************************************************/
LayoutDocManager::instance().init();
- QCString &layoutFileName = Config_getString(LAYOUT_FILE);
+ QCString layoutFileName = Config_getString(LAYOUT_FILE);
bool defaultLayoutUsed = FALSE;
if (layoutFileName.isEmpty())
{
- layoutFileName = "DoxygenLayout.xml";
+ layoutFileName = Config_updateString(LAYOUT_FILE,"DoxygenLayout.xml");
defaultLayoutUsed = TRUE;
}
@@ -10880,13 +10981,14 @@ void parseInput()
**************************************************************************/
// prevent search in the output directories
- QStrList &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
- if (generateHtml) exclPatterns.append(htmlOutput);
- if (generateDocbook) exclPatterns.append(docbookOutput);
- if (generateXml) exclPatterns.append(xmlOutput);
- if (generateLatex) exclPatterns.append(latexOutput);
- if (generateRtf) exclPatterns.append(rtfOutput);
- if (generateMan) exclPatterns.append(manOutput);
+ StringVector exclPatterns = Config_getList(EXCLUDE_PATTERNS);
+ if (generateHtml) exclPatterns.push_back(htmlOutput.data());
+ if (generateDocbook) exclPatterns.push_back(docbookOutput.data());
+ if (generateXml) exclPatterns.push_back(xmlOutput.data());
+ if (generateLatex) exclPatterns.push_back(latexOutput.data());
+ if (generateRtf) exclPatterns.push_back(rtfOutput.data());
+ if (generateMan) exclPatterns.push_back(manOutput.data());
+ Config_updateList(EXCLUDE_PATTERNS,exclPatterns);
searchInputFiles();
@@ -10919,12 +11021,10 @@ void parseInput()
std::shared_ptr<Entry> root = std::make_shared<Entry>();
msg("Reading and parsing tag files\n");
- QStrList &tagFileList = Config_getList(TAGFILES);
- char *s=tagFileList.first();
- while (s)
+ const StringVector &tagFileList = Config_getList(TAGFILES);
+ for (const auto &s : tagFileList)
{
- readTagFile(root,s);
- s=tagFileList.next();
+ readTagFile(root,s.c_str());
}
/**************************************************************************
@@ -11445,12 +11545,14 @@ void generateOutput()
Doxygen::generatingXmlOutput=FALSE;
g_s.end();
}
- if (USE_SQLITE3)
+#if USE_SQLITE3
+ if (Config_getBool(GENERATE_SQLITE3))
{
g_s.begin("Generating SQLITE3 output...\n");
generateSqlite3();
g_s.end();
}
+#endif
if (Config_getBool(GENERATE_AUTOGEN_DEF))
{
@@ -11588,7 +11690,7 @@ void generateOutput()
if (Debug::isFlagSet(Debug::Time))
{
msg("Total elapsed time: %.3f seconds\n(of which %.3f seconds waiting for external tools to finish)\n",
- ((double)Debug::elapsedTime())/1000.0,
+ ((double)Debug::elapsedTime()),
Portable::getSysElapsedTime()
);
g_s.print();
diff --git a/src/doxygen.h b/src/doxygen.h
index 99b5d6f..e5757c3 100644
--- a/src/doxygen.h
+++ b/src/doxygen.h
@@ -30,7 +30,9 @@
#include "memberlist.h"
#include "define.h"
+#ifndef MULTITHREADED_INPUT
#define MULTITHREADED_INPUT 0
+#endif
#if MULTITHREADED_INPUT
#define THREAD_LOCAL thread_local
@@ -148,9 +150,9 @@ class Doxygen
static int subpageNestingLevel;
static QCString spaces;
static bool generatingXmlOutput;
- static bool markdownSupport;
static GenericsSDict *genericsDict;
- static DefineList macroDefinitions;
+ static DefinesPerFileList macroDefinitions;
+ static bool clangAssistedParsing;
};
void initDoxygen();
@@ -165,8 +167,8 @@ void cleanUpDoxygen();
int readFileOrDirectory(const char *s,
FileNameLinkedMap *fnDict,
StringUnorderedSet *exclSet,
- QStrList *patList,
- QStrList *exclPatList,
+ const StringVector *patList,
+ const StringVector *exclPatList,
StringVector *resultList,
StringUnorderedSet *resultSet,
bool recursive,
diff --git a/src/entry.cpp b/src/entry.cpp
index e5f6d90..6e343b0 100644
--- a/src/entry.cpp
+++ b/src/entry.cpp
@@ -24,18 +24,15 @@
#include "doxygen.h"
#include "arguments.h"
#include "config.h"
-//------------------------------------------------------------------
-
-#define HEADER ('D'<<24)+('O'<<16)+('X'<<8)+'!'
//------------------------------------------------------------------
-int Entry::num=0;
+static AtomicInt g_num;
Entry::Entry()
{
//printf("Entry::Entry(%p)\n",this);
- num++;
+ g_num++;
m_parent=0;
section = EMPTY_SEC;
//printf("Entry::Entry() tArgList=0\n");
@@ -50,7 +47,7 @@ Entry::Entry()
Entry::Entry(const Entry &e)
{
//printf("Entry::Entry(%p):copy\n",this);
- num++;
+ g_num++;
section = e.section;
type = e.type;
name = e.name;
@@ -123,11 +120,11 @@ Entry::Entry(const Entry &e)
Entry::~Entry()
{
- //printf("Entry::~Entry(%p) num=%d\n",this,num);
+ //printf("Entry::~Entry(%p) num=%d\n",this,g_num);
//printf("Deleting entry %d name %s type %x children %d\n",
// num,name.data(),section,sublist->count());
- num--;
+ g_num--;
}
void Entry::moveToSubEntryAndRefresh(Entry *&current)
@@ -183,10 +180,10 @@ void Entry::removeSubEntry(const Entry *e)
void Entry::reset()
{
- static bool entryCallGraph = Config_getBool(CALL_GRAPH);
- static bool entryCallerGraph = Config_getBool(CALLER_GRAPH);
- static bool entryReferencedByRelation = Config_getBool(REFERENCED_BY_RELATION);
- static bool entryReferencesRelation = Config_getBool(REFERENCES_RELATION);
+ bool entryCallGraph = Config_getBool(CALL_GRAPH);
+ bool entryCallerGraph = Config_getBool(CALLER_GRAPH);
+ bool entryReferencedByRelation = Config_getBool(REFERENCED_BY_RELATION);
+ bool entryReferencesRelation = Config_getBool(REFERENCES_RELATION);
//printf("Entry::reset()\n");
name.resize(0);
type.resize(0);
diff --git a/src/entry.h b/src/entry.h
index c3d1558..d6c0936 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -297,9 +297,6 @@ class Entry
LocalToc localToc;
QCString metaData; //!< Slice metadata
-
- static int num; //!< counts the total number of entries
-
/// return the command name used to define GROUPDOC_SEC
const char *groupDocCmd() const
{
diff --git a/src/filedef.cpp b/src/filedef.cpp
index 7e8afdc..658023b 100644
--- a/src/filedef.cpp
+++ b/src/filedef.cpp
@@ -55,7 +55,8 @@ class FileDefImpl : public DefinitionImpl, public FileDef
virtual ~FileDefImpl();
virtual DefType definitionType() const { return TypeFile; }
- virtual QCString name() const;
+ virtual const QCString &name() const;
+
virtual QCString displayName(bool=TRUE) const { return name(); }
virtual QCString fileName() const { return m_fileName; }
virtual QCString getOutputFileBase() const;
@@ -81,7 +82,7 @@ class FileDefImpl : public DefinitionImpl, public FileDef
virtual SDict<Definition> *getUsedClasses() const { return m_usingDeclList; }
virtual QList<IncludeInfo> *includeFileList() const { return m_includeList; }
virtual QList<IncludeInfo> *includedByFileList() const { return m_includedByList; }
- virtual void getAllIncludeFilesRecursively(QStrList &incFiles) const;
+ virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const;
virtual MemberList *getMemberList(MemberListType lt) const;
virtual const QList<MemberList> &getMemberLists() const { return m_memberLists; }
virtual MemberGroupSDict *getMemberGroupSDict() const { return m_memberGroupSDict; }
@@ -100,10 +101,8 @@ class FileDefImpl : public DefinitionImpl, public FileDef
virtual void writeQuickMemberLinks(OutputList &ol,const MemberDef *currentMd) const;
virtual void writeSummaryLinks(OutputList &ol) const;
virtual void writeTagFile(FTextStream &t);
- virtual void startParsing();
- virtual void writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu);
- virtual void parseSource(bool sameTu,QStrList &filesInSameTu);
- virtual void finishParsing();
+ virtual void writeSource(OutputList &ol,ClangTUParser *clangParser);
+ virtual void parseSource(ClangTUParser *clangParser);
virtual void setDiskName(const QCString &name);
virtual void insertMember(MemberDef *md);
virtual void insertClass(ClassDef *cd);
@@ -116,7 +115,7 @@ class FileDefImpl : public DefinitionImpl, public FileDef
virtual void combineUsingRelations();
virtual bool generateSourceFile() const;
virtual void sortMemberLists();
- virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect);
+ virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported);
virtual void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported);
virtual void addMembersToMemberGroup();
virtual void distributeMemberGroupDocumentation();
@@ -356,25 +355,22 @@ void FileDefImpl::writeTagFile(FTextStream &tagFile)
IncludeInfo *ii;
for (;(ii=ili.current());++ili)
{
- if (!ii->indirect)
+ FileDef *fd=ii->fileDef;
+ if (fd && fd->isLinkable() && !fd->isReference())
{
- FileDef *fd=ii->fileDef;
- if (fd && fd->isLinkable() && !fd->isReference())
- {
- bool isIDLorJava = FALSE;
- SrcLangExt lang = fd->getLanguage();
- isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
- const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no";
- const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no";
- tagFile << " <includes id=\""
- << convertToXML(fd->getOutputFileBase()) << "\" "
- << "name=\"" << convertToXML(fd->name()) << "\" "
- << "local=\"" << locStr << "\" "
- << "imported=\"" << impStr << "\">"
- << convertToXML(ii->includeName)
- << "</includes>"
- << endl;
- }
+ bool isIDLorJava = FALSE;
+ SrcLangExt lang = fd->getLanguage();
+ isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ const char *locStr = (ii->local || isIDLorJava) ? "yes" : "no";
+ const char *impStr = (ii->imported || isIDLorJava) ? "yes" : "no";
+ tagFile << " <includes id=\""
+ << convertToXML(fd->getOutputFileBase()) << "\" "
+ << "name=\"" << convertToXML(fd->name()) << "\" "
+ << "local=\"" << locStr << "\" "
+ << "imported=\"" << impStr << "\">"
+ << convertToXML(ii->includeName)
+ << "</includes>"
+ << endl;
}
}
}
@@ -476,7 +472,8 @@ void FileDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title)
ol.startTextBlock();
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
{
- ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
!documentation().isEmpty())
@@ -493,7 +490,8 @@ void FileDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title)
}
if (!documentation().isEmpty())
{
- ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
//printf("Writing source ref for file %s\n",name().data());
if (Config_getBool(SOURCE_BROWSER))
@@ -541,7 +539,8 @@ void FileDefImpl::writeBriefDescription(OutputList &ol)
if (hasBriefDescription())
{
DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
- briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ briefDescription(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (rootNode && !rootNode->isEmpty())
{
@@ -596,61 +595,58 @@ void FileDefImpl::writeIncludeFiles(OutputList &ol)
IncludeInfo *ii;
for (;(ii=ili.current());++ili)
{
- if (!ii->indirect)
+ FileDef *fd=ii->fileDef;
+ bool isIDLorJava = FALSE;
+ if (fd)
{
- FileDef *fd=ii->fileDef;
- bool isIDLorJava = FALSE;
- if (fd)
- {
- SrcLangExt lang = fd->getLanguage();
- isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
- }
- ol.startTypewriter();
- if (isIDLorJava) // IDL/Java include
- {
- ol.docify("import ");
- }
- else if (ii->imported) // Objective-C include
- {
- ol.docify("#import ");
- }
- else // C/C++ include
- {
- ol.docify("#include ");
- }
- if (ii->local || isIDLorJava)
- ol.docify("\"");
- else
- ol.docify("<");
- ol.disable(OutputGenerator::Html);
- ol.docify(ii->includeName);
- ol.enableAll();
- ol.disableAllBut(OutputGenerator::Html);
-
- // Here we use the include file name as it appears in the file.
- // we could also we the name as it is used within doxygen,
- // then we should have used fd->docName() instead of ii->includeName
- if (fd && fd->isLinkable())
- {
- ol.writeObjectLink(fd->getReference(),
- fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(),
- 0,ii->includeName);
- }
- else
- {
- ol.docify(ii->includeName);
- }
+ SrcLangExt lang = fd->getLanguage();
+ isIDLorJava = lang==SrcLangExt_IDL || lang==SrcLangExt_Java;
+ }
+ ol.startTypewriter();
+ if (isIDLorJava) // IDL/Java include
+ {
+ ol.docify("import ");
+ }
+ else if (ii->imported) // Objective-C include
+ {
+ ol.docify("#import ");
+ }
+ else // C/C++ include
+ {
+ ol.docify("#include ");
+ }
+ if (ii->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify("<");
+ ol.disable(OutputGenerator::Html);
+ ol.docify(ii->includeName);
+ ol.enableAll();
+ ol.disableAllBut(OutputGenerator::Html);
- ol.enableAll();
- if (ii->local || isIDLorJava)
- ol.docify("\"");
- else
- ol.docify(">");
- if (isIDLorJava)
- ol.docify(";");
- ol.endTypewriter();
- ol.lineBreak();
+ // Here we use the include file name as it appears in the file.
+ // we could also we the name as it is used within doxygen,
+ // then we should have used fd->docName() instead of ii->includeName
+ if (fd && fd->isLinkable())
+ {
+ ol.writeObjectLink(fd->getReference(),
+ fd->generateSourceFile() ? fd->includeName() : fd->getOutputFileBase(),
+ 0,ii->includeName);
+ }
+ else
+ {
+ ol.docify(ii->includeName);
}
+
+ ol.enableAll();
+ if (ii->local || isIDLorJava)
+ ol.docify("\"");
+ else
+ ol.docify(">");
+ if (isIDLorJava)
+ ol.docify(";");
+ ol.endTypewriter();
+ ol.lineBreak();
}
ol.endTextBlock();
}
@@ -1153,7 +1149,7 @@ void FileDefImpl::writeQuickMemberLinks(OutputList &ol,const MemberDef *currentM
}
/*! Write a source listing of this file to the output */
-void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu)
+void FileDefImpl::writeSource(OutputList &ol,ClangTUParser *clangParser)
{
static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
@@ -1211,23 +1207,13 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu
ol.popGeneratorState();
}
- (void)sameTu;
- (void)filesInSameTu;
#if USE_LIBCLANG
- static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
- if (clangAssistedParsing &&
+ if (Doxygen::clangAssistedParsing && clangParser &&
(getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC))
{
ol.startCodeFragment();
- if (!sameTu)
- {
- ClangParser::instance()->start(absFilePath(),filesInSameTu);
- }
- else
- {
- ClangParser::instance()->switchToFile(absFilePath());
- }
- ClangParser::instance()->writeSources(ol,this);
+ clangParser->switchToFile(this);
+ clangParser->writeSources(ol,this);
ol.endCodeFragment();
}
else
@@ -1271,26 +1257,16 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu
ol.enableAll();
}
-void FileDefImpl::parseSource(bool sameTu,QStrList &filesInSameTu)
+void FileDefImpl::parseSource(ClangTUParser *clangParser)
{
static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES);
DevNullCodeDocInterface devNullIntf;
- (void)sameTu;
- (void)filesInSameTu;
#if USE_LIBCLANG
- static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING);
- if (clangAssistedParsing &&
+ if (Doxygen::clangAssistedParsing && clangParser &&
(getLanguage()==SrcLangExt_Cpp || getLanguage()==SrcLangExt_ObjC))
{
- if (!sameTu)
- {
- ClangParser::instance()->start(absFilePath(),filesInSameTu);
- }
- else
- {
- ClangParser::instance()->switchToFile(absFilePath());
- }
- ClangParser::instance()->writeSources(devNullIntf,this);
+ clangParser->switchToFile(this);
+ clangParser->writeSources(devNullIntf,this);
}
else
#endif
@@ -1306,15 +1282,6 @@ void FileDefImpl::parseSource(bool sameTu,QStrList &filesInSameTu)
}
}
-void FileDefImpl::startParsing()
-{
-}
-
-void FileDefImpl::finishParsing()
-{
- ClangParser::instance()->finish();
-}
-
void FileDefImpl::addMembersToMemberGroup()
{
QListIterator<MemberList> mli(m_memberLists);
@@ -1464,7 +1431,7 @@ void FileDefImpl::insertNamespace(NamespaceDef *nd)
}
}
-QCString FileDefImpl::name() const
+const QCString &FileDefImpl::name() const
{
if (Config_getBool(FULL_PATH_NAMES))
return m_fileName;
@@ -1540,8 +1507,7 @@ void FileDefImpl::addUsingDeclaration(Definition *d)
}
}
-void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool local,
- bool imported,bool indirect)
+void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported)
{
//printf("FileDefImpl::addIncludeDependency(%p,%s,%d)\n",fd,incName,local);
QCString iName = fd ? fd->absFilePath().data() : incName;
@@ -1558,7 +1524,6 @@ void FileDefImpl::addIncludeDependency(FileDef *fd,const char *incName,bool loca
ii->includeName = incName;
ii->local = local;
ii->imported = imported;
- ii->indirect = indirect;
m_includeList->append(ii);
m_includeDict->insert(iName,ii);
}
@@ -1655,7 +1620,6 @@ void FileDefImpl::addIncludedByDependency(FileDef *fd,const char *incName,
ii->includeName = incName;
ii->local = local;
ii->imported = imported;
- ii->indirect = FALSE;
m_includedByList->append(ii);
m_includedByDict->insert(iName,ii);
}
@@ -2166,7 +2130,7 @@ bool FileDefImpl::isLinkableInProject() const
}
static void getAllIncludeFilesRecursively(
- QDict<void> *filesVisited,const FileDef *fd,QStrList &incFiles)
+ StringUnorderedSet &filesVisited,const FileDef *fd,StringVector &incFiles)
{
if (fd->includeFileList())
{
@@ -2175,21 +2139,21 @@ static void getAllIncludeFilesRecursively(
for (iii.toFirst();(ii=iii.current());++iii)
{
if (ii->fileDef && !ii->fileDef->isReference() &&
- !filesVisited->find(ii->fileDef->absFilePath()))
+ filesVisited.find(ii->fileDef->absFilePath().str())==filesVisited.end())
{
//printf("FileDefImpl::addIncludeDependency(%s)\n",ii->fileDef->absFilePath().data());
- incFiles.append(ii->fileDef->absFilePath());
- filesVisited->insert(ii->fileDef->absFilePath(),(void*)0x8);
+ incFiles.push_back(ii->fileDef->absFilePath().str());
+ filesVisited.insert(ii->fileDef->absFilePath().str());
getAllIncludeFilesRecursively(filesVisited,ii->fileDef,incFiles);
}
}
}
}
-void FileDefImpl::getAllIncludeFilesRecursively(QStrList &incFiles) const
+void FileDefImpl::getAllIncludeFilesRecursively(StringVector &incFiles) const
{
- QDict<void> includes(257);
- ::getAllIncludeFilesRecursively(&includes,this,incFiles);
+ StringUnorderedSet includes;
+ ::getAllIncludeFilesRecursively(includes,this,incFiles);
}
QCString FileDefImpl::title() const
diff --git a/src/filedef.h b/src/filedef.h
index 2ca33db..e4bb549 100644
--- a/src/filedef.h
+++ b/src/filedef.h
@@ -1,12 +1,12 @@
/******************************************************************************
*
- *
+ *
*
* 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
+ * 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.
*
@@ -25,6 +25,7 @@
#include "definition.h"
#include "sortdict.h"
#include "memberlist.h"
+#include "containers.h"
class MemberList;
class FileDef;
@@ -40,24 +41,24 @@ class MemberGroupSDict;
class PackageDef;
class DirDef;
class FTextStream;
+class ClangTUParser;
/** Class representing the data associated with a \#include statement. */
struct IncludeInfo
{
- IncludeInfo() : fileDef(0), local(FALSE), imported(FALSE), indirect(FALSE) {}
+ IncludeInfo() : fileDef(0), local(FALSE), imported(FALSE) {}
~IncludeInfo() {}
FileDef *fileDef;
QCString includeName;
bool local;
bool imported;
- bool indirect;
};
-/** A model of a file symbol.
- *
+/** A model of a file symbol.
+ *
* An object of this class contains all file information that is gathered.
* This includes the members and compounds defined in the file.
- *
+ *
* The member writeDocumentation() can be used to generate the page of
* documentation to HTML and LaTeX.
*/
@@ -71,7 +72,7 @@ class FileDef : virtual public Definition
virtual DefType definitionType() const = 0;
/*! Returns the unique file name (this may include part of the path). */
- virtual QCString name() const = 0;
+ virtual const QCString &name() const = 0;
virtual QCString displayName(bool=TRUE) const = 0;
virtual QCString fileName() const = 0;
@@ -119,7 +120,7 @@ class FileDef : virtual public Definition
virtual SDict<Definition> *getUsedClasses() const = 0;
virtual QList<IncludeInfo> *includeFileList() const = 0;
virtual QList<IncludeInfo> *includedByFileList() const = 0;
- virtual void getAllIncludeFilesRecursively(QStrList &incFiles) const = 0;
+ virtual void getAllIncludeFilesRecursively(StringVector &incFiles) const = 0;
virtual MemberList *getMemberList(MemberListType lt) const = 0;
virtual const QList<MemberList> &getMemberLists() const = 0;
@@ -149,10 +150,8 @@ class FileDef : virtual public Definition
virtual void writeSummaryLinks(OutputList &ol) const = 0;
virtual void writeTagFile(FTextStream &t) = 0;
- virtual void startParsing() = 0;
- virtual void writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu) = 0;
- virtual void parseSource(bool sameTu,QStrList &filesInSameTu) = 0;
- virtual void finishParsing() = 0;
+ virtual void writeSource(OutputList &ol,ClangTUParser *clangParser) = 0;
+ virtual void parseSource(ClangTUParser *clangParser) = 0;
virtual void setDiskName(const QCString &name) = 0;
virtual void insertMember(MemberDef *md) = 0;
@@ -170,7 +169,7 @@ class FileDef : virtual public Definition
virtual bool generateSourceFile() const = 0;
virtual void sortMemberLists() = 0;
- virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported,bool indirect) = 0;
+ virtual void addIncludeDependency(FileDef *fd,const char *incName,bool local,bool imported) = 0;
virtual void addIncludedByDependency(FileDef *fd,const char *incName,bool local,bool imported) = 0;
virtual void addMembersToMemberGroup() = 0;
@@ -228,11 +227,11 @@ class DirEntry
{
public:
enum EntryKind { Dir, File };
- DirEntry(DirEntry *parent,FileDef *fd)
- : m_parent(parent), m_name(fd->name()), m_kind(File), m_fd(fd),
+ DirEntry(DirEntry *parent,FileDef *fd)
+ : m_parent(parent), m_name(fd->name()), m_kind(File), m_fd(fd),
m_isLast(FALSE) { }
- DirEntry(DirEntry *parent,QCString name)
- : m_parent(parent), m_name(name), m_kind(Dir),
+ DirEntry(DirEntry *parent,QCString name)
+ : m_parent(parent), m_name(name), m_kind(Dir),
m_fd(0), m_isLast(FALSE) { }
virtual ~DirEntry() { }
EntryKind kind() const { return m_kind; }
@@ -257,7 +256,7 @@ class DirEntry
class Directory : public DirEntry
{
public:
- Directory(Directory *parent,const QCString &name)
+ Directory(Directory *parent,const QCString &name)
: DirEntry(parent,name)
{ m_children.setAutoDelete(TRUE); }
virtual ~Directory() {}
diff --git a/src/fortranscanner.h b/src/fortranscanner.h
index 6ffcb1f..0e67bb2 100644
--- a/src/fortranscanner.h
+++ b/src/fortranscanner.h
@@ -1,12 +1,12 @@
/******************************************************************************
*
- *
+ *
*
* 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
+ * 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.
*
@@ -29,13 +29,10 @@ class FortranOutlineParser : public OutlineParserInterface
public:
FortranOutlineParser(FortranFormat format=FortranFormat_Unknown);
~FortranOutlineParser();
- void startTranslationUnit(const char *) {}
- void finishTranslationUnit() {}
void parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList &filesInSameTranslationUnit);
+ ClangTUParser *clangParser);
bool needsPreprocessing(const QCString &extension) const;
void parsePrototype(const char *text);
diff --git a/src/fortranscanner.l b/src/fortranscanner.l
index 852c4d9..cf48a3e 100644
--- a/src/fortranscanner.l
+++ b/src/fortranscanner.l
@@ -467,6 +467,7 @@ SCOPENAME ({ID}{BS}"::"{BS})*
<Use>{ID} {
DBG_CTX((stderr,"using dir %s\n",yytext));
yyextra->current->name=yytext;
+ yyextra->current->name=yyextra->current->name.lower();
yyextra->current->fileName = yyextra->fileName;
yyextra->current->section=Entry::USINGDIR_SEC;
yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
@@ -475,12 +476,14 @@ SCOPENAME ({ID}{BS}"::"{BS})*
}
<Use>{ID}/, {
yyextra->useModuleName=yytext;
+ yyextra->useModuleName=yyextra->useModuleName.lower();
}
<Use>,{BS}"ONLY" { BEGIN(UseOnly);
}
<UseOnly>{BS},{BS} {}
<UseOnly>{ID} {
yyextra->current->name= yyextra->useModuleName+"::"+yytext;
+ yyextra->current->name=yyextra->current->name.lower();
yyextra->current->fileName = yyextra->fileName;
yyextra->current->section=Entry::USINGDECL_SEC;
yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
@@ -2514,7 +2517,8 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief
int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
int position=0;
bool needsEntry = FALSE;
- QCString processedDoc = processMarkdownForCommentBlock(doc,yyextra->fileName,lineNr);
+ Markdown markdown(yyextra->fileName,lineNr);
+ QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(doc,lineNr) : doc;
while (yyextra->commentScanner.parseCommentBlock(
yyextra->thisParser,
yyextra->docBlockInBody ? yyextra->subrCurrent.back().get() : yyextra->current.get(),
@@ -2526,8 +2530,9 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief
yyextra->docBlockInBody,
yyextra->defaultProtection,
position,
- needsEntry
- ))
+ needsEntry,
+ Config_getBool(MARKDOWN_SUPPORT)
+ ))
{
DBG_CTX((stderr,"parseCommentBlock position=%d [%s] needsEntry=%d\n",position,doc.data()+position,needsEntry));
if (needsEntry) addCurrentEntry(yyscanner,false);
@@ -2801,8 +2806,7 @@ FortranOutlineParser::~FortranOutlineParser()
void FortranOutlineParser::parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool /*sameTranslationUnit*/,
- QStrList & /*filesInSameTranslationUnit*/)
+ ClangTUParser * /*clangParser*/)
{
struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
yyextra->thisParser = this;
diff --git a/src/ftextstream.h b/src/ftextstream.h
index bfc5bd5..5b6a9ca 100644
--- a/src/ftextstream.h
+++ b/src/ftextstream.h
@@ -60,7 +60,8 @@ inline FTextStream &FTextStream::operator<<( const char* s)
inline FTextStream &FTextStream::operator<<( const QCString &s)
{
- return operator<<(s.data());
+ if (m_dev) m_dev->writeBlock( s, s.length() );
+ return *this;
}
typedef FTextStream & (*FTSFUNC)(FTextStream &);// manipulator function
diff --git a/src/ftvhelp.cpp b/src/ftvhelp.cpp
index cb50af1..6fc14bf 100644
--- a/src/ftvhelp.cpp
+++ b/src/ftvhelp.cpp
@@ -348,7 +348,8 @@ static void generateBriefDoc(FTextStream &t,const Definition *def)
if (!brief.isEmpty())
{
DocNode *root = validatingParseDoc(def->briefFile(),def->briefLine(),
- def,0,brief,FALSE,FALSE,0,TRUE,TRUE);
+ def,0,brief,FALSE,FALSE,
+ 0,TRUE,TRUE,Config_getBool(MARKDOWN_SUPPORT));
QCString relPath = relativePathToRoot(def->getOutputFileBase());
HtmlCodeGenerator htmlGen(t,relPath);
HtmlDocVisitor *visitor = new HtmlDocVisitor(t,htmlGen,def);
@@ -669,7 +670,7 @@ static void generateJSNavTree(const QList<FTVNode> &nodeList)
t << "var NAVTREE =" << endl;
t << "[" << endl;
t << " [ ";
- QCString &projName = Config_getString(PROJECT_NAME);
+ QCString projName = Config_getString(PROJECT_NAME);
if (projName.isEmpty())
{
if (mainPageHasTitle()) // Use title of main page as root
diff --git a/src/groupdef.cpp b/src/groupdef.cpp
index 3b4d537..9b33356 100644
--- a/src/groupdef.cpp
+++ b/src/groupdef.cpp
@@ -834,7 +834,8 @@ void GroupDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title
// repeat brief description
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
{
- ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
// write separator between brief and details
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
@@ -854,13 +855,15 @@ void GroupDefImpl::writeDetailedDescription(OutputList &ol,const QCString &title
// write detailed documentation
if (!documentation().isEmpty())
{
- ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
// write inbody documentation
if (!inbodyDocumentation().isEmpty())
{
- ol.generateDoc(inbodyFile(),inbodyLine(),this,0,inbodyDocumentation()+"\n",TRUE,FALSE);
+ ol.generateDoc(inbodyFile(),inbodyLine(),this,0,inbodyDocumentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
}
}
@@ -870,7 +873,8 @@ void GroupDefImpl::writeBriefDescription(OutputList &ol)
if (hasBriefDescription())
{
DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
- briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ briefDescription(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (rootNode && !rootNode->isEmpty())
{
ol.startParagraph();
@@ -944,7 +948,8 @@ void GroupDefImpl::writeFiles(OutputList &ol,const QCString &title)
if (!fd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
{
ol.startMemberDescription(fd->getOutputFileBase());
- ol.generateDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberDescription();
}
ol.endMemberDeclaration(0,0);
@@ -999,7 +1004,8 @@ void GroupDefImpl::writeNestedGroups(OutputList &ol,const QCString &title)
if (!gd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
{
ol.startMemberDescription(gd->getOutputFileBase());
- ol.generateDoc(briefFile(),briefLine(),gd,0,gd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),gd,0,gd->briefDescription(),FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberDescription();
}
ol.endMemberDeclaration(0,0);
@@ -1030,7 +1036,8 @@ void GroupDefImpl::writeDirs(OutputList &ol,const QCString &title)
if (!dd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
{
ol.startMemberDescription(dd->getOutputFileBase());
- ol.generateDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),FALSE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberDescription();
}
ol.endMemberDeclaration(0,0);
@@ -1068,7 +1075,8 @@ void GroupDefImpl::writePageDocumentation(OutputList &ol)
ol.endSection(si->label(),SectionType::Subsection);
}
ol.startTextBlock();
- ol.generateDoc(pd->docFile(),pd->docLine(),pd,0,pd->documentation()+pd->inbodyDocumentation(),TRUE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc(pd->docFile(),pd->docLine(),pd,0,pd->documentation()+pd->inbodyDocumentation(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endTextBlock();
}
}
@@ -1199,6 +1207,11 @@ void GroupDefImpl::writeDocumentation(OutputList &ol)
ol.pushGeneratorState();
ol.disableAllBut(OutputGenerator::Man);
ol.endTitleHead(getOutputFileBase(),name());
+ if (!m_title.isEmpty())
+ {
+ ol.writeString(" - ");
+ ol.parseText(m_title);
+ }
ol.popGeneratorState();
ol.endHeaderSection();
ol.startContents();
diff --git a/src/growbuf.h b/src/growbuf.h
index cd6a67b..2f8075b 100644
--- a/src/growbuf.h
+++ b/src/growbuf.h
@@ -13,6 +13,7 @@ class GrowBuf
GrowBuf() : m_str(0), m_pos(0), m_len(0) {}
GrowBuf(uint initialSize) : m_pos(0), m_len(initialSize) { m_str=(char*)malloc(m_len); }
~GrowBuf() { free(m_str); }
+ void reserve(uint size) { if (m_len<size) { m_len = size; m_str = (char*)realloc(m_str,m_len); } }
void clear() { m_pos=0; }
void addChar(char c) { if (m_pos>=m_len) { m_len+=GROW_AMOUNT; m_str = (char*)realloc(m_str,m_len); }
m_str[m_pos++]=c;
diff --git a/src/htags.cpp b/src/htags.cpp
index 1a240b1..0c3a9af 100644
--- a/src/htags.cpp
+++ b/src/htags.cpp
@@ -3,8 +3,8 @@
* 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
+ * 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.
*
@@ -36,25 +36,25 @@ static QDict<QCString> g_symbolDict(10007);
*/
bool Htags::execute(const QCString &htmldir)
{
- static QStrList &inputSource = Config_getList(INPUT);
- static bool quiet = Config_getBool(QUIET);
- static bool warnings = Config_getBool(WARNINGS);
- static QCString htagsOptions = ""; //Config_getString(HTAGS_OPTIONS);
- static QCString projectName = Config_getString(PROJECT_NAME);
- static QCString projectNumber = Config_getString(PROJECT_NUMBER);
+ const StringVector &inputSource = Config_getList(INPUT);
+ bool quiet = Config_getBool(QUIET);
+ bool warnings = Config_getBool(WARNINGS);
+ QCString htagsOptions = ""; //Config_getString(HTAGS_OPTIONS);
+ QCString projectName = Config_getString(PROJECT_NAME);
+ QCString projectNumber = Config_getString(PROJECT_NUMBER);
QCString cwd = QDir::currentDirPath().utf8();
- if (inputSource.isEmpty())
+ if (inputSource.empty())
{
g_inputDir.setPath(cwd);
}
- else if (inputSource.count()==1)
+ else if (inputSource.size()==1)
{
- g_inputDir.setPath(inputSource.first());
+ g_inputDir.setPath(inputSource.back().c_str());
if (!g_inputDir.exists())
err("Cannot find directory %s. "
"Check the value of the INPUT tag in the configuration file.\n",
- inputSource.first()
+ inputSource.back().c_str()
);
}
else
@@ -69,16 +69,16 @@ bool Htags::execute(const QCString &htmldir)
QCString commandLine = " -g -s -a -n ";
if (!quiet) commandLine += "-v ";
if (warnings) commandLine += "-w ";
- if (!htagsOptions.isEmpty())
+ if (!htagsOptions.isEmpty())
{
commandLine += ' ';
commandLine += htagsOptions;
}
- if (!projectName.isEmpty())
+ if (!projectName.isEmpty())
{
commandLine += "-t \"";
commandLine += projectName;
- if (!projectNumber.isEmpty())
+ if (!projectNumber.isEmpty())
{
commandLine += '-';
commandLine += projectNumber;
@@ -150,7 +150,7 @@ bool Htags::loadFilemap(const QCString &htmlDir)
}
else
{
- err("file %s cannot be opened\n",fileMapName.data());
+ err("file %s cannot be opened\n",fileMapName.data());
}
}
return FALSE;
diff --git a/src/htmlgen.cpp b/src/htmlgen.cpp
index 7458b23..7b125af 100644
--- a/src/htmlgen.cpp
+++ b/src/htmlgen.cpp
@@ -67,7 +67,7 @@ static void writeClientSearchBox(FTextStream &t,const char *relPath)
{
t << " <div id=\"MSearchBox\" class=\"MSearchBoxInactive\">\n";
t << " <span class=\"left\">\n";
- t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.png\"\n";
+ t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag_sel.svg\"\n";
t << " onmouseover=\"return searchBox.OnSearchSelectShow()\"\n";
t << " onmouseout=\"return searchBox.OnSearchSelectHide()\"\n";
t << " alt=\"\"/>\n";
@@ -78,7 +78,7 @@ static void writeClientSearchBox(FTextStream &t,const char *relPath)
t << " onkeyup=\"searchBox.OnSearchFieldChange(event)\"/>\n";
t << " </span><span class=\"right\">\n";
t << " <a id=\"MSearchClose\" href=\"javascript:searchBox.CloseResultsWindow()\">"
- << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.png\" alt=\"\"/></a>\n";
+ << "<img id=\"MSearchCloseImg\" border=\"0\" src=\"" << relPath << "search/close.svg\" alt=\"\"/></a>\n";
t << " </span>\n";
t << " </div>\n";
}
@@ -100,7 +100,7 @@ static void writeServerSearchBox(FTextStream &t,const char *relPath,bool highlig
t << "search.php";
}
t << "\" method=\"get\">\n";
- t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.png\" alt=\"\"/>\n";
+ t << " <img id=\"MSearchSelect\" src=\"" << relPath << "search/mag.svg\" alt=\"\"/>\n";
if (!highlightSearch)
{
t << " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\""
@@ -415,7 +415,6 @@ static QCString substituteHtmlKeywords(const QCString &str,
{
// Build CSS/JavaScript tags depending on treeview, search engine settings
QCString cssFile;
- QStrList extraCssFile;
QCString generatedBy;
QCString treeViewCssJs;
QCString searchCssJs;
@@ -456,10 +455,10 @@ static QCString substituteHtmlKeywords(const QCString &str,
}
extraCssText = "";
- extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
- for (uint i=0; i<extraCssFile.count(); ++i)
+ const StringVector &extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
+ for (const auto &extraFile : extraCssFile)
{
- QCString fileName(extraCssFile.at(i));
+ QCString fileName = extraFile.c_str();
if (!fileName.isEmpty())
{
QFileInfo fi(fileName);
@@ -541,12 +540,10 @@ static QCString substituteHtmlKeywords(const QCString &str,
mathJaxJs = "<script type=\"text/x-mathjax-config\">\n"
" MathJax.Hub.Config({\n"
" extensions: [\"tex2jax.js\"";
- QStrList &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
- const char *s = mathJaxExtensions.first();
- while (s)
+ const StringVector &mathJaxExtensions = Config_getList(MATHJAX_EXTENSIONS);
+ for (const auto &s : mathJaxExtensions)
{
- mathJaxJs+= ", \""+QCString(s)+".js\"";
- s = mathJaxExtensions.next();
+ mathJaxJs+= ", \""+QCString(s.c_str())+".js\"";
}
if (mathJaxFormat.isEmpty())
{
@@ -1019,7 +1016,7 @@ void HtmlGenerator::writeTabData()
mgr.copyResource("nav_h.lum",dname);
mgr.copyResource("nav_f.lum",dname);
mgr.copyResource("bc_s.luma",dname);
- mgr.copyResource("doxygen.luma",dname);
+ mgr.copyResource("doxygen.svg",dname);
mgr.copyResource("closed.luma",dname);
mgr.copyResource("open.luma",dname);
mgr.copyResource("bdwn.luma",dname);
@@ -1049,15 +1046,15 @@ void HtmlGenerator::writeSearchData(const char *dir)
Doxygen::indexList->addImageFile("search/search_r.png");
if (serverBasedSearch)
{
- mgr.copyResource("mag.png",dir);
- Doxygen::indexList->addImageFile("search/mag.png");
+ mgr.copyResource("mag.svg",dir);
+ Doxygen::indexList->addImageFile("search/mag.svg");
}
else
{
- mgr.copyResource("close.png",dir);
- Doxygen::indexList->addImageFile("search/close.png");
- mgr.copyResource("mag_sel.png",dir);
- Doxygen::indexList->addImageFile("search/mag_sel.png");
+ mgr.copyResource("close.svg",dir);
+ Doxygen::indexList->addImageFile("search/close.svg");
+ mgr.copyResource("mag_sel.svg",dir);
+ Doxygen::indexList->addImageFile("search/mag_sel.svg");
}
QCString searchDirName = Config_getString(HTML_OUTPUT)+"/search";
@@ -1184,7 +1181,7 @@ QCString HtmlGenerator::writeLogoAsString(const char *path)
result += "&#160;\n<a href=\"http://www.doxygen.org/index.html\">\n"
"<img class=\"footer\" src=\"";
result += path;
- result += "doxygen.png\" alt=\"doxygen\"/></a> ";
+ result += "doxygen.svg\" width=\"104\" height=\"31\" alt=\"doxygen\"/></a> ";
result += getDoxygenVersion();
result += " ";
return result;
@@ -1261,10 +1258,10 @@ void HtmlGenerator::writeStyleInfo(int part)
}
Doxygen::indexList->addStyleSheetFile(cssfi.fileName().utf8());
}
- static QStrList extraCssFile = Config_getList(HTML_EXTRA_STYLESHEET);
- for (uint i=0; i<extraCssFile.count(); ++i)
+ const StringVector &extraCssFiles = Config_getList(HTML_EXTRA_STYLESHEET);
+ for (const auto &extraCss : extraCssFiles)
{
- QCString fileName(extraCssFile.at(i));
+ QCString fileName = extraCss.c_str();
if (!fileName.isEmpty())
{
QFileInfo fi(fileName);
@@ -2768,11 +2765,10 @@ void HtmlGenerator::writeExternalSearchPage()
t << "var tagMap = {" << endl;
bool first=TRUE;
// add search mappings
- QStrList &extraSearchMappings = Config_getList(EXTRA_SEARCH_MAPPINGS);
- char *ml=extraSearchMappings.first();
- while (ml)
+ const StringVector &extraSearchMappings = Config_getList(EXTRA_SEARCH_MAPPINGS);
+ for (const auto &ml : extraSearchMappings)
{
- QCString mapLine = ml;
+ QCString mapLine = ml.c_str();
int eqPos = mapLine.find('=');
if (eqPos!=-1) // tag command contains a destination
{
@@ -2785,7 +2781,6 @@ void HtmlGenerator::writeExternalSearchPage()
first=FALSE;
}
}
- ml=extraSearchMappings.next();
}
if (!first) t << endl;
t << "};" << endl << endl;
diff --git a/src/htmlhelp.cpp b/src/htmlhelp.cpp
index 066e6f7..8ef3d19 100644
--- a/src/htmlhelp.cpp
+++ b/src/htmlhelp.cpp
@@ -171,7 +171,7 @@ void HtmlHelpIndex::writeFields(FTextStream &t)
dict->sort();
IndexFieldSDict::Iterator ifli(*dict);
IndexField *f;
- QCString lastLevel1;
+ QCString prevLevel1;
bool level2Started=FALSE;
for (;(f=ifli.current());++ifli)
{
@@ -187,7 +187,6 @@ void HtmlHelpIndex::writeFields(FTextStream &t)
level1 = f->name.copy();
}
- //if (level1!=lastLevel1)
{ // finish old list at level 2
if (level2Started) t << " </UL>" << endl;
level2Started=FALSE;
@@ -206,10 +205,11 @@ void HtmlHelpIndex::writeFields(FTextStream &t)
nextLevel1 = fnext->name.left(fnext->name.find('?'));
--ifli;
}
- if (level1 != nextLevel1)
+ if (!(level1 == prevLevel1 || level1 == nextLevel1))
{
level2 = "";
}
+ prevLevel1 = level1.copy();
// </Antony>
if (level2.isEmpty())
@@ -257,7 +257,6 @@ void HtmlHelpIndex::writeFields(FTextStream &t)
t << "<param name=\"Name\" value=\"" << m_help->recode(level2) << "\">"
"</OBJECT>\n";
}
- lastLevel1 = level1.copy();
}
if (level2Started) t << " </UL>" << endl;
}
@@ -420,7 +419,7 @@ void HtmlHelp::initialize()
s_languageDict.insert("chinese-traditional", new QCString("0x404 Chinese (Taiwan)"));
// new LCIDs
- s_languageDict.insert("indonesian", new QCString("0x412 Indonesian"));
+ s_languageDict.insert("indonesian", new QCString("0x421 Indonesian"));
s_languageDict.insert("croatian", new QCString("0x41A Croatian"));
s_languageDict.insert("romanian", new QCString("0x418 Romanian"));
s_languageDict.insert("slovene", new QCString("0x424 Slovenian"));
diff --git a/src/index.cpp b/src/index.cpp
index db58129..12f35f2 100644
--- a/src/index.cpp
+++ b/src/index.cpp
@@ -1396,7 +1396,8 @@ static void writeSingleFileIndex(OutputList &ol,FileDef *fd)
FALSE, // isExample
0, // example name
TRUE, // single line
- TRUE // link from index
+ TRUE, // link from index
+ Config_getBool(MARKDOWN_SUPPORT)
);
//ol.docify(")");
}
@@ -1768,7 +1769,8 @@ static void writeNamespaceIndex(OutputList &ol)
FALSE, // isExample
0, // example name
TRUE, // single line
- TRUE // link from index
+ TRUE, // link from index
+ Config_getBool(MARKDOWN_SUPPORT)
);
//ol.docify(")");
}
@@ -1902,7 +1904,8 @@ static void writeAnnotatedClassList(OutputList &ol,ClassDef::CompoundType ct)
FALSE, // isExample
0, // example name
TRUE, // single line
- TRUE // link from index
+ TRUE, // link from index
+ Config_getBool(MARKDOWN_SUPPORT)
);
}
ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
@@ -3908,14 +3911,14 @@ void writeGraphInfo(OutputList &ol)
DotLegendGraph gd;
gd.writeGraph(Config_getString(HTML_OUTPUT));
- bool &stripCommentsStateRef = Config_getBool(STRIP_CODE_COMMENTS);
+ bool stripCommentsStateRef = Config_getBool(STRIP_CODE_COMMENTS);
bool oldStripCommentsState = stripCommentsStateRef;
- bool &createSubdirs = Config_getBool(CREATE_SUBDIRS);
+ bool createSubdirs = Config_getBool(CREATE_SUBDIRS);
bool oldCreateSubdirs = createSubdirs;
// temporarily disable the stripping of comments for our own code example!
- stripCommentsStateRef = FALSE;
+ stripCommentsStateRef = Config_updateBool(STRIP_CODE_COMMENTS,FALSE);
// temporarily disable create subdirs for linking to our example
- createSubdirs = FALSE;
+ createSubdirs = Config_updateBool(CREATE_SUBDIRS,FALSE);
startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
startTitle(ol,0);
@@ -3932,12 +3935,13 @@ void writeGraphInfo(OutputList &ol)
//printf("legendDocs=%s\n",legendDocs.data());
}
FileDef *fd = createFileDef("","graph_legend.dox");
- ol.generateDoc("graph_legend",1,fd,0,legendDocs,FALSE,FALSE);
+ ol.generateDoc("graph_legend",1,fd,0,legendDocs,FALSE,FALSE,
+ 0,FALSE,FALSE,FALSE);
delete fd;
// restore config settings
- stripCommentsStateRef = oldStripCommentsState;
- createSubdirs = oldCreateSubdirs;
+ Config_updateBool(STRIP_CODE_COMMENTS,oldStripCommentsState);
+ Config_updateBool(CREATE_SUBDIRS,oldCreateSubdirs);
endFile(ol);
ol.popGeneratorState();
@@ -3988,7 +3992,7 @@ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp*
numSubItems += gd->getNamespaces()->count();
numSubItems += gd->getClasses()->count();
numSubItems += gd->getFiles()->count();
- numSubItems += gd->getDirs().size();
+ numSubItems += static_cast<int>(gd->getDirs().size());
numSubItems += gd->getPages()->count();
}
@@ -4496,8 +4500,8 @@ static void writeIndex(OutputList &ol)
ol.startHeaderSection();
ol.startTitleHead(0);
ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
- Doxygen::mainPage,0,Doxygen::mainPage->title(),
- TRUE,FALSE,0,TRUE,FALSE);
+ Doxygen::mainPage,0,Doxygen::mainPage->title(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
headerWritten = TRUE;
}
}
@@ -4533,7 +4537,8 @@ static void writeIndex(OutputList &ol)
ol.startTextBlock();
ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
- Doxygen::mainPage->documentation(),TRUE,FALSE);
+ Doxygen::mainPage->documentation(),TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endTextBlock();
ol.endPageDoc();
@@ -4570,7 +4575,8 @@ static void writeIndex(OutputList &ol)
if (!Config_getString(PROJECT_NUMBER).isEmpty())
{
ol.startProjectNumber();
- ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString(PROJECT_NUMBER),FALSE,FALSE);
+ ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString(PROJECT_NUMBER),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endProjectNumber();
}
ol.endIndexSection(isTitlePageStart);
@@ -4783,7 +4789,8 @@ static void writeIndex(OutputList &ol)
ol.startContents();
ol.startTextBlock();
ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
- Doxygen::mainPage->documentation(),FALSE,FALSE
+ Doxygen::mainPage->documentation(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)
);
ol.endTextBlock();
endFile(ol);
diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp
index b899935..19f01b0 100644
--- a/src/latexdocvisitor.cpp
+++ b/src/latexdocvisitor.cpp
@@ -1,13 +1,13 @@
/******************************************************************************
*
- *
+ *
*
*
* 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
+ * 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.
*
@@ -16,7 +16,7 @@
*
*/
#include "htmlattrib.h"
-#include <qfileinfo.h>
+#include <qfileinfo.h>
#include "latexdocvisitor.h"
#include "latexgen.h"
#include "docparser.h"
@@ -37,7 +37,7 @@
#include "plantuml.h"
const int maxLevels=5;
-static const char *secLabels[maxLevels] =
+static const char *secLabels[maxLevels] =
{ "doxysection","doxysubsection","doxysubsubsection","doxyparagraph","doxysubparagraph" };
static const char *getSectionName(int level)
@@ -176,8 +176,8 @@ QCString LatexDocVisitor::escapeMakeIndexChars(const char *s)
LatexDocVisitor::LatexDocVisitor(FTextStream &t,CodeOutputInterface &ci,
- const char *langExt,bool insideTabbing)
- : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE),
+ const char *langExt,bool insideTabbing)
+ : DocVisitor(DocVisitor_Latex), m_t(t), m_ci(ci), m_insidePre(FALSE),
m_insideItem(FALSE), m_hide(FALSE), m_hideCaption(FALSE), m_insideTabbing(insideTabbing),
m_langExt(langExt)
{
@@ -322,7 +322,7 @@ void LatexDocVisitor::visit(DocStyleChange *s)
if (s->enable()) m_t << "\n\\footnotesize "; else m_t << "\n\\normalsize ";
break;
case DocStyleChange::Preformatted:
- if (s->enable())
+ if (s->enable())
{
m_t << "\n\\begin{DoxyPre}";
m_insidePre=TRUE;
@@ -349,7 +349,7 @@ void LatexDocVisitor::visit(DocVerbatim *s)
SrcLangExt langExt = getLanguageFromFileName(lang);
switch(s->type())
{
- case DocVerbatim::Code:
+ case DocVerbatim::Code:
{
m_t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n";
LatexCodeGenerator::setDoxyCodeOpen(TRUE);
@@ -360,28 +360,28 @@ void LatexDocVisitor::visit(DocVerbatim *s)
m_t << "\\end{DoxyCode}\n";
}
break;
- case DocVerbatim::Verbatim:
+ case DocVerbatim::Verbatim:
m_t << "\\begin{DoxyVerb}";
m_t << s->text();
m_t << "\\end{DoxyVerb}\n";
break;
- case DocVerbatim::HtmlOnly:
- case DocVerbatim::XmlOnly:
- case DocVerbatim::ManOnly:
+ case DocVerbatim::HtmlOnly:
+ case DocVerbatim::XmlOnly:
+ case DocVerbatim::ManOnly:
case DocVerbatim::RtfOnly:
case DocVerbatim::DocbookOnly:
- /* nothing */
+ /* nothing */
break;
- case DocVerbatim::LatexOnly:
- m_t << s->text();
+ case DocVerbatim::LatexOnly:
+ m_t << s->text();
break;
- case DocVerbatim::Dot:
+ case DocVerbatim::Dot:
{
static int dotindex = 1;
QCString fileName(4096);
- fileName.sprintf("%s%d%s",
- (Config_getString(LATEX_OUTPUT)+"/inline_dotgraph_").data(),
+ fileName.sprintf("%s%d%s",
+ (Config_getString(LATEX_OUTPUT)+"/inline_dotgraph_").data(),
dotindex++,
".dot"
);
@@ -403,13 +403,13 @@ void LatexDocVisitor::visit(DocVerbatim *s)
}
}
break;
- case DocVerbatim::Msc:
+ case DocVerbatim::Msc:
{
static int mscindex = 1;
QCString baseName(4096);
- baseName.sprintf("%s%d",
- (Config_getString(LATEX_OUTPUT)+"/inline_mscgraph_").data(),
+ baseName.sprintf("%s%d",
+ (Config_getString(LATEX_OUTPUT)+"/inline_mscgraph_").data(),
mscindex++
);
QFile file(baseName+".msc");
@@ -431,7 +431,7 @@ void LatexDocVisitor::visit(DocVerbatim *s)
}
}
break;
- case DocVerbatim::PlantUML:
+ case DocVerbatim::PlantUML:
{
QCString latexOutput = Config_getString(LATEX_OUTPUT);
QCString baseName = PlantumlManager::instance()->writePlantUMLSource(latexOutput,s->exampleFile(),s->text(),PlantumlManager::PUML_EPS);
@@ -446,11 +446,11 @@ void LatexDocVisitor::visit(DocAnchor *anc)
{
if (m_hide) return;
m_t << "\\label{" << stripPath(anc->file()) << "_" << anc->anchor() << "}%" << endl;
- if (!anc->file().isEmpty() && Config_getBool(PDF_HYPERLINKS))
+ if (!anc->file().isEmpty() && Config_getBool(PDF_HYPERLINKS))
{
- m_t << "\\Hypertarget{" << stripPath(anc->file()) << "_" << anc->anchor()
+ m_t << "\\Hypertarget{" << stripPath(anc->file()) << "_" << anc->anchor()
<< "}%" << endl;
- }
+ }
}
void LatexDocVisitor::visit(DocInclude *inc)
@@ -460,7 +460,7 @@ void LatexDocVisitor::visit(DocInclude *inc)
switch(inc->type())
{
case DocInclude::IncWithLines:
- {
+ {
m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n";
LatexCodeGenerator::setDoxyCodeOpen(TRUE);
QFileInfo cfi( inc->file() );
@@ -482,8 +482,8 @@ void LatexDocVisitor::visit(DocInclude *inc)
LatexCodeGenerator::setDoxyCodeOpen(FALSE);
m_t << "\\end{DoxyCodeInclude}" << endl;
}
- break;
- case DocInclude::Include:
+ break;
+ case DocInclude::Include:
m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n";
LatexCodeGenerator::setDoxyCodeOpen(TRUE);
Doxygen::parserManager->getCodeParser(inc->extension())
@@ -511,7 +511,7 @@ void LatexDocVisitor::visit(DocInclude *inc)
case DocInclude::LatexInclude:
m_t << inc->text();
break;
- case DocInclude::VerbInclude:
+ case DocInclude::VerbInclude:
m_t << "\n\\begin{DoxyVerbInclude}\n";
m_t << inc->text();
m_t << "\\end{DoxyVerbInclude}\n";
@@ -544,7 +544,7 @@ void LatexDocVisitor::visit(DocInclude *inc)
extractBlock(inc->text(),inc->blockId()),
langExt,
inc->isExample(),
- inc->exampleFile(),
+ inc->exampleFile(),
fd,
lineBlock(inc->text(),inc->blockId()),
-1, // endLine
@@ -557,8 +557,8 @@ void LatexDocVisitor::visit(DocInclude *inc)
m_t << "\\end{DoxyCodeInclude}" << endl;
}
break;
- case DocInclude::SnippetDoc:
- case DocInclude::IncludeDoc:
+ case DocInclude::SnippetDoc:
+ case DocInclude::IncludeDoc:
err("Internal inconsistency: found switch SnippetDoc / IncludeDoc in file: %s"
"Please create a bug report\n",__FILE__);
break;
@@ -569,7 +569,7 @@ void LatexDocVisitor::visit(DocIncOperator *op)
{
//printf("DocIncOperator: type=%d first=%d, last=%d text='%s'\n",
// op->type(),op->isFirst(),op->isLast(),op->text().data());
- if (op->isFirst())
+ if (op->isFirst())
{
if (!m_hide) m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n";
LatexCodeGenerator::setDoxyCodeOpen(TRUE);
@@ -579,10 +579,10 @@ void LatexDocVisitor::visit(DocIncOperator *op)
QCString locLangExt = getFileNameExtension(op->includeFileName());
if (locLangExt.isEmpty()) locLangExt = m_langExt;
SrcLangExt langExt = getLanguageFromFileName(locLangExt);
- if (op->type()!=DocIncOperator::Skip)
+ if (op->type()!=DocIncOperator::Skip)
{
popEnabled();
- if (!m_hide)
+ if (!m_hide)
{
FileDef *fd = 0;
if (!op->includeFileName().isEmpty())
@@ -606,7 +606,7 @@ void LatexDocVisitor::visit(DocIncOperator *op)
pushEnabled();
m_hide=TRUE;
}
- if (op->isLast())
+ if (op->isLast())
{
popEnabled();
LatexCodeGenerator::setDoxyCodeOpen(FALSE);
@@ -621,7 +621,8 @@ void LatexDocVisitor::visit(DocIncOperator *op)
void LatexDocVisitor::visit(DocFormula *f)
{
if (m_hide) return;
- const char *p=f->text();
+ QCString s = f->text();
+ const char *p = s.data();
char c;
if (p)
{
@@ -653,7 +654,7 @@ void LatexDocVisitor::visit(DocSimpleSectSep *)
void LatexDocVisitor::visit(DocCite *cite)
{
if (m_hide) return;
- if (!cite->file().isEmpty())
+ if (!cite->file().isEmpty())
{
//startLink(cite->ref(),cite->file(),cite->anchor());
QCString anchor = cite->anchor();
@@ -705,11 +706,11 @@ void LatexDocVisitor::visitPre(DocAutoListItem *)
m_t << "\n\\item ";
}
-void LatexDocVisitor::visitPost(DocAutoListItem *)
+void LatexDocVisitor::visitPost(DocAutoListItem *)
{
}
-void LatexDocVisitor::visitPre(DocPara *)
+void LatexDocVisitor::visitPre(DocPara *)
{
}
@@ -799,7 +800,7 @@ void LatexDocVisitor::visitPre(DocSimpleSect *s)
case DocSimpleSect::User:
m_t << "\\begin{DoxyParagraph}{";
break;
- case DocSimpleSect::Rcs:
+ case DocSimpleSect::Rcs:
m_t << "\\begin{DoxyParagraph}{";
break;
case DocSimpleSect::Unknown: break;
@@ -869,7 +870,7 @@ void LatexDocVisitor::visitPost(DocSimpleSect *s)
case DocSimpleSect::User:
m_t << "\n\\end{DoxyParagraph}\n";
break;
- case DocSimpleSect::Rcs:
+ case DocSimpleSect::Rcs:
m_t << "\n\\end{DoxyParagraph}\n";
break;
default:
@@ -906,7 +907,7 @@ void LatexDocVisitor::visitPre(DocSimpleListItem *)
m_t << "\\item ";
}
-void LatexDocVisitor::visitPost(DocSimpleListItem *)
+void LatexDocVisitor::visitPost(DocSimpleListItem *)
{
}
@@ -922,25 +923,25 @@ void LatexDocVisitor::visitPre(DocSection *s)
m_t << "}\\label{" << stripPath(s->file()) << "_" << s->anchor() << "}" << endl;
}
-void LatexDocVisitor::visitPost(DocSection *)
+void LatexDocVisitor::visitPost(DocSection *)
{
}
void LatexDocVisitor::visitPre(DocHtmlList *s)
{
if (m_hide) return;
- if (s->type()==DocHtmlList::Ordered)
+ if (s->type()==DocHtmlList::Ordered)
m_t << "\n\\begin{DoxyEnumerate}";
- else
+ else
m_t << "\n\\begin{DoxyItemize}";
}
-void LatexDocVisitor::visitPost(DocHtmlList *s)
+void LatexDocVisitor::visitPost(DocHtmlList *s)
{
if (m_hide) return;
- if (s->type()==DocHtmlList::Ordered)
+ if (s->type()==DocHtmlList::Ordered)
m_t << "\n\\end{DoxyEnumerate}";
- else
+ else
m_t << "\n\\end{DoxyItemize}";
}
@@ -950,7 +951,7 @@ void LatexDocVisitor::visitPre(DocHtmlListItem *)
m_t << "\n\\item ";
}
-void LatexDocVisitor::visitPost(DocHtmlListItem *)
+void LatexDocVisitor::visitPost(DocHtmlListItem *)
{
}
@@ -960,7 +961,7 @@ void LatexDocVisitor::visitPost(DocHtmlListItem *)
// m_insidePre=TRUE;
//}
-//void LatexDocVisitor::visitPost(DocHtmlPre *)
+//void LatexDocVisitor::visitPost(DocHtmlPre *)
//{
// m_insidePre=FALSE;
// m_t << "\\end{alltt}\\normalsize " << endl;
@@ -980,7 +981,7 @@ void LatexDocVisitor::visitPre(DocHtmlDescList *dl)
}
}
-void LatexDocVisitor::visitPost(DocHtmlDescList *dl)
+void LatexDocVisitor::visitPost(DocHtmlDescList *dl)
{
if (m_hide) return;
QCString val = dl->attribs().find("class");
@@ -1001,7 +1002,7 @@ void LatexDocVisitor::visitPre(DocHtmlDescTitle *)
m_insideItem=TRUE;
}
-void LatexDocVisitor::visitPost(DocHtmlDescTitle *)
+void LatexDocVisitor::visitPost(DocHtmlDescTitle *)
{
if (m_hide) return;
m_insideItem=FALSE;
@@ -1012,7 +1013,7 @@ void LatexDocVisitor::visitPre(DocHtmlDescData *)
{
}
-void LatexDocVisitor::visitPost(DocHtmlDescData *)
+void LatexDocVisitor::visitPost(DocHtmlDescData *)
{
}
@@ -1120,7 +1121,7 @@ void LatexDocVisitor::visitPre(DocHtmlRow *r)
setCurrentColumn(0);
}
-void LatexDocVisitor::visitPost(DocHtmlRow *row)
+void LatexDocVisitor::visitPost(DocHtmlRow *row)
{
if (m_hide) return;
@@ -1155,7 +1156,7 @@ void LatexDocVisitor::visitPost(DocHtmlRow *row)
}
m_t << "\\\\";
-
+
int col = 1;
uint i;
for (i=0;i<rowSpans().count();i++)
@@ -1289,7 +1290,7 @@ void LatexDocVisitor::visitPre(DocHtmlCell *c)
}
}
-void LatexDocVisitor::visitPost(DocHtmlCell *c)
+void LatexDocVisitor::visitPost(DocHtmlCell *c)
{
if (m_hide) return;
if (c->isHeading())
@@ -1317,7 +1318,7 @@ void LatexDocVisitor::visitPre(DocInternal *)
//m_t << "}\n";
}
-void LatexDocVisitor::visitPost(DocInternal *)
+void LatexDocVisitor::visitPost(DocInternal *)
{
if (m_hide) return;
//m_t << "\\end{DoxyInternal}" << endl;
@@ -1335,7 +1336,7 @@ void LatexDocVisitor::visitPre(DocHRef *href)
m_t << "{\\texttt{ ";
}
-void LatexDocVisitor::visitPost(DocHRef *)
+void LatexDocVisitor::visitPost(DocHRef *)
{
if (m_hide) return;
m_t << "}}";
@@ -1347,7 +1348,7 @@ void LatexDocVisitor::visitPre(DocHtmlHeader *header)
m_t << "\\" << getSectionName(header->level()) << "*{";
}
-void LatexDocVisitor::visitPost(DocHtmlHeader *)
+void LatexDocVisitor::visitPost(DocHtmlHeader *)
{
if (m_hide) return;
m_t << "}";
@@ -1372,7 +1373,7 @@ void LatexDocVisitor::visitPre(DocImage *img)
}
}
-void LatexDocVisitor::visitPost(DocImage *img)
+void LatexDocVisitor::visitPost(DocImage *img)
{
if (img->type()==DocImage::Latex)
{
@@ -1391,7 +1392,7 @@ void LatexDocVisitor::visitPre(DocDotFile *df)
startDotFile(df->file(),df->width(),df->height(),df->hasCaption());
}
-void LatexDocVisitor::visitPost(DocDotFile *df)
+void LatexDocVisitor::visitPost(DocDotFile *df)
{
if (m_hide) return;
endDotFile(df->hasCaption());
@@ -1402,7 +1403,7 @@ void LatexDocVisitor::visitPre(DocMscFile *df)
startMscFile(df->file(),df->width(),df->height(),df->hasCaption());
}
-void LatexDocVisitor::visitPost(DocMscFile *df)
+void LatexDocVisitor::visitPost(DocMscFile *df)
{
if (m_hide) return;
endMscFile(df->hasCaption());
@@ -1425,7 +1426,7 @@ void LatexDocVisitor::visitPre(DocLink *lnk)
startLink(lnk->ref(),lnk->file(),lnk->anchor());
}
-void LatexDocVisitor::visitPost(DocLink *lnk)
+void LatexDocVisitor::visitPost(DocLink *lnk)
{
if (m_hide) return;
endLink(lnk->ref(),lnk->file(),lnk->anchor());
@@ -1447,7 +1448,7 @@ void LatexDocVisitor::visitPre(DocRef *ref)
if (!ref->hasLinkText()) filter(ref->targetTitle());
}
-void LatexDocVisitor::visitPost(DocRef *ref)
+void LatexDocVisitor::visitPost(DocRef *ref)
{
if (m_hide) return;
if (ref->isSubPage())
@@ -1471,7 +1472,7 @@ void LatexDocVisitor::visitPre(DocSecRefItem *ref)
}
}
-void LatexDocVisitor::visitPost(DocSecRefItem *ref)
+void LatexDocVisitor::visitPost(DocSecRefItem *ref)
{
if (m_hide) return;
static bool pdfHyperlinks = Config_getBool(PDF_HYPERLINKS);
@@ -1490,7 +1491,7 @@ void LatexDocVisitor::visitPre(DocSecRefList *)
m_t << "\\begin{DoxyCompactList}" << endl;
}
-void LatexDocVisitor::visitPost(DocSecRefList *)
+void LatexDocVisitor::visitPost(DocSecRefList *)
{
if (m_hide) return;
m_t << "\\end{DoxyCompactList}" << endl;
@@ -1517,11 +1518,11 @@ void LatexDocVisitor::visitPre(DocParamSect *s)
m_t << "\n\\begin{DoxyRetVals}{";
filter(theTranslator->trReturnValues());
break;
- case DocParamSect::Exception:
+ case DocParamSect::Exception:
m_t << "\n\\begin{DoxyExceptions}{";
filter(theTranslator->trExceptions());
break;
- case DocParamSect::TemplateParam:
+ case DocParamSect::TemplateParam:
m_t << "\n\\begin{DoxyTemplParams}{";
filter(theTranslator->trTemplateParameters());
break;
@@ -1543,10 +1544,10 @@ void LatexDocVisitor::visitPost(DocParamSect *s)
case DocParamSect::RetVal:
m_t << "\\end{DoxyRetVals}\n";
break;
- case DocParamSect::Exception:
+ case DocParamSect::Exception:
m_t << "\\end{DoxyExceptions}\n";
break;
- case DocParamSect::TemplateParam:
+ case DocParamSect::TemplateParam:
m_t << "\\end{DoxyTemplParams}\n";
break;
default:
@@ -1601,11 +1602,11 @@ void LatexDocVisitor::visitPre(DocParamList *pl)
{
if (type->kind()==DocNode::Kind_Word)
{
- visit((DocWord*)type);
+ visit((DocWord*)type);
}
else if (type->kind()==DocNode::Kind_LinkedWord)
{
- visit((DocLinkedWord*)type);
+ visit((DocLinkedWord*)type);
}
else if (type->kind()==DocNode::Kind_Sep)
{
@@ -1626,11 +1627,11 @@ void LatexDocVisitor::visitPre(DocParamList *pl)
m_insideItem=TRUE;
if (param->kind()==DocNode::Kind_Word)
{
- visit((DocWord*)param);
+ visit((DocWord*)param);
}
else if (param->kind()==DocNode::Kind_LinkedWord)
{
- visit((DocLinkedWord*)param);
+ visit((DocLinkedWord*)param);
}
m_insideItem=FALSE;
}
@@ -1705,7 +1706,7 @@ void LatexDocVisitor::visitPre(DocInternalRef *ref)
startLink(0,ref->file(),ref->anchor());
}
-void LatexDocVisitor::visitPost(DocInternalRef *ref)
+void LatexDocVisitor::visitPost(DocInternalRef *ref)
{
if (m_hide) return;
endLink(0,ref->file(),ref->anchor());
@@ -1752,7 +1753,7 @@ void LatexDocVisitor::visitPost(DocParBlock *)
}
void LatexDocVisitor::filter(const char *str)
-{
+{
filterLatexString(m_t,str,m_insideTabbing,m_insidePre,m_insideItem);
}
@@ -1833,7 +1834,7 @@ void LatexDocVisitor::startDotFile(const QCString &fileName,
if ((i=baseName.findRev('/'))!=-1)
{
baseName=baseName.right(baseName.length()-i-1);
- }
+ }
if ((i=baseName.find('.'))!=-1)
{
baseName=baseName.left(i);
@@ -1862,7 +1863,7 @@ void LatexDocVisitor::startMscFile(const QCString &fileName,
if ((i=baseName.findRev('/'))!=-1)
{
baseName=baseName.right(baseName.length()-i-1);
- }
+ }
if ((i=baseName.find('.'))!=-1)
{
baseName=baseName.left(i);
@@ -1870,7 +1871,7 @@ void LatexDocVisitor::startMscFile(const QCString &fileName,
baseName.prepend("msc_");
QCString outDir = Config_getString(LATEX_OUTPUT);
- writeMscGraphFromFile(fileName,outDir,baseName,MSC_EPS);
+ writeMscGraphFromFile(fileName,outDir,baseName,MSC_EPS);
visitPreStart(m_t,hasCaption, baseName, width, height);
}
@@ -1888,7 +1889,7 @@ void LatexDocVisitor::writeMscFile(const QCString &baseName, DocVerbatim *s)
if ((i=shortName.findRev('/'))!=-1)
{
shortName=shortName.right(shortName.length()-i-1);
- }
+ }
QCString outDir = Config_getString(LATEX_OUTPUT);
writeMscGraphFromFile(baseName+".msc",outDir,shortName,MSC_EPS);
visitPreStart(m_t, s->hasCaption(), shortName, s->width(),s->height());
diff --git a/src/latexgen.cpp b/src/latexgen.cpp
index 52a8acf..cb42863 100644
--- a/src/latexgen.cpp
+++ b/src/latexgen.cpp
@@ -511,10 +511,10 @@ static void writeDefaultHeaderPart1(FTextStream &t)
"\\usepackage{fixltx2e}\n" // for \textsubscript
"\\usepackage{calc}\n"
"\\usepackage{doxygen}\n";
- QStrList extraLatexStyle = Config_getList(LATEX_EXTRA_STYLESHEET);
- for (uint i=0; i<extraLatexStyle.count(); ++i)
+ const StringVector &extraLatexStyles = Config_getList(LATEX_EXTRA_STYLESHEET);
+ for (const auto &extraStyle : extraLatexStyles)
{
- QCString fileName(extraLatexStyle.at(i));
+ QCString fileName = extraStyle.c_str();
if (!fileName.isEmpty())
{
QFileInfo fi(fileName);
@@ -560,11 +560,13 @@ static void writeDefaultHeaderPart1(FTextStream &t)
{
t << "\\usepackage[" << fontenc << "]{fontenc}\n";
}
- t << "\\usepackage[scaled=.90]{helvet}\n"
- "\\usepackage{courier}\n"
- "\\usepackage{amssymb}\n"
+ QCString font = theTranslator->latexFont();
+ if (!font.isEmpty())
+ {
+ t << font;
+ }
+ t << "\\usepackage{amssymb}\n"
"\\usepackage{sectsty}\n"
- "\\renewcommand{\\familydefault}{\\sfdefault}\n"
"\\allsectionsfont{%\n"
" \\fontseries{bc}\\selectfont%\n"
" \\color{darkgray}%\n"
@@ -914,8 +916,8 @@ void LatexGenerator::startProjectNumber()
void LatexGenerator::startIndexSection(IndexSections is)
{
- bool &compactLatex = Config_getBool(COMPACT_LATEX);
- QCString &latexHeader = Config_getString(LATEX_HEADER);
+ bool compactLatex = Config_getBool(COMPACT_LATEX);
+ QCString latexHeader = Config_getString(LATEX_HEADER);
switch (is)
{
case isTitlePageStart:
diff --git a/src/layout.cpp b/src/layout.cpp
index f84fec0..fd31803 100644
--- a/src/layout.cpp
+++ b/src/layout.cpp
@@ -1,13 +1,13 @@
/******************************************************************************
*
- *
+ *
*
*
* 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
+ * 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.
*
@@ -63,7 +63,7 @@ static bool elemIsVisible(const QXmlAttributes &attrib,bool defVal=TRUE)
const ConfigValues::Info *opt = ConfigValues::instance().get(id);
if (opt && opt->type==ConfigValues::Info::Bool)
{
- return ConfigValues::instance().*((ConfigValues::InfoBool*)opt)->item;
+ return ConfigValues::instance().*(opt->value.b);
}
else if (!opt)
{
@@ -84,7 +84,7 @@ LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind,
LayoutNavEntry *entry;
for (li.toFirst();(entry=li.current());++li)
{
- // depth first search, needed to find the entry furthest from the
+ // depth first search, needed to find the entry furthest from the
// root in case an entry is in the tree twice
result = entry->find(kind,file);
if (result) return result;
@@ -99,7 +99,7 @@ LayoutNavEntry *LayoutNavEntry::find(LayoutNavEntry::Kind kind,
QCString LayoutNavEntry::url() const
{
QCString url = baseFile().stripWhiteSpace();
- if ((kind()!=LayoutNavEntry::User && kind()!=LayoutNavEntry::UserGroup) ||
+ if ((kind()!=LayoutNavEntry::User && kind()!=LayoutNavEntry::UserGroup) ||
(kind()==LayoutNavEntry::UserGroup && url.left(9)=="usergroup"))
{
url+=Doxygen::htmlFileExtension;
@@ -111,7 +111,7 @@ QCString LayoutNavEntry::url() const
bool found=FALSE;
if (resolveLink(0,url.mid(5).stripWhiteSpace(),TRUE,&d,anchor))
{
- if (d && d->isLinkable())
+ if (d && d->isLinkable())
{
url=d->getOutputFileBase()+Doxygen::htmlFileExtension;
if (!anchor.isEmpty())
@@ -137,14 +137,14 @@ class LayoutParser : public QXmlDefaultHandler
private:
class StartElementHandler
{
- typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib);
+ typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib);
public:
- StartElementHandler(LayoutParser *parent, Handler h)
+ StartElementHandler(LayoutParser *parent, Handler h)
: m_parent(parent), m_handler(h) {}
virtual ~StartElementHandler() {}
- virtual void operator()(const QXmlAttributes &attrib)
- {
- (m_parent->*m_handler)(attrib);
+ virtual void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(attrib);
}
protected:
StartElementHandler() : m_parent(0), m_handler(0) {}
@@ -156,13 +156,13 @@ class LayoutParser : public QXmlDefaultHandler
class StartElementHandlerKind : public StartElementHandler
{
typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind,
- const QXmlAttributes &attrib);
+ const QXmlAttributes &attrib);
public:
- StartElementHandlerKind(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h)
+ StartElementHandlerKind(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h)
: m_parent(parent), m_kind(k), m_handler(h) {}
- void operator()(const QXmlAttributes &attrib)
- {
- (m_parent->*m_handler)(m_kind,attrib);
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(m_kind,attrib);
}
private:
LayoutParser *m_parent;
@@ -174,14 +174,14 @@ class LayoutParser : public QXmlDefaultHandler
{
typedef void (LayoutParser::*Handler)(LayoutDocEntry::Kind kind,
const QXmlAttributes &attrib,
- const QCString &title);
+ const QCString &title);
public:
StartElementHandlerSection(LayoutParser *parent, LayoutDocEntry::Kind k,Handler h,
- const QCString &title)
+ const QCString &title)
: m_parent(parent), m_kind(k), m_handler(h), m_title(title) {}
- void operator()(const QXmlAttributes &attrib)
- {
- (m_parent->*m_handler)(m_kind,attrib,m_title);
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(m_kind,attrib,m_title);
}
private:
LayoutParser *m_parent;
@@ -195,19 +195,19 @@ class LayoutParser : public QXmlDefaultHandler
typedef void (LayoutParser::*Handler)(const QXmlAttributes &attrib,
MemberListType type,
const QCString &title,
- const QCString &subtitle);
+ const QCString &subtitle);
public:
- StartElementHandlerMember(LayoutParser *parent,
+ StartElementHandlerMember(LayoutParser *parent,
Handler h,
MemberListType type,
const QCString &tl,
const QCString &ss = QCString()
- )
+ )
: m_parent(parent), m_handler(h), m_type(type),
m_title(tl), m_subscript(ss) {}
- void operator()(const QXmlAttributes &attrib)
- {
- (m_parent->*m_handler)(attrib,m_type,m_title,m_subscript);
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(attrib,m_type,m_title,m_subscript);
}
private:
LayoutParser *m_parent;
@@ -221,17 +221,17 @@ class LayoutParser : public QXmlDefaultHandler
{
typedef void (LayoutParser::*Handler)(LayoutNavEntry::Kind kind,
const QXmlAttributes &attrib,
- const QCString &title);
+ const QCString &title);
public:
StartElementHandlerNavEntry(LayoutParser *parent,
- LayoutNavEntry::Kind kind,
+ LayoutNavEntry::Kind kind,
Handler h,
const QCString &tl
- )
+ )
: m_parent(parent), m_kind(kind), m_handler(h), m_title(tl) {}
- void operator()(const QXmlAttributes &attrib)
- {
- (m_parent->*m_handler)(m_kind,attrib,m_title);
+ void operator()(const QXmlAttributes &attrib)
+ {
+ (m_parent->*m_handler)(m_kind,attrib,m_title);
}
private:
LayoutParser *m_parent;
@@ -242,7 +242,7 @@ class LayoutParser : public QXmlDefaultHandler
class EndElementHandler
{
- typedef void (LayoutParser::*Handler)();
+ typedef void (LayoutParser::*Handler)();
public:
EndElementHandler(LayoutParser *parent, Handler h) : m_parent(parent), m_handler(h) {}
void operator()() { (m_parent->*m_handler)(); }
@@ -266,51 +266,51 @@ class LayoutParser : public QXmlDefaultHandler
m_rootNav = 0;
//bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
- //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
+ //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
//bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
// start & end handlers
- m_sHandler.insert("doxygenlayout",
+ m_sHandler.insert("doxygenlayout",
new StartElementHandler(this,&LayoutParser::startLayout));
- m_eHandler.insert("doxygenlayout",
+ m_eHandler.insert("doxygenlayout",
new EndElementHandler(this,&LayoutParser::endLayout));
// class layout handlers
- m_sHandler.insert("navindex",
+ m_sHandler.insert("navindex",
new StartElementHandler(this,&LayoutParser::startNavIndex));
- m_sHandler.insert("navindex/tab",
+ m_sHandler.insert("navindex/tab",
new StartElementHandler(this,&LayoutParser::startNavEntry));
- m_eHandler.insert("navindex/tab",
+ m_eHandler.insert("navindex/tab",
new EndElementHandler(this,&LayoutParser::endNavEntry));
- m_eHandler.insert("navindex",
+ m_eHandler.insert("navindex",
new EndElementHandler(this,&LayoutParser::endNavIndex));
// class layout handlers
- m_sHandler.insert("class",
+ m_sHandler.insert("class",
new StartElementHandler(this,&LayoutParser::startClass));
- m_sHandler.insert("class/briefdescription",
+ m_sHandler.insert("class/briefdescription",
new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/detaileddescription",
+ m_sHandler.insert("class/detaileddescription",
new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
theTranslator->trDetailedDescription()));
- m_sHandler.insert("class/authorsection",
+ m_sHandler.insert("class/authorsection",
new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/includes",
+ m_sHandler.insert("class/includes",
new StartElementHandlerKind(this,LayoutDocEntry::ClassIncludes,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/inheritancegraph",
+ m_sHandler.insert("class/inheritancegraph",
new StartElementHandlerKind(this,LayoutDocEntry::ClassInheritanceGraph,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/collaborationgraph",
+ m_sHandler.insert("class/collaborationgraph",
new StartElementHandlerKind(this,LayoutDocEntry::ClassCollaborationGraph,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/allmemberslink",
+ m_sHandler.insert("class/allmemberslink",
new StartElementHandlerKind(this,LayoutDocEntry::ClassAllMembersLink,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/usedfiles",
+ m_sHandler.insert("class/usedfiles",
new StartElementHandlerKind(this,LayoutDocEntry::ClassUsedFiles,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/memberdecl",
+ m_sHandler.insert("class/memberdecl",
new StartElementHandler(this,&LayoutParser::startMemberDecl));
- m_sHandler.insert("class/memberdecl/membergroups",
+ m_sHandler.insert("class/memberdecl/membergroups",
new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("class/memberdecl/nestedclasses",
+ m_sHandler.insert("class/memberdecl/nestedclasses",
new StartElementHandlerSection(this,LayoutDocEntry::ClassNestedClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_2_OPTIONS(
theTranslator->trCompounds(),
@@ -323,118 +323,118 @@ class LayoutParser : public QXmlDefaultHandler
m_sHandler.insert("class/memberdecl/interfaces",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_interfaces,theTranslator->trInterfaces()));
- m_sHandler.insert("class/memberdecl/publictypes",
+ m_sHandler.insert("class/memberdecl/publictypes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_pubTypes,theTranslator->trPublicTypes()));
- m_sHandler.insert("class/memberdecl/publicslots",
+ m_sHandler.insert("class/memberdecl/publicslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pubSlots,theTranslator->trPublicSlots()));
- m_sHandler.insert("class/memberdecl/signals",
+ MemberListType_pubSlots,theTranslator->trPublicSlots()));
+ m_sHandler.insert("class/memberdecl/signals",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_signals,theTranslator->trSignals()));
- m_sHandler.insert("class/memberdecl/publicmethods",
+ MemberListType_signals,theTranslator->trSignals()));
+ m_sHandler.insert("class/memberdecl/publicmethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_pubMethods,
COMPILE_FOR_2_OPTIONS(
theTranslator->trPublicMembers(),
SrcLangExt_ObjC,theTranslator->trInstanceMethods(),
SrcLangExt_Slice,theTranslator->trOperations()
- )));
- m_sHandler.insert("class/memberdecl/publicstaticmethods",
+ )));
+ m_sHandler.insert("class/memberdecl/publicstaticmethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_pubStaticMethods,
COMPILE_FOR_1_OPTION(
theTranslator->trStaticPublicMembers(),
SrcLangExt_ObjC,theTranslator->trClassMethods()
- )));
- m_sHandler.insert("class/memberdecl/publicattributes",
+ )));
+ m_sHandler.insert("class/memberdecl/publicattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_pubAttribs,
COMPILE_FOR_1_OPTION(
theTranslator->trPublicAttribs(),
SrcLangExt_Slice,theTranslator->trDataMembers()
- )));
- m_sHandler.insert("class/memberdecl/publicstaticattributes",
+ )));
+ m_sHandler.insert("class/memberdecl/publicstaticattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs()));
- m_sHandler.insert("class/memberdecl/protectedtypes",
+ MemberListType_pubStaticAttribs,theTranslator->trStaticPublicAttribs()));
+ m_sHandler.insert("class/memberdecl/protectedtypes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_proTypes,theTranslator->trProtectedTypes()));
- m_sHandler.insert("class/memberdecl/protectedslots",
+ MemberListType_proTypes,theTranslator->trProtectedTypes()));
+ m_sHandler.insert("class/memberdecl/protectedslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_proSlots,theTranslator->trProtectedSlots()));
- m_sHandler.insert("class/memberdecl/protectedmethods",
+ MemberListType_proSlots,theTranslator->trProtectedSlots()));
+ m_sHandler.insert("class/memberdecl/protectedmethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_proMethods,theTranslator->trProtectedMembers()));
- m_sHandler.insert("class/memberdecl/protectedstaticmethods",
+ MemberListType_proMethods,theTranslator->trProtectedMembers()));
+ m_sHandler.insert("class/memberdecl/protectedstaticmethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_proStaticMethods,theTranslator->trStaticProtectedMembers()));
- m_sHandler.insert("class/memberdecl/protectedattributes",
+ m_sHandler.insert("class/memberdecl/protectedattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_proAttribs,theTranslator->trProtectedAttribs()));
- m_sHandler.insert("class/memberdecl/protectedstaticattributes",
+ MemberListType_proAttribs,theTranslator->trProtectedAttribs()));
+ m_sHandler.insert("class/memberdecl/protectedstaticattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()));
- m_sHandler.insert("class/memberdecl/packagetypes",
+ MemberListType_proStaticAttribs,theTranslator->trStaticProtectedAttribs()));
+ m_sHandler.insert("class/memberdecl/packagetypes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pacTypes,theTranslator->trPackageTypes()));
- m_sHandler.insert("class/memberdecl/packagemethods",
+ MemberListType_pacTypes,theTranslator->trPackageTypes()));
+ m_sHandler.insert("class/memberdecl/packagemethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pacMethods,theTranslator->trPackageMembers()));
- m_sHandler.insert("class/memberdecl/packagestaticmethods",
+ MemberListType_pacMethods,theTranslator->trPackageMembers()));
+ m_sHandler.insert("class/memberdecl/packagestaticmethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()));
- m_sHandler.insert("class/memberdecl/packageattributes",
+ MemberListType_pacStaticMethods,theTranslator->trStaticPackageMembers()));
+ m_sHandler.insert("class/memberdecl/packageattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pacAttribs,theTranslator->trPackageAttribs()));
- m_sHandler.insert("class/memberdecl/packagestaticattributes",
+ MemberListType_pacAttribs,theTranslator->trPackageAttribs()));
+ m_sHandler.insert("class/memberdecl/packagestaticattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()));
- m_sHandler.insert("class/memberdecl/properties",
+ MemberListType_pacStaticAttribs,theTranslator->trStaticPackageAttribs()));
+ m_sHandler.insert("class/memberdecl/properties",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_properties,theTranslator->trProperties()));
- m_sHandler.insert("class/memberdecl/events",
+ MemberListType_properties,theTranslator->trProperties()));
+ m_sHandler.insert("class/memberdecl/events",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_events,theTranslator->trEvents()));
- m_sHandler.insert("class/memberdecl/privatetypes",
+ MemberListType_events,theTranslator->trEvents()));
+ m_sHandler.insert("class/memberdecl/privatetypes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_priTypes,theTranslator->trPrivateTypes()));
- m_sHandler.insert("class/memberdecl/privateslots",
+ MemberListType_priTypes,theTranslator->trPrivateTypes()));
+ m_sHandler.insert("class/memberdecl/privateslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_priSlots,theTranslator->trPrivateSlots()));
- m_sHandler.insert("class/memberdecl/privatemethods",
+ MemberListType_priSlots,theTranslator->trPrivateSlots()));
+ m_sHandler.insert("class/memberdecl/privatemethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_priMethods,theTranslator->trPrivateMembers()));
- m_sHandler.insert("class/memberdecl/privatestaticmethods",
+ MemberListType_priMethods,theTranslator->trPrivateMembers()));
+ m_sHandler.insert("class/memberdecl/privatestaticmethods",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers()));
- m_sHandler.insert("class/memberdecl/privateattributes",
+ MemberListType_priStaticMethods,theTranslator->trStaticPrivateMembers()));
+ m_sHandler.insert("class/memberdecl/privateattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_priAttribs,theTranslator->trPrivateAttribs()));
- m_sHandler.insert("class/memberdecl/privatestaticattributes",
+ MemberListType_priAttribs,theTranslator->trPrivateAttribs()));
+ m_sHandler.insert("class/memberdecl/privatestaticattributes",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
- MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs()));
- m_sHandler.insert("class/memberdecl/friends",
+ MemberListType_priStaticAttribs,theTranslator->trStaticPrivateAttribs()));
+ m_sHandler.insert("class/memberdecl/friends",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_friends,theTranslator->trFriends()));
- m_sHandler.insert("class/memberdecl/related",
+ m_sHandler.insert("class/memberdecl/related",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_related,theTranslator->trRelatedFunctions(),
- theTranslator->trRelatedSubscript()));
- m_eHandler.insert("class/memberdecl",
+ theTranslator->trRelatedSubscript()));
+ m_eHandler.insert("class/memberdecl",
new EndElementHandler(this,&LayoutParser::endMemberDecl));
- m_sHandler.insert("class/memberdef",
+ m_sHandler.insert("class/memberdef",
new StartElementHandler(this,&LayoutParser::startMemberDef));
- m_sHandler.insert("class/memberdef/inlineclasses",
+ m_sHandler.insert("class/memberdef/inlineclasses",
new StartElementHandlerSection(this,LayoutDocEntry::ClassInlineClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_1_OPTION(
theTranslator->trClassDocumentation(),
SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
)));
- m_sHandler.insert("class/memberdef/typedefs",
+ m_sHandler.insert("class/memberdef/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_typedefMembers,theTranslator->trMemberTypedefDocumentation()));
- m_sHandler.insert("class/memberdef/enums",
+ m_sHandler.insert("class/memberdef/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_enumMembers,theTranslator->trMemberEnumerationDocumentation()));
m_sHandler.insert("class/memberdef/services",
@@ -443,10 +443,10 @@ class LayoutParser : public QXmlDefaultHandler
m_sHandler.insert("class/memberdef/interfaces",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_interfaceMembers,theTranslator->trInterfaces()));
- m_sHandler.insert("class/memberdef/constructors",
+ m_sHandler.insert("class/memberdef/constructors",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_constructors,theTranslator->trConstructorDocumentation()));
- m_sHandler.insert("class/memberdef/functions",
+ m_sHandler.insert("class/memberdef/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_functionMembers,
COMPILE_FOR_3_OPTIONS(
@@ -455,41 +455,41 @@ class LayoutParser : public QXmlDefaultHandler
SrcLangExt_Fortran,theTranslator->trMemberFunctionDocumentationFortran(),
SrcLangExt_Slice,theTranslator->trOperationDocumentation()
)));
- m_sHandler.insert("class/memberdef/related",
+ m_sHandler.insert("class/memberdef/related",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_relatedMembers,theTranslator->trRelatedFunctionDocumentation()));
- m_sHandler.insert("class/memberdef/variables",
+ m_sHandler.insert("class/memberdef/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_variableMembers,
COMPILE_FOR_1_OPTION(
theTranslator->trMemberDataDocumentation(),
SrcLangExt_Slice,theTranslator->trDataMemberDocumentation()
- )));
- m_sHandler.insert("class/memberdef/properties",
+ )));
+ m_sHandler.insert("class/memberdef/properties",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_propertyMembers,theTranslator->trPropertyDocumentation()));
- m_sHandler.insert("class/memberdef/events",
+ m_sHandler.insert("class/memberdef/events",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_eventMembers,theTranslator->trEventDocumentation()));
- m_eHandler.insert("class/memberdef",
+ m_eHandler.insert("class/memberdef",
new EndElementHandler(this,&LayoutParser::endMemberDef));
- m_eHandler.insert("class",
+ m_eHandler.insert("class",
new EndElementHandler(this,&LayoutParser::endClass));
// namespace layout handlers
- m_sHandler.insert("namespace",
+ m_sHandler.insert("namespace",
new StartElementHandler(this,&LayoutParser::startNamespace));
- m_sHandler.insert("namespace/briefdescription",
+ m_sHandler.insert("namespace/briefdescription",
new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("namespace/detaileddescription",
+ m_sHandler.insert("namespace/detaileddescription",
new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
theTranslator->trDetailedDescription()));
- m_sHandler.insert("namespace/authorsection",
+ m_sHandler.insert("namespace/authorsection",
new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("namespace/memberdecl",
+ m_sHandler.insert("namespace/memberdecl",
new StartElementHandler(this,&LayoutParser::startMemberDecl));
- m_sHandler.insert("namespace/memberdecl/nestednamespaces",
+ m_sHandler.insert("namespace/memberdecl/nestednamespaces",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedNamespaces,&LayoutParser::startSectionEntry,
COMPILE_FOR_5_OPTIONS(
theTranslator->trNamespaces(),
@@ -503,37 +503,37 @@ class LayoutParser : public QXmlDefaultHandler
m_sHandler.insert("namespace/memberdecl/constantgroups",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceNestedConstantGroups,&LayoutParser::startSectionEntry,
theTranslator->trConstantGroups()));
- m_sHandler.insert("namespace/memberdecl/interfaces",
+ m_sHandler.insert("namespace/memberdecl/interfaces",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInterfaces,&LayoutParser::startSectionEntry,
theTranslator->trSliceInterfaces()));
- m_sHandler.insert("namespace/memberdecl/classes",
+ m_sHandler.insert("namespace/memberdecl/classes",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_2_OPTIONS(
theTranslator->trCompounds(),
SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE),
SrcLangExt_Fortran,theTranslator->trDataTypes()
)));
- m_sHandler.insert("namespace/memberdecl/structs",
+ m_sHandler.insert("namespace/memberdecl/structs",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceStructs,&LayoutParser::startSectionEntry,
theTranslator->trStructs()));
- m_sHandler.insert("namespace/memberdecl/exceptions",
+ m_sHandler.insert("namespace/memberdecl/exceptions",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceExceptions,&LayoutParser::startSectionEntry,
theTranslator->trExceptions()));
- m_sHandler.insert("namespace/memberdecl/membergroups",
+ m_sHandler.insert("namespace/memberdecl/membergroups",
new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("namespace/memberdecl/typedefs",
+ m_sHandler.insert("namespace/memberdecl/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
- m_sHandler.insert("namespace/memberdecl/sequences",
+ m_sHandler.insert("namespace/memberdecl/sequences",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decSequenceMembers,theTranslator->trSequences()));
- m_sHandler.insert("namespace/memberdecl/dictionaries",
+ m_sHandler.insert("namespace/memberdecl/dictionaries",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decDictionaryMembers,theTranslator->trDictionaries()));
- m_sHandler.insert("namespace/memberdecl/enums",
+ m_sHandler.insert("namespace/memberdecl/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decEnumMembers,theTranslator->trEnumerations()));
- m_sHandler.insert("namespace/memberdecl/functions",
+ m_sHandler.insert("namespace/memberdecl/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decFuncMembers,
COMPILE_FOR_2_OPTIONS(
@@ -541,89 +541,89 @@ class LayoutParser : public QXmlDefaultHandler
SrcLangExt_Fortran,theTranslator->trSubprograms(),
SrcLangExt_VHDL,theTranslator->trFunctionAndProc()
)));
- m_sHandler.insert("namespace/memberdecl/variables",
+ m_sHandler.insert("namespace/memberdecl/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decVarMembers,
sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()));
- m_eHandler.insert("namespace/memberdecl",
+ m_eHandler.insert("namespace/memberdecl",
new EndElementHandler(this,&LayoutParser::endMemberDecl));
- m_sHandler.insert("namespace/memberdef",
+ m_sHandler.insert("namespace/memberdef",
new StartElementHandler(this,&LayoutParser::startMemberDef));
- m_sHandler.insert("namespace/memberdef/inlineclasses",
+ m_sHandler.insert("namespace/memberdef/inlineclasses",
new StartElementHandlerSection(this,LayoutDocEntry::NamespaceInlineClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_1_OPTION(
theTranslator->trClassDocumentation(),
SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
)));
- m_sHandler.insert("namespace/memberdef/typedefs",
+ m_sHandler.insert("namespace/memberdef/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
- m_sHandler.insert("namespace/memberdef/sequences",
+ m_sHandler.insert("namespace/memberdef/sequences",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()));
- m_sHandler.insert("namespace/memberdef/dictionaries",
+ m_sHandler.insert("namespace/memberdef/dictionaries",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docDictionaryMembers,
theTranslator->trDictionaryDocumentation()));
- m_sHandler.insert("namespace/memberdef/enums",
+ m_sHandler.insert("namespace/memberdef/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()));
- m_sHandler.insert("namespace/memberdef/functions",
+ m_sHandler.insert("namespace/memberdef/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docFuncMembers,
COMPILE_FOR_1_OPTION(
theTranslator->trFunctionDocumentation(),
SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
)));
- m_sHandler.insert("namespace/memberdef/variables",
+ m_sHandler.insert("namespace/memberdef/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docVarMembers,
sliceOpt ? theTranslator->trConstantDocumentation() :
theTranslator->trVariableDocumentation()));
- m_eHandler.insert("namespace/memberdef",
+ m_eHandler.insert("namespace/memberdef",
new EndElementHandler(this,&LayoutParser::endMemberDef));
- m_eHandler.insert("namespace",
+ m_eHandler.insert("namespace",
new EndElementHandler(this,&LayoutParser::endNamespace));
// file layout handlers
- m_sHandler.insert("file",
+ m_sHandler.insert("file",
new StartElementHandler(this,&LayoutParser::startFile));
- m_sHandler.insert("file/briefdescription",
+ m_sHandler.insert("file/briefdescription",
new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/detaileddescription",
+ m_sHandler.insert("file/detaileddescription",
new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
theTranslator->trDetailedDescription()));
- m_sHandler.insert("file/authorsection",
+ m_sHandler.insert("file/authorsection",
new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/includes",
+ m_sHandler.insert("file/includes",
new StartElementHandlerKind(this,LayoutDocEntry::FileIncludes,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/includegraph",
+ m_sHandler.insert("file/includegraph",
new StartElementHandlerKind(this,LayoutDocEntry::FileIncludeGraph,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/includedbygraph",
+ m_sHandler.insert("file/includedbygraph",
new StartElementHandlerKind(this,LayoutDocEntry::FileIncludedByGraph,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/sourcelink",
+ m_sHandler.insert("file/sourcelink",
new StartElementHandlerKind(this,LayoutDocEntry::FileSourceLink,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/memberdecl/membergroups",
+ m_sHandler.insert("file/memberdecl/membergroups",
new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("file/memberdecl",
+ m_sHandler.insert("file/memberdecl",
new StartElementHandler(this,&LayoutParser::startMemberDecl));
- m_sHandler.insert("file/memberdecl/interfaces",
+ m_sHandler.insert("file/memberdecl/interfaces",
new StartElementHandlerSection(this,LayoutDocEntry::FileInterfaces,&LayoutParser::startSectionEntry,
theTranslator->trSliceInterfaces()));
- m_sHandler.insert("file/memberdecl/classes",
+ m_sHandler.insert("file/memberdecl/classes",
new StartElementHandlerSection(this,LayoutDocEntry::FileClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_2_OPTIONS(
theTranslator->trCompounds(),
SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE),
SrcLangExt_Fortran,theTranslator->trDataTypes()
)));
- m_sHandler.insert("file/memberdecl/structs",
+ m_sHandler.insert("file/memberdecl/structs",
new StartElementHandlerSection(this,LayoutDocEntry::FileStructs,&LayoutParser::startSectionEntry,
theTranslator->trStructs()));
- m_sHandler.insert("file/memberdecl/exceptions",
+ m_sHandler.insert("file/memberdecl/exceptions",
new StartElementHandlerSection(this,LayoutDocEntry::FileExceptions,&LayoutParser::startSectionEntry,
theTranslator->trExceptions()));
- m_sHandler.insert("file/memberdecl/namespaces",
+ m_sHandler.insert("file/memberdecl/namespaces",
new StartElementHandlerSection(this,LayoutDocEntry::FileNamespaces,&LayoutParser::startSectionEntry,
COMPILE_FOR_4_OPTIONS(
theTranslator->trNamespaces(),
@@ -635,22 +635,22 @@ class LayoutParser : public QXmlDefaultHandler
m_sHandler.insert("file/memberdecl/constantgroups",
new StartElementHandlerSection(this,LayoutDocEntry::FileConstantGroups,&LayoutParser::startSectionEntry,
theTranslator->trConstantGroups()));
- m_sHandler.insert("file/memberdecl/defines",
+ m_sHandler.insert("file/memberdecl/defines",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decDefineMembers,theTranslator->trDefines()));
- m_sHandler.insert("file/memberdecl/typedefs",
+ m_sHandler.insert("file/memberdecl/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
- m_sHandler.insert("file/memberdecl/sequences",
+ m_sHandler.insert("file/memberdecl/sequences",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decSequenceMembers,theTranslator->trSequences()));
- m_sHandler.insert("file/memberdecl/dictionaries",
+ m_sHandler.insert("file/memberdecl/dictionaries",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decDictionaryMembers,theTranslator->trDictionaries()));
- m_sHandler.insert("file/memberdecl/enums",
+ m_sHandler.insert("file/memberdecl/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decEnumMembers,theTranslator->trEnumerations()));
- m_sHandler.insert("file/memberdecl/functions",
+ m_sHandler.insert("file/memberdecl/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decFuncMembers,
COMPILE_FOR_2_OPTIONS(
@@ -658,115 +658,115 @@ class LayoutParser : public QXmlDefaultHandler
SrcLangExt_Fortran,theTranslator->trSubprograms(),
SrcLangExt_VHDL,theTranslator->trFunctionAndProc()
)));
- m_sHandler.insert("file/memberdecl/variables",
+ m_sHandler.insert("file/memberdecl/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decVarMembers,
sliceOpt ? theTranslator->trConstants() : theTranslator->trVariables()));
- m_eHandler.insert("file/memberdecl",
+ m_eHandler.insert("file/memberdecl",
new EndElementHandler(this,&LayoutParser::endMemberDecl));
- m_sHandler.insert("file/memberdef",
+ m_sHandler.insert("file/memberdef",
new StartElementHandler(this,&LayoutParser::startMemberDef));
- m_sHandler.insert("file/memberdef/inlineclasses",
+ m_sHandler.insert("file/memberdef/inlineclasses",
new StartElementHandlerSection(this,LayoutDocEntry::FileInlineClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_1_OPTION(
theTranslator->trClassDocumentation(),
SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
)));
- m_sHandler.insert("file/memberdef/defines",
+ m_sHandler.insert("file/memberdef/defines",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()));
- m_sHandler.insert("file/memberdef/typedefs",
+ m_sHandler.insert("file/memberdef/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
- m_sHandler.insert("file/memberdef/sequences",
+ m_sHandler.insert("file/memberdef/sequences",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()));
- m_sHandler.insert("file/memberdef/dictionaries",
+ m_sHandler.insert("file/memberdef/dictionaries",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docDictionaryMembers,
theTranslator->trDictionaryDocumentation()));
- m_sHandler.insert("file/memberdef/enums",
+ m_sHandler.insert("file/memberdef/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docEnumMembers,
theTranslator->trEnumerationTypeDocumentation()));
- m_sHandler.insert("file/memberdef/functions",
+ m_sHandler.insert("file/memberdef/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docFuncMembers,
COMPILE_FOR_1_OPTION(
theTranslator->trFunctionDocumentation(),
SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
)));
- m_sHandler.insert("file/memberdef/variables",
+ m_sHandler.insert("file/memberdef/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
- m_eHandler.insert("file/memberdef",
+ m_eHandler.insert("file/memberdef",
new EndElementHandler(this,&LayoutParser::endMemberDef));
- m_eHandler.insert("file",
+ m_eHandler.insert("file",
new EndElementHandler(this,&LayoutParser::endFile));
// group layout handlers
- m_sHandler.insert("group",
+ m_sHandler.insert("group",
new StartElementHandler(this,&LayoutParser::startGroup));
- m_sHandler.insert("group/briefdescription",
+ m_sHandler.insert("group/briefdescription",
new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("group/detaileddescription",
+ m_sHandler.insert("group/detaileddescription",
new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
theTranslator->trDetailedDescription()));
- m_sHandler.insert("group/authorsection",
+ m_sHandler.insert("group/authorsection",
new StartElementHandlerKind(this,LayoutDocEntry::AuthorSection,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("group/groupgraph",
+ m_sHandler.insert("group/groupgraph",
new StartElementHandlerKind(this,LayoutDocEntry::GroupGraph,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("group/memberdecl/membergroups",
+ m_sHandler.insert("group/memberdecl/membergroups",
new StartElementHandlerKind(this,LayoutDocEntry::MemberGroups,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("group/memberdecl",
+ m_sHandler.insert("group/memberdecl",
new StartElementHandler(this,&LayoutParser::startMemberDecl));
- m_sHandler.insert("group/memberdecl/classes",
+ m_sHandler.insert("group/memberdecl/classes",
new StartElementHandlerSection(this,LayoutDocEntry::GroupClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_2_OPTIONS(
theTranslator->trCompounds(),
SrcLangExt_VHDL,theTranslator->trVhdlType(VhdlDocGen::ENTITY,FALSE),
SrcLangExt_Fortran,theTranslator->trDataTypes()
)));
- m_sHandler.insert("group/memberdecl/namespaces",
+ m_sHandler.insert("group/memberdecl/namespaces",
new StartElementHandlerSection(this,LayoutDocEntry::GroupNamespaces,&LayoutParser::startSectionEntry,
COMPILE_FOR_2_OPTIONS(
theTranslator->trNamespaces(),
SrcLangExt_Java,theTranslator->trPackages(),
SrcLangExt_Fortran,theTranslator->trModules()
)));
- m_sHandler.insert("group/memberdecl/dirs",
+ m_sHandler.insert("group/memberdecl/dirs",
new StartElementHandlerSection(this,LayoutDocEntry::GroupDirs,&LayoutParser::startSectionEntry,
theTranslator->trDirectories()
));
- m_sHandler.insert("group/memberdecl/nestedgroups",
+ m_sHandler.insert("group/memberdecl/nestedgroups",
new StartElementHandlerSection(this,LayoutDocEntry::GroupNestedGroups,&LayoutParser::startSectionEntry,
theTranslator->trModules()
));
- m_sHandler.insert("group/memberdecl/files",
+ m_sHandler.insert("group/memberdecl/files",
new StartElementHandlerSection(this,LayoutDocEntry::GroupFiles,&LayoutParser::startSectionEntry,
theTranslator->trFile(TRUE,FALSE)
));
- m_sHandler.insert("group/memberdecl/defines",
+ m_sHandler.insert("group/memberdecl/defines",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decDefineMembers,theTranslator->trDefines()));
- m_sHandler.insert("group/memberdecl/typedefs",
+ m_sHandler.insert("group/memberdecl/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decTypedefMembers,theTranslator->trTypedefs()));
- m_sHandler.insert("group/memberdecl/sequences",
+ m_sHandler.insert("group/memberdecl/sequences",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decSequenceMembers,theTranslator->trSequences()));
- m_sHandler.insert("group/memberdecl/dictionaries",
+ m_sHandler.insert("group/memberdecl/dictionaries",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decDictionaryMembers,theTranslator->trDictionaries()));
- m_sHandler.insert("group/memberdecl/enums",
+ m_sHandler.insert("group/memberdecl/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decEnumMembers,theTranslator->trEnumerations()));
- m_sHandler.insert("group/memberdecl/enumvalues",
+ m_sHandler.insert("group/memberdecl/enumvalues",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decEnumValMembers,theTranslator->trEnumerationValues()));
- m_sHandler.insert("group/memberdecl/functions",
+ m_sHandler.insert("group/memberdecl/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decFuncMembers,
COMPILE_FOR_2_OPTIONS(
@@ -774,116 +774,116 @@ class LayoutParser : public QXmlDefaultHandler
SrcLangExt_Fortran,theTranslator->trSubprograms(),
SrcLangExt_VHDL,theTranslator->trFunctionAndProc()
)));
- m_sHandler.insert("group/memberdecl/variables",
+ m_sHandler.insert("group/memberdecl/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decVarMembers,theTranslator->trVariables()));
- m_sHandler.insert("group/memberdecl/signals",
+ m_sHandler.insert("group/memberdecl/signals",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decSignalMembers,theTranslator->trSignals()));
- m_sHandler.insert("group/memberdecl/publicslots",
+ m_sHandler.insert("group/memberdecl/publicslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decPubSlotMembers,theTranslator->trPublicSlots()));
- m_sHandler.insert("group/memberdecl/protectedslots",
+ m_sHandler.insert("group/memberdecl/protectedslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decProSlotMembers,theTranslator->trProtectedSlots()));
- m_sHandler.insert("group/memberdecl/privateslots",
+ m_sHandler.insert("group/memberdecl/privateslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decPriSlotMembers,theTranslator->trPrivateSlots()));
- m_sHandler.insert("group/memberdecl/events",
+ m_sHandler.insert("group/memberdecl/events",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decEventMembers,theTranslator->trEvents()));
- m_sHandler.insert("group/memberdecl/properties",
+ m_sHandler.insert("group/memberdecl/properties",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decPropMembers,theTranslator->trProperties()));
- m_sHandler.insert("group/memberdecl/friends",
+ m_sHandler.insert("group/memberdecl/friends",
new StartElementHandlerMember(this,&LayoutParser::startMemberDeclEntry,
MemberListType_decFriendMembers,theTranslator->trFriends()));
- m_eHandler.insert("group/memberdecl",
+ m_eHandler.insert("group/memberdecl",
new EndElementHandler(this,&LayoutParser::endMemberDecl));
- m_sHandler.insert("group/memberdef",
+ m_sHandler.insert("group/memberdef",
new StartElementHandler(this,&LayoutParser::startMemberDef));
- m_sHandler.insert("group/memberdef/pagedocs",
+ m_sHandler.insert("group/memberdef/pagedocs",
new StartElementHandlerKind(this,LayoutDocEntry::GroupPageDocs,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("group/memberdef/inlineclasses",
+ m_sHandler.insert("group/memberdef/inlineclasses",
new StartElementHandlerSection(this,LayoutDocEntry::GroupInlineClasses,&LayoutParser::startSectionEntry,
COMPILE_FOR_1_OPTION(
theTranslator->trClassDocumentation(),
SrcLangExt_Fortran,theTranslator->trTypeDocumentation()
)));
- m_sHandler.insert("group/memberdef/defines",
+ m_sHandler.insert("group/memberdef/defines",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docDefineMembers,theTranslator->trDefineDocumentation()));
- m_sHandler.insert("group/memberdef/typedefs",
+ m_sHandler.insert("group/memberdef/typedefs",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docTypedefMembers,theTranslator->trTypedefDocumentation()));
- m_sHandler.insert("group/memberdef/sequences",
+ m_sHandler.insert("group/memberdef/sequences",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docSequenceMembers,theTranslator->trSequenceDocumentation()));
- m_sHandler.insert("group/memberdef/dictionaries",
+ m_sHandler.insert("group/memberdef/dictionaries",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docDictionaryMembers,
theTranslator->trDictionaryDocumentation()));
- m_sHandler.insert("group/memberdef/enums",
+ m_sHandler.insert("group/memberdef/enums",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docEnumMembers,theTranslator->trEnumerationTypeDocumentation()));
- m_sHandler.insert("group/memberdef/enumvalues",
+ m_sHandler.insert("group/memberdef/enumvalues",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docEnumValMembers,theTranslator->trEnumerationValueDocumentation()));
- m_sHandler.insert("group/memberdef/functions",
+ m_sHandler.insert("group/memberdef/functions",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docFuncMembers,
COMPILE_FOR_1_OPTION(
theTranslator->trFunctionDocumentation(),
SrcLangExt_Fortran,theTranslator->trSubprogramDocumentation()
)));
- m_sHandler.insert("group/memberdef/variables",
+ m_sHandler.insert("group/memberdef/variables",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docVarMembers,theTranslator->trVariableDocumentation()));
- m_sHandler.insert("group/memberdef/signals",
+ m_sHandler.insert("group/memberdef/signals",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
- MemberListType_docSignalMembers,theTranslator->trSignals()));
- m_sHandler.insert("group/memberdef/publicslots",
+ MemberListType_docSignalMembers,theTranslator->trSignals()));
+ m_sHandler.insert("group/memberdef/publicslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docPubSlotMembers,theTranslator->trPublicSlots()));
- m_sHandler.insert("group/memberdef/protectedslots",
+ m_sHandler.insert("group/memberdef/protectedslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docProSlotMembers,theTranslator->trProtectedSlots()));
- m_sHandler.insert("group/memberdef/privateslots",
+ m_sHandler.insert("group/memberdef/privateslots",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docPriSlotMembers,theTranslator->trPrivateSlots()));
- m_sHandler.insert("group/memberdef/events",
+ m_sHandler.insert("group/memberdef/events",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docEventMembers,theTranslator->trEvents()));
- m_sHandler.insert("group/memberdef/properties",
+ m_sHandler.insert("group/memberdef/properties",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docPropMembers,theTranslator->trProperties()));
- m_sHandler.insert("group/memberdef/friends",
+ m_sHandler.insert("group/memberdef/friends",
new StartElementHandlerMember(this,&LayoutParser::startMemberDefEntry,
MemberListType_docFriendMembers,theTranslator->trFriends()));
- m_eHandler.insert("group/memberdef",
+ m_eHandler.insert("group/memberdef",
new EndElementHandler(this,&LayoutParser::endMemberDef));
- m_eHandler.insert("group",
+ m_eHandler.insert("group",
new EndElementHandler(this,&LayoutParser::endGroup));
// directory layout handlers
- m_sHandler.insert("directory",
+ m_sHandler.insert("directory",
new StartElementHandler(this,&LayoutParser::startDirectory));
- m_sHandler.insert("directory/briefdescription",
+ m_sHandler.insert("directory/briefdescription",
new StartElementHandlerKind(this,LayoutDocEntry::BriefDesc,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("directory/detaileddescription",
+ m_sHandler.insert("directory/detaileddescription",
new StartElementHandlerSection(this,LayoutDocEntry::DetailedDesc,&LayoutParser::startSectionEntry,
theTranslator->trDetailedDescription()));
- m_sHandler.insert("directory/directorygraph",
+ m_sHandler.insert("directory/directorygraph",
new StartElementHandlerKind(this,LayoutDocEntry::DirGraph,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("directory/memberdecl",
+ m_sHandler.insert("directory/memberdecl",
new StartElementHandler(this,&LayoutParser::startMemberDecl));
- m_sHandler.insert("directory/memberdecl/dirs",
+ m_sHandler.insert("directory/memberdecl/dirs",
new StartElementHandlerKind(this,LayoutDocEntry::DirSubDirs,&LayoutParser::startSimpleEntry));
- m_sHandler.insert("directory/memberdecl/files",
+ m_sHandler.insert("directory/memberdecl/files",
new StartElementHandlerKind(this,LayoutDocEntry::DirFiles,&LayoutParser::startSimpleEntry));
- m_eHandler.insert("directory/memberdecl",
+ m_eHandler.insert("directory/memberdecl",
new EndElementHandler(this,&LayoutParser::endMemberDecl));
- m_eHandler.insert("directory",
+ m_eHandler.insert("directory",
new EndElementHandler(this,&LayoutParser::endDirectory));
}
@@ -964,7 +964,7 @@ class LayoutParser : public QXmlDefaultHandler
if (m_rootNav && !m_rootNav->find(LayoutNavEntry::MainPage))
{
// no MainPage node... add one as the first item of the root node...
- new LayoutNavEntry(m_rootNav,LayoutNavEntry::MainPage, TRUE,
+ new LayoutNavEntry(m_rootNav,LayoutNavEntry::MainPage, TRUE,
/*Config_getBool(GENERATE_TREEVIEW) ? "main" :*/ "index",
theTranslator->trMainPage(),"",TRUE);
}
@@ -974,8 +974,8 @@ class LayoutParser : public QXmlDefaultHandler
{
static bool javaOpt = Config_getBool(OPTIMIZE_OUTPUT_JAVA);
static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
- static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
- static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
+ static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
+ static bool sliceOpt = Config_getBool(OPTIMIZE_OUTPUT_SLICE);
static bool hasGraphicalHierarchy = Config_getBool(HAVE_DOT) &&
Config_getBool(GRAPHICAL_HIERARCHY);
static bool extractAll = Config_getBool(EXTRACT_ALL);
@@ -1213,7 +1213,7 @@ class LayoutParser : public QXmlDefaultHandler
}
i++;
}
- if (mapping[i].typeStr==0)
+ if (mapping[i].typeStr==0)
{
if (type.isEmpty())
{
@@ -1230,7 +1230,7 @@ class LayoutParser : public QXmlDefaultHandler
QCString title = attrib.value("title").utf8();
bool isVisible = elemIsVisible(attrib);
if (title.isEmpty()) // use default title
- {
+ {
title = mapping[i].mainName; // use title for main row
if (m_rootNav!=LayoutDocManager::instance().rootNavEntry() && !mapping[i].subName.isEmpty())
{
@@ -1384,7 +1384,7 @@ class LayoutParser : public QXmlDefaultHandler
}
// reimplemented from QXmlDefaultHandler
- bool startElement( const QString&, const QString&,
+ bool startElement( const QString&, const QString&,
const QString& name, const QXmlAttributes& attrib )
{
//printf("startElement [%s]::[%s]\n",m_scope.data(),name.data());
@@ -1568,7 +1568,7 @@ void writeDefaultLayoutFile(const char *fileName)
//----------------------------------------------------------------------------------
// Convert input to a title.
-// The format of input can be a simple title "A title" or in case there are different
+// The format of input can be a simple title "A title" or in case there are different
// titles for some programming languages they can take the following form:
// "A title|16=Another title|8=Yet Another title"
// where the number is a value of SrcLangExt in decimal notation (i.e. 16=Java, 8=IDL).
diff --git a/src/mangen.cpp b/src/mangen.cpp
index 6709748..1faa296 100644
--- a/src/mangen.cpp
+++ b/src/mangen.cpp
@@ -1,12 +1,12 @@
/******************************************************************************
*
- *
+ *
*
* 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
+ * 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.
*
@@ -41,7 +41,7 @@ static QCString getExtension()
QCString ext = Config_getString(MAN_EXTENSION);
if (ext.isEmpty())
{
- ext = "3";
+ ext = "3";
}
else
{
@@ -49,7 +49,7 @@ static QCString getExtension()
{
if (ext.length()==1)
{
- ext = "3";
+ ext = "3";
}
else // strip .
{
@@ -91,8 +91,8 @@ ManGenerator::~ManGenerator()
void ManGenerator::init()
{
- QCString &manOutput = Config_getString(MAN_OUTPUT);
-
+ QCString manOutput = Config_getString(MAN_OUTPUT);
+
QDir d(manOutput);
if (!d.exists() && !d.mkdir(manOutput))
{
@@ -139,7 +139,7 @@ static QCString buildFileName(const char *name)
}
QCString manExtension = "." + getExtension();
- if (fileName.right(manExtension.length())!=manExtension)
+ if (fileName.right(manExtension.length())!=manExtension)
{
fileName+=manExtension;
}
@@ -161,11 +161,11 @@ void ManGenerator::endFile()
void ManGenerator::endTitleHead(const char *,const char *name)
{
- t << ".TH \"" << name << "\" " << getExtension() << " \""
+ t << ".TH \"" << name << "\" " << getExtension() << " \""
<< dateToString(FALSE) << "\" \"";
if (!Config_getString(PROJECT_NUMBER).isEmpty())
t << "Version " << Config_getString(PROJECT_NUMBER) << "\" \"";
- if (Config_getString(PROJECT_NAME).isEmpty())
+ if (Config_getString(PROJECT_NAME).isEmpty())
t << "Doxygen";
else
t << Config_getString(PROJECT_NAME);
@@ -284,7 +284,7 @@ void ManGenerator::docify(const char *str)
{
const char *p=str;
char c=0;
- while ((c=*p++))
+ while ((c=*p++))
{
switch(c)
{
@@ -318,8 +318,8 @@ void ManGenerator::codify(const char *str)
case '.': t << "\\&."; break; // see bug652277
case '\t': spacesToNextTabStop =
Config_getInt(TAB_SIZE) - (m_col%Config_getInt(TAB_SIZE));
- t << Doxygen::spaces.left(spacesToNextTabStop);
- m_col+=spacesToNextTabStop;
+ t << Doxygen::spaces.left(spacesToNextTabStop);
+ m_col+=spacesToNextTabStop;
break;
case '\n': t << "\n"; m_firstCol=TRUE; m_col=0; break;
case '\\': t << "\\"; m_col++; break;
@@ -346,21 +346,21 @@ void ManGenerator::writeChar(char c)
m_paragraph=FALSE;
}
-void ManGenerator::startDescList(SectionTypes)
+void ManGenerator::startDescList(SectionTypes)
{
- if (!m_firstCol)
- { t << endl << ".PP" << endl;
- m_firstCol=TRUE; m_paragraph=TRUE;
+ if (!m_firstCol)
+ { t << endl << ".PP" << endl;
+ m_firstCol=TRUE; m_paragraph=TRUE;
m_col=0;
}
m_paragraph=FALSE;
startBold();
}
-void ManGenerator::startTitle()
-{
- if (!m_firstCol) t << endl;
- t << ".SH \"";
+void ManGenerator::startTitle()
+{
+ if (!m_firstCol) t << endl;
+ t << ".SH \"";
m_firstCol=FALSE;
m_paragraph=FALSE;
}
@@ -370,40 +370,40 @@ void ManGenerator::endTitle()
t << "\"";
}
-void ManGenerator::startItemListItem()
-{
- if (!m_firstCol) t << endl;
- t << ".TP" << endl;
+void ManGenerator::startItemListItem()
+{
+ if (!m_firstCol) t << endl;
+ t << ".TP" << endl;
m_firstCol=TRUE;
m_paragraph=FALSE;
m_col=0;
-}
+}
void ManGenerator::endItemListItem()
{
}
-void ManGenerator::startCodeFragment()
-{
+void ManGenerator::startCodeFragment()
+{
newParagraph();
- t << ".nf" << endl;
+ t << ".nf" << endl;
m_firstCol=TRUE;
m_paragraph=FALSE;
}
-void ManGenerator::endCodeFragment()
-{
+void ManGenerator::endCodeFragment()
+{
if (!m_firstCol) t << endl;
- t << ".fi" << endl;
+ t << ".fi" << endl;
m_firstCol=TRUE;
m_paragraph=FALSE;
m_col=0;
}
-void ManGenerator::startMemberDoc(const char *,const char *,const char *,const char *,int,int,bool)
-{
+void ManGenerator::startMemberDoc(const char *,const char *,const char *,const char *,int,int,bool)
+{
if (!m_firstCol) t << endl;
- t << ".SS \"";
+ t << ".SS \"";
m_firstCol=FALSE;
m_paragraph=FALSE;
}
@@ -413,7 +413,7 @@ void ManGenerator::startDoxyAnchor(const char *,const char *manName,
const char *)
{
// something to be done?
- if( !Config_getBool(MAN_LINKS) )
+ if( !Config_getBool(MAN_LINKS) )
{
return; // no
}
@@ -426,14 +426,14 @@ void ManGenerator::startDoxyAnchor(const char *,const char *manName,
//printf("Converting man link '%s'->'%s'->'%s'\n",
// name,baseName.data(),buildFileName(baseName).data());
-
+
// - remove dangerous characters and append suffix, then add dir prefix
QCString fileName=m_dir+"/"+buildFileName( baseName );
QFile linkfile( fileName );
// - only create file if it doesn't exist already
- if ( !linkfile.open( IO_ReadOnly ) )
+ if ( !linkfile.open( IO_ReadOnly ) )
{
- if ( linkfile.open( IO_WriteOnly ) )
+ if ( linkfile.open( IO_WriteOnly ) )
{
FTextStream linkstream;
linkstream.setDevice(&linkfile);
@@ -449,10 +449,10 @@ void ManGenerator::endMemberDoc(bool)
t << "\"\n";
}
-void ManGenerator::startSubsection()
-{
+void ManGenerator::startSubsection()
+{
if (!m_firstCol) t << endl;
- t << ".SS \"";
+ t << ".SS \"";
m_firstCol=FALSE;
m_paragraph=FALSE;
}
@@ -463,10 +463,10 @@ void ManGenerator::endSubsection()
}
-void ManGenerator::startSubsubsection()
-{
+void ManGenerator::startSubsubsection()
+{
if (!m_firstCol) t << endl;
- t << "\n.SS \"";
+ t << "\n.SS \"";
m_firstCol=FALSE;
m_paragraph=FALSE;
}
@@ -476,10 +476,10 @@ void ManGenerator::endSubsubsection()
t << "\"";
}
-void ManGenerator::writeSynopsis()
-{
+void ManGenerator::writeSynopsis()
+{
if (!m_firstCol) t << endl;
- t << ".SH SYNOPSIS\n.br\n.PP\n";
+ t << ".SH SYNOPSIS\n.br\n.PP\n";
m_firstCol=TRUE;
m_paragraph=FALSE;
}
@@ -534,31 +534,31 @@ void ManGenerator::endAnonTypeScope(int indentLevel)
}
-void ManGenerator::startMemberItem(const char *,int,const char *)
-{
+void ManGenerator::startMemberItem(const char *,int,const char *)
+{
if (m_firstCol && !m_insideTabbing) t << ".in +1c\n";
- t << "\n.ti -1c\n.RI \"";
+ t << "\n.ti -1c\n.RI \"";
m_firstCol=FALSE;
}
-void ManGenerator::endMemberItem()
-{
- t << "\"\n.br";
+void ManGenerator::endMemberItem()
+{
+ t << "\"\n.br";
}
-void ManGenerator::startMemberList()
-{
+void ManGenerator::startMemberList()
+{
if (!m_insideTabbing)
{
- t << "\n.in +1c"; m_firstCol=FALSE;
+ t << "\n.in +1c"; m_firstCol=FALSE;
}
}
-void ManGenerator::endMemberList()
-{
+void ManGenerator::endMemberList()
+{
if (!m_insideTabbing)
{
- t << "\n.in -1c"; m_firstCol=FALSE;
+ t << "\n.in -1c"; m_firstCol=FALSE;
}
}
@@ -595,7 +595,7 @@ void ManGenerator::endMemberGroup(bool)
void ManGenerator::startSection(const char *,const char *,SectionType type)
{
- if( !m_inHeader )
+ if( !m_inHeader )
{
switch(type)
{
@@ -634,9 +634,9 @@ void ManGenerator::endSection(const char *,SectionType type)
void ManGenerator::startExamples()
{
- if (!m_firstCol)
- { t << endl << ".PP" << endl;
- m_firstCol=TRUE; m_paragraph=TRUE;
+ if (!m_firstCol)
+ { t << endl << ".PP" << endl;
+ m_firstCol=TRUE; m_paragraph=TRUE;
m_col=0;
}
m_paragraph=FALSE;
@@ -652,9 +652,9 @@ void ManGenerator::endExamples()
void ManGenerator::startDescTable(const char *title)
{
- if (!m_firstCol)
- { t << endl << ".PP" << endl;
- m_firstCol=TRUE; m_paragraph=TRUE;
+ if (!m_firstCol)
+ { t << endl << ".PP" << endl;
+ m_firstCol=TRUE; m_paragraph=TRUE;
m_col=0;
}
m_paragraph=FALSE;
@@ -672,9 +672,9 @@ void ManGenerator::endDescTable()
void ManGenerator::startParamList(ParamListTypes,const char *title)
{
- if (!m_firstCol)
- { t << endl << ".PP" << endl;
- m_firstCol=TRUE; m_paragraph=TRUE;
+ if (!m_firstCol)
+ { t << endl << ".PP" << endl;
+ m_firstCol=TRUE; m_paragraph=TRUE;
m_col=0;
}
m_paragraph=FALSE;
@@ -692,16 +692,16 @@ void ManGenerator::writeDoc(DocNode *n,const Definition *ctx,const MemberDef *)
{
ManDocVisitor *visitor = new ManDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""));
n->accept(visitor);
- delete visitor;
+ delete visitor;
m_firstCol=FALSE;
m_paragraph = FALSE;
}
void ManGenerator::startConstraintList(const char *header)
{
- if (!m_firstCol)
- { t << endl << ".PP" << endl;
- m_firstCol=TRUE; m_paragraph=TRUE;
+ if (!m_firstCol)
+ { t << endl << ".PP" << endl;
+ m_firstCol=TRUE; m_paragraph=TRUE;
m_col=0;
}
m_paragraph=FALSE;
@@ -748,16 +748,16 @@ void ManGenerator::endConstraintList()
}
-void ManGenerator::startInlineHeader()
+void ManGenerator::startInlineHeader()
{
- if (!m_firstCol)
+ if (!m_firstCol)
{
t << endl << ".PP" << endl << ".in -1c" << endl;
}
- t << ".RI \"\\fB";
+ t << ".RI \"\\fB";
}
-void ManGenerator::endInlineHeader()
+void ManGenerator::endInlineHeader()
{
t << "\\fP\"" << endl << ".in +1c" << endl;
m_firstCol = FALSE;
@@ -765,7 +765,7 @@ void ManGenerator::endInlineHeader()
void ManGenerator::startMemberDocSimple(bool isEnum)
{
- if (!m_firstCol)
+ if (!m_firstCol)
{
t << endl << ".PP" << endl;
}
diff --git a/src/markdown.cpp b/src/markdown.cpp
index c4dd9fb..2863669 100644
--- a/src/markdown.cpp
+++ b/src/markdown.cpp
@@ -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
@@ -35,11 +35,9 @@
#include <qglobal.h>
#include <qregexp.h>
#include <qfileinfo.h>
-#include <qdict.h>
-#include <qvector.h>
-//#define USE_ORIGINAL_TABLES
-#include <atomic>
+#include <unordered_map>
+#include <functional>
#include "markdown.h"
#include "growbuf.h"
@@ -48,13 +46,96 @@
#include "doxygen.h"
#include "commentscan.h"
#include "entry.h"
-#include "bufstr.h"
#include "commentcnv.h"
#include "config.h"
#include "section.h"
#include "message.h"
#include "portable.h"
+#if !defined(NDEBUG)
+#define ENABLE_TRACING
+#endif
+
+#ifdef ENABLE_TRACING
+#define IOSTREAM stdout
+#define DATA_BUFSIZE 20
+#if defined(_WIN32) && !defined(CYGWIN)
+#define PRETTY_FUNC __FUNCSIG__
+#else
+#define PRETTY_FUNC __PRETTY_FUNCTION__
+#endif
+
+class Trace
+{
+ public:
+ Trace(const char *func) : m_func(func)
+ {
+ if (Debug::isFlagSet(Debug::Markdown))
+ {
+ fprintf(IOSTREAM,"> %s\n",func);
+ s_indent++;
+ }
+ }
+ Trace(const char *func,const char *data) : m_func(func)
+ {
+ if (Debug::isFlagSet(Debug::Markdown))
+ {
+ indent();
+ char data_s[DATA_BUFSIZE*2+1] = ""; // worst case each input char outputs 2 chars + 0 terminator.
+ int j=0;
+ if (data)
+ {
+ for (int i=0;i<DATA_BUFSIZE;i++)
+ {
+ char c=data[i];
+ if (c==0) break;
+ else if (c=='\n') { data_s[j++]='\\'; data_s[j++]='n'; }
+ else if (c=='\t') { data_s[j++]='\\'; data_s[j++]='t'; }
+ else if (c=='\r') { data_s[j++]='\\'; data_s[j++]='r'; }
+ else if (c=='\\') { data_s[j++]='\\'; data_s[j++]='\\'; }
+ else data_s[j++]=c;
+ }
+ }
+ data_s[j++]=0;
+ fprintf(IOSTREAM,"> %s data=[%s…]\n",func,data_s);
+ s_indent++;
+ }
+ }
+ ~Trace()
+ {
+ if (Debug::isFlagSet(Debug::Markdown))
+ {
+ s_indent--;
+ indent();
+ fprintf(IOSTREAM,"< %s\n",m_func);
+ }
+ }
+ void trace(const char *fmt,...)
+ {
+ if (Debug::isFlagSet(Debug::Markdown))
+ {
+ indent();
+ fprintf(IOSTREAM,": %s: ",m_func);
+ va_list args;
+ va_start(args,fmt);
+ vfprintf(IOSTREAM, fmt, args);
+ va_end(args);
+ }
+ }
+ private:
+ void indent() { for (int i=0;i<s_indent;i++) fputs(" ",IOSTREAM); }
+ const char *m_func;
+ static int s_indent;
+};
+
+int Trace::s_indent = 0;
+#define TRACE(data) Trace trace_(PRETTY_FUNC,data);
+#define TRACE_MORE(...) trace_.trace(__VA_ARGS__);
+#else
+#define TRACE(data) do {} while(false)
+#define TRACE_MORE(...) do {} while(false)
+#endif
+
//-----------
// is character at position i in data part of an identifier?
@@ -84,13 +165,6 @@
//----------
-struct LinkRef
-{
- LinkRef(const QCString &l,const QCString &t) : link(l), title(t) {}
- QCString link;
- QCString title;
-};
-
struct TableCell
{
TableCell() : colSpan(false) {}
@@ -98,30 +172,51 @@ struct TableCell
bool colSpan;
};
-typedef int (*action_t)(GrowBuf &out,const char *data,int offset,int size);
+Markdown::Markdown(const char *fileName,int lineNr,int indentLevel)
+ : m_fileName(fileName), m_lineNr(lineNr), m_indentLevel(indentLevel)
+{
+ using namespace std::placeholders;
+ // setup callback table for special characters
+ m_actions[(unsigned int)'_'] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3);
+ m_actions[(unsigned int)'*'] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3);
+ m_actions[(unsigned int)'~'] = std::bind(&Markdown::processEmphasis, this,_1,_2,_3);
+ m_actions[(unsigned int)'`'] = std::bind(&Markdown::processCodeSpan, this,_1,_2,_3);
+ m_actions[(unsigned int)'\\']= std::bind(&Markdown::processSpecialCommand,this,_1,_2,_3);
+ m_actions[(unsigned int)'@'] = std::bind(&Markdown::processSpecialCommand,this,_1,_2,_3);
+ m_actions[(unsigned int)'['] = std::bind(&Markdown::processLink, this,_1,_2,_3);
+ m_actions[(unsigned int)'!'] = std::bind(&Markdown::processLink, this,_1,_2,_3);
+ m_actions[(unsigned int)'<'] = std::bind(&Markdown::processHtmlTag, this,_1,_2,_3);
+ m_actions[(unsigned int)'-'] = std::bind(&Markdown::processNmdash, this,_1,_2,_3);
+ m_actions[(unsigned int)'"'] = std::bind(&Markdown::processQuoted, this,_1,_2,_3);
+ (void)m_lineNr; // not used yet
+}
enum Alignment { AlignNone, AlignLeft, AlignCenter, AlignRight };
-//----------
-
-static QDict<LinkRef> g_linkRefs(257);
-static action_t g_actions[256];
-static Entry *g_current;
-static QCString g_fileName;
-static int g_lineNr;
-static int g_indentLevel=0; // 0 is outside markdown, -1=page level
-static const uchar g_utf8_nbsp[3] = { 0xc2, 0xa0, 0}; // UTF-8 nbsp
-static const char *g_doxy_nsbp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
-//----------
-
+//---------- contants -------
+//
+const uchar g_utf8_nbsp[3] = { 0xc2, 0xa0, 0}; // UTF-8 nbsp
+const char *g_doxy_nsbp = "&_doxy_nbsp;"; // doxygen escape command for UTF-8 nbsp
const int codeBlockIndent = 4;
-static void processInline(GrowBuf &out,const char *data,int size);
+//---------- helpers -------
+
+// test if the next characters in data represent a new line (which can be character \n or string \ilinebr).
+// returns 0 if no newline is found, or the number of characters that make up the newline if found.
+inline int isNewline(const char *data)
+{
+ // normal newline
+ if (data[0] == '\n') return 1;
+ // artificial new line from ^^ in ALIASES
+ if (data[0] == '\\' && qstrncmp(data+1,"ilinebr",7)==0) return 8;
+ return 0;
+}
// escape characters that have a special meaning later on.
static QCString escapeSpecialChars(const QCString &s)
{
+ TRACE(s.data());
if (s.isEmpty()) return "";
bool insideQuote=FALSE;
GrowBuf growBuf;
@@ -147,6 +242,7 @@ static QCString escapeSpecialChars(const QCString &s)
static void convertStringFragment(QCString &result,const char *data,int size)
{
+ TRACE(result.data());
if (size<0) size=0;
result.resize(size+1);
memcpy(result.rawData(),data,size);
@@ -196,8 +292,9 @@ static Alignment markersToAlignment(bool leftMarker,bool rightMarker)
// \xmlonly..\endxmlonly
// \rtfonly..\endrtfonly
// \manonly..\endmanonly
-static QCString isBlockCommand(const char *data,int offset,int size)
+QCString Markdown::isBlockCommand(const char *data,int offset,int size)
{
+ TRACE(data);
bool openBracket = offset>0 && data[-1]=='{';
bool isEscaped = offset>0 && (data[-1]=='\\' || data[-1]=='@');
if (isEscaped) return QCString();
@@ -250,8 +347,9 @@ static QCString isBlockCommand(const char *data,int offset,int size)
/** looks for the next emph char, skipping other constructs, and
* stopping when either it is found, or we are at the end of a paragraph.
*/
-static int findEmphasisChar(const char *data, int size, char c, int c_size)
+int Markdown::findEmphasisChar(const char *data, int size, char c, int c_size)
{
+ TRACE(data);
int i = 1;
while (i<size)
@@ -348,8 +446,9 @@ static int findEmphasisChar(const char *data, int size, char c, int c_size)
}
/** process single emphasis */
-static int processEmphasis1(GrowBuf &out, const char *data, int size, char c)
+int Markdown::processEmphasis1(const char *data, int size, char c)
{
+ TRACE(data);
int i = 0, len;
/* skipping one symbol if coming from emph3 */
@@ -369,9 +468,9 @@ static int processEmphasis1(GrowBuf &out, const char *data, int size, char c)
}
if (data[i]==c && data[i-1]!=' ' && data[i-1]!='\n')
{
- out.addStr("<em>");
- processInline(out,data,i);
- out.addStr("</em>");
+ m_out.addStr("<em>");
+ processInline(data,i);
+ m_out.addStr("</em>");
return i+1;
}
}
@@ -379,8 +478,9 @@ static int processEmphasis1(GrowBuf &out, const char *data, int size, char c)
}
/** process double emphasis */
-static int processEmphasis2(GrowBuf &out, const char *data, int size, char c)
+int Markdown::processEmphasis2(const char *data, int size, char c)
{
+ TRACE(data);
int i = 0, len;
while (i<size)
@@ -395,11 +495,11 @@ static int processEmphasis2(GrowBuf &out, const char *data, int size, char c)
data[i-1]!='\n'
)
{
- if (c == '~') out.addStr("<strike>");
- else out.addStr("<strong>");
- processInline(out,data,i);
- if (c == '~') out.addStr("</strike>");
- else out.addStr("</strong>");
+ if (c == '~') m_out.addStr("<strike>");
+ else m_out.addStr("<strong>");
+ processInline(data,i);
+ if (c == '~') m_out.addStr("</strike>");
+ else m_out.addStr("</strong>");
return i + 2;
}
i++;
@@ -410,8 +510,9 @@ static int processEmphasis2(GrowBuf &out, const char *data, int size, char c)
/** Parsing triple emphasis.
* Finds the first closing tag, and delegates to the other emph
*/
-static int processEmphasis3(GrowBuf &out, const char *data, int size, char c)
+int Markdown::processEmphasis3(const char *data, int size, char c)
{
+ TRACE(data);
int i = 0, len;
while (i<size)
@@ -431,15 +532,15 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c)
if (i+2<size && data[i+1]==c && data[i+2]==c)
{
- out.addStr("<em><strong>");
- processInline(out,data,i);
- out.addStr("</strong></em>");
+ m_out.addStr("<em><strong>");
+ processInline(data,i);
+ m_out.addStr("</strong></em>");
return i+3;
}
else if (i+1<size && data[i+1]==c)
{
// double symbol found, handing over to emph1
- len = processEmphasis1(out, data-2, size+2, c);
+ len = processEmphasis1(data-2, size+2, c);
if (len==0)
{
return 0;
@@ -452,7 +553,7 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c)
else
{
// single symbol found, handing over to emph2
- len = processEmphasis2(out, data-1, size+1, c);
+ len = processEmphasis2(data-1, size+1, c);
if (len==0)
{
return 0;
@@ -467,8 +568,9 @@ static int processEmphasis3(GrowBuf &out, const char *data, int size, char c)
}
/** Process ndash and mdashes */
-static int processNmdash(GrowBuf &out,const char *data,int off,int size)
+int Markdown::processNmdash(const char *data,int off,int size)
{
+ TRACE(data);
// precondition: data[0]=='-'
int i=1;
int count=1;
@@ -488,12 +590,12 @@ static int processNmdash(GrowBuf &out,const char *data,int off,int size)
if (count==2 && (data[2]=='>')) return 0; // end HTML comment
if (count==2 && (off<8 || qstrncmp(data-8,"operator",8)!=0)) // -- => ndash
{
- out.addStr("&ndash;");
+ m_out.addStr("&ndash;");
return 2;
}
else if (count==3) // --- => ndash
{
- out.addStr("&mdash;");
+ m_out.addStr("&mdash;");
return 3;
}
// not an ndash or mdash
@@ -501,8 +603,9 @@ static int processNmdash(GrowBuf &out,const char *data,int off,int size)
}
/** Process quoted section "...", can contain one embedded newline */
-static int processQuoted(GrowBuf &out,const char *data,int,int size)
+int Markdown::processQuoted(const char *data,int,int size)
{
+ TRACE(data);
int i=1;
int nl=0;
while (i<size && data[i]!='"' && nl<2)
@@ -512,7 +615,7 @@ static int processQuoted(GrowBuf &out,const char *data,int,int size)
}
if (i<size && data[i]=='"' && nl<2)
{
- out.addStr(data,i+1);
+ m_out.addStr(data,i+1);
return i+1;
}
// not a quoted section
@@ -522,8 +625,9 @@ static int processQuoted(GrowBuf &out,const char *data,int,int size)
/** Process a HTML tag. Note that <pre>..</pre> are treated specially, in
* the sense that all code inside is written unprocessed
*/
-static int processHtmlTagWrite(GrowBuf &out,const char *data,int offset,int size,bool doWrite)
+int Markdown::processHtmlTagWrite(const char *data,int offset,int size,bool doWrite)
{
+ TRACE(data);
if (offset>0 && data[-1]=='\\') return 0; // escaped <
// find the end of the html tag
@@ -545,7 +649,7 @@ static int processHtmlTagWrite(GrowBuf &out,const char *data,int offset,int size
tolower(data[i+2])=='p' && tolower(data[i+3])=='r' &&
tolower(data[i+4])=='e' && tolower(data[i+5])=='>')
{ // found </pre> tag, copy from start to end of tag
- if (doWrite) out.addStr(data,i+6);
+ if (doWrite) m_out.addStr(data,i+6);
//printf("found <pre>..</pre> [%d..%d]\n",0,i+6);
return i+6;
}
@@ -568,13 +672,13 @@ static int processHtmlTagWrite(GrowBuf &out,const char *data,int offset,int size
if (data[i]=='/' && i<size-1 && data[i+1]=='>') // <bla/>
{
//printf("Found htmlTag={%s}\n",QCString(data).left(i+2).data());
- if (doWrite) out.addStr(data,i+2);
+ if (doWrite) m_out.addStr(data,i+2);
return i+2;
}
else if (data[i]=='>') // <bla>
{
//printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
- if (doWrite) out.addStr(data,i+1);
+ if (doWrite) m_out.addStr(data,i+1);
return i+1;
}
else if (data[i]==' ') // <bla attr=...
@@ -594,7 +698,7 @@ static int processHtmlTagWrite(GrowBuf &out,const char *data,int offset,int size
else if (!insideAttr && data[i]=='>') // found end of tag
{
//printf("Found htmlTag={%s}\n",QCString(data).left(i+1).data());
- if (doWrite) out.addStr(data,i+1);
+ if (doWrite) m_out.addStr(data,i+1);
return i+1;
}
i++;
@@ -605,13 +709,16 @@ static int processHtmlTagWrite(GrowBuf &out,const char *data,int offset,int size
//printf("Not a valid html tag\n");
return 0;
}
-static int processHtmlTag(GrowBuf &out,const char *data,int offset,int size)
+
+int Markdown::processHtmlTag(const char *data,int offset,int size)
{
- return processHtmlTagWrite(out,data,offset,size,true);
+ TRACE(data);
+ return processHtmlTagWrite(data,offset,size,true);
}
-static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
+int Markdown::processEmphasis(const char *data,int offset,int size)
{
+ TRACE(data);
if ((offset>0 && !isOpenEmphChar(-1)) || // invalid char before * or _
(size>1 && data[0]!=data[1] && !(isIdChar(1) || extraChar(1) || data[1]=='[')) || // invalid char after * or _
(size>2 && data[0]==data[1] && !(isIdChar(2) || extraChar(2) || data[2]=='['))) // invalid char after ** or __
@@ -625,7 +732,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
{
// whitespace cannot follow an opening emphasis
if (data[1]==' ' || data[1]=='\n' ||
- (ret = processEmphasis1(out, data+1, size-1, c)) == 0)
+ (ret = processEmphasis1(data+1, size-1, c)) == 0)
{
return 0;
}
@@ -634,7 +741,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
if (size>3 && data[1]==c && data[2]!=c) // __bla or **bla
{
if (data[2]==' ' || data[2]=='\n' ||
- (ret = processEmphasis2(out, data+2, size-2, c)) == 0)
+ (ret = processEmphasis2(data+2, size-2, c)) == 0)
{
return 0;
}
@@ -643,7 +750,7 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
if (size>4 && c!='~' && data[1]==c && data[2]==c && data[3]!=c) // ___bla or ***bla
{
if (data[3]==' ' || data[3]=='\n' ||
- (ret = processEmphasis3(out, data+3, size-3, c)) == 0)
+ (ret = processEmphasis3(data+3, size-3, c)) == 0)
{
return 0;
}
@@ -652,29 +759,32 @@ static int processEmphasis(GrowBuf &out,const char *data,int offset,int size)
return 0;
}
-static void writeMarkdownImage(GrowBuf &out, const char *fmt, bool explicitTitle, QCString title, QCString content, QCString link, FileDef *fd)
+void Markdown::writeMarkdownImage(const char *fmt, bool explicitTitle,
+ const QCString &title, const QCString &content,
+ const QCString &link, const FileDef *fd)
{
- out.addStr("@image{inline} ");
- out.addStr(fmt);
- out.addStr(" ");
- out.addStr(link.mid(fd ? 0 : 5));
+ m_out.addStr("@image{inline} ");
+ m_out.addStr(fmt);
+ m_out.addStr(" ");
+ m_out.addStr(link.mid(fd ? 0 : 5));
if (!explicitTitle && !content.isEmpty())
{
- out.addStr(" \"");
- out.addStr(content);
- out.addStr("\"");
+ m_out.addStr(" \"");
+ m_out.addStr(content);
+ m_out.addStr("\"");
}
else if ((content.isEmpty() || explicitTitle) && !title.isEmpty())
{
- out.addStr(" \"");
- out.addStr(title);
- out.addStr("\"");
+ m_out.addStr(" \"");
+ m_out.addStr(title);
+ m_out.addStr("\"");
}
- out.addStr("\n");
+ m_out.addStr("\n");
}
-static int processLink(GrowBuf &out,const char *data,int,int size)
+int Markdown::processLink(const char *data,int,int size)
{
+ TRACE(data);
QCString content;
QCString link;
QCString title;
@@ -828,11 +938,12 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
link=content;
}
// lookup reference
- LinkRef *lr = g_linkRefs.find(link.lower());
- if (lr) // found it
+ QCString link_lower = link.lower();
+ auto lr_it=m_linkRefs.find(link_lower.str());
+ if (lr_it!=m_linkRefs.end()) // found it
{
- link = lr->link;
- title = lr->title;
+ link = lr_it->second.link;
+ title = lr_it->second.title;
//printf("processLink: ref: link={%s} title={%s}\n",link.data(),title.data());
}
else // reference not found!
@@ -844,12 +955,13 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
}
else if (i<size && data[i]!=':' && !content.isEmpty()) // minimal link ref notation [some id]
{
- LinkRef *lr = g_linkRefs.find(content.lower());
+ QCString content_lower = content.lower();
+ auto lr_it = m_linkRefs.find(content_lower.str());
//printf("processLink: minimal link {%s} lr=%p",content.data(),lr);
- if (lr) // found it
+ if (lr_it!=m_linkRefs.end()) // found it
{
- link = lr->link;
- title = lr->title;
+ link = lr_it->second.link;
+ title = lr_it->second.title;
explicitTitle=TRUE;
i=contentEnd;
}
@@ -873,9 +985,9 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
int toc_level = Config_getInt(TOC_INCLUDE_HEADINGS);
if (toc_level > 0 && toc_level <=5)
{
- out.addStr("@tableofcontents{html:");
- out.addStr(QCString().setNum(toc_level));
- out.addStr("}");
+ m_out.addStr("@tableofcontents{html:");
+ m_out.addStr(QCString().setNum(toc_level));
+ m_out.addStr("}");
}
}
else if (isImageLink)
@@ -886,25 +998,25 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
(fd=findFileDef(Doxygen::imageNameLinkedMap,link,ambig)))
// assume doxygen symbol link or local image link
{
- writeMarkdownImage(out, "html", explicitTitle, title, content, link, fd);
- writeMarkdownImage(out, "latex", explicitTitle, title, content, link, fd);
- writeMarkdownImage(out, "rtf", explicitTitle, title, content, link, fd);
- writeMarkdownImage(out, "docbook", explicitTitle, title, content, link, fd);
+ writeMarkdownImage("html", explicitTitle, title, content, link, fd);
+ writeMarkdownImage("latex", explicitTitle, title, content, link, fd);
+ writeMarkdownImage("rtf", explicitTitle, title, content, link, fd);
+ writeMarkdownImage("docbook", explicitTitle, title, content, link, fd);
}
else
{
- out.addStr("<img src=\"");
- out.addStr(link);
- out.addStr("\" alt=\"");
- out.addStr(content);
- out.addStr("\"");
+ m_out.addStr("<img src=\"");
+ m_out.addStr(link);
+ m_out.addStr("\" alt=\"");
+ m_out.addStr(content);
+ m_out.addStr("\"");
if (!title.isEmpty())
{
- out.addStr(" title=\"");
- out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;"));
- out.addStr("\"");
+ m_out.addStr(" title=\"");
+ m_out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;"));
+ m_out.addStr("\"");
}
- out.addStr("/>");
+ m_out.addStr("/>");
}
}
else
@@ -916,14 +1028,14 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
{
if (lp==-1) // link to markdown page
{
- out.addStr("@ref ");
+ m_out.addStr("@ref ");
if (!(Portable::isAbsolutePath(link) || isURL(link)))
{
QFileInfo forg(link);
if (!(forg.exists() && forg.isReadable()))
{
- QFileInfo fi(g_fileName);
- QCString mdFile = g_fileName.left(g_fileName.length()-fi.fileName().length()) + link;
+ QFileInfo fi(m_fileName);
+ QCString mdFile = m_fileName.left(m_fileName.length()-fi.fileName().length()) + link;
QFileInfo fmd(mdFile);
if (fmd.exists() && fmd.isReadable())
{
@@ -932,33 +1044,33 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
}
}
}
- out.addStr(link);
- out.addStr(" \"");
+ m_out.addStr(link);
+ m_out.addStr(" \"");
if (explicitTitle && !title.isEmpty())
{
- out.addStr(title);
+ m_out.addStr(title);
}
else
{
- out.addStr(content);
+ m_out.addStr(content);
}
- out.addStr("\"");
+ m_out.addStr("\"");
}
else if (link.find('/')!=-1 || link.find('.')!=-1 || link.find('#')!=-1)
{ // file/url link
- out.addStr("<a href=\"");
- out.addStr(link);
- out.addStr("\"");
+ m_out.addStr("<a href=\"");
+ m_out.addStr(link);
+ m_out.addStr("\"");
if (!title.isEmpty())
{
- out.addStr(" title=\"");
- out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;"));
- out.addStr("\"");
+ m_out.addStr(" title=\"");
+ m_out.addStr(substitute(title.simplifyWhiteSpace(),"\"","&quot;"));
+ m_out.addStr("\"");
}
- out.addStr(">");
+ m_out.addStr(">");
content = content.simplifyWhiteSpace();
- processInline(out,content,content.length());
- out.addStr("</a>");
+ processInline(content,content.length());
+ m_out.addStr("</a>");
}
else // avoid link to e.g. F[x](y)
{
@@ -970,8 +1082,9 @@ static int processLink(GrowBuf &out,const char *data,int,int size)
}
/** '`' parsing a code span (assuming codespan != 0) */
-static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int size)
+int Markdown::processCodeSpan(const char *data, int /*offset*/, int size)
{
+ TRACE(data);
int end, nb = 0, i, f_begin, f_end;
/* counting the number of backticks in the delimiter */
@@ -998,9 +1111,9 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s
{ // look for quoted strings like 'some word', but skip strings like `it's cool`
QCString textFragment;
convertStringFragment(textFragment,data+nb,end-nb);
- out.addStr("&lsquo;");
- out.addStr(textFragment);
- out.addStr("&rsquo;");
+ m_out.addStr("&lsquo;");
+ m_out.addStr(textFragment);
+ m_out.addStr("&rsquo;");
return end+1;
}
else
@@ -1036,32 +1149,35 @@ static int processCodeSpan(GrowBuf &out, const char *data, int /*offset*/, int s
{
QCString codeFragment;
convertStringFragment(codeFragment,data+f_begin,f_end-f_begin);
- out.addStr("<tt>");
- //out.addStr(convertToHtml(codeFragment,TRUE));
- out.addStr(escapeSpecialChars(codeFragment));
- out.addStr("</tt>");
+ m_out.addStr("<tt>");
+ //m_out.addStr(convertToHtml(codeFragment,TRUE));
+ m_out.addStr(escapeSpecialChars(codeFragment));
+ m_out.addStr("</tt>");
}
return end;
}
-static void addStrEscapeUtf8Nbsp(GrowBuf &out,const char *s,int len)
+void Markdown::addStrEscapeUtf8Nbsp(const char *s,int len)
{
+ TRACE(s);
if (Portable::strnstr(s,g_doxy_nsbp,len)==0) // no escape needed -> fast
{
- out.addStr(s,len);
+ m_out.addStr(s,len);
}
else // escape needed -> slow
{
- out.addStr(substitute(QCString(s).left(len),g_doxy_nsbp,(const char *)g_utf8_nbsp));
+ m_out.addStr(substitute(QCString(s).left(len),g_doxy_nsbp,(const char *)g_utf8_nbsp));
}
}
-static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int size)
+int Markdown::processSpecialCommand(const char *data, int offset, int size)
{
+ TRACE(data);
int i=1;
QCString endBlockName = isBlockCommand(data,offset,size);
if (!endBlockName.isEmpty())
{
+ TRACE_MORE("endBlockName=%s\n",qPrint(endBlockName));
int l = endBlockName.length();
while (i<size-l)
{
@@ -1071,7 +1187,8 @@ static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int
if (qstrncmp(&data[i+1],endBlockName,l)==0)
{
//printf("found end at %d\n",i);
- addStrEscapeUtf8Nbsp(out,data,i+1+l);
+ addStrEscapeUtf8Nbsp(data,i+1+l);
+ TRACE_MORE("result=%d\n",i+1+l);
return i+1+l;
}
}
@@ -1083,34 +1200,39 @@ static int processSpecialCommand(GrowBuf &out, const char *data, int offset, int
char c=data[1];
if (c=='[' || c==']' || c=='*' || c=='!' || c=='(' || c==')' || c=='`' || c=='_')
{
- out.addChar(data[1]);
+ m_out.addChar(data[1]);
+ TRACE_MORE("result=2\n");
return 2;
}
else if (c=='-' && size>3 && data[2]=='-' && data[3]=='-') // \---
{
- out.addStr(&data[1],3);
+ m_out.addStr(&data[1],3);
+ TRACE_MORE("result=4\n");
return 4;
}
else if (c=='-' && size>2 && data[2]=='-') // \--
{
- out.addStr(&data[1],2);
+ m_out.addStr(&data[1],2);
+ TRACE_MORE("result=3\n");
return 3;
}
}
+ TRACE_MORE("result=0\n");
return 0;
}
-static void processInline(GrowBuf &out,const char *data,int size)
+void Markdown::processInline(const char *data,int size)
{
+ TRACE(data);
int i=0, end=0;
- action_t action = 0;
+ Action_t action;
while (i<size)
{
- while (end<size && ((action=g_actions[(uchar)data[end]])==0)) end++;
- out.addStr(data+i,end-i);
+ while (end<size && ((action=m_actions[(uchar)data[end]])==0)) end++;
+ m_out.addStr(data+i,end-i);
if (end>=size) break;
i=end;
- end = action(out,data+i,i,size-i);
+ end = action(data+i,i,size-i);
if (end<=0)
{
end=i+1-end;
@@ -1124,8 +1246,9 @@ static void processInline(GrowBuf &out,const char *data,int size)
}
/** returns whether the line is a setext-style hdr underline */
-static int isHeaderline(const char *data, int size, bool allowAdjustLevel)
+int Markdown::isHeaderline(const char *data, int size, bool allowAdjustLevel)
{
+ TRACE(data);
int i=0, c=0;
while (i<size && data[i]==' ') i++;
@@ -1135,30 +1258,31 @@ static int isHeaderline(const char *data, int size, bool allowAdjustLevel)
while (i<size && data[i]=='=') i++,c++;
while (i<size && data[i]==' ') i++;
int level = (c>1 && (i>=size || data[i]=='\n')) ? 1 : 0;
- if (allowAdjustLevel && level==1 && g_indentLevel==-1)
+ if (allowAdjustLevel && level==1 && m_indentLevel==-1)
{
// In case a page starts with a header line we use it as title, promoting it to @page.
// We set g_indentLevel to -1 to promoting the other sections if they have a deeper
// nesting level than the page header, i.e. @section..@subsection becomes @page..@section.
// In case a section at the same level is found (@section..@section) however we need
// to undo this (and the result will be @page..@section).
- g_indentLevel=0;
+ m_indentLevel=0;
}
- return g_indentLevel+level;
+ return m_indentLevel+level;
}
// test of level 2 header
if (data[i]=='-')
{
while (i<size && data[i]=='-') i++,c++;
while (i<size && data[i]==' ') i++;
- return (c>1 && (i>=size || data[i]=='\n')) ? g_indentLevel+2 : 0;
+ return (c>1 && (i>=size || data[i]=='\n')) ? m_indentLevel+2 : 0;
}
return 0;
}
/** returns TRUE if this line starts a block quote */
-static bool isBlockQuote(const char *data,int size,int indent)
+bool isBlockQuote(const char *data,int size,int indent)
{
+ TRACE(data);
int i = 0;
while (i<size && data[i]==' ') i++;
if (i<indent+codeBlockIndent) // could be a quotation
@@ -1185,6 +1309,7 @@ static bool isBlockQuote(const char *data,int size,int indent)
static int isLinkRef(const char *data,int size,
QCString &refid,QCString &link,QCString &title)
{
+ TRACE(data);
//printf("isLinkRef data={%s}\n",data);
// format: start with [some text]:
int i = 0;
@@ -1274,6 +1399,7 @@ static int isLinkRef(const char *data,int size,
static int isHRuler(const char *data,int size)
{
+ TRACE(data);
int i=0;
if (size>0 && data[size-1]=='\n') size--; // ignore newline character
while (i<size && data[i]==' ') i++;
@@ -1301,6 +1427,7 @@ static int isHRuler(const char *data,int size)
static QCString extractTitleId(QCString &title, int level)
{
+ TRACE(title.data());
//static QRegExp r1("^[a-z_A-Z][a-z_A-Z0-9\\-]*:");
static QRegExp r2("\\{#[a-z_A-Z][a-z_A-Z0-9\\-]*\\}");
int l=0;
@@ -1325,9 +1452,10 @@ static QCString extractTitleId(QCString &title, int level)
}
-static int isAtxHeader(const char *data,int size,
+int Markdown::isAtxHeader(const char *data,int size,
QCString &header,QCString &id,bool allowAdjustLevel)
{
+ TRACE(data);
int i = 0, end;
int level = 0, blanks=0;
@@ -1359,7 +1487,7 @@ static int isAtxHeader(const char *data,int size,
header=header.left(i+1);
}
- if (allowAdjustLevel && level==1 && g_indentLevel==-1)
+ if (allowAdjustLevel && level==1 && m_indentLevel==-1)
{
// in case we find a `# Section` on a markdown page that started with the same level
// header, we no longer need to artificially decrease the paragraph level.
@@ -1379,13 +1507,14 @@ static int isAtxHeader(const char *data,int size,
// @section autotoc_md1 Heading 2
// -------------------
- g_indentLevel=0;
+ m_indentLevel=0;
}
- return level+g_indentLevel;
+ return level+m_indentLevel;
}
static int isEmptyLine(const char *data,int size)
{
+ TRACE(data);
int i=0;
while (i<size)
{
@@ -1406,6 +1535,7 @@ static int isEmptyLine(const char *data,int size)
// such as -, -#, *, +, 1., and <li>
static int computeIndentExcludingListMarkers(const char *data,int size)
{
+ TRACE(data);
int i=0;
int indent=0;
bool isDigit=FALSE;
@@ -1474,6 +1604,7 @@ static int computeIndentExcludingListMarkers(const char *data,int size)
static bool isFencedCodeBlock(const char *data,int size,int refIndent,
QCString &lang,int &start,int &end,int &offset)
{
+ TRACE(data);
// rules: at least 3 ~~~, end of the block same amount of ~~~'s, otherwise
// return FALSE
int i=0;
@@ -1501,8 +1632,11 @@ static bool isFencedCodeBlock(const char *data,int size,int refIndent,
while (i<size && data[i]==' ') i++;
if (i==size || data[i]=='\n')
{
- offset=i;
- return endTildes==startTildes;
+ if (endTildes==startTildes)
+ {
+ offset=i;
+ return TRUE;
+ }
}
}
i++;
@@ -1512,6 +1646,7 @@ static bool isFencedCodeBlock(const char *data,int size,int refIndent,
static bool isCodeBlock(const char *data,int offset,int size,int &indent)
{
+ TRACE(data);
//printf("<isCodeBlock(offset=%d,size=%d,indent=%d)\n",offset,size,indent);
// determine the indent of this line
int i=0;
@@ -1588,6 +1723,7 @@ static bool isCodeBlock(const char *data,int offset,int size,int &indent)
*/
int findTableColumns(const char *data,int size,int &start,int &end,int &columns)
{
+ TRACE(data);
int i=0,n=0;
int eol;
// find start character of the table line
@@ -1596,8 +1732,12 @@ int findTableColumns(const char *data,int size,int &start,int &end,int &columns)
start = i;
// find end character of the table line
- while (i<size && data[i]!='\n') i++;
- eol=i+1;
+ //while (i<size && data[i]!='\n') i++;
+ //eol=i+1;
+ int j = 0;
+ while (i<size && (j = isNewline(data + i))==0) i++;
+ eol=i+j;
+
i--;
while (i>0 && data[i]==' ') i--;
if (i>0 && data[i-1]!='\\' && data[i]=='|') i--,n++; // trailing or escaped | does not count
@@ -1627,6 +1767,7 @@ int findTableColumns(const char *data,int size,int &start,int &end,int &columns)
/** Returns TRUE iff data points to the start of a table block */
static bool isTableBlock(const char *data,int size)
{
+ TRACE(data);
int cc0,start,end;
// the first line should have at least two columns separated by '|'
@@ -1663,8 +1804,9 @@ static bool isTableBlock(const char *data,int size)
return cc1==cc2;
}
-static int writeTableBlock(GrowBuf &out,const char *data,int size)
+int Markdown::writeTableBlock(const char *data,int size)
{
+ TRACE(data);
int i=0,j,k;
int columns,start,end,cc;
@@ -1673,17 +1815,10 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
int headerStart = start;
int headerEnd = end;
-#ifdef USE_ORIGINAL_TABLES
- out.addStr("<table>");
-
- // write table header, in range [start..end]
- out.addStr("<tr>");
-#endif
-
// read cell alignments
int ret = findTableColumns(data+i,size-i,start,end,cc);
k=0;
- Alignment *columnAlignment = new Alignment[columns];
+ std::vector<int> columnAlignment(columns);
bool leftMarker=FALSE,rightMarker=FALSE;
bool startFound=FALSE;
@@ -1720,100 +1855,27 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
// proceed to next line
i+=ret;
-#ifdef USE_ORIGINAL_TABLES
-
- int m=headerStart;
- for (k=0;k<columns;k++)
- {
- out.addStr("<th");
- switch (columnAlignment[k])
- {
- case AlignLeft: out.addStr(" align=\"left\""); break;
- case AlignRight: out.addStr(" align=\"right\""); break;
- case AlignCenter: out.addStr(" align=\"center\""); break;
- case AlignNone: break;
- }
- out.addStr(">");
- while (m<=headerEnd && (data[m]!='|' || (m>0 && data[m-1]=='\\')))
- {
- out.addChar(data[m++]);
- }
- m++;
- }
- out.addStr("\n</th>\n");
-
- // write table cells
- while (i<size)
- {
- int ret = findTableColumns(data+i,size-i,start,end,cc);
- //printf("findTableColumns cc=%d\n",cc);
- if (cc!=columns) break; // end of table
-
- out.addStr("<tr>");
- j=start+i;
- int columnStart=j;
- k=0;
- while (j<=end+i)
- {
- if (j==columnStart)
- {
- out.addStr("<td");
- switch (columnAlignment[k])
- {
- case AlignLeft: out.addStr(" align=\"left\""); break;
- case AlignRight: out.addStr(" align=\"right\""); break;
- case AlignCenter: out.addStr(" align=\"center\""); break;
- case AlignNone: break;
- }
- out.addStr(">");
- }
- if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\')))
- {
- columnStart=j+1;
- k++;
- }
- else
- {
- out.addChar(data[j]);
- }
- j++;
- }
- out.addChar('\n');
-
- // proceed to next line
- i+=ret;
- }
-
- out.addStr("</table> ");
-#else
// Store the table cell information by row then column. This
// allows us to handle row spanning.
- QVector<QVector<TableCell> > tableContents;
- tableContents.setAutoDelete(TRUE);
+ std::vector<std::vector<TableCell> > tableContents;
int m=headerStart;
- QVector<TableCell> *headerContents = new QVector<TableCell>(columns);
- headerContents->setAutoDelete(TRUE);
+ std::vector<TableCell> headerContents(columns);
for (k=0;k<columns;k++)
{
- headerContents->insert(k, new TableCell);
while (m<=headerEnd && (data[m]!='|' || (m>0 && data[m-1]=='\\')))
{
- headerContents->at(k)->cellText += data[m++];
+ headerContents[k].cellText += data[m++];
}
m++;
// do the column span test before stripping white space
// || is spanning columns, | | is not
- headerContents->at(k)->colSpan = headerContents->at(k)->cellText.isEmpty();
- headerContents->at(k)->cellText = headerContents->at(k)->cellText.stripWhiteSpace();
+ headerContents[k].colSpan = headerContents[k].cellText.isEmpty();
+ headerContents[k].cellText = headerContents[k].cellText.stripWhiteSpace();
}
- // qvector doesn't have an append like std::vector, so we gotta do
- // extra work
- tableContents.resize(1);
- tableContents.insert(0, headerContents);
+ tableContents.push_back(headerContents);
// write table cells
- int rowNum = 1;
while (i<size)
{
ret = findTableColumns(data+i,size-i,start,end,cc);
@@ -1821,41 +1883,34 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
j=start+i;
k=0;
- QVector<TableCell> *rowContents = new QVector<TableCell>(columns);
- rowContents->setAutoDelete(TRUE);
- rowContents->insert(k, new TableCell);
+ std::vector<TableCell> rowContents(columns);
while (j<=end+i)
{
if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\')))
{
// do the column span test before stripping white space
// || is spanning columns, | | is not
- rowContents->at(k)->colSpan = rowContents->at(k)->cellText.isEmpty();
- rowContents->at(k)->cellText = rowContents->at(k)->cellText.stripWhiteSpace();
+ rowContents[k].colSpan = rowContents[k].cellText.isEmpty();
+ rowContents[k].cellText = rowContents[k].cellText.stripWhiteSpace();
k++;
- rowContents->insert(k, new TableCell);
} // if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\')))
else
{
- rowContents->at(k)->cellText += data[j];
+ rowContents[k].cellText += data[j];
} // else { if (j<=end+i && (data[j]=='|' && (j==0 || data[j-1]!='\\'))) }
j++;
} // while (j<=end+i)
// do the column span test before stripping white space
// || is spanning columns, | | is not
- rowContents->at(k)->colSpan = rowContents->at(k)->cellText.isEmpty();
- rowContents->at(k)->cellText = rowContents->at(k)->cellText.stripWhiteSpace();
- // qvector doesn't have an append like std::vector, so we gotta do
- // extra work
- tableContents.resize(tableContents.size()+1);
- tableContents.insert(rowNum++, rowContents);
+ rowContents[k].colSpan = rowContents[k].cellText.isEmpty();
+ rowContents[k].cellText = rowContents[k].cellText.stripWhiteSpace();
+ tableContents.push_back(rowContents);
// proceed to next line
i+=ret;
}
-
- out.addStr("<table class=\"markdownTable\">");
+ m_out.addStr("<table class=\"markdownTable\">");
QCString cellTag("th"), cellClass("class=\"markdownTableHead");
for (unsigned row = 0; row < tableContents.size(); row++)
{
@@ -1863,58 +1918,57 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
{
if (row % 2)
{
- out.addStr("<tr class=\"markdownTableRowOdd\">");
+ m_out.addStr("<tr class=\"markdownTableRowOdd\">");
}
else
{
- out.addStr("<tr class=\"markdownTableRowEven\">");
+ m_out.addStr("<tr class=\"markdownTableRowEven\">");
}
}
else
{
- out.addStr(" <tr class=\"markdownTableHead\">");
+ m_out.addStr(" <tr class=\"markdownTableHead\">");
}
for (int c = 0; c < columns; c++)
{
// save the cell text for use after column span computation
- QCString cellText(tableContents[row]->at(c)->cellText);
+ QCString cellText(tableContents[row][c].cellText);
// Row span handling. Spanning rows will contain a caret ('^').
// If the current cell contains just a caret, this is part of an
// earlier row's span and the cell should not be added to the
// output.
- if (tableContents[row]->at(c)->cellText == "^")
+ if (tableContents[row][c].cellText == "^")
continue;
unsigned rowSpan = 1, spanRow = row+1;
while ((spanRow < tableContents.size()) &&
- (tableContents[spanRow]->at(c)->cellText == "^"))
+ (tableContents[spanRow][c].cellText == "^"))
{
spanRow++;
rowSpan++;
}
- out.addStr(" <" + cellTag + " " + cellClass);
+ m_out.addStr(" <" + cellTag + " " + cellClass);
// use appropriate alignment style
switch (columnAlignment[c])
{
- case AlignLeft: out.addStr("Left\""); break;
- case AlignRight: out.addStr("Right\""); break;
- case AlignCenter: out.addStr("Center\""); break;
- case AlignNone: out.addStr("None\""); break;
+ case AlignLeft: m_out.addStr("Left\""); break;
+ case AlignRight: m_out.addStr("Right\""); break;
+ case AlignCenter: m_out.addStr("Center\""); break;
+ case AlignNone: m_out.addStr("None\""); break;
}
if (rowSpan > 1)
{
QCString spanStr;
spanStr.setNum(rowSpan);
- out.addStr(" rowspan=\"" + spanStr + "\"");
+ m_out.addStr(" rowspan=\"" + spanStr + "\"");
}
// Column span handling, assumes that column spans will have
// empty strings, which would indicate the sequence "||", used
// to signify spanning columns.
unsigned colSpan = 1;
- while ((c < columns-1) &&
- tableContents[row]->at(c+1)->colSpan)
+ while ((c < columns-1) && tableContents[row][c+1].colSpan)
{
c++;
colSpan++;
@@ -1923,26 +1977,25 @@ static int writeTableBlock(GrowBuf &out,const char *data,int size)
{
QCString spanStr;
spanStr.setNum(colSpan);
- out.addStr(" colspan=\"" + spanStr + "\"");
+ m_out.addStr(" colspan=\"" + spanStr + "\"");
}
// need at least one space on either side of the cell text in
// order for doxygen to do other formatting
- out.addStr("> " + cellText + "</" + cellTag + ">");
+ m_out.addStr("> " + cellText + "\\ilinebr </" + cellTag + ">");
}
cellTag = "td";
cellClass = "class=\"markdownTableBody";
- out.addStr(" </tr>\n");
+ m_out.addStr(" </tr>\n");
}
- out.addStr("</table>\n");
-#endif
+ m_out.addStr("</table>\n");
- delete[] columnAlignment;
return i;
}
static int hasLineBreak(const char *data,int size)
{
+ TRACE(data);
int i=0;
int j=0;
// search for end of line and also check if it is not a completely blank
@@ -1957,14 +2010,15 @@ static int hasLineBreak(const char *data,int size)
}
-void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size)
+void Markdown::writeOneLineHeaderOrRuler(const char *data,int size)
{
+ TRACE(data);
int level;
QCString header;
QCString id;
if (isHRuler(data,size))
{
- out.addStr("\n<hr>\n");
+ m_out.addStr("\n<hr>\n");
}
else if ((level=isAtxHeader(data,size,header,id,TRUE)))
{
@@ -1973,44 +2027,45 @@ void writeOneLineHeaderOrRuler(GrowBuf &out,const char *data,int size)
{
switch(level)
{
- case 1: out.addStr("@section ");
+ case 1: m_out.addStr("@section ");
break;
- case 2: out.addStr("@subsection ");
+ case 2: m_out.addStr("@subsection ");
break;
- case 3: out.addStr("@subsubsection ");
+ case 3: m_out.addStr("@subsubsection ");
break;
- default: out.addStr("@paragraph ");
+ default: m_out.addStr("@paragraph ");
break;
}
- out.addStr(id);
- out.addStr(" ");
- out.addStr(header);
- out.addStr("\n");
+ m_out.addStr(id);
+ m_out.addStr(" ");
+ m_out.addStr(header);
+ m_out.addStr("\n");
}
else
{
if (!id.isEmpty())
{
- out.addStr("\\anchor "+id+"\n");
+ m_out.addStr("\\anchor "+id+"\n");
}
hTag.sprintf("h%d",level);
- out.addStr("<"+hTag+">");
- out.addStr(header);
- out.addStr("</"+hTag+">\n");
+ m_out.addStr("<"+hTag+">");
+ m_out.addStr(header);
+ m_out.addStr("</"+hTag+">\n");
}
}
else // nothing interesting -> just output the line
{
- out.addStr(data,size);
+ m_out.addStr(data,size);
if (hasLineBreak(data,size))
{
- out.addStr("<br>\n");
+ m_out.addStr("<br>\n");
}
}
}
-static int writeBlockQuote(GrowBuf &out,const char *data,int size)
+int Markdown::writeBlockQuote(const char *data,int size)
{
+ TRACE(data);
int l;
int i=0;
int curLevel=0;
@@ -2040,36 +2095,37 @@ static int writeBlockQuote(GrowBuf &out,const char *data,int size)
{
for (l=curLevel;l<level;l++)
{
- out.addStr("<blockquote>\n");
+ m_out.addStr("<blockquote>\n");
}
}
else if (level<curLevel) // quote level decreased => add end markers
{
for (l=level;l<curLevel;l++)
{
- out.addStr("</blockquote>\n");
+ m_out.addStr("</blockquote>\n");
}
}
curLevel=level;
if (level==0) break; // end of quote block
// copy line without quotation marks
- out.addStr(data+indent,end-indent);
+ m_out.addStr(data+indent,end-indent);
// proceed with next line
i=end;
}
// end of comment within blockquote => add end markers
for (l=0;l<curLevel;l++)
{
- out.addStr("</blockquote>\n");
+ m_out.addStr("</blockquote>\n");
}
return i;
}
-static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent)
+int Markdown::writeCodeBlock(const char *data,int size,int refIndent)
{
+ TRACE(data);
int i=0,end;
//printf("writeCodeBlock: data={%s}\n",QCString(data).left(size).data());
- out.addStr("@verbatim\n");
+ m_out.addStr("@verbatim\n");
int emptyLines=0;
while (i<size)
{
@@ -2091,11 +2147,11 @@ static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent)
while (emptyLines>0) // write skipped empty lines
{
// add empty line
- out.addStr("\n");
+ m_out.addStr("\n");
emptyLines--;
}
// add code line minus the indent
- out.addStr(data+i+refIndent+codeBlockIndent,end-i-refIndent-codeBlockIndent);
+ m_out.addStr(data+i+refIndent+codeBlockIndent,end-i-refIndent-codeBlockIndent);
i=end;
}
else // end of code block
@@ -2103,11 +2159,11 @@ static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent)
break;
}
}
- out.addStr("@endverbatim\n");
+ m_out.addStr("@endverbatim\n");
while (emptyLines>0) // write skipped empty lines
{
// add empty line
- out.addStr("\n");
+ m_out.addStr("\n");
emptyLines--;
}
//printf("i=%d\n",i);
@@ -2116,13 +2172,16 @@ static int writeCodeBlock(GrowBuf &out,const char *data,int size,int refIndent)
// start searching for the end of the line start at offset \a i
// keeping track of possible blocks that need to be skipped.
-static void findEndOfLine(GrowBuf &out,const char *data,int size,
+void Markdown::findEndOfLine(const char *data,int size,
int &pi,int&i,int &end)
{
+ TRACE(data);
// find end of the line
int nb=0;
end=i+1;
- while (end<=size && data[end-1]!='\n')
+ //while (end<=size && data[end-1]!='\n')
+ int j=0;
+ while (end<=size && (j=isNewline(data+end-1))==0)
{
// while looking for the end of the line we might encounter a block
// that needs to be passed unprocessed.
@@ -2144,7 +2203,7 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size,
if (qstrncmp(&data[end+1],endBlockName,l)==0)
{
// found end marker, skip over this block
- //printf("feol.block out={%s}\n",QCString(data+i).left(end+l+1-i).data());
+ //printf("feol.block m_out={%s}\n",QCString(data+i).left(end+l+1-i).data());
end = end + l + 2;
break;
}
@@ -2160,7 +2219,7 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size,
tolower(data[end+2])=='e' && data[end+3]=='>') // <pre> tag
{
// skip part until including </pre>
- end = end + processHtmlTagWrite(out,data+end-1,end-1,size-end+1,false) + 2;
+ end = end + processHtmlTagWrite(data+end-1,end-1,size-end+1,false) + 2;
break;
}
else
@@ -2183,27 +2242,30 @@ static void findEndOfLine(GrowBuf &out,const char *data,int size,
end++;
}
}
+ if (j>0) end+=j-1;
//printf("findEndOfLine pi=%d i=%d end=%d {%s}\n",pi,i,end,QCString(data+i).left(end-i).data());
}
-static void writeFencedCodeBlock(GrowBuf &out,const char *data,const char *lng,
+void Markdown::writeFencedCodeBlock(const char *data,const char *lng,
int blockStart,int blockEnd)
{
+ TRACE(data);
QCString lang = lng;
if (!lang.isEmpty() && lang.at(0)=='.') lang=lang.mid(1);
- out.addStr("@code");
+ m_out.addStr("@code");
if (!lang.isEmpty())
{
- out.addStr("{"+lang+"}");
+ m_out.addStr("{"+lang+"}");
}
- addStrEscapeUtf8Nbsp(out,data+blockStart,blockEnd-blockStart);
- out.addStr("\n");
- out.addStr("@endcode\n");
+ addStrEscapeUtf8Nbsp(data+blockStart,blockEnd-blockStart);
+ m_out.addStr("\n");
+ m_out.addStr("@endcode\n");
}
-static QCString processQuotations(const QCString &s,int refIndent)
+QCString Markdown::processQuotations(const QCString &s,int refIndent)
{
- GrowBuf out;
+ TRACE(s.data());
+ m_out.clear();
const char *data = s.data();
int size = s.length();
int i=0,end=0,pi=-1;
@@ -2211,14 +2273,14 @@ static QCString processQuotations(const QCString &s,int refIndent)
QCString lang;
while (i<size)
{
- findEndOfLine(out,data,size,pi,i,end);
+ findEndOfLine(data,size,pi,i,end);
// line is now found at [i..end)
if (pi!=-1)
{
if (isFencedCodeBlock(data+pi,size-pi,refIndent,lang,blockStart,blockEnd,blockOffset))
{
- writeFencedCodeBlock(out,data+pi,lang,blockStart,blockEnd);
+ writeFencedCodeBlock(data+pi,lang,blockStart,blockEnd);
i=pi+blockOffset;
pi=-1;
end=i+1;
@@ -2226,15 +2288,15 @@ static QCString processQuotations(const QCString &s,int refIndent)
}
else if (isBlockQuote(data+pi,i-pi,refIndent))
{
- i = pi+writeBlockQuote(out,data+pi,size-pi);
+ i = pi+writeBlockQuote(data+pi,size-pi);
pi=-1;
end=i+1;
continue;
}
else
{
- //printf("quote out={%s}\n",QCString(data+pi).left(i-pi).data());
- out.addStr(data+pi,i-pi);
+ //printf("quote m_out={%s}\n",QCString(data+pi).left(i-pi).data());
+ m_out.addStr(data+pi,i-pi);
}
}
pi=i;
@@ -2244,24 +2306,25 @@ static QCString processQuotations(const QCString &s,int refIndent)
{
if (isBlockQuote(data+pi,size-pi,refIndent))
{
- writeBlockQuote(out,data+pi,size-pi);
+ writeBlockQuote(data+pi,size-pi);
}
else
{
- out.addStr(data+pi,size-pi);
+ m_out.addStr(data+pi,size-pi);
}
}
- out.addChar(0);
+ m_out.addChar(0);
//printf("Process quotations\n---- input ----\n%s\n---- output ----\n%s\n------------\n",
- // s.data(),out.get());
+ // s.data(),m_out.get());
- return out.get();
+ return m_out.get();
}
-static QCString processBlocks(const QCString &s,int indent)
+QCString Markdown::processBlocks(const QCString &s,int indent)
{
- GrowBuf out;
+ TRACE(s.data());
+ m_out.clear();
const char *data = s.data();
int size = s.length();
int i=0,end=0,pi=-1,ref,level;
@@ -2277,14 +2340,14 @@ static QCString processBlocks(const QCString &s,int indent)
end++;
}
-#if 0 // commented out, since starting with a comment block is probably a usage error
+#if 0 // commented m_out, since starting with a comment block is probably a usage error
// see also http://stackoverflow.com/q/20478611/784672
// special case when the documentation starts with a code block
// since the first line is skipped when looking for a code block later on.
if (end>codeBlockIndent && isCodeBlock(data,0,end,blockIndent))
{
- i=writeCodeBlock(out,data,size,blockIndent);
+ i=writeCodeBlock(m_out,data,size,blockIndent);
end=i+1;
pi=-1;
}
@@ -2293,7 +2356,7 @@ static QCString processBlocks(const QCString &s,int indent)
// process each line
while (i<size)
{
- findEndOfLine(out,data,size,pi,i,end);
+ findEndOfLine(data,size,pi,i,end);
// line is now found at [i..end)
//printf("findEndOfLine: pi=%d i=%d end=%d\n",pi,i,end);
@@ -2316,22 +2379,22 @@ static QCString processBlocks(const QCString &s,int indent)
{
if (!id.isEmpty())
{
- out.addStr(level==1?"@section ":"@subsection ");
- out.addStr(id);
- out.addStr(" ");
- out.addStr(header);
- out.addStr("\n\n");
+ m_out.addStr(level==1?"@section ":"@subsection ");
+ m_out.addStr(id);
+ m_out.addStr(" ");
+ m_out.addStr(header);
+ m_out.addStr("\n\n");
}
else
{
- out.addStr(level==1?"<h1>":"<h2>");
- out.addStr(header);
- out.addStr(level==1?"\n</h1>\n":"\n</h2>\n");
+ m_out.addStr(level==1?"<h1>":"<h2>");
+ m_out.addStr(header);
+ m_out.addStr(level==1?"\n</h1>\n":"\n</h2>\n");
}
}
else
{
- out.addStr("\n<hr>\n");
+ m_out.addStr("\n<hr>\n");
}
pi=-1;
i=end;
@@ -2342,7 +2405,7 @@ static QCString processBlocks(const QCString &s,int indent)
{
//printf("found link ref: id='%s' link='%s' title='%s'\n",
// id.data(),link.data(),title.data());
- g_linkRefs.insert(id.lower(),new LinkRef(link,title));
+ m_linkRefs.insert({id.lower().str(),LinkRef(link,title)});
i=ref+pi;
pi=-1;
end=i+1;
@@ -2351,7 +2414,7 @@ static QCString processBlocks(const QCString &s,int indent)
{
//printf("Found FencedCodeBlock lang='%s' start=%d end=%d code={%s}\n",
// lang.data(),blockStart,blockEnd,QCString(data+pi+blockStart).left(blockEnd-blockStart).data());
- writeFencedCodeBlock(out,data+pi,lang,blockStart,blockEnd);
+ writeFencedCodeBlock(data+pi,lang,blockStart,blockEnd);
i=pi+blockOffset;
pi=-1;
end=i+1;
@@ -2360,21 +2423,21 @@ static QCString processBlocks(const QCString &s,int indent)
else if (isCodeBlock(data+i,i,end-i,blockIndent))
{
// skip previous line (it is empty anyway)
- i+=writeCodeBlock(out,data+i,size-i,blockIndent);
+ i+=writeCodeBlock(data+i,size-i,blockIndent);
pi=-1;
end=i+1;
continue;
}
else if (isTableBlock(data+pi,size-pi))
{
- i=pi+writeTableBlock(out,data+pi,size-pi);
+ i=pi+writeTableBlock(data+pi,size-pi);
pi=-1;
end=i+1;
continue;
}
else
{
- writeOneLineHeaderOrRuler(out,data+pi,i-pi);
+ writeOneLineHeaderOrRuler(data+pi,i-pi);
}
}
pi=i;
@@ -2387,21 +2450,22 @@ static QCString processBlocks(const QCString &s,int indent)
{
//printf("found link ref: id='%s' link='%s' title='%s'\n",
// id.data(),link.data(),title.data());
- g_linkRefs.insert(id.lower(),new LinkRef(link,title));
+ m_linkRefs.insert({id.lower().str(),LinkRef(link,title)});
}
else
{
- writeOneLineHeaderOrRuler(out,data+pi,size-pi);
+ writeOneLineHeaderOrRuler(data+pi,size-pi);
}
}
- out.addChar(0);
- return out.get();
+ m_out.addChar(0);
+ return m_out.get();
}
/** returns TRUE if input string docs starts with \@page or \@mainpage command */
static bool isExplicitPage(const QCString &docs)
{
+ TRACE(docs.data());
int i=0;
const char *data = docs.data();
if (data)
@@ -2422,8 +2486,9 @@ static bool isExplicitPage(const QCString &docs)
return FALSE;
}
-static QCString extractPageTitle(QCString &docs,QCString &id)
+QCString Markdown::extractPageTitle(QCString &docs,QCString &id)
{
+ TRACE(docs.data());
int ln=0;
// first first non-empty line
QCString title;
@@ -2469,11 +2534,13 @@ static QCString extractPageTitle(QCString &docs,QCString &id)
return title;
}
-static QCString detab(const QCString &s,int &refIndent)
+QCString Markdown::detab(const QCString &s,int &refIndent)
{
+ TRACE(s.data());
int tabSize = Config_getInt(TAB_SIZE);
int size = s.length();
- GrowBuf out(size);
+ m_out.clear();
+ m_out.reserve(size);
const char *data = s.data();
int i=0;
int col=0;
@@ -2489,15 +2556,15 @@ static QCString detab(const QCString &s,int &refIndent)
int stop = tabSize - (col%tabSize);
//printf("expand at %d stop=%d\n",col,stop);
col+=stop;
- while (stop--) out.addChar(' ');
+ while (stop--) m_out.addChar(' ');
}
break;
case '\n': // reset column counter
- out.addChar(c);
+ m_out.addChar(c);
col=0;
break;
case ' ': // increment column counter
- out.addChar(c);
+ m_out.addChar(c);
col++;
break;
default: // non-whitespace => update minIndent
@@ -2506,90 +2573,86 @@ static QCString detab(const QCString &s,int &refIndent)
// special handling of the UTF-8 nbsp character 0xC2 0xA0
if ((uchar)c == 0xC2 && (uchar)(data[i]) == 0xA0)
{
- out.addStr(g_doxy_nsbp);
+ m_out.addStr(g_doxy_nsbp);
i++;
}
else
{
- out.addChar(c);
- out.addChar(data[i++]); // >= 2 bytes
+ m_out.addChar(c);
+ m_out.addChar(data[i++]); // >= 2 bytes
if (((uchar)c&0xE0)==0xE0 && i<size)
{
- out.addChar(data[i++]); // 3 bytes
+ m_out.addChar(data[i++]); // 3 bytes
}
if (((uchar)c&0xF0)==0xF0 && i<size)
{
- out.addChar(data[i++]); // 4 byres
+ m_out.addChar(data[i++]); // 4 byres
}
}
}
else
{
- out.addChar(c);
+ m_out.addChar(c);
}
if (col<minIndent) minIndent=col;
col++;
}
}
if (minIndent!=maxIndent) refIndent=minIndent; else refIndent=0;
- out.addChar(0);
+ m_out.addChar(0);
//printf("detab refIndent=%d\n",refIndent);
- return out.get();
+ return m_out.get();
}
//---------------------------------------------------------------------------
-QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &input)
+QCString Markdown::process(const QCString &input, int &startNewlines)
{
- static AtomicBool init { FALSE };
- if (!init)
- {
- // setup callback table for special characters
- g_actions[(unsigned int)'_']=processEmphasis;
- g_actions[(unsigned int)'*']=processEmphasis;
- g_actions[(unsigned int)'~']=processEmphasis;
- g_actions[(unsigned int)'`']=processCodeSpan;
- g_actions[(unsigned int)'\\']=processSpecialCommand;
- g_actions[(unsigned int)'@']=processSpecialCommand;
- g_actions[(unsigned int)'[']=processLink;
- g_actions[(unsigned int)'!']=processLink;
- g_actions[(unsigned int)'<']=processHtmlTag;
- g_actions[(unsigned int)'-']=processNmdash;
- g_actions[(unsigned int)'"']=processQuoted;
- init=TRUE;
- }
-
- g_linkRefs.setAutoDelete(TRUE);
- g_linkRefs.clear();
- g_current = e;
- g_fileName = fileName;
- g_lineNr = lineNr;
- GrowBuf out;
if (input.isEmpty()) return input;
- out.clear();
int refIndent;
+
// for replace tabs by spaces
QCString s = input;
if (s.at(s.length()-1)!='\n') s += "\n"; // see PR #6766
s = detab(s,refIndent);
//printf("======== DeTab =========\n---- output -----\n%s\n---------\n",s.data());
+
// then process quotation blocks (as these may contain other blocks)
s = processQuotations(s,refIndent);
//printf("======== Quotations =========\n---- output -----\n%s\n---------\n",s.data());
+
// then process block items (headers, rules, and code blocks, references)
s = processBlocks(s,refIndent);
//printf("======== Blocks =========\n---- output -----\n%s\n---------\n",s.data());
+
// finally process the inline markup (links, emphasis and code spans)
- processInline(out,s,s.length());
- out.addChar(0);
- Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n=========\n",qPrint(input),qPrint(out.get()));
- return substitute(out.get(),g_doxy_nsbp,"&nbsp;");
+ m_out.clear();
+ processInline(s,s.length());
+ m_out.addChar(0);
+ Debug::print(Debug::Markdown,0,"======== Markdown =========\n---- input ------- \n%s\n---- output -----\n%s\n=========\n",qPrint(input),qPrint(m_out.get()));
+
+ // post processing
+ QCString result = substitute(m_out.get(),g_doxy_nsbp,"&nbsp;");
+ const char *p = result.data();
+ if (p)
+ {
+ while (*p==' ') p++; // skip over spaces
+ while (*p=='\n') {startNewlines++;p++;}; // skip over newlines
+ if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br>
+ }
+ if (p>result.data())
+ {
+ // strip part of the input
+ result = result.mid(p-result.data());
+ }
+ return result;
}
//---------------------------------------------------------------------------
QCString markdownFileNameToId(const QCString &fileName)
{
+ TRACE(fileName.data());
QCString baseFn = stripFromPath(QFileInfo(fileName).absFilePath().utf8());
int i = baseFn.findRev('.');
if (i!=-1) baseFn = baseFn.left(i);
@@ -2599,35 +2662,6 @@ QCString markdownFileNameToId(const QCString &fileName)
//---------------------------------------------------------------------------
-QCString processMarkdownForCommentBlock(const QCString &comment,
- const QCString &fileName,
- int lineNr)
-{
- if (!comment.isEmpty() && Doxygen::markdownSupport)
- {
- QCString result = processMarkdown(fileName,lineNr,0,comment);
- const char *p = result.data();
- if (p)
- {
- while (*p==' ') p++; // skip over spaces
- while (*p=='\n') p++; // skip over newlines
- if (qstrncmp(p,"<br>",4)==0) p+=4; // skip over <br>
- }
- if (p>result.data())
- {
- // strip part of the input
- result = result.mid(p-result.data());
- }
- return result;
- }
- else
- {
- return comment;
- }
-}
-
-//---------------------------------------------------------------------------
-
struct MarkdownOutlineParser::Private
{
CommentScanner commentScanner;
@@ -2644,8 +2678,7 @@ MarkdownOutlineParser::~MarkdownOutlineParser()
void MarkdownOutlineParser::parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool /*sameTranslationUnit*/,
- QStrList & /*filesInSameTranslationUnit*/)
+ ClangTUParser* /*clangParser*/)
{
std::shared_ptr<Entry> current = std::make_shared<Entry>();
current->lang = SrcLangExt_Markdown;
@@ -2654,9 +2687,11 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
current->docLine = 1;
QCString docs = fileBuf;
QCString id;
- QCString title=extractPageTitle(docs,id).stripWhiteSpace();
+ Markdown markdown(fileName,1,0);
+ QCString title=markdown.extractPageTitle(docs,id).stripWhiteSpace();
if (id.startsWith("autotoc_md")) id = "";
- g_indentLevel=title.isEmpty() ? 0 : -1;
+ int indentLevel=title.isEmpty() ? 0 : -1;
+ markdown.setIndentLevel(indentLevel);
QCString titleFn = QFileInfo(fileName).baseName().utf8();
QCString fn = QFileInfo(fileName).fileName().utf8();
QCString mdfileAsMainPage = Config_getString(USE_MDFILE_AS_MAINPAGE);
@@ -2688,15 +2723,12 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
}
int lineNr=1;
- // even without markdown support enabled, we still
- // parse markdown files as such
- bool markdownEnabled = Doxygen::markdownSupport;
- Doxygen::markdownSupport = TRUE;
-
Protection prot=Public;
bool needsEntry = FALSE;
int position=0;
- QCString processedDocs = processMarkdownForCommentBlock(docs,fileName,lineNr);
+ int startNewlines;
+ QCString processedDocs = markdown.process(docs,startNewlines);
+ lineNr += startNewlines;
while (p->commentScanner.parseCommentBlock(
this,
current.get(),
@@ -2708,7 +2740,8 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
FALSE, // inBodyDocs
prot, // protection
position,
- needsEntry))
+ needsEntry,
+ true))
{
if (needsEntry)
{
@@ -2723,10 +2756,6 @@ void MarkdownOutlineParser::parseInput(const char *fileName,
{
root->moveToSubEntryAndKeep(current);
}
-
- // restore setting
- Doxygen::markdownSupport = markdownEnabled;
- g_indentLevel=0;
}
void MarkdownOutlineParser::parsePrototype(const char *text)
diff --git a/src/markdown.h b/src/markdown.h
index bc1e9bb..1210967 100644
--- a/src/markdown.h
+++ b/src/markdown.h
@@ -3,8 +3,8 @@
* 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
+ * 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.
*
@@ -16,39 +16,87 @@
#ifndef MARKDOWN_H
#define MARKDOWN_H
+#include <functional>
+
#include <qcstring.h>
#include "parserintf.h"
+#include "growbuf.h"
class Entry;
/** processes string \a s and converts markdown into doxygen/html commands. */
-QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &s);
+//QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &s);
QCString markdownFileNameToId(const QCString &fileName);
-/** Performs markdown processing for a comment block if markdown processing is enabled.
- * @param[in] comment A string representing the actual comment block.
- * Note that leading *'s should already be stripped from the comment block.
- * @param[in] fileName The name of the file in which the comment is found.
- * Mainly used for producing warnings.
- * @param[in] lineNr The line number at which the comment block was found.
- * @returns The processed comment block
- */
-QCString processMarkdownForCommentBlock(const QCString &comment,
- const QCString &fileName,
- int lineNr);
+/// Helper class to process markdown formatted text
+class Markdown
+{
+ public:
+ Markdown(const char *fileName,int lineNr,int indentLevel=0);
+ QCString process(const QCString &input, int &startNewlines);
+ QCString extractPageTitle(QCString &docs,QCString &id);
+ void setIndentLevel(int level) { m_indentLevel = level; }
+
+ private:
+ QCString detab(const QCString &s,int &refIndent);
+ QCString processQuotations(const QCString &s,int refIndent);
+ QCString processBlocks(const QCString &s,int indent);
+ QCString isBlockCommand(const char *data,int offset,int size);
+ void findEndOfLine(const char *data,int size,int &pi,int&i,int &end);
+ int processHtmlTagWrite(const char *data,int offset,int size,bool doWrite);
+ int processHtmlTag(const char *data,int offset,int size);
+ int processEmphasis(const char *data,int offset,int size);
+ int processEmphasis1(const char *data, int size, char c);
+ int processEmphasis2(const char *data, int size, char c);
+ int processEmphasis3(const char *data, int size, char c);
+ int processNmdash(const char *data,int off,int size);
+ int processQuoted(const char *data,int,int size);
+ int processCodeSpan(const char *data, int /*offset*/, int size);
+ void addStrEscapeUtf8Nbsp(const char *s,int len);
+ int processSpecialCommand(const char *data, int offset, int size);
+ int processLink(const char *data,int,int size);
+ int findEmphasisChar(const char *data, int size, char c, int c_size);
+ void processInline(const char *data,int size);
+ void writeMarkdownImage(const char *fmt, bool explicitTitle,
+ const QCString &title, const QCString &content,
+ const QCString &link, const FileDef *fd);
+ int isHeaderline(const char *data, int size, bool allowAdjustLevel);
+ int isAtxHeader(const char *data,int size,
+ QCString &header,QCString &id,bool allowAdjustLevel);
+ void writeOneLineHeaderOrRuler(const char *data,int size);
+ void writeFencedCodeBlock(const char *data,const char *lng,
+ int blockStart,int blockEnd);
+ int writeBlockQuote(const char *data,int size);
+ int writeCodeBlock(const char *data,int size,int refIndent);
+ int writeTableBlock(const char *data,int size);
+
+ private:
+ struct LinkRef
+ {
+ LinkRef(const char *l,const char *t) : link(l), title(t) {}
+ QCString link;
+ QCString title;
+ };
+ using Action_t = std::function<int(const char *,int,int)>;
+
+ std::unordered_map<std::string,LinkRef> m_linkRefs;
+ QCString m_fileName;
+ int m_lineNr = 0;
+ int m_indentLevel=0; // 0 is outside markdown, -1=page level
+ GrowBuf m_out;
+ Markdown::Action_t m_actions[256];
+};
+
class MarkdownOutlineParser : public OutlineParserInterface
{
public:
MarkdownOutlineParser();
virtual ~MarkdownOutlineParser();
- void startTranslationUnit(const char *) {}
- void finishTranslationUnit() {}
- void parseInput(const char *fileName,
- const char *fileBuf,
+ void parseInput(const char *fileName,
+ const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList &filesInSameTranslationUnit);
+ ClangTUParser *clangParser);
bool needsPreprocessing(const QCString &) const { return FALSE; }
void parsePrototype(const char *text);
private:
diff --git a/src/memberdef.cpp b/src/memberdef.cpp
index d857fa6..7645a01 100644
--- a/src/memberdef.cpp
+++ b/src/memberdef.cpp
@@ -2606,8 +2606,8 @@ void MemberDefImpl::writeDeclaration(OutputList &ol,
)
{
DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),
- getOuterScope()?getOuterScope():d,this,briefDescription(),
- TRUE,FALSE,0,TRUE,FALSE);
+ getOuterScope()?getOuterScope():d,this,briefDescription(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (rootNode && !rootNode->isEmpty())
{
@@ -2733,7 +2733,7 @@ void MemberDefImpl::getLabels(QStrList &sl,const Definition *container) const
isFriend() || isRelated() ||
(isInline() && inlineInfo) ||
isSignal() || isSlot() ||
- isStatic() ||
+ isStatic() || isExternal() ||
(getClassDef() && getClassDef()!=container && container->definitionType()==TypeClass) ||
(m_impl->memSpec & ~Entry::Inline)!=0
)
@@ -2745,7 +2745,7 @@ void MemberDefImpl::getLabels(QStrList &sl,const Definition *container) const
//ol.docify(" [");
SrcLangExt lang = getLanguage();
bool optVhdl = lang==SrcLangExt_VHDL;
- bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
+ static bool extractPrivate = Config_getBool(EXTRACT_PRIVATE);
if (optVhdl)
{
sl.append(theTranslator->trVhdlType(getMemberSpecifiers(),TRUE));
@@ -2756,7 +2756,8 @@ void MemberDefImpl::getLabels(QStrList &sl,const Definition *container) const
else if (isRelated()) sl.append("related");
else
{
- if (Config_getBool(INLINE_INFO) && isInline()) sl.append("inline");
+ if (isExternal()) sl.append("extern");
+ if (inlineInfo && isInline()) sl.append("inline");
if (isExplicit()) sl.append("explicit");
if (isMutable()) sl.append("mutable");
if (isStatic()) sl.append("static");
@@ -3146,7 +3147,8 @@ void MemberDefImpl::_writeEnumValues(OutputList &ol,const Definition *container,
{
ol.generateDoc(fmd->briefFile(),fmd->briefLine(),
getOuterScope()?getOuterScope():container,
- fmd,fmd->briefDescription(),TRUE,FALSE);
+ fmd,fmd->briefDescription(),TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
// FIXME:PARA
//if (!fmd->briefDescription().isEmpty() &&
@@ -3158,7 +3160,8 @@ void MemberDefImpl::_writeEnumValues(OutputList &ol,const Definition *container,
{
ol.generateDoc(fmd->docFile(),fmd->docLine(),
getOuterScope()?getOuterScope():container,
- fmd,fmd->documentation()+"\n",TRUE,FALSE);
+ fmd,fmd->documentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
ol.endDescTableData();
ol.endDescTableRow();
@@ -3706,7 +3709,8 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml,
ol.startParagraph();
ol.generateDoc(briefFile(),briefLine(),
scopedContainer,this,
- brief,FALSE,FALSE,0,TRUE,FALSE);
+ brief,FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endParagraph();
}
@@ -3722,14 +3726,16 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml,
}
else
{
- ol.generateDoc(docFile(),docLine(),scopedContainer,this,detailed+"\n",TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),scopedContainer,this,detailed+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
if (!inbodyDocumentation().isEmpty())
{
ol.generateDoc(inbodyFile(),inbodyLine(),
- scopedContainer,this,
- inbodyDocumentation()+"\n",TRUE,FALSE);
+ scopedContainer,this,
+ inbodyDocumentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
}
else if (!brief.isEmpty() && (Config_getBool(REPEAT_BRIEF) ||
@@ -3737,7 +3743,8 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml,
{
if (!inbodyDocumentation().isEmpty())
{
- ol.generateDoc(inbodyFile(),inbodyLine(),scopedContainer,this,inbodyDocumentation()+"\n",TRUE,FALSE);
+ ol.generateDoc(inbodyFile(),inbodyLine(),scopedContainer,this,inbodyDocumentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
}
@@ -3754,7 +3761,7 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml,
{
QCString docsWithoutDir = a.docs;
QCString direction = extractDirection(docsWithoutDir);
- paramDocs+="@param"+direction+" "+a.name+" "+a.docs;
+ paramDocs+="@param"+direction+" "+a.name+" "+docsWithoutDir;
}
}
// feed the result to the documentation parser
@@ -3764,7 +3771,8 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml,
this, // memberDef
paramDocs, // docStr
TRUE, // indexWords
- FALSE // isExample
+ FALSE, // isExample
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT)
);
}
@@ -3958,7 +3966,8 @@ void MemberDefImpl::writeMemberDocSimple(OutputList &ol, const Definition *conta
{
ol.generateDoc(briefFile(),briefLine(),
getOuterScope()?getOuterScope():container,this,
- brief,FALSE,FALSE,0,TRUE,FALSE);
+ brief,FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
/* write detailed description */
@@ -3966,7 +3975,8 @@ void MemberDefImpl::writeMemberDocSimple(OutputList &ol, const Definition *conta
{
ol.generateDoc(docFile(),docLine(),
getOuterScope()?getOuterScope():container,this,
- detailed+"\n",FALSE,FALSE,0,FALSE,FALSE);
+ detailed+"\n",FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
@@ -4157,6 +4167,7 @@ void MemberDefImpl::warnIfUndocumentedParams() const
if (!Config_getBool(EXTRACT_ALL) &&
Config_getBool(WARN_IF_UNDOCUMENTED) &&
Config_getBool(WARN_NO_PARAMDOC) &&
+ isFunction() &&
!isDeleted() &&
!isReference() &&
!Doxygen::suppressDocWarnings)
@@ -4169,7 +4180,7 @@ void MemberDefImpl::warnIfUndocumentedParams() const
qPrint(qualifiedName()));
}
if (!m_impl->hasDocumentedReturnType &&
- isFunction() && hasDocumentation() && !returnType.isEmpty())
+ hasDocumentation() && !returnType.isEmpty())
{
warn_doc_error(getDefFileName(),getDefLine(),
"return type of member %s is not documented",
diff --git a/src/memberlist.cpp b/src/memberlist.cpp
index b5377a4..b8e5e89 100644
--- a/src/memberlist.cpp
+++ b/src/memberlist.cpp
@@ -517,7 +517,8 @@ void MemberList::writePlainDeclarations(OutputList &ol,
md->briefFile(),md->briefLine(),
cd,md,
md->briefDescription(),
- TRUE,FALSE,0,TRUE,FALSE
+ TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT)
);
if (rootNode && !rootNode->isEmpty())
{
@@ -684,7 +685,8 @@ void MemberList::writeDeclarations(OutputList &ol,
if (!st.isEmpty())
{
ol.startMemberSubtitle();
- ol.generateDoc("[generated]",-1,ctx,0,subtitle,FALSE,FALSE,0,FALSE,FALSE);
+ ol.generateDoc("[generated]",-1,ctx,0,subtitle,FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberSubtitle();
}
}
@@ -727,7 +729,8 @@ void MemberList::writeDeclarations(OutputList &ol,
{
//printf("Member group has docs!\n");
ol.startMemberGroupDocs();
- ol.generateDoc(mg->docFile(),mg->docLine(),ctx,0,mg->documentation()+"\n",FALSE,FALSE);
+ ol.generateDoc(mg->docFile(),mg->docLine(),ctx,0,mg->documentation()+"\n",FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberGroupDocs();
}
ol.startMemberGroup();
diff --git a/src/message.cpp b/src/message.cpp
index bbf578b..96c54a1 100644
--- a/src/message.cpp
+++ b/src/message.cpp
@@ -117,7 +117,7 @@ void msg(const char *fmt, ...)
#endif
if (Debug::isFlagSet(Debug::Time))
{
- printf("%.3f sec: ",((double)Debug::elapsedTime())/1000.0);
+ printf("%.3f sec: ",((double)Debug::elapsedTime()));
}
va_list args;
va_start(args, fmt);
diff --git a/src/namespacedef.cpp b/src/namespacedef.cpp
index 51454e0..6e0b45c 100644
--- a/src/namespacedef.cpp
+++ b/src/namespacedef.cpp
@@ -698,7 +698,8 @@ void NamespaceDefImpl::writeDetailedDescription(OutputList &ol,const QCString &t
ol.startTextBlock();
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF))
{
- ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
+ ol.generateDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
if (!briefDescription().isEmpty() && Config_getBool(REPEAT_BRIEF) &&
!documentation().isEmpty())
@@ -715,7 +716,8 @@ void NamespaceDefImpl::writeDetailedDescription(OutputList &ol,const QCString &t
}
if (!documentation().isEmpty())
{
- ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
}
ol.endTextBlock();
}
@@ -726,7 +728,8 @@ void NamespaceDefImpl::writeBriefDescription(OutputList &ol)
if (hasBriefDescription())
{
DocRoot *rootNode = validatingParseDoc(briefFile(),briefLine(),this,0,
- briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
+ briefDescription(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (rootNode && !rootNode->isEmpty())
{
ol.startParagraph();
@@ -1440,7 +1443,8 @@ void NamespaceSDict::writeDeclaration(OutputList &ol,const char *title,
if (!nd->briefDescription().isEmpty() && Config_getBool(BRIEF_MEMBER_DESC))
{
ol.startMemberDescription(nd->getOutputFileBase());
- ol.generateDoc(nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription(),FALSE,FALSE,0,TRUE);
+ ol.generateDoc(nd->briefFile(),nd->briefLine(),nd,0,nd->briefDescription(),FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberDescription();
}
ol.endMemberDeclaration(0,0);
diff --git a/src/outputlist.cpp b/src/outputlist.cpp
index 07d6491..e942465 100644
--- a/src/outputlist.cpp
+++ b/src/outputlist.cpp
@@ -115,7 +115,8 @@ void OutputList::generateDoc(const char *fileName,int startLine,
const Definition *ctx,const MemberDef * md,
const QCString &docStr,bool indexWords,
bool isExample,const char *exampleName,
- bool singleLine,bool linkFromIndex)
+ bool singleLine,bool linkFromIndex,
+ bool markdownSupport)
{
int count=0;
if (docStr.isEmpty()) return;
@@ -132,7 +133,7 @@ void OutputList::generateDoc(const char *fileName,int startLine,
DocRoot *root=0;
root = validatingParseDoc(fileName,startLine,
ctx,md,docStr,indexWords,isExample,exampleName,
- singleLine,linkFromIndex);
+ singleLine,linkFromIndex,markdownSupport);
if (count>0) writeDoc(root,ctx,md);
delete root;
}
diff --git a/src/outputlist.h b/src/outputlist.h
index 58e4425..9393a59 100644
--- a/src/outputlist.h
+++ b/src/outputlist.h
@@ -59,8 +59,9 @@ class OutputList : public OutputDocInterface
void generateDoc(const char *fileName,int startLine,
const Definition *ctx,const MemberDef *md,const QCString &docStr,
- bool indexWords,bool isExample,const char *exampleName=0,
- bool singleLine=FALSE,bool linkFromIndex=FALSE);
+ bool indexWords,bool isExample,const char *exampleName /*=0*/,
+ bool singleLine /*=FALSE*/,bool linkFromIndex /*=FALSE*/,
+ bool markdownSupport /*=FALSE*/);
void writeDoc(DocRoot *root,const Definition *ctx,const MemberDef *md);
void parseText(const QCString &textStr);
diff --git a/src/pagedef.cpp b/src/pagedef.cpp
index 011b647..09152de 100644
--- a/src/pagedef.cpp
+++ b/src/pagedef.cpp
@@ -3,8 +3,8 @@
* 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
+ * 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.
*
@@ -102,18 +102,18 @@ void PageDefImpl::findSectionsInDocumentation()
docFindSections(documentation(),this,docFile());
}
-GroupDef *PageDefImpl::getGroupDef() const
-{
+GroupDef *PageDefImpl::getGroupDef() const
+{
GroupList *groups = partOfGroups();
- return groups!=0 ? groups->getFirst() : 0;
+ return groups!=0 ? groups->getFirst() : 0;
}
-QCString PageDefImpl::getOutputFileBase() const
-{
- if (getGroupDef())
+QCString PageDefImpl::getOutputFileBase() const
+{
+ if (getGroupDef())
return getGroupDef()->getOutputFileBase();
- else
- return m_fileName;
+ else
+ return m_fileName;
}
void PageDefImpl::setFileName(const char *name)
@@ -142,7 +142,7 @@ void PageDefImpl::addInnerCompound(const Definition *const_def)
bool PageDefImpl::hasParentPage() const
{
- return getOuterScope() &&
+ return getOuterScope() &&
getOuterScope()->definitionType()==Definition::TypePage;
}
@@ -180,9 +180,9 @@ void PageDefImpl::writeDocumentation(OutputList &ol)
//printf("PageDefImpl::writeDocumentation: %s\n",getOutputFileBase().data());
ol.pushGeneratorState();
- //1.{
+ //1.{
- if (m_nestingLevel>0
+ if (m_nestingLevel>0
//&& // a sub page
//(Doxygen::mainPage==0 || getOuterScope()!=Doxygen::mainPage) // and not a subpage of the mainpage
)
@@ -195,14 +195,14 @@ void PageDefImpl::writeDocumentation(OutputList &ol)
}
ol.pushGeneratorState();
- //2.{
+ //2.{
ol.disableAllBut(OutputGenerator::Man);
startFile(ol,getOutputFileBase(),manPageName,title(),HLI_Pages,!generateTreeView);
ol.enableAll();
ol.disable(OutputGenerator::Man);
startFile(ol,getOutputFileBase(),pageName,title(),HLI_Pages,!generateTreeView);
ol.popGeneratorState();
- //2.}
+ //2.}
if (!generateTreeView)
{
@@ -229,7 +229,8 @@ void PageDefImpl::writeDocumentation(OutputList &ol)
if (si->title() != manPageName)
{
- ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endSection(si->label(),si->type());
}
}
@@ -248,7 +249,8 @@ void PageDefImpl::writeDocumentation(OutputList &ol)
ol.startPageDoc(si->title());
//ol.startSection(si->label,si->title,si->type);
startTitle(ol,getOutputFileBase(),this);
- ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc(docFile(),docLine(),this,0,si->title(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
//stringToSearchIndex(getOutputFileBase(),
// theTranslator->trPage(TRUE,TRUE)+" "+si->title,
// si->title);
@@ -287,13 +289,6 @@ void PageDefImpl::writeDocumentation(OutputList &ol)
void PageDefImpl::writePageDocumentation(OutputList &ol)
{
-
- bool markdownEnabled = Doxygen::markdownSupport;
- if (getLanguage()==SrcLangExt_Markdown)
- {
- Doxygen::markdownSupport = TRUE;
- }
-
ol.startTextBlock();
QCString docStr = documentation()+inbodyDocumentation();
if (hasBriefDescription() && !SectionManager::instance().find(name()))
@@ -310,12 +305,14 @@ void PageDefImpl::writePageDocumentation(OutputList &ol)
0, // memberdef
docStr, // docStr
TRUE, // index words
- FALSE // not an example
+ FALSE, // not an example
+ 0, // exampleName
+ FALSE, // singleLine
+ FALSE, // linkFromIndex
+ TRUE // markdown support
);
ol.endTextBlock();
- Doxygen::markdownSupport = markdownEnabled;
-
if (hasSubPages())
{
// for printed documentation we write subpages as section's of the
@@ -357,16 +354,16 @@ bool PageDefImpl::visibleInIndex() const
{
static bool externalPages = Config_getBool(EXTERNAL_PAGES);
return // not part of a group
- !getGroupDef() &&
+ !getGroupDef() &&
// not an externally defined page
- (!isReference() || externalPages)
+ (!isReference() || externalPages)
;
}
bool PageDefImpl::documentedPage() const
{
return // not part of a group
- !getGroupDef() &&
+ !getGroupDef() &&
// not an externally defined page
!isReference();
}
diff --git a/src/parserintf.h b/src/parserintf.h
index f11352e..911b707 100644
--- a/src/parserintf.h
+++ b/src/parserintf.h
@@ -26,12 +26,14 @@
#include <string>
#include "types.h"
+#include "containers.h"
class Entry;
class FileDef;
class CodeOutputInterface;
class MemberDef;
class Definition;
+class ClangTUParser;
/** \brief Abstract interface for outline parsers.
*
@@ -44,36 +46,18 @@ class OutlineParserInterface
public:
virtual ~OutlineParserInterface() {}
- /** Starts processing a translation unit (source files + headers).
- * After this call parseInput() is called with sameTranslationUnit
- * set to FALSE. If parseInput() returns additional include files,
- * these are also processed using parseInput() with
- * sameTranslationUnit set to TRUE. After that
- * finishTranslationUnit() is called.
- */
- virtual void startTranslationUnit(const char *fileName) = 0;
-
- /** Called after all files in a translation unit have been
- * processed.
- */
- virtual void finishTranslationUnit() = 0;
-
/** Parses a single input file with the goal to build an Entry tree.
* @param[in] fileName The full name of the file.
* @param[in] fileBuf The contents of the file (zero terminated).
* @param[in,out] root The root of the tree of Entry *nodes
* representing the information extracted from the file.
- * @param[in] sameTranslationUnit TRUE if this file was found in the same
- * translation unit (in the filesInSameTranslationUnit list
- * returned for another file).
- * @param[in,out] filesInSameTranslationUnit other files expected to be
- * found in the same translation unit (used for libclang)
+ * @param[in] clangParser The clang translation unit parser object
+ * or nullptr if disabled.
*/
virtual void parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList &filesInSameTranslationUnit) = 0;
+ ClangTUParser *clangParser) = 0;
/** Returns TRUE if the language identified by \a extension needs
* the C preprocessor to be run before feed the result to the input
diff --git a/src/perlmodgen.cpp b/src/perlmodgen.cpp
index a08e480..a6e9f22 100644
--- a/src/perlmodgen.cpp
+++ b/src/perlmodgen.cpp
@@ -1446,16 +1446,6 @@ static void addTemplateArgumentList(const ArgumentList &al,PerlModOutput &output
output.closeList();
}
-#if 0
-static void addMemberTemplateLists(MemberDef *md,PerlModOutput &output)
-{
- ClassDef *cd = md->getClassDef();
- const char *cname = cd ? cd->name().data() : 0;
- if (md->templateArguments()) // function template prefix
- addTemplateArgumentList(md->templateArguments(),output,cname);
-}
-#endif
-
static void addTemplateList(const ClassDef *cd,PerlModOutput &output)
{
addTemplateArgumentList(cd->templateArguments(),output,cd->name());
@@ -1473,7 +1463,8 @@ static void addPerlModDocBlock(PerlModOutput &output,
if (stext.isEmpty())
output.addField(name).add("{}");
else {
- DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext,FALSE,0);
+ DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,stext,FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
output.openHash(name);
PerlModDocVisitor *visitor = new PerlModDocVisitor(output);
root->accept(visitor);
diff --git a/src/plantuml.cpp b/src/plantuml.cpp
index 2e172ac..d020da0 100644
--- a/src/plantuml.cpp
+++ b/src/plantuml.cpp
@@ -208,21 +208,23 @@ static void runPlantumlContent(const QDict< QList <QCString> > &plantumlFiles,
QCString pumlType = "";
QCString pumlOutDir = "";
- QStrList &pumlIncludePathList = Config_getList(PLANTUML_INCLUDE_PATH);
- char *s=pumlIncludePathList.first();
- if (s)
+ const StringVector &pumlIncludePathList = Config_getList(PLANTUML_INCLUDE_PATH);
{
- pumlArgs += "-Dplantuml.include.path=\"";
- pumlArgs += s;
- s = pumlIncludePathList.next();
- }
- while (s)
- {
- pumlArgs += Portable::pathListSeparator();
- pumlArgs += s;
- s = pumlIncludePathList.next();
+ auto it = pumlIncludePathList.begin();
+ if (it!=pumlIncludePathList.end())
+ {
+ pumlArgs += "-Dplantuml.include.path=\"";
+ pumlArgs += it->c_str();
+ ++it;
+ }
+ while (it!=pumlIncludePathList.end())
+ {
+ pumlArgs += Portable::pathListSeparator();
+ pumlArgs += it->c_str();
+ ++it;
+ }
}
- if (pumlIncludePathList.first()) pumlArgs += "\" ";
+ if (!pumlIncludePathList.empty()) pumlArgs += "\" ";
pumlArgs += "-Djava.awt.headless=true -jar \""+plantumlJarPath+"plantuml.jar\" ";
if (!plantumlConfigFile.isEmpty())
{
diff --git a/src/pre.l b/src/pre.l
index 5981147..18b4615 100644
--- a/src/pre.l
+++ b/src/pre.l
@@ -26,11 +26,16 @@
* includes
*/
+#include "doxygen.h"
+
#include <stack>
#include <deque>
#include <algorithm>
#include <utility>
+#if MULTITHREADED_INPUT
#include <mutex>
+#include <thread>
+#endif
#include <stdio.h>
#include <assert.h>
@@ -45,7 +50,6 @@
#include "pre.h"
#include "constexp.h"
#include "define.h"
-#include "doxygen.h"
#include "message.h"
#include "util.h"
#include "defargs.h"
@@ -92,275 +96,138 @@ struct FileState
QCString fileName;
};
-/** A dictionary of references to Define objects. */
-typedef std::map< std::string,Define* > DefineMapRef;
+struct PreIncludeInfo
+{
+ PreIncludeInfo(const char *fn,FileDef *srcFd, FileDef *dstFd,const char *iName,bool loc, bool imp)
+ : fileName(fn), fromFileDef(srcFd), toFileDef(dstFd), includeName(iName), local(loc), imported(imp)
+ {
+ }
+ QCString fileName; // file name in which the include statement was found
+ FileDef *fromFileDef; // filedef in which the include statement was found
+ FileDef *toFileDef; // filedef to which the include is pointing
+ QCString includeName; // name used in the #include statement
+ bool local; // is it a "local" or <global> include
+ bool imported; // include via "import" keyword (Objective-C)
+};
/** A dictionary of managed Define objects. */
typedef std::map< std::string,std::unique_ptr<Define> > DefineMapOwning;
-/** @brief Singleton that manages the defines available while
+/** @brief Class that manages the defines available while
* preprocessing files.
*/
class DefineManager
{
- /** Local class used to hold the defines for a single file */
- class DefinesPerFile
- {
- public:
- /** Creates an empty container for defines */
- DefinesPerFile(DefineManager *parent)
- : m_parent(parent)
- {
- }
- /** Destroys the object */
- virtual ~DefinesPerFile()
- {
- }
- /** Adds a define in the context of a file. Will replace
- * an existing define with the same name (redefinition)
- * @param def The Define object to add. Ownership will be transferred.
- */
- void addDefine(std::unique_ptr<Define> &&def)
- {
- auto it = m_defines.find(def->name.data());
- if (it!=m_defines.end()) // redefine
- {
- m_defines.erase(it);
- }
- m_defines.insert(std::make_pair(toStdString(def->name),std::move(def)));
- }
- /** Adds an include file for this file
- * @param fileName The name of the include file
- */
- void addInclude(const char *fileName)
- {
- m_includedFiles.insert(fileName);
- }
- void collectDefines(DefineMapRef &map,StringSet &includeStack);
- private:
- DefineManager *m_parent;
- DefineMapOwning m_defines;
- StringSet m_includedFiles;
- };
-
- public:
- friend class DefinesPerFile;
-
- /** Creates a new DefineManager object */
- DefineManager()
+ private:
+ /** Local class used to hold the defines for a single file */
+ class DefinesPerFile
{
- }
+ public:
+ /** Creates an empty container for defines */
+ DefinesPerFile(DefineManager *parent)
+ : m_parent(parent)
+ {
+ }
+ void addInclude(std::string fileName)
+ {
+ m_includedFiles.insert(fileName);
+ }
+ void store(const DefineMapOwning &fromMap)
+ {
+ for (auto &kv : fromMap)
+ {
+ m_defines.emplace(kv.first,std::make_unique<Define>(*kv.second.get()));
+ }
+ }
+ void retrieve(DefineMapOwning &toMap)
+ {
+ StringSet includeStack;
+ retrieveRec(toMap,includeStack);
+ }
+ void retrieveRec(DefineMapOwning &toMap,StringSet &includeStack)
+ {
+ for (auto incFile : m_includedFiles)
+ {
+ DefinesPerFile *dpf = m_parent->find(incFile);
+ if (dpf && includeStack.find(incFile)==includeStack.end())
+ {
+ //printf(" processing include %s\n",incFile.data());
+ includeStack.insert(incFile);
+ dpf->retrieveRec(toMap,includeStack);
+ }
+ }
+ for (auto &kv : m_defines)
+ {
+ toMap.emplace(kv.first,std::make_unique<Define>(*kv.second.get()));
+ }
+ }
+ private:
+ DefineManager *m_parent;
+ DefineMapOwning m_defines;
+ StringSet m_includedFiles;
+ };
- /** Destroys the object */
- virtual ~DefineManager()
- {
- }
+ friend class DefinesPerFile;
+ public:
- /** Starts a context in which defines are collected.
- * Called at the start of a new file that is preprocessed.
- * @param fileName the name of the file to process.
- */
- void startContext(const char *fileName)
- {
-#if MULTITHREADED_INPUT
- std::unique_lock<std::mutex> lock(m_mutex);
-#endif
- //printf("DefineManager::startContext()\n");
- m_contextDefines.clear();
- if (fileName==0) return;
- //DefinesPerFile *dpf = m_fileMap.find(fileName);
- auto it = m_fileMap.find(fileName);
- if (it==m_fileMap.end())
- {
- //printf("New file!\n");
- m_fileMap.emplace(toStdString(fileName),std::make_unique<DefinesPerFile>(this));
- }
- }
- /** Ends the context started with startContext() freeing any
- * defines collected within in this context.
- */
- void endContext()
+ void addInclude(std::string fromFileName,std::string toFileName)
{
-#if MULTITHREADED_INPUT
- std::unique_lock<std::mutex> lock(m_mutex);
-#endif
- //printf("DefineManager::endContext()\n");
- m_contextDefines.clear();
- }
- /** Add an included file to the current context.
- * If the file has been pre-processed already, all defines are added
- * to the context.
- * @param fileName The name of the include file to add to the context.
- */
- void addFileToContext(const char *fileName)
- {
- if (fileName==0) return;
-#if MULTITHREADED_INPUT
- std::unique_lock<std::mutex> lock(m_mutex);
-#endif
-
- //printf("DefineManager::addFileToContext(%s)\n",fileName);
- auto it = m_fileMap.find(fileName);
- if (it==m_fileMap.end())
- {
- //printf("New file!\n");
- m_fileMap.emplace(toStdString(fileName),std::make_unique<DefinesPerFile>(this));
- }
- else
+ auto it = m_fileMap.find(fromFileName);
+ if (it!=m_fileMap.end())
{
- //printf("existing file!\n");
- StringSet includeStack;
- it->second->collectDefines(m_contextDefines,includeStack);
+ auto &dpf = it->second;
+ dpf->addInclude(toFileName);
}
}
- /** Add a define to the manager object.
- * @param fileName The file in which the define was found
- * @param def The Define object to add. Ownership will be transferred.
- */
- void addDefine(const char *fileName,std::unique_ptr<Define> &&def)
+ void store(std::string fileName,const DefineMapOwning &fromMap)
{
- if (fileName==0) return;
-
-#if MULTITHREADED_INPUT
- std::unique_lock<std::mutex> lock(m_mutex);
-#endif
- //printf("DefineManager::addDefine(%s,%s)\n",fileName,def->name.data());
-
- m_contextDefines[def->name.data()] = def.get();
-
auto it = m_fileMap.find(fileName);
if (it==m_fileMap.end())
{
- auto ptr = std::make_unique<DefinesPerFile>(this);
- ptr->addDefine(std::move(def));
- m_fileMap.emplace(toStdString(fileName),std::move(ptr));
- }
- else
- {
- it->second->addDefine(std::move(def));
+ it = m_fileMap.emplace(fileName,std::make_unique<DefinesPerFile>(this)).first;
}
+ it->second->store(fromMap);
}
- /** Add an include relation to the manager object.
- * @param fromFileName file name in which the include was found.
- * @param toFileName file name that is included.
- */
- void addInclude(const char *fromFileName,const char *toFileName)
+ void retrieve(std::string fileName,DefineMapOwning &toMap)
{
-#if MULTITHREADED_INPUT
- std::unique_lock<std::mutex> lock(m_mutex);
-#endif
- //printf("DefineManager::addInclude(%s,%s)\n",fromFileName,toFileName);
- if (fromFileName==0 || toFileName==0) return;
- auto it = m_fileMap.find(fromFileName);
- if (it==m_fileMap.end())
- {
- auto ptr = std::make_unique<DefinesPerFile>(this);
- ptr->addInclude(toFileName);
- m_fileMap.emplace(toStdString(fromFileName),std::move(ptr));
- }
- else
- {
- it->second->addInclude(toFileName);
- }
- }
- /** Returns a reference to a Define object given its name or 0 if the Define does
- * not exist.
- */
- Define *isDefined(const char *name)
- {
-#if MULTITHREADED_INPUT
- std::unique_lock<std::mutex> lock(m_mutex);
-#endif
- Define *d=0;
- auto it = m_contextDefines.find(name);
- if (it!=m_contextDefines.end())
+ auto it = m_fileMap.find(fileName);
+ if (it!=m_fileMap.end())
{
- d = it->second;
- if (d->undef)
- {
- d=0;
- }
+ auto &dpf = it->second;
+ dpf->retrieve(toMap);
}
- //printf("isDefined(%s)=%p\n",name,d);
- return d;
}
- /** Returns a reference to the defines found in the current context. */
- const DefineMapRef &defineContext() const
+ bool alreadyProcessed(std::string fileName) const
{
- return m_contextDefines;
+ return m_fileMap.find(fileName)!=m_fileMap.end();
}
private:
- /** Helper function to collect all define for a given file */
- void collectDefinesForFile(const char *fileName,DefineMapRef &map)
- {
- if (fileName==0) return;
- auto it = m_fileMap.find(fileName);
- if (it!=m_fileMap.end())
- {
- StringSet includeStack;
- it->second->collectDefines(map,includeStack);
- }
- }
-
/** Helper function to return the DefinesPerFile object for a given file name. */
- DefinesPerFile *find(const char *fileName) const
+ DefinesPerFile *find(std::string fileName) const
{
- if (fileName==0) return nullptr;
auto it = m_fileMap.find(fileName);
return it!=m_fileMap.end() ? it->second.get() : nullptr;
}
- std::map< std::string,std::unique_ptr<DefinesPerFile> > m_fileMap;
- DefineMapRef m_contextDefines;
-#if MULTITHREADED_INPUT
- std::mutex m_mutex;
-#endif
+ std::unordered_map< std::string, std::unique_ptr<DefinesPerFile> > m_fileMap;
};
-/** Collects all defines for a file and all files that the file includes.
- * This function will recursively call itself for each file.
- * @param dict The dictionary to fill with the defines. A redefine will
- * replace a previous definition.
- * @param includeStack The stack of includes, used to stop recursion in
- * case there is a cyclic include dependency.
- */
-void DefineManager::DefinesPerFile::collectDefines(
- DefineMapRef &map,StringSet &includeStack)
-{
- //printf("DefinesPerFile::collectDefines #defines=%d\n",m_defines.count());
- {
- for (auto incFile : m_includedFiles)
- {
- DefinesPerFile *dpf = m_parent->find(incFile.c_str());
- if (dpf && includeStack.find(incFile)==includeStack.end())
- {
- //printf(" processing include %s\n",incFile.data());
- includeStack.insert(incFile);
- dpf->collectDefines(map,includeStack);
- }
- }
- }
- {
- for (auto &kv : m_defines)
- {
- const std::unique_ptr<Define> &def = kv.second;
- map[def->name.data()] = def.get();
- //printf(" adding define %s\n",def->name.data());
- }
- }
-}
-
-
/* -----------------------------------------------------------------
*
* global state
*/
-static StringUnorderedSet g_allIncludes;
+#if MULTITHREADED_INPUT
+static std::mutex g_debugMutex;
+static std::mutex g_globalDefineMutex;
+//static std::mutex g_addIncludeRelationMutex;
+//static std::mutex g_macroDefinitionsMutex;
+static std::mutex g_updateGlobals;
+#endif
static DefineManager g_defineManager;
@@ -424,6 +291,9 @@ struct preYY_state
std::unordered_map<std::string,Define*> expandedDict;
StringUnorderedSet expanded;
ConstExpressionParser constExpParser;
+ DefineMapOwning contextDefines;
+ DefineList macroDefinitions;
+ LinkedMap<PreIncludeInfo> includeRelations;
};
// stateless functions
@@ -444,9 +314,10 @@ 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 addMacroDefinition(yyscan_t yyscanner);
-static std::unique_ptr<Define> newDefine(yyscan_t yyscanner);
+static void addDefine(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);
+static Define * isDefined(yyscan_t yyscanner,const char *name);
/* ----------------------------------------------------------------- */
@@ -539,7 +410,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
!(
(yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
yyextra->macroExpansion &&
- (def=g_defineManager.isDefined(name)) &&
+ (def=isDefined(yyscanner,name)) &&
/*macroIsAccessible(def) &&*/
(!yyextra->expandOnlyPredef || def->isPredefined)
)
@@ -665,7 +536,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
yyextra->expectGuard = FALSE;
Define *def=0;
//def=yyextra->globalDefineDict->find(yytext);
- //def=g_defineManager.isDefined(yytext);
+ //def=isDefined(yyscanner,yytext);
//printf("Search for define %s found=%d yyextra->includeStack.empty()=%d "
// "yyextra->curlyCount=%d yyextra->macroExpansion=%d yyextra->expandOnlyPredef=%d "
// "isPreDefined=%d\n",yytext,def ? 1 : 0,
@@ -674,7 +545,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
// );
if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
yyextra->macroExpansion &&
- (def=g_defineManager.isDefined(yytext)) &&
+ (def=isDefined(yyscanner,yytext)) &&
/*(def->isPredefined || macroIsAccessible(def)) && */
(!yyextra->expandOnlyPredef || def->isPredefined)
)
@@ -702,7 +573,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
Define *def=0;
if ((yyextra->includeStack.empty() || yyextra->curlyCount>0) &&
yyextra->macroExpansion &&
- (def=g_defineManager.isDefined(yytext)) &&
+ (def=isDefined(yyscanner,yytext)) &&
def->nargs==-1 &&
/*(def->isPredefined || macroIsAccessible(def)) &&*/
(!yyextra->expandOnlyPredef || def->isPredefined)
@@ -919,7 +790,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
<Command>. {yyextra->yyColNr+=(int)yyleng;}
<UndefName>{ID} {
Define *def;
- if ((def=g_defineManager.isDefined(yytext))
+ if ((def=isDefined(yyscanner,yytext))
/*&& !def->isPredefined*/
&& !def->nonRecursive
)
@@ -961,7 +832,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
<DefinedExpr1,DefinedExpr2>\\\n { yyextra->yyLineNr++; outputChar(yyscanner,'\n'); }
<DefinedExpr1>{ID} {
- if (g_defineManager.isDefined(yytext) || yyextra->guardName==yytext)
+ if (isDefined(yyscanner,yytext) || yyextra->guardName==yytext)
yyextra->guardExpr+=" 1L ";
else
yyextra->guardExpr+=" 0L ";
@@ -969,7 +840,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
BEGIN(Guard);
}
<DefinedExpr2>{ID} {
- if (g_defineManager.isDefined(yytext) || yyextra->guardName==yytext)
+ if (isDefined(yyscanner,yytext) || yyextra->guardName==yytext)
yyextra->guardExpr+=" 1L ";
else
yyextra->guardExpr+=" 0L ";
@@ -1570,17 +1441,11 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
{
addMacroDefinition(yyscanner);
}
- def=g_defineManager.isDefined(yyextra->defName);
+ def=isDefined(yyscanner,yyextra->defName);
if (def==0) // new define
{
//printf("new define '%s'!\n",yyextra->defName.data());
- g_defineManager.addDefine(yyextra->yyFileName,newDefine(yyscanner));
-
- // also add it to the local file list if it is a source file
- //if (yyextra->isSource && yyextra->includeStack.empty())
- //{
- // yyextra->fileDefineDict->insert(yyextra->defName,nd);
- //}
+ addDefine(yyscanner);
}
else if (def /*&& macroIsAccessible(def)*/)
// name already exists
@@ -1652,6 +1517,7 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
}
else
{
+ QCString toFileName = yyextra->yyFileName;
const std::unique_ptr<FileState> &fs=yyextra->includeStack.back();
//fileDefineCache->merge(yyextra->yyFileName,fs->fileName);
YY_BUFFER_STATE oldBuf = YY_CURRENT_BUFFER;
@@ -1672,6 +1538,31 @@ CHARLIT (("'"\\[0-7]{1,3}"'")|("'"\\."'")|("'"[^'\\\n]{1,4}"'"))
outputArray(yyscanner,lineStr.data(),lineStr.length());
yyextra->includeStack.pop_back();
+
+#if MULTITHREADED_INPUT
+ {
+ std::lock_guard<std::mutex> lock(g_globalDefineMutex);
+#endif
+ // to avoid deadlocks we allow multiple threads to process the same header file.
+ // The first one to finish will store the results globally. After that the
+ // next time the same file is encountered, the stored data is used and the file
+ // is not processed again.
+ if (!g_defineManager.alreadyProcessed(toFileName.str()))
+ {
+ // now that the file is completely processed, prevent it from processing it again
+ g_defineManager.addInclude(yyextra->yyFileName.str(),toFileName.str());
+ g_defineManager.store(toFileName.str(),yyextra->contextDefines);
+ }
+ else
+ {
+ if (Debug::isFlagSet(Debug::Preprocessor))
+ {
+ Debug::print(Debug::Preprocessor,0,"#include %s: was already processed by another thread! not storing data...\n",qPrint(toFileName));
+ }
+ }
+#if MULTITHREADED_INPUT
+ }
+#endif
}
}
<*>"/*"/"*/" |
@@ -1787,41 +1678,44 @@ static void setCaseDone(yyscan_t yyscanner,bool value)
}
-static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,bool &alreadyIncluded)
+static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,bool &alreadyProcessed)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
- alreadyIncluded = FALSE;
+ alreadyProcessed = FALSE;
FileState *fs = 0;
//printf("checkAndOpenFile(%s)\n",fileName.data());
QFileInfo fi(fileName);
if (fi.exists() && fi.isFile())
{
- const QStrList &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
- if (patternMatch(fi,&exclPatterns)) return 0;
+ const StringVector &exclPatterns = Config_getList(EXCLUDE_PATTERNS);
+ if (patternMatch(fi,exclPatterns)) return 0;
QCString absName = fi.absFilePath().utf8();
// global guard
if (state->curlyCount==0) // not #include inside { ... }
{
- if (g_allIncludes.find(absName.data())!=g_allIncludes.end())
+#if MULTITHREADED_INPUT
+ std::lock_guard<std::mutex> lock(g_globalDefineMutex);
+#endif
+
+ if (g_defineManager.alreadyProcessed(absName.str()))
{
- alreadyIncluded = TRUE;
+ alreadyProcessed = TRUE;
//printf(" already included 1\n");
return 0; // already done
}
- g_allIncludes.insert(absName.data());
}
// check include stack for absName
- alreadyIncluded = std::any_of(
+ alreadyProcessed = std::any_of(
state->includeStack.begin(),
state->includeStack.end(),
[absName](const std::unique_ptr<FileState> &lfs)
{ return lfs->fileName==absName; }
);
- if (alreadyIncluded)
+ if (alreadyProcessed)
{
//printf(" already included 2\n");
return 0;
@@ -1844,20 +1738,20 @@ static FileState *checkAndOpenFile(yyscan_t yyscanner,const QCString &fileName,b
return fs;
}
-static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localInclude,bool &alreadyIncluded)
+static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localInclude,bool &alreadyProcessed)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
//printf("** findFile(%s,%d) state->yyFileName=%s\n",fileName,localInclude,state->yyFileName.data());
if (Portable::isAbsolutePath(fileName))
{
- FileState *fs = checkAndOpenFile(yyscanner,fileName,alreadyIncluded);
+ FileState *fs = checkAndOpenFile(yyscanner,fileName,alreadyProcessed);
if (fs)
{
setFileName(yyscanner,fileName);
state->yyLineNr=1;
return fs;
}
- else if (alreadyIncluded)
+ else if (alreadyProcessed)
{
return 0;
}
@@ -1868,14 +1762,14 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn
if (fi.exists())
{
QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+fileName;
- FileState *fs = checkAndOpenFile(yyscanner,absName,alreadyIncluded);
+ FileState *fs = checkAndOpenFile(yyscanner,absName,alreadyProcessed);
if (fs)
{
setFileName(yyscanner,absName);
state->yyLineNr=1;
return fs;
}
- else if (alreadyIncluded)
+ else if (alreadyProcessed)
{
return 0;
}
@@ -1889,7 +1783,7 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn
{
std::string absName = path+"/"+fileName;
//printf(" Looking for %s in %s\n",fileName,path.c_str());
- FileState *fs = checkAndOpenFile(yyscanner,absName.c_str(),alreadyIncluded);
+ FileState *fs = checkAndOpenFile(yyscanner,absName.c_str(),alreadyProcessed);
if (fs)
{
setFileName(yyscanner,absName.c_str());
@@ -1897,7 +1791,7 @@ static FileState *findFile(yyscan_t yyscanner, const char *fileName,bool localIn
//printf(" -> found it\n");
return fs;
}
- else if (alreadyIncluded)
+ else if (alreadyProcessed)
{
return 0;
}
@@ -2439,7 +2333,7 @@ static bool expandExpression(yyscan_t yyscanner,QCString &expr,QCString *rest,in
{
if (state->expandedDict.find(macroName.data())==state->expandedDict.end()) // expand macro
{
- Define *def=g_defineManager.isDefined(macroName);
+ Define *def=isDefined(yyscanner,macroName);
if (macroName=="defined")
{
//printf("found defined inside macro definition '%s'\n",expr.right(expr.length()-p).data());
@@ -2792,7 +2686,7 @@ static QCString expandMacro(yyscan_t yyscanner,const QCString &name)
return n;
}
-static std::unique_ptr<Define> newDefine(yyscan_t yyscanner)
+static void addDefine(yyscan_t yyscanner)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
std::unique_ptr<Define> def = std::make_unique<Define>();
@@ -2808,11 +2702,16 @@ static std::unique_ptr<Define> newDefine(yyscan_t yyscanner)
// def->fileDef ? def->fileDef->name().data() : def->fileName.data());
//printf("newDefine: '%s'->'%s'\n",def->name.data(),def->definition.data());
if (!def->name.isEmpty() &&
- Doxygen::expandAsDefinedSet.find(def->name.data())!=Doxygen::expandAsDefinedSet.end())
+ Doxygen::expandAsDefinedSet.find(def->name.str())!=Doxygen::expandAsDefinedSet.end())
{
def->isPredefined=TRUE;
}
- return def;
+ auto it = state->contextDefines.find(def->name.str());
+ if (it!=state->contextDefines.end()) // redefine
+ {
+ state->contextDefines.erase(it);
+ }
+ state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def)));
}
static void addMacroDefinition(yyscan_t yyscanner)
@@ -2854,7 +2753,9 @@ static void addMacroDefinition(yyscan_t yyscanner)
{
define->definition = litTextStripped;
}
- Doxygen::macroDefinitions.push_back(std::move(define));
+ {
+ state->macroDefinitions.push_back(std::move(define));
+ }
}
static inline void outputChar(yyscan_t yyscanner,char c)
@@ -2869,10 +2770,47 @@ static inline void outputArray(yyscan_t yyscanner,const char *a,int len)
if (state->includeStack.empty() || state->curlyCount>0) state->outputBuf->addArray(a,len);
}
+static QCString determineAbsoluteIncludeName(const QCString &curFile,const QCString &incFileName)
+{
+ bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
+ QCString absIncFileName = incFileName;
+ QFileInfo fi(curFile);
+ if (fi.exists())
+ {
+ QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+incFileName;
+ QFileInfo fi2(absName);
+ if (fi2.exists())
+ {
+ absIncFileName=fi2.absFilePath().utf8();
+ }
+ else if (searchIncludes) // search in INCLUDE_PATH as well
+ {
+ const StringVector &includePath = Config_getList(INCLUDE_PATH);
+ for (const auto &incPath : includePath)
+ {
+ QFileInfo fi3(incPath.c_str());
+ if (fi3.exists() && fi3.isDir())
+ {
+ absName = QCString(fi3.absFilePath().utf8())+"/"+incFileName;
+ //printf("trying absName=%s\n",absName.data());
+ QFileInfo fi4(absName);
+ if (fi4.exists())
+ {
+ absIncFileName=fi4.absFilePath().utf8();
+ break;
+ }
+ //printf( "absIncFileName = %s\n", absIncFileName.data() );
+ }
+ }
+ }
+ //printf( "absIncFileName = %s\n", absIncFileName.data() );
+ }
+ return absIncFileName;
+}
+
static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
- bool searchIncludes = Config_getBool(SEARCH_INCLUDES);
uint i=0;
// find the start of the include file name
@@ -2904,51 +2842,13 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
int oldLineNr = state->yyLineNr;
//printf("Searching for '%s'\n",incFileName.data());
- // absIncFileName avoids difficulties for incFileName starting with "../" (bug 641336)
- QCString absIncFileName = incFileName;
- {
- QFileInfo fi(state->yyFileName);
- if (fi.exists())
- {
- QCString absName = QCString(fi.dirPath(TRUE).data())+"/"+incFileName;
- QFileInfo fi2(absName);
- if (fi2.exists())
- {
- absIncFileName=fi2.absFilePath().utf8();
- }
- else if (searchIncludes) // search in INCLUDE_PATH as well
- {
- QStrList &includePath = Config_getList(INCLUDE_PATH);
- char *incPath=includePath.first();
- while (incPath)
- {
- QFileInfo fi3(incPath);
- if (fi3.exists() && fi3.isDir())
- {
- absName = QCString(fi3.absFilePath().utf8())+"/"+incFileName;
- //printf("trying absName=%s\n",absName.data());
- QFileInfo fi4(absName);
- if (fi4.exists())
- {
- absIncFileName=fi4.absFilePath().utf8();
- break;
- }
- //printf( "absIncFileName = %s\n", absIncFileName.data() );
- }
- incPath=includePath.next();
- }
- }
- //printf( "absIncFileName = %s\n", absIncFileName.data() );
- }
- }
- g_defineManager.addInclude(state->yyFileName,absIncFileName);
- g_defineManager.addFileToContext(absIncFileName);
+ QCString absIncFileName = determineAbsoluteIncludeName(state->yyFileName,incFileName);
// findFile will overwrite state->yyFileDef if found
FileState *fs;
- bool alreadyIncluded = FALSE;
+ bool alreadyProcessed = FALSE;
//printf("calling findFile(%s)\n",incFileName.data());
- if ((fs=findFile(yyscanner,incFileName,localInclude,alreadyIncluded))) // see if the include file can be found
+ if ((fs=findFile(yyscanner,incFileName,localInclude,alreadyProcessed))) // see if the include file can be found
{
//printf("Found include file!\n");
if (Debug::isFlagSet(Debug::Preprocessor))
@@ -2959,24 +2859,25 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
}
//msg("#include %s: parsing...\n",incFileName.data());
}
- if (oldFileDef)
+
+ if (state->includeStack.empty() && oldFileDef)
{
- // add include dependency to the file in which the #include was found
- bool ambig;
- // change to absolute name for bug 641336
- FileDef *incFd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig);
- oldFileDef->addIncludeDependency(ambig ? 0 : incFd,incFileName,localInclude,state->isImported,FALSE);
- // add included by dependency
- if (state->yyFileDef)
+ PreIncludeInfo *ii = state->includeRelations.find(absIncFileName);
+ if (ii==0)
{
- //printf("Adding include dependency %s->%s\n",oldFileDef->name().data(),incFileName.data());
- state->yyFileDef->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,state->isImported);
+ bool ambig;
+ FileDef *incFd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig);
+ state->includeRelations.add(
+ absIncFileName,
+ oldFileDef,
+ ambig?nullptr:incFd,
+ incFileName,
+ localInclude,
+ state->isImported
+ );
}
}
- else if (state->inputFileDef)
- {
- state->inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,state->isImported,TRUE);
- }
+
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
fs->bufState = YY_CURRENT_BUFFER;
fs->lineNr = oldLineNr;
@@ -3001,32 +2902,37 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
}
else
{
- //printf(" calling findFile(%s) alreadyInc=%d\n",incFileName.data(),alreadyIncluded);
- if (oldFileDef)
+ if (alreadyProcessed) // if this header was already process we can just copy the stored macros
+ // in the local context
{
- bool ambig;
-
- // change to absolute name for bug 641336
- FileDef *fd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig);
- //printf("%s::findFileDef(%s)=%p\n",oldFileDef->name().data(),incFileName.data(),fd);
- // add include dependency to the file in which the #include was found
- oldFileDef->addIncludeDependency(ambig ? 0 : fd,incFileName,localInclude,state->isImported,FALSE);
- // add included by dependency
- if (fd)
- {
- //printf("Adding include dependency (2) %s->%s ambig=%d\n",oldFileDef->name().data(),fd->name().data(),ambig);
- fd->addIncludedByDependency(oldFileDef,oldFileDef->docName(),localInclude,state->isImported);
- }
+#if MULTITHREADED_INPUT
+ std::lock_guard<std::mutex> lock(g_globalDefineMutex);
+#endif
+ g_defineManager.retrieve(absIncFileName.str(),state->contextDefines);
}
- else if (state->inputFileDef)
+
+ if (state->includeStack.empty() && oldFileDef)
{
- state->inputFileDef->addIncludeDependency(0,absIncFileName,localInclude,state->isImported,TRUE);
+ PreIncludeInfo *ii = state->includeRelations.find(absIncFileName);
+ if (ii==0)
+ {
+ bool ambig;
+ FileDef *incFd = findFileDef(Doxygen::inputNameLinkedMap,absIncFileName,ambig);
+ ii = state->includeRelations.add(absIncFileName,
+ oldFileDef,
+ ambig?0:incFd,
+ incFileName,
+ localInclude,
+ state->isImported
+ );
+ }
}
+
if (Debug::isFlagSet(Debug::Preprocessor))
{
- if (alreadyIncluded)
+ if (alreadyProcessed)
{
- Debug::print(Debug::Preprocessor,0,"#include %s: already included! skipping...\n",qPrint(incFileName));
+ Debug::print(Debug::Preprocessor,0,"#include %s: already processed! skipping...\n",qPrint(incFileName));
}
else
{
@@ -3034,10 +2940,11 @@ static void readIncludeFile(yyscan_t yyscanner,const QCString &inc)
}
//printf("error: include file %s not found\n",yytext);
}
- if (state->curlyCount>0 && !alreadyIncluded) // failed to find #include inside { ... }
+ if (state->curlyCount>0 && !alreadyProcessed) // failed to find #include inside { ... }
{
warn(state->yyFileName,state->yyLineNr,"include file %s not found, perhaps you forgot to add its directory to INCLUDE_PATH?",incFileName.data());
}
+
}
}
}
@@ -3186,17 +3093,34 @@ static void unputChar(yyscan_t yyscanner,const QCString &expr,QCString *rest,uin
//printf("result: unputChar(%s,%s,%d,%c)\n",expr.data(),rest ? rest->data() : 0,pos,c);
}
+/** Returns a reference to a Define object given its name or 0 if the Define does
+ * not exist.
+ */
+static Define *isDefined(yyscan_t yyscanner,const char *name)
+{
+ YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
+ Define *d=0;
+ auto it = state->contextDefines.find(name);
+ if (it!=state->contextDefines.end())
+ {
+ d = it->second.get();
+ if (d->undef)
+ {
+ d=0;
+ }
+ }
+ return d;
+}
+
static void initPredefined(yyscan_t yyscanner,const char *fileName)
{
YY_EXTRA_TYPE state = preYYget_extra(yyscanner);
// add predefined macros
- char *defStr;
- QStrList &predefList = Config_getList(PREDEFINED);
- QStrListIterator sli(predefList);
- for (sli.toFirst();(defStr=sli.current());++sli)
+ const StringVector &predefList = Config_getList(PREDEFINED);
+ for (const auto &defStr : predefList)
{
- QCString ds = defStr;
+ QCString ds = defStr.c_str();
int i_equals=ds.find('=');
int i_obrace=ds.find('(');
int i_cbrace=ds.find(')');
@@ -3267,7 +3191,7 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
def->nonRecursive = nonRecursive;
def->fileDef = state->yyFileDef;
def->fileName = fileName;
- g_defineManager.addDefine(state->yyFileName,std::move(def));
+ state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def)));
//printf("#define '%s' '%s' #nargs=%d\n",
// def->name.data(),def->definition.data(),def->nargs);
@@ -3299,7 +3223,7 @@ static void initPredefined(yyscan_t yyscanner,const char *fileName)
def->nonRecursive = nonRecursive;
def->fileDef = state->yyFileDef;
def->fileName = fileName;
- g_defineManager.addDefine(state->yyFileName,std::move(def));
+ state->contextDefines.insert(std::make_pair(toStdString(def->name),std::move(def)));
}
}
}
@@ -3333,6 +3257,7 @@ Preprocessor::~Preprocessor()
void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output)
{
+// printf("Preprocessor::processFile(%s)\n",fileName);
yyscan_t yyscanner = p->yyscanner;
YY_EXTRA_TYPE state = preYYget_extra(p->yyscanner);
struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
@@ -3356,12 +3281,13 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
state->outputBuf=&output;
state->includeStack.clear();
state->expandedDict.clear();
+ state->contextDefines.clear();
while (!state->condStack.empty()) state->condStack.pop();
- //state->fileDefineDict->clear();
setFileName(yyscanner,fileName);
+
state->inputFileDef = state->yyFileDef;
- g_defineManager.startContext(state->yyFileName);
+ //yyextra->defineManager.startContext(state->yyFileName);
initPredefined(yyscanner,fileName);
@@ -3392,6 +3318,9 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
if (Debug::isFlagSet(Debug::Preprocessor))
{
+#if MULTITHREADED_INPUT
+ std::lock_guard<std::mutex> lock(g_debugMutex);
+#endif
char *orgPos=output.data()+orgOffset;
char *newPos=output.data()+output.curPos();
Debug::print(Debug::Preprocessor,0,"Preprocessor output of %s (size: %d bytes):\n",fileName,newPos-orgPos);
@@ -3404,14 +3333,13 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
orgPos++;
}
Debug::print(Debug::Preprocessor,0,"\n---------\n");
- if (g_defineManager.defineContext().size()>0)
+ if (yyextra->contextDefines.size()>0)
{
Debug::print(Debug::Preprocessor,0,"Macros accessible in this file (%s):\n", fileName);
Debug::print(Debug::Preprocessor,0,"---------\n");
- for (auto &kv : g_defineManager.defineContext())
+ for (auto &kv : yyextra->contextDefines)
{
- Define *def = kv.second;
- Debug::print(Debug::Preprocessor,0,"%s ",qPrint(def->name));
+ Debug::print(Debug::Preprocessor,0,"%s ",qPrint(kv.second->name));
}
Debug::print(Debug::Preprocessor,0,"\n---------\n");
}
@@ -3420,8 +3348,29 @@ void Preprocessor::processFile(const char *fileName,BufStr &input,BufStr &output
Debug::print(Debug::Preprocessor,0,"No macros accessible in this file (%s).\n", fileName);
}
}
- g_defineManager.endContext();
+
+ {
+#if MULTITHREADED_INPUT
+ std::lock_guard<std::mutex> lock(g_updateGlobals);
+#endif
+ for (const auto &inc : state->includeRelations)
+ {
+ if (inc->fromFileDef)
+ {
+ inc->fromFileDef->addIncludeDependency(inc->toFileDef,inc->includeName,inc->local,inc->imported);
+ }
+ if (inc->toFileDef && inc->fromFileDef)
+ {
+ inc->toFileDef->addIncludedByDependency(inc->fromFileDef,inc->fromFileDef->docName(),inc->local,inc->imported);
+ }
+ }
+ // add the macro definition for this file to the global map
+ Doxygen::macroDefinitions.emplace(std::make_pair(state->yyFileName.str(),std::move(state->macroDefinitions)));
+ }
+
+ //yyextra->defineManager.endContext();
printlex(yy_flex_debug, FALSE, __FILE__, fileName);
+// printf("Preprocessor::processFile(%s) finished\n",fileName);
}
#if USE_STATE2STRING
diff --git a/src/pyscanner.h b/src/pyscanner.h
index d6e8672..4f0ae38 100644
--- a/src/pyscanner.h
+++ b/src/pyscanner.h
@@ -1,12 +1,12 @@
/******************************************************************************
*
- *
+ *
*
* 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
+ * 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.
*
@@ -36,13 +36,10 @@ class PythonOutlineParser : public OutlineParserInterface
public:
PythonOutlineParser();
virtual ~PythonOutlineParser();
- void startTranslationUnit(const char *) {}
- void finishTranslationUnit() {}
- void parseInput(const char * fileName,
- const char *fileBuf,
+ void parseInput(const char * fileName,
+ const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList &filesInSameTranslationUnit);
+ ClangTUParser *clangParser);
bool needsPreprocessing(const QCString &extension) const;
void parsePrototype(const char *text);
private:
diff --git a/src/pyscanner.l b/src/pyscanner.l
index ed76c75..773391b 100644
--- a/src/pyscanner.l
+++ b/src/pyscanner.l
@@ -97,6 +97,7 @@ struct pyscannerYY_state
QGString * copyString = 0;
int indent = 0;
int curIndent = 0;
+ int commentIndent = 0;
bool importTuple = FALSE;
QDict<QCString> packageNameCache;
char atomStart = 0;
@@ -140,6 +141,7 @@ static void initSpecialBlock(yyscan_t yyscanner);
static void searchFoundDef(yyscan_t yyscanner);
static void searchFoundClass(yyscan_t yyscanner);
static QCString findPackageScope(yyscan_t yyscanner,const char *fileName);
+static void stripIndentation(QCString &doc,const int indentationLevel);
static yy_size_t yyread(yyscan_t yyscanner,char *buf,yy_size_t max_size);
@@ -1251,7 +1253,8 @@ STARTDOCSYMS "##"
QCString actualDoc=yyextra->docBlock;
if (!yyextra->docBlockSpecial) // legacy unformatted docstring
{
- actualDoc.prepend("\\verbatim ");
+ stripIndentation(actualDoc,yyextra->commentIndent);
+ actualDoc.prepend("\\verbatim\n");
actualDoc.append("\\endverbatim ");
}
//printf("-------> yyextra->current=%p yyextra->bodyEntry=%p\n",yyextra->current,yyextra->bodyEntry);
@@ -1262,7 +1265,8 @@ STARTDOCSYMS "##"
QCString actualDoc=yyextra->docBlock;
if (!yyextra->docBlockSpecial) // legacy unformatted docstring
{
- actualDoc.prepend("\\verbatim ");
+ stripIndentation(actualDoc,yyextra->commentIndent);
+ actualDoc.prepend("\\verbatim\n");
actualDoc.append("\\endverbatim ");
}
actualDoc.prepend("\\namespace "+yyextra->moduleScope+" ");
@@ -1290,18 +1294,7 @@ STARTDOCSYMS "##"
^{BB} { // leading whitespace
- int indent = computeIndent(yytext);
- if (indent>=yyextra->curIndent)
- { // strip yyextra->curIndent amount of whitespace
- int i;
- for (i=0;i<indent-yyextra->curIndent;i++) yyextra->docBlock+=' ';
- DBG_CTX((stderr,"stripping indent %d\n",yyextra->curIndent));
- }
- else
- {
- DBG_CTX((stderr,"not stripping: %d<%d\n",indent,yyextra->curIndent));
- yyextra->docBlock += yytext;
- }
+ yyextra->docBlock += yytext;
}
[^"'\n \t\\]+ {
yyextra->docBlock += yytext;
@@ -1517,7 +1510,7 @@ static void newFunction(yyscan_t yyscanner)
static inline int computeIndent(const char *s)
{
int col=0;
- static int tabSize=Config_getInt(TAB_SIZE);
+ int tabSize=Config_getInt(TAB_SIZE);
const char *p=s;
char c;
while ((c=*p++))
@@ -1529,6 +1522,55 @@ static inline int computeIndent(const char *s)
return col;
}
+// strip up to \a indentationLevel spaces from each line in \a doc (excluding the first line)
+static void stripIndentation(QCString &doc,const int indentationLevel)
+{
+ if (indentationLevel <= 0) return; // nothing to strip
+
+ // by stripping content the string will only become shorter so we write the results
+ // back into the input string and then resize it at the end.
+ char c;
+ const char *src = doc.data();
+ char *dst = doc.rawData();
+ bool insideIndent = false; // skip the initial line from stripping
+ int cnt = 0;
+ while ((c=*src++)!=0)
+ {
+ // invariant: dst<=src
+ switch(c)
+ {
+ case '\n':
+ *dst++ = c;
+ insideIndent = true;
+ cnt = indentationLevel;
+ break;
+ case ' ':
+ if (insideIndent)
+ {
+ if (cnt>0) // count down the spacing until the end of the indent
+ {
+ cnt--;
+ }
+ else // reached the end of the indent, start of the part of the line to keep
+ {
+ insideIndent = false;
+ *dst++ = c;
+ }
+ }
+ else // part after indent, copy to the output
+ {
+ *dst++ = c;
+ }
+ break;
+ default:
+ insideIndent = false;
+ *dst++ = c;
+ break;
+ }
+ }
+ doc.resize(dst-doc.data()+1);
+}
+
static QCString findPackageScopeFromPath(yyscan_t yyscanner,const QCString &path)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
@@ -1630,7 +1672,8 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief
int position = 0;
bool needsEntry;
int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine;
- QCString processedDoc = processMarkdownForCommentBlock(doc,yyextra->yyFileName,lineNr);
+ Markdown markdown(yyextra->yyFileName,lineNr);
+ QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(doc,lineNr) : doc;
while (yyextra->commentScanner.parseCommentBlock(
yyextra->thisParser,
(yyextra->docBlockInBody && yyextra->previous) ? yyextra->previous.get() : yyextra->current.get(),
@@ -1642,7 +1685,8 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief
yyextra->docBlockInBody,
yyextra->protection,
position,
- needsEntry)
+ needsEntry,
+ Config_getBool(MARKDOWN_SUPPORT))
) // need to start a new entry
{
if (needsEntry)
@@ -1684,6 +1728,7 @@ static void initTriDoubleQuoteBlock(yyscan_t yyscanner)
yyextra->docBlockJavaStyle = TRUE;
yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!';
yyextra->docBlock.resize(0);
+ yyextra->commentIndent = yyextra->curIndent;
yyextra->doubleQuote = TRUE;
startCommentBlock(yyscanner,FALSE);
}
@@ -1696,6 +1741,7 @@ static void initTriSingleQuoteBlock(yyscan_t yyscanner)
yyextra->docBlockJavaStyle = TRUE;
yyextra->docBlockSpecial = yytext[strlen(yytext) - 1]=='!';
yyextra->docBlock.resize(0);
+ yyextra->commentIndent = yyextra->curIndent;
yyextra->doubleQuote = FALSE;
startCommentBlock(yyscanner,FALSE);
}
@@ -1708,6 +1754,7 @@ static void initSpecialBlock(yyscan_t yyscanner)
yyextra->docBlockJavaStyle = TRUE;
yyextra->docBrief = TRUE;
yyextra->docBlock.resize(0);
+ yyextra->commentIndent = yyextra->curIndent;
startCommentBlock(yyscanner,TRUE);
}
@@ -1934,8 +1981,7 @@ PythonOutlineParser::~PythonOutlineParser()
void PythonOutlineParser::parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool /*sameTranslationUnit*/,
- QStrList & /*filesInSameTranslationUnit*/)
+ ClangTUParser * /*clangParser*/)
{
struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
yyextra->thisParser = this;
diff --git a/src/res2cc_cmd.py b/src/res2cc_cmd.py
index 86d999d..268ae86 100755
--- a/src/res2cc_cmd.py
+++ b/src/res2cc_cmd.py
@@ -58,6 +58,7 @@ class File(object):
if ext=='.lum': return LumFile(directory,subdir,fname)
if ext=='.luma': return LumaFile(directory,subdir,fname)
if ext=='.css': return CSSFile(directory,subdir,fname)
+ if ext=='.svg': return SVGFile(directory,subdir,fname)
return VerbatimFile(directory,subdir,fname)
class VerbatimFile(File):
@@ -76,6 +77,14 @@ class CSSFile(File):
def writeDirEntry(self,outputFile):
print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::CSS }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile)
+class SVGFile(File):
+ def __init__(self,directory,subdir,fileName):
+ File.__init__(self,directory,subdir,fileName,"r")
+ def writeContents(self,outputFile):
+ self.writeBytes(self.inputFile.read(),outputFile)
+ def writeDirEntry(self,outputFile):
+ print(" { \"%s\", \"%s\", %s_data, %s_len, Resource::SVG }," % (self.subdir,self.fileName,self.bareName,self.bareName), file=outputFile)
+
class LumFile(File):
def __init__(self,directory,subdir,fileName):
File.__init__(self,directory,subdir,fileName,"r")
diff --git a/src/resourcemgr.cpp b/src/resourcemgr.cpp
index 4ba3388..6d2946c 100644
--- a/src/resourcemgr.cpp
+++ b/src/resourcemgr.cpp
@@ -150,6 +150,18 @@ bool ResourceMgr::copyResourceAs(const char *name,const char *targetDir,const ch
}
}
break;
+ case Resource::SVG:
+ {
+ QFile f(pathName);
+ if (f.open(IO_WriteOnly))
+ {
+ QCString buf(res->size+1);
+ memcpy(buf.rawData(),res->data,res->size);
+ FTextStream t(&f);
+ t << replaceColorMarkers(buf);
+ return TRUE;
+ }
+ }
}
}
else
diff --git a/src/resourcemgr.h b/src/resourcemgr.h
index 6e1587d..1959ec4 100644
--- a/src/resourcemgr.h
+++ b/src/resourcemgr.h
@@ -20,7 +20,7 @@
/** @brief Compiled resource */
struct Resource
{
- enum Type { Verbatim, Luminance, LumAlpha, CSS };
+ enum Type { Verbatim, Luminance, LumAlpha, CSS, SVG };
const char *category;
const char *name;
const unsigned char *data;
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index ecf2d32..9d0a957 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -186,14 +186,14 @@ void RTFGenerator::init()
}
// overwrite some (or all) definitions from file
- QCString &rtfStyleSheetFile = Config_getString(RTF_STYLESHEET_FILE);
+ QCString rtfStyleSheetFile = Config_getString(RTF_STYLESHEET_FILE);
if (!rtfStyleSheetFile.isEmpty())
{
loadStylesheet(rtfStyleSheetFile, rtf_Style);
}
// If user has defined an extension file, load its contents.
- QCString &rtfExtensionsFile = Config_getString(RTF_EXTENSIONS_FILE);
+ QCString rtfExtensionsFile = Config_getString(RTF_EXTENSIONS_FILE);
if (!rtfExtensionsFile.isEmpty())
{
loadExtensions(rtfExtensionsFile);
diff --git a/src/scanner.h b/src/scanner.h
index 70df660..cefc934 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -1,12 +1,12 @@
/******************************************************************************
*
- *
+ *
*
* 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
+ * 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.
*
@@ -23,7 +23,7 @@
/** \brief C-like language parser using state-based lexical scanning.
*
* This is the language parser for doxygen. It is somewhat fuzzy and
- * supports C++ and various languages that are closely related to C++,
+ * supports C++ and various languages that are closely related to C++,
* such as C, C#, Objective-C, Java, PHP, and IDL.
*/
class COutlineParser : public OutlineParserInterface
@@ -31,13 +31,10 @@ class COutlineParser : public OutlineParserInterface
public:
COutlineParser();
virtual ~COutlineParser();
- void startTranslationUnit(const char *fileName);
- void finishTranslationUnit();
void parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList &filesInSameTranslationUnit);
+ ClangTUParser *clangParser);
bool needsPreprocessing(const QCString &extension) const;
void parsePrototype(const char *text);
private:
diff --git a/src/scanner.l b/src/scanner.l
index 384b088..e63b8a0 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -193,6 +193,8 @@ struct scannerYY_state
uint fencedSize = 0;
bool nestedComment = false;
std::vector< std::pair<Entry*,std::shared_ptr<Entry> > > outerScopeEntries;
+
+ ClangTUParser * clangParser = 0;
};
#if USE_STATE2STRING
@@ -766,9 +768,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
yyextra->current->type = "id";
}
yyextra->current->name = yytext;
- if (yyextra->insideCpp || yyextra->insideObjC)
+ if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
{
- yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext);
+ yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
}
}
<ObjCMethod>":"{B}* { // start of parameter list
@@ -2045,9 +2047,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
BEGIN(FindMembers);
}
<FindMembers,FindMemberName>{SCOPENAME} {
- if (yyextra->insideCpp || yyextra->insideObjC)
+ if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
{
- yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext);
+ yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
}
yyextra->yyBegColNr=yyextra->yyColNr;
yyextra->yyBegLineNr=yyextra->yyLineNr;
@@ -2348,9 +2350,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
*/
<Define>{ID} {
//printf("Define '%s' without args\n",yytext);
- if (yyextra->insideCpp || yyextra->insideObjC)
+ if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
{
- yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext);
+ yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
}
yyextra->current->bodyLine = yyextra->yyLineNr;
yyextra->current->bodyColumn = yyextra->yyColNr;
@@ -2359,7 +2361,6 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
}
<DefineEnd>\n {
//printf("End define: doc=%s docFile=%s docLine=%d\n",yyextra->current->doc.data(),yyextra->current->docFile.data(),yyextra->current->docLine);
- lineCount(yyscanner);
yyextra->current->fileName = yyextra->yyFileName;
yyextra->current->startLine = yyextra->yyLineNr;
yyextra->current->startColumn = yyextra->yyColNr;
@@ -2368,6 +2369,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
yyextra->current->name = yyextra->current->name.stripWhiteSpace();
yyextra->current->section = Entry::DEFINE_SEC;
yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current);
+ lineCount(yyscanner);
initEntry(yyscanner);
BEGIN(yyextra->lastDefineContext);
}
@@ -3463,9 +3465,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
}
<Sharp>. { yyextra->current->type += *yytext ; }
<FindFields>{ID} {
- if (yyextra->insideCpp || yyextra->insideObjC)
+ if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
{
- yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext);
+ yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
}
yyextra->current->bodyLine = yyextra->yyLineNr;
yyextra->current->bodyColumn = yyextra->yyColNr;
@@ -5334,9 +5336,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
}
<CompoundName>{SCOPENAME} {
yyextra->current->name = yytext ;
- if (yyextra->insideCpp || yyextra->insideObjC)
+ if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
{
- yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext);
+ yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
}
lineCount(yyscanner);
if (yyextra->current->spec & Entry::Protocol)
@@ -5399,9 +5401,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP})
}
}
<ClassVar>{ID} {
- if (yyextra->insideCpp || yyextra->insideObjC)
+ if (yyextra->clangParser && (yyextra->insideCpp || yyextra->insideObjC))
{
- yyextra->current->id = ClangParser::instance()->lookup(yyextra->yyLineNr,yytext);
+ yyextra->current->id = yyextra->clangParser->lookup(yyextra->yyLineNr,yytext);
}
if (yyextra->insideIDL && qstrcmp(yytext,"switch")==0)
{
@@ -7016,7 +7018,9 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief
int position=0;
bool needsEntry=FALSE;
- QCString processedDoc = processMarkdownForCommentBlock(stripIndentation(doc),yyextra->yyFileName,lineNr);
+ Markdown markdown(yyextra->yyFileName,lineNr);
+ QCString strippedDoc = stripIndentation(doc);
+ QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(strippedDoc,lineNr) : strippedDoc;
while (yyextra->commentScanner.parseCommentBlock(
yyextra->thisParser,
yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(),
@@ -7028,7 +7032,8 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief
yyextra->docBlockInBody, // isInBody
yyextra->protection,
position,
- needsEntry
+ needsEntry,
+ Config_getBool(MARKDOWN_SUPPORT)
)
)
{
@@ -7087,9 +7092,10 @@ static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al)
FALSE,
yyextra->protection,
position,
- needsEntry
+ needsEntry,
+ Config_getBool(MARKDOWN_SUPPORT)
)
- )
+ )
{
//printf("handleParametersCommentBlock position=%d [%s]\n",position,doc.data()+position);
if (needsEntry) newEntry(yyscanner);
@@ -7228,8 +7234,7 @@ static void parseMain(yyscan_t yyscanner,
const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &rt,
- bool sameTranslationUnit,
- QStrList & filesInSameTranslationUnit)
+ ClangTUParser *clangParser)
{
struct yyguts_t *yyg = (struct yyguts_t*)yyscanner;
initParser(yyscanner);
@@ -7250,19 +7255,8 @@ static void parseMain(yyscan_t yyscanner,
yyextra->yyBegLineNr = 1;
yyextra->yyBegColNr = 0;
yyextra->yyFileName = fileName;
+ yyextra->clangParser = clangParser;
setContext(yyscanner);
- bool processWithClang = yyextra->insideCpp || yyextra->insideObjC;
- if (processWithClang)
- {
- if (!sameTranslationUnit) // new file
- {
- ClangParser::instance()->start(fileName,filesInSameTranslationUnit);
- }
- else
- {
- ClangParser::instance()->switchToFile(fileName);
- }
- }
rt->lang = yyextra->language;
msg("Parsing file %s...\n",yyextra->yyFileName.data());
@@ -7399,33 +7393,17 @@ COutlineParser::~COutlineParser()
scannerYYlex_destroy(p->yyscanner);
}
-void COutlineParser::startTranslationUnit(const char *)
-{
-}
-
-void COutlineParser::finishTranslationUnit()
-{
- struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
- bool processWithClang = yyextra->insideCpp || yyextra->insideObjC;
- if (processWithClang)
- {
- ClangParser::instance()->finish();
- }
-}
-
void COutlineParser::parseInput(const char *fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList & filesInSameTranslationUnit)
+ ClangTUParser *clangParser)
{
struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner;
yyextra->thisParser = this;
printlex(yy_flex_debug, TRUE, __FILE__, fileName);
- ::parseMain(p->yyscanner, fileName,fileBuf,root,
- sameTranslationUnit,filesInSameTranslationUnit);
+ ::parseMain(p->yyscanner,fileName,fileBuf,root,clangParser);
printlex(yy_flex_debug, FALSE, __FILE__, fileName);
}
diff --git a/src/sqlite3gen.cpp b/src/sqlite3gen.cpp
index f767eab..2f72221 100644
--- a/src/sqlite3gen.cpp
+++ b/src/sqlite3gen.cpp
@@ -1424,7 +1424,11 @@ QCString getSQLDocBlock(const Definition *scope,
dynamic_cast<const MemberDef*>(def),
doc,
FALSE,
- FALSE
+ FALSE,
+ 0,
+ FALSE,
+ FALSE,
+ Config_getBool(MARKDOWN_SUPPORT)
);
XMLCodeGenerator codeGen(t);
// create a parse tree visitor for XML
@@ -1991,7 +1995,6 @@ static void generateSqlite3ForClass(const ClassDef *cd)
DBG_CTX(("-----> ClassDef includeInfo for %s\n", nm.data()));
DBG_CTX((" local : %d\n", ii->local));
DBG_CTX((" imported : %d\n", ii->imported));
- DBG_CTX((" indirect : %d\n", ii->indirect));
DBG_CTX(("header: %s\n", ii->fileDef->absFilePath().data()));
DBG_CTX((" file_id : %d\n", file_id));
DBG_CTX((" header_id: %d\n", header_id));
@@ -2207,7 +2210,6 @@ static void generateSqlite3ForFile(const FileDef *fd)
DBG_CTX(("-----> FileDef includeInfo for %s\n", ii->includeName.data()));
DBG_CTX((" local: %d\n", ii->local));
DBG_CTX((" imported: %d\n", ii->imported));
- DBG_CTX((" indirect: %d\n", ii->indirect));
if(ii->fileDef)
{
DBG_CTX(("include: %s\n", ii->fileDef->absFilePath().data()));
@@ -2501,11 +2503,10 @@ static void generateSqlite3ForPage(const PageDef *pd,bool isExample)
static sqlite3* openDbConnection()
{
- QCString outputDirectory = Config_getString(OUTPUT_DIRECTORY);
+ QCString outputDirectory = Config_getString(SQLITE3_OUTPUT);
QDir sqlite3Dir(outputDirectory);
sqlite3 *db;
int rc;
- struct stat buf;
rc = sqlite3_initialize();
if (rc != SQLITE_OK)
@@ -2514,15 +2515,24 @@ static sqlite3* openDbConnection()
return NULL;
}
+ QCString dbFileName = "doxygen_sqlite3.db";
+ QFileInfo fi(outputDirectory+"/"+dbFileName);
- if (stat (outputDirectory+"/doxygen_sqlite3.db", &buf) == 0)
+ if (fi.exists())
{
- err("doxygen_sqlite3.db already exists! Rename, remove, or archive it to regenerate\n");
- return NULL;
+ if (Config_getBool(SQLITE3_RECREATE_DB))
+ {
+ QDir().remove(fi.absFilePath());
+ }
+ else
+ {
+ err("doxygen_sqlite3.db already exists! Rename, remove, or archive it to regenerate\n");
+ return NULL;
+ }
}
rc = sqlite3_open_v2(
- outputDirectory+"/doxygen_sqlite3.db",
+ fi.absFilePath().utf8(),
&db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
0
diff --git a/src/tagreader.cpp b/src/tagreader.cpp
index 12010e8..3c493b4 100644
--- a/src/tagreader.cpp
+++ b/src/tagreader.cpp
@@ -1526,7 +1526,7 @@ void TagFileParser::addIncludes()
// ifd->getOutputFileBase().data(),ii->id.data());
if (ifd->getOutputFileBase()==QCString(ii->id))
{
- fd->addIncludeDependency(ifd.get(),ii->text,ii->isLocal,ii->isImported,FALSE);
+ fd->addIncludeDependency(ifd.get(),ii->text,ii->isLocal,ii->isImported);
}
}
}
diff --git a/src/template.cpp b/src/template.cpp
index 1763eec..c836c6b 100644
--- a/src/template.cpp
+++ b/src/template.cpp
@@ -2843,7 +2843,11 @@ template<class T> class TemplateNodeCreator : public TemplateNode
if (d.exists())
{
bool ok = d.mkdir(fileName.mid(j,i-j));
- if (!ok) break;
+ if (!ok)
+ {
+ err("Failed to create directory '%s'\n",(fileName.mid(j,i-j)).data());
+ break;
+ }
QCString dirName = outputDir+'/'+fileName.left(i);
d = QDir(dirName);
j = i+1;
diff --git a/src/translator.h b/src/translator.h
index 8412560..94f5abf 100644
--- a/src/translator.h
+++ b/src/translator.h
@@ -50,6 +50,11 @@ class Translator
* can be returned.
*/
virtual QCString latexFontenc() { return "T1"; }
+ virtual QCString latexFont() {
+ return "\\usepackage[scaled=.90]{helvet}\n"
+ "\\usepackage{courier}\n"
+ "\\renewcommand{\\familydefault}{\\sfdefault}\n";
+ }
/*!
* Sets the commands to be inserted directly after the `\\begin{document}`
* in the LaTeX document.
@@ -588,7 +593,6 @@ class Translator
virtual QCString trClassMethods() = 0;
virtual QCString trInstanceMethods() = 0;
virtual QCString trMethodDocumentation() = 0;
- virtual QCString trDesignOverview() = 0;
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
diff --git a/src/translator_adapter.h b/src/translator_adapter.h
index b0c8a24..fdc68f9 100644
--- a/src/translator_adapter.h
+++ b/src/translator_adapter.h
@@ -216,9 +216,6 @@ class TranslatorAdapter_1_8_2 : public TranslatorAdapter_1_8_4
virtual QCString trMethodDocumentation()
{ return english.trMethodDocumentation(); }
-
- virtual QCString trDesignOverview()
- { return english.trDesignOverview(); }
};
diff --git a/src/translator_br.h b/src/translator_br.h
index 16f8d6e..2630435 100644
--- a/src/translator_br.h
+++ b/src/translator_br.h
@@ -2011,15 +2011,6 @@ class TranslatorBrazilian : public Translator
return "Documentação do método";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- // I'm not sure how to accurately translate it
- return "Visão geral do design";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_cn.h b/src/translator_cn.h
index 735bf45..d989d77 100644
--- a/src/translator_cn.h
+++ b/src/translator_cn.h
@@ -1862,14 +1862,6 @@ class TranslatorChinese : public TranslatorAdapter_1_8_15
return "函数文档";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "设计概要";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_cz.h b/src/translator_cz.h
index 2b985ae..c364dbb 100644
--- a/src/translator_cz.h
+++ b/src/translator_cz.h
@@ -1977,14 +1977,6 @@ class TranslatorCzech : public TranslatorAdapter_1_8_15
return "Dokumentace metody";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Návrhové schéma";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_de.h b/src/translator_de.h
index a29284f..2e23a6d 100644
--- a/src/translator_de.h
+++ b/src/translator_de.h
@@ -2072,14 +2072,6 @@ class TranslatorGerman : public TranslatorAdapter_1_8_15
return "Methodendokumentation";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Übersicht";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_en.h b/src/translator_en.h
index cee8cf9..d1cd7be 100644
--- a/src/translator_en.h
+++ b/src/translator_en.h
@@ -1940,14 +1940,6 @@ class TranslatorEnglish : public Translator
return "Method Documentation";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Design Overview";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_eo.h b/src/translator_eo.h
index 67315f3..87e7524 100644
--- a/src/translator_eo.h
+++ b/src/translator_eo.h
@@ -1941,7 +1941,6 @@ class TranslatorEsperanto : public TranslatorAdapter_1_8_4
return "Fasona Superrigardo";
}
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.19, but completely filled so no need for a TranslatorAdapter_1_8_19
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_es.h b/src/translator_es.h
index 03cd128..cfd5763 100644
--- a/src/translator_es.h
+++ b/src/translator_es.h
@@ -1992,14 +1992,6 @@ class TranslatorSpanish : public TranslatorAdapter_1_8_15
return "Método de documentación";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Diseño información general";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_fr.h b/src/translator_fr.h
index 9317967..d7a431f 100644
--- a/src/translator_fr.h
+++ b/src/translator_fr.h
@@ -2001,14 +2001,6 @@ class TranslatorFrench : public TranslatorAdapter_1_8_15
return "Documentation des méthodes";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Vue d'ensemble";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_gr.h b/src/translator_gr.h
index 4e45539..d687929 100644
--- a/src/translator_gr.h
+++ b/src/translator_gr.h
@@ -59,8 +59,18 @@ class TranslatorGreek : public TranslatorAdapter_1_8_15
virtual QCString latexLanguageSupportCommand()
{
- return "\\usepackage[greek,english]{babel}\n"
- "\\usepackage{alphabeta}\n";
+ return "\\usepackage{fontspec}\n"
+ "\\usepackage[greek]{babel}\n";
+ }
+
+ virtual QCString latexFontenc()
+ {
+ return "";
+ }
+ virtual QCString latexFont()
+ {
+ return "\\setmainfont{Libertinus Sans}\n"
+ "\\setmonofont{Courier New}\n";
}
// --- Language translation methods -------------------
@@ -1159,6 +1169,16 @@ class TranslatorGreek : public TranslatorAdapter_1_8_15
return "1253";
}
+ virtual QCString latexCommandName()
+ {
+ QCString latex_command = Config_getString(LATEX_CMD_NAME);
+ if (latex_command.isEmpty()) latex_command = "latex";
+ if (Config_getBool(USE_PDFLATEX))
+ {
+ if (latex_command == "latex") latex_command = "xelatex";
+ }
+ return latex_command;
+ }
/*! Used as ansicpg for RTF fcharset
*/
@@ -1916,14 +1936,6 @@ class TranslatorGreek : public TranslatorAdapter_1_8_15
return "Τεκμηρίωση Μεθόδου";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Επισκόπηση σχεδίασης";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_hu.h b/src/translator_hu.h
index 67d6a6e..edf2c58 100644
--- a/src/translator_hu.h
+++ b/src/translator_hu.h
@@ -1955,14 +1955,6 @@ class TranslatorHungarian : public TranslatorAdapter_1_8_15
return "Metódus dokumentáció";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Dizájn áttekintés";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_it.h b/src/translator_it.h
index ddfed09..33437d6 100644
--- a/src/translator_it.h
+++ b/src/translator_it.h
@@ -1912,14 +1912,6 @@ class TranslatorItalian : public TranslatorAdapter_1_8_15
return "Documentazione dei metodi";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Panoramica del progetto";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_jp.h b/src/translator_jp.h
index 64c49c0..6032bd3 100644
--- a/src/translator_jp.h
+++ b/src/translator_jp.h
@@ -1925,14 +1925,6 @@ class TranslatorJapanese : public TranslatorAdapter_1_8_15
return "メソッド詳解";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "デザイン概観";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_kr.h b/src/translator_kr.h
index 79fd6c8..2d593a7 100644
--- a/src/translator_kr.h
+++ b/src/translator_kr.h
@@ -1948,14 +1948,6 @@ class TranslatorKorean : public TranslatorAdapter_1_8_15
return "메소드 문서화";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "디자인 개요";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_lv.h b/src/translator_lv.h
index 107b209..bc02cfb 100644
--- a/src/translator_lv.h
+++ b/src/translator_lv.h
@@ -1944,7 +1944,6 @@ class TranslatorLatvian : public TranslatorAdapter_1_8_4
return "Dizaina pārskats";
}
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.19, but completely filled so no need for a TranslatorAdapter_1_8_19
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_nl.h b/src/translator_nl.h
index 81818f4..b6625ac 100644
--- a/src/translator_nl.h
+++ b/src/translator_nl.h
@@ -1530,14 +1530,6 @@ class TranslatorDutch : public Translator
return "Methode Documentatie";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Ontwerp Overzicht";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_pt.h b/src/translator_pt.h
index ff3aac4..b884849 100644
--- a/src/translator_pt.h
+++ b/src/translator_pt.h
@@ -1945,15 +1945,6 @@ class TranslatorPortuguese : public Translator
return "Documentação do método";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- // I'm not sure how to accurately translate it
- return "Visão geral do design";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_ro.h b/src/translator_ro.h
index cf6d3df..99752fb 100644
--- a/src/translator_ro.h
+++ b/src/translator_ro.h
@@ -1943,14 +1943,6 @@ class TranslatorRomanian : public TranslatorAdapter_1_8_15
return "Documentația Metodelor";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Vedere de Ansamblu a Designului";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_ru.h b/src/translator_ru.h
index 9ac2ed3..3e6c8c8 100644
--- a/src/translator_ru.h
+++ b/src/translator_ru.h
@@ -1904,14 +1904,6 @@ class TranslatorRussian : public TranslatorAdapter_1_8_15
return "Документация метода";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Обзор дизайна";
- }
-
///////////////////////////////////////////////////////////////////////
// new since 1.8.4
///////////////////////////////////////////////////////////////////////
diff --git a/src/translator_sk.h b/src/translator_sk.h
index cc7de8c..7534ec0 100644
--- a/src/translator_sk.h
+++ b/src/translator_sk.h
@@ -1907,14 +1907,6 @@ class TranslatorSlovak : public TranslatorAdapter_1_8_15
return "Dokumentácia metódy";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Návrhová schéma";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_sv.h b/src/translator_sv.h
index cfdac67..a885344 100644
--- a/src/translator_sv.h
+++ b/src/translator_sv.h
@@ -2020,14 +2020,6 @@ class TranslatorSwedish : public Translator
return "Metoddokumentation";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "Designöversikt";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_tw.h b/src/translator_tw.h
index 61d5a1f..d1c74f3 100644
--- a/src/translator_tw.h
+++ b/src/translator_tw.h
@@ -1913,14 +1913,6 @@ class TranslatorChinesetraditional : public TranslatorAdapter_1_8_15
return "方法文件";
}
- /*! Used as the title of the design overview picture created for the
- * VHDL output.
- */
- virtual QCString trDesignOverview()
- {
- return "設計概述";
- }
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.4
//////////////////////////////////////////////////////////////////////////
diff --git a/src/translator_ua.h b/src/translator_ua.h
index 6ff908a..c52e762 100644
--- a/src/translator_ua.h
+++ b/src/translator_ua.h
@@ -1909,7 +1909,6 @@ class TranslatorUkrainian : public TranslatorAdapter_1_8_4
return "Огляд дизайну проекту";
}
-
//////////////////////////////////////////////////////////////////////////
// new since 1.8.19, but completely filled so no need for a TranslatorAdapter_1_8_19
//////////////////////////////////////////////////////////////////////////
diff --git a/src/util.cpp b/src/util.cpp
index 86435fa..aa1acb4 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -23,6 +23,7 @@
#include <string.h>
#include <mutex>
+#include <unordered_set>
#include "md5.h"
@@ -277,22 +278,20 @@ QCString generateMarker(int id)
return result;
}
-static QCString stripFromPath(const QCString &path,QStrList &l)
+static QCString stripFromPath(const QCString &path,const StringVector &l)
{
// look at all the strings in the list and strip the longest match
- const char *s=l.first();
QCString potential;
unsigned int length = 0;
- while (s)
+ for (const auto &s : l)
{
- QCString prefix = s;
+ QCString prefix = s.c_str();
if (prefix.length() > length &&
qstricmp(path.left(prefix.length()),prefix)==0) // case insensitive compare
{
length = prefix.length();
potential = path.right(path.length()-prefix.length());
}
- s = l.next();
}
if (length) return potential;
return path;
@@ -2377,15 +2376,13 @@ int filterCRLF(char *buf,int len)
return dest; // length of the valid part of the buf
}
-static QCString getFilterFromList(const char *name,const QStrList &filterList,bool &found)
+static QCString getFilterFromList(const char *name,const StringVector &filterList,bool &found)
{
found=FALSE;
// compare the file name to the filter pattern list
- QStrListIterator sli(filterList);
- char* filterStr;
- for (sli.toFirst(); (filterStr = sli.current()); ++sli)
+ for (const auto &filterStr : filterList)
{
- QCString fs = filterStr;
+ QCString fs = filterStr.c_str();
int i_equals=fs.find('=');
if (i_equals!=-1)
{
@@ -2419,12 +2416,12 @@ QCString getFileFilter(const char* name,bool isSourceCode)
// sanity check
if (name==0) return "";
- QStrList& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
- QStrList& filterList = Config_getList(FILTER_PATTERNS);
+ const StringVector& filterSrcList = Config_getList(FILTER_SOURCE_PATTERNS);
+ const StringVector& filterList = Config_getList(FILTER_PATTERNS);
QCString filterName;
bool found=FALSE;
- if (isSourceCode && !filterSrcList.isEmpty())
+ if (isSourceCode && !filterSrcList.empty())
{ // first look for source filter pattern list
filterName = getFilterFromList(name,filterSrcList,found);
}
@@ -4633,11 +4630,10 @@ QCString substituteKeywords(const QCString &s,const char *title,
int getPrefixIndex(const QCString &name)
{
if (name.isEmpty()) return 0;
- static QStrList &sl = Config_getList(IGNORE_PREFIX);
- char *s = sl.first();
- while (s)
+ const StringVector &sl = Config_getList(IGNORE_PREFIX);
+ for (const auto &s : sl)
{
- const char *ps=s;
+ const char *ps=s.c_str();
const char *pd=name.data();
int i=0;
while (*ps!=0 && *pd!=0 && *ps==*pd) ps++,pd++,i++;
@@ -4645,7 +4641,6 @@ int getPrefixIndex(const QCString &name)
{
return i;
}
- s = sl.next();
}
return 0;
}
@@ -5028,10 +5023,20 @@ void createSubDirs(QDir &d)
int l1,l2;
for (l1=0;l1<16;l1++)
{
- d.mkdir(QCString().sprintf("d%x",l1));
+ QCString subdir;
+ subdir.sprintf("d%x",l1);
+ if (!d.exists(subdir) && !d.mkdir(subdir))
+ {
+ term("Failed to create output directory '%s'\n",subdir.data());
+ }
for (l2=0;l2<256;l2++)
{
- d.mkdir(QCString().sprintf("d%x/d%02x",l1,l2));
+ QCString subsubdir;
+ subsubdir.sprintf("d%x/d%02x",l1,l2);
+ if (!d.exists(subsubdir) && !d.mkdir(subsubdir))
+ {
+ term("Failed to create output directory '%s'\n",subsubdir.data());
+ }
}
}
}
@@ -5278,6 +5283,16 @@ QCString convertToId(const char *s)
return growBuf.get();
}
+/*! Some strings have been corrected but the requirement regarding the fact
+ * that an id cannot have a digit at the first position. To overcome problems
+ * with double labels we always place an "a" in front
+ */
+QCString correctId(QCString s)
+{
+ if (s.isEmpty()) return s;
+ return "a" + s;
+}
+
/*! Converts a string to an XML-encoded string */
QCString convertToXML(const char *s, bool keepEntities)
{
@@ -6597,10 +6612,11 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
// search for leading empty lines
int i=0,li=-1,l=s.length();
char c;
- while ((c=*p++))
+ while ((c=*p))
{
- if (c==' ' || c=='\t' || c=='\r') i++;
- else if (c=='\n') i++,li=i,docLine++;
+ if (c==' ' || c=='\t' || c=='\r') i++,p++;
+ else if (c=='\\' && qstrncmp(p,"\\ilinebr",8)==0) i+=8,li=i,docLine++,p+=8;
+ else if (c=='\n') i++,li=i,docLine++,p++;
else break;
}
@@ -6609,9 +6625,10 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
p=s.data()+b;
while (b>=0)
{
- c=*p; p--;
- if (c==' ' || c=='\t' || c=='\r') b--;
- else if (c=='\n') bi=b,b--;
+ c=*p;
+ if (c==' ' || c=='\t' || c=='\r') b--,p--;
+ else if (c=='r' && b>=7 && qstrncmp(p-7,"\\ilinebr",8)==0) bi=b-7,b-=8,p-=8;
+ else if (c=='\n') bi=b,b--,p--;
else break;
}
@@ -6622,6 +6639,7 @@ QCString stripLeadingAndTrailingEmptyLines(const QCString &s,int &docLine)
if (bi==-1) bi=l;
if (li==-1) li=0;
if (bi<=li) return 0; // only empty lines
+ //printf("docLine='%s' len=%d li=%d bi=%d\n",s.data(),s.length(),li,bi);
return s.mid(li,bi-li);
}
@@ -6973,7 +6991,8 @@ QCString parseCommentAsText(const Definition *scope,const MemberDef *md,
if (doc.isEmpty()) return s.data();
FTextStream t(&s);
DocNode *root = validatingParseDoc(fileName,lineNr,
- (Definition*)scope,(MemberDef*)md,doc,FALSE,FALSE);
+ (Definition*)scope,(MemberDef*)md,doc,FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
TextDocVisitor *visitor = new TextDocVisitor(t);
root->accept(visitor);
delete visitor;
@@ -7008,9 +7027,8 @@ QCString parseCommentAsText(const Definition *scope,const MemberDef *md,
//--------------------------------------------------------------------------------------
-static QDict<void> aliasesProcessed;
-
-static QCString expandAliasRec(const QCString s,bool allowRecursion=FALSE);
+static QCString expandAliasRec(StringUnorderedSet &aliasesProcessed,
+ const QCString s,bool allowRecursion=FALSE);
struct Marker
{
@@ -7052,7 +7070,8 @@ static int findEndOfCommand(const char *s)
* with the corresponding values found in the comma separated argument
* list \a argList and the returns the result after recursive alias expansion.
*/
-static QCString replaceAliasArguments(const QCString &aliasValue,const QCString &argList)
+static QCString replaceAliasArguments(StringUnorderedSet &aliasesProcessed,
+ const QCString &aliasValue,const QCString &argList)
{
//printf("----- replaceAliasArguments(val=[%s],args=[%s])\n",aliasValue.data(),argList.data());
@@ -7132,7 +7151,7 @@ static QCString replaceAliasArguments(const QCString &aliasValue,const QCString
//printf("part before marker %d: '%s'\n",i,aliasValue.mid(p,m->pos-p).data());
if (m->number>0 && m->number<=(int)args.count()) // valid number
{
- result+=expandAliasRec(*args.at(m->number-1),TRUE);
+ result+=expandAliasRec(aliasesProcessed,*args.at(m->number-1),TRUE);
//printf("marker index=%d pos=%d number=%d size=%d replacement %s\n",i,m->pos,m->number,m->size,
// args.at(m->number-1)->data());
}
@@ -7144,7 +7163,7 @@ static QCString replaceAliasArguments(const QCString &aliasValue,const QCString
// expand the result again
result = substitute(result,"\\{","{");
result = substitute(result,"\\}","}");
- result = expandAliasRec(substitute(result,"\\,",","));
+ result = expandAliasRec(aliasesProcessed,substitute(result,"\\,",","));
return result;
}
@@ -7171,7 +7190,7 @@ static QCString escapeCommas(const QCString &s)
return result.data();
}
-static QCString expandAliasRec(const QCString s,bool allowRecursion)
+static QCString expandAliasRec(StringUnorderedSet &aliasesProcessed,const QCString s,bool allowRecursion)
{
QCString result;
static QRegExp cmdPat("[\\\\@][a-z_A-Z][a-z_A-Z0-9]*");
@@ -7204,19 +7223,20 @@ static QCString expandAliasRec(const QCString s,bool allowRecursion)
}
//printf("Found command s='%s' cmd='%s' numArgs=%d args='%s' aliasText=%s\n",
// s.data(),cmd.data(),numArgs,args.data(),aliasText?aliasText->data():"<none>");
- if ((allowRecursion || aliasesProcessed.find(cmd)==0) && aliasText) // expand the alias
+ if ((allowRecursion || aliasesProcessed.find(cmd.str())==aliasesProcessed.end()) &&
+ aliasText) // expand the alias
{
//printf("is an alias!\n");
- if (!allowRecursion) aliasesProcessed.insert(cmd,(void *)0x8);
+ if (!allowRecursion) aliasesProcessed.insert(cmd.str());
QCString val = *aliasText;
if (hasArgs)
{
- val = replaceAliasArguments(val,args);
+ val = replaceAliasArguments(aliasesProcessed,val,args);
//printf("replace '%s'->'%s' args='%s'\n",
// aliasText->data(),val.data(),args.data());
}
- result+=expandAliasRec(val);
- if (!allowRecursion) aliasesProcessed.remove(cmd);
+ result+=expandAliasRec(aliasesProcessed,val);
+ if (!allowRecursion) aliasesProcessed.erase(cmd.str());
p=i+l;
if (hasArgs) p+=argsLen+2;
}
@@ -7286,9 +7306,9 @@ QCString extractAliasArgs(const QCString &args,int pos)
QCString resolveAliasCmd(const QCString aliasCmd)
{
QCString result;
- aliasesProcessed.clear();
+ StringUnorderedSet aliasesProcessed;
//printf("Expanding: '%s'\n",aliasCmd.data());
- result = expandAliasRec(aliasCmd);
+ result = expandAliasRec(aliasesProcessed,aliasCmd);
//printf("Expanding result: '%s'->'%s'\n",aliasCmd.data(),result.data());
return result;
}
@@ -7296,12 +7316,12 @@ QCString resolveAliasCmd(const QCString aliasCmd)
QCString expandAlias(const QCString &aliasName,const QCString &aliasValue)
{
QCString result;
- aliasesProcessed.clear();
+ StringUnorderedSet aliasesProcessed;
// avoid expanding this command recursively
- aliasesProcessed.insert(aliasName,(void *)0x8);
+ aliasesProcessed.insert(aliasName.str());
// expand embedded commands
//printf("Expanding: '%s'->'%s'\n",aliasName.data(),aliasValue.data());
- result = expandAliasRec(aliasValue);
+ result = expandAliasRec(aliasesProcessed,aliasValue);
//printf("Expanding result: '%s'->'%s'\n",aliasName.data(),result.data());
return result;
}
@@ -7319,7 +7339,8 @@ void writeTypeConstraints(OutputList &ol,const Definition *d,const ArgumentList
linkifyText(TextGeneratorOLImpl(ol),d,0,0,a.type);
ol.endConstraintType();
ol.startConstraintDocs();
- ol.generateDoc(d->docFile(),d->docLine(),d,0,a.docs,TRUE,FALSE);
+ ol.generateDoc(d->docFile(),d->docLine(),d,0,a.docs,TRUE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endConstraintDocs();
}
ol.endConstraintList();
@@ -7506,9 +7527,9 @@ QCString filterTitle(const QCString &title)
// returns TRUE if the name of the file represented by 'fi' matches
// one of the file patterns in the 'patList' list.
-bool patternMatch(const QFileInfo &fi,const QStrList *patList)
+bool patternMatch(const QFileInfo &fi,const StringVector &patList)
{
- static bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES);
+ bool caseSenseNames = Config_getBool(CASE_SENSE_NAMES);
bool found = FALSE;
// For platforms where the file system is non case sensitive overrule the setting
@@ -7517,17 +7538,15 @@ bool patternMatch(const QFileInfo &fi,const QStrList *patList)
caseSenseNames = FALSE;
}
- if (patList)
+ if (!patList.empty())
{
- QStrListIterator it(*patList);
- QCString pattern;
-
QCString fn = fi.fileName().data();
QCString fp = fi.filePath().data();
QCString afp= fi.absFilePath().data();
- for (it.toFirst();(pattern=it.current());++it)
+ for (const auto &pat: patList)
{
+ QCString pattern = pat.c_str();
if (!pattern.isEmpty())
{
int i=pattern.find('=');
@@ -8118,20 +8137,22 @@ bool classVisibleInIndex(const ClassDef *cd)
QCString extractDirection(QCString &docs)
{
- QRegExp re("\\[[^\\]]+\\]"); // [...]
+ QRegExp re("\\[[ inout,]+\\]"); // [...]
int l=0;
- if (re.match(docs,0,&l)==0)
+ if (re.match(docs,0,&l)==0 && l>2)
{
- int inPos = docs.find("in", 1,FALSE);
- int outPos = docs.find("out",1,FALSE);
- bool input = inPos!=-1 && inPos<l;
- bool output = outPos!=-1 && outPos<l;
- if (input || output) // in,out attributes
+ // make dir the part inside [...] without separators
+ QCString dir=substitute(substitute(docs.mid(1,l-2)," ",""),",","");
+ int inIndex, outIndex;
+ unsigned char ioMask=0;
+ if (( inIndex=dir.find( "in"))!=-1) dir.remove (inIndex,2),ioMask|=(1<<0);
+ if ((outIndex=dir.find("out"))!=-1) dir.remove(outIndex,3),ioMask|=(1<<1);
+ if (dir.isEmpty() && ioMask!=0) // only in and/or out attributes found
{
docs = docs.mid(l); // strip attributes
- if (input && output) return "[in,out]";
- else if (input) return "[in]";
- else if (output) return "[out]";
+ if (ioMask==((1<<0)|(1<<1))) return "[in,out]";
+ else if (ioMask==(1<<0)) return "[in]";
+ else if (ioMask==(1<<1)) return "[out]";
}
}
return QCString();
@@ -8368,18 +8389,16 @@ bool openOutputFile(const char *outFile,QFile &f)
void writeExtraLatexPackages(FTextStream &t)
{
// User-specified packages
- QStrList &extraPackages = Config_getList(EXTRA_PACKAGES);
- if (!extraPackages.isEmpty())
+ const StringVector &extraPackages = Config_getList(EXTRA_PACKAGES);
+ if (!extraPackages.empty())
{
t << "% Packages requested by user\n";
- const char *pkgName=extraPackages.first();
- while (pkgName)
+ for (const auto &pkgName : extraPackages)
{
if ((pkgName[0] == '[') || (pkgName[0] == '{'))
- t << "\\usepackage" << pkgName << "\n";
+ t << "\\usepackage" << pkgName.c_str() << "\n";
else
- t << "\\usepackage{" << pkgName << "}\n";
- pkgName=extraPackages.next();
+ t << "\\usepackage{" << pkgName.c_str() << "}\n";
}
t << "\n";
}
diff --git a/src/util.h b/src/util.h
index e49a807..65d164a 100644
--- a/src/util.h
+++ b/src/util.h
@@ -31,6 +31,7 @@
#include "docparser.h"
#include "classdef.h"
#include "arguments.h"
+#include "containers.h"
//--------------------------------------------------------------------
@@ -277,6 +278,7 @@ QCString insertTemplateSpecifierInScope(const QCString &scope,const QCString &te
QCString stripScope(const char *name);
QCString convertToId(const char *s);
+QCString correctId(QCString s);
QCString convertToHtml(const char *s,bool keepEntities=TRUE);
@@ -436,7 +438,7 @@ bool readInputFile(const char *fileName,BufStr &inBuf,
bool filter=TRUE,bool isSourceCode=FALSE);
QCString filterTitle(const QCString &title);
-bool patternMatch(const QFileInfo &fi,const QStrList *patList);
+bool patternMatch(const QFileInfo &fi,const StringVector &patList);
QCString externalLinkTarget(const bool parent = false);
QCString externalRef(const QCString &relPath,const QCString &ref,bool href);
diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp
index 9a48e14..8e311b7 100644
--- a/src/vhdldocgen.cpp
+++ b/src/vhdldocgen.cpp
@@ -2165,8 +2165,9 @@ void VhdlDocGen::writeVHDLDeclaration(const MemberDef* mdef,OutputList &ol,
QCString s=mdef->briefDescription();
ol.startMemberDescription(mdef->anchor(), NULL, mm == VhdlDocGen::PORT);
ol.generateDoc(mdef->briefFile(),mdef->briefLine(),
- mdef->getOuterScope()?mdef->getOuterScope():d,
- mdef,s.data(),TRUE,FALSE,0,TRUE,FALSE);
+ mdef->getOuterScope()?mdef->getOuterScope():d,
+ mdef,s.data(),TRUE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
if (detailsVisible)
{
ol.pushGeneratorState();
@@ -2270,7 +2271,8 @@ void VhdlDocGen::writeVHDLDeclarations(const MemberList* ml,OutputList &ol,
if (subtitle && subtitle[0]!=0)
{
ol.startMemberSubtitle();
- ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,0,TRUE,FALSE);
+ ol.generateDoc("[generated]",-1,0,0,subtitle,FALSE,FALSE,
+ 0,TRUE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberSubtitle();
} //printf("memberGroupList=%p\n",memberGroupList);
@@ -2296,7 +2298,8 @@ void VhdlDocGen::writeVHDLDeclarations(const MemberList* ml,OutputList &ol,
{
//printf("Member group has docs!\n");
ol.startMemberGroupDocs();
- ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE);
+ ol.generateDoc("[generated]",-1,0,0,mg->documentation()+"\n",FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
ol.endMemberGroupDocs();
}
ol.startMemberGroup();
@@ -2939,10 +2942,8 @@ void VhdlDocGen::createFlowChart(const MemberDef *mdef)
auto parser { Doxygen::parserManager->getOutlineParser(".vhd") };
VhdlDocGen::setFlowMember(mdef);
std::shared_ptr<Entry> root = std::make_shared<Entry>();
- QStrList filesInSameTu;
- parser->startTranslationUnit("");
- parser->parseInput("",codeFragment.data(),root,FALSE,filesInSameTu);
- parser->finishTranslationUnit();
+ StringVector filesInSameTu;
+ parser->parseInput("",codeFragment.data(),root,nullptr);
}
void VhdlDocGen::resetCodeVhdlParserState()
@@ -3171,20 +3172,18 @@ void FlowChart::printFlowTree()
void FlowChart::colTextNodes()
{
- QCString text;
- FlowChart *flno;
+ FlowChart *flno = NULL;
bool found=FALSE;
for (uint j=0;j<flowList.count();j++)
{
FlowChart *flo=flowList.at(j);
if (flo->type&TEXT_NO)
{
- text+=flo->text+'\n';
if (!found)
{
flno=flo;
}
- if (found)
+ else
{
flno->text+=flo->text;
flowList.remove(flo);
@@ -3524,12 +3523,11 @@ void FlowChart::printUmlTree()
}
qcs+="\n";
- QCString & htmlOutDir = Config_getString(HTML_OUTPUT);
+ QCString htmlOutDir = Config_getString(HTML_OUTPUT);
QCString n=convertNameToFileName();
- QCString tmp=htmlOutDir;
- n=PlantumlManager::instance()->writePlantUMLSource(tmp,n,qcs,PlantumlManager::PUML_SVG);
- PlantumlManager::instance()->generatePlantUMLOutput(n.data(),tmp.data(),PlantumlManager::PUML_SVG);
+ n=PlantumlManager::instance()->writePlantUMLSource(htmlOutDir,n,qcs,PlantumlManager::PUML_SVG);
+ PlantumlManager::instance()->generatePlantUMLOutput(n,htmlOutDir,PlantumlManager::PUML_SVG);
}
QCString FlowChart::convertNameToFileName()
@@ -3638,9 +3636,8 @@ void FlowChart::writeFlowChart()
#ifdef DEBUGFLOW
printFlowTree();
#endif
- const MemberDef *p=VhdlDocGen::getFlowMember();
- if (p->isStatic())
+ if (!Config_getString(PLANTUML_JAR_PATH).isEmpty())
{
printUmlTree();
delFlowList();
diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp
index ea60dd6..7c83d52 100644
--- a/src/vhdljjparser.cpp
+++ b/src/vhdljjparser.cpp
@@ -81,6 +81,7 @@ struct VHDLOutlineParser::Private
VHDLDocInfo str_doc;
VhdlParser::SharedState shared;
QCString forL;
+ int code = 0;
};
@@ -125,7 +126,7 @@ VHDLOutlineParser::~VHDLOutlineParser()
}
void VHDLOutlineParser::parseInput(const char *fileName,const char *fileBuf,
- const std::shared_ptr<Entry> &root, bool ,QStrList&)
+ const std::shared_ptr<Entry> &root, ClangTUParser *)
{
VhdlParser::SharedState *s = &p->shared;
p->thisParser=this;
@@ -264,34 +265,128 @@ void VHDLOutlineParser::handleFlowComment(const char* doc)
}
}
+int VHDLOutlineParser::checkInlineCode(QCString &doc)
+{
+ QRegExp cs("[\\\\@]code");
+ QRegExp cend("[\\s ]*[\\\\@]endcode");
+ QRegExp cbrief("[\\\\@]brief");
+ int index = doc.find(cs);
+
+ if (doc.contains(cend) > 0)
+ return 1;
+
+ if (index < 0)
+ return index;
+
+ VhdlParser::SharedState *s = &p->shared;
+ p->strComment += doc;
+ p->code = p->inputString.find(cs, p->code + 1);
+ int com = p->inputString.find(p->strComment.data());
+ int ref = p->inputString.find(cend, p->code + 1);
+ int len = p->strComment.size();
+
+ int ll = com + len;
+ int diff = ref - ll - 3;
+ QCString code = p->inputString.mid(ll, diff);
+ int iLine = 0;
+ code = stripLeadingAndTrailingEmptyLines(code, iLine);
+ int val = code.contains('\n');
+ VhdlDocGen::prepareComment(p->strComment);
+ QCStringList ql = QCStringList::split('\n', p->strComment);
+
+ QCString co;
+ QCString na;
+ for (QCString qcs : ql)
+ {
+ qcs = qcs.simplifyWhiteSpace();
+ if (qcs.contains(cs))
+ {
+ int i = qcs.find('{');
+ int j = qcs.find('}');
+ if (i > 0 && j > 0 && j > i)
+ {
+ na = qcs.mid(i + 1, (j - i - 1));
+ }
+ continue;
+ }
+ qcs = qcs.replace(cbrief, "");
+ co += qcs;
+ co += '\n';
+ }
+
+ VhdlDocGen::prepareComment(co);
+
+ Entry gBlock;
+ if (!na.isEmpty())
+ gBlock.name = na;
+ else
+ gBlock.name = "misc" + VhdlDocGen::getRecordNumber();
+ gBlock.startLine = p->yyLineNr+iLine-1;
+ gBlock.bodyLine = p->yyLineNr+iLine-1 ;
+ gBlock.doc = code;
+ gBlock.inbodyDocs = code;
+ gBlock.brief = co;
+ gBlock.section = Entry::VARIABLE_SEC;
+ gBlock.spec = VhdlDocGen::MISCELLANEOUS;
+ gBlock.fileName = p->yyFileName;
+ gBlock.endBodyLine = p->yyLineNr + val +iLine;
+ gBlock.lang = SrcLangExt_VHDL;
+ std::shared_ptr<Entry> compound;
+
+ if (s->lastEntity)
+ compound = s->lastEntity;
+ else if (s->lastCompound)
+ compound = s->lastCompound;
+ else
+ compound = 0;
+
+ if (compound)
+ {
+ compound->copyToSubEntry(&gBlock);
+ }
+ else
+ {
+ gBlock.type = "misc"; // global code like library ieee...
+ s->current_root->copyToSubEntry(&gBlock);
+ }
+ p->strComment.resize(0);
+ return 1;
+}
-void VHDLOutlineParser::handleCommentBlock(const char* doc1,bool brief)
+void VHDLOutlineParser::handleCommentBlock(const char *doc1, bool brief)
{
+ int position = 0;
+ bool needsEntry = FALSE;
VhdlParser::SharedState *s = &p->shared;
QCString doc = doc1;
- if (doc.isEmpty()) return;
- if (checkMultiComment(doc,p->yyLineNr))
+ if (doc.isEmpty())
+ return;
+
+ if (checkMultiComment(doc, p->yyLineNr))
{
p->strComment.resize(0);
return;
}
- VhdlDocGen::prepareComment(doc);
+ if (checkInlineCode(doc) > 0)
+ {
+ return;
+ }
- Protection protection=Public;
+ Protection protection = Public;
+ VhdlDocGen::prepareComment(doc);
- if (p->oldEntry==s->current.get())
+ if (p->oldEntry == s->current.get())
{
- //printf("\n find pending message < %s > at line: %d \n ",doc.data(),iDocLine);
- p->str_doc.doc=doc;
- p->str_doc.iDocLine=p->iDocLine;
- p->str_doc.brief=brief;
- p->str_doc.pending=TRUE;
+ p->str_doc.doc = doc;
+ p->str_doc.iDocLine = p->iDocLine;
+ p->str_doc.brief = brief;
+ p->str_doc.pending = TRUE;
return;
}
- p->oldEntry=s->current.get();
+ p->oldEntry = s->current.get();
if (brief)
{
@@ -302,45 +397,41 @@ void VHDLOutlineParser::handleCommentBlock(const char* doc1,bool brief)
s->current->docLine = p->yyLineNr;
}
- int j=doc.find("[plant]");
- if (j>=0)
- {
- doc=doc.remove(j,7);
- s->current->stat=true;
- }
- int position=0;
- bool needsEntry=FALSE;
- QCString processedDoc = processMarkdownForCommentBlock(doc,p->yyFileName,p->iDocLine);
+
+ Markdown markdown(p->yyFileName,p->iDocLine);
+ int lineNr = p->iDocLine;
+ QCString processedDoc = Config_getBool(MARKDOWN_SUPPORT) ? markdown.process(doc,lineNr) : doc;
+
while (p->commentScanner.parseCommentBlock(
- p->thisParser,
- s->current.get(),
- processedDoc, // text
- p->yyFileName, // file
- p->iDocLine, // line of block start
- brief,
- 0,
- FALSE,
- protection,
- position,
- needsEntry
- )
- )
- {
- if (needsEntry) newEntry();
+ p->thisParser,
+ s->current.get(),
+ processedDoc, // text
+ p->yyFileName, // file
+ lineNr, // line of block start
+ brief,
+ 0,
+ FALSE,
+ protection,
+ position,
+ needsEntry,
+ Config_getBool(MARKDOWN_SUPPORT)))
+ {
+ if (needsEntry)
+ newEntry();
}
if (needsEntry)
{
if (p->varr)
{
- p->varr=FALSE;
- s->current->name=p->varName;
- s->current->section=Entry::VARIABLEDOC_SEC;
- p->varName="";
+ p->varr = FALSE;
+ s->current->name = p->varName;
+ s->current->section = Entry::VARIABLEDOC_SEC;
+ p->varName = "";
}
newEntry();
}
- p->iDocLine=-1;
+ p->iDocLine = -1;
p->strComment.resize(0);
}
diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h
index c4a55de..651221c 100755
--- a/src/vhdljjparser.h
+++ b/src/vhdljjparser.h
@@ -32,20 +32,17 @@ class VHDLOutlineParser : public OutlineParserInterface
public:
VHDLOutlineParser();
virtual ~VHDLOutlineParser();
- void startTranslationUnit(const char *) {}
- void finishTranslationUnit() {}
void parseInput(const char * fileName,
const char *fileBuf,
const std::shared_ptr<Entry> &root,
- bool sameTranslationUnit,
- QStrList &filesInSameTranslationUnit);
+ ClangTUParser *clangParser);
bool needsPreprocessing(const QCString &) const { return TRUE; }
void parsePrototype(const char *text);
// interface for generated parser code
-
+
void setLineParsed(int tok);
int getLine(int tok);
int getLine();
@@ -72,6 +69,7 @@ class VHDLOutlineParser : public OutlineParserInterface
bool checkMultiComment(QCString& qcs,int line);
void insertEntryAtLine(std::shared_ptr<Entry> ce,int line);
QString getNameID();
+ int checkInlineCode(QCString & doc);
private:
struct Private;
std::unique_ptr<Private> p;
diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp
index ec728c4..19f1553 100644
--- a/src/xmlgen.cpp
+++ b/src/xmlgen.cpp
@@ -403,7 +403,8 @@ static void writeXMLDocBlock(FTextStream &t,
QCString stext = text.stripWhiteSpace();
if (stext.isEmpty()) return;
// convert the documentation string into an abstract syntax tree
- DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE);
+ DocNode *root = validatingParseDoc(fileName,lineNr,scope,md,text,FALSE,FALSE,
+ 0,FALSE,FALSE,Config_getBool(MARKDOWN_SUPPORT));
// create a code generator
XMLCodeGenerator *xmlCodeGen = new XMLCodeGenerator(t);
// create a parse tree visitor for XML
@@ -1152,7 +1153,8 @@ static void writeInnerNamespaces(const NamespaceSDict *nl,FTextStream &t)
if (!nd->isHidden() && !nd->isAnonymous())
{
t << " <innernamespace refid=\"" << nd->getOutputFileBase()
- << "\">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
+ << "\"" << (nd->isInline() ? " inline=\"yes\"" : "")
+ << ">" << convertToXML(nd->name()) << "</innernamespace>" << endl;
}
}
}
@@ -1460,7 +1462,9 @@ static void generateXMLForNamespace(const NamespaceDef *nd,FTextStream &ti)
writeXMLHeader(t);
t << " <compounddef id=\"" << nd->getOutputFileBase()
- << "\" kind=\"namespace\" language=\""
+ << "\" kind=\"namespace\" "
+ << (nd->isInline()?"inline=\"yes\" ":"")
+ << "language=\""
<< langToString(nd->getLanguage()) << "\">" << endl;
t << " <compoundname>";
writeXMLString(t,nd->name());