diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2019-12-08 10:38:32 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-08 10:38:32 (GMT) |
commit | 0aadb2f3e79f7aec63d8de43534916bb7358f135 (patch) | |
tree | 211b939b77c914eea991e4a619fc0ae0e8c5d3d5 /src | |
parent | ef06c8d14c7889e723331601ac847cc481966f5c (diff) | |
parent | 6d4835dbe01a27923db8a1e4559b61da5065cb7a (diff) | |
download | Doxygen-0aadb2f3e79f7aec63d8de43534916bb7358f135.zip Doxygen-0aadb2f3e79f7aec63d8de43534916bb7358f135.tar.gz Doxygen-0aadb2f3e79f7aec63d8de43534916bb7358f135.tar.bz2 |
Merge branch 'master' into feature/bug_coverity_unint
Diffstat (limited to 'src')
50 files changed, 835 insertions, 895 deletions
@@ -18,28 +18,37 @@ #ifndef CODE_H #define CODE_H -#include "types.h" +#include "parserintf.h" -class CodeOutputInterface; class FileDef; class MemberDef; class QCString; class Definition; -class CodeScanner +class CCodeParser : public CodeParserInterface { public: - CodeScanner(); - virtual ~CodeScanner(); - void parseCCode(CodeOutputInterface &,const char *,const QCString &, - SrcLangExt lang, bool isExample, const char *exName,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, - bool collectXRefs); - void reset(); + CCodeParser(); + virtual ~CCodeParser(); + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt lang, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + const MemberDef *memberDef=0, + bool showLineNumbers=TRUE, + const Definition *searchCtx=0, + bool collectXRefs=TRUE + ); + void resetCodeParserState(); private: struct Private; - Private *p; + std::unique_ptr<Private> p; }; #endif @@ -3861,25 +3861,30 @@ static void restoreObjCContext(yyscan_t yyscanner) } } -struct CodeScanner::Private +struct CCodeParser::Private { yyscan_t yyscanner; codeYY_state state; }; -CodeScanner::CodeScanner() +CCodeParser::CCodeParser() : p(std::make_unique<CCodeParser::Private>()) { - p = new Private; codeYYlex_init_extra(&p->state,&p->yyscanner); +#ifdef FLEX_DEBUG + codeYYset_debug(1,p->yyscanner); +#endif } -CodeScanner::~CodeScanner() +CCodeParser::~CCodeParser() { + struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; + yyextra->classScopeLengthStack.clear(); + delete yyextra->codeClassSDict; + yyextra->codeClassSDict=0; codeYYlex_destroy(p->yyscanner); - delete p; } -void CodeScanner::reset() +void CCodeParser::resetCodeParserState() { struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; //printf("***CodeParser::reset()\n"); @@ -3895,7 +3900,7 @@ void CodeScanner::reset() yyextra->anchorCount = 0; } -void CodeScanner::parseCCode(CodeOutputInterface &od,const char *className,const QCString &s, +void CCodeParser::parseCode(CodeOutputInterface &od,const char *className,const QCString &s, SrcLangExt lang,bool exBlock, const char *exName,FileDef *fd, int startLine,int endLine,bool inlineFragment, const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, @@ -3912,7 +3917,7 @@ void CodeScanner::parseCCode(CodeOutputInterface &od,const char *className,const if (yyextra->codeClassSDict==0) { - reset(); + resetCodeParserState(); } yyextra->code = &od; yyextra->inputString = s; diff --git a/src/commentcnv.l b/src/commentcnv.l index 940f1a5..13a21c3 100644 --- a/src/commentcnv.l +++ b/src/commentcnv.l @@ -1093,6 +1093,9 @@ void convertCppComments(BufStr *inBuf,BufStr *outBuf,const char *fileName) yyscan_t yyscanner; commentcnvYY_state extra; commentcnvYYlex_init_extra(&extra,&yyscanner); +#ifdef FLEX_DEBUG + commentcnvYYset_debug(1,yyscanner); +#endif struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("convertCppComments(%s)\n",fileName); yyextra->inBuf = inBuf; diff --git a/src/commentscan.h b/src/commentscan.h index 7d2189f..f471890 100644 --- a/src/commentscan.h +++ b/src/commentscan.h @@ -19,7 +19,7 @@ #include "types.h" class Entry; -class ParserInterface; +class OutlineParserInterface; /** @file * @brief Interface for the comment block parser */ @@ -72,7 +72,7 @@ QCString preprocessCommentBlock(const QCString &comment, * where to proceed parsing. FALSE indicates no further processing is * needed. */ -bool parseCommentBlock(ParserInterface *parser, +bool parseCommentBlock(OutlineParserInterface *parser, Entry *curEntry, const QCString &comment, const QCString &fileName, diff --git a/src/commentscan.l b/src/commentscan.l index 2b10f87..fa454e5 100644 --- a/src/commentscan.l +++ b/src/commentscan.l @@ -395,7 +395,7 @@ class GuardedSection * statics */ -static ParserInterface *langParser; // the language parser that is calling us +static OutlineParserInterface *langParser; // the language parser that is calling us static QCString inputString; // input string static int inputPosition; // read pointer static QCString yyFileName; // file name that is read from @@ -3127,7 +3127,7 @@ QCString preprocessCommentBlock(const QCString &comment, } } -bool parseCommentBlock(/* in */ ParserInterface *parser, +bool parseCommentBlock(/* in */ OutlineParserInterface *parser, /* in */ Entry *curEntry, /* in */ const QCString &comment, /* in */ const QCString &fileName, diff --git a/src/context.cpp b/src/context.cpp index ebe6857..476c15e 100644 --- a/src/context.cpp +++ b/src/context.cpp @@ -1302,8 +1302,8 @@ static TemplateVariant parseDoc(const Definition *def,const QCString &file,int l static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const QCString &relPath, const QCString &code,int startLine=-1,int endLine=-1,bool showLineNumbers=FALSE) { - ParserInterface *pIntf = Doxygen::parserManager->getParser(md->getDefFileExtension()); - pIntf->resetCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(md->getDefFileExtension()); + intf.resetCodeParserState(); QGString s; FTextStream t(&s); switch (g_globals.outputFormat) @@ -1311,14 +1311,14 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(t,relPath); - pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), + intf.parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), startLine,endLine,TRUE,md,showLineNumbers,md); } break; case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(t,relPath,md->docFile()); - pIntf->parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), + intf.parseCode(codeGen,scopeName,code,md->getLanguage(),FALSE,0,md->getBodyDef(), startLine,endLine,TRUE,md,showLineNumbers,md); } break; @@ -1333,8 +1333,8 @@ static TemplateVariant parseCode(MemberDef *md,const QCString &scopeName,const Q static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) { static bool filterSourceFiles = Config_getBool(FILTER_SOURCE_FILES); - ParserInterface *pIntf = Doxygen::parserManager->getParser(fd->getDefFileExtension()); - pIntf->resetCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); + intf.resetCodeParserState(); QGString s; FTextStream t(&s); switch (g_globals.outputFormat) @@ -1342,7 +1342,7 @@ static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) case ContextOutputFormat_Html: { HtmlCodeGenerator codeGen(t,relPath); - pIntf->parseCode(codeGen,0, + intf.parseCode(codeGen,0, fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources fd->getLanguage(), // lang FALSE, // isExampleBlock @@ -1361,7 +1361,7 @@ static TemplateVariant parseCode(const FileDef *fd,const QCString &relPath) case ContextOutputFormat_Latex: { LatexCodeGenerator codeGen(t,relPath,fd->docFile()); - pIntf->parseCode(codeGen,0, + intf.parseCode(codeGen,0, fileToString(fd->absFilePath(),filterSourceFiles,TRUE), // the sources fd->getLanguage(), // lang FALSE, // isExampleBlock diff --git a/src/declinfo.l b/src/declinfo.l index 37d0449..af94569 100644 --- a/src/declinfo.l +++ b/src/declinfo.l @@ -262,7 +262,7 @@ void parseFuncDecl(const QCString &decl,const SrcLangExt lang,QCString &cl,QCStr struct yyguts_t *yyg = (struct yyguts_t*)g_yyscanner; #ifdef FLEX_DEBUG - yyset_debug(1,g_yyscanner); + declinfoYYset_debug(1,g_yyscanner); #endif printlex(yy_flex_debug, TRUE, __FILE__, NULL); diff --git a/src/definition.cpp b/src/definition.cpp index 80060ba..9a1519e 100644 --- a/src/definition.cpp +++ b/src/definition.cpp @@ -1262,26 +1262,26 @@ void DefinitionImpl::writeInlineCode(OutputList &ol,const char *scopeName) const { //printf("Adding code fragment '%s' ext='%s'\n", // codeFragment.data(),m_impl->defFileExt.data()); - ParserInterface *pIntf = Doxygen::parserManager->getParser(m_impl->defFileExt); - pIntf->resetCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(m_impl->defFileExt); + intf.resetCodeParserState(); //printf("Read:\n'%s'\n\n",codeFragment.data()); const MemberDef *thisMd = 0; if (definitionType()==TypeMember) thisMd = dynamic_cast <const MemberDef*>(this); ol.startCodeFragment(); - pIntf->parseCode(ol, // codeOutIntf - scopeName, // scope - codeFragment, // input - m_impl->lang, // lang - FALSE, // isExample - 0, // exampleName - m_impl->body->fileDef, // fileDef - actualStart, // startLine - actualEnd, // endLine - TRUE, // inlineFragment - thisMd, // memberDef - TRUE // show line numbers - ); + intf.parseCode(ol, // codeOutIntf + scopeName, // scope + codeFragment, // input + m_impl->lang, // lang + FALSE, // isExample + 0, // exampleName + m_impl->body->fileDef, // fileDef + actualStart, // startLine + actualEnd, // endLine + TRUE, // inlineFragment + thisMd, // memberDef + TRUE // show line numbers + ); ol.endCodeFragment(); } } diff --git a/src/docbookvisitor.cpp b/src/docbookvisitor.cpp index ce3a845..08ec4dd 100644 --- a/src/docbookvisitor.cpp +++ b/src/docbookvisitor.cpp @@ -280,8 +280,8 @@ DB_VIS_C { case DocVerbatim::Code: // fall though m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getParser(m_langExt) - ->parseCode(m_ci,s->context(),s->text(),langExt, + Doxygen::parserManager->getCodeParser(m_langExt) + .parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); m_t << "</computeroutput></literallayout>"; break; @@ -389,8 +389,8 @@ DB_VIS_C m_t << "<literallayout><computeroutput>"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -401,8 +401,8 @@ DB_VIS_C break; case DocInclude::Include: m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -421,8 +421,8 @@ DB_VIS_C break; case DocInclude::Snippet: m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -436,8 +436,8 @@ DB_VIS_C QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); m_t << "<literallayout><computeroutput>"; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -489,8 +489,8 @@ DB_VIS_C fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getParser(locLangExt) - ->parseCode(m_ci,op->context(), + Doxygen::parserManager->getCodeParser(locLangExt) + .parseCode(m_ci,op->context(), op->text(),langExt,op->isExample(), op->exampleFile(), fd, // fileDef diff --git a/src/doxygen.cpp b/src/doxygen.cpp index 3277bbe..fd4341c 100644 --- a/src/doxygen.cpp +++ b/src/doxygen.cpp @@ -75,10 +75,12 @@ #include "searchindex.h" #include "parserintf.h" #include "htags.h" +#include "pycode.h" #include "pyscanner.h" +#include "fortrancode.h" #include "fortranscanner.h" -#include "xmlscanner.h" -#include "sqlscanner.h" +#include "xmlcode.h" +#include "sqlcode.h" #include "tclscanner.h" #include "code.h" #include "objcache.h" @@ -420,9 +422,9 @@ static STLInfo g_stlinfo[] = { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE } }; -static void addSTLMember(const std::unique_ptr<Entry> &root,const char *type,const char *name) +static void addSTLMember(const std::shared_ptr<Entry> &root,const char *type,const char *name) { - std::unique_ptr<Entry> memEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> memEntry = std::make_shared<Entry>(); memEntry->name = name; memEntry->type = type; memEntry->protection = Public; @@ -433,9 +435,9 @@ static void addSTLMember(const std::unique_ptr<Entry> &root,const char *type,con root->moveToSubEntryAndKeep(memEntry); } -static void addSTLIterator(const std::unique_ptr<Entry> &classEntry,const char *name) +static void addSTLIterator(const std::shared_ptr<Entry> &classEntry,const char *name) { - std::unique_ptr<Entry> iteratorClassEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> iteratorClassEntry = std::make_shared<Entry>(); iteratorClassEntry->fileName = "[STL]"; iteratorClassEntry->startLine = 1; iteratorClassEntry->name = name; @@ -446,14 +448,14 @@ static void addSTLIterator(const std::unique_ptr<Entry> &classEntry,const char * classEntry->moveToSubEntryAndKeep(iteratorClassEntry); } -static void addSTLClass(const std::unique_ptr<Entry> &root,const STLInfo *info) +static void addSTLClass(const std::shared_ptr<Entry> &root,const STLInfo *info) { //printf("Adding STL class %s\n",info->className); QCString fullName = info->className; fullName.prepend("std::"); // add fake Entry for the class - std::unique_ptr<Entry> classEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> classEntry = std::make_shared<Entry>(); classEntry->fileName = "[STL]"; classEntry->startLine = 1; classEntry->name = fullName; @@ -488,9 +490,9 @@ static void addSTLClass(const std::unique_ptr<Entry> &root,const STLInfo *info) addSTLMember(classEntry,info->templType2,info->templName2); } if (fullName=="std::auto_ptr" || fullName=="std::smart_ptr" || fullName=="std::shared_ptr" || - fullName=="std::unique_ptr" || fullName=="std::weak_ptr") + fullName=="std::shared_ptr" || fullName=="std::weak_ptr") { - std::unique_ptr<Entry> memEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> memEntry = std::make_shared<Entry>(); memEntry->name = "operator->"; memEntry->args = "()"; memEntry->type = "T*"; @@ -521,9 +523,9 @@ static void addSTLClass(const std::unique_ptr<Entry> &root,const STLInfo *info) } -static void addSTLClasses(const std::unique_ptr<Entry> &root) +static void addSTLClasses(const std::shared_ptr<Entry> &root) { - std::unique_ptr<Entry> namespaceEntry = std::make_unique<Entry>(); + std::shared_ptr<Entry> namespaceEntry = std::make_shared<Entry>(); namespaceEntry->fileName = "[STL]"; namespaceEntry->startLine = 1; namespaceEntry->name = "std"; @@ -8992,8 +8994,8 @@ static void generateExampleDocs() for (pdi.toFirst();(pd=pdi.current());++pdi) { msg("Generating docs for example %s...\n",pd->name().data()); - ParserInterface *pIntf = Doxygen::parserManager->getParser(".c"); // TODO: do this on code type - pIntf->resetCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(".c"); // TODO: do this on code type + intf.resetCodeParserState(); QCString n=pd->getOutputFileBase(); startFile(*g_outputList,n,n,pd->name()); startTitle(*g_outputList,n); @@ -9199,7 +9201,7 @@ static void compareDoxyfile() //---------------------------------------------------------------------------- -static void readTagFile(const std::unique_ptr<Entry> &root,const char *tl) +static void readTagFile(const std::shared_ptr<Entry> &root,const char *tl) { QCString tagLine = tl; QCString fileName; @@ -9349,7 +9351,7 @@ static void copyExtraFiles(QStrList files,const QCString &filesOption,const QCSt //---------------------------------------------------------------------------- -static ParserInterface *getParserForFile(const char *fn) +static OutlineParserInterface &getParserForFile(const char *fn) { QCString fileName=fn; QCString extension; @@ -9364,11 +9366,11 @@ static ParserInterface *getParserForFile(const char *fn) extension = ".no_extension"; } - return Doxygen::parserManager->getParser(extension); + return Doxygen::parserManager->getOutlineParser(extension); } -static void parseFile(ParserInterface *parser, - const std::unique_ptr<Entry> &root,FileDef *fd,const char *fn, +static void parseFile(OutlineParserInterface &parser, + const std::shared_ptr<Entry> &root,FileDef *fd,const char *fn, bool sameTu,QStrList &filesInSameTu) { #if USE_LIBCLANG @@ -9392,7 +9394,7 @@ static void parseFile(ParserInterface *parser, BufStr preBuf(fi.size()+4096); if (Config_getBool(ENABLE_PREPROCESSING) && - parser->needsPreprocessing(extension)) + parser.needsPreprocessing(extension)) { BufStr inBuf(fi.size()+4096); msg("Preprocessing %s...\n",fn); @@ -9421,15 +9423,15 @@ static void parseFile(ParserInterface *parser, fd->getAllIncludeFilesRecursively(filesInSameTu); } - std::unique_ptr<Entry> fileRoot = std::make_unique<Entry>(); + std::shared_ptr<Entry> fileRoot = std::make_shared<Entry>(); // use language parse to parse the file - parser->parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); + parser.parseInput(fileName,convBuf.data(),fileRoot,sameTu,filesInSameTu); fileRoot->setFileDef(fd); root->moveToSubEntryAndKeep(fileRoot); } //! parse the list of input files -static void parseFiles(const std::unique_ptr<Entry> &root) +static void parseFiles(const std::shared_ptr<Entry> &root) { #if USE_LIBCLANG static bool clangAssistedParsing = Config_getBool(CLANG_ASSISTED_PARSING); @@ -9455,8 +9457,8 @@ static void parseFiles(const std::unique_ptr<Entry> &root) if (fd->isSource() && !fd->isReference()) // this is a source file { QStrList filesInSameTu; - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); //printf(" got %d extra files in tu\n",filesInSameTu.count()); @@ -9478,7 +9480,7 @@ static void parseFiles(const std::unique_ptr<Entry> &root) } incFile = filesInSameTu.next(); } - parser->finishTranslationUnit(); + parser.finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } } @@ -9491,10 +9493,10 @@ static void parseFiles(const std::unique_ptr<Entry> &root) QStrList filesInSameTu; FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); ASSERT(fd!=0); - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); - parser->finishTranslationUnit(); + parser.finishTranslationUnit(); g_processedFiles.insert(*s,(void*)0x8); } } @@ -9510,8 +9512,8 @@ static void parseFiles(const std::unique_ptr<Entry> &root) QStrList filesInSameTu; FileDef *fd=findFileDef(Doxygen::inputNameDict,s->data(),ambig); ASSERT(fd!=0); - ParserInterface * parser = getParserForFile(s->data()); - parser->startTranslationUnit(s->data()); + OutlineParserInterface &parser = getParserForFile(s->data()); + parser.startTranslationUnit(s->data()); parseFile(parser,root,fd,s->data(),FALSE,filesInSameTu); } } @@ -10068,6 +10070,19 @@ static const char *getArg(int argc,char **argv,int &optind) //---------------------------------------------------------------------------- +/** @brief /dev/null outline parser */ +class NullOutlineParser : public OutlineParserInterface +{ + public: + void startTranslationUnit(const char *) {} + void finishTranslationUnit() {} + void parseInput(const char *, const char *,const std::shared_ptr<Entry> &, bool, QStrList &) {} + bool needsPreprocessing(const QCString &) const { return FALSE; } + void parsePrototype(const char *) {} +}; + + + void initDoxygen() { initResources(); @@ -10082,18 +10097,28 @@ void initDoxygen() Doxygen::runningTime.start(); Doxygen::preprocessor = new Preprocessor(); - Doxygen::parserManager = new ParserManager; - Doxygen::parserManager->registerDefaultParser( new FileParser); - Doxygen::parserManager->registerParser("c", new CLanguageScanner); - Doxygen::parserManager->registerParser("python", new PythonLanguageScanner); - Doxygen::parserManager->registerParser("fortran", new FortranLanguageScanner); - Doxygen::parserManager->registerParser("fortranfree", new FortranLanguageScannerFree); - Doxygen::parserManager->registerParser("fortranfixed", new FortranLanguageScannerFixed); - Doxygen::parserManager->registerParser("vhdl", new VHDLLanguageScanner); - Doxygen::parserManager->registerParser("xml", new XMLScanner); - Doxygen::parserManager->registerParser("sql", new SQLScanner); - Doxygen::parserManager->registerParser("tcl", new TclLanguageScanner); - Doxygen::parserManager->registerParser("md", new MarkdownFileParser); + Doxygen::parserManager = new ParserManager( std::make_unique<NullOutlineParser>(), + std::make_unique<FileCodeParser>()); + Doxygen::parserManager->registerParser("c", std::make_unique<COutlineParser>(), + std::make_unique<CCodeParser>()); + Doxygen::parserManager->registerParser("python", std::make_unique<PythonOutlineParser>(), + std::make_unique<PythonCodeParser>()); + Doxygen::parserManager->registerParser("fortran", std::make_unique<FortranOutlineParser>(), + std::make_unique<FortranCodeParser>()); + Doxygen::parserManager->registerParser("fortranfree", std::make_unique<FortranOutlineParserFree>(), + std::make_unique<FortranCodeParserFree>()); + Doxygen::parserManager->registerParser("fortranfixed", std::make_unique<FortranOutlineParserFixed>(), + std::make_unique<FortranCodeParserFixed>()); + Doxygen::parserManager->registerParser("vhdl", std::make_unique<VHDLOutlineParser>(), + std::make_unique<VHDLCodeParser>()); + Doxygen::parserManager->registerParser("xml", std::make_unique<NullOutlineParser>(), + std::make_unique<XMLCodeParser>()); + Doxygen::parserManager->registerParser("sql", std::make_unique<NullOutlineParser>(), + std::make_unique<SQLCodeParser>()); + Doxygen::parserManager->registerParser("tcl", std::make_unique<TclOutlineParser>(), + std::make_unique<TclCodeParser>()); + Doxygen::parserManager->registerParser("md", std::make_unique<MarkdownOutlineParser>(), + std::make_unique<FileCodeParser>()); // register any additional parsers here... @@ -11241,7 +11266,7 @@ void parseInput() * Handle Tag Files * **************************************************************************/ - std::unique_ptr<Entry> root = std::make_unique<Entry>(); + std::shared_ptr<Entry> root = std::make_shared<Entry>(); msg("Reading and parsing tag files\n"); QStrList &tagFileList = Config_getList(TAGFILES); diff --git a/src/entry.cpp b/src/entry.cpp index 066c4a0..cc8cd1f 100644 --- a/src/entry.cpp +++ b/src/entry.cpp @@ -116,7 +116,7 @@ Entry::Entry(const Entry &e) m_sublist.reserve(e.m_sublist.size()); for (const auto &cur : e.m_sublist) { - m_sublist.push_back(std::make_unique<Entry>(*cur)); + m_sublist.push_back(std::make_shared<Entry>(*cur)); } } @@ -136,11 +136,11 @@ void Entry::moveToSubEntryAndRefresh(Entry *¤t) current = new Entry; } -void Entry::moveToSubEntryAndRefresh(std::unique_ptr<Entry> ¤t) +void Entry::moveToSubEntryAndRefresh(std::shared_ptr<Entry> ¤t) { current->m_parent=this; - m_sublist.push_back(std::move(current)); - current = std::make_unique<Entry>(); + m_sublist.push_back(current); + current = std::make_shared<Entry>(); } void Entry::moveToSubEntryAndKeep(Entry *current) @@ -149,10 +149,10 @@ void Entry::moveToSubEntryAndKeep(Entry *current) m_sublist.emplace_back(current); } -void Entry::moveToSubEntryAndKeep(std::unique_ptr<Entry> ¤t) +void Entry::moveToSubEntryAndKeep(std::shared_ptr<Entry> ¤t) { current->m_parent=this; - m_sublist.push_back(std::move(current)); + m_sublist.push_back(current); } void Entry::copyToSubEntry(Entry *current) @@ -162,20 +162,20 @@ void Entry::copyToSubEntry(Entry *current) m_sublist.emplace_back(copy); } -void Entry::copyToSubEntry(const std::unique_ptr<Entry> ¤t) +void Entry::copyToSubEntry(const std::shared_ptr<Entry> ¤t) { - std::unique_ptr<Entry> copy = std::make_unique<Entry>(*current); + std::shared_ptr<Entry> copy = std::make_shared<Entry>(*current); copy->m_parent=this; - m_sublist.push_back(std::move(copy)); + m_sublist.push_back(copy); } -void Entry::moveFromSubEntry(const Entry *child,std::unique_ptr<Entry> &moveTo) +void Entry::moveFromSubEntry(const Entry *child,std::shared_ptr<Entry> &moveTo) { auto it = std::find_if(m_sublist.begin(),m_sublist.end(), - [child](const std::unique_ptr<Entry>&elem) { return elem.get()==child; }); + [child](const std::shared_ptr<Entry>&elem) { return elem.get()==child; }); if (it!=m_sublist.end()) { - moveTo = std::move(*it); + moveTo = *it; m_sublist.erase(it); } else @@ -187,7 +187,7 @@ void Entry::moveFromSubEntry(const Entry *child,std::unique_ptr<Entry> &moveTo) void Entry::removeSubEntry(const Entry *e) { auto it = std::find_if(m_sublist.begin(),m_sublist.end(), - [e](const std::unique_ptr<Entry>&elem) { return elem.get()==e; }); + [e](const std::shared_ptr<Entry>&elem) { return elem.get()==e; }); if (it!=m_sublist.end()) { m_sublist.erase(it); diff --git a/src/entry.h b/src/entry.h index 9d4ae9d..0391075 100644 --- a/src/entry.h +++ b/src/entry.h @@ -202,26 +202,26 @@ class Entry /*! Returns the list of children for this Entry * @see addSubEntry() and removeSubEntry() */ - const std::vector< std::unique_ptr<Entry> > &children() const { return m_sublist; } + const std::vector< std::shared_ptr<Entry> > &children() const { return m_sublist; } /*! @name add entry as a child and pass ownership. * @note This makes the entry passed invalid! (TODO: tclscanner.l still has use after move!) * @{ */ void moveToSubEntryAndKeep(Entry* e); - void moveToSubEntryAndKeep(std::unique_ptr<Entry> &e); + void moveToSubEntryAndKeep(std::shared_ptr<Entry> &e); /*! @} */ /*! @name add entry as a child, pass ownership and reinitialize entry */ void moveToSubEntryAndRefresh(Entry* &e); - void moveToSubEntryAndRefresh(std::unique_ptr<Entry> &e); + void moveToSubEntryAndRefresh(std::shared_ptr<Entry> &e); /*! take \a child of of to list of children and move it into \a moveTo */ - void moveFromSubEntry(const Entry *child,std::unique_ptr<Entry> &moveTo); + void moveFromSubEntry(const Entry *child,std::shared_ptr<Entry> &moveTo); /*! make a copy of \a e and add it as a child to this entry */ void copyToSubEntry (Entry* e); - void copyToSubEntry (const std::unique_ptr<Entry> &e); + void copyToSubEntry (const std::shared_ptr<Entry> &e); /*! Removes entry \a e from the list of children. * The entry will be deleted if found. @@ -332,7 +332,7 @@ class Entry private: Entry *m_parent; //!< parent node in the tree - std::vector< std::unique_ptr<Entry> > m_sublist; + std::vector< std::shared_ptr<Entry> > m_sublist; Entry &operator=(const Entry &); FileDef *m_fileDef; }; diff --git a/src/filedef.cpp b/src/filedef.cpp index 346fb62..0be5d75 100644 --- a/src/filedef.cpp +++ b/src/filedef.cpp @@ -1233,8 +1233,8 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu else #endif { - ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); - pIntf->resetCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); + intf.resetCodeParserState(); ol.startCodeFragment(); bool needs2PassParsing = Doxygen::parseSourcesNeeded && // we need to parse (filtered) sources for cross-references @@ -1244,13 +1244,13 @@ void FileDefImpl::writeSource(OutputList &ol,bool sameTu,QStrList &filesInSameTu if (needs2PassParsing) { // parse code for cross-references only (see bug707641) - pIntf->parseCode(devNullIntf,0, + intf.parseCode(devNullIntf,0, fileToString(absFilePath(),TRUE,TRUE), getLanguage(), FALSE,0,this ); } - pIntf->parseCode(ol,0, + intf.parseCode(ol,0, fileToString(absFilePath(),filterSourceFiles,TRUE), getLanguage(), // lang FALSE, // isExampleBlock @@ -1295,9 +1295,9 @@ void FileDefImpl::parseSource(bool sameTu,QStrList &filesInSameTu) else #endif { - ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); - pIntf->resetCodeParserState(); - pIntf->parseCode( + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); + intf.resetCodeParserState(); + intf.parseCode( devNullIntf,0, fileToString(absFilePath(),filterSourceFiles,TRUE), getLanguage(), diff --git a/src/fileparser.cpp b/src/fileparser.cpp index 45bdc81..34085dc 100644 --- a/src/fileparser.cpp +++ b/src/fileparser.cpp @@ -16,7 +16,7 @@ #include "fileparser.h" #include "outputgen.h" -void FileParser::parseCode(CodeOutputInterface &codeOutIntf, +void FileCodeParser::parseCode(CodeOutputInterface &codeOutIntf, const char *, // scopeName const QCString & input, SrcLangExt, // lang diff --git a/src/fileparser.h b/src/fileparser.h index 3132f92..3245878 100644 --- a/src/fileparser.h +++ b/src/fileparser.h @@ -18,15 +18,11 @@ #include "parserintf.h" -/** @brief General file parser */ -class FileParser : public ParserInterface +/** @brief Generic code parser */ +class FileCodeParser : public CodeParserInterface { public: - virtual ~FileParser() {} - void startTranslationUnit(const char *) {} - void finishTranslationUnit() {} - void parseInput(const char *, const char *,const std::unique_ptr<Entry> &, bool, QStrList &) {} - bool needsPreprocessing(const QCString &) const { return FALSE; } + virtual ~FileCodeParser() {} void parseCode(CodeOutputInterface &codeOutIntf, const char *scopeName, const QCString &input, @@ -43,8 +39,6 @@ class FileParser : public ParserInterface bool collectXRefs=TRUE ); void resetCodeParserState() {} - void parsePrototype(const char *) {} }; - #endif diff --git a/src/fortrancode.h b/src/fortrancode.h index 4df20a9..8391a0b 100644 --- a/src/fortrancode.h +++ b/src/fortrancode.h @@ -18,7 +18,7 @@ #ifndef FORTRANCODE_H #define FORTRANCODE_H -#include "types.h" +#include "parserintf.h" class CodeOutputInterface; class FileDef; @@ -26,13 +26,45 @@ class MemberDef; class QCString; class Definition; -void parseFortranCode(CodeOutputInterface &,const char *,const QCString &, - bool ,const char *,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, - bool collectRefs, FortranFormat format); -void resetFortranCodeParserState(); void codeFreeScanner(); const int fixedCommentAfter = 72; + +class FortranCodeParser : public CodeParserInterface +{ + public: + FortranCodeParser(FortranFormat format=FortranFormat_Unknown) : m_format(format) { } + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt lang, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + const MemberDef *memberDef=0, + bool showLineNumbers=TRUE, + const Definition *searchCtx=0, + bool collectXRefs=TRUE + ); + void resetCodeParserState(); + + private: + FortranFormat m_format; +}; + +class FortranCodeParserFree : public FortranCodeParser +{ + public: + FortranCodeParserFree() : FortranCodeParser(FortranFormat_Free) { } +}; + +class FortranCodeParserFixed : public FortranCodeParser +{ + public: + FortranCodeParserFixed() : FortranCodeParser(FortranFormat_Fixed) { } +}; + #endif diff --git a/src/fortrancode.l b/src/fortrancode.l index 3bbecd8..21d1fa5 100644 --- a/src/fortrancode.l +++ b/src/fortrancode.l @@ -1395,4 +1395,34 @@ void parseFortranCode(CodeOutputInterface &od,const char *,const QCString &s, return; } +//--------------------------------------------------------- + +void FortranCodeParser::parseCode(CodeOutputInterface & codeOutIntf, + const char * scopeName, + const QCString & input, + SrcLangExt /*lang*/, + bool isExampleBlock, + const char * exampleName, + FileDef * fileDef, + int startLine, + int endLine, + bool inlineFragment, + const MemberDef *memberDef, + bool showLineNumbers, + const Definition *searchCtx, + bool collectXRefs + ) +{ + ::parseFortranCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, + fileDef,startLine,endLine,inlineFragment,memberDef, + showLineNumbers,searchCtx,collectXRefs,m_format); +} + +void FortranCodeParser::resetCodeParserState() +{ + ::resetFortranCodeParserState(); +} + +//--------------------------------------------------------- + #include "fortrancode.l.h" diff --git a/src/fortranscanner.h b/src/fortranscanner.h index 6476c98..7a13f47 100644 --- a/src/fortranscanner.h +++ b/src/fortranscanner.h @@ -24,51 +24,35 @@ * * This is the Fortran language parser for doxygen. */ -class FortranLanguageScanner : public ParserInterface +class FortranOutlineParser : public OutlineParserInterface { public: - FortranLanguageScanner(FortranFormat format=FortranFormat_Unknown) : m_format(format) { } - virtual ~FortranLanguageScanner() {} + FortranOutlineParser(FortranFormat format=FortranFormat_Unknown) : m_format(format) { } void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension) const; - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ); - void resetCodeParserState(); void parsePrototype(const char *text); private: FortranFormat m_format; }; -class FortranLanguageScannerFree : public FortranLanguageScanner +class FortranOutlineParserFree : public FortranOutlineParser { public: - FortranLanguageScannerFree() : FortranLanguageScanner(FortranFormat_Free) { } + FortranOutlineParserFree() : FortranOutlineParser(FortranFormat_Free) { } }; -class FortranLanguageScannerFixed : public FortranLanguageScanner +class FortranOutlineParserFixed : public FortranOutlineParser { public: - FortranLanguageScannerFixed() : FortranLanguageScanner(FortranFormat_Fixed) { } + FortranOutlineParserFixed() : FortranOutlineParser(FortranFormat_Fixed) { } }; + #endif diff --git a/src/fortranscanner.l b/src/fortranscanner.l index e0d6d63..08c7a6a 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -136,7 +136,7 @@ static const char *directionParam[] = * * statics */ -static ParserInterface *g_thisParser; +static OutlineParserInterface *g_thisParser; static const char * inputString; static int inputPosition; static bool isFixedForm; @@ -145,7 +145,7 @@ static QCString inputStringSemi; ///< Input string after command separat static unsigned int inputPositionPrepass; static int lineCountPrepass = 0; -static QList<Entry> subrCurrent; +static std::vector< std::shared_ptr<Entry> > subrCurrent; struct CommentInPrepass { int column; @@ -162,14 +162,15 @@ static QFile inputFile; static QCString yyFileName; static int yyLineNr = 1 ; static int yyColNr = 0 ; -static Entry* current_root = 0 ; -static Entry* global_root = 0 ; -static Entry* file_root = 0 ; -static Entry* last_entry = 0 ; -static Entry* last_enum = 0 ; -static std::unique_ptr<Entry> current; +static Entry *current_root = 0; +static Entry *global_scope = 0; +static std::shared_ptr<Entry> global_root; +static std::shared_ptr<Entry> file_root; +static std::shared_ptr<Entry> last_entry; +static std::shared_ptr<Entry> last_enum; +static std::shared_ptr<Entry> current; static ScanVar v_type = V_IGNORE; // type of parsed variable -static std::vector<Entry*> moduleProcedures; // list of all interfaces which contain unresolved +static std::vector<std::shared_ptr<Entry> > moduleProcedures; // list of all interfaces which contain unresolved // module procedures static QCString docBlock; static bool docBlockInBody = FALSE; @@ -202,7 +203,6 @@ static SymbolModifiers currentModifiers; //! Holds program scope->symbol name->symbol modifiers. static QMap<Entry*,QMap<QCString,SymbolModifiers> > modifiers; -static Entry *global_scope = 0; static int anonCount = 0 ; //----------------------------------------------------------------------------- @@ -491,13 +491,13 @@ SCOPENAME ({ID}{BS}"::"{BS})* QCString name = QCString(yytext).stripWhiteSpace(); name = name.right(name.length() - 9).stripWhiteSpace().lower(); addInterface(name, ifType); - startScope(last_entry); + startScope(last_entry.get()); } } <InterfaceBody>^{BS}end{BS}interface({BS_}{ID})? { // end scope only if GENERIC interface - if (ifType == IF_GENERIC)last_entry->parent()->endBodyLine = yyLineNr - 1; + if (ifType == IF_GENERIC) last_entry->parent()->endBodyLine = yyLineNr - 1; if (ifType == IF_GENERIC && !endScope(current_root)) yyterminate(); @@ -510,12 +510,12 @@ SCOPENAME ({ID}{BS}"::"{BS})* <ModuleProcedure>{ID} { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) { addInterface(yytext, ifType); - startScope(last_entry); + startScope(last_entry.get()); } current->section = Entry::FUNCTION_SEC ; current->name = yytext; - moduleProcedures.push_back(current.get()); + moduleProcedures.push_back(current); addCurrentEntry(true); } <ModuleProcedure>"\n" { yyColNr -= 1; @@ -639,7 +639,7 @@ private { current->startLine = yyLineNr; /* if type is part of a module, mod name is necessary for output */ - if ((current_root) && + if (current_root && (current_root->section == Entry::CLASS_SEC || current_root->section == Entry::NAMESPACE_SEC)) { @@ -647,7 +647,7 @@ private { } addCurrentEntry(true); - startScope(last_entry); + startScope(last_entry.get()); BEGIN(TypedefBody); } } @@ -727,7 +727,7 @@ private { if (!endScope(current_root)) yyterminate(); - subrCurrent.remove(0u); + subrCurrent.pop_back(); yy_pop_state() ; } <BlockData>{ @@ -736,7 +736,7 @@ private { } <Start,ModuleBody,TypedefBody,SubprogBody,Enum>{ ^{BS}{TYPE_SPEC}/{SEPARATE} { - last_enum = 0; + last_enum.reset(); if (YY_START == Enum) { argType = "@"; // enum marker @@ -867,7 +867,7 @@ private { { current_root->copyToSubEntry(current); // add to the scope surrounding the enum (copy!) - last_enum = current.get(); + last_enum = current; current_root->parent()->moveToSubEntryAndRefresh(current); initEntry(); } @@ -1066,7 +1066,7 @@ private { } addCurrentEntry(true); - startScope(last_entry); + startScope(last_entry.get()); BEGIN( Enum ) ; } <Enum>"end"{BS}"enum" { @@ -1083,7 +1083,7 @@ private { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) { addInterface("$interface$", ifType); - startScope(last_entry); + startScope(last_entry.get()); } // TYPE_SPEC is for old function style function result @@ -1109,7 +1109,7 @@ private { if (ifType == IF_ABSTRACT || ifType == IF_SPECIFIC) { addInterface("$interface$", ifType); - startScope(last_entry); + startScope(last_entry.get()); } result = QCString(yytext).stripWhiteSpace(); @@ -1136,7 +1136,7 @@ private { current->args += ")"; current->args = removeRedundantWhiteSpace(current->args); addCurrentEntry(true); - startScope(last_entry); + startScope(last_entry.get()); BEGIN(SubprogBody); } <Parameterlist>{COMMA}|{BS} { current->args += yytext; @@ -1162,7 +1162,7 @@ private { newLine(); //printf("3=========> without parameterlist \n"); addCurrentEntry(true); - startScope(last_entry); + startScope(last_entry.get()); BEGIN(SubprogBody); } <SubprogBody>result{BS}\({BS}{ID} { @@ -1214,20 +1214,19 @@ private { unput(*yytext); if (v_type == V_VARIABLE) { - std::unique_ptr<Entry> tmp_entry; - current.swap(tmp_entry); + std::shared_ptr<Entry> tmp_entry = current; // temporarily switch to the previous entry if (last_enum) { - current.reset(last_enum); + current = last_enum; } else { - current.reset(last_entry); + current = last_entry; } handleCommentBlock(docBlock,TRUE); // switch back - tmp_entry.swap(current); + current = tmp_entry; } else if (v_type == V_PARAMETER) { @@ -1779,7 +1778,7 @@ static void popBuffer() { } /** used to copy entry to an interface module procedure */ -static void copyEntry(Entry *dest, const std::unique_ptr<Entry> &src) +static void copyEntry(std::shared_ptr<Entry> dest, const std::shared_ptr<Entry> &src) { dest->type = src->type; dest->fileName = src->fileName; @@ -2306,7 +2305,7 @@ static int yyread(char *buf,int max_size) static void initParser() { - last_entry = 0; + last_entry.reset(); } static void initEntry() @@ -2333,7 +2332,7 @@ static void addCurrentEntry(bool case_insens) { if (case_insens) current->name = current->name.lower(); //printf("===Adding entry %s to %s\n", current->name.data(), current_root->name.data()); - last_entry = current.get(); + last_entry = current; current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -2367,14 +2366,14 @@ static void addModule(const char *name, bool isModule) current->startLine = yyLineNr; current->protection = Public ; addCurrentEntry(true); - startScope(last_entry); + startScope(last_entry.get()); } static void addSubprogram(const char *text) { DBG_CTX((stderr,"1=========> got subprog, type: %s\n",text)); - subrCurrent.prepend(current.get()); + subrCurrent.push_back(current); current->section = Entry::FUNCTION_SEC ; QCString subtype = text; subtype=subtype.lower().stripWhiteSpace(); functionLine = (subtype.find("function") != -1); @@ -2487,7 +2486,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - docBlockInBody ? subrCurrent.getFirst() : current.get(), + docBlockInBody ? subrCurrent.back().get() : current.get(), processedDoc, // text yyFileName, // file lineNr, @@ -2515,9 +2514,8 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - std::unique_ptr<Entry> tmp_entry; - current.swap(tmp_entry); - current.reset(subrCurrent.getFirst()); // temporarily switch to the entry of the subroutine / function + std::shared_ptr<Entry> tmp_entry = current; + current = subrCurrent.back(); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation current->inbodyDocs = ""; @@ -2566,7 +2564,7 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) loc_doc.stripWhiteSpace(); if (loc_doc.isEmpty() || (loc_doc.lower() == argName.lower())) { - tmp_entry.swap(current); + current = tmp_entry; return; } handleCommentBlock(QCString("\n\n@param ") + directionParam[SymbolModifiers::OUT] + " " + @@ -2610,7 +2608,7 @@ static void subrHandleCommentBlock(const QCString &doc,bool brief) } // reset current back to the part inside the routine - tmp_entry.swap(current); + current = tmp_entry; } //---------------------------------------------------------------------------- /// Handle result description as defined after the declaration of the parameter @@ -2619,9 +2617,8 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief) QCString loc_doc; loc_doc = doc.stripWhiteSpace(); - std::unique_ptr<Entry> tmp_entry; - current.swap(tmp_entry); - current.reset(subrCurrent.getFirst()); // temporarily switch to the entry of the subroutine / function + std::shared_ptr<Entry> tmp_entry = current; + current = subrCurrent.back(); // temporarily switch to the entry of the subroutine / function // Still in the specification section so no inbodyDocs yet, but parameter documentation current->inbodyDocs = ""; @@ -2640,7 +2637,7 @@ static void subrHandleCommentBlockResult(const QCString &doc,bool brief) } // reset current back to the part inside the routine - tmp_entry.swap(current); + current = tmp_entry; } //---------------------------------------------------------------------------- @@ -2661,7 +2658,7 @@ level--; static void parseMain(const char *fileName,const char *fileBuf, - const std::unique_ptr<Entry> &rt, FortranFormat format) + const std::shared_ptr<Entry> &rt, FortranFormat format) { char *tmpBuf = NULL; initParser(); @@ -2677,7 +2674,7 @@ static void parseMain(const char *fileName,const char *fileBuf, gstat = FALSE; virt = Normal; current_root = rt.get(); - global_root = rt.get(); + global_root = rt; inputFile.setName(fileName); if (inputFile.open(IO_ReadOnly)) { @@ -2719,11 +2716,11 @@ static void parseMain(const char *fileName,const char *fileBuf, Doxygen::docGroup.enterFile(yyFileName,yyLineNr); // add entry for the file - current = std::make_unique<Entry>(); + current = std::make_shared<Entry>(); current->lang = SrcLangExt_Fortran; current->name = yyFileName; current->section = Entry::SOURCE_SEC; - file_root = current.get(); + file_root = current; current_root->moveToSubEntryAndRefresh(current); current->lang = SrcLangExt_Fortran; @@ -2757,9 +2754,9 @@ static void parseMain(const char *fileName,const char *fileBuf, //---------------------------------------------------------------------------- -void FortranLanguageScanner::parseInput(const char *fileName, +void FortranOutlineParser::parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { @@ -2772,37 +2769,11 @@ void FortranLanguageScanner::parseInput(const char *fileName, printlex(yy_flex_debug, FALSE, __FILE__, fileName); } -void FortranLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, - const char * scopeName, - const QCString & input, - SrcLangExt /*lang*/, - bool isExampleBlock, - const char * exampleName, - FileDef * fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) -{ - ::parseFortranCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, - fileDef,startLine,endLine,inlineFragment,memberDef, - showLineNumbers,searchCtx,collectXRefs,m_format); -} - -bool FortranLanguageScanner::needsPreprocessing(const QCString &extension) const +bool FortranOutlineParser::needsPreprocessing(const QCString &extension) const { return extension!=extension.lower(); // use preprocessor only for upper case extensions } -void FortranLanguageScanner::resetCodeParserState() -{ - ::resetFortranCodeParserState(); -} - -void FortranLanguageScanner::parsePrototype(const char *text) +void FortranOutlineParser::parsePrototype(const char *text) { QCString buffer = QCString(text); pushBuffer(buffer); @@ -2813,6 +2784,8 @@ void FortranLanguageScanner::parsePrototype(const char *text) popBuffer(); } +//---------------------------------------------------------------------------- + static void scanner_abort() { fprintf(stderr,"********************************************************************\n"); @@ -2823,7 +2796,7 @@ static void scanner_abort() for (const auto &ce : global_root->children()) { - if (ce.get() == file_root) start=TRUE; + if (ce == file_root) start=TRUE; if (start) ce->reset(); } diff --git a/src/htmldocvisitor.cpp b/src/htmldocvisitor.cpp index 513c3a4..3dec509 100644 --- a/src/htmldocvisitor.cpp +++ b/src/htmldocvisitor.cpp @@ -518,8 +518,8 @@ void HtmlDocVisitor::visit(DocVerbatim *s) case DocVerbatim::Code: forceEndParagraph(s); m_t << PREFRAG_START; - Doxygen::parserManager->getParser(lang) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(lang) + .parseCode(m_ci, s->context(), s->text(), langExt, @@ -666,8 +666,8 @@ void HtmlDocVisitor::visit(DocInclude *inc) case DocInclude::Include: forceEndParagraph(inc); m_t << PREFRAG_START; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), inc->text(), langExt, @@ -690,8 +690,8 @@ void HtmlDocVisitor::visit(DocInclude *inc) m_t << PREFRAG_START; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), inc->text(), langExt, @@ -732,8 +732,8 @@ void HtmlDocVisitor::visit(DocInclude *inc) { forceEndParagraph(inc); m_t << PREFRAG_START; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -757,8 +757,8 @@ void HtmlDocVisitor::visit(DocInclude *inc) m_t << PREFRAG_START; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -810,8 +810,8 @@ void HtmlDocVisitor::visit(DocIncOperator *op) QFileInfo cfi( op->includeFileName() ); fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getParser(locLangExt) - ->parseCode( + Doxygen::parserManager->getCodeParser(locLangExt) + .parseCode( m_ci, op->context(), op->text(), diff --git a/src/latexdocvisitor.cpp b/src/latexdocvisitor.cpp index a0bbf73..5fd2e78 100644 --- a/src/latexdocvisitor.cpp +++ b/src/latexdocvisitor.cpp @@ -349,8 +349,8 @@ void LatexDocVisitor::visit(DocVerbatim *s) { m_t << "\n\\begin{DoxyCode}{" << usedTableLevels() << "}\n"; LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getParser(lang) - ->parseCode(m_ci,s->context(),s->text(),langExt, + Doxygen::parserManager->getCodeParser(lang) + .parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); LatexCodeGenerator::setDoxyCodeOpen(FALSE); m_t << "\\end{DoxyCode}\n"; @@ -461,8 +461,8 @@ void LatexDocVisitor::visit(DocInclude *inc) LatexCodeGenerator::setDoxyCodeOpen(TRUE); QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -482,8 +482,8 @@ void LatexDocVisitor::visit(DocInclude *inc) case DocInclude::Include: m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(),langExt,inc->isExample(), inc->exampleFile(), 0, // fileDef @@ -512,8 +512,8 @@ void LatexDocVisitor::visit(DocInclude *inc) { m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -530,8 +530,8 @@ void LatexDocVisitor::visit(DocInclude *inc) FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); m_t << "\n\\begin{DoxyCodeInclude}{" << usedTableLevels() << "}\n"; LatexCodeGenerator::setDoxyCodeOpen(TRUE); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -583,8 +583,8 @@ void LatexDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getParser(locLangExt) - ->parseCode(m_ci,op->context(),op->text(),langExt, + Doxygen::parserManager->getCodeParser(locLangExt) + .parseCode(m_ci,op->context(),op->text(),langExt, op->isExample(),op->exampleFile(), fd, // fileDef op->line(), // startLine diff --git a/src/mandocvisitor.cpp b/src/mandocvisitor.cpp index 21e7cb9..3db556d 100644 --- a/src/mandocvisitor.cpp +++ b/src/mandocvisitor.cpp @@ -204,8 +204,8 @@ void ManDocVisitor::visit(DocVerbatim *s) if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; - Doxygen::parserManager->getParser(lang) - ->parseCode(m_ci,s->context(),s->text(), + Doxygen::parserManager->getCodeParser(lang) + .parseCode(m_ci,s->context(),s->text(), langExt, s->isExample(),s->exampleFile()); if (!m_firstCol) m_t << endl; @@ -257,8 +257,8 @@ void ManDocVisitor::visit(DocInclude *inc) m_t << ".nf" << endl; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -281,8 +281,8 @@ void ManDocVisitor::visit(DocInclude *inc) if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -318,8 +318,8 @@ void ManDocVisitor::visit(DocInclude *inc) if (!m_firstCol) m_t << endl; m_t << ".PP" << endl; m_t << ".nf" << endl; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -338,8 +338,8 @@ void ManDocVisitor::visit(DocInclude *inc) m_t << ".nf" << endl; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -397,8 +397,8 @@ void ManDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getParser(locLangExt) - ->parseCode(m_ci,op->context(),op->text(),langExt, + Doxygen::parserManager->getCodeParser(locLangExt) + .parseCode(m_ci,op->context(),op->text(),langExt, op->isExample(),op->exampleFile(), fd, // fileDef op->line(), // startLine diff --git a/src/markdown.cpp b/src/markdown.cpp index e054941..42ea2ff 100644 --- a/src/markdown.cpp +++ b/src/markdown.cpp @@ -2576,13 +2576,13 @@ QCString markdownFileNameToId(const QCString &fileName) } -void MarkdownFileParser::parseInput(const char *fileName, +void MarkdownOutlineParser::parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { - std::unique_ptr<Entry> current = std::make_unique<Entry>(); + std::shared_ptr<Entry> current = std::make_shared<Entry>(); current->lang = SrcLangExt_Markdown; current->fileName = fileName; current->docFile = fileName; @@ -2660,47 +2660,14 @@ void MarkdownFileParser::parseInput(const char *fileName, g_indentLevel=0; } -void MarkdownFileParser::parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName, - FileDef *fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) +void MarkdownOutlineParser::parsePrototype(const char *text) { - ParserInterface *pIntf = Doxygen::parserManager->getParser("*.cpp"); - if (pIntf!=this) + OutlineParserInterface &intf = Doxygen::parserManager->getOutlineParser("*.cpp"); + if (&intf!=this) { - pIntf->parseCode( - codeOutIntf,scopeName,input,lang,isExampleBlock,exampleName, - fileDef,startLine,endLine,inlineFragment,memberDef,showLineNumbers, - searchCtx,collectXRefs); + intf.parsePrototype(text); } } -void MarkdownFileParser::resetCodeParserState() -{ - ParserInterface *pIntf = Doxygen::parserManager->getParser("*.cpp"); - if (pIntf!=this) - { - pIntf->resetCodeParserState(); - } -} - -void MarkdownFileParser::parsePrototype(const char *text) -{ - ParserInterface *pIntf = Doxygen::parserManager->getParser("*.cpp"); - if (pIntf!=this) - { - pIntf->parsePrototype(text); - } -} +//------------------------------------------------------------------------ diff --git a/src/markdown.h b/src/markdown.h index 2c9a496..3ffd155 100644 --- a/src/markdown.h +++ b/src/markdown.h @@ -25,38 +25,20 @@ class Entry; QCString processMarkdown(const QCString &fileName,const int lineNr,Entry *e,const QCString &s); QCString markdownFileNameToId(const QCString &fileName); -class MarkdownFileParser : public ParserInterface +class MarkdownOutlineParser : public OutlineParserInterface { public: - virtual ~MarkdownFileParser() {} + virtual ~MarkdownOutlineParser() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &) const { return FALSE; } - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ); - void resetCodeParserState(); void parsePrototype(const char *text); }; - - #endif diff --git a/src/memberdef.cpp b/src/memberdef.cpp index f3fd4b4..85d1cdf 100644 --- a/src/memberdef.cpp +++ b/src/memberdef.cpp @@ -3707,10 +3707,10 @@ void MemberDefImpl::writeDocumentation(const MemberList *ml, else ol.parseText(theTranslator->trInitialValue()); ol.endBold(); - ParserInterface *pIntf = Doxygen::parserManager->getParser(getDefFileExtension()); - pIntf->resetCodeParserState(); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(getDefFileExtension()); + intf.resetCodeParserState(); ol.startCodeFragment(); - pIntf->parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()), + intf.parseCode(ol,scopeName,m_impl->initializer,lang,FALSE,0,const_cast<FileDef*>(getFileDef()), -1,-1,TRUE,this,FALSE,this); ol.endCodeFragment(); } diff --git a/src/parserintf.h b/src/parserintf.h index c0939c9..5095a1e 100644 --- a/src/parserintf.h +++ b/src/parserintf.h @@ -18,10 +18,11 @@ #ifndef PARSERINTF_H #define PARSERINTF_H -#include <qdict.h> #include <qstrlist.h> #include <memory> +#include <map> +#include <string> #include "types.h" @@ -31,16 +32,16 @@ class CodeOutputInterface; class MemberDef; class Definition; -/** \brief Abstract interface for programming language parsers. +/** \brief Abstract interface for outline parsers. * * By implementing the methods of this interface one can add - * a new language parser to doxygen. The parser can make use of the + * a new language parser to doxygen. The parser implementation can make use of the * comment block parser to parse the contents of special comment blocks. */ -class ParserInterface +class OutlineParserInterface { public: - virtual ~ParserInterface() {} + virtual ~OutlineParserInterface() {} /** Starts processing a translation unit (source files + headers). * After this call parseInput() is called with sameTranslationUnit @@ -69,7 +70,7 @@ class ParserInterface */ virtual void parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit) = 0; @@ -80,6 +81,27 @@ class ParserInterface */ virtual bool needsPreprocessing(const QCString &extension) const = 0; + /** Callback function called by the comment block scanner. + * It provides a string \a text containing the prototype of a function + * or variable. The parser should parse this and store the information + * in the Entry node that corresponds with the node for which the + * comment block parser was invoked. + */ + virtual void parsePrototype(const char *text) = 0; + +}; + +/** \brief Abstract interface for code parsers. + * + * By implementing the methods of this interface one can add + * a new language parser to doxygen. This interface is used for + * syntax highlighting, but also to extract cross references and call graphs. + */ +class CodeParserInterface +{ + public: + virtual ~CodeParserInterface() {} + /** Parses a source file or fragment with the goal to produce * highlighted and cross-referenced output. * @param[in] codeOutIntf Abstract interface for writing the result. @@ -125,14 +147,6 @@ class ParserInterface */ virtual void resetCodeParserState() = 0; - /** Callback function called by the comment block scanner. - * It provides a string \a text containing the prototype of a function - * or variable. The parser should parse this and store the information - * in the Entry node that corresponds with the node for which the - * comment block parser was invoked. - */ - virtual void parsePrototype(const char *text) = 0; - }; //----------------------------------------------------------------------------- @@ -145,18 +159,22 @@ class ParserInterface class ParserManager { public: - /** Creates the parser manager object. - */ - ParserManager() - : m_defaultParser(0) { m_parsers.setAutoDelete(TRUE); } - ~ParserManager() + struct ParserPair { - delete m_defaultParser; - } + ParserPair(std::unique_ptr<OutlineParserInterface> oli, + std::unique_ptr<CodeParserInterface> cpi) + : outlineParser(std::move(oli)), codeParser(std::move(cpi)) + { + } - void registerDefaultParser(ParserInterface *parser) + std::unique_ptr<OutlineParserInterface> outlineParser; + std::unique_ptr<CodeParserInterface> codeParser; + }; + + ParserManager(std::unique_ptr<OutlineParserInterface> outlineParser, + std::unique_ptr<CodeParserInterface> codeParser) + : m_defaultParsers(std::move(outlineParser),std::move(codeParser)) { - m_defaultParser = parser; } /** Registers an additional parser. @@ -165,9 +183,11 @@ class ParserManager * @param[in] parser The parser that is to be used for the * given name. */ - void registerParser(const char *name,ParserInterface *parser) + void registerParser(const char *name,std::unique_ptr<OutlineParserInterface> outlineParser, + std::unique_ptr<CodeParserInterface> codeParser) { - m_parsers.insert(name,parser); + m_parsers.emplace(std::string(name), + ParserPair(std::move(outlineParser),std::move(codeParser))); } /** Registers a file \a extension with a parser with name \a parserName. @@ -176,13 +196,16 @@ class ParserManager bool registerExtension(const char *extension, const char *parserName) { if (parserName==0 || extension==0) return FALSE; - ParserInterface *intf = m_parsers.find(parserName); - if (intf==0) return FALSE; - if (m_extensions.find(extension)!=0) // extension already exists + + const auto &parserIt = m_parsers.find(parserName); + if (parserIt == m_parsers.end()) return FALSE; + + auto extensionIt = m_extensions.find(extension); + if (extensionIt != m_extensions.end()) // extension already exists { - m_extensions.remove(extension); // remove it + m_extensions.erase(extensionIt); // remove it (e.g. user specified extension overrules built in one) } - m_extensions.insert(extension,intf); // add new mapping + m_extensions.emplace(std::string(extension),parserIt->second); // add new mapping return TRUE; } @@ -190,22 +213,36 @@ class ParserManager * If there is no parser explicitly registered for the supplied extension, * the interface to the default parser will be returned. */ - ParserInterface *getParser(const char *extension) + OutlineParserInterface &getOutlineParser(const char *extension) { - QCString ext = QCString(extension).lower(); + return *getParsers(extension).outlineParser; + } + + /** Gets the interface to the parser associated with given \a extension. + * If there is no parser explicitly registered for the supplied extension, + * the interface to the default parser will be returned. + */ + CodeParserInterface &getCodeParser(const char *extension) + { + return *getParsers(extension).codeParser; + } + + private: + ParserPair &getParsers(const char *extension) + { + QCString ext = QCString(extension).lower().data(); if (ext.isEmpty()) ext=".no_extension"; - ParserInterface *intf = m_extensions.find(ext); - if (intf==0 && ext.length()>4) + auto it = m_extensions.find(ext.data()); + if (it==m_extensions.end() && ext.length()>4) { - intf = m_extensions.find(ext.left(4)); + it = m_extensions.find(ext.left(4).data()); } - return intf ? intf : m_defaultParser; + return it!=m_extensions.end() ? it->second : m_defaultParsers; } - private: - QDict<ParserInterface> m_parsers; - QDict<ParserInterface> m_extensions; - ParserInterface *m_defaultParser; + std::map<std::string,ParserPair> m_parsers; + std::map<std::string,ParserPair &> m_extensions; + ParserPair m_defaultParsers; }; #endif diff --git a/src/pycode.h b/src/pycode.h index de0a8a9..e3a01b4 100644 --- a/src/pycode.h +++ b/src/pycode.h @@ -25,7 +25,7 @@ #ifndef PYCODE_H #define PYCODE_H -#include "types.h" +#include "parserintf.h" class CodeOutputInterface; class FileDef; @@ -33,11 +33,26 @@ class MemberDef; class QCString; class Definition; -extern void parsePythonCode(CodeOutputInterface &,const char *,const QCString &, - bool ,const char *,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, - bool collectXRefs); -extern void resetPythonCodeParserState(); +class PythonCodeParser : public CodeParserInterface +{ + public: + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt lang, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + const MemberDef *memberDef=0, + bool showLineNumbers=TRUE, + const Definition *searchCtx=0, + bool collectXrefs=TRUE + ); + void resetCodeParserState(); +}; + #endif diff --git a/src/pycode.l b/src/pycode.l index 4e53a27..f7e255f 100644 --- a/src/pycode.l +++ b/src/pycode.l @@ -1638,4 +1638,33 @@ void parsePythonCode(CodeOutputInterface &od,const char * /*className*/, return; } +//---------------------------------------------------------------------------- + +void PythonCodeParser::parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt /*lang*/, + bool isExampleBlock, + const char *exampleName, + FileDef *fileDef, + int startLine, + int endLine, + bool inlineFragment, + const MemberDef *memberDef, + bool showLineNumbers, + const Definition *searchCtx, + bool collectXRefs + ) +{ + ::parsePythonCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, + fileDef,startLine,endLine,inlineFragment,memberDef, + showLineNumbers,searchCtx,collectXRefs); +} + +void PythonCodeParser::resetCodeParserState() +{ + ::resetPythonCodeParserState(); +} + + #include "pycode.l.h" diff --git a/src/pyscanner.h b/src/pyscanner.h index 2faffdc..6cfadf6 100644 --- a/src/pyscanner.h +++ b/src/pyscanner.h @@ -31,34 +31,17 @@ * * This is the Python language parser for doxygen. */ -class PythonLanguageScanner : public ParserInterface +class PythonOutlineParser : public OutlineParserInterface { public: - virtual ~PythonLanguageScanner() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char * fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension) const; - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXrefs=TRUE - ); - void resetCodeParserState(); void parsePrototype(const char *text); }; diff --git a/src/pyscanner.l b/src/pyscanner.l index 5d6b303..efdc943 100644 --- a/src/pyscanner.l +++ b/src/pyscanner.l @@ -65,17 +65,17 @@ */ -static ParserInterface *g_thisParser; +static OutlineParserInterface *g_thisParser; static const char * inputString; static int inputPosition; static QFile inputFile; static Protection protection; -static Entry* current_root = 0 ; -static std::unique_ptr<Entry> current; -static Entry* previous = 0 ; -static Entry* bodyEntry = 0 ; +static std::shared_ptr<Entry> current_root; +static std::shared_ptr<Entry> current; +static std::shared_ptr<Entry> previous; +static std::shared_ptr<Entry> bodyEntry; static int yyLineNr = 1 ; static QCString yyFileName; static MethodTypes mtype; @@ -151,7 +151,7 @@ static void initEntry() static void newEntry() { - previous = current.get(); + previous = current; current_root->moveToSubEntryAndRefresh(current); initEntry(); } @@ -292,7 +292,7 @@ static void handleCommentBlock(const QCString &doc,bool brief) QCString processedDoc = preprocessCommentBlock(doc,yyFileName,lineNr); while (parseCommentBlock( g_thisParser, - (docBlockInBody && previous) ? previous : current.get(), + (docBlockInBody && previous) ? previous.get() : current.get(), processedDoc, // text yyFileName, // file lineNr, @@ -913,7 +913,7 @@ STARTDOCSYMS "##" } {B}":"{B} { // function without arguments g_specialBlock = TRUE; // expecting a docstring - bodyEntry = current.get(); + bodyEntry = current; BEGIN(FunctionBody); } @@ -1300,7 +1300,7 @@ STARTDOCSYMS "##" current->program+=yytext; //current->startLine = yyLineNr; g_curIndent=computeIndent(yytext); - bodyEntry = current.get(); + bodyEntry = current; DBG_CTX((stderr,"setting indent %d\n",g_curIndent)); //printf("current->program=[%s]\n",current->program.data()); //g_hideClassDocs = TRUE; @@ -1706,12 +1706,12 @@ STARTDOCSYMS "##" //---------------------------------------------------------------------------- -static void parseCompounds(Entry *rt) +static void parseCompounds(std::shared_ptr<Entry> rt) { //printf("parseCompounds(%s)\n",rt->name.data()); for (int i=0; i<rt->children().size(); ++i) { - Entry *ce = rt->children()[i].get(); + std::shared_ptr<Entry> ce = rt->children()[i]; if (!ce->program.isEmpty()) { //printf("-- %s ---------\n%s\n---------------\n", @@ -1727,14 +1727,14 @@ static void parseCompounds(Entry *rt) } else if (ce->parent()) { - current_root = ce->parent(); + current_root = rt; //printf("Searching for member variables in %s parent=%s\n", // ce->name.data(),ce->parent->name.data()); BEGIN( SearchMemVars ); } yyFileName = ce->fileName; yyLineNr = ce->bodyLine ; - current = std::make_unique<Entry>(); + current = std::make_shared<Entry>(); initEntry(); QCString name = ce->name; @@ -1754,7 +1754,7 @@ static void parseCompounds(Entry *rt) //---------------------------------------------------------------------------- -static void parseMain(const char *fileName,const char *fileBuf,const std::unique_ptr<Entry> &rt) +static void parseMain(const char *fileName,const char *fileBuf,const std::shared_ptr<Entry> &rt) { initParser(); @@ -1765,7 +1765,7 @@ static void parseMain(const char *fileName,const char *fileBuf,const std::unique mtype = Method; gstat = FALSE; virt = Normal; - current_root = rt.get(); + current_root = rt; g_specialBlock = FALSE; @@ -1789,7 +1789,7 @@ static void parseMain(const char *fileName,const char *fileBuf,const std::unique g_moduleScope+=baseName; } - current = std::make_unique<Entry>(); + current = std::make_shared<Entry>(); initEntry(); current->name = g_moduleScope; current->section = Entry::NAMESPACE_SEC; @@ -1798,7 +1798,7 @@ static void parseMain(const char *fileName,const char *fileBuf,const std::unique current->startLine = yyLineNr; current->bodyLine = yyLineNr; - current_root = current.get(); + current_root = current; rt->moveToSubEntryAndRefresh(current); @@ -1886,9 +1886,9 @@ void pyscanFreeScanner() //---------------------------------------------------------------------------- -void PythonLanguageScanner::parseInput(const char *fileName, +void PythonOutlineParser::parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { @@ -1901,43 +1901,17 @@ void PythonLanguageScanner::parseInput(const char *fileName, // printAST(global_root); } -bool PythonLanguageScanner::needsPreprocessing(const QCString &) const +bool PythonOutlineParser::needsPreprocessing(const QCString &) const { return FALSE; } -void PythonLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt /*lang*/, - bool isExampleBlock, - const char *exampleName, - FileDef *fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) -{ - ::parsePythonCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, - fileDef,startLine,endLine,inlineFragment,memberDef, - showLineNumbers,searchCtx,collectXRefs); -} - -void PythonLanguageScanner::parsePrototype(const char *text) +void PythonOutlineParser::parsePrototype(const char *text) { ::parsePrototype(text); } -void PythonLanguageScanner::resetCodeParserState() -{ - ::resetPythonCodeParserState(); -} - //---------------------------------------------------------------------------- #include "pyscanner.l.h" diff --git a/src/rtfdocvisitor.cpp b/src/rtfdocvisitor.cpp index 43ac362..5a8e49d 100644 --- a/src/rtfdocvisitor.cpp +++ b/src/rtfdocvisitor.cpp @@ -305,8 +305,8 @@ void RTFDocVisitor::visit(DocVerbatim *s) m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getParser(lang) - ->parseCode(m_ci,s->context(),s->text(),langExt, + Doxygen::parserManager->getCodeParser(lang) + .parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); //m_t << "\\par" << endl; m_t << "}" << endl; @@ -432,8 +432,8 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << rtf_Style_Reset << getStyle("CodeExample"); QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -454,8 +454,8 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{" << endl; m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(),langExt,inc->isExample(), inc->exampleFile(), 0, // fileDef @@ -485,8 +485,8 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{" << endl; if (!m_lastIsPara) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -502,8 +502,8 @@ void RTFDocVisitor::visit(DocInclude *inc) m_t << "{" << endl; if (!m_lastIsPara) m_t << "\\par" << endl; m_t << rtf_Style_Reset << getStyle("CodeExample"); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -560,8 +560,8 @@ void RTFDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getParser(locLangExt) - ->parseCode(m_ci,op->context(),op->text(),langExt, + Doxygen::parserManager->getCodeParser(locLangExt) + .parseCode(m_ci,op->context(),op->text(),langExt, op->isExample(),op->exampleFile(), fd, // fileDef op->line(), // startLine diff --git a/src/scanner.h b/src/scanner.h index fd40485..70df660 100644 --- a/src/scanner.h +++ b/src/scanner.h @@ -26,39 +26,24 @@ * supports C++ and various languages that are closely related to C++, * such as C, C#, Objective-C, Java, PHP, and IDL. */ -class CLanguageScanner : public ParserInterface +class COutlineParser : public OutlineParserInterface { public: - CLanguageScanner(); - virtual ~CLanguageScanner(); + COutlineParser(); + virtual ~COutlineParser(); void startTranslationUnit(const char *fileName); void finishTranslationUnit(); void parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension) const; - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ); - void resetCodeParserState(); void parsePrototype(const char *text); private: struct Private; - Private *p; + std::unique_ptr<Private> p; }; + #endif diff --git a/src/scanner.l b/src/scanner.l index 6c02153..0e3aeb0 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -58,7 +58,7 @@ struct scannerYY_state { - ParserInterface *thisParser; + OutlineParserInterface *thisParser; const char * inputString = 0; int inputPosition = 0; int lastContext = 0; @@ -90,12 +90,12 @@ struct scannerYY_state int curlyCount = 0 ; int squareCount = 0 ; int padCount = 0 ; - std::unique_ptr<Entry> current; - Entry* current_root = 0 ; - Entry* previous = 0 ; - std::unique_ptr<Entry> tempEntry; - Entry* firstTypedefEntry = 0 ; - Entry* memspecEntry = 0 ; + std::shared_ptr<Entry> current; + std::shared_ptr<Entry> current_root; + std::shared_ptr<Entry> previous; + std::shared_ptr<Entry> tempEntry; + std::shared_ptr<Entry> firstTypedefEntry; + std::shared_ptr<Entry> memspecEntry; int yyLineNr = 1 ; int yyBegLineNr = 1 ; int yyColNr = 1 ; @@ -188,8 +188,7 @@ struct scannerYY_state int fencedSize = 0; bool nestedComment = false; - std::vector< std::pair<Entry*,std::unique_ptr<Entry> > > outerScopeEntries; - CodeScanner codeScanner; + std::vector< std::pair<Entry*,std::shared_ptr<Entry> > > outerScopeEntries; }; static const char *stateToString(int state); @@ -1002,7 +1001,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) lineCount(yyscanner); } <PackageName>";" { - Entry *tmp = yyextra->current.get(); + std::shared_ptr<Entry> tmp = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); yyextra->current_root = tmp; initEntry(yyscanner); @@ -1685,7 +1684,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //printf("import name = %s -> %s\n",yytext,yyextra->current->name.data()); yyextra->current->section=Entry::USINGDECL_SEC; } - yyextra->previous = yyextra->current.get(); + yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); BEGIN(Using); @@ -1703,7 +1702,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->fileName = yyextra->yyFileName; yyextra->current->section=Entry::USINGDECL_SEC; yyextra->current->startLine = yyextra->yyLineNr; - yyextra->previous = yyextra->current.get(); + yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); if (yyextra->insideCS) /* Hack: in C# a using declaration and @@ -2483,7 +2482,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) if (yyextra->previous && yyextra->previous->section==Entry::GROUPDOC_SEC) { // link open command to the group defined in the yyextra->previous entry - Doxygen::docGroup.open(yyextra->previous,yyextra->yyFileName,yyextra->yyLineNr); + Doxygen::docGroup.open(yyextra->previous.get(),yyextra->yyFileName,yyextra->yyLineNr); } else { @@ -3491,7 +3490,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // add to the scope surrounding the enum (copy!) // we cannot during it directly as that would invalidate the iterator in parseCompounds. //printf("*** adding outer scope entry for %s\n",yyextra->current->name.data()); - yyextra->outerScopeEntries.emplace_back(yyextra->current_root->parent(), std::make_unique<Entry>(*yyextra->current)); + yyextra->outerScopeEntries.emplace_back(yyextra->current_root->parent(), std::make_shared<Entry>(*yyextra->current)); } yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); @@ -3588,7 +3587,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) else { yyextra->current->endBodyLine = yyextra->yyLineNr; - Entry * original_root = yyextra->current_root; // save root this namespace is in + std::shared_ptr<Entry> original_root = yyextra->current_root; // save root this namespace is in if (yyextra->current->section == Entry::NAMESPACE_SEC && yyextra->current->type == "namespace") { int split_point; @@ -3608,16 +3607,17 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->briefFile = ""; while ((split_point = yyextra->current->name.find("::")) != -1) { - std::unique_ptr<Entry> new_current = std::make_unique<Entry>(*yyextra->current); + std::shared_ptr<Entry> new_current = std::make_shared<Entry>(*yyextra->current); yyextra->current->program = ""; new_current->name = yyextra->current->name.mid(split_point + 2); yyextra->current->name = yyextra->current->name.left(split_point); if (!yyextra->current_root->name.isEmpty()) yyextra->current->name.prepend(yyextra->current_root->name+"::"); - Entry *tmp = yyextra->current.get(); + std::shared_ptr<Entry> tmp = yyextra->current; yyextra->current_root->moveToSubEntryAndKeep(yyextra->current); yyextra->current_root = tmp; - yyextra->current.swap(new_current); + + yyextra->current = new_current; } // restore documentation values yyextra->current->doc = doc; @@ -3659,7 +3659,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else { - yyextra->memspecEntry = yyextra->current.get(); + yyextra->memspecEntry = yyextra->current; yyextra->current_root->copyToSubEntry( yyextra->current ) ; if (yyextra->current->section==Entry::NAMESPACE_SEC || (yyextra->current->spec==Entry::Interface) || @@ -3670,7 +3670,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->current->reset(); yyextra->current_root = original_root; // restore scope from before namespace descent initEntry(yyscanner); - yyextra->memspecEntry = 0; + yyextra->memspecEntry.reset(); BEGIN( FindMembers ) ; } else @@ -3725,7 +3725,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //printf("Adding compound %s %s %s\n",yyextra->current->type.data(),yyextra->current->name.data(),yyextra->current->args.data()); if (!yyextra->firstTypedefEntry) { - yyextra->firstTypedefEntry = yyextra->current.get(); + yyextra->firstTypedefEntry = yyextra->current; } yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ; initEntry(yyscanner); @@ -3741,7 +3741,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // add compound definition to the tree yyextra->current->args = yyextra->current->args.simplifyWhiteSpace(); yyextra->current->type = yyextra->current->type.simplifyWhiteSpace(); - yyextra->memspecEntry = yyextra->current.get(); + yyextra->memspecEntry = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh( yyextra->current ) ; initEntry(yyscanner); unput(';'); @@ -3795,7 +3795,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) // anonymous compound. If so we insert a // special 'anonymous' variable. //Entry *p=yyextra->current_root; - const Entry *p=yyextra->current.get(); + const Entry *p=yyextra->current.get(); while (p) { // only look for class scopes, not namespace scopes @@ -3813,7 +3813,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } } //p=p->parent; - if (p==yyextra->current.get()) p=yyextra->current_root; else p=p->parent(); + if (p==yyextra->current.get()) p=yyextra->current_root.get(); else p=p->parent(); } } //printf("yyextra->msName=%s yyextra->current->name=%s\n",yyextra->msName.data(),yyextra->current->name.data()); @@ -3834,7 +3834,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) } else // case 2: create a typedef field { - std::unique_ptr<Entry> varEntry=std::make_unique<Entry>(); + std::shared_ptr<Entry> varEntry=std::make_shared<Entry>(); varEntry->lang = yyextra->language; varEntry->protection = yyextra->current->protection ; varEntry->mtype = yyextra->current->mtype; @@ -3894,8 +3894,8 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) yyextra->msName.resize(0); yyextra->msArgs.resize(0); yyextra->isTypedef=FALSE; - yyextra->firstTypedefEntry=0; - yyextra->memspecEntry=0; + yyextra->firstTypedefEntry.reset(); + yyextra->memspecEntry.reset(); yyextra->current->reset(); initEntry(yyscanner); BEGIN( FindMembers ); @@ -4826,7 +4826,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { findAndRemoveWord(yyextra->current->type,"function"); } - yyextra->previous = yyextra->current.get(); + yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); initEntry(yyscanner); // Objective C 2.0: Required/Optional section @@ -4920,9 +4920,9 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) { yyextra->current->endBodyLine=yyextra->yyLineNr; // take yyextra->previous out of yyextra->current_root and move it into yyextra->current - yyextra->current.swap(yyextra->tempEntry); // remember yyextra->current - yyextra->current_root->moveFromSubEntry(yyextra->previous,yyextra->current); - yyextra->previous = 0; + yyextra->tempEntry = yyextra->current; // remember yyextra->current + yyextra->current_root->moveFromSubEntry(yyextra->previous.get(),yyextra->current); + yyextra->previous.reset(); yyextra->docBlockContext = SkipCurlyEndDoc; yyextra->docBlockInBody = FALSE; @@ -4964,7 +4964,7 @@ OPERATOR "operator"{B}*({ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}) //addToBody("}"); if (yyextra->tempEntry) // we can only switch back to yyextra->current if no new item was created { - yyextra->tempEntry.swap(yyextra->current); + yyextra->current = yyextra->tempEntry; yyextra->tempEntry.reset(); } BEGIN( yyextra->lastCurlyContext ); @@ -6616,8 +6616,8 @@ static void initParser(yyscan_t yyscanner) yyextra->insideCode=FALSE; yyextra->insideCli=Config_getBool(CPP_CLI_SUPPORT); yyextra->previous = 0; - yyextra->firstTypedefEntry = 0; - yyextra->memspecEntry =0; + yyextra->firstTypedefEntry.reset(); + yyextra->memspecEntry.reset(); } static void initEntry(yyscan_t yyscanner) @@ -6929,13 +6929,13 @@ static void newEntry(yyscan_t yyscanner) // already added to yyextra->current_root, so we should not add it again // (see bug723314) { - yyextra->previous = yyextra->current.get(); + yyextra->previous = yyextra->current; yyextra->current_root->moveToSubEntryAndRefresh(yyextra->current); } else { - yyextra->previous = yyextra->current.get(); - yyextra->tempEntry.swap(yyextra->current); + yyextra->previous = yyextra->current; + yyextra->current = yyextra->tempEntry; yyextra->tempEntry.reset(); } initEntry(yyscanner); @@ -6950,7 +6950,7 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief int lineNr = brief ? yyextra->current->briefLine : yyextra->current->docLine; // line of block start // fill in inbodyFile && inbodyLine the first time, see bug 633891 - Entry *docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current.get(); + std::shared_ptr<Entry> docEntry = yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current; if (yyextra->docBlockInBody && docEntry && docEntry->inbodyLine==-1) { docEntry->inbodyFile = yyextra->yyFileName; @@ -6962,7 +6962,7 @@ static void handleCommentBlock(yyscan_t yyscanner,const QCString &doc,bool brief QCString processedDoc = preprocessCommentBlock(stripIndentation(doc),yyextra->yyFileName,lineNr); while (parseCommentBlock( yyextra->thisParser, - yyextra->docBlockInBody && yyextra->previous ? yyextra->previous : yyextra->current.get(), + yyextra->docBlockInBody && yyextra->previous ? yyextra->previous.get() : yyextra->current.get(), processedDoc, // text yyextra->yyFileName, // file lineNr, // line of block start @@ -7055,7 +7055,7 @@ static void handleParametersCommentBlocks(yyscan_t yyscanner,ArgumentList &al) //---------------------------------------------------------------------------- -static void parseCompounds(yyscan_t yyscanner,const std::unique_ptr<Entry> &rt) +static void parseCompounds(yyscan_t yyscanner,const std::shared_ptr<Entry> &rt) { struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; //printf("parseCompounds(%s)\n",rt->name.data()); @@ -7075,14 +7075,14 @@ static void parseCompounds(yyscan_t yyscanner,const std::unique_ptr<Entry> &rt) BEGIN( FindFields ) ; else BEGIN( FindMembers ) ; - yyextra->current_root = ce.get() ; + yyextra->current_root = ce; yyextra->yyFileName = ce->fileName; //setContext(); yyextra->yyLineNr = ce->startLine ; yyextra->yyColNr = ce->startColumn ; yyextra->insideObjC = ce->lang==SrcLangExt_ObjC; //printf("---> Inner block starts at line %d objC=%d\n",yyextra->yyLineNr,yyextra->insideObjC); - yyextra->current = std::make_unique<Entry>(); + yyextra->current = std::make_shared<Entry>(); yyextra->stat = FALSE; initEntry(yyscanner); @@ -7170,7 +7170,7 @@ static void parseCompounds(yyscan_t yyscanner,const std::unique_ptr<Entry> &rt) static void parseMain(yyscan_t yyscanner, const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &rt, + const std::shared_ptr<Entry> &rt, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { @@ -7188,7 +7188,7 @@ static void parseMain(yyscan_t yyscanner, yyextra->mtype = Method; yyextra->stat = FALSE; yyextra->virt = Normal; - yyextra->current_root = rt.get(); + yyextra->current_root = rt; yyextra->yyLineNr= 1 ; yyextra->yyFileName = fileName; setContext(yyscanner); @@ -7207,10 +7207,10 @@ static void parseMain(yyscan_t yyscanner, rt->lang = yyextra->language; msg("Parsing file %s...\n",yyextra->yyFileName.data()); - yyextra->current_root = rt.get() ; + yyextra->current_root = rt; initParser(yyscanner); Doxygen::docGroup.enterFile(yyextra->yyFileName,yyextra->yyLineNr); - yyextra->current = std::make_unique<Entry>(); + yyextra->current = std::make_shared<Entry>(); //printf("yyextra->current=%p yyextra->current_root=%p\n",yyextra->current,yyextra->current_root); int sec=guessSection(yyextra->yyFileName); if (sec) @@ -7321,29 +7321,30 @@ static void parsePrototype(yyscan_t yyscanner,const QCString &text) //---------------------------------------------------------------------------- -struct CLanguageScanner::Private +struct COutlineParser::Private { yyscan_t yyscanner; scannerYY_state state; }; -CLanguageScanner::CLanguageScanner() +COutlineParser::COutlineParser() : p(std::make_unique<COutlineParser::Private>()) { - p = new Private; scannerYYlex_init_extra(&p->state,&p->yyscanner); +#ifdef FLEX_DEBUG + scannerYYset_debug(1,p->yyscanner); +#endif } -CLanguageScanner::~CLanguageScanner() +COutlineParser::~COutlineParser() { scannerYYlex_destroy(p->yyscanner); - delete p; } -void CLanguageScanner::startTranslationUnit(const char *) +void COutlineParser::startTranslationUnit(const char *) { } -void CLanguageScanner::finishTranslationUnit() +void COutlineParser::finishTranslationUnit() { struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; bool processWithClang = yyextra->insideCpp || yyextra->insideObjC; @@ -7353,9 +7354,9 @@ void CLanguageScanner::finishTranslationUnit() } } -void CLanguageScanner::parseInput(const char *fileName, +void COutlineParser::parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList & filesInSameTranslationUnit) { @@ -7371,29 +7372,7 @@ void CLanguageScanner::parseInput(const char *fileName, } -void CLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, - const char * scopeName, - const QCString & input, - SrcLangExt lang, - bool isExampleBlock, - const char * exampleName, - FileDef * fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) -{ - struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; - yyextra->codeScanner.parseCCode(codeOutIntf,scopeName,input,lang,isExampleBlock,exampleName, - fileDef,startLine,endLine,inlineFragment,memberDef, - showLineNumbers,searchCtx,collectXRefs); -} - -bool CLanguageScanner::needsPreprocessing(const QCString &extension) const +bool COutlineParser::needsPreprocessing(const QCString &extension) const { QCString fe=extension.lower(); SrcLangExt lang = getLanguageFromFileName(extension); @@ -7403,13 +7382,7 @@ bool CLanguageScanner::needsPreprocessing(const QCString &extension) const ); } -void CLanguageScanner::resetCodeParserState() -{ - struct yyguts_t *yyg = (struct yyguts_t*)p->yyscanner; - yyextra->codeScanner.reset(); -} - -void CLanguageScanner::parsePrototype(const char *text) +void COutlineParser::parsePrototype(const char *text) { ::parsePrototype(p->yyscanner,text); } diff --git a/src/sqlcode.h b/src/sqlcode.h index d8a09b7..20e20f7 100644 --- a/src/sqlcode.h +++ b/src/sqlcode.h @@ -19,7 +19,7 @@ #ifndef SQLCODE_H #define SQLCODE_H -#include "types.h" +#include "parserintf.h" class CodeOutputInterface; class FileDef; @@ -27,11 +27,28 @@ class MemberDef; class QCString; class Definition; -extern void parseSqlCode(CodeOutputInterface &,const char *,const QCString &, - bool ,const char *,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, - bool collectXRefs); -extern void resetSqlCodeParserState(); +/** SQL scanner. Only support syntax highlighting of code at the moment. + */ +class SQLCodeParser : public CodeParserInterface +{ + public: + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + const MemberDef *memberDef=0, + bool showLineNumbers=TRUE, + const Definition *searchCtx=0, + bool collectXRefs=TRUE + ); + void resetCodeParserState(); +}; + #endif diff --git a/src/sqlcode.l b/src/sqlcode.l index a9e88a7..02c2c14 100644 --- a/src/sqlcode.l +++ b/src/sqlcode.l @@ -383,7 +383,7 @@ void parseSqlCode( struct yyguts_t *yyg = (struct yyguts_t*)yyscanner; #ifdef FLEX_DEBUG - yyset_debug(1,yyscanner); + sqlcodeYYset_debug(1,yyscanner); #endif printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL); @@ -454,4 +454,34 @@ void resetSqlCodeParserState() yyextra->currentMemberDef = 0; } +//--------------------------------------------------------------------------------- + +void SQLCodeParser::parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt, + bool isExampleBlock, + const char *exampleName, + FileDef *fileDef, + int startLine, + int endLine, + bool inlineFragment, + const MemberDef *memberDef, + bool showLineNumbers, + const Definition *searchCtx, + bool collectXRefs + ) +{ + parseSqlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, + fileDef,startLine,endLine,inlineFragment,memberDef, + showLineNumbers,searchCtx,collectXRefs); +} + +void SQLCodeParser::resetCodeParserState() +{ + resetSqlCodeParserState(); +} + +//--------------------------------------------------------------------------------- + #include "sqlcode.l.h" diff --git a/src/sqlscanner.h b/src/sqlscanner.h deleted file mode 100644 index 694bf80..0000000 --- a/src/sqlscanner.h +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#ifndef SQLSCANNER_H -#define SQLSCANNER_H - -#include "parserintf.h" -#include "sqlcode.h" - -/** SQL scanner. Only support syntax highlighting of code at the moment. - */ -class SQLScanner : public ParserInterface -{ -public: - SQLScanner() {} - virtual ~SQLScanner() {} - void startTranslationUnit(const char *) {} - void finishTranslationUnit() {} - void parseInput(const char *, const char *, const std::unique_ptr<Entry> &, bool , QStrList &) {} - bool needsPreprocessing(const QCString &) const { return FALSE; } - - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ) - { - parseSqlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, - fileDef,startLine,endLine,inlineFragment,memberDef, - showLineNumbers,searchCtx,collectXRefs); - } - - void resetCodeParserState() - { - resetSqlCodeParserState(); - } - - void parsePrototype(const char *) {} - -private: -}; - -#endif diff --git a/src/tagreader.cpp b/src/tagreader.cpp index 65336e3..8f85e9d 100644 --- a/src/tagreader.cpp +++ b/src/tagreader.cpp @@ -909,12 +909,12 @@ class TagFileParser : public QXmlDefaultHandler } void dump(); - void buildLists(const std::unique_ptr<Entry> &root); + void buildLists(const std::shared_ptr<Entry> &root); void addIncludes(); private: - void buildMemberList(const std::unique_ptr<Entry> &ce,QList<TagMemberInfo> &members); - void addDocAnchors(const std::unique_ptr<Entry> &e,const TagAnchorInfoList &l); + void buildMemberList(const std::shared_ptr<Entry> &ce,QList<TagMemberInfo> &members); + void addDocAnchors(const std::shared_ptr<Entry> &e,const TagAnchorInfoList &l); QList<TagClassInfo> m_tagFileClasses; QList<TagFileInfo> m_tagFileFiles; QList<TagNamespaceInfo> m_tagFileNamespaces; @@ -1139,7 +1139,7 @@ void TagFileParser::dump() } } -void TagFileParser::addDocAnchors(const std::unique_ptr<Entry> &e,const TagAnchorInfoList &l) +void TagFileParser::addDocAnchors(const std::shared_ptr<Entry> &e,const TagAnchorInfoList &l) { QListIterator<TagAnchorInfo> tli(l); TagAnchorInfo *ta; @@ -1161,13 +1161,13 @@ void TagFileParser::addDocAnchors(const std::unique_ptr<Entry> &e,const TagAncho } } -void TagFileParser::buildMemberList(const std::unique_ptr<Entry> &ce,QList<TagMemberInfo> &members) +void TagFileParser::buildMemberList(const std::shared_ptr<Entry> &ce,QList<TagMemberInfo> &members) { QListIterator<TagMemberInfo> mii(members); TagMemberInfo *tmi; for (;(tmi=mii.current());++mii) { - std::unique_ptr<Entry> me = std::make_unique<Entry>(); + std::shared_ptr<Entry> me = std::make_shared<Entry>(); me->type = tmi->type; me->name = tmi->name; me->args = tmi->arglist; @@ -1182,7 +1182,7 @@ void TagFileParser::buildMemberList(const std::unique_ptr<Entry> &ce,QList<TagMe TagEnumValueInfo *evi; for (evii.toFirst();(evi=evii.current());++evii) { - std::unique_ptr<Entry> ev = std::make_unique<Entry>(); + std::shared_ptr<Entry> ev = std::make_shared<Entry>(); ev->type = "@"; ev->name = evi->name; ev->id = evi->clangid; @@ -1296,14 +1296,14 @@ static QCString stripPath(const QCString &s) * This tree contains the information extracted from the input in a * "unrelated" form. */ -void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) +void TagFileParser::buildLists(const std::shared_ptr<Entry> &root) { // build class list QListIterator<TagClassInfo> cit(m_tagFileClasses); TagClassInfo *tci; for (cit.toFirst();(tci=cit.current());++cit) { - std::unique_ptr<Entry> ce = std::make_unique<Entry>(); + std::shared_ptr<Entry> ce = std::make_shared<Entry>(); ce->section = Entry::CLASS_SEC; switch (tci->kind) { @@ -1360,7 +1360,7 @@ void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) TagFileInfo *tfi; for (fit.toFirst();(tfi=fit.current());++fit) { - std::unique_ptr<Entry> fe = std::make_unique<Entry>(); + std::shared_ptr<Entry> fe = std::make_shared<Entry>(); fe->section = guessSection(tfi->name); fe->name = tfi->name; addDocAnchors(fe,tfi->docAnchors); @@ -1396,7 +1396,7 @@ void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) TagNamespaceInfo *tni; for (nit.toFirst();(tni=nit.current());++nit) { - std::unique_ptr<Entry> ne = std::make_unique<Entry>(); + std::shared_ptr<Entry> ne = std::make_shared<Entry>(); ne->section = Entry::NAMESPACE_SEC; ne->name = tni->name; addDocAnchors(ne,tni->docAnchors); @@ -1414,7 +1414,7 @@ void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) TagPackageInfo *tpgi; for (pit.toFirst();(tpgi=pit.current());++pit) { - std::unique_ptr<Entry> pe = std::make_unique<Entry>(); + std::shared_ptr<Entry> pe = std::make_shared<Entry>(); pe->section = Entry::PACKAGE_SEC; pe->name = tpgi->name; addDocAnchors(pe,tpgi->docAnchors); @@ -1431,7 +1431,7 @@ void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) TagGroupInfo *tgi; for (git.toFirst();(tgi=git.current());++git) { - std::unique_ptr<Entry> ge = std::make_unique<Entry>(); + std::shared_ptr<Entry> ge = std::make_shared<Entry>(); ge->section = Entry::GROUPDOC_SEC; ge->name = tgi->name; ge->type = tgi->title; @@ -1455,7 +1455,7 @@ void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) //for (eli.toFirst();(childNode=eli.current());++eli) const auto &children = root->children(); auto i = std::find_if(children.begin(),children.end(), - [&](const std::unique_ptr<Entry> &e) { return e->name = *it; }); + [&](const std::shared_ptr<Entry> &e) { return e->name = *it; }); if (i!=children.end()) { (*i)->groups.push_back(Grouping(tgi->name,Grouping::GROUPING_INGROUP)); @@ -1468,7 +1468,7 @@ void TagFileParser::buildLists(const std::unique_ptr<Entry> &root) TagPageInfo *tpi; for (pgit.toFirst();(tpi=pgit.current());++pgit) { - std::unique_ptr<Entry> pe = std::make_unique<Entry>(); + std::shared_ptr<Entry> pe = std::make_shared<Entry>(); pe->section = tpi->filename=="index" ? Entry::MAINPAGEDOC_SEC : Entry::PAGEDOC_SEC; pe->name = tpi->name; pe->args = tpi->title; @@ -1527,7 +1527,7 @@ void TagFileParser::addIncludes() } } -void parseTagFile(const std::unique_ptr<Entry> &root,const char *fullName) +void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullName) { QFileInfo fi(fullName); if (!fi.exists()) return; diff --git a/src/tagreader.h b/src/tagreader.h index 4c09a04..454060b 100644 --- a/src/tagreader.h +++ b/src/tagreader.h @@ -23,6 +23,6 @@ class Entry; #include <memory> -void parseTagFile(const std::unique_ptr<Entry> &root,const char *fullPathName); +void parseTagFile(const std::shared_ptr<Entry> &root,const char *fullPathName); #endif diff --git a/src/tclscanner.h b/src/tclscanner.h index 94da68b..cdd56d8 100644 --- a/src/tclscanner.h +++ b/src/tclscanner.h @@ -25,18 +25,23 @@ * * This is the Tcl language parser for doxygen. */ -class TclLanguageScanner : public ParserInterface +class TclOutlineParser : public OutlineParserInterface { public: - virtual ~TclLanguageScanner() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char *fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); bool needsPreprocessing(const QCString &extension) const; + void parsePrototype(const char *text); +}; + +class TclCodeParser : public CodeParserInterface +{ + public: void parseCode(CodeOutputInterface &codeOutIntf, const char *scopeName, const QCString &input, @@ -53,7 +58,6 @@ class TclLanguageScanner : public ParserInterface bool collectXRefs=TRUE ); void resetCodeParserState(); - void parsePrototype(const char *text); }; #endif diff --git a/src/tclscanner.l b/src/tclscanner.l index fccc7fc..a4709ce 100644 --- a/src/tclscanner.l +++ b/src/tclscanner.l @@ -429,7 +429,7 @@ static struct QCString input_string; // file contents int input_position; // position in file QCString file_name; // name of used file - ParserInterface *this_parser; // myself + OutlineParserInterface *this_parser; // myself int command; // true if command was found int comment; // set true if comment was scanned int brace_level; // bookkeeping of braces @@ -2964,9 +2964,9 @@ static void tcl_parse(const QCString ns, const QCString cls) } //! Parse text file and build up entry tree. -void TclLanguageScanner::parseInput(const char *fileName, +void TclOutlineParser::parseInput(const char *fileName, const char *input, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool /*sameTranslationUnit*/, QStrList & /*filesInSameTranslationUnit*/) { @@ -2995,8 +2995,40 @@ tcl_inf("%s\n",fileName); printlex(yy_flex_debug, FALSE, __FILE__, fileName); } + +bool TclOutlineParser::needsPreprocessing(const QCString &extension) const +{ + (void)extension; + return FALSE; +} + +void TclOutlineParser::parsePrototype(const char *text) +{ + (void)text; +} + +static int yyread(char *buf,int max_size) +{ + int c=0; + + *buf = '\0'; + while ( c < max_size && tcl.input_string.at(tcl.input_position) ) + { + *buf = tcl.input_string.at(tcl.input_position++) ; + c++; buf++; + } + //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c); + return c; +} + +//---------------------------------------------------------------------------- + +void TclCodeParser::resetCodeParserState() +{ +} + //! Parse file and codify. -void TclLanguageScanner::parseCode(CodeOutputInterface & codeOutIntf, +void TclCodeParser::parseCode(CodeOutputInterface & codeOutIntf, const char * scopeName, const QCString & input, SrcLangExt lang, @@ -3100,36 +3132,6 @@ tcl_inf("%s (%d,%d) %d %d\n",myStr.data(),startLine,endLine,isExampleBlock,inlin tcl.entry.clear(); printlex(yy_flex_debug, FALSE, __FILE__, fileDef ? fileDef->fileName().data(): NULL); } - -bool TclLanguageScanner::needsPreprocessing(const QCString &extension) const -{ - (void)extension; - return FALSE; -} - -void TclLanguageScanner::resetCodeParserState() -{ -} - -void TclLanguageScanner::parsePrototype(const char *text) -{ - (void)text; -} - -static int yyread(char *buf,int max_size) -{ - int c=0; - - *buf = '\0'; - while ( c < max_size && tcl.input_string.at(tcl.input_position) ) - { - *buf = tcl.input_string.at(tcl.input_position++) ; - c++; buf++; - } - //printf("Read from=%d size=%d max=%d c=%d\n",tcl.input_position,strlen(&tcl.input_string[tcl.input_position]),max_size,c); - return c; -} - //---------------------------------------------------------------------------- // to avoid a warning diff --git a/src/vhdlcode.h b/src/vhdlcode.h index a7b4687..b79e2ab 100644 --- a/src/vhdlcode.h +++ b/src/vhdlcode.h @@ -1,16 +1,35 @@ #ifndef VHDLCODE_H #define VHDLCODE_H +#include "parserintf.h" + class CodeOutputInterface; class FileDef; class MemberDef; -void parseVhdlCode(CodeOutputInterface &,const char *,const QCString &, - bool ,const char *,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, - bool collectXRefs); -void resetVhdlCodeParserState(); void codeFreeVhdlScanner(); +class VHDLCodeParser : public CodeParserInterface +{ + public: + virtual ~VHDLCodeParser() {} + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt lang, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + const MemberDef *memberDef=0, + bool showLineNumbers=TRUE, + const Definition *searchCtx=0, + bool collectXRefs=TRUE + ); + void resetCodeParserState() {} +}; + + #endif diff --git a/src/vhdlcode.l b/src/vhdlcode.l index 53e1ed8..fe5a8d9 100644 --- a/src/vhdlcode.l +++ b/src/vhdlcode.l @@ -33,6 +33,7 @@ #include <qdir.h> #include <qcstringlist.h> +#include "vhdlcode.h" #include "entry.h" #include "doxygen.h" #include "message.h" @@ -1530,17 +1531,26 @@ XILINX "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFI /*@ ---------------------------------------------------------------------------- */ -void resetVhdlCodeParserState() +static void resetVhdlCodeParserState() { g_vhdlKeyDict.setAutoDelete(TRUE); g_vhdlKeyDict.clear(); } -void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s, - bool exBlock, const char *exName,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool,const Definition *searchCtx, - bool /* collectXRefs */) +void VHDLCodeParser::parseCode(CodeOutputInterface &od, + const char *className, + const QCString &s, + SrcLangExt, + bool exBlock, + const char *exName, + FileDef *fd, + int startLine, + int endLine, + bool inlineFragment, + const MemberDef *memberDef, + bool, + const Definition *searchCtx, + bool /* collectXRefs */) { //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd); if (s.isEmpty()) return; diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 90d4829..dc39321 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -72,7 +72,7 @@ static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCStri static void writeUCFLink(const MemberDef* mdef,OutputList &ol); static void assignBinding(VhdlConfNode* conf); static void addInstance(ClassDef* entity, ClassDef* arch, ClassDef *inst, - const std::unique_ptr<Entry> &cur); + const std::shared_ptr<Entry> &cur); //---------- create svg ------------------------------------------------------------- static void createSVG(); @@ -2379,7 +2379,7 @@ void VhdlDocGen::writeStringLink(const MemberDef *mdef,QCString mem, OutputList& void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString & cname) { - ParserInterface *pIntf = Doxygen::parserManager->getParser(".vhd"); + CodeParserInterface &intf = Doxygen::parserManager->getCodeParser(".vhd"); // pIntf->resetCodeParserState(); QCString codeFragment=mdef->documentation(); @@ -2405,7 +2405,7 @@ void VhdlDocGen::writeSource(const MemberDef *mdef,OutputList& ol,const QCString codeFragment.prepend("\n"); ol.pushGeneratorState(); ol.startCodeFragment(); - pIntf->parseCode(ol, // codeOutIntf + intf.parseCode( ol, // codeOutIntf 0, // scope codeFragment, // input SrcLangExt_VHDL, // lang @@ -2535,7 +2535,7 @@ static void initUCF(Entry* root,const char* type,QCString & qcs,int line,QCStr qcs.stripPrefix("="); - std::unique_ptr<Entry> current = std::make_unique<Entry>(); + std::shared_ptr<Entry> current = std::make_shared<Entry>(); current->spec=VhdlDocGen::UCF_CONST; current->section=Entry::VARIABLE_SEC; current->bodyLine=line; @@ -2900,7 +2900,7 @@ void VhdlDocGen::computeVhdlComponentRelations() } static void addInstance(ClassDef* classEntity, ClassDef* ar, - ClassDef *cd , const std::unique_ptr<Entry> &cur) + ClassDef *cd , const std::shared_ptr<Entry> &cur) { QCString bName,n1; @@ -3134,13 +3134,13 @@ void VhdlDocGen::createFlowChart(const MemberDef *mdef) bool b=readCodeFragment( fd->absFilePath().data(), actualStart,actualEnd,codeFragment); if (!b) return; - VHDLLanguageScanner *pIntf =(VHDLLanguageScanner*) Doxygen::parserManager->getParser(".vhd"); + VHDLOutlineParser &intf =dynamic_cast<VHDLOutlineParser&>(Doxygen::parserManager->getOutlineParser(".vhd")); VhdlDocGen::setFlowMember(mdef); - std::unique_ptr<Entry> root = std::make_unique<Entry>(); + std::shared_ptr<Entry> root = std::make_shared<Entry>(); QStrList filesInSameTu; - pIntf->startTranslationUnit(""); - pIntf->parseInput("",codeFragment.data(),root,FALSE,filesInSameTu); - pIntf->finishTranslationUnit(); + intf.startTranslationUnit(""); + intf.parseInput("",codeFragment.data(),root,FALSE,filesInSameTu); + intf.finishTranslationUnit(); } void VhdlDocGen::resetCodeVhdlParserState() @@ -4312,42 +4312,3 @@ void FlowChart::writeFlowLinks(FTextStream &t) } //writeFlowLinks -void VHDLLanguageScanner::parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt, // lang - bool isExampleBlock, - const char *exampleName, - FileDef *fileDef, - int startLine, - int endLine, - bool inlineFragment, - const MemberDef *memberDef, - bool showLineNumbers, - const Definition *searchCtx, - bool collectXRefs - ) -{ - -parseVhdlCode(codeOutIntf, - scopeName, - input, - isExampleBlock, - exampleName, - fileDef, - startLine, - endLine, - inlineFragment, - memberDef, - showLineNumbers, - searchCtx, - collectXRefs - -); - - - - - - -}// class diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index d6e3ac3..8b7ebf6 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -33,7 +33,7 @@ using namespace vhdl::parser; using namespace std; -static ParserInterface *g_thisParser; +static OutlineParserInterface *g_thisParser; static QCString yyFileName; static int yyLineNr = 1; @@ -48,16 +48,15 @@ static Entry* oldEntry; static bool varr=FALSE; static QCString varName; -static std::vector< std::unique_ptr<Entry> > instFiles; -static std::vector< std::unique_ptr<Entry> > libUse; +static std::vector< std::shared_ptr<Entry> > instFiles; +static std::vector< std::shared_ptr<Entry> > libUse; static std::vector<Entry*> lineEntry; -Entry* VhdlParser::currentCompound=0; Entry* VhdlParser::tempEntry=0; Entry* VhdlParser::lastEntity=0 ; Entry* VhdlParser::lastCompound=0 ; Entry* VhdlParser::current_root = 0; -std::unique_ptr<Entry> VhdlParser::current=0; +std::shared_ptr<Entry> VhdlParser::current=0; QCString VhdlParser::compSpec; QCString VhdlParser::currName; QCString VhdlParser::confName; @@ -90,7 +89,7 @@ static void insertEntryAtLine(const Entry* ce,int line); //------------------------------------- const QList<VhdlConfNode>& getVhdlConfiguration() { return configL; } -const std::vector<std::unique_ptr<Entry> > &getVhdlInstList() { return instFiles; } +const std::vector<std::shared_ptr<Entry> > &getVhdlInstList() { return instFiles; } Entry* getVhdlCompound() { @@ -105,8 +104,8 @@ bool isConstraintFile(const QCString &fileName,const QCString &ext) } -void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf, - const std::unique_ptr<Entry> &root, bool ,QStrList&) +void VHDLOutlineParser::parseInput(const char *fileName,const char *fileBuf, + const std::shared_ptr<Entry> &root, bool ,QStrList&) { g_thisParser=this; bool inLine=false; @@ -140,10 +139,9 @@ void VHDLLanguageScanner::parseInput(const char *fileName,const char *fileBuf, VhdlParser::current_root=root.get(); VhdlParser::lastCompound=0; VhdlParser::lastEntity=0; - VhdlParser::currentCompound=0; VhdlParser::lastEntity=0; oldEntry = 0; - VhdlParser::current=std::make_unique<Entry>(); + VhdlParser::current=std::make_shared<Entry>(); VhdlParser::initEntry(VhdlParser::current.get()); Doxygen::docGroup.enterFile(fileName,yyLineNr); vhdlFileName = fileName; @@ -321,7 +319,7 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) strComment.resize(0); } -void VHDLLanguageScanner::parsePrototype(const char *text) +void VHDLOutlineParser::parsePrototype(const char *text) { varName=text; varr=TRUE; @@ -355,10 +353,10 @@ void VhdlParser::addCompInst(const char *n, const char* instName, const char* co if (true) // !findInstant(current->type)) { initEntry(current.get()); - instFiles.emplace_back(std::make_unique<Entry>(*current)); + instFiles.emplace_back(std::make_shared<Entry>(*current)); } - current=std::make_unique<Entry>(); + current=std::make_shared<Entry>(); } else { @@ -396,7 +394,7 @@ void VhdlParser::addVhdlType(const char *n,int startLine,int section, if (!lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) { - libUse.emplace_back(std::make_unique<Entry>(*current)); + libUse.emplace_back(std::make_shared<Entry>(*current)); current->reset(); } newEntry(); diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index 26bfb0e..53eb0be 100644 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -39,36 +39,20 @@ struct VhdlConfNode; * * This is the VHDL language parser for doxygen. */ -class VHDLLanguageScanner : public ParserInterface +class VHDLOutlineParser : public OutlineParserInterface { public: - virtual ~VHDLLanguageScanner() {} + virtual ~VHDLOutlineParser() {} void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char * fileName, const char *fileBuf, - const std::unique_ptr<Entry> &root, + const std::shared_ptr<Entry> &root, bool sameTranslationUnit, QStrList &filesInSameTranslationUnit); - - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt lang, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ); - bool needsPreprocessing(const QCString &) const { return TRUE; } - void resetCodeParserState(){}; - void parsePrototype(const char *text); + + bool needsPreprocessing(const QCString &) const { return TRUE; } + void parsePrototype(const char *text); }; struct VhdlConfNode @@ -98,6 +82,6 @@ struct VhdlConfNode void vhdlscanFreeScanner(); const QList<VhdlConfNode>& getVhdlConfiguration(); -const std::vector<std::unique_ptr<Entry> >&getVhdlInstList(); +const std::vector<std::shared_ptr<Entry> >&getVhdlInstList(); #endif diff --git a/src/xmlcode.h b/src/xmlcode.h index e463866..4cada9b 100644 --- a/src/xmlcode.h +++ b/src/xmlcode.h @@ -19,7 +19,7 @@ #ifndef XMLCODE_H #define XMLCODE_H -#include "types.h" +#include "parserintf.h" class CodeOutputInterface; class FileDef; @@ -27,11 +27,28 @@ class MemberDef; class QCString; class Definition; -extern void parseXmlCode(CodeOutputInterface &,const char *,const QCString &, - bool ,const char *,FileDef *fd, - int startLine,int endLine,bool inlineFragment, - const MemberDef *memberDef,bool showLineNumbers,const Definition *searchCtx, - bool collectXRefs); -extern void resetXmlCodeParserState(); +/** XML scanner. Only support syntax highlighting of code at the moment. + */ +class XMLCodeParser : public CodeParserInterface +{ + public: + void parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt, + bool isExampleBlock, + const char *exampleName=0, + FileDef *fileDef=0, + int startLine=-1, + int endLine=-1, + bool inlineFragment=FALSE, + const MemberDef *memberDef=0, + bool showLineNumbers=TRUE, + const Definition *searchCtx=0, + bool collectXRefs=TRUE + ); + void resetCodeParserState(); +}; + #endif diff --git a/src/xmlcode.l b/src/xmlcode.l index 2fedf2d..94548f8 100644 --- a/src/xmlcode.l +++ b/src/xmlcode.l @@ -407,4 +407,32 @@ void resetXmlCodeParserState() g_currentMemberDef = 0; } +//---------------------------------------------------------------------------- + +void XMLCodeParser::parseCode(CodeOutputInterface &codeOutIntf, + const char *scopeName, + const QCString &input, + SrcLangExt, + bool isExampleBlock, + const char *exampleName, + FileDef *fileDef, + int startLine, + int endLine, + bool inlineFragment, + const MemberDef *memberDef, + bool showLineNumbers, + const Definition *searchCtx, + bool collectXRefs + ) +{ + parseXmlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, + fileDef,startLine,endLine,inlineFragment,memberDef, + showLineNumbers,searchCtx,collectXRefs); +} + +void XMLCodeParser::resetCodeParserState() +{ + resetXmlCodeParserState(); +} + #include "xmlcode.l.h" diff --git a/src/xmldocvisitor.cpp b/src/xmldocvisitor.cpp index a0afa9d..828c265 100644 --- a/src/xmldocvisitor.cpp +++ b/src/xmldocvisitor.cpp @@ -251,8 +251,8 @@ void XmlDocVisitor::visit(DocVerbatim *s) m_t << " filename=\"" << lang << "\">"; else m_t << ">"; - Doxygen::parserManager->getParser(lang) - ->parseCode(m_ci,s->context(),s->text(),langExt, + Doxygen::parserManager->getCodeParser(lang) + .parseCode(m_ci,s->context(),s->text(),langExt, s->isExample(),s->exampleFile()); m_t << "</programlisting>"; break; @@ -306,8 +306,8 @@ void XmlDocVisitor::visit(DocInclude *inc) m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -325,8 +325,8 @@ void XmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::Include: m_t << "<programlisting filename=\"" << inc->file() << "\">"; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci,inc->context(), + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci,inc->context(), inc->text(), langExt, inc->isExample(), @@ -367,8 +367,8 @@ void XmlDocVisitor::visit(DocInclude *inc) break; case DocInclude::Snippet: m_t << "<programlisting filename=\"" << inc->file() << "\">"; - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -382,8 +382,8 @@ void XmlDocVisitor::visit(DocInclude *inc) m_t << "<programlisting filename=\"" << inc->file() << "\">"; QFileInfo cfi( inc->file() ); FileDef *fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); - Doxygen::parserManager->getParser(inc->extension()) - ->parseCode(m_ci, + Doxygen::parserManager->getCodeParser(inc->extension()) + .parseCode(m_ci, inc->context(), extractBlock(inc->text(),inc->blockId()), langExt, @@ -436,8 +436,8 @@ void XmlDocVisitor::visit(DocIncOperator *op) fd = createFileDef( cfi.dirPath().utf8(), cfi.fileName().utf8() ); } - Doxygen::parserManager->getParser(locLangExt) - ->parseCode(m_ci,op->context(), + Doxygen::parserManager->getCodeParser(locLangExt) + .parseCode(m_ci,op->context(), op->text(),langExt,op->isExample(), op->exampleFile(), fd, // fileDef diff --git a/src/xmlgen.cpp b/src/xmlgen.cpp index 83e97b2..bf5af84 100644 --- a/src/xmlgen.cpp +++ b/src/xmlgen.cpp @@ -417,11 +417,11 @@ static void writeXMLDocBlock(FTextStream &t, void writeXMLCodeBlock(FTextStream &t,FileDef *fd) { - ParserInterface *pIntf=Doxygen::parserManager->getParser(fd->getDefFileExtension()); + CodeParserInterface &intf=Doxygen::parserManager->getCodeParser(fd->getDefFileExtension()); SrcLangExt langExt = getLanguageFromFileName(fd->getDefFileExtension()); - pIntf->resetCodeParserState(); + intf.resetCodeParserState(); XMLCodeGenerator *xmlGen = new XMLCodeGenerator(t); - pIntf->parseCode(*xmlGen, // codeOutIntf + intf.parseCode(*xmlGen, // codeOutIntf 0, // scopeName fileToString(fd->absFilePath(),Config_getBool(FILTER_SOURCE_FILES)), langExt, // lang diff --git a/src/xmlscanner.h b/src/xmlscanner.h deleted file mode 100644 index 0fe01a7..0000000 --- a/src/xmlscanner.h +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 1997-2015 by Dimitri van Heesch. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation under the terms of the GNU General Public License is hereby - * granted. No representations are made about the suitability of this software - * for any purpose. It is provided "as is" without express or implied warranty. - * See the GNU General Public License for more details. - * - * Documents produced by Doxygen are derivative works derived from the - * input used in their production; they are not affected by this license. - * - */ - -#ifndef XMLSCANNER_H -#define XMLSCANNER_H - -#include "parserintf.h" -#include "xmlcode.h" - -/** XML scanner. Only support syntax highlighting of code at the moment. - */ -class XMLScanner : public ParserInterface -{ -public: - XMLScanner() {} - virtual ~XMLScanner() {} - void startTranslationUnit(const char *) {} - void finishTranslationUnit() {} - void parseInput(const char *, const char *, const std::unique_ptr<Entry> &, bool , QStrList &) {} - bool needsPreprocessing(const QCString &) const { return FALSE; } - - void parseCode(CodeOutputInterface &codeOutIntf, - const char *scopeName, - const QCString &input, - SrcLangExt, - bool isExampleBlock, - const char *exampleName=0, - FileDef *fileDef=0, - int startLine=-1, - int endLine=-1, - bool inlineFragment=FALSE, - const MemberDef *memberDef=0, - bool showLineNumbers=TRUE, - const Definition *searchCtx=0, - bool collectXRefs=TRUE - ) - { - parseXmlCode(codeOutIntf,scopeName,input,isExampleBlock,exampleName, - fileDef,startLine,endLine,inlineFragment,memberDef, - showLineNumbers,searchCtx,collectXRefs); - } - - void resetCodeParserState() - { - resetXmlCodeParserState(); - } - - void parsePrototype(const char *) {} - -private: -}; - -#endif |